/**
 * marked - a markdown parser
 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
 * https://github.com/chjj/marked
 */

;(function() {

/**
 * Block-Level Grammar
 */

var block = {
  newline: /^\n+/,
  code: /^( {4}[^\n]+\n*)+/,
  fences: noop,
  hr: /^( *[-*_]){3,} *(?:\n+|$)/,
  heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
  nptable: noop,
  lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
  blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
  list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
  html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
  table: noop,
  paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
  text: /^[^\n]+/
};

block.bullet = /(?:[*+-]|\d+\.)/;
block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
block.item = replace(block.item, 'gm')
  (/bull/g, block.bullet)
  ();

block.list = replace(block.list)
  (/bull/g, block.bullet)
  ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
  ('def', '\\n+(?=' + block.def.source + ')')
  ();

block.blockquote = replace(block.blockquote)
  ('def', block.def)
  ();

block._tag = '(?!(?:'
  + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
  + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
  + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';

block.html = replace(block.html)
  ('comment', /<!--[\s\S]*?-->/)
  ('closed', /<(tag)[\s\S]+?<\/\1>/)
  ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
  (/tag/g, block._tag)
  ();

block.paragraph = replace(block.paragraph)
  ('hr', block.hr)
  ('heading', block.heading)
  ('lheading', block.lheading)
  ('blockquote', block.blockquote)
  ('tag', '<' + block._tag)
  ('def', block.def)
  ();

/**
 * Normal Block Grammar
 */

block.normal = merge({}, block);

/**
 * GFM Block Grammar
 */

block.gfm = merge({}, block.normal, {
  fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
  paragraph: /^/,
  heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
});

block.gfm.paragraph = replace(block.paragraph)
  ('(?!', '(?!'
    + block.gfm.fences.source.replace('\\1', '\\2') + '|'
    + block.list.source.replace('\\1', '\\3') + '|')
  ();

/**
 * GFM + Tables Block Grammar
 */

block.tables = merge({}, block.gfm, {
  nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
  table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
});

/**
 * Block Lexer
 */

function Lexer(options) {
  this.tokens = [];
  this.tokens.links = {};
  this.options = options || marked.defaults;
  this.rules = block.normal;

  if (this.options.gfm) {
    if (this.options.tables) {
      this.rules = block.tables;
    } else {
      this.rules = block.gfm;
    }
  }
}

/**
 * Expose Block Rules
 */

Lexer.rules = block;

/**
 * Static Lex Method
 */

Lexer.lex = function(src, options) {
  var lexer = new Lexer(options);
  return lexer.lex(src);
};

/**
 * Preprocessing
 */

Lexer.prototype.lex = function(src) {
  src = src
    .replace(/\r\n|\r/g, '\n')
    .replace(/\t/g, '    ')
    .replace(/\u00a0/g, ' ')
    .replace(/\u2424/g, '\n');

  return this.token(src, true);
};

/**
 * Lexing
 */

Lexer.prototype.token = function(src, top, bq) {
  var src = src.replace(/^ +$/gm, '')
    , next
    , loose
    , cap
    , bull
    , b
    , item
    , space
    , i
    , l;

  while (src) {
    // newline
    if (cap = this.rules.newline.exec(src)) {
      src = src.substring(cap[0].length);
      if (cap[0].length > 1) {
        this.tokens.push({
          type: 'space'
        });
      }
    }

    // code
    if (cap = this.rules.code.exec(src)) {
      src = src.substring(cap[0].length);
      cap = cap[0].replace(/^ {4}/gm, '');
      this.tokens.push({
        type: 'code',
        text: !this.options.pedantic
          ? cap.replace(/\n+$/, '')
          : cap
      });
      continue;
    }

    // fences (gfm)
    if (cap = this.rules.fences.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'code',
        lang: cap[2],
        text: cap[3] || ''
      });
      continue;
    }

    // heading
    if (cap = this.rules.heading.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'heading',
        depth: cap[1].length,
        text: cap[2]
      });
      continue;
    }

    // table no leading pipe (gfm)
    if (top && (cap = this.rules.nptable.exec(src))) {
      src = src.substring(cap[0].length);

      item = {
        type: 'table',
        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
        cells: cap[3].replace(/\n$/, '').split('\n')
      };

      for (i = 0; i < item.align.length; i++) {
        if (/^ *-+: *$/.test(item.align[i])) {
          item.align[i] = 'right';
        } else if (/^ *:-+: *$/.test(item.align[i])) {
          item.align[i] = 'center';
        } else if (/^ *:-+ *$/.test(item.align[i])) {
          item.align[i] = 'left';
        } else {
          item.align[i] = null;
        }
      }

      for (i = 0; i < item.cells.length; i++) {
        item.cells[i] = item.cells[i].split(/ *\| */);
      }

      this.tokens.push(item);

      continue;
    }

    // lheading
    if (cap = this.rules.lheading.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'heading',
        depth: cap[2] === '=' ? 1 : 2,
        text: cap[1]
      });
      continue;
    }

    // hr
    if (cap = this.rules.hr.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'hr'
      });
      continue;
    }

    // blockquote
    if (cap = this.rules.blockquote.exec(src)) {
      src = src.substring(cap[0].length);

      this.tokens.push({
        type: 'blockquote_start'
      });

      cap = cap[0].replace(/^ *> ?/gm, '');

      // Pass `top` to keep the current
      // "toplevel" state. This is exactly
      // how markdown.pl works.
      this.token(cap, top, true);

      this.tokens.push({
        type: 'blockquote_end'
      });

      continue;
    }

    // list
    if (cap = this.rules.list.exec(src)) {
      src = src.substring(cap[0].length);
      bull = cap[2];

      this.tokens.push({
        type: 'list_start',
        ordered: bull.length > 1
      });

      // Get each top-level item.
      cap = cap[0].match(this.rules.item);

      next = false;
      l = cap.length;
      i = 0;

      for (; i < l; i++) {
        item = cap[i];

        // Remove the list item's bullet
        // so it is seen as the next token.
        space = item.length;
        item = item.replace(/^ *([*+-]|\d+\.) +/, '');

        // Outdent whatever the
        // list item contains. Hacky.
        if (~item.indexOf('\n ')) {
          space -= item.length;
          item = !this.options.pedantic
            ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
            : item.replace(/^ {1,4}/gm, '');
        }

        // Determine whether the next list item belongs here.
        // Backpedal if it does not belong in this list.
        if (this.options.smartLists && i !== l - 1) {
          b = block.bullet.exec(cap[i + 1])[0];
          if (bull !== b && !(bull.length > 1 && b.length > 1)) {
            src = cap.slice(i + 1).join('\n') + src;
            i = l - 1;
          }
        }

        // Determine whether item is loose or not.
        // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
        // for discount behavior.
        loose = next || /\n\n(?!\s*$)/.test(item);
        if (i !== l - 1) {
          next = item.charAt(item.length - 1) === '\n';
          if (!loose) loose = next;
        }

        this.tokens.push({
          type: loose
            ? 'loose_item_start'
            : 'list_item_start'
        });

        // Recurse.
        this.token(item, false, bq);

        this.tokens.push({
          type: 'list_item_end'
        });
      }

      this.tokens.push({
        type: 'list_end'
      });

      continue;
    }

    // html
    if (cap = this.rules.html.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: this.options.sanitize
          ? 'paragraph'
          : 'html',
        pre: !this.options.sanitizer
          && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
        text: cap[0]
      });
      continue;
    }

    // def
    if ((!bq && top) && (cap = this.rules.def.exec(src))) {
      src = src.substring(cap[0].length);
      this.tokens.links[cap[1].toLowerCase()] = {
        href: cap[2],
        title: cap[3]
      };
      continue;
    }

    // table (gfm)
    if (top && (cap = this.rules.table.exec(src))) {
      src = src.substring(cap[0].length);

      item = {
        type: 'table',
        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
        cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
      };

      for (i = 0; i < item.align.length; i++) {
        if (/^ *-+: *$/.test(item.align[i])) {
          item.align[i] = 'right';
        } else if (/^ *:-+: *$/.test(item.align[i])) {
          item.align[i] = 'center';
        } else if (/^ *:-+ *$/.test(item.align[i])) {
          item.align[i] = 'left';
        } else {
          item.align[i] = null;
        }
      }

      for (i = 0; i < item.cells.length; i++) {
        item.cells[i] = item.cells[i]
          .replace(/^ *\| *| *\| *$/g, '')
          .split(/ *\| */);
      }

      this.tokens.push(item);

      continue;
    }

    // top-level paragraph
    if (top && (cap = this.rules.paragraph.exec(src))) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'paragraph',
        text: cap[1].charAt(cap[1].length - 1) === '\n'
          ? cap[1].slice(0, -1)
          : cap[1]
      });
      continue;
    }

    // text
    if (cap = this.rules.text.exec(src)) {
      // Top-level should never reach here.
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'text',
        text: cap[0]
      });
      continue;
    }

    if (src) {
      throw new
        Error('Infinite loop on byte: ' + src.charCodeAt(0));
    }
  }

  return this.tokens;
};

/**
 * Inline-Level Grammar
 */

var inline = {
  escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
  autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
  url: noop,
  tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
  link: /^!?\[(inside)\]\(href\)/,
  reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
  nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
  strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
  em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
  code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
  br: /^ {2,}\n(?!\s*$)/,
  del: noop,
  text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
};

inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;

inline.link = replace(inline.link)
  ('inside', inline._inside)
  ('href', inline._href)
  ();

inline.reflink = replace(inline.reflink)
  ('inside', inline._inside)
  ();

/**
 * Normal Inline Grammar
 */

inline.normal = merge({}, inline);

/**
 * Pedantic Inline Grammar
 */

inline.pedantic = merge({}, inline.normal, {
  strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
  em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
});

/**
 * GFM Inline Grammar
 */

inline.gfm = merge({}, inline.normal, {
  escape: replace(inline.escape)('])', '~|])')(),
  url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
  del: /^~~(?=\S)([\s\S]*?\S)~~/,
  text: replace(inline.text)
    (']|', '~]|')
    ('|', '|https?://|')
    ()
});

/**
 * GFM + Line Breaks Inline Grammar
 */

inline.breaks = merge({}, inline.gfm, {
  br: replace(inline.br)('{2,}', '*')(),
  text: replace(inline.gfm.text)('{2,}', '*')()
});

/**
 * Inline Lexer & Compiler
 */

function InlineLexer(links, options) {
  this.options = options || marked.defaults;
  this.links = links;
  this.rules = inline.normal;
  this.renderer = this.options.renderer || new Renderer;
  this.renderer.options = this.options;

  if (!this.links) {
    throw new
      Error('Tokens array requires a `links` property.');
  }

  if (this.options.gfm) {
    if (this.options.breaks) {
      this.rules = inline.breaks;
    } else {
      this.rules = inline.gfm;
    }
  } else if (this.options.pedantic) {
    this.rules = inline.pedantic;
  }
}

/**
 * Expose Inline Rules
 */

InlineLexer.rules = inline;

/**
 * Static Lexing/Compiling Method
 */

InlineLexer.output = function(src, links, options) {
  var inline = new InlineLexer(links, options);
  return inline.output(src);
};

/**
 * Lexing/Compiling
 */

InlineLexer.prototype.output = function(src) {
  var out = ''
    , link
    , text
    , href
    , cap;

  while (src) {
    // escape
    if (cap = this.rules.escape.exec(src)) {
      src = src.substring(cap[0].length);
      out += cap[1];
      continue;
    }

    // autolink
    if (cap = this.rules.autolink.exec(src)) {
      src = src.substring(cap[0].length);
      if (cap[2] === '@') {
        text = cap[1].charAt(6) === ':'
          ? this.mangle(cap[1].substring(7))
          : this.mangle(cap[1]);
        href = this.mangle('mailto:') + text;
      } else {
        text = escape(cap[1]);
        href = text;
      }
      out += this.renderer.link(href, null, text);
      continue;
    }

    // url (gfm)
    if (!this.inLink && (cap = this.rules.url.exec(src))) {
      src = src.substring(cap[0].length);
      text = escape(cap[1]);
      href = text;
      out += this.renderer.link(href, null, text);
      continue;
    }

    // tag
    if (cap = this.rules.tag.exec(src)) {
      if (!this.inLink && /^<a /i.test(cap[0])) {
        this.inLink = true;
      } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
        this.inLink = false;
      }
      src = src.substring(cap[0].length);
      out += this.options.sanitize
        ? this.options.sanitizer
          ? this.options.sanitizer(cap[0])
          : escape(cap[0])
        : cap[0]
      continue;
    }

    // link
    if (cap = this.rules.link.exec(src)) {
      src = src.substring(cap[0].length);
      this.inLink = true;
      out += this.outputLink(cap, {
        href: cap[2],
        title: cap[3]
      });
      this.inLink = false;
      continue;
    }

    // reflink, nolink
    if ((cap = this.rules.reflink.exec(src))
        || (cap = this.rules.nolink.exec(src))) {
      src = src.substring(cap[0].length);
      link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
      link = this.links[link.toLowerCase()];
      if (!link || !link.href) {
        out += cap[0].charAt(0);
        src = cap[0].substring(1) + src;
        continue;
      }
      this.inLink = true;
      out += this.outputLink(cap, link);
      this.inLink = false;
      continue;
    }

    // strong
    if (cap = this.rules.strong.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.strong(this.output(cap[2] || cap[1]));
      continue;
    }

    // em
    if (cap = this.rules.em.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.em(this.output(cap[2] || cap[1]));
      continue;
    }

    // code
    if (cap = this.rules.code.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.codespan(escape(cap[2], true));
      continue;
    }

    // br
    if (cap = this.rules.br.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.br();
      continue;
    }

    // del (gfm)
    if (cap = this.rules.del.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.del(this.output(cap[1]));
      continue;
    }

    // text
    if (cap = this.rules.text.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.text(escape(this.smartypants(cap[0])));
      continue;
    }

    if (src) {
      throw new
        Error('Infinite loop on byte: ' + src.charCodeAt(0));
    }
  }

  return out;
};

/**
 * Compile Link
 */

InlineLexer.prototype.outputLink = function(cap, link) {
  var href = escape(link.href)
    , title = link.title ? escape(link.title) : null;

  return cap[0].charAt(0) !== '!'
    ? this.renderer.link(href, title, this.output(cap[1]))
    : this.renderer.image(href, title, escape(cap[1]));
};

/**
 * Smartypants Transformations
 */

InlineLexer.prototype.smartypants = function(text) {
  if (!this.options.smartypants) return text;
  return text
    // em-dashes
    .replace(/---/g, '\u2014')
    // en-dashes
    .replace(/--/g, '\u2013')
    // opening singles
    .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
    // closing singles & apostrophes
    .replace(/'/g, '\u2019')
    // opening doubles
    .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
    // closing doubles
    .replace(/"/g, '\u201d')
    // ellipses
    .replace(/\.{3}/g, '\u2026');
};

/**
 * Mangle Links
 */

InlineLexer.prototype.mangle = function(text) {
  if (!this.options.mangle) return text;
  var out = ''
    , l = text.length
    , i = 0
    , ch;

  for (; i < l; i++) {
    ch = text.charCodeAt(i);
    if (Math.random() > 0.5) {
      ch = 'x' + ch.toString(16);
    }
    out += '&#' + ch + ';';
  }

  return out;
};

/**
 * Renderer
 */

function Renderer(options) {
  this.options = options || {};
}

Renderer.prototype.code = function(code, lang, escaped) {
  if (this.options.highlight) {
    var out = this.options.highlight(code, lang);
    if (out != null && out !== code) {
      escaped = true;
      code = out;
    }
  }

  if (!lang) {
    return '<pre><code>'
      + (escaped ? code : escape(code, true))
      + '\n</code></pre>';
  }

  return '<pre><code class="'
    + this.options.langPrefix
    + escape(lang, true)
    + '">'
    + (escaped ? code : escape(code, true))
    + '\n</code></pre>\n';
};

Renderer.prototype.blockquote = function(quote) {
  return '<blockquote>\n' + quote + '</blockquote>\n';
};

Renderer.prototype.html = function(html) {
  return html;
};

Renderer.prototype.heading = function(text, level, raw) {
  return '<h'
    + level
    + ' id="'
    + this.options.headerPrefix
    + raw.toLowerCase().replace(/[^\w]+/g, '-')
    + '">'
    + text
    + '</h'
    + level
    + '>\n';
};

Renderer.prototype.hr = function() {
  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
};

Renderer.prototype.list = function(body, ordered) {
  var type = ordered ? 'ol' : 'ul';
  return '<' + type + '>\n' + body + '</' + type + '>\n';
};

Renderer.prototype.listitem = function(text) {
  return '<li>' + text + '</li>\n';
};

Renderer.prototype.paragraph = function(text) {
  return '<p>' + text + '</p>\n';
};

Renderer.prototype.table = function(header, body) {
  return '<table>\n'
    + '<thead>\n'
    + header
    + '</thead>\n'
    + '<tbody>\n'
    + body
    + '</tbody>\n'
    + '</table>\n';
};

Renderer.prototype.tablerow = function(content) {
  return '<tr>\n' + content + '</tr>\n';
};

Renderer.prototype.tablecell = function(content, flags) {
  var type = flags.header ? 'th' : 'td';
  var tag = flags.align
    ? '<' + type + ' style="text-align:' + flags.align + '">'
    : '<' + type + '>';
  return tag + content + '</' + type + '>\n';
};

// span level renderer
Renderer.prototype.strong = function(text) {
  return '<strong>' + text + '</strong>';
};

Renderer.prototype.em = function(text) {
  return '<em>' + text + '</em>';
};

Renderer.prototype.codespan = function(text) {
  return '<code>' + text + '</code>';
};

Renderer.prototype.br = function() {
  return this.options.xhtml ? '<br/>' : '<br>';
};

Renderer.prototype.del = function(text) {
  return '<del>' + text + '</del>';
};

Renderer.prototype.link = function(href, title, text) {
  if (this.options.sanitize) {
    try {
      var prot = decodeURIComponent(unescape(href))
        .replace(/[^\w:]/g, '')
        .toLowerCase();
    } catch (e) {
      return '';
    }
    if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
      return '';
    }
  }
  var out = '<a href="' + href + '"';
  if (title) {
    out += ' title="' + title + '"';
  }
  out += '>' + text + '</a>';
  return out;
};

Renderer.prototype.image = function(href, title, text) {
  var out = '<img src="' + href + '" alt="' + text + '"';
  if (title) {
    out += ' title="' + title + '"';
  }
  out += this.options.xhtml ? '/>' : '>';
  return out;
};

Renderer.prototype.text = function(text) {
  return text;
};

/**
 * Parsing & Compiling
 */

function Parser(options) {
  this.tokens = [];
  this.token = null;
  this.options = options || marked.defaults;
  this.options.renderer = this.options.renderer || new Renderer;
  this.renderer = this.options.renderer;
  this.renderer.options = this.options;
}

/**
 * Static Parse Method
 */

Parser.parse = function(src, options, renderer) {
  var parser = new Parser(options, renderer);
  return parser.parse(src);
};

/**
 * Parse Loop
 */

Parser.prototype.parse = function(src) {
  this.inline = new InlineLexer(src.links, this.options, this.renderer);
  this.tokens = src.reverse();

  var out = '';
  while (this.next()) {
    out += this.tok();
  }

  return out;
};

/**
 * Next Token
 */

Parser.prototype.next = function() {
  return this.token = this.tokens.pop();
};

/**
 * Preview Next Token
 */

Parser.prototype.peek = function() {
  return this.tokens[this.tokens.length - 1] || 0;
};

/**
 * Parse Text Tokens
 */

Parser.prototype.parseText = function() {
  var body = this.token.text;

  while (this.peek().type === 'text') {
    body += '\n' + this.next().text;
  }

  return this.inline.output(body);
};

/**
 * Parse Current Token
 */

Parser.prototype.tok = function() {
  switch (this.token.type) {
    case 'space': {
      return '';
    }
    case 'hr': {
      return this.renderer.hr();
    }
    case 'heading': {
      return this.renderer.heading(
        this.inline.output(this.token.text),
        this.token.depth,
        this.token.text);
    }
    case 'code': {
      return this.renderer.code(this.token.text,
        this.token.lang,
        this.token.escaped);
    }
    case 'table': {
      var header = ''
        , body = ''
        , i
        , row
        , cell
        , flags
        , j;

      // header
      cell = '';
      for (i = 0; i < this.token.header.length; i++) {
        flags = { header: true, align: this.token.align[i] };
        cell += this.renderer.tablecell(
          this.inline.output(this.token.header[i]),
          { header: true, align: this.token.align[i] }
        );
      }
      header += this.renderer.tablerow(cell);

      for (i = 0; i < this.token.cells.length; i++) {
        row = this.token.cells[i];

        cell = '';
        for (j = 0; j < row.length; j++) {
          cell += this.renderer.tablecell(
            this.inline.output(row[j]),
            { header: false, align: this.token.align[j] }
          );
        }

        body += this.renderer.tablerow(cell);
      }
      return this.renderer.table(header, body);
    }
    case 'blockquote_start': {
      var body = '';

      while (this.next().type !== 'blockquote_end') {
        body += this.tok();
      }

      return this.renderer.blockquote(body);
    }
    case 'list_start': {
      var body = ''
        , ordered = this.token.ordered;

      while (this.next().type !== 'list_end') {
        body += this.tok();
      }

      return this.renderer.list(body, ordered);
    }
    case 'list_item_start': {
      var body = '';

      while (this.next().type !== 'list_item_end') {
        body += this.token.type === 'text'
          ? this.parseText()
          : this.tok();
      }

      return this.renderer.listitem(body);
    }
    case 'loose_item_start': {
      var body = '';

      while (this.next().type !== 'list_item_end') {
        body += this.tok();
      }

      return this.renderer.listitem(body);
    }
    case 'html': {
      var html = !this.token.pre && !this.options.pedantic
        ? this.inline.output(this.token.text)
        : this.token.text;
      return this.renderer.html(html);
    }
    case 'paragraph': {
      return this.renderer.paragraph(this.inline.output(this.token.text));
    }
    case 'text': {
      return this.renderer.paragraph(this.parseText());
    }
  }
};

/**
 * Helpers
 */

function escape(html, encode) {
  return html
    .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function unescape(html) {
  return html.replace(/&([#\w]+);/g, function(_, n) {
    n = n.toLowerCase();
    if (n === 'colon') return ':';
    if (n.charAt(0) === '#') {
      return n.charAt(1) === 'x'
        ? String.fromCharCode(parseInt(n.substring(2), 16))
        : String.fromCharCode(+n.substring(1));
    }
    return '';
  });
}

function replace(regex, opt) {
  regex = regex.source;
  opt = opt || '';
  return function self(name, val) {
    if (!name) return new RegExp(regex, opt);
    val = val.source || val;
    val = val.replace(/(^|[^\[])\^/g, '$1');
    regex = regex.replace(name, val);
    return self;
  };
}

function noop() {}
noop.exec = noop;

function merge(obj) {
  var i = 1
    , target
    , key;

  for (; i < arguments.length; i++) {
    target = arguments[i];
    for (key in target) {
      if (Object.prototype.hasOwnProperty.call(target, key)) {
        obj[key] = target[key];
      }
    }
  }

  return obj;
}


/**
 * Marked
 */

function marked(src, opt, callback) {
  if (callback || typeof opt === 'function') {
    if (!callback) {
      callback = opt;
      opt = null;
    }

    opt = merge({}, marked.defaults, opt || {});

    var highlight = opt.highlight
      , tokens
      , pending
      , i = 0;

    try {
      tokens = Lexer.lex(src, opt)
    } catch (e) {
      return callback(e);
    }

    pending = tokens.length;

    var done = function(err) {
      if (err) {
        opt.highlight = highlight;
        return callback(err);
      }

      var out;

      try {
        out = Parser.parse(tokens, opt);
      } catch (e) {
        err = e;
      }

      opt.highlight = highlight;

      return err
        ? callback(err)
        : callback(null, out);
    };

    if (!highlight || highlight.length < 3) {
      return done();
    }

    delete opt.highlight;

    if (!pending) return done();

    for (; i < tokens.length; i++) {
      (function(token) {
        if (token.type !== 'code') {
          return --pending || done();
        }
        return highlight(token.text, token.lang, function(err, code) {
          if (err) return done(err);
          if (code == null || code === token.text) {
            return --pending || done();
          }
          token.text = code;
          token.escaped = true;
          --pending || done();
        });
      })(tokens[i]);
    }

    return;
  }
  try {
    if (opt) opt = merge({}, marked.defaults, opt);
    return Parser.parse(Lexer.lex(src, opt), opt);
  } catch (e) {
    e.message += '\nPlease report this to https://github.com/chjj/marked.';
    if ((opt || marked.defaults).silent) {
      return '<p>An error occured:</p><pre>'
        + escape(e.message + '', true)
        + '</pre>';
    }
    throw e;
  }
}

/**
 * Options
 */

marked.options =
marked.setOptions = function(opt) {
  merge(marked.defaults, opt);
  return marked;
};

marked.defaults = {
  gfm: true,
  tables: true,
  breaks: false,
  pedantic: false,
  sanitize: false,
  sanitizer: null,
  mangle: true,
  smartLists: false,
  silent: false,
  highlight: null,
  langPrefix: 'lang-',
  smartypants: false,
  headerPrefix: '',
  renderer: new Renderer,
  xhtml: false
};

/**
 * Expose
 */

marked.Parser = Parser;
marked.parser = Parser.parse;

marked.Renderer = Renderer;

marked.Lexer = Lexer;
marked.lexer = Lexer.lex;

marked.InlineLexer = InlineLexer;
marked.inlineLexer = InlineLexer.output;

marked.parse = marked;

if (typeof module !== 'undefined' && typeof exports === 'object') {
  module.exports = marked;
} else if (typeof define === 'function' && define.amd) {
  define(function() { return marked; });
} else {
  this.marked = marked;
}

}).call(function() {
  return this || (typeof window !== 'undefined' ? window : global);
}());

(function(factory) {

  // Setup highlight.js for different environments. First is Node.js or
  // CommonJS.
  if(typeof exports !== 'undefined') {
    factory(exports);
  } else {
    // Export hljs globally even when using AMD for cases when this script
    // is loaded with others that may still expect a global hljs.
    window.hljs = factory({});

    // Finally register the global hljs with AMD.
    if(typeof define === 'function' && define.amd) {
      define('hljs', [], function() {
        return window.hljs;
      });
    }
  }

}(function(hljs) {

  /* Utility functions */

  function escape(value) {
    return value.replace(/&/gm, '&amp;').replace(/</gm, '&lt;').replace(/>/gm, '&gt;');
  }

  function tag(node) {
    return node.nodeName.toLowerCase();
  }

  function testRe(re, lexeme) {
    var match = re && re.exec(lexeme);
    return match && match.index == 0;
  }

  function isNotHighlighted(language) {
    return (/^(no-?highlight|plain|text)$/i).test(language);
  }

  function blockLanguage(block) {
    var i, match, length,
        classes = block.className + ' ';

    classes += block.parentNode ? block.parentNode.className : '';

    // language-* takes precedence over non-prefixed class names
    match = (/\blang(?:uage)?-([\w-]+)\b/i).exec(classes);
    if (match) {
      return getLanguage(match[1]) ? match[1] : 'no-highlight';
    }

    classes = classes.split(/\s+/);
    for (i = 0, length = classes.length; i < length; i++) {
      if (getLanguage(classes[i]) || isNotHighlighted(classes[i])) {
        return classes[i];
      }
    }
  }

  function inherit(parent, obj) {
    var result = {}, key;
    for (key in parent)
      result[key] = parent[key];
    if (obj)
      for (key in obj)
        result[key] = obj[key];
    return result;
  }

  /* Stream merging */

  function nodeStream(node) {
    var result = [];
    (function _nodeStream(node, offset) {
      for (var child = node.firstChild; child; child = child.nextSibling) {
        if (child.nodeType == 3)
          offset += child.nodeValue.length;
        else if (child.nodeType == 1) {
          result.push({
            event: 'start',
            offset: offset,
            node: child
          });
          offset = _nodeStream(child, offset);
          // Prevent void elements from having an end tag that would actually
          // double them in the output. There are more void elements in HTML
          // but we list only those realistically expected in code display.
          if (!tag(child).match(/br|hr|img|input/)) {
            result.push({
              event: 'stop',
              offset: offset,
              node: child
            });
          }
        }
      }
      return offset;
    })(node, 0);
    return result;
  }

  function mergeStreams(original, highlighted, value) {
    var processed = 0;
    var result = '';
    var nodeStack = [];

    function selectStream() {
      if (!original.length || !highlighted.length) {
        return original.length ? original : highlighted;
      }
      if (original[0].offset != highlighted[0].offset) {
        return (original[0].offset < highlighted[0].offset) ? original : highlighted;
      }

      /*
      To avoid starting the stream just before it should stop the order is
      ensured that original always starts first and closes last:

      if (event1 == 'start' && event2 == 'start')
        return original;
      if (event1 == 'start' && event2 == 'stop')
        return highlighted;
      if (event1 == 'stop' && event2 == 'start')
        return original;
      if (event1 == 'stop' && event2 == 'stop')
        return highlighted;

      ... which is collapsed to:
      */
      return highlighted[0].event == 'start' ? original : highlighted;
    }

    function open(node) {
      function attr_str(a) {return ' ' + a.nodeName + '="' + escape(a.value) + '"';}
      result += '<' + tag(node) + Array.prototype.map.call(node.attributes, attr_str).join('') + '>';
    }

    function close(node) {
      result += '</' + tag(node) + '>';
    }

    function render(event) {
      (event.event == 'start' ? open : close)(event.node);
    }

    while (original.length || highlighted.length) {
      var stream = selectStream();
      result += escape(value.substr(processed, stream[0].offset - processed));
      processed = stream[0].offset;
      if (stream == original) {
        /*
        On any opening or closing tag of the original markup we first close
        the entire highlighted node stack, then render the original tag along
        with all the following original tags at the same offset and then
        reopen all the tags on the highlighted stack.
        */
        nodeStack.reverse().forEach(close);
        do {
          render(stream.splice(0, 1)[0]);
          stream = selectStream();
        } while (stream == original && stream.length && stream[0].offset == processed);
        nodeStack.reverse().forEach(open);
      } else {
        if (stream[0].event == 'start') {
          nodeStack.push(stream[0].node);
        } else {
          nodeStack.pop();
        }
        render(stream.splice(0, 1)[0]);
      }
    }
    return result + escape(value.substr(processed));
  }

  /* Initialization */

  function compileLanguage(language) {

    function reStr(re) {
        return (re && re.source) || re;
    }

    function langRe(value, global) {
      return new RegExp(
        reStr(value),
        'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')
      );
    }

    function compileMode(mode, parent) {
      if (mode.compiled)
        return;
      mode.compiled = true;

      mode.keywords = mode.keywords || mode.beginKeywords;
      if (mode.keywords) {
        var compiled_keywords = {};

        var flatten = function(className, str) {
          if (language.case_insensitive) {
            str = str.toLowerCase();
          }
          str.split(' ').forEach(function(kw) {
            var pair = kw.split('|');
            compiled_keywords[pair[0]] = [className, pair[1] ? Number(pair[1]) : 1];
          });
        };

        if (typeof mode.keywords == 'string') { // string
          flatten('keyword', mode.keywords);
        } else {
          Object.keys(mode.keywords).forEach(function (className) {
            flatten(className, mode.keywords[className]);
          });
        }
        mode.keywords = compiled_keywords;
      }
      mode.lexemesRe = langRe(mode.lexemes || /\b\w+\b/, true);

      if (parent) {
        if (mode.beginKeywords) {
          mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')\\b';
        }
        if (!mode.begin)
          mode.begin = /\B|\b/;
        mode.beginRe = langRe(mode.begin);
        if (!mode.end && !mode.endsWithParent)
          mode.end = /\B|\b/;
        if (mode.end)
          mode.endRe = langRe(mode.end);
        mode.terminator_end = reStr(mode.end) || '';
        if (mode.endsWithParent && parent.terminator_end)
          mode.terminator_end += (mode.end ? '|' : '') + parent.terminator_end;
      }
      if (mode.illegal)
        mode.illegalRe = langRe(mode.illegal);
      if (mode.relevance === undefined)
        mode.relevance = 1;
      if (!mode.contains) {
        mode.contains = [];
      }
      var expanded_contains = [];
      mode.contains.forEach(function(c) {
        if (c.variants) {
          c.variants.forEach(function(v) {expanded_contains.push(inherit(c, v));});
        } else {
          expanded_contains.push(c == 'self' ? mode : c);
        }
      });
      mode.contains = expanded_contains;
      mode.contains.forEach(function(c) {compileMode(c, mode);});

      if (mode.starts) {
        compileMode(mode.starts, parent);
      }

      var terminators =
        mode.contains.map(function(c) {
          return c.beginKeywords ? '\\.?(' + c.begin + ')\\.?' : c.begin;
        })
        .concat([mode.terminator_end, mode.illegal])
        .map(reStr)
        .filter(Boolean);
      mode.terminators = terminators.length ? langRe(terminators.join('|'), true) : {exec: function(/*s*/) {return null;}};
    }

    compileMode(language);
  }

  /*
  Core highlighting function. Accepts a language name, or an alias, and a
  string with the code to highlight. Returns an object with the following
  properties:

  - relevance (int)
  - value (an HTML string with highlighting markup)

  */
  function highlight(name, value, ignore_illegals, continuation) {

    function subMode(lexeme, mode) {
      for (var i = 0; i < mode.contains.length; i++) {
        if (testRe(mode.contains[i].beginRe, lexeme)) {
          return mode.contains[i];
        }
      }
    }

    function endOfMode(mode, lexeme) {
      if (testRe(mode.endRe, lexeme)) {
        while (mode.endsParent && mode.parent) {
          mode = mode.parent;
        }
        return mode;
      }
      if (mode.endsWithParent) {
        return endOfMode(mode.parent, lexeme);
      }
    }

    function isIllegal(lexeme, mode) {
      return !ignore_illegals && testRe(mode.illegalRe, lexeme);
    }

    function keywordMatch(mode, match) {
      var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0];
      return mode.keywords.hasOwnProperty(match_str) && mode.keywords[match_str];
    }

    function buildSpan(classname, insideSpan, leaveOpen, noPrefix) {
      var classPrefix = noPrefix ? '' : options.classPrefix,
          openSpan    = '<span class="' + classPrefix,
          closeSpan   = leaveOpen ? '' : '</span>';

      openSpan += classname + '">';

      return openSpan + insideSpan + closeSpan;
    }

    function processKeywords() {
      if (!top.keywords)
        return escape(mode_buffer);
      var result = '';
      var last_index = 0;
      top.lexemesRe.lastIndex = 0;
      var match = top.lexemesRe.exec(mode_buffer);
      while (match) {
        result += escape(mode_buffer.substr(last_index, match.index - last_index));
        var keyword_match = keywordMatch(top, match);
        if (keyword_match) {
          relevance += keyword_match[1];
          result += buildSpan(keyword_match[0], escape(match[0]));
        } else {
          result += escape(match[0]);
        }
        last_index = top.lexemesRe.lastIndex;
        match = top.lexemesRe.exec(mode_buffer);
      }
      return result + escape(mode_buffer.substr(last_index));
    }

    function processSubLanguage() {
      var explicit = typeof top.subLanguage == 'string';
      if (explicit && !languages[top.subLanguage]) {
        return escape(mode_buffer);
      }

      var result = explicit ?
                   highlight(top.subLanguage, mode_buffer, true, continuations[top.subLanguage]) :
                   highlightAuto(mode_buffer, top.subLanguage.length ? top.subLanguage : undefined);

      // Counting embedded language score towards the host language may be disabled
      // with zeroing the containing mode relevance. Usecase in point is Markdown that
      // allows XML everywhere and makes every XML snippet to have a much larger Markdown
      // score.
      if (top.relevance > 0) {
        relevance += result.relevance;
      }
      if (explicit) {
        continuations[top.subLanguage] = result.top;
      }
      return buildSpan(result.language, result.value, false, true);
    }

    function processBuffer() {
      return top.subLanguage !== undefined ? processSubLanguage() : processKeywords();
    }

    function startNewMode(mode, lexeme) {
      var markup = mode.className? buildSpan(mode.className, '', true): '';
      if (mode.returnBegin) {
        result += markup;
        mode_buffer = '';
      } else if (mode.excludeBegin) {
        result += escape(lexeme) + markup;
        mode_buffer = '';
      } else {
        result += markup;
        mode_buffer = lexeme;
      }
      top = Object.create(mode, {parent: {value: top}});
    }

    function processLexeme(buffer, lexeme) {

      mode_buffer += buffer;
      if (lexeme === undefined) {
        result += processBuffer();
        return 0;
      }

      var new_mode = subMode(lexeme, top);
      if (new_mode) {
        result += processBuffer();
        startNewMode(new_mode, lexeme);
        return new_mode.returnBegin ? 0 : lexeme.length;
      }

      var end_mode = endOfMode(top, lexeme);
      if (end_mode) {
        var origin = top;
        if (!(origin.returnEnd || origin.excludeEnd)) {
          mode_buffer += lexeme;
        }
        result += processBuffer();
        do {
          if (top.className) {
            result += '</span>';
          }
          relevance += top.relevance;
          top = top.parent;
        } while (top != end_mode.parent);
        if (origin.excludeEnd) {
          result += escape(lexeme);
        }
        mode_buffer = '';
        if (end_mode.starts) {
          startNewMode(end_mode.starts, '');
        }
        return origin.returnEnd ? 0 : lexeme.length;
      }

      if (isIllegal(lexeme, top))
        throw new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.className || '<unnamed>') + '"');

      /*
      Parser should not reach this point as all types of lexemes should be caught
      earlier, but if it does due to some bug make sure it advances at least one
      character forward to prevent infinite looping.
      */
      mode_buffer += lexeme;
      return lexeme.length || 1;
    }

    var language = getLanguage(name);
    if (!language) {
      throw new Error('Unknown language: "' + name + '"');
    }

    compileLanguage(language);
    var top = continuation || language;
    var continuations = {}; // keep continuations for sub-languages
    var result = '', current;
    for(current = top; current != language; current = current.parent) {
      if (current.className) {
        result = buildSpan(current.className, '', true) + result;
      }
    }
    var mode_buffer = '';
    var relevance = 0;
    try {
      var match, count, index = 0;
      while (true) {
        top.terminators.lastIndex = index;
        match = top.terminators.exec(value);
        if (!match)
          break;
        count = processLexeme(value.substr(index, match.index - index), match[0]);
        index = match.index + count;
      }
      processLexeme(value.substr(index));
      for(current = top; current.parent; current = current.parent) { // close dangling modes
        if (current.className) {
          result += '</span>';
        }
      }
      return {
        relevance: relevance,
        value: result,
        language: name,
        top: top
      };
    } catch (e) {
      if (e.message.indexOf('Illegal') != -1) {
        return {
          relevance: 0,
          value: escape(value)
        };
      } else {
        throw e;
      }
    }
  }

  /*
  Highlighting with language detection. Accepts a string with the code to
  highlight. Returns an object with the following properties:

  - language (detected language)
  - relevance (int)
  - value (an HTML string with highlighting markup)
  - second_best (object with the same structure for second-best heuristically
    detected language, may be absent)

  */
  function highlightAuto(text, languageSubset) {
    languageSubset = languageSubset || options.languages || Object.keys(languages);
    var result = {
      relevance: 0,
      value: escape(text)
    };
    var second_best = result;
    languageSubset.forEach(function(name) {
      if (!getLanguage(name)) {
        return;
      }
      var current = highlight(name, text, false);
      current.language = name;
      if (current.relevance > second_best.relevance) {
        second_best = current;
      }
      if (current.relevance > result.relevance) {
        second_best = result;
        result = current;
      }
    });
    if (second_best.language) {
      result.second_best = second_best;
    }
    return result;
  }

  /*
  Post-processing of the highlighted markup:

  - replace TABs with something more useful
  - replace real line-breaks with '<br>' for non-pre containers

  */
  function fixMarkup(value) {
    if (options.tabReplace) {
      value = value.replace(/^((<[^>]+>|\t)+)/gm, function(match, p1 /*..., offset, s*/) {
        return p1.replace(/\t/g, options.tabReplace);
      });
    }
    if (options.useBR) {
      value = value.replace(/\n/g, '<br>');
    }
    return value;
  }

  function buildClassName(prevClassName, currentLang, resultLang) {
    var language = currentLang ? aliases[currentLang] : resultLang,
        result   = [prevClassName.trim()];

    if (!prevClassName.match(/\bhljs\b/)) {
      result.push('hljs');
    }

    if (prevClassName.indexOf(language) === -1) {
      result.push(language);
    }

    return result.join(' ').trim();
  }

  /*
  Applies highlighting to a DOM node containing code. Accepts a DOM node and
  two optional parameters for fixMarkup.
  */
  function highlightBlock(block) {
    var language = blockLanguage(block);
    if (isNotHighlighted(language))
        return;

    var node;
    if (options.useBR) {
      node = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
      node.innerHTML = block.innerHTML.replace(/\n/g, '').replace(/<br[ \/]*>/g, '\n');
    } else {
      node = block;
    }
    var text = node.textContent;
    var result = language ? highlight(language, text, true) : highlightAuto(text);

    var originalStream = nodeStream(node);
    if (originalStream.length) {
      var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
      resultNode.innerHTML = result.value;
      result.value = mergeStreams(originalStream, nodeStream(resultNode), text);
    }
    result.value = fixMarkup(result.value);

    block.innerHTML = result.value;
    block.className = buildClassName(block.className, language, result.language);
    block.result = {
      language: result.language,
      re: result.relevance
    };
    if (result.second_best) {
      block.second_best = {
        language: result.second_best.language,
        re: result.second_best.relevance
      };
    }
  }

  var options = {
    classPrefix: 'hljs-',
    tabReplace: null,
    useBR: false,
    languages: undefined
  };

  /*
  Updates highlight.js global options with values passed in the form of an object
  */
  function configure(user_options) {
    options = inherit(options, user_options);
  }

  /*
  Applies highlighting to all <pre><code>..</code></pre> blocks on a page.
  */
  function initHighlighting() {
    if (initHighlighting.called)
      return;
    initHighlighting.called = true;

    var blocks = document.querySelectorAll('pre code');
    Array.prototype.forEach.call(blocks, highlightBlock);
  }

  /*
  Attaches highlighting to the page load event.
  */
  function initHighlightingOnLoad() {
    addEventListener('DOMContentLoaded', initHighlighting, false);
    addEventListener('load', initHighlighting, false);
  }

  var languages = {};
  var aliases = {};

  function registerLanguage(name, language) {
    var lang = languages[name] = language(hljs);
    if (lang.aliases) {
      lang.aliases.forEach(function(alias) {aliases[alias] = name;});
    }
  }

  function listLanguages() {
    return Object.keys(languages);
  }

  function getLanguage(name) {
    name = (name || '').toLowerCase();
    return languages[name] || languages[aliases[name]];
  }

  /* Interface definition */

  hljs.highlight = highlight;
  hljs.highlightAuto = highlightAuto;
  hljs.fixMarkup = fixMarkup;
  hljs.highlightBlock = highlightBlock;
  hljs.configure = configure;
  hljs.initHighlighting = initHighlighting;
  hljs.initHighlightingOnLoad = initHighlightingOnLoad;
  hljs.registerLanguage = registerLanguage;
  hljs.listLanguages = listLanguages;
  hljs.getLanguage = getLanguage;
  hljs.inherit = inherit;

  // Common regexps
  hljs.IDENT_RE = '[a-zA-Z]\\w*';
  hljs.UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*';
  hljs.NUMBER_RE = '\\b\\d+(\\.\\d+)?';
  hljs.C_NUMBER_RE = '(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float
  hljs.BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...
  hljs.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';

  // Common modes
  hljs.BACKSLASH_ESCAPE = {
    begin: '\\\\[\\s\\S]', relevance: 0
  };
  hljs.APOS_STRING_MODE = {
    className: 'string',
    begin: '\'', end: '\'',
    illegal: '\\n',
    contains: [hljs.BACKSLASH_ESCAPE]
  };
  hljs.QUOTE_STRING_MODE = {
    className: 'string',
    begin: '"', end: '"',
    illegal: '\\n',
    contains: [hljs.BACKSLASH_ESCAPE]
  };
  hljs.PHRASAL_WORDS_MODE = {
    begin: /\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/
  };
  hljs.COMMENT = function (begin, end, inherits) {
    var mode = hljs.inherit(
      {
        className: 'comment',
        begin: begin, end: end,
        contains: []
      },
      inherits || {}
    );
    mode.contains.push(hljs.PHRASAL_WORDS_MODE);
    mode.contains.push({
      className: 'doctag',
      begin: "(?:TODO|FIXME|NOTE|BUG|XXX):",
      relevance: 0
    });
    return mode;
  };
  hljs.C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$');
  hljs.C_BLOCK_COMMENT_MODE = hljs.COMMENT('/\\*', '\\*/');
  hljs.HASH_COMMENT_MODE = hljs.COMMENT('#', '$');
  hljs.NUMBER_MODE = {
    className: 'number',
    begin: hljs.NUMBER_RE,
    relevance: 0
  };
  hljs.C_NUMBER_MODE = {
    className: 'number',
    begin: hljs.C_NUMBER_RE,
    relevance: 0
  };
  hljs.BINARY_NUMBER_MODE = {
    className: 'number',
    begin: hljs.BINARY_NUMBER_RE,
    relevance: 0
  };
  hljs.CSS_NUMBER_MODE = {
    className: 'number',
    begin: hljs.NUMBER_RE + '(' +
      '%|em|ex|ch|rem'  +
      '|vw|vh|vmin|vmax' +
      '|cm|mm|in|pt|pc|px' +
      '|deg|grad|rad|turn' +
      '|s|ms' +
      '|Hz|kHz' +
      '|dpi|dpcm|dppx' +
      ')?',
    relevance: 0
  };
  hljs.REGEXP_MODE = {
    className: 'regexp',
    begin: /\//, end: /\/[gimuy]*/,
    illegal: /\n/,
    contains: [
      hljs.BACKSLASH_ESCAPE,
      {
        begin: /\[/, end: /\]/,
        relevance: 0,
        contains: [hljs.BACKSLASH_ESCAPE]
      }
    ]
  };
  hljs.TITLE_MODE = {
    className: 'title',
    begin: hljs.IDENT_RE,
    relevance: 0
  };
  hljs.UNDERSCORE_TITLE_MODE = {
    className: 'title',
    begin: hljs.UNDERSCORE_IDENT_RE,
    relevance: 0
  };

hljs.registerLanguage('1c', function(hljs){
  var IDENT_RE_RU = '[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*';
  var OneS_KEYWORDS = 'возврат дата для если и или иначе иначеесли исключение конецесли ' +
    'конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем ' +
    'перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл ' +
    'число экспорт';
  var OneS_BUILT_IN = 'ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ' +
    'ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос ' +
    'восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц ' +
    'датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации ' +
    'запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр ' +
    'значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера ' +
    'имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы ' +
    'кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби ' +
    'конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс ' +
    'максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ ' +
    'назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби ' +
    'началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели ' +
    'номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки ' +
    'основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально ' +
    'отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята ' +
    'получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта ' +
    'получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации ' +
    'пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц ' +
    'разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына ' +
    'рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп ' +
    'сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить ' +
    'стрколичествострок стрполучитьстроку  стрчисловхождений сформироватьпозициюдокумента ' +
    'счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты ' +
    'установитьтана установитьтапо фиксшаблон формат цел шаблон';
  var DQUOTE =  {className: 'dquote',  begin: '""'};
  var STR_START = {
      className: 'string',
      begin: '"', end: '"|$',
      contains: [DQUOTE]
    };
  var STR_CONT = {
    className: 'string',
    begin: '\\|', end: '"|$',
    contains: [DQUOTE]
  };

  return {
    case_insensitive: true,
    lexemes: IDENT_RE_RU,
    keywords: {keyword: OneS_KEYWORDS, built_in: OneS_BUILT_IN},
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.NUMBER_MODE,
      STR_START, STR_CONT,
      {
        className: 'function',
        begin: '(процедура|функция)', end: '$',
        lexemes: IDENT_RE_RU,
        keywords: 'процедура функция',
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE_RU}),
          {
            className: 'tail',
            endsWithParent: true,
            contains: [
              {
                className: 'params',
                begin: '\\(', end: '\\)',
                lexemes: IDENT_RE_RU,
                keywords: 'знач',
                contains: [STR_START, STR_CONT]
              },
              {
                className: 'export',
                begin: 'экспорт', endsWithParent: true,
                lexemes: IDENT_RE_RU,
                keywords: 'экспорт',
                contains: [hljs.C_LINE_COMMENT_MODE]
              }
            ]
          },
          hljs.C_LINE_COMMENT_MODE
        ]
      },
      {className: 'preprocessor', begin: '#', end: '$'},
      {className: 'date', begin: '\'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})\''}
    ]
  };
});

hljs.registerLanguage('accesslog', function(hljs) {
  return {
    contains: [
      // IP
      {
        className: 'number',
        begin: '\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b'
      },
      // Other numbers
      {
        className: 'number',
        begin: '\\b\\d+\\b',
        relevance: 0
      },
      // Requests
      {
        className: 'string',
        begin: '"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)', end: '"',
        keywords: 'GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE',
        illegal: '\\n',
        relevance: 10
      },
      // Dates
      {
        className: 'string',
        begin: /\[/, end: /\]/,
        illegal: '\\n'
      },
      // Strings
      {
        className: 'string',
        begin: '"', end: '"',
        illegal: '\\n'
      }
    ]
  };
});

hljs.registerLanguage('actionscript', function(hljs) {
  var IDENT_RE = '[a-zA-Z_$][a-zA-Z0-9_$]*';
  var IDENT_FUNC_RETURN_TYPE_RE = '([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)';

  var AS3_REST_ARG_MODE = {
    className: 'rest_arg',
    begin: '[.]{3}', end: IDENT_RE,
    relevance: 10
  };

  return {
    aliases: ['as'],
    keywords: {
      keyword: 'as break case catch class const continue default delete do dynamic each ' +
        'else extends final finally for function get if implements import in include ' +
        'instanceof interface internal is namespace native new override package private ' +
        'protected public return set static super switch this throw try typeof use var void ' +
        'while with',
      literal: 'true false null undefined'
    },
    contains: [
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'package',
        beginKeywords: 'package', end: '{',
        contains: [hljs.TITLE_MODE]
      },
      {
        className: 'class',
        beginKeywords: 'class interface', end: '{', excludeEnd: true,
        contains: [
          {
            beginKeywords: 'extends implements'
          },
          hljs.TITLE_MODE
        ]
      },
      {
        className: 'preprocessor',
        beginKeywords: 'import include', end: ';'
      },
      {
        className: 'function',
        beginKeywords: 'function', end: '[{;]', excludeEnd: true,
        illegal: '\\S',
        contains: [
          hljs.TITLE_MODE,
          {
            className: 'params',
            begin: '\\(', end: '\\)',
            contains: [
              hljs.APOS_STRING_MODE,
              hljs.QUOTE_STRING_MODE,
              hljs.C_LINE_COMMENT_MODE,
              hljs.C_BLOCK_COMMENT_MODE,
              AS3_REST_ARG_MODE
            ]
          },
          {
            className: 'type',
            begin: ':',
            end: IDENT_FUNC_RETURN_TYPE_RE,
            relevance: 10
          }
        ]
      }
    ],
    illegal: /#/
  };
});

hljs.registerLanguage('apache', function(hljs) {
  var NUMBER = {className: 'number', begin: '[\\$%]\\d+'};
  return {
    aliases: ['apacheconf'],
    case_insensitive: true,
    contains: [
      hljs.HASH_COMMENT_MODE,
      {className: 'tag', begin: '</?', end: '>'},
      {
        className: 'keyword',
        begin: /\w+/,
        relevance: 0,
        // keywords aren’t needed for highlighting per se, they only boost relevance
        // for a very generally defined mode (starts with a word, ends with line-end
        keywords: {
          common:
            'order deny allow setenv rewriterule rewriteengine rewritecond documentroot ' +
            'sethandler errordocument loadmodule options header listen serverroot ' +
            'servername'
        },
        starts: {
          end: /$/,
          relevance: 0,
          keywords: {
            literal: 'on off all'
          },
          contains: [
            {
              className: 'sqbracket',
              begin: '\\s\\[', end: '\\]$'
            },
            {
              className: 'cbracket',
              begin: '[\\$%]\\{', end: '\\}',
              contains: ['self', NUMBER]
            },
            NUMBER,
            hljs.QUOTE_STRING_MODE
          ]
        }
      }
    ],
    illegal: /\S/
  };
});

hljs.registerLanguage('applescript', function(hljs) {
  var STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: ''});
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)',
    contains: ['self', hljs.C_NUMBER_MODE, STRING]
  };
  var COMMENT_MODE_1 = hljs.COMMENT('--', '$');
  var COMMENT_MODE_2 = hljs.COMMENT(
    '\\(\\*',
    '\\*\\)',
    {
      contains: ['self', COMMENT_MODE_1] //allow nesting
    }
  );
  var COMMENTS = [
    COMMENT_MODE_1,
    COMMENT_MODE_2,
    hljs.HASH_COMMENT_MODE
  ];

  return {
    aliases: ['osascript'],
    keywords: {
      keyword:
        'about above after against and around as at back before beginning ' +
        'behind below beneath beside between but by considering ' +
        'contain contains continue copy div does eighth else end equal ' +
        'equals error every exit fifth first for fourth from front ' +
        'get given global if ignoring in into is it its last local me ' +
        'middle mod my ninth not of on onto or over prop property put ref ' +
        'reference repeat returning script second set seventh since ' +
        'sixth some tell tenth that the|0 then third through thru ' +
        'timeout times to transaction try until where while whose with ' +
        'without',
      constant:
        'AppleScript false linefeed return pi quote result space tab true',
      type:
        'alias application boolean class constant date file integer list ' +
        'number real record string text',
      command:
        'activate beep count delay launch log offset read round ' +
        'run say summarize write',
      property:
        'character characters contents day frontmost id item length ' +
        'month name paragraph paragraphs rest reverse running time version ' +
        'weekday word words year'
    },
    contains: [
      STRING,
      hljs.C_NUMBER_MODE,
      {
        className: 'type',
        begin: '\\bPOSIX file\\b'
      },
      {
        className: 'command',
        begin:
          '\\b(clipboard info|the clipboard|info for|list (disks|folder)|' +
          'mount volume|path to|(close|open for) access|(get|set) eof|' +
          'current date|do shell script|get volume settings|random number|' +
          'set volume|system attribute|system info|time to GMT|' +
          '(load|run|store) script|scripting components|' +
          'ASCII (character|number)|localized string|' +
          'choose (application|color|file|file name|' +
          'folder|from list|remote application|URL)|' +
          'display (alert|dialog))\\b|^\\s*return\\b'
      },
      {
        className: 'constant',
        begin:
          '\\b(text item delimiters|current application|missing value)\\b'
      },
      {
        className: 'keyword',
        begin:
          '\\b(apart from|aside from|instead of|out of|greater than|' +
          "isn't|(doesn't|does not) (equal|come before|come after|contain)|" +
          '(greater|less) than( or equal)?|(starts?|ends|begins?) with|' +
          'contained by|comes (before|after)|a (ref|reference))\\b'
      },
      {
        className: 'property',
        begin:
          '\\b(POSIX path|(date|time) string|quoted form)\\b'
      },
      {
        className: 'function_start',
        beginKeywords: 'on',
        illegal: '[${=;\\n]',
        contains: [hljs.UNDERSCORE_TITLE_MODE, PARAMS]
      }
    ].concat(COMMENTS),
    illegal: '//|->|=>|\\[\\['
  };
});

hljs.registerLanguage('armasm', function(hljs) {
    //local labels: %?[FB]?[AT]?\d{1,2}\w+
  return {
    case_insensitive: true,
    aliases: ['arm'],
    lexemes: '\\.?' + hljs.IDENT_RE,
    keywords: {
      literal:
        'r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 '+ //standard registers
        'pc lr sp ip sl sb fp '+ //typical regs plus backward compatibility
        'a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 '+ //more regs and fp
        'p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 '+ //coprocessor regs
        'c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 '+ //more coproc
        'q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 '+ //advanced SIMD NEON regs

        //program status registers
        'cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf '+
        'spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf '+

        //NEON and VFP registers
        's0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 '+
        's16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 '+
        'd0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 '+
        'd16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 ',
    preprocessor:
        //GNU preprocs
        '.2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg '+
        //ARM directives
        'ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ',
    built_in:
        '{PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @ '
    },
    contains: [
      {
        className: 'keyword',
        begin: '\\b('+     //mnemonics
            'adc|'+
            '(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|'+
            'and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|'+
            'bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|'+
            'setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|'+
            'ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|'+
            'mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|'+
            'mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|'+
            'mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|'+
            'rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|'+
            'stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|'+
            '[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|'+
            'wfe|wfi|yield'+
        ')'+
        '(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?'+ //condition codes
        '[sptrx]?' ,                                             //legal postfixes
        end: '\\s'
      },
      hljs.COMMENT('[;@]', '$', {relevance: 0}),
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        begin: '\'',
        end: '[^\\\\]\'',
        relevance: 0
      },
      {
        className: 'title',
        begin: '\\|', end: '\\|',
        illegal: '\\n',
        relevance: 0
      },
      {
        className: 'number',
        variants: [
            {begin: '[#$=]?0x[0-9a-f]+'}, //hex
            {begin: '[#$=]?0b[01]+'},     //bin
            {begin: '[#$=]\\d+'},        //literal
            {begin: '\\b\\d+'}           //bare number
        ],
        relevance: 0
      },
      {
        className: 'label',
        variants: [
            {begin: '^[a-z_\\.\\$][a-z0-9_\\.\\$]+'}, //ARM syntax
            {begin: '^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:'}, //GNU ARM syntax
            {begin: '[=#]\\w+' }  //label reference
        ],
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('xml', function(hljs) {
  var XML_IDENT_RE = '[A-Za-z0-9\\._:-]+';
  var PHP = {
    begin: /<\?(php)?(?!\w)/, end: /\?>/,
    subLanguage: 'php'
  };
  var TAG_INTERNALS = {
    endsWithParent: true,
    illegal: /</,
    relevance: 0,
    contains: [
      PHP,
      {
        className: 'attribute',
        begin: XML_IDENT_RE,
        relevance: 0
      },
      {
        begin: '=',
        relevance: 0,
        contains: [
          {
            className: 'value',
            contains: [PHP],
            variants: [
              {begin: /"/, end: /"/},
              {begin: /'/, end: /'/},
              {begin: /[^\s\/>]+/}
            ]
          }
        ]
      }
    ]
  };
  return {
    aliases: ['html', 'xhtml', 'rss', 'atom', 'xsl', 'plist'],
    case_insensitive: true,
    contains: [
      {
        className: 'doctype',
        begin: '<!DOCTYPE', end: '>',
        relevance: 10,
        contains: [{begin: '\\[', end: '\\]'}]
      },
      hljs.COMMENT(
        '<!--',
        '-->',
        {
          relevance: 10
        }
      ),
      {
        className: 'cdata',
        begin: '<\\!\\[CDATA\\[', end: '\\]\\]>',
        relevance: 10
      },
      {
        className: 'tag',
        /*
        The lookahead pattern (?=...) ensures that 'begin' only matches
        '<style' as a single word, followed by a whitespace or an
        ending braket. The '$' is needed for the lexeme to be recognized
        by hljs.subMode() that tests lexemes outside the stream.
        */
        begin: '<style(?=\\s|>|$)', end: '>',
        keywords: {title: 'style'},
        contains: [TAG_INTERNALS],
        starts: {
          end: '</style>', returnEnd: true,
          subLanguage: 'css'
        }
      },
      {
        className: 'tag',
        // See the comment in the <style tag about the lookahead pattern
        begin: '<script(?=\\s|>|$)', end: '>',
        keywords: {title: 'script'},
        contains: [TAG_INTERNALS],
        starts: {
          end: '\<\/script\>', returnEnd: true,
          subLanguage: ['actionscript', 'javascript', 'handlebars']
        }
      },
      PHP,
      {
        className: 'pi',
        begin: /<\?\w+/, end: /\?>/,
        relevance: 10
      },
      {
        className: 'tag',
        begin: '</?', end: '/?>',
        contains: [
          {
            className: 'title', begin: /[^ \/><\n\t]+/, relevance: 0
          },
          TAG_INTERNALS
        ]
      }
    ]
  };
});

hljs.registerLanguage('asciidoc', function(hljs) {
  return {
    aliases: ['adoc'],
    contains: [
      // block comment
      hljs.COMMENT(
        '^/{4,}\\n',
        '\\n/{4,}$',
        // can also be done as...
        //'^/{4,}$',
        //'^/{4,}$',
        {
          relevance: 10
        }
      ),
      // line comment
      hljs.COMMENT(
        '^//',
        '$',
        {
          relevance: 0
        }
      ),
      // title
      {
        className: 'title',
        begin: '^\\.\\w.*$'
      },
      // example, admonition & sidebar blocks
      {
        begin: '^[=\\*]{4,}\\n',
        end: '\\n^[=\\*]{4,}$',
        relevance: 10
      },
      // headings
      {
        className: 'header',
        begin: '^(={1,5}) .+?( \\1)?$',
        relevance: 10
      },
      {
        className: 'header',
        begin: '^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$',
        relevance: 10
      },
      // document attributes
      {
        className: 'attribute',
        begin: '^:.+?:',
        end: '\\s',
        excludeEnd: true,
        relevance: 10
      },
      // block attributes
      {
        className: 'attribute',
        begin: '^\\[.+?\\]$',
        relevance: 0
      },
      // quoteblocks
      {
        className: 'blockquote',
        begin: '^_{4,}\\n',
        end: '\\n_{4,}$',
        relevance: 10
      },
      // listing and literal blocks
      {
        className: 'code',
        begin: '^[\\-\\.]{4,}\\n',
        end: '\\n[\\-\\.]{4,}$',
        relevance: 10
      },
      // passthrough blocks
      {
        begin: '^\\+{4,}\\n',
        end: '\\n\\+{4,}$',
        contains: [
          {
            begin: '<', end: '>',
            subLanguage: 'xml',
            relevance: 0
          }
        ],
        relevance: 10
      },
      // lists (can only capture indicators)
      {
        className: 'bullet',
        begin: '^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+'
      },
      // admonition
      {
        className: 'label',
        begin: '^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+',
        relevance: 10
      },
      // inline strong
      {
        className: 'strong',
        // must not follow a word character or be followed by an asterisk or space
        begin: '\\B\\*(?![\\*\\s])',
        end: '(\\n{2}|\\*)',
        // allow escaped asterisk followed by word char
        contains: [
          {
            begin: '\\\\*\\w',
            relevance: 0
          }
        ]
      },
      // inline emphasis
      {
        className: 'emphasis',
        // must not follow a word character or be followed by a single quote or space
        begin: '\\B\'(?![\'\\s])',
        end: '(\\n{2}|\')',
        // allow escaped single quote followed by word char
        contains: [
          {
            begin: '\\\\\'\\w',
            relevance: 0
          }
        ],
        relevance: 0
      },
      // inline emphasis (alt)
      {
        className: 'emphasis',
        // must not follow a word character or be followed by an underline or space
        begin: '_(?![_\\s])',
        end: '(\\n{2}|_)',
        relevance: 0
      },
      // inline smart quotes
      {
        className: 'smartquote',
        variants: [
          {begin: "``.+?''"},
          {begin: "`.+?'"}
        ]
      },
      // inline code snippets (TODO should get same treatment as strong and emphasis)
      {
        className: 'code',
        begin: '(`.+?`|\\+.+?\\+)',
        relevance: 0
      },
      // indented literal block
      {
        className: 'code',
        begin: '^[ \\t]',
        end: '$',
        relevance: 0
      },
      // horizontal rules
      {
        className: 'horizontal_rule',
        begin: '^\'{3,}[ \\t]*$',
        relevance: 10
      },
      // images and links
      {
        begin: '(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]',
        returnBegin: true,
        contains: [
          {
            //className: 'macro',
            begin: '(link|image:?):',
            relevance: 0
          },
          {
            className: 'link_url',
            begin: '\\w',
            end: '[^\\[]+',
            relevance: 0
          },
          {
            className: 'link_label',
            begin: '\\[',
            end: '\\]',
            excludeBegin: true,
            excludeEnd: true,
            relevance: 0
          }
        ],
        relevance: 10
      }
    ]
  };
});

hljs.registerLanguage('aspectj', function (hljs) {
  var KEYWORDS =
    'false synchronized int abstract float private char boolean static null if const ' +
    'for true while long throw strictfp finally protected import native final return void ' +
    'enum else extends implements break transient new catch instanceof byte super volatile case ' +
    'assert short package default double public try this switch continue throws privileged ' +
    'aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization ' +
    'staticinitialization withincode target within execution getWithinTypeName handler ' +
    'thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents '+
    'warning error soft precedence thisAspectInstance';
  var SHORTKEYS = 'get set args call';
  return {
    keywords : KEYWORDS,
    illegal : /<\/|#/,
    contains : [
      hljs.COMMENT(
        '/\\*\\*',
        '\\*/',
        {
          relevance : 0,
          contains : [{
            className : 'doctag',
            begin : '@[A-Za-z]+'
          }]
        }
      ),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className : 'aspect',
        beginKeywords : 'aspect',
        end : /[{;=]/,
        excludeEnd : true,
        illegal : /[:;"\[\]]/,
        contains : [
          {
            beginKeywords : 'extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton'
          },
          hljs.UNDERSCORE_TITLE_MODE,
          {
            begin : /\([^\)]*/,
            end : /[)]+/,
            keywords : KEYWORDS + ' ' + SHORTKEYS,
            excludeEnd : false
          }
        ]
      },
      {
        className : 'class',
        beginKeywords : 'class interface',
        end : /[{;=]/,
        excludeEnd : true,
        relevance: 0,
        keywords : 'class interface',
        illegal : /[:"\[\]]/,
        contains : [
          {beginKeywords : 'extends implements'},
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        // AspectJ Constructs
        beginKeywords : 'pointcut after before around throwing returning',
        end : /[)]/,
        excludeEnd : false,
        illegal : /["\[\]]/,
        contains : [
          {
            begin : hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
            returnBegin : true,
            contains : [hljs.UNDERSCORE_TITLE_MODE]
          }
        ]
      },
      {
        begin : /[:]/,
        returnBegin : true,
        end : /[{;]/,
        relevance: 0,
        excludeEnd : false,
        keywords : KEYWORDS,
        illegal : /["\[\]]/,
        contains : [
          {
            begin : hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
            keywords : KEYWORDS + ' ' + SHORTKEYS
          },
          hljs.QUOTE_STRING_MODE
        ]
      },
      {
        // this prevents 'new Name(...), or throw ...' from being recognized as a function definition
        beginKeywords : 'new throw',
        relevance : 0
      },
      {
        // the function class is a bit different for AspectJ compared to the Java language
        className : 'function',
        begin : /\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,
        returnBegin : true,
        end : /[{;=]/,
        keywords : KEYWORDS,
        excludeEnd : true,
        contains : [
          {
            begin : hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
            returnBegin : true,
            relevance: 0,
            contains : [hljs.UNDERSCORE_TITLE_MODE]
          },
          {
            className : 'params',
            begin : /\(/, end : /\)/,
            relevance: 0,
            keywords : KEYWORDS,
            contains : [
              hljs.APOS_STRING_MODE,
              hljs.QUOTE_STRING_MODE,
              hljs.C_NUMBER_MODE,
              hljs.C_BLOCK_COMMENT_MODE
            ]
          },
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE
        ]
      },
      hljs.C_NUMBER_MODE,
      {
        // annotation is also used in this language
        className : 'annotation',
        begin : '@[A-Za-z]+'
      }
    ]
  };
});

hljs.registerLanguage('autohotkey', function(hljs) {
  var BACKTICK_ESCAPE = {
    className: 'escape',
    begin: '`[\\s\\S]'
  };
  var COMMENTS = hljs.COMMENT(
    ';',
    '$',
    {
      relevance: 0
    }
  );
  var BUILT_IN = [
    {
      className: 'built_in',
      begin: 'A_[a-zA-Z0-9]+'
    },
    {
      className: 'built_in',
      beginKeywords: 'ComSpec Clipboard ClipboardAll ErrorLevel'
    }
  ];

  return {
    case_insensitive: true,
    keywords: {
      keyword: 'Break Continue Else Gosub If Loop Return While',
      literal: 'A true false NOT AND OR'
    },
    contains: BUILT_IN.concat([
      BACKTICK_ESCAPE,
      hljs.inherit(hljs.QUOTE_STRING_MODE, {contains: [BACKTICK_ESCAPE]}),
      COMMENTS,
      {
        className: 'number',
        begin: hljs.NUMBER_RE,
        relevance: 0
      },
      {
        className: 'var_expand', // FIXME
        begin: '%', end: '%',
        illegal: '\\n',
        contains: [BACKTICK_ESCAPE]
      },
      {
        className: 'label',
        contains: [BACKTICK_ESCAPE],
        variants: [
          {begin: '^[^\\n";]+::(?!=)'},
          {begin: '^[^\\n";]+:(?!=)', relevance: 0} // zero relevance as it catches a lot of things
                                                    // followed by a single ':' in many languages
        ]
      },
      {
        // consecutive commas, not for highlighting but just for relevance
        begin: ',\\s*,',
        relevance: 10
      }
    ])
  }
});

hljs.registerLanguage('autoit', function(hljs) {
    var KEYWORDS = 'ByRef Case Const ContinueCase ContinueLoop ' +
        'Default Dim Do Else ElseIf EndFunc EndIf EndSelect ' +
        'EndSwitch EndWith Enum Exit ExitLoop For Func ' +
        'Global If In Local Next ReDim Return Select Static ' +
        'Step Switch Then To Until Volatile WEnd While With',

        LITERAL = 'True False And Null Not Or',

        BUILT_IN = 'Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin ' +
        'Assign ATan AutoItSetOption AutoItWinGetTitle ' +
        'AutoItWinSetTitle Beep Binary BinaryLen BinaryMid ' +
        'BinaryToString BitAND BitNOT BitOR BitRotate BitShift ' +
        'BitXOR BlockInput Break Call CDTray Ceiling Chr ' +
        'ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ' +
        'ConsoleWriteError ControlClick ControlCommand ' +
        'ControlDisable ControlEnable ControlFocus ControlGetFocus ' +
        'ControlGetHandle ControlGetPos ControlGetText ControlHide ' +
        'ControlListView ControlMove ControlSend ControlSetText ' +
        'ControlShow ControlTreeView Cos Dec DirCopy DirCreate ' +
        'DirGetSize DirMove DirRemove DllCall DllCallAddress ' +
        'DllCallbackFree DllCallbackGetPtr DllCallbackRegister ' +
        'DllClose DllOpen DllStructCreate DllStructGetData ' +
        'DllStructGetPtr DllStructGetSize DllStructSetData ' +
        'DriveGetDrive DriveGetFileSystem DriveGetLabel ' +
        'DriveGetSerial DriveGetType DriveMapAdd DriveMapDel ' +
        'DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal ' +
        'DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp ' +
        'FileChangeDir FileClose FileCopy FileCreateNTFSLink ' +
        'FileCreateShortcut FileDelete FileExists FileFindFirstFile ' +
        'FileFindNextFile FileFlush FileGetAttrib FileGetEncoding ' +
        'FileGetLongName FileGetPos FileGetShortcut FileGetShortName ' +
        'FileGetSize FileGetTime FileGetVersion FileInstall ' +
        'FileMove FileOpen FileOpenDialog FileRead FileReadLine ' +
        'FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog ' +
        'FileSelectFolder FileSetAttrib FileSetEnd FileSetPos ' +
        'FileSetTime FileWrite FileWriteLine Floor FtpSetProxy ' +
        'FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton ' +
        'GUICtrlCreateCheckbox GUICtrlCreateCombo ' +
        'GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy ' +
        'GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup ' +
        'GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel ' +
        'GUICtrlCreateList GUICtrlCreateListView ' +
        'GUICtrlCreateListViewItem GUICtrlCreateMenu ' +
        'GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj ' +
        'GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio ' +
        'GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem ' +
        'GUICtrlCreateTreeView GUICtrlCreateTreeViewItem ' +
        'GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle ' +
        'GUICtrlGetState GUICtrlRead GUICtrlRecvMsg ' +
        'GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy ' +
        'GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor ' +
        'GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor ' +
        'GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage ' +
        'GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos ' +
        'GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle ' +
        'GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg ' +
        'GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor ' +
        'GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon ' +
        'GUISetOnEvent GUISetState GUISetStyle GUIStartGroup ' +
        'GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent ' +
        'HWnd InetClose InetGet InetGetInfo InetGetSize InetRead ' +
        'IniDelete IniRead IniReadSection IniReadSectionNames ' +
        'IniRenameSection IniWrite IniWriteSection InputBox Int ' +
        'IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct ' +
        'IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj ' +
        'IsPtr IsString Log MemGetStats Mod MouseClick ' +
        'MouseClickDrag MouseDown MouseGetCursor MouseGetPos ' +
        'MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ' +
        'ObjCreateInterface ObjEvent ObjGet ObjName ' +
        'OnAutoItExitRegister OnAutoItExitUnRegister Opt Ping ' +
        'PixelChecksum PixelGetColor PixelSearch ProcessClose ' +
        'ProcessExists ProcessGetStats ProcessList ' +
        'ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ' +
        'ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey ' +
        'RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait ' +
        'RunWait Send SendKeepActive SetError SetExtended ' +
        'ShellExecute ShellExecuteWait Shutdown Sin Sleep ' +
        'SoundPlay SoundSetWaveVolume SplashImageOn SplashOff ' +
        'SplashTextOn Sqrt SRandom StatusbarGetText StderrRead ' +
        'StdinWrite StdioClose StdoutRead String StringAddCR ' +
        'StringCompare StringFormat StringFromASCIIArray StringInStr ' +
        'StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit ' +
        'StringIsFloat StringIsInt StringIsLower StringIsSpace ' +
        'StringIsUpper StringIsXDigit StringLeft StringLen ' +
        'StringLower StringMid StringRegExp StringRegExpReplace ' +
        'StringReplace StringReverse StringRight StringSplit ' +
        'StringStripCR StringStripWS StringToASCIIArray ' +
        'StringToBinary StringTrimLeft StringTrimRight StringUpper ' +
        'Tan TCPAccept TCPCloseSocket TCPConnect TCPListen ' +
        'TCPNameToIP TCPRecv TCPSend TCPShutdown TCPStartup ' +
        'TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu ' +
        'TrayGetMsg TrayItemDelete TrayItemGetHandle ' +
        'TrayItemGetState TrayItemGetText TrayItemSetOnEvent ' +
        'TrayItemSetState TrayItemSetText TraySetClick TraySetIcon ' +
        'TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip ' +
        'TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv ' +
        'UDPSend UDPShutdown UDPStartup VarGetType WinActivate ' +
        'WinActive WinClose WinExists WinFlash WinGetCaretPos ' +
        'WinGetClassList WinGetClientSize WinGetHandle WinGetPos ' +
        'WinGetProcess WinGetState WinGetText WinGetTitle WinKill ' +
        'WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo ' +
        'WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans ' +
        'WinWait WinWaitActive WinWaitClose WinWaitNotActive ' +
        'Array1DToHistogram ArrayAdd ArrayBinarySearch ' +
        'ArrayColDelete ArrayColInsert ArrayCombinations ' +
        'ArrayConcatenate ArrayDelete ArrayDisplay ArrayExtract ' +
        'ArrayFindAll ArrayInsert ArrayMax ArrayMaxIndex ArrayMin ' +
        'ArrayMinIndex ArrayPermute ArrayPop ArrayPush ' +
        'ArrayReverse ArraySearch ArrayShuffle ArraySort ArraySwap ' +
        'ArrayToClip ArrayToString ArrayTranspose ArrayTrim ' +
        'ArrayUnique Assert ChooseColor ChooseFont ' +
        'ClipBoard_ChangeChain ClipBoard_Close ClipBoard_CountFormats ' +
        'ClipBoard_Empty ClipBoard_EnumFormats ClipBoard_FormatStr ' +
        'ClipBoard_GetData ClipBoard_GetDataEx ClipBoard_GetFormatName ' +
        'ClipBoard_GetOpenWindow ClipBoard_GetOwner ' +
        'ClipBoard_GetPriorityFormat ClipBoard_GetSequenceNumber ' +
        'ClipBoard_GetViewer ClipBoard_IsFormatAvailable ' +
        'ClipBoard_Open ClipBoard_RegisterFormat ClipBoard_SetData ' +
        'ClipBoard_SetDataEx ClipBoard_SetViewer ClipPutFile ' +
        'ColorConvertHSLtoRGB ColorConvertRGBtoHSL ColorGetBlue ' +
        'ColorGetCOLORREF ColorGetGreen ColorGetRed ColorGetRGB ' +
        'ColorSetCOLORREF ColorSetRGB Crypt_DecryptData ' +
        'Crypt_DecryptFile Crypt_DeriveKey Crypt_DestroyKey ' +
        'Crypt_EncryptData Crypt_EncryptFile Crypt_GenRandom ' +
        'Crypt_HashData Crypt_HashFile Crypt_Shutdown Crypt_Startup ' +
        'DateAdd DateDayOfWeek DateDaysInMonth DateDiff ' +
        'DateIsLeapYear DateIsValid DateTimeFormat DateTimeSplit ' +
        'DateToDayOfWeek DateToDayOfWeekISO DateToDayValue ' +
        'DateToMonth Date_Time_CompareFileTime ' +
        'Date_Time_DOSDateTimeToArray Date_Time_DOSDateTimeToFileTime ' +
        'Date_Time_DOSDateTimeToStr Date_Time_DOSDateToArray ' +
        'Date_Time_DOSDateToStr Date_Time_DOSTimeToArray ' +
        'Date_Time_DOSTimeToStr Date_Time_EncodeFileTime ' +
        'Date_Time_EncodeSystemTime Date_Time_FileTimeToArray ' +
        'Date_Time_FileTimeToDOSDateTime ' +
        'Date_Time_FileTimeToLocalFileTime Date_Time_FileTimeToStr ' +
        'Date_Time_FileTimeToSystemTime Date_Time_GetFileTime ' +
        'Date_Time_GetLocalTime Date_Time_GetSystemTime ' +
        'Date_Time_GetSystemTimeAdjustment ' +
        'Date_Time_GetSystemTimeAsFileTime Date_Time_GetSystemTimes ' +
        'Date_Time_GetTickCount Date_Time_GetTimeZoneInformation ' +
        'Date_Time_LocalFileTimeToFileTime Date_Time_SetFileTime ' +
        'Date_Time_SetLocalTime Date_Time_SetSystemTime ' +
        'Date_Time_SetSystemTimeAdjustment ' +
        'Date_Time_SetTimeZoneInformation Date_Time_SystemTimeToArray ' +
        'Date_Time_SystemTimeToDateStr Date_Time_SystemTimeToDateTimeStr ' +
        'Date_Time_SystemTimeToFileTime Date_Time_SystemTimeToTimeStr ' +
        'Date_Time_SystemTimeToTzSpecificLocalTime ' +
        'Date_Time_TzSpecificLocalTimeToSystemTime DayValueToDate ' +
        'DebugBugReportEnv DebugCOMError DebugOut DebugReport ' +
        'DebugReportEx DebugReportVar DebugSetup Degree ' +
        'EventLog__Backup EventLog__Clear EventLog__Close ' +
        'EventLog__Count EventLog__DeregisterSource EventLog__Full ' +
        'EventLog__Notify EventLog__Oldest EventLog__Open ' +
        'EventLog__OpenBackup EventLog__Read EventLog__RegisterSource ' +
        'EventLog__Report Excel_BookAttach Excel_BookClose ' +
        'Excel_BookList Excel_BookNew Excel_BookOpen ' +
        'Excel_BookOpenText Excel_BookSave Excel_BookSaveAs ' +
        'Excel_Close Excel_ColumnToLetter Excel_ColumnToNumber ' +
        'Excel_ConvertFormula Excel_Export Excel_FilterGet ' +
        'Excel_FilterSet Excel_Open Excel_PictureAdd Excel_Print ' +
        'Excel_RangeCopyPaste Excel_RangeDelete Excel_RangeFind ' +
        'Excel_RangeInsert Excel_RangeLinkAddRemove Excel_RangeRead ' +
        'Excel_RangeReplace Excel_RangeSort Excel_RangeValidate ' +
        'Excel_RangeWrite Excel_SheetAdd Excel_SheetCopyMove ' +
        'Excel_SheetDelete Excel_SheetList FileCountLines FileCreate ' +
        'FileListToArray FileListToArrayRec FilePrint ' +
        'FileReadToArray FileWriteFromArray FileWriteLog ' +
        'FileWriteToLine FTP_Close FTP_Command FTP_Connect ' +
        'FTP_DecodeInternetStatus FTP_DirCreate FTP_DirDelete ' +
        'FTP_DirGetCurrent FTP_DirPutContents FTP_DirSetCurrent ' +
        'FTP_FileClose FTP_FileDelete FTP_FileGet FTP_FileGetSize ' +
        'FTP_FileOpen FTP_FilePut FTP_FileRead FTP_FileRename ' +
        'FTP_FileTimeLoHiToStr FTP_FindFileClose FTP_FindFileFirst ' +
        'FTP_FindFileNext FTP_GetLastResponseInfo FTP_ListToArray ' +
        'FTP_ListToArray2D FTP_ListToArrayEx FTP_Open ' +
        'FTP_ProgressDownload FTP_ProgressUpload FTP_SetStatusCallback ' +
        'GDIPlus_ArrowCapCreate GDIPlus_ArrowCapDispose ' +
        'GDIPlus_ArrowCapGetFillState GDIPlus_ArrowCapGetHeight ' +
        'GDIPlus_ArrowCapGetMiddleInset GDIPlus_ArrowCapGetWidth ' +
        'GDIPlus_ArrowCapSetFillState GDIPlus_ArrowCapSetHeight ' +
        'GDIPlus_ArrowCapSetMiddleInset GDIPlus_ArrowCapSetWidth ' +
        'GDIPlus_BitmapApplyEffect GDIPlus_BitmapApplyEffectEx ' +
        'GDIPlus_BitmapCloneArea GDIPlus_BitmapConvertFormat ' +
        'GDIPlus_BitmapCreateApplyEffect ' +
        'GDIPlus_BitmapCreateApplyEffectEx ' +
        'GDIPlus_BitmapCreateDIBFromBitmap GDIPlus_BitmapCreateFromFile ' +
        'GDIPlus_BitmapCreateFromGraphics ' +
        'GDIPlus_BitmapCreateFromHBITMAP GDIPlus_BitmapCreateFromHICON ' +
        'GDIPlus_BitmapCreateFromHICON32 GDIPlus_BitmapCreateFromMemory ' +
        'GDIPlus_BitmapCreateFromResource GDIPlus_BitmapCreateFromScan0 ' +
        'GDIPlus_BitmapCreateFromStream ' +
        'GDIPlus_BitmapCreateHBITMAPFromBitmap GDIPlus_BitmapDispose ' +
        'GDIPlus_BitmapGetHistogram GDIPlus_BitmapGetHistogramEx ' +
        'GDIPlus_BitmapGetHistogramSize GDIPlus_BitmapGetPixel ' +
        'GDIPlus_BitmapLockBits GDIPlus_BitmapSetPixel ' +
        'GDIPlus_BitmapUnlockBits GDIPlus_BrushClone ' +
        'GDIPlus_BrushCreateSolid GDIPlus_BrushDispose ' +
        'GDIPlus_BrushGetSolidColor GDIPlus_BrushGetType ' +
        'GDIPlus_BrushSetSolidColor GDIPlus_ColorMatrixCreate ' +
        'GDIPlus_ColorMatrixCreateGrayScale ' +
        'GDIPlus_ColorMatrixCreateNegative ' +
        'GDIPlus_ColorMatrixCreateSaturation ' +
        'GDIPlus_ColorMatrixCreateScale ' +
        'GDIPlus_ColorMatrixCreateTranslate GDIPlus_CustomLineCapClone ' +
        'GDIPlus_CustomLineCapCreate GDIPlus_CustomLineCapDispose ' +
        'GDIPlus_CustomLineCapGetStrokeCaps ' +
        'GDIPlus_CustomLineCapSetStrokeCaps GDIPlus_Decoders ' +
        'GDIPlus_DecodersGetCount GDIPlus_DecodersGetSize ' +
        'GDIPlus_DrawImageFX GDIPlus_DrawImageFXEx ' +
        'GDIPlus_DrawImagePoints GDIPlus_EffectCreate ' +
        'GDIPlus_EffectCreateBlur GDIPlus_EffectCreateBrightnessContrast ' +
        'GDIPlus_EffectCreateColorBalance GDIPlus_EffectCreateColorCurve ' +
        'GDIPlus_EffectCreateColorLUT GDIPlus_EffectCreateColorMatrix ' +
        'GDIPlus_EffectCreateHueSaturationLightness ' +
        'GDIPlus_EffectCreateLevels GDIPlus_EffectCreateRedEyeCorrection ' +
        'GDIPlus_EffectCreateSharpen GDIPlus_EffectCreateTint ' +
        'GDIPlus_EffectDispose GDIPlus_EffectGetParameters ' +
        'GDIPlus_EffectSetParameters GDIPlus_Encoders ' +
        'GDIPlus_EncodersGetCLSID GDIPlus_EncodersGetCount ' +
        'GDIPlus_EncodersGetParamList GDIPlus_EncodersGetParamListSize ' +
        'GDIPlus_EncodersGetSize GDIPlus_FontCreate ' +
        'GDIPlus_FontDispose GDIPlus_FontFamilyCreate ' +
        'GDIPlus_FontFamilyCreateFromCollection ' +
        'GDIPlus_FontFamilyDispose GDIPlus_FontFamilyGetCellAscent ' +
        'GDIPlus_FontFamilyGetCellDescent GDIPlus_FontFamilyGetEmHeight ' +
        'GDIPlus_FontFamilyGetLineSpacing GDIPlus_FontGetHeight ' +
        'GDIPlus_FontPrivateAddFont GDIPlus_FontPrivateAddMemoryFont ' +
        'GDIPlus_FontPrivateCollectionDispose ' +
        'GDIPlus_FontPrivateCreateCollection GDIPlus_GraphicsClear ' +
        'GDIPlus_GraphicsCreateFromHDC GDIPlus_GraphicsCreateFromHWND ' +
        'GDIPlus_GraphicsDispose GDIPlus_GraphicsDrawArc ' +
        'GDIPlus_GraphicsDrawBezier GDIPlus_GraphicsDrawClosedCurve ' +
        'GDIPlus_GraphicsDrawClosedCurve2 GDIPlus_GraphicsDrawCurve ' +
        'GDIPlus_GraphicsDrawCurve2 GDIPlus_GraphicsDrawEllipse ' +
        'GDIPlus_GraphicsDrawImage GDIPlus_GraphicsDrawImagePointsRect ' +
        'GDIPlus_GraphicsDrawImageRect GDIPlus_GraphicsDrawImageRectRect ' +
        'GDIPlus_GraphicsDrawLine GDIPlus_GraphicsDrawPath ' +
        'GDIPlus_GraphicsDrawPie GDIPlus_GraphicsDrawPolygon ' +
        'GDIPlus_GraphicsDrawRect GDIPlus_GraphicsDrawString ' +
        'GDIPlus_GraphicsDrawStringEx GDIPlus_GraphicsFillClosedCurve ' +
        'GDIPlus_GraphicsFillClosedCurve2 GDIPlus_GraphicsFillEllipse ' +
        'GDIPlus_GraphicsFillPath GDIPlus_GraphicsFillPie ' +
        'GDIPlus_GraphicsFillPolygon GDIPlus_GraphicsFillRect ' +
        'GDIPlus_GraphicsFillRegion GDIPlus_GraphicsGetCompositingMode ' +
        'GDIPlus_GraphicsGetCompositingQuality GDIPlus_GraphicsGetDC ' +
        'GDIPlus_GraphicsGetInterpolationMode ' +
        'GDIPlus_GraphicsGetSmoothingMode GDIPlus_GraphicsGetTransform ' +
        'GDIPlus_GraphicsMeasureCharacterRanges ' +
        'GDIPlus_GraphicsMeasureString GDIPlus_GraphicsReleaseDC ' +
        'GDIPlus_GraphicsResetClip GDIPlus_GraphicsResetTransform ' +
        'GDIPlus_GraphicsRestore GDIPlus_GraphicsRotateTransform ' +
        'GDIPlus_GraphicsSave GDIPlus_GraphicsScaleTransform ' +
        'GDIPlus_GraphicsSetClipPath GDIPlus_GraphicsSetClipRect ' +
        'GDIPlus_GraphicsSetClipRegion ' +
        'GDIPlus_GraphicsSetCompositingMode ' +
        'GDIPlus_GraphicsSetCompositingQuality ' +
        'GDIPlus_GraphicsSetInterpolationMode ' +
        'GDIPlus_GraphicsSetPixelOffsetMode ' +
        'GDIPlus_GraphicsSetSmoothingMode ' +
        'GDIPlus_GraphicsSetTextRenderingHint ' +
        'GDIPlus_GraphicsSetTransform GDIPlus_GraphicsTransformPoints ' +
        'GDIPlus_GraphicsTranslateTransform GDIPlus_HatchBrushCreate ' +
        'GDIPlus_HICONCreateFromBitmap GDIPlus_ImageAttributesCreate ' +
        'GDIPlus_ImageAttributesDispose ' +
        'GDIPlus_ImageAttributesSetColorKeys ' +
        'GDIPlus_ImageAttributesSetColorMatrix GDIPlus_ImageDispose ' +
        'GDIPlus_ImageGetDimension GDIPlus_ImageGetFlags ' +
        'GDIPlus_ImageGetGraphicsContext GDIPlus_ImageGetHeight ' +
        'GDIPlus_ImageGetHorizontalResolution ' +
        'GDIPlus_ImageGetPixelFormat GDIPlus_ImageGetRawFormat ' +
        'GDIPlus_ImageGetThumbnail GDIPlus_ImageGetType ' +
        'GDIPlus_ImageGetVerticalResolution GDIPlus_ImageGetWidth ' +
        'GDIPlus_ImageLoadFromFile GDIPlus_ImageLoadFromStream ' +
        'GDIPlus_ImageResize GDIPlus_ImageRotateFlip ' +
        'GDIPlus_ImageSaveToFile GDIPlus_ImageSaveToFileEx ' +
        'GDIPlus_ImageSaveToStream GDIPlus_ImageScale ' +
        'GDIPlus_LineBrushCreate GDIPlus_LineBrushCreateFromRect ' +
        'GDIPlus_LineBrushCreateFromRectWithAngle ' +
        'GDIPlus_LineBrushGetColors GDIPlus_LineBrushGetRect ' +
        'GDIPlus_LineBrushMultiplyTransform ' +
        'GDIPlus_LineBrushResetTransform GDIPlus_LineBrushSetBlend ' +
        'GDIPlus_LineBrushSetColors GDIPlus_LineBrushSetGammaCorrection ' +
        'GDIPlus_LineBrushSetLinearBlend GDIPlus_LineBrushSetPresetBlend ' +
        'GDIPlus_LineBrushSetSigmaBlend GDIPlus_LineBrushSetTransform ' +
        'GDIPlus_MatrixClone GDIPlus_MatrixCreate ' +
        'GDIPlus_MatrixDispose GDIPlus_MatrixGetElements ' +
        'GDIPlus_MatrixInvert GDIPlus_MatrixMultiply ' +
        'GDIPlus_MatrixRotate GDIPlus_MatrixScale ' +
        'GDIPlus_MatrixSetElements GDIPlus_MatrixShear ' +
        'GDIPlus_MatrixTransformPoints GDIPlus_MatrixTranslate ' +
        'GDIPlus_PaletteInitialize GDIPlus_ParamAdd GDIPlus_ParamInit ' +
        'GDIPlus_ParamSize GDIPlus_PathAddArc GDIPlus_PathAddBezier ' +
        'GDIPlus_PathAddClosedCurve GDIPlus_PathAddClosedCurve2 ' +
        'GDIPlus_PathAddCurve GDIPlus_PathAddCurve2 ' +
        'GDIPlus_PathAddCurve3 GDIPlus_PathAddEllipse ' +
        'GDIPlus_PathAddLine GDIPlus_PathAddLine2 GDIPlus_PathAddPath ' +
        'GDIPlus_PathAddPie GDIPlus_PathAddPolygon ' +
        'GDIPlus_PathAddRectangle GDIPlus_PathAddString ' +
        'GDIPlus_PathBrushCreate GDIPlus_PathBrushCreateFromPath ' +
        'GDIPlus_PathBrushGetCenterPoint GDIPlus_PathBrushGetFocusScales ' +
        'GDIPlus_PathBrushGetPointCount GDIPlus_PathBrushGetRect ' +
        'GDIPlus_PathBrushGetWrapMode GDIPlus_PathBrushMultiplyTransform ' +
        'GDIPlus_PathBrushResetTransform GDIPlus_PathBrushSetBlend ' +
        'GDIPlus_PathBrushSetCenterColor GDIPlus_PathBrushSetCenterPoint ' +
        'GDIPlus_PathBrushSetFocusScales ' +
        'GDIPlus_PathBrushSetGammaCorrection ' +
        'GDIPlus_PathBrushSetLinearBlend GDIPlus_PathBrushSetPresetBlend ' +
        'GDIPlus_PathBrushSetSigmaBlend ' +
        'GDIPlus_PathBrushSetSurroundColor ' +
        'GDIPlus_PathBrushSetSurroundColorsWithCount ' +
        'GDIPlus_PathBrushSetTransform GDIPlus_PathBrushSetWrapMode ' +
        'GDIPlus_PathClone GDIPlus_PathCloseFigure GDIPlus_PathCreate ' +
        'GDIPlus_PathCreate2 GDIPlus_PathDispose GDIPlus_PathFlatten ' +
        'GDIPlus_PathGetData GDIPlus_PathGetFillMode ' +
        'GDIPlus_PathGetLastPoint GDIPlus_PathGetPointCount ' +
        'GDIPlus_PathGetPoints GDIPlus_PathGetWorldBounds ' +
        'GDIPlus_PathIsOutlineVisiblePoint GDIPlus_PathIsVisiblePoint ' +
        'GDIPlus_PathIterCreate GDIPlus_PathIterDispose ' +
        'GDIPlus_PathIterGetSubpathCount GDIPlus_PathIterNextMarkerPath ' +
        'GDIPlus_PathIterNextSubpathPath GDIPlus_PathIterRewind ' +
        'GDIPlus_PathReset GDIPlus_PathReverse GDIPlus_PathSetFillMode ' +
        'GDIPlus_PathSetMarker GDIPlus_PathStartFigure ' +
        'GDIPlus_PathTransform GDIPlus_PathWarp GDIPlus_PathWiden ' +
        'GDIPlus_PathWindingModeOutline GDIPlus_PenCreate ' +
        'GDIPlus_PenCreate2 GDIPlus_PenDispose GDIPlus_PenGetAlignment ' +
        'GDIPlus_PenGetColor GDIPlus_PenGetCustomEndCap ' +
        'GDIPlus_PenGetDashCap GDIPlus_PenGetDashStyle ' +
        'GDIPlus_PenGetEndCap GDIPlus_PenGetMiterLimit ' +
        'GDIPlus_PenGetWidth GDIPlus_PenSetAlignment ' +
        'GDIPlus_PenSetColor GDIPlus_PenSetCustomEndCap ' +
        'GDIPlus_PenSetDashCap GDIPlus_PenSetDashStyle ' +
        'GDIPlus_PenSetEndCap GDIPlus_PenSetLineCap ' +
        'GDIPlus_PenSetLineJoin GDIPlus_PenSetMiterLimit ' +
        'GDIPlus_PenSetStartCap GDIPlus_PenSetWidth ' +
        'GDIPlus_RectFCreate GDIPlus_RegionClone ' +
        'GDIPlus_RegionCombinePath GDIPlus_RegionCombineRect ' +
        'GDIPlus_RegionCombineRegion GDIPlus_RegionCreate ' +
        'GDIPlus_RegionCreateFromPath GDIPlus_RegionCreateFromRect ' +
        'GDIPlus_RegionDispose GDIPlus_RegionGetBounds ' +
        'GDIPlus_RegionGetHRgn GDIPlus_RegionTransform ' +
        'GDIPlus_RegionTranslate GDIPlus_Shutdown GDIPlus_Startup ' +
        'GDIPlus_StringFormatCreate GDIPlus_StringFormatDispose ' +
        'GDIPlus_StringFormatGetMeasurableCharacterRangeCount ' +
        'GDIPlus_StringFormatSetAlign GDIPlus_StringFormatSetLineAlign ' +
        'GDIPlus_StringFormatSetMeasurableCharacterRanges ' +
        'GDIPlus_TextureCreate GDIPlus_TextureCreate2 ' +
        'GDIPlus_TextureCreateIA GetIP GUICtrlAVI_Close ' +
        'GUICtrlAVI_Create GUICtrlAVI_Destroy GUICtrlAVI_IsPlaying ' +
        'GUICtrlAVI_Open GUICtrlAVI_OpenEx GUICtrlAVI_Play ' +
        'GUICtrlAVI_Seek GUICtrlAVI_Show GUICtrlAVI_Stop ' +
        'GUICtrlButton_Click GUICtrlButton_Create ' +
        'GUICtrlButton_Destroy GUICtrlButton_Enable ' +
        'GUICtrlButton_GetCheck GUICtrlButton_GetFocus ' +
        'GUICtrlButton_GetIdealSize GUICtrlButton_GetImage ' +
        'GUICtrlButton_GetImageList GUICtrlButton_GetNote ' +
        'GUICtrlButton_GetNoteLength GUICtrlButton_GetSplitInfo ' +
        'GUICtrlButton_GetState GUICtrlButton_GetText ' +
        'GUICtrlButton_GetTextMargin GUICtrlButton_SetCheck ' +
        'GUICtrlButton_SetDontClick GUICtrlButton_SetFocus ' +
        'GUICtrlButton_SetImage GUICtrlButton_SetImageList ' +
        'GUICtrlButton_SetNote GUICtrlButton_SetShield ' +
        'GUICtrlButton_SetSize GUICtrlButton_SetSplitInfo ' +
        'GUICtrlButton_SetState GUICtrlButton_SetStyle ' +
        'GUICtrlButton_SetText GUICtrlButton_SetTextMargin ' +
        'GUICtrlButton_Show GUICtrlComboBoxEx_AddDir ' +
        'GUICtrlComboBoxEx_AddString GUICtrlComboBoxEx_BeginUpdate ' +
        'GUICtrlComboBoxEx_Create GUICtrlComboBoxEx_CreateSolidBitMap ' +
        'GUICtrlComboBoxEx_DeleteString GUICtrlComboBoxEx_Destroy ' +
        'GUICtrlComboBoxEx_EndUpdate GUICtrlComboBoxEx_FindStringExact ' +
        'GUICtrlComboBoxEx_GetComboBoxInfo ' +
        'GUICtrlComboBoxEx_GetComboControl GUICtrlComboBoxEx_GetCount ' +
        'GUICtrlComboBoxEx_GetCurSel ' +
        'GUICtrlComboBoxEx_GetDroppedControlRect ' +
        'GUICtrlComboBoxEx_GetDroppedControlRectEx ' +
        'GUICtrlComboBoxEx_GetDroppedState ' +
        'GUICtrlComboBoxEx_GetDroppedWidth ' +
        'GUICtrlComboBoxEx_GetEditControl GUICtrlComboBoxEx_GetEditSel ' +
        'GUICtrlComboBoxEx_GetEditText ' +
        'GUICtrlComboBoxEx_GetExtendedStyle ' +
        'GUICtrlComboBoxEx_GetExtendedUI GUICtrlComboBoxEx_GetImageList ' +
        'GUICtrlComboBoxEx_GetItem GUICtrlComboBoxEx_GetItemEx ' +
        'GUICtrlComboBoxEx_GetItemHeight GUICtrlComboBoxEx_GetItemImage ' +
        'GUICtrlComboBoxEx_GetItemIndent ' +
        'GUICtrlComboBoxEx_GetItemOverlayImage ' +
        'GUICtrlComboBoxEx_GetItemParam ' +
        'GUICtrlComboBoxEx_GetItemSelectedImage ' +
        'GUICtrlComboBoxEx_GetItemText GUICtrlComboBoxEx_GetItemTextLen ' +
        'GUICtrlComboBoxEx_GetList GUICtrlComboBoxEx_GetListArray ' +
        'GUICtrlComboBoxEx_GetLocale GUICtrlComboBoxEx_GetLocaleCountry ' +
        'GUICtrlComboBoxEx_GetLocaleLang ' +
        'GUICtrlComboBoxEx_GetLocalePrimLang ' +
        'GUICtrlComboBoxEx_GetLocaleSubLang ' +
        'GUICtrlComboBoxEx_GetMinVisible GUICtrlComboBoxEx_GetTopIndex ' +
        'GUICtrlComboBoxEx_GetUnicode GUICtrlComboBoxEx_InitStorage ' +
        'GUICtrlComboBoxEx_InsertString GUICtrlComboBoxEx_LimitText ' +
        'GUICtrlComboBoxEx_ReplaceEditSel GUICtrlComboBoxEx_ResetContent ' +
        'GUICtrlComboBoxEx_SetCurSel GUICtrlComboBoxEx_SetDroppedWidth ' +
        'GUICtrlComboBoxEx_SetEditSel GUICtrlComboBoxEx_SetEditText ' +
        'GUICtrlComboBoxEx_SetExtendedStyle ' +
        'GUICtrlComboBoxEx_SetExtendedUI GUICtrlComboBoxEx_SetImageList ' +
        'GUICtrlComboBoxEx_SetItem GUICtrlComboBoxEx_SetItemEx ' +
        'GUICtrlComboBoxEx_SetItemHeight GUICtrlComboBoxEx_SetItemImage ' +
        'GUICtrlComboBoxEx_SetItemIndent ' +
        'GUICtrlComboBoxEx_SetItemOverlayImage ' +
        'GUICtrlComboBoxEx_SetItemParam ' +
        'GUICtrlComboBoxEx_SetItemSelectedImage ' +
        'GUICtrlComboBoxEx_SetMinVisible GUICtrlComboBoxEx_SetTopIndex ' +
        'GUICtrlComboBoxEx_SetUnicode GUICtrlComboBoxEx_ShowDropDown ' +
        'GUICtrlComboBox_AddDir GUICtrlComboBox_AddString ' +
        'GUICtrlComboBox_AutoComplete GUICtrlComboBox_BeginUpdate ' +
        'GUICtrlComboBox_Create GUICtrlComboBox_DeleteString ' +
        'GUICtrlComboBox_Destroy GUICtrlComboBox_EndUpdate ' +
        'GUICtrlComboBox_FindString GUICtrlComboBox_FindStringExact ' +
        'GUICtrlComboBox_GetComboBoxInfo GUICtrlComboBox_GetCount ' +
        'GUICtrlComboBox_GetCueBanner GUICtrlComboBox_GetCurSel ' +
        'GUICtrlComboBox_GetDroppedControlRect ' +
        'GUICtrlComboBox_GetDroppedControlRectEx ' +
        'GUICtrlComboBox_GetDroppedState GUICtrlComboBox_GetDroppedWidth ' +
        'GUICtrlComboBox_GetEditSel GUICtrlComboBox_GetEditText ' +
        'GUICtrlComboBox_GetExtendedUI ' +
        'GUICtrlComboBox_GetHorizontalExtent ' +
        'GUICtrlComboBox_GetItemHeight GUICtrlComboBox_GetLBText ' +
        'GUICtrlComboBox_GetLBTextLen GUICtrlComboBox_GetList ' +
        'GUICtrlComboBox_GetListArray GUICtrlComboBox_GetLocale ' +
        'GUICtrlComboBox_GetLocaleCountry GUICtrlComboBox_GetLocaleLang ' +
        'GUICtrlComboBox_GetLocalePrimLang ' +
        'GUICtrlComboBox_GetLocaleSubLang GUICtrlComboBox_GetMinVisible ' +
        'GUICtrlComboBox_GetTopIndex GUICtrlComboBox_InitStorage ' +
        'GUICtrlComboBox_InsertString GUICtrlComboBox_LimitText ' +
        'GUICtrlComboBox_ReplaceEditSel GUICtrlComboBox_ResetContent ' +
        'GUICtrlComboBox_SelectString GUICtrlComboBox_SetCueBanner ' +
        'GUICtrlComboBox_SetCurSel GUICtrlComboBox_SetDroppedWidth ' +
        'GUICtrlComboBox_SetEditSel GUICtrlComboBox_SetEditText ' +
        'GUICtrlComboBox_SetExtendedUI ' +
        'GUICtrlComboBox_SetHorizontalExtent ' +
        'GUICtrlComboBox_SetItemHeight GUICtrlComboBox_SetMinVisible ' +
        'GUICtrlComboBox_SetTopIndex GUICtrlComboBox_ShowDropDown ' +
        'GUICtrlDTP_Create GUICtrlDTP_Destroy GUICtrlDTP_GetMCColor ' +
        'GUICtrlDTP_GetMCFont GUICtrlDTP_GetMonthCal ' +
        'GUICtrlDTP_GetRange GUICtrlDTP_GetRangeEx ' +
        'GUICtrlDTP_GetSystemTime GUICtrlDTP_GetSystemTimeEx ' +
        'GUICtrlDTP_SetFormat GUICtrlDTP_SetMCColor ' +
        'GUICtrlDTP_SetMCFont GUICtrlDTP_SetRange ' +
        'GUICtrlDTP_SetRangeEx GUICtrlDTP_SetSystemTime ' +
        'GUICtrlDTP_SetSystemTimeEx GUICtrlEdit_AppendText ' +
        'GUICtrlEdit_BeginUpdate GUICtrlEdit_CanUndo ' +
        'GUICtrlEdit_CharFromPos GUICtrlEdit_Create ' +
        'GUICtrlEdit_Destroy GUICtrlEdit_EmptyUndoBuffer ' +
        'GUICtrlEdit_EndUpdate GUICtrlEdit_Find GUICtrlEdit_FmtLines ' +
        'GUICtrlEdit_GetCueBanner GUICtrlEdit_GetFirstVisibleLine ' +
        'GUICtrlEdit_GetLimitText GUICtrlEdit_GetLine ' +
        'GUICtrlEdit_GetLineCount GUICtrlEdit_GetMargins ' +
        'GUICtrlEdit_GetModify GUICtrlEdit_GetPasswordChar ' +
        'GUICtrlEdit_GetRECT GUICtrlEdit_GetRECTEx GUICtrlEdit_GetSel ' +
        'GUICtrlEdit_GetText GUICtrlEdit_GetTextLen ' +
        'GUICtrlEdit_HideBalloonTip GUICtrlEdit_InsertText ' +
        'GUICtrlEdit_LineFromChar GUICtrlEdit_LineIndex ' +
        'GUICtrlEdit_LineLength GUICtrlEdit_LineScroll ' +
        'GUICtrlEdit_PosFromChar GUICtrlEdit_ReplaceSel ' +
        'GUICtrlEdit_Scroll GUICtrlEdit_SetCueBanner ' +
        'GUICtrlEdit_SetLimitText GUICtrlEdit_SetMargins ' +
        'GUICtrlEdit_SetModify GUICtrlEdit_SetPasswordChar ' +
        'GUICtrlEdit_SetReadOnly GUICtrlEdit_SetRECT ' +
        'GUICtrlEdit_SetRECTEx GUICtrlEdit_SetRECTNP ' +
        'GUICtrlEdit_SetRectNPEx GUICtrlEdit_SetSel ' +
        'GUICtrlEdit_SetTabStops GUICtrlEdit_SetText ' +
        'GUICtrlEdit_ShowBalloonTip GUICtrlEdit_Undo ' +
        'GUICtrlHeader_AddItem GUICtrlHeader_ClearFilter ' +
        'GUICtrlHeader_ClearFilterAll GUICtrlHeader_Create ' +
        'GUICtrlHeader_CreateDragImage GUICtrlHeader_DeleteItem ' +
        'GUICtrlHeader_Destroy GUICtrlHeader_EditFilter ' +
        'GUICtrlHeader_GetBitmapMargin GUICtrlHeader_GetImageList ' +
        'GUICtrlHeader_GetItem GUICtrlHeader_GetItemAlign ' +
        'GUICtrlHeader_GetItemBitmap GUICtrlHeader_GetItemCount ' +
        'GUICtrlHeader_GetItemDisplay GUICtrlHeader_GetItemFlags ' +
        'GUICtrlHeader_GetItemFormat GUICtrlHeader_GetItemImage ' +
        'GUICtrlHeader_GetItemOrder GUICtrlHeader_GetItemParam ' +
        'GUICtrlHeader_GetItemRect GUICtrlHeader_GetItemRectEx ' +
        'GUICtrlHeader_GetItemText GUICtrlHeader_GetItemWidth ' +
        'GUICtrlHeader_GetOrderArray GUICtrlHeader_GetUnicodeFormat ' +
        'GUICtrlHeader_HitTest GUICtrlHeader_InsertItem ' +
        'GUICtrlHeader_Layout GUICtrlHeader_OrderToIndex ' +
        'GUICtrlHeader_SetBitmapMargin ' +
        'GUICtrlHeader_SetFilterChangeTimeout ' +
        'GUICtrlHeader_SetHotDivider GUICtrlHeader_SetImageList ' +
        'GUICtrlHeader_SetItem GUICtrlHeader_SetItemAlign ' +
        'GUICtrlHeader_SetItemBitmap GUICtrlHeader_SetItemDisplay ' +
        'GUICtrlHeader_SetItemFlags GUICtrlHeader_SetItemFormat ' +
        'GUICtrlHeader_SetItemImage GUICtrlHeader_SetItemOrder ' +
        'GUICtrlHeader_SetItemParam GUICtrlHeader_SetItemText ' +
        'GUICtrlHeader_SetItemWidth GUICtrlHeader_SetOrderArray ' +
        'GUICtrlHeader_SetUnicodeFormat GUICtrlIpAddress_ClearAddress ' +
        'GUICtrlIpAddress_Create GUICtrlIpAddress_Destroy ' +
        'GUICtrlIpAddress_Get GUICtrlIpAddress_GetArray ' +
        'GUICtrlIpAddress_GetEx GUICtrlIpAddress_IsBlank ' +
        'GUICtrlIpAddress_Set GUICtrlIpAddress_SetArray ' +
        'GUICtrlIpAddress_SetEx GUICtrlIpAddress_SetFocus ' +
        'GUICtrlIpAddress_SetFont GUICtrlIpAddress_SetRange ' +
        'GUICtrlIpAddress_ShowHide GUICtrlListBox_AddFile ' +
        'GUICtrlListBox_AddString GUICtrlListBox_BeginUpdate ' +
        'GUICtrlListBox_ClickItem GUICtrlListBox_Create ' +
        'GUICtrlListBox_DeleteString GUICtrlListBox_Destroy ' +
        'GUICtrlListBox_Dir GUICtrlListBox_EndUpdate ' +
        'GUICtrlListBox_FindInText GUICtrlListBox_FindString ' +
        'GUICtrlListBox_GetAnchorIndex GUICtrlListBox_GetCaretIndex ' +
        'GUICtrlListBox_GetCount GUICtrlListBox_GetCurSel ' +
        'GUICtrlListBox_GetHorizontalExtent GUICtrlListBox_GetItemData ' +
        'GUICtrlListBox_GetItemHeight GUICtrlListBox_GetItemRect ' +
        'GUICtrlListBox_GetItemRectEx GUICtrlListBox_GetListBoxInfo ' +
        'GUICtrlListBox_GetLocale GUICtrlListBox_GetLocaleCountry ' +
        'GUICtrlListBox_GetLocaleLang GUICtrlListBox_GetLocalePrimLang ' +
        'GUICtrlListBox_GetLocaleSubLang GUICtrlListBox_GetSel ' +
        'GUICtrlListBox_GetSelCount GUICtrlListBox_GetSelItems ' +
        'GUICtrlListBox_GetSelItemsText GUICtrlListBox_GetText ' +
        'GUICtrlListBox_GetTextLen GUICtrlListBox_GetTopIndex ' +
        'GUICtrlListBox_InitStorage GUICtrlListBox_InsertString ' +
        'GUICtrlListBox_ItemFromPoint GUICtrlListBox_ReplaceString ' +
        'GUICtrlListBox_ResetContent GUICtrlListBox_SelectString ' +
        'GUICtrlListBox_SelItemRange GUICtrlListBox_SelItemRangeEx ' +
        'GUICtrlListBox_SetAnchorIndex GUICtrlListBox_SetCaretIndex ' +
        'GUICtrlListBox_SetColumnWidth GUICtrlListBox_SetCurSel ' +
        'GUICtrlListBox_SetHorizontalExtent GUICtrlListBox_SetItemData ' +
        'GUICtrlListBox_SetItemHeight GUICtrlListBox_SetLocale ' +
        'GUICtrlListBox_SetSel GUICtrlListBox_SetTabStops ' +
        'GUICtrlListBox_SetTopIndex GUICtrlListBox_Sort ' +
        'GUICtrlListBox_SwapString GUICtrlListBox_UpdateHScroll ' +
        'GUICtrlListView_AddArray GUICtrlListView_AddColumn ' +
        'GUICtrlListView_AddItem GUICtrlListView_AddSubItem ' +
        'GUICtrlListView_ApproximateViewHeight ' +
        'GUICtrlListView_ApproximateViewRect ' +
        'GUICtrlListView_ApproximateViewWidth GUICtrlListView_Arrange ' +
        'GUICtrlListView_BeginUpdate GUICtrlListView_CancelEditLabel ' +
        'GUICtrlListView_ClickItem GUICtrlListView_CopyItems ' +
        'GUICtrlListView_Create GUICtrlListView_CreateDragImage ' +
        'GUICtrlListView_CreateSolidBitMap ' +
        'GUICtrlListView_DeleteAllItems GUICtrlListView_DeleteColumn ' +
        'GUICtrlListView_DeleteItem GUICtrlListView_DeleteItemsSelected ' +
        'GUICtrlListView_Destroy GUICtrlListView_DrawDragImage ' +
        'GUICtrlListView_EditLabel GUICtrlListView_EnableGroupView ' +
        'GUICtrlListView_EndUpdate GUICtrlListView_EnsureVisible ' +
        'GUICtrlListView_FindInText GUICtrlListView_FindItem ' +
        'GUICtrlListView_FindNearest GUICtrlListView_FindParam ' +
        'GUICtrlListView_FindText GUICtrlListView_GetBkColor ' +
        'GUICtrlListView_GetBkImage GUICtrlListView_GetCallbackMask ' +
        'GUICtrlListView_GetColumn GUICtrlListView_GetColumnCount ' +
        'GUICtrlListView_GetColumnOrder ' +
        'GUICtrlListView_GetColumnOrderArray ' +
        'GUICtrlListView_GetColumnWidth GUICtrlListView_GetCounterPage ' +
        'GUICtrlListView_GetEditControl ' +
        'GUICtrlListView_GetExtendedListViewStyle ' +
        'GUICtrlListView_GetFocusedGroup GUICtrlListView_GetGroupCount ' +
        'GUICtrlListView_GetGroupInfo ' +
        'GUICtrlListView_GetGroupInfoByIndex ' +
        'GUICtrlListView_GetGroupRect ' +
        'GUICtrlListView_GetGroupViewEnabled GUICtrlListView_GetHeader ' +
        'GUICtrlListView_GetHotCursor GUICtrlListView_GetHotItem ' +
        'GUICtrlListView_GetHoverTime GUICtrlListView_GetImageList ' +
        'GUICtrlListView_GetISearchString GUICtrlListView_GetItem ' +
        'GUICtrlListView_GetItemChecked GUICtrlListView_GetItemCount ' +
        'GUICtrlListView_GetItemCut GUICtrlListView_GetItemDropHilited ' +
        'GUICtrlListView_GetItemEx GUICtrlListView_GetItemFocused ' +
        'GUICtrlListView_GetItemGroupID GUICtrlListView_GetItemImage ' +
        'GUICtrlListView_GetItemIndent GUICtrlListView_GetItemParam ' +
        'GUICtrlListView_GetItemPosition ' +
        'GUICtrlListView_GetItemPositionX ' +
        'GUICtrlListView_GetItemPositionY GUICtrlListView_GetItemRect ' +
        'GUICtrlListView_GetItemRectEx GUICtrlListView_GetItemSelected ' +
        'GUICtrlListView_GetItemSpacing GUICtrlListView_GetItemSpacingX ' +
        'GUICtrlListView_GetItemSpacingY GUICtrlListView_GetItemState ' +
        'GUICtrlListView_GetItemStateImage GUICtrlListView_GetItemText ' +
        'GUICtrlListView_GetItemTextArray ' +
        'GUICtrlListView_GetItemTextString GUICtrlListView_GetNextItem ' +
        'GUICtrlListView_GetNumberOfWorkAreas GUICtrlListView_GetOrigin ' +
        'GUICtrlListView_GetOriginX GUICtrlListView_GetOriginY ' +
        'GUICtrlListView_GetOutlineColor ' +
        'GUICtrlListView_GetSelectedColumn ' +
        'GUICtrlListView_GetSelectedCount ' +
        'GUICtrlListView_GetSelectedIndices ' +
        'GUICtrlListView_GetSelectionMark GUICtrlListView_GetStringWidth ' +
        'GUICtrlListView_GetSubItemRect GUICtrlListView_GetTextBkColor ' +
        'GUICtrlListView_GetTextColor GUICtrlListView_GetToolTips ' +
        'GUICtrlListView_GetTopIndex GUICtrlListView_GetUnicodeFormat ' +
        'GUICtrlListView_GetView GUICtrlListView_GetViewDetails ' +
        'GUICtrlListView_GetViewLarge GUICtrlListView_GetViewList ' +
        'GUICtrlListView_GetViewRect GUICtrlListView_GetViewSmall ' +
        'GUICtrlListView_GetViewTile GUICtrlListView_HideColumn ' +
        'GUICtrlListView_HitTest GUICtrlListView_InsertColumn ' +
        'GUICtrlListView_InsertGroup GUICtrlListView_InsertItem ' +
        'GUICtrlListView_JustifyColumn GUICtrlListView_MapIDToIndex ' +
        'GUICtrlListView_MapIndexToID GUICtrlListView_RedrawItems ' +
        'GUICtrlListView_RegisterSortCallBack ' +
        'GUICtrlListView_RemoveAllGroups GUICtrlListView_RemoveGroup ' +
        'GUICtrlListView_Scroll GUICtrlListView_SetBkColor ' +
        'GUICtrlListView_SetBkImage GUICtrlListView_SetCallBackMask ' +
        'GUICtrlListView_SetColumn GUICtrlListView_SetColumnOrder ' +
        'GUICtrlListView_SetColumnOrderArray ' +
        'GUICtrlListView_SetColumnWidth ' +
        'GUICtrlListView_SetExtendedListViewStyle ' +
        'GUICtrlListView_SetGroupInfo GUICtrlListView_SetHotItem ' +
        'GUICtrlListView_SetHoverTime GUICtrlListView_SetIconSpacing ' +
        'GUICtrlListView_SetImageList GUICtrlListView_SetItem ' +
        'GUICtrlListView_SetItemChecked GUICtrlListView_SetItemCount ' +
        'GUICtrlListView_SetItemCut GUICtrlListView_SetItemDropHilited ' +
        'GUICtrlListView_SetItemEx GUICtrlListView_SetItemFocused ' +
        'GUICtrlListView_SetItemGroupID GUICtrlListView_SetItemImage ' +
        'GUICtrlListView_SetItemIndent GUICtrlListView_SetItemParam ' +
        'GUICtrlListView_SetItemPosition ' +
        'GUICtrlListView_SetItemPosition32 ' +
        'GUICtrlListView_SetItemSelected GUICtrlListView_SetItemState ' +
        'GUICtrlListView_SetItemStateImage GUICtrlListView_SetItemText ' +
        'GUICtrlListView_SetOutlineColor ' +
        'GUICtrlListView_SetSelectedColumn ' +
        'GUICtrlListView_SetSelectionMark GUICtrlListView_SetTextBkColor ' +
        'GUICtrlListView_SetTextColor GUICtrlListView_SetToolTips ' +
        'GUICtrlListView_SetUnicodeFormat GUICtrlListView_SetView ' +
        'GUICtrlListView_SetWorkAreas GUICtrlListView_SimpleSort ' +
        'GUICtrlListView_SortItems GUICtrlListView_SubItemHitTest ' +
        'GUICtrlListView_UnRegisterSortCallBack GUICtrlMenu_AddMenuItem ' +
        'GUICtrlMenu_AppendMenu GUICtrlMenu_CalculatePopupWindowPosition ' +
        'GUICtrlMenu_CheckMenuItem GUICtrlMenu_CheckRadioItem ' +
        'GUICtrlMenu_CreateMenu GUICtrlMenu_CreatePopup ' +
        'GUICtrlMenu_DeleteMenu GUICtrlMenu_DestroyMenu ' +
        'GUICtrlMenu_DrawMenuBar GUICtrlMenu_EnableMenuItem ' +
        'GUICtrlMenu_FindItem GUICtrlMenu_FindParent ' +
        'GUICtrlMenu_GetItemBmp GUICtrlMenu_GetItemBmpChecked ' +
        'GUICtrlMenu_GetItemBmpUnchecked GUICtrlMenu_GetItemChecked ' +
        'GUICtrlMenu_GetItemCount GUICtrlMenu_GetItemData ' +
        'GUICtrlMenu_GetItemDefault GUICtrlMenu_GetItemDisabled ' +
        'GUICtrlMenu_GetItemEnabled GUICtrlMenu_GetItemGrayed ' +
        'GUICtrlMenu_GetItemHighlighted GUICtrlMenu_GetItemID ' +
        'GUICtrlMenu_GetItemInfo GUICtrlMenu_GetItemRect ' +
        'GUICtrlMenu_GetItemRectEx GUICtrlMenu_GetItemState ' +
        'GUICtrlMenu_GetItemStateEx GUICtrlMenu_GetItemSubMenu ' +
        'GUICtrlMenu_GetItemText GUICtrlMenu_GetItemType ' +
        'GUICtrlMenu_GetMenu GUICtrlMenu_GetMenuBackground ' +
        'GUICtrlMenu_GetMenuBarInfo GUICtrlMenu_GetMenuContextHelpID ' +
        'GUICtrlMenu_GetMenuData GUICtrlMenu_GetMenuDefaultItem ' +
        'GUICtrlMenu_GetMenuHeight GUICtrlMenu_GetMenuInfo ' +
        'GUICtrlMenu_GetMenuStyle GUICtrlMenu_GetSystemMenu ' +
        'GUICtrlMenu_InsertMenuItem GUICtrlMenu_InsertMenuItemEx ' +
        'GUICtrlMenu_IsMenu GUICtrlMenu_LoadMenu ' +
        'GUICtrlMenu_MapAccelerator GUICtrlMenu_MenuItemFromPoint ' +
        'GUICtrlMenu_RemoveMenu GUICtrlMenu_SetItemBitmaps ' +
        'GUICtrlMenu_SetItemBmp GUICtrlMenu_SetItemBmpChecked ' +
        'GUICtrlMenu_SetItemBmpUnchecked GUICtrlMenu_SetItemChecked ' +
        'GUICtrlMenu_SetItemData GUICtrlMenu_SetItemDefault ' +
        'GUICtrlMenu_SetItemDisabled GUICtrlMenu_SetItemEnabled ' +
        'GUICtrlMenu_SetItemGrayed GUICtrlMenu_SetItemHighlighted ' +
        'GUICtrlMenu_SetItemID GUICtrlMenu_SetItemInfo ' +
        'GUICtrlMenu_SetItemState GUICtrlMenu_SetItemSubMenu ' +
        'GUICtrlMenu_SetItemText GUICtrlMenu_SetItemType ' +
        'GUICtrlMenu_SetMenu GUICtrlMenu_SetMenuBackground ' +
        'GUICtrlMenu_SetMenuContextHelpID GUICtrlMenu_SetMenuData ' +
        'GUICtrlMenu_SetMenuDefaultItem GUICtrlMenu_SetMenuHeight ' +
        'GUICtrlMenu_SetMenuInfo GUICtrlMenu_SetMenuStyle ' +
        'GUICtrlMenu_TrackPopupMenu GUICtrlMonthCal_Create ' +
        'GUICtrlMonthCal_Destroy GUICtrlMonthCal_GetCalendarBorder ' +
        'GUICtrlMonthCal_GetCalendarCount GUICtrlMonthCal_GetColor ' +
        'GUICtrlMonthCal_GetColorArray GUICtrlMonthCal_GetCurSel ' +
        'GUICtrlMonthCal_GetCurSelStr GUICtrlMonthCal_GetFirstDOW ' +
        'GUICtrlMonthCal_GetFirstDOWStr GUICtrlMonthCal_GetMaxSelCount ' +
        'GUICtrlMonthCal_GetMaxTodayWidth ' +
        'GUICtrlMonthCal_GetMinReqHeight GUICtrlMonthCal_GetMinReqRect ' +
        'GUICtrlMonthCal_GetMinReqRectArray ' +
        'GUICtrlMonthCal_GetMinReqWidth GUICtrlMonthCal_GetMonthDelta ' +
        'GUICtrlMonthCal_GetMonthRange GUICtrlMonthCal_GetMonthRangeMax ' +
        'GUICtrlMonthCal_GetMonthRangeMaxStr ' +
        'GUICtrlMonthCal_GetMonthRangeMin ' +
        'GUICtrlMonthCal_GetMonthRangeMinStr ' +
        'GUICtrlMonthCal_GetMonthRangeSpan GUICtrlMonthCal_GetRange ' +
        'GUICtrlMonthCal_GetRangeMax GUICtrlMonthCal_GetRangeMaxStr ' +
        'GUICtrlMonthCal_GetRangeMin GUICtrlMonthCal_GetRangeMinStr ' +
        'GUICtrlMonthCal_GetSelRange GUICtrlMonthCal_GetSelRangeMax ' +
        'GUICtrlMonthCal_GetSelRangeMaxStr ' +
        'GUICtrlMonthCal_GetSelRangeMin ' +
        'GUICtrlMonthCal_GetSelRangeMinStr GUICtrlMonthCal_GetToday ' +
        'GUICtrlMonthCal_GetTodayStr GUICtrlMonthCal_GetUnicodeFormat ' +
        'GUICtrlMonthCal_HitTest GUICtrlMonthCal_SetCalendarBorder ' +
        'GUICtrlMonthCal_SetColor GUICtrlMonthCal_SetCurSel ' +
        'GUICtrlMonthCal_SetDayState GUICtrlMonthCal_SetFirstDOW ' +
        'GUICtrlMonthCal_SetMaxSelCount GUICtrlMonthCal_SetMonthDelta ' +
        'GUICtrlMonthCal_SetRange GUICtrlMonthCal_SetSelRange ' +
        'GUICtrlMonthCal_SetToday GUICtrlMonthCal_SetUnicodeFormat ' +
        'GUICtrlRebar_AddBand GUICtrlRebar_AddToolBarBand ' +
        'GUICtrlRebar_BeginDrag GUICtrlRebar_Create ' +
        'GUICtrlRebar_DeleteBand GUICtrlRebar_Destroy ' +
        'GUICtrlRebar_DragMove GUICtrlRebar_EndDrag ' +
        'GUICtrlRebar_GetBandBackColor GUICtrlRebar_GetBandBorders ' +
        'GUICtrlRebar_GetBandBordersEx GUICtrlRebar_GetBandChildHandle ' +
        'GUICtrlRebar_GetBandChildSize GUICtrlRebar_GetBandCount ' +
        'GUICtrlRebar_GetBandForeColor GUICtrlRebar_GetBandHeaderSize ' +
        'GUICtrlRebar_GetBandID GUICtrlRebar_GetBandIdealSize ' +
        'GUICtrlRebar_GetBandLength GUICtrlRebar_GetBandLParam ' +
        'GUICtrlRebar_GetBandMargins GUICtrlRebar_GetBandMarginsEx ' +
        'GUICtrlRebar_GetBandRect GUICtrlRebar_GetBandRectEx ' +
        'GUICtrlRebar_GetBandStyle GUICtrlRebar_GetBandStyleBreak ' +
        'GUICtrlRebar_GetBandStyleChildEdge ' +
        'GUICtrlRebar_GetBandStyleFixedBMP ' +
        'GUICtrlRebar_GetBandStyleFixedSize ' +
        'GUICtrlRebar_GetBandStyleGripperAlways ' +
        'GUICtrlRebar_GetBandStyleHidden ' +
        'GUICtrlRebar_GetBandStyleHideTitle ' +
        'GUICtrlRebar_GetBandStyleNoGripper ' +
        'GUICtrlRebar_GetBandStyleTopAlign ' +
        'GUICtrlRebar_GetBandStyleUseChevron ' +
        'GUICtrlRebar_GetBandStyleVariableHeight ' +
        'GUICtrlRebar_GetBandText GUICtrlRebar_GetBarHeight ' +
        'GUICtrlRebar_GetBarInfo GUICtrlRebar_GetBKColor ' +
        'GUICtrlRebar_GetColorScheme GUICtrlRebar_GetRowCount ' +
        'GUICtrlRebar_GetRowHeight GUICtrlRebar_GetTextColor ' +
        'GUICtrlRebar_GetToolTips GUICtrlRebar_GetUnicodeFormat ' +
        'GUICtrlRebar_HitTest GUICtrlRebar_IDToIndex ' +
        'GUICtrlRebar_MaximizeBand GUICtrlRebar_MinimizeBand ' +
        'GUICtrlRebar_MoveBand GUICtrlRebar_SetBandBackColor ' +
        'GUICtrlRebar_SetBandForeColor GUICtrlRebar_SetBandHeaderSize ' +
        'GUICtrlRebar_SetBandID GUICtrlRebar_SetBandIdealSize ' +
        'GUICtrlRebar_SetBandLength GUICtrlRebar_SetBandLParam ' +
        'GUICtrlRebar_SetBandStyle GUICtrlRebar_SetBandStyleBreak ' +
        'GUICtrlRebar_SetBandStyleChildEdge ' +
        'GUICtrlRebar_SetBandStyleFixedBMP ' +
        'GUICtrlRebar_SetBandStyleFixedSize ' +
        'GUICtrlRebar_SetBandStyleGripperAlways ' +
        'GUICtrlRebar_SetBandStyleHidden ' +
        'GUICtrlRebar_SetBandStyleHideTitle ' +
        'GUICtrlRebar_SetBandStyleNoGripper ' +
        'GUICtrlRebar_SetBandStyleTopAlign ' +
        'GUICtrlRebar_SetBandStyleUseChevron ' +
        'GUICtrlRebar_SetBandStyleVariableHeight ' +
        'GUICtrlRebar_SetBandText GUICtrlRebar_SetBarInfo ' +
        'GUICtrlRebar_SetBKColor GUICtrlRebar_SetColorScheme ' +
        'GUICtrlRebar_SetTextColor GUICtrlRebar_SetToolTips ' +
        'GUICtrlRebar_SetUnicodeFormat GUICtrlRebar_ShowBand ' +
        'GUICtrlRichEdit_AppendText GUICtrlRichEdit_AutoDetectURL ' +
        'GUICtrlRichEdit_CanPaste GUICtrlRichEdit_CanPasteSpecial ' +
        'GUICtrlRichEdit_CanRedo GUICtrlRichEdit_CanUndo ' +
        'GUICtrlRichEdit_ChangeFontSize GUICtrlRichEdit_Copy ' +
        'GUICtrlRichEdit_Create GUICtrlRichEdit_Cut ' +
        'GUICtrlRichEdit_Deselect GUICtrlRichEdit_Destroy ' +
        'GUICtrlRichEdit_EmptyUndoBuffer GUICtrlRichEdit_FindText ' +
        'GUICtrlRichEdit_FindTextInRange GUICtrlRichEdit_GetBkColor ' +
        'GUICtrlRichEdit_GetCharAttributes ' +
        'GUICtrlRichEdit_GetCharBkColor GUICtrlRichEdit_GetCharColor ' +
        'GUICtrlRichEdit_GetCharPosFromXY ' +
        'GUICtrlRichEdit_GetCharPosOfNextWord ' +
        'GUICtrlRichEdit_GetCharPosOfPreviousWord ' +
        'GUICtrlRichEdit_GetCharWordBreakInfo ' +
        'GUICtrlRichEdit_GetFirstCharPosOnLine GUICtrlRichEdit_GetFont ' +
        'GUICtrlRichEdit_GetLineCount GUICtrlRichEdit_GetLineLength ' +
        'GUICtrlRichEdit_GetLineNumberFromCharPos ' +
        'GUICtrlRichEdit_GetNextRedo GUICtrlRichEdit_GetNextUndo ' +
        'GUICtrlRichEdit_GetNumberOfFirstVisibleLine ' +
        'GUICtrlRichEdit_GetParaAlignment ' +
        'GUICtrlRichEdit_GetParaAttributes GUICtrlRichEdit_GetParaBorder ' +
        'GUICtrlRichEdit_GetParaIndents GUICtrlRichEdit_GetParaNumbering ' +
        'GUICtrlRichEdit_GetParaShading GUICtrlRichEdit_GetParaSpacing ' +
        'GUICtrlRichEdit_GetParaTabStops GUICtrlRichEdit_GetPasswordChar ' +
        'GUICtrlRichEdit_GetRECT GUICtrlRichEdit_GetScrollPos ' +
        'GUICtrlRichEdit_GetSel GUICtrlRichEdit_GetSelAA ' +
        'GUICtrlRichEdit_GetSelText GUICtrlRichEdit_GetSpaceUnit ' +
        'GUICtrlRichEdit_GetText GUICtrlRichEdit_GetTextInLine ' +
        'GUICtrlRichEdit_GetTextInRange GUICtrlRichEdit_GetTextLength ' +
        'GUICtrlRichEdit_GetVersion GUICtrlRichEdit_GetXYFromCharPos ' +
        'GUICtrlRichEdit_GetZoom GUICtrlRichEdit_GotoCharPos ' +
        'GUICtrlRichEdit_HideSelection GUICtrlRichEdit_InsertText ' +
        'GUICtrlRichEdit_IsModified GUICtrlRichEdit_IsTextSelected ' +
        'GUICtrlRichEdit_Paste GUICtrlRichEdit_PasteSpecial ' +
        'GUICtrlRichEdit_PauseRedraw GUICtrlRichEdit_Redo ' +
        'GUICtrlRichEdit_ReplaceText GUICtrlRichEdit_ResumeRedraw ' +
        'GUICtrlRichEdit_ScrollLineOrPage GUICtrlRichEdit_ScrollLines ' +
        'GUICtrlRichEdit_ScrollToCaret GUICtrlRichEdit_SetBkColor ' +
        'GUICtrlRichEdit_SetCharAttributes ' +
        'GUICtrlRichEdit_SetCharBkColor GUICtrlRichEdit_SetCharColor ' +
        'GUICtrlRichEdit_SetEventMask GUICtrlRichEdit_SetFont ' +
        'GUICtrlRichEdit_SetLimitOnText GUICtrlRichEdit_SetModified ' +
        'GUICtrlRichEdit_SetParaAlignment ' +
        'GUICtrlRichEdit_SetParaAttributes GUICtrlRichEdit_SetParaBorder ' +
        'GUICtrlRichEdit_SetParaIndents GUICtrlRichEdit_SetParaNumbering ' +
        'GUICtrlRichEdit_SetParaShading GUICtrlRichEdit_SetParaSpacing ' +
        'GUICtrlRichEdit_SetParaTabStops GUICtrlRichEdit_SetPasswordChar ' +
        'GUICtrlRichEdit_SetReadOnly GUICtrlRichEdit_SetRECT ' +
        'GUICtrlRichEdit_SetScrollPos GUICtrlRichEdit_SetSel ' +
        'GUICtrlRichEdit_SetSpaceUnit GUICtrlRichEdit_SetTabStops ' +
        'GUICtrlRichEdit_SetText GUICtrlRichEdit_SetUndoLimit ' +
        'GUICtrlRichEdit_SetZoom GUICtrlRichEdit_StreamFromFile ' +
        'GUICtrlRichEdit_StreamFromVar GUICtrlRichEdit_StreamToFile ' +
        'GUICtrlRichEdit_StreamToVar GUICtrlRichEdit_Undo ' +
        'GUICtrlSlider_ClearSel GUICtrlSlider_ClearTics ' +
        'GUICtrlSlider_Create GUICtrlSlider_Destroy ' +
        'GUICtrlSlider_GetBuddy GUICtrlSlider_GetChannelRect ' +
        'GUICtrlSlider_GetChannelRectEx GUICtrlSlider_GetLineSize ' +
        'GUICtrlSlider_GetLogicalTics GUICtrlSlider_GetNumTics ' +
        'GUICtrlSlider_GetPageSize GUICtrlSlider_GetPos ' +
        'GUICtrlSlider_GetRange GUICtrlSlider_GetRangeMax ' +
        'GUICtrlSlider_GetRangeMin GUICtrlSlider_GetSel ' +
        'GUICtrlSlider_GetSelEnd GUICtrlSlider_GetSelStart ' +
        'GUICtrlSlider_GetThumbLength GUICtrlSlider_GetThumbRect ' +
        'GUICtrlSlider_GetThumbRectEx GUICtrlSlider_GetTic ' +
        'GUICtrlSlider_GetTicPos GUICtrlSlider_GetToolTips ' +
        'GUICtrlSlider_GetUnicodeFormat GUICtrlSlider_SetBuddy ' +
        'GUICtrlSlider_SetLineSize GUICtrlSlider_SetPageSize ' +
        'GUICtrlSlider_SetPos GUICtrlSlider_SetRange ' +
        'GUICtrlSlider_SetRangeMax GUICtrlSlider_SetRangeMin ' +
        'GUICtrlSlider_SetSel GUICtrlSlider_SetSelEnd ' +
        'GUICtrlSlider_SetSelStart GUICtrlSlider_SetThumbLength ' +
        'GUICtrlSlider_SetTic GUICtrlSlider_SetTicFreq ' +
        'GUICtrlSlider_SetTipSide GUICtrlSlider_SetToolTips ' +
        'GUICtrlSlider_SetUnicodeFormat GUICtrlStatusBar_Create ' +
        'GUICtrlStatusBar_Destroy GUICtrlStatusBar_EmbedControl ' +
        'GUICtrlStatusBar_GetBorders GUICtrlStatusBar_GetBordersHorz ' +
        'GUICtrlStatusBar_GetBordersRect GUICtrlStatusBar_GetBordersVert ' +
        'GUICtrlStatusBar_GetCount GUICtrlStatusBar_GetHeight ' +
        'GUICtrlStatusBar_GetIcon GUICtrlStatusBar_GetParts ' +
        'GUICtrlStatusBar_GetRect GUICtrlStatusBar_GetRectEx ' +
        'GUICtrlStatusBar_GetText GUICtrlStatusBar_GetTextFlags ' +
        'GUICtrlStatusBar_GetTextLength GUICtrlStatusBar_GetTextLengthEx ' +
        'GUICtrlStatusBar_GetTipText GUICtrlStatusBar_GetUnicodeFormat ' +
        'GUICtrlStatusBar_GetWidth GUICtrlStatusBar_IsSimple ' +
        'GUICtrlStatusBar_Resize GUICtrlStatusBar_SetBkColor ' +
        'GUICtrlStatusBar_SetIcon GUICtrlStatusBar_SetMinHeight ' +
        'GUICtrlStatusBar_SetParts GUICtrlStatusBar_SetSimple ' +
        'GUICtrlStatusBar_SetText GUICtrlStatusBar_SetTipText ' +
        'GUICtrlStatusBar_SetUnicodeFormat GUICtrlStatusBar_ShowHide ' +
        'GUICtrlTab_ActivateTab GUICtrlTab_ClickTab GUICtrlTab_Create ' +
        'GUICtrlTab_DeleteAllItems GUICtrlTab_DeleteItem ' +
        'GUICtrlTab_DeselectAll GUICtrlTab_Destroy GUICtrlTab_FindTab ' +
        'GUICtrlTab_GetCurFocus GUICtrlTab_GetCurSel ' +
        'GUICtrlTab_GetDisplayRect GUICtrlTab_GetDisplayRectEx ' +
        'GUICtrlTab_GetExtendedStyle GUICtrlTab_GetImageList ' +
        'GUICtrlTab_GetItem GUICtrlTab_GetItemCount ' +
        'GUICtrlTab_GetItemImage GUICtrlTab_GetItemParam ' +
        'GUICtrlTab_GetItemRect GUICtrlTab_GetItemRectEx ' +
        'GUICtrlTab_GetItemState GUICtrlTab_GetItemText ' +
        'GUICtrlTab_GetRowCount GUICtrlTab_GetToolTips ' +
        'GUICtrlTab_GetUnicodeFormat GUICtrlTab_HighlightItem ' +
        'GUICtrlTab_HitTest GUICtrlTab_InsertItem ' +
        'GUICtrlTab_RemoveImage GUICtrlTab_SetCurFocus ' +
        'GUICtrlTab_SetCurSel GUICtrlTab_SetExtendedStyle ' +
        'GUICtrlTab_SetImageList GUICtrlTab_SetItem ' +
        'GUICtrlTab_SetItemImage GUICtrlTab_SetItemParam ' +
        'GUICtrlTab_SetItemSize GUICtrlTab_SetItemState ' +
        'GUICtrlTab_SetItemText GUICtrlTab_SetMinTabWidth ' +
        'GUICtrlTab_SetPadding GUICtrlTab_SetToolTips ' +
        'GUICtrlTab_SetUnicodeFormat GUICtrlToolbar_AddBitmap ' +
        'GUICtrlToolbar_AddButton GUICtrlToolbar_AddButtonSep ' +
        'GUICtrlToolbar_AddString GUICtrlToolbar_ButtonCount ' +
        'GUICtrlToolbar_CheckButton GUICtrlToolbar_ClickAccel ' +
        'GUICtrlToolbar_ClickButton GUICtrlToolbar_ClickIndex ' +
        'GUICtrlToolbar_CommandToIndex GUICtrlToolbar_Create ' +
        'GUICtrlToolbar_Customize GUICtrlToolbar_DeleteButton ' +
        'GUICtrlToolbar_Destroy GUICtrlToolbar_EnableButton ' +
        'GUICtrlToolbar_FindToolbar GUICtrlToolbar_GetAnchorHighlight ' +
        'GUICtrlToolbar_GetBitmapFlags GUICtrlToolbar_GetButtonBitmap ' +
        'GUICtrlToolbar_GetButtonInfo GUICtrlToolbar_GetButtonInfoEx ' +
        'GUICtrlToolbar_GetButtonParam GUICtrlToolbar_GetButtonRect ' +
        'GUICtrlToolbar_GetButtonRectEx GUICtrlToolbar_GetButtonSize ' +
        'GUICtrlToolbar_GetButtonState GUICtrlToolbar_GetButtonStyle ' +
        'GUICtrlToolbar_GetButtonText GUICtrlToolbar_GetColorScheme ' +
        'GUICtrlToolbar_GetDisabledImageList ' +
        'GUICtrlToolbar_GetExtendedStyle GUICtrlToolbar_GetHotImageList ' +
        'GUICtrlToolbar_GetHotItem GUICtrlToolbar_GetImageList ' +
        'GUICtrlToolbar_GetInsertMark GUICtrlToolbar_GetInsertMarkColor ' +
        'GUICtrlToolbar_GetMaxSize GUICtrlToolbar_GetMetrics ' +
        'GUICtrlToolbar_GetPadding GUICtrlToolbar_GetRows ' +
        'GUICtrlToolbar_GetString GUICtrlToolbar_GetStyle ' +
        'GUICtrlToolbar_GetStyleAltDrag ' +
        'GUICtrlToolbar_GetStyleCustomErase GUICtrlToolbar_GetStyleFlat ' +
        'GUICtrlToolbar_GetStyleList GUICtrlToolbar_GetStyleRegisterDrop ' +
        'GUICtrlToolbar_GetStyleToolTips ' +
        'GUICtrlToolbar_GetStyleTransparent ' +
        'GUICtrlToolbar_GetStyleWrapable GUICtrlToolbar_GetTextRows ' +
        'GUICtrlToolbar_GetToolTips GUICtrlToolbar_GetUnicodeFormat ' +
        'GUICtrlToolbar_HideButton GUICtrlToolbar_HighlightButton ' +
        'GUICtrlToolbar_HitTest GUICtrlToolbar_IndexToCommand ' +
        'GUICtrlToolbar_InsertButton GUICtrlToolbar_InsertMarkHitTest ' +
        'GUICtrlToolbar_IsButtonChecked GUICtrlToolbar_IsButtonEnabled ' +
        'GUICtrlToolbar_IsButtonHidden ' +
        'GUICtrlToolbar_IsButtonHighlighted ' +
        'GUICtrlToolbar_IsButtonIndeterminate ' +
        'GUICtrlToolbar_IsButtonPressed GUICtrlToolbar_LoadBitmap ' +
        'GUICtrlToolbar_LoadImages GUICtrlToolbar_MapAccelerator ' +
        'GUICtrlToolbar_MoveButton GUICtrlToolbar_PressButton ' +
        'GUICtrlToolbar_SetAnchorHighlight GUICtrlToolbar_SetBitmapSize ' +
        'GUICtrlToolbar_SetButtonBitMap GUICtrlToolbar_SetButtonInfo ' +
        'GUICtrlToolbar_SetButtonInfoEx GUICtrlToolbar_SetButtonParam ' +
        'GUICtrlToolbar_SetButtonSize GUICtrlToolbar_SetButtonState ' +
        'GUICtrlToolbar_SetButtonStyle GUICtrlToolbar_SetButtonText ' +
        'GUICtrlToolbar_SetButtonWidth GUICtrlToolbar_SetCmdID ' +
        'GUICtrlToolbar_SetColorScheme ' +
        'GUICtrlToolbar_SetDisabledImageList ' +
        'GUICtrlToolbar_SetDrawTextFlags GUICtrlToolbar_SetExtendedStyle ' +
        'GUICtrlToolbar_SetHotImageList GUICtrlToolbar_SetHotItem ' +
        'GUICtrlToolbar_SetImageList GUICtrlToolbar_SetIndent ' +
        'GUICtrlToolbar_SetIndeterminate GUICtrlToolbar_SetInsertMark ' +
        'GUICtrlToolbar_SetInsertMarkColor GUICtrlToolbar_SetMaxTextRows ' +
        'GUICtrlToolbar_SetMetrics GUICtrlToolbar_SetPadding ' +
        'GUICtrlToolbar_SetParent GUICtrlToolbar_SetRows ' +
        'GUICtrlToolbar_SetStyle GUICtrlToolbar_SetStyleAltDrag ' +
        'GUICtrlToolbar_SetStyleCustomErase GUICtrlToolbar_SetStyleFlat ' +
        'GUICtrlToolbar_SetStyleList GUICtrlToolbar_SetStyleRegisterDrop ' +
        'GUICtrlToolbar_SetStyleToolTips ' +
        'GUICtrlToolbar_SetStyleTransparent ' +
        'GUICtrlToolbar_SetStyleWrapable GUICtrlToolbar_SetToolTips ' +
        'GUICtrlToolbar_SetUnicodeFormat GUICtrlToolbar_SetWindowTheme ' +
        'GUICtrlTreeView_Add GUICtrlTreeView_AddChild ' +
        'GUICtrlTreeView_AddChildFirst GUICtrlTreeView_AddFirst ' +
        'GUICtrlTreeView_BeginUpdate GUICtrlTreeView_ClickItem ' +
        'GUICtrlTreeView_Create GUICtrlTreeView_CreateDragImage ' +
        'GUICtrlTreeView_CreateSolidBitMap GUICtrlTreeView_Delete ' +
        'GUICtrlTreeView_DeleteAll GUICtrlTreeView_DeleteChildren ' +
        'GUICtrlTreeView_Destroy GUICtrlTreeView_DisplayRect ' +
        'GUICtrlTreeView_DisplayRectEx GUICtrlTreeView_EditText ' +
        'GUICtrlTreeView_EndEdit GUICtrlTreeView_EndUpdate ' +
        'GUICtrlTreeView_EnsureVisible GUICtrlTreeView_Expand ' +
        'GUICtrlTreeView_ExpandedOnce GUICtrlTreeView_FindItem ' +
        'GUICtrlTreeView_FindItemEx GUICtrlTreeView_GetBkColor ' +
        'GUICtrlTreeView_GetBold GUICtrlTreeView_GetChecked ' +
        'GUICtrlTreeView_GetChildCount GUICtrlTreeView_GetChildren ' +
        'GUICtrlTreeView_GetCount GUICtrlTreeView_GetCut ' +
        'GUICtrlTreeView_GetDropTarget GUICtrlTreeView_GetEditControl ' +
        'GUICtrlTreeView_GetExpanded GUICtrlTreeView_GetFirstChild ' +
        'GUICtrlTreeView_GetFirstItem GUICtrlTreeView_GetFirstVisible ' +
        'GUICtrlTreeView_GetFocused GUICtrlTreeView_GetHeight ' +
        'GUICtrlTreeView_GetImageIndex ' +
        'GUICtrlTreeView_GetImageListIconHandle ' +
        'GUICtrlTreeView_GetIndent GUICtrlTreeView_GetInsertMarkColor ' +
        'GUICtrlTreeView_GetISearchString GUICtrlTreeView_GetItemByIndex ' +
        'GUICtrlTreeView_GetItemHandle GUICtrlTreeView_GetItemParam ' +
        'GUICtrlTreeView_GetLastChild GUICtrlTreeView_GetLineColor ' +
        'GUICtrlTreeView_GetNext GUICtrlTreeView_GetNextChild ' +
        'GUICtrlTreeView_GetNextSibling GUICtrlTreeView_GetNextVisible ' +
        'GUICtrlTreeView_GetNormalImageList ' +
        'GUICtrlTreeView_GetParentHandle GUICtrlTreeView_GetParentParam ' +
        'GUICtrlTreeView_GetPrev GUICtrlTreeView_GetPrevChild ' +
        'GUICtrlTreeView_GetPrevSibling GUICtrlTreeView_GetPrevVisible ' +
        'GUICtrlTreeView_GetScrollTime GUICtrlTreeView_GetSelected ' +
        'GUICtrlTreeView_GetSelectedImageIndex ' +
        'GUICtrlTreeView_GetSelection GUICtrlTreeView_GetSiblingCount ' +
        'GUICtrlTreeView_GetState GUICtrlTreeView_GetStateImageIndex ' +
        'GUICtrlTreeView_GetStateImageList GUICtrlTreeView_GetText ' +
        'GUICtrlTreeView_GetTextColor GUICtrlTreeView_GetToolTips ' +
        'GUICtrlTreeView_GetTree GUICtrlTreeView_GetUnicodeFormat ' +
        'GUICtrlTreeView_GetVisible GUICtrlTreeView_GetVisibleCount ' +
        'GUICtrlTreeView_HitTest GUICtrlTreeView_HitTestEx ' +
        'GUICtrlTreeView_HitTestItem GUICtrlTreeView_Index ' +
        'GUICtrlTreeView_InsertItem GUICtrlTreeView_IsFirstItem ' +
        'GUICtrlTreeView_IsParent GUICtrlTreeView_Level ' +
        'GUICtrlTreeView_SelectItem GUICtrlTreeView_SelectItemByIndex ' +
        'GUICtrlTreeView_SetBkColor GUICtrlTreeView_SetBold ' +
        'GUICtrlTreeView_SetChecked GUICtrlTreeView_SetCheckedByIndex ' +
        'GUICtrlTreeView_SetChildren GUICtrlTreeView_SetCut ' +
        'GUICtrlTreeView_SetDropTarget GUICtrlTreeView_SetFocused ' +
        'GUICtrlTreeView_SetHeight GUICtrlTreeView_SetIcon ' +
        'GUICtrlTreeView_SetImageIndex GUICtrlTreeView_SetIndent ' +
        'GUICtrlTreeView_SetInsertMark ' +
        'GUICtrlTreeView_SetInsertMarkColor ' +
        'GUICtrlTreeView_SetItemHeight GUICtrlTreeView_SetItemParam ' +
        'GUICtrlTreeView_SetLineColor GUICtrlTreeView_SetNormalImageList ' +
        'GUICtrlTreeView_SetScrollTime GUICtrlTreeView_SetSelected ' +
        'GUICtrlTreeView_SetSelectedImageIndex GUICtrlTreeView_SetState ' +
        'GUICtrlTreeView_SetStateImageIndex ' +
        'GUICtrlTreeView_SetStateImageList GUICtrlTreeView_SetText ' +
        'GUICtrlTreeView_SetTextColor GUICtrlTreeView_SetToolTips ' +
        'GUICtrlTreeView_SetUnicodeFormat GUICtrlTreeView_Sort ' +
        'GUIImageList_Add GUIImageList_AddBitmap GUIImageList_AddIcon ' +
        'GUIImageList_AddMasked GUIImageList_BeginDrag ' +
        'GUIImageList_Copy GUIImageList_Create GUIImageList_Destroy ' +
        'GUIImageList_DestroyIcon GUIImageList_DragEnter ' +
        'GUIImageList_DragLeave GUIImageList_DragMove ' +
        'GUIImageList_Draw GUIImageList_DrawEx GUIImageList_Duplicate ' +
        'GUIImageList_EndDrag GUIImageList_GetBkColor ' +
        'GUIImageList_GetIcon GUIImageList_GetIconHeight ' +
        'GUIImageList_GetIconSize GUIImageList_GetIconSizeEx ' +
        'GUIImageList_GetIconWidth GUIImageList_GetImageCount ' +
        'GUIImageList_GetImageInfoEx GUIImageList_Remove ' +
        'GUIImageList_ReplaceIcon GUIImageList_SetBkColor ' +
        'GUIImageList_SetIconSize GUIImageList_SetImageCount ' +
        'GUIImageList_Swap GUIScrollBars_EnableScrollBar ' +
        'GUIScrollBars_GetScrollBarInfoEx GUIScrollBars_GetScrollBarRect ' +
        'GUIScrollBars_GetScrollBarRGState ' +
        'GUIScrollBars_GetScrollBarXYLineButton ' +
        'GUIScrollBars_GetScrollBarXYThumbBottom ' +
        'GUIScrollBars_GetScrollBarXYThumbTop ' +
        'GUIScrollBars_GetScrollInfo GUIScrollBars_GetScrollInfoEx ' +
        'GUIScrollBars_GetScrollInfoMax GUIScrollBars_GetScrollInfoMin ' +
        'GUIScrollBars_GetScrollInfoPage GUIScrollBars_GetScrollInfoPos ' +
        'GUIScrollBars_GetScrollInfoTrackPos GUIScrollBars_GetScrollPos ' +
        'GUIScrollBars_GetScrollRange GUIScrollBars_Init ' +
        'GUIScrollBars_ScrollWindow GUIScrollBars_SetScrollInfo ' +
        'GUIScrollBars_SetScrollInfoMax GUIScrollBars_SetScrollInfoMin ' +
        'GUIScrollBars_SetScrollInfoPage GUIScrollBars_SetScrollInfoPos ' +
        'GUIScrollBars_SetScrollRange GUIScrollBars_ShowScrollBar ' +
        'GUIToolTip_Activate GUIToolTip_AddTool GUIToolTip_AdjustRect ' +
        'GUIToolTip_BitsToTTF GUIToolTip_Create GUIToolTip_Deactivate ' +
        'GUIToolTip_DelTool GUIToolTip_Destroy GUIToolTip_EnumTools ' +
        'GUIToolTip_GetBubbleHeight GUIToolTip_GetBubbleSize ' +
        'GUIToolTip_GetBubbleWidth GUIToolTip_GetCurrentTool ' +
        'GUIToolTip_GetDelayTime GUIToolTip_GetMargin ' +
        'GUIToolTip_GetMarginEx GUIToolTip_GetMaxTipWidth ' +
        'GUIToolTip_GetText GUIToolTip_GetTipBkColor ' +
        'GUIToolTip_GetTipTextColor GUIToolTip_GetTitleBitMap ' +
        'GUIToolTip_GetTitleText GUIToolTip_GetToolCount ' +
        'GUIToolTip_GetToolInfo GUIToolTip_HitTest ' +
        'GUIToolTip_NewToolRect GUIToolTip_Pop GUIToolTip_PopUp ' +
        'GUIToolTip_SetDelayTime GUIToolTip_SetMargin ' +
        'GUIToolTip_SetMaxTipWidth GUIToolTip_SetTipBkColor ' +
        'GUIToolTip_SetTipTextColor GUIToolTip_SetTitle ' +
        'GUIToolTip_SetToolInfo GUIToolTip_SetWindowTheme ' +
        'GUIToolTip_ToolExists GUIToolTip_ToolToArray ' +
        'GUIToolTip_TrackActivate GUIToolTip_TrackPosition ' +
        'GUIToolTip_Update GUIToolTip_UpdateTipText HexToString ' +
        'IEAction IEAttach IEBodyReadHTML IEBodyReadText ' +
        'IEBodyWriteHTML IECreate IECreateEmbedded IEDocGetObj ' +
        'IEDocInsertHTML IEDocInsertText IEDocReadHTML ' +
        'IEDocWriteHTML IEErrorNotify IEFormElementCheckBoxSelect ' +
        'IEFormElementGetCollection IEFormElementGetObjByName ' +
        'IEFormElementGetValue IEFormElementOptionSelect ' +
        'IEFormElementRadioSelect IEFormElementSetValue ' +
        'IEFormGetCollection IEFormGetObjByName IEFormImageClick ' +
        'IEFormReset IEFormSubmit IEFrameGetCollection ' +
        'IEFrameGetObjByName IEGetObjById IEGetObjByName ' +
        'IEHeadInsertEventScript IEImgClick IEImgGetCollection ' +
        'IEIsFrameSet IELinkClickByIndex IELinkClickByText ' +
        'IELinkGetCollection IELoadWait IELoadWaitTimeout IENavigate ' +
        'IEPropertyGet IEPropertySet IEQuit IETableGetCollection ' +
        'IETableWriteToArray IETagNameAllGetCollection ' +
        'IETagNameGetCollection IE_Example IE_Introduction ' +
        'IE_VersionInfo INetExplorerCapable INetGetSource INetMail ' +
        'INetSmtpMail IsPressed MathCheckDiv Max MemGlobalAlloc ' +
        'MemGlobalFree MemGlobalLock MemGlobalSize MemGlobalUnlock ' +
        'MemMoveMemory MemVirtualAlloc MemVirtualAllocEx ' +
        'MemVirtualFree MemVirtualFreeEx Min MouseTrap ' +
        'NamedPipes_CallNamedPipe NamedPipes_ConnectNamedPipe ' +
        'NamedPipes_CreateNamedPipe NamedPipes_CreatePipe ' +
        'NamedPipes_DisconnectNamedPipe ' +
        'NamedPipes_GetNamedPipeHandleState NamedPipes_GetNamedPipeInfo ' +
        'NamedPipes_PeekNamedPipe NamedPipes_SetNamedPipeHandleState ' +
        'NamedPipes_TransactNamedPipe NamedPipes_WaitNamedPipe ' +
        'Net_Share_ConnectionEnum Net_Share_FileClose ' +
        'Net_Share_FileEnum Net_Share_FileGetInfo Net_Share_PermStr ' +
        'Net_Share_ResourceStr Net_Share_SessionDel ' +
        'Net_Share_SessionEnum Net_Share_SessionGetInfo ' +
        'Net_Share_ShareAdd Net_Share_ShareCheck Net_Share_ShareDel ' +
        'Net_Share_ShareEnum Net_Share_ShareGetInfo ' +
        'Net_Share_ShareSetInfo Net_Share_StatisticsGetSvr ' +
        'Net_Share_StatisticsGetWrk Now NowCalc NowCalcDate ' +
        'NowDate NowTime PathFull PathGetRelative PathMake ' +
        'PathSplit ProcessGetName ProcessGetPriority Radian ' +
        'ReplaceStringInFile RunDos ScreenCapture_Capture ' +
        'ScreenCapture_CaptureWnd ScreenCapture_SaveImage ' +
        'ScreenCapture_SetBMPFormat ScreenCapture_SetJPGQuality ' +
        'ScreenCapture_SetTIFColorDepth ScreenCapture_SetTIFCompression ' +
        'Security__AdjustTokenPrivileges ' +
        'Security__CreateProcessWithToken Security__DuplicateTokenEx ' +
        'Security__GetAccountSid Security__GetLengthSid ' +
        'Security__GetTokenInformation Security__ImpersonateSelf ' +
        'Security__IsValidSid Security__LookupAccountName ' +
        'Security__LookupAccountSid Security__LookupPrivilegeValue ' +
        'Security__OpenProcessToken Security__OpenThreadToken ' +
        'Security__OpenThreadTokenEx Security__SetPrivilege ' +
        'Security__SetTokenInformation Security__SidToStringSid ' +
        'Security__SidTypeStr Security__StringSidToSid SendMessage ' +
        'SendMessageA SetDate SetTime Singleton SoundClose ' +
        'SoundLength SoundOpen SoundPause SoundPlay SoundPos ' +
        'SoundResume SoundSeek SoundStatus SoundStop ' +
        'SQLite_Changes SQLite_Close SQLite_Display2DResult ' +
        'SQLite_Encode SQLite_ErrCode SQLite_ErrMsg SQLite_Escape ' +
        'SQLite_Exec SQLite_FastEncode SQLite_FastEscape ' +
        'SQLite_FetchData SQLite_FetchNames SQLite_GetTable ' +
        'SQLite_GetTable2d SQLite_LastInsertRowID SQLite_LibVersion ' +
        'SQLite_Open SQLite_Query SQLite_QueryFinalize ' +
        'SQLite_QueryReset SQLite_QuerySingleRow SQLite_SafeMode ' +
        'SQLite_SetTimeout SQLite_Shutdown SQLite_SQLiteExe ' +
        'SQLite_Startup SQLite_TotalChanges StringBetween ' +
        'StringExplode StringInsert StringProper StringRepeat ' +
        'StringTitleCase StringToHex TCPIpToName TempFile ' +
        'TicksToTime Timer_Diff Timer_GetIdleTime Timer_GetTimerID ' +
        'Timer_Init Timer_KillAllTimers Timer_KillTimer ' +
        'Timer_SetTimer TimeToTicks VersionCompare viClose ' +
        'viExecCommand viFindGpib viGpibBusReset viGTL ' +
        'viInteractiveControl viOpen viSetAttribute viSetTimeout ' +
        'WeekNumberISO WinAPI_AbortPath WinAPI_ActivateKeyboardLayout ' +
        'WinAPI_AddClipboardFormatListener WinAPI_AddFontMemResourceEx ' +
        'WinAPI_AddFontResourceEx WinAPI_AddIconOverlay ' +
        'WinAPI_AddIconTransparency WinAPI_AddMRUString ' +
        'WinAPI_AdjustBitmap WinAPI_AdjustTokenPrivileges ' +
        'WinAPI_AdjustWindowRectEx WinAPI_AlphaBlend WinAPI_AngleArc ' +
        'WinAPI_AnimateWindow WinAPI_Arc WinAPI_ArcTo ' +
        'WinAPI_ArrayToStruct WinAPI_AssignProcessToJobObject ' +
        'WinAPI_AssocGetPerceivedType WinAPI_AssocQueryString ' +
        'WinAPI_AttachConsole WinAPI_AttachThreadInput ' +
        'WinAPI_BackupRead WinAPI_BackupReadAbort WinAPI_BackupSeek ' +
        'WinAPI_BackupWrite WinAPI_BackupWriteAbort WinAPI_Beep ' +
        'WinAPI_BeginBufferedPaint WinAPI_BeginDeferWindowPos ' +
        'WinAPI_BeginPaint WinAPI_BeginPath WinAPI_BeginUpdateResource ' +
        'WinAPI_BitBlt WinAPI_BringWindowToTop ' +
        'WinAPI_BroadcastSystemMessage WinAPI_BrowseForFolderDlg ' +
        'WinAPI_BufferedPaintClear WinAPI_BufferedPaintInit ' +
        'WinAPI_BufferedPaintSetAlpha WinAPI_BufferedPaintUnInit ' +
        'WinAPI_CallNextHookEx WinAPI_CallWindowProc ' +
        'WinAPI_CallWindowProcW WinAPI_CascadeWindows ' +
        'WinAPI_ChangeWindowMessageFilterEx WinAPI_CharToOem ' +
        'WinAPI_ChildWindowFromPointEx WinAPI_ClientToScreen ' +
        'WinAPI_ClipCursor WinAPI_CloseDesktop WinAPI_CloseEnhMetaFile ' +
        'WinAPI_CloseFigure WinAPI_CloseHandle WinAPI_CloseThemeData ' +
        'WinAPI_CloseWindow WinAPI_CloseWindowStation ' +
        'WinAPI_CLSIDFromProgID WinAPI_CoInitialize ' +
        'WinAPI_ColorAdjustLuma WinAPI_ColorHLSToRGB ' +
        'WinAPI_ColorRGBToHLS WinAPI_CombineRgn ' +
        'WinAPI_CombineTransform WinAPI_CommandLineToArgv ' +
        'WinAPI_CommDlgExtendedError WinAPI_CommDlgExtendedErrorEx ' +
        'WinAPI_CompareString WinAPI_CompressBitmapBits ' +
        'WinAPI_CompressBuffer WinAPI_ComputeCrc32 ' +
        'WinAPI_ConfirmCredentials WinAPI_CopyBitmap WinAPI_CopyCursor ' +
        'WinAPI_CopyEnhMetaFile WinAPI_CopyFileEx WinAPI_CopyIcon ' +
        'WinAPI_CopyImage WinAPI_CopyRect WinAPI_CopyStruct ' +
        'WinAPI_CoTaskMemAlloc WinAPI_CoTaskMemFree ' +
        'WinAPI_CoTaskMemRealloc WinAPI_CoUninitialize ' +
        'WinAPI_Create32BitHBITMAP WinAPI_Create32BitHICON ' +
        'WinAPI_CreateANDBitmap WinAPI_CreateBitmap ' +
        'WinAPI_CreateBitmapIndirect WinAPI_CreateBrushIndirect ' +
        'WinAPI_CreateBuffer WinAPI_CreateBufferFromStruct ' +
        'WinAPI_CreateCaret WinAPI_CreateColorAdjustment ' +
        'WinAPI_CreateCompatibleBitmap WinAPI_CreateCompatibleBitmapEx ' +
        'WinAPI_CreateCompatibleDC WinAPI_CreateDesktop ' +
        'WinAPI_CreateDIB WinAPI_CreateDIBColorTable ' +
        'WinAPI_CreateDIBitmap WinAPI_CreateDIBSection ' +
        'WinAPI_CreateDirectory WinAPI_CreateDirectoryEx ' +
        'WinAPI_CreateEllipticRgn WinAPI_CreateEmptyIcon ' +
        'WinAPI_CreateEnhMetaFile WinAPI_CreateEvent WinAPI_CreateFile ' +
        'WinAPI_CreateFileEx WinAPI_CreateFileMapping ' +
        'WinAPI_CreateFont WinAPI_CreateFontEx ' +
        'WinAPI_CreateFontIndirect WinAPI_CreateGUID ' +
        'WinAPI_CreateHardLink WinAPI_CreateIcon ' +
        'WinAPI_CreateIconFromResourceEx WinAPI_CreateIconIndirect ' +
        'WinAPI_CreateJobObject WinAPI_CreateMargins ' +
        'WinAPI_CreateMRUList WinAPI_CreateMutex WinAPI_CreateNullRgn ' +
        'WinAPI_CreateNumberFormatInfo WinAPI_CreateObjectID ' +
        'WinAPI_CreatePen WinAPI_CreatePoint WinAPI_CreatePolygonRgn ' +
        'WinAPI_CreateProcess WinAPI_CreateProcessWithToken ' +
        'WinAPI_CreateRect WinAPI_CreateRectEx WinAPI_CreateRectRgn ' +
        'WinAPI_CreateRectRgnIndirect WinAPI_CreateRoundRectRgn ' +
        'WinAPI_CreateSemaphore WinAPI_CreateSize ' +
        'WinAPI_CreateSolidBitmap WinAPI_CreateSolidBrush ' +
        'WinAPI_CreateStreamOnHGlobal WinAPI_CreateString ' +
        'WinAPI_CreateSymbolicLink WinAPI_CreateTransform ' +
        'WinAPI_CreateWindowEx WinAPI_CreateWindowStation ' +
        'WinAPI_DecompressBuffer WinAPI_DecryptFile ' +
        'WinAPI_DeferWindowPos WinAPI_DefineDosDevice ' +
        'WinAPI_DefRawInputProc WinAPI_DefSubclassProc ' +
        'WinAPI_DefWindowProc WinAPI_DefWindowProcW WinAPI_DeleteDC ' +
        'WinAPI_DeleteEnhMetaFile WinAPI_DeleteFile ' +
        'WinAPI_DeleteObject WinAPI_DeleteObjectID ' +
        'WinAPI_DeleteVolumeMountPoint WinAPI_DeregisterShellHookWindow ' +
        'WinAPI_DestroyCaret WinAPI_DestroyCursor WinAPI_DestroyIcon ' +
        'WinAPI_DestroyWindow WinAPI_DeviceIoControl ' +
        'WinAPI_DisplayStruct WinAPI_DllGetVersion WinAPI_DllInstall ' +
        'WinAPI_DllUninstall WinAPI_DPtoLP WinAPI_DragAcceptFiles ' +
        'WinAPI_DragFinish WinAPI_DragQueryFileEx ' +
        'WinAPI_DragQueryPoint WinAPI_DrawAnimatedRects ' +
        'WinAPI_DrawBitmap WinAPI_DrawEdge WinAPI_DrawFocusRect ' +
        'WinAPI_DrawFrameControl WinAPI_DrawIcon WinAPI_DrawIconEx ' +
        'WinAPI_DrawLine WinAPI_DrawShadowText WinAPI_DrawText ' +
        'WinAPI_DrawThemeBackground WinAPI_DrawThemeEdge ' +
        'WinAPI_DrawThemeIcon WinAPI_DrawThemeParentBackground ' +
        'WinAPI_DrawThemeText WinAPI_DrawThemeTextEx ' +
        'WinAPI_DuplicateEncryptionInfoFile WinAPI_DuplicateHandle ' +
        'WinAPI_DuplicateTokenEx WinAPI_DwmDefWindowProc ' +
        'WinAPI_DwmEnableBlurBehindWindow WinAPI_DwmEnableComposition ' +
        'WinAPI_DwmExtendFrameIntoClientArea ' +
        'WinAPI_DwmGetColorizationColor ' +
        'WinAPI_DwmGetColorizationParameters ' +
        'WinAPI_DwmGetWindowAttribute WinAPI_DwmInvalidateIconicBitmaps ' +
        'WinAPI_DwmIsCompositionEnabled ' +
        'WinAPI_DwmQueryThumbnailSourceSize WinAPI_DwmRegisterThumbnail ' +
        'WinAPI_DwmSetColorizationParameters ' +
        'WinAPI_DwmSetIconicLivePreviewBitmap ' +
        'WinAPI_DwmSetIconicThumbnail WinAPI_DwmSetWindowAttribute ' +
        'WinAPI_DwmUnregisterThumbnail ' +
        'WinAPI_DwmUpdateThumbnailProperties WinAPI_DWordToFloat ' +
        'WinAPI_DWordToInt WinAPI_EjectMedia WinAPI_Ellipse ' +
        'WinAPI_EmptyWorkingSet WinAPI_EnableWindow WinAPI_EncryptFile ' +
        'WinAPI_EncryptionDisable WinAPI_EndBufferedPaint ' +
        'WinAPI_EndDeferWindowPos WinAPI_EndPaint WinAPI_EndPath ' +
        'WinAPI_EndUpdateResource WinAPI_EnumChildProcess ' +
        'WinAPI_EnumChildWindows WinAPI_EnumDesktops ' +
        'WinAPI_EnumDesktopWindows WinAPI_EnumDeviceDrivers ' +
        'WinAPI_EnumDisplayDevices WinAPI_EnumDisplayMonitors ' +
        'WinAPI_EnumDisplaySettings WinAPI_EnumDllProc ' +
        'WinAPI_EnumFiles WinAPI_EnumFileStreams ' +
        'WinAPI_EnumFontFamilies WinAPI_EnumHardLinks ' +
        'WinAPI_EnumMRUList WinAPI_EnumPageFiles ' +
        'WinAPI_EnumProcessHandles WinAPI_EnumProcessModules ' +
        'WinAPI_EnumProcessThreads WinAPI_EnumProcessWindows ' +
        'WinAPI_EnumRawInputDevices WinAPI_EnumResourceLanguages ' +
        'WinAPI_EnumResourceNames WinAPI_EnumResourceTypes ' +
        'WinAPI_EnumSystemGeoID WinAPI_EnumSystemLocales ' +
        'WinAPI_EnumUILanguages WinAPI_EnumWindows ' +
        'WinAPI_EnumWindowsPopup WinAPI_EnumWindowStations ' +
        'WinAPI_EnumWindowsTop WinAPI_EqualMemory WinAPI_EqualRect ' +
        'WinAPI_EqualRgn WinAPI_ExcludeClipRect ' +
        'WinAPI_ExpandEnvironmentStrings WinAPI_ExtCreatePen ' +
        'WinAPI_ExtCreateRegion WinAPI_ExtFloodFill WinAPI_ExtractIcon ' +
        'WinAPI_ExtractIconEx WinAPI_ExtSelectClipRgn ' +
        'WinAPI_FatalAppExit WinAPI_FatalExit ' +
        'WinAPI_FileEncryptionStatus WinAPI_FileExists ' +
        'WinAPI_FileIconInit WinAPI_FileInUse WinAPI_FillMemory ' +
        'WinAPI_FillPath WinAPI_FillRect WinAPI_FillRgn ' +
        'WinAPI_FindClose WinAPI_FindCloseChangeNotification ' +
        'WinAPI_FindExecutable WinAPI_FindFirstChangeNotification ' +
        'WinAPI_FindFirstFile WinAPI_FindFirstFileName ' +
        'WinAPI_FindFirstStream WinAPI_FindNextChangeNotification ' +
        'WinAPI_FindNextFile WinAPI_FindNextFileName ' +
        'WinAPI_FindNextStream WinAPI_FindResource ' +
        'WinAPI_FindResourceEx WinAPI_FindTextDlg WinAPI_FindWindow ' +
        'WinAPI_FlashWindow WinAPI_FlashWindowEx WinAPI_FlattenPath ' +
        'WinAPI_FloatToDWord WinAPI_FloatToInt WinAPI_FlushFileBuffers ' +
        'WinAPI_FlushFRBuffer WinAPI_FlushViewOfFile ' +
        'WinAPI_FormatDriveDlg WinAPI_FormatMessage WinAPI_FrameRect ' +
        'WinAPI_FrameRgn WinAPI_FreeLibrary WinAPI_FreeMemory ' +
        'WinAPI_FreeMRUList WinAPI_FreeResource WinAPI_GdiComment ' +
        'WinAPI_GetActiveWindow WinAPI_GetAllUsersProfileDirectory ' +
        'WinAPI_GetAncestor WinAPI_GetApplicationRestartSettings ' +
        'WinAPI_GetArcDirection WinAPI_GetAsyncKeyState ' +
        'WinAPI_GetBinaryType WinAPI_GetBitmapBits ' +
        'WinAPI_GetBitmapDimension WinAPI_GetBitmapDimensionEx ' +
        'WinAPI_GetBkColor WinAPI_GetBkMode WinAPI_GetBoundsRect ' +
        'WinAPI_GetBrushOrg WinAPI_GetBufferedPaintBits ' +
        'WinAPI_GetBufferedPaintDC WinAPI_GetBufferedPaintTargetDC ' +
        'WinAPI_GetBufferedPaintTargetRect WinAPI_GetBValue ' +
        'WinAPI_GetCaretBlinkTime WinAPI_GetCaretPos WinAPI_GetCDType ' +
        'WinAPI_GetClassInfoEx WinAPI_GetClassLongEx ' +
        'WinAPI_GetClassName WinAPI_GetClientHeight ' +
        'WinAPI_GetClientRect WinAPI_GetClientWidth ' +
        'WinAPI_GetClipboardSequenceNumber WinAPI_GetClipBox ' +
        'WinAPI_GetClipCursor WinAPI_GetClipRgn ' +
        'WinAPI_GetColorAdjustment WinAPI_GetCompressedFileSize ' +
        'WinAPI_GetCompression WinAPI_GetConnectedDlg ' +
        'WinAPI_GetCurrentDirectory WinAPI_GetCurrentHwProfile ' +
        'WinAPI_GetCurrentObject WinAPI_GetCurrentPosition ' +
        'WinAPI_GetCurrentProcess ' +
        'WinAPI_GetCurrentProcessExplicitAppUserModelID ' +
        'WinAPI_GetCurrentProcessID WinAPI_GetCurrentThemeName ' +
        'WinAPI_GetCurrentThread WinAPI_GetCurrentThreadId ' +
        'WinAPI_GetCursor WinAPI_GetCursorInfo WinAPI_GetDateFormat ' +
        'WinAPI_GetDC WinAPI_GetDCEx WinAPI_GetDefaultPrinter ' +
        'WinAPI_GetDefaultUserProfileDirectory WinAPI_GetDesktopWindow ' +
        'WinAPI_GetDeviceCaps WinAPI_GetDeviceDriverBaseName ' +
        'WinAPI_GetDeviceDriverFileName WinAPI_GetDeviceGammaRamp ' +
        'WinAPI_GetDIBColorTable WinAPI_GetDIBits ' +
        'WinAPI_GetDiskFreeSpaceEx WinAPI_GetDlgCtrlID ' +
        'WinAPI_GetDlgItem WinAPI_GetDllDirectory ' +
        'WinAPI_GetDriveBusType WinAPI_GetDriveGeometryEx ' +
        'WinAPI_GetDriveNumber WinAPI_GetDriveType ' +
        'WinAPI_GetDurationFormat WinAPI_GetEffectiveClientRect ' +
        'WinAPI_GetEnhMetaFile WinAPI_GetEnhMetaFileBits ' +
        'WinAPI_GetEnhMetaFileDescription WinAPI_GetEnhMetaFileDimension ' +
        'WinAPI_GetEnhMetaFileHeader WinAPI_GetErrorMessage ' +
        'WinAPI_GetErrorMode WinAPI_GetExitCodeProcess ' +
        'WinAPI_GetExtended WinAPI_GetFileAttributes WinAPI_GetFileID ' +
        'WinAPI_GetFileInformationByHandle ' +
        'WinAPI_GetFileInformationByHandleEx WinAPI_GetFilePointerEx ' +
        'WinAPI_GetFileSizeEx WinAPI_GetFileSizeOnDisk ' +
        'WinAPI_GetFileTitle WinAPI_GetFileType ' +
        'WinAPI_GetFileVersionInfo WinAPI_GetFinalPathNameByHandle ' +
        'WinAPI_GetFinalPathNameByHandleEx WinAPI_GetFocus ' +
        'WinAPI_GetFontMemoryResourceInfo WinAPI_GetFontName ' +
        'WinAPI_GetFontResourceInfo WinAPI_GetForegroundWindow ' +
        'WinAPI_GetFRBuffer WinAPI_GetFullPathName WinAPI_GetGeoInfo ' +
        'WinAPI_GetGlyphOutline WinAPI_GetGraphicsMode ' +
        'WinAPI_GetGuiResources WinAPI_GetGUIThreadInfo ' +
        'WinAPI_GetGValue WinAPI_GetHandleInformation ' +
        'WinAPI_GetHGlobalFromStream WinAPI_GetIconDimension ' +
        'WinAPI_GetIconInfo WinAPI_GetIconInfoEx WinAPI_GetIdleTime ' +
        'WinAPI_GetKeyboardLayout WinAPI_GetKeyboardLayoutList ' +
        'WinAPI_GetKeyboardState WinAPI_GetKeyboardType ' +
        'WinAPI_GetKeyNameText WinAPI_GetKeyState ' +
        'WinAPI_GetLastActivePopup WinAPI_GetLastError ' +
        'WinAPI_GetLastErrorMessage WinAPI_GetLayeredWindowAttributes ' +
        'WinAPI_GetLocaleInfo WinAPI_GetLogicalDrives ' +
        'WinAPI_GetMapMode WinAPI_GetMemorySize ' +
        'WinAPI_GetMessageExtraInfo WinAPI_GetModuleFileNameEx ' +
        'WinAPI_GetModuleHandle WinAPI_GetModuleHandleEx ' +
        'WinAPI_GetModuleInformation WinAPI_GetMonitorInfo ' +
        'WinAPI_GetMousePos WinAPI_GetMousePosX WinAPI_GetMousePosY ' +
        'WinAPI_GetMUILanguage WinAPI_GetNumberFormat WinAPI_GetObject ' +
        'WinAPI_GetObjectID WinAPI_GetObjectInfoByHandle ' +
        'WinAPI_GetObjectNameByHandle WinAPI_GetObjectType ' +
        'WinAPI_GetOpenFileName WinAPI_GetOutlineTextMetrics ' +
        'WinAPI_GetOverlappedResult WinAPI_GetParent ' +
        'WinAPI_GetParentProcess WinAPI_GetPerformanceInfo ' +
        'WinAPI_GetPEType WinAPI_GetPhysicallyInstalledSystemMemory ' +
        'WinAPI_GetPixel WinAPI_GetPolyFillMode WinAPI_GetPosFromRect ' +
        'WinAPI_GetPriorityClass WinAPI_GetProcAddress ' +
        'WinAPI_GetProcessAffinityMask WinAPI_GetProcessCommandLine ' +
        'WinAPI_GetProcessFileName WinAPI_GetProcessHandleCount ' +
        'WinAPI_GetProcessID WinAPI_GetProcessIoCounters ' +
        'WinAPI_GetProcessMemoryInfo WinAPI_GetProcessName ' +
        'WinAPI_GetProcessShutdownParameters WinAPI_GetProcessTimes ' +
        'WinAPI_GetProcessUser WinAPI_GetProcessWindowStation ' +
        'WinAPI_GetProcessWorkingDirectory WinAPI_GetProfilesDirectory ' +
        'WinAPI_GetPwrCapabilities WinAPI_GetRawInputBuffer ' +
        'WinAPI_GetRawInputBufferLength WinAPI_GetRawInputData ' +
        'WinAPI_GetRawInputDeviceInfo WinAPI_GetRegionData ' +
        'WinAPI_GetRegisteredRawInputDevices ' +
        'WinAPI_GetRegKeyNameByHandle WinAPI_GetRgnBox WinAPI_GetROP2 ' +
        'WinAPI_GetRValue WinAPI_GetSaveFileName WinAPI_GetShellWindow ' +
        'WinAPI_GetStartupInfo WinAPI_GetStdHandle ' +
        'WinAPI_GetStockObject WinAPI_GetStretchBltMode ' +
        'WinAPI_GetString WinAPI_GetSysColor WinAPI_GetSysColorBrush ' +
        'WinAPI_GetSystemDefaultLangID WinAPI_GetSystemDefaultLCID ' +
        'WinAPI_GetSystemDefaultUILanguage WinAPI_GetSystemDEPPolicy ' +
        'WinAPI_GetSystemInfo WinAPI_GetSystemMetrics ' +
        'WinAPI_GetSystemPowerStatus WinAPI_GetSystemTimes ' +
        'WinAPI_GetSystemWow64Directory WinAPI_GetTabbedTextExtent ' +
        'WinAPI_GetTempFileName WinAPI_GetTextAlign ' +
        'WinAPI_GetTextCharacterExtra WinAPI_GetTextColor ' +
        'WinAPI_GetTextExtentPoint32 WinAPI_GetTextFace ' +
        'WinAPI_GetTextMetrics WinAPI_GetThemeAppProperties ' +
        'WinAPI_GetThemeBackgroundContentRect ' +
        'WinAPI_GetThemeBackgroundExtent WinAPI_GetThemeBackgroundRegion ' +
        'WinAPI_GetThemeBitmap WinAPI_GetThemeBool ' +
        'WinAPI_GetThemeColor WinAPI_GetThemeDocumentationProperty ' +
        'WinAPI_GetThemeEnumValue WinAPI_GetThemeFilename ' +
        'WinAPI_GetThemeFont WinAPI_GetThemeInt WinAPI_GetThemeMargins ' +
        'WinAPI_GetThemeMetric WinAPI_GetThemePartSize ' +
        'WinAPI_GetThemePosition WinAPI_GetThemePropertyOrigin ' +
        'WinAPI_GetThemeRect WinAPI_GetThemeString ' +
        'WinAPI_GetThemeSysBool WinAPI_GetThemeSysColor ' +
        'WinAPI_GetThemeSysColorBrush WinAPI_GetThemeSysFont ' +
        'WinAPI_GetThemeSysInt WinAPI_GetThemeSysSize ' +
        'WinAPI_GetThemeSysString WinAPI_GetThemeTextExtent ' +
        'WinAPI_GetThemeTextMetrics WinAPI_GetThemeTransitionDuration ' +
        'WinAPI_GetThreadDesktop WinAPI_GetThreadErrorMode ' +
        'WinAPI_GetThreadLocale WinAPI_GetThreadUILanguage ' +
        'WinAPI_GetTickCount WinAPI_GetTickCount64 ' +
        'WinAPI_GetTimeFormat WinAPI_GetTopWindow ' +
        'WinAPI_GetUDFColorMode WinAPI_GetUpdateRect ' +
        'WinAPI_GetUpdateRgn WinAPI_GetUserDefaultLangID ' +
        'WinAPI_GetUserDefaultLCID WinAPI_GetUserDefaultUILanguage ' +
        'WinAPI_GetUserGeoID WinAPI_GetUserObjectInformation ' +
        'WinAPI_GetVersion WinAPI_GetVersionEx ' +
        'WinAPI_GetVolumeInformation WinAPI_GetVolumeInformationByHandle ' +
        'WinAPI_GetVolumeNameForVolumeMountPoint WinAPI_GetWindow ' +
        'WinAPI_GetWindowDC WinAPI_GetWindowDisplayAffinity ' +
        'WinAPI_GetWindowExt WinAPI_GetWindowFileName ' +
        'WinAPI_GetWindowHeight WinAPI_GetWindowInfo ' +
        'WinAPI_GetWindowLong WinAPI_GetWindowOrg ' +
        'WinAPI_GetWindowPlacement WinAPI_GetWindowRect ' +
        'WinAPI_GetWindowRgn WinAPI_GetWindowRgnBox ' +
        'WinAPI_GetWindowSubclass WinAPI_GetWindowText ' +
        'WinAPI_GetWindowTheme WinAPI_GetWindowThreadProcessId ' +
        'WinAPI_GetWindowWidth WinAPI_GetWorkArea ' +
        'WinAPI_GetWorldTransform WinAPI_GetXYFromPoint ' +
        'WinAPI_GlobalMemoryStatus WinAPI_GradientFill ' +
        'WinAPI_GUIDFromString WinAPI_GUIDFromStringEx WinAPI_HashData ' +
        'WinAPI_HashString WinAPI_HiByte WinAPI_HideCaret ' +
        'WinAPI_HiDWord WinAPI_HiWord WinAPI_InflateRect ' +
        'WinAPI_InitMUILanguage WinAPI_InProcess ' +
        'WinAPI_IntersectClipRect WinAPI_IntersectRect ' +
        'WinAPI_IntToDWord WinAPI_IntToFloat WinAPI_InvalidateRect ' +
        'WinAPI_InvalidateRgn WinAPI_InvertANDBitmap ' +
        'WinAPI_InvertColor WinAPI_InvertRect WinAPI_InvertRgn ' +
        'WinAPI_IOCTL WinAPI_IsAlphaBitmap WinAPI_IsBadCodePtr ' +
        'WinAPI_IsBadReadPtr WinAPI_IsBadStringPtr ' +
        'WinAPI_IsBadWritePtr WinAPI_IsChild WinAPI_IsClassName ' +
        'WinAPI_IsDoorOpen WinAPI_IsElevated WinAPI_IsHungAppWindow ' +
        'WinAPI_IsIconic WinAPI_IsInternetConnected ' +
        'WinAPI_IsLoadKBLayout WinAPI_IsMemory ' +
        'WinAPI_IsNameInExpression WinAPI_IsNetworkAlive ' +
        'WinAPI_IsPathShared WinAPI_IsProcessInJob ' +
        'WinAPI_IsProcessorFeaturePresent WinAPI_IsRectEmpty ' +
        'WinAPI_IsThemeActive ' +
        'WinAPI_IsThemeBackgroundPartiallyTransparent ' +
        'WinAPI_IsThemePartDefined WinAPI_IsValidLocale ' +
        'WinAPI_IsWindow WinAPI_IsWindowEnabled WinAPI_IsWindowUnicode ' +
        'WinAPI_IsWindowVisible WinAPI_IsWow64Process ' +
        'WinAPI_IsWritable WinAPI_IsZoomed WinAPI_Keybd_Event ' +
        'WinAPI_KillTimer WinAPI_LineDDA WinAPI_LineTo ' +
        'WinAPI_LoadBitmap WinAPI_LoadCursor WinAPI_LoadCursorFromFile ' +
        'WinAPI_LoadIcon WinAPI_LoadIconMetric ' +
        'WinAPI_LoadIconWithScaleDown WinAPI_LoadImage ' +
        'WinAPI_LoadIndirectString WinAPI_LoadKeyboardLayout ' +
        'WinAPI_LoadLibrary WinAPI_LoadLibraryEx WinAPI_LoadMedia ' +
        'WinAPI_LoadResource WinAPI_LoadShell32Icon WinAPI_LoadString ' +
        'WinAPI_LoadStringEx WinAPI_LoByte WinAPI_LocalFree ' +
        'WinAPI_LockDevice WinAPI_LockFile WinAPI_LockResource ' +
        'WinAPI_LockWindowUpdate WinAPI_LockWorkStation WinAPI_LoDWord ' +
        'WinAPI_LongMid WinAPI_LookupIconIdFromDirectoryEx ' +
        'WinAPI_LoWord WinAPI_LPtoDP WinAPI_MAKELANGID ' +
        'WinAPI_MAKELCID WinAPI_MakeLong WinAPI_MakeQWord ' +
        'WinAPI_MakeWord WinAPI_MapViewOfFile WinAPI_MapVirtualKey ' +
        'WinAPI_MaskBlt WinAPI_MessageBeep WinAPI_MessageBoxCheck ' +
        'WinAPI_MessageBoxIndirect WinAPI_MirrorIcon ' +
        'WinAPI_ModifyWorldTransform WinAPI_MonitorFromPoint ' +
        'WinAPI_MonitorFromRect WinAPI_MonitorFromWindow ' +
        'WinAPI_Mouse_Event WinAPI_MoveFileEx WinAPI_MoveMemory ' +
        'WinAPI_MoveTo WinAPI_MoveToEx WinAPI_MoveWindow ' +
        'WinAPI_MsgBox WinAPI_MulDiv WinAPI_MultiByteToWideChar ' +
        'WinAPI_MultiByteToWideCharEx WinAPI_NtStatusToDosError ' +
        'WinAPI_OemToChar WinAPI_OffsetClipRgn WinAPI_OffsetPoints ' +
        'WinAPI_OffsetRect WinAPI_OffsetRgn WinAPI_OffsetWindowOrg ' +
        'WinAPI_OpenDesktop WinAPI_OpenFileById WinAPI_OpenFileDlg ' +
        'WinAPI_OpenFileMapping WinAPI_OpenIcon ' +
        'WinAPI_OpenInputDesktop WinAPI_OpenJobObject WinAPI_OpenMutex ' +
        'WinAPI_OpenProcess WinAPI_OpenProcessToken ' +
        'WinAPI_OpenSemaphore WinAPI_OpenThemeData ' +
        'WinAPI_OpenWindowStation WinAPI_PageSetupDlg ' +
        'WinAPI_PaintDesktop WinAPI_PaintRgn WinAPI_ParseURL ' +
        'WinAPI_ParseUserName WinAPI_PatBlt WinAPI_PathAddBackslash ' +
        'WinAPI_PathAddExtension WinAPI_PathAppend ' +
        'WinAPI_PathBuildRoot WinAPI_PathCanonicalize ' +
        'WinAPI_PathCommonPrefix WinAPI_PathCompactPath ' +
        'WinAPI_PathCompactPathEx WinAPI_PathCreateFromUrl ' +
        'WinAPI_PathFindExtension WinAPI_PathFindFileName ' +
        'WinAPI_PathFindNextComponent WinAPI_PathFindOnPath ' +
        'WinAPI_PathGetArgs WinAPI_PathGetCharType ' +
        'WinAPI_PathGetDriveNumber WinAPI_PathIsContentType ' +
        'WinAPI_PathIsDirectory WinAPI_PathIsDirectoryEmpty ' +
        'WinAPI_PathIsExe WinAPI_PathIsFileSpec ' +
        'WinAPI_PathIsLFNFileSpec WinAPI_PathIsRelative ' +
        'WinAPI_PathIsRoot WinAPI_PathIsSameRoot ' +
        'WinAPI_PathIsSystemFolder WinAPI_PathIsUNC ' +
        'WinAPI_PathIsUNCServer WinAPI_PathIsUNCServerShare ' +
        'WinAPI_PathMakeSystemFolder WinAPI_PathMatchSpec ' +
        'WinAPI_PathParseIconLocation WinAPI_PathRelativePathTo ' +
        'WinAPI_PathRemoveArgs WinAPI_PathRemoveBackslash ' +
        'WinAPI_PathRemoveExtension WinAPI_PathRemoveFileSpec ' +
        'WinAPI_PathRenameExtension WinAPI_PathSearchAndQualify ' +
        'WinAPI_PathSkipRoot WinAPI_PathStripPath ' +
        'WinAPI_PathStripToRoot WinAPI_PathToRegion ' +
        'WinAPI_PathUndecorate WinAPI_PathUnExpandEnvStrings ' +
        'WinAPI_PathUnmakeSystemFolder WinAPI_PathUnquoteSpaces ' +
        'WinAPI_PathYetAnotherMakeUniqueName WinAPI_PickIconDlg ' +
        'WinAPI_PlayEnhMetaFile WinAPI_PlaySound WinAPI_PlgBlt ' +
        'WinAPI_PointFromRect WinAPI_PolyBezier WinAPI_PolyBezierTo ' +
        'WinAPI_PolyDraw WinAPI_Polygon WinAPI_PostMessage ' +
        'WinAPI_PrimaryLangId WinAPI_PrintDlg WinAPI_PrintDlgEx ' +
        'WinAPI_PrintWindow WinAPI_ProgIDFromCLSID WinAPI_PtInRect ' +
        'WinAPI_PtInRectEx WinAPI_PtInRegion WinAPI_PtVisible ' +
        'WinAPI_QueryDosDevice WinAPI_QueryInformationJobObject ' +
        'WinAPI_QueryPerformanceCounter WinAPI_QueryPerformanceFrequency ' +
        'WinAPI_RadialGradientFill WinAPI_ReadDirectoryChanges ' +
        'WinAPI_ReadFile WinAPI_ReadProcessMemory WinAPI_Rectangle ' +
        'WinAPI_RectInRegion WinAPI_RectIsEmpty WinAPI_RectVisible ' +
        'WinAPI_RedrawWindow WinAPI_RegCloseKey ' +
        'WinAPI_RegConnectRegistry WinAPI_RegCopyTree ' +
        'WinAPI_RegCopyTreeEx WinAPI_RegCreateKey ' +
        'WinAPI_RegDeleteEmptyKey WinAPI_RegDeleteKey ' +
        'WinAPI_RegDeleteKeyValue WinAPI_RegDeleteTree ' +
        'WinAPI_RegDeleteTreeEx WinAPI_RegDeleteValue ' +
        'WinAPI_RegDisableReflectionKey WinAPI_RegDuplicateHKey ' +
        'WinAPI_RegEnableReflectionKey WinAPI_RegEnumKey ' +
        'WinAPI_RegEnumValue WinAPI_RegFlushKey ' +
        'WinAPI_RegisterApplicationRestart WinAPI_RegisterClass ' +
        'WinAPI_RegisterClassEx WinAPI_RegisterHotKey ' +
        'WinAPI_RegisterPowerSettingNotification ' +
        'WinAPI_RegisterRawInputDevices WinAPI_RegisterShellHookWindow ' +
        'WinAPI_RegisterWindowMessage WinAPI_RegLoadMUIString ' +
        'WinAPI_RegNotifyChangeKeyValue WinAPI_RegOpenKey ' +
        'WinAPI_RegQueryInfoKey WinAPI_RegQueryLastWriteTime ' +
        'WinAPI_RegQueryMultipleValues WinAPI_RegQueryReflectionKey ' +
        'WinAPI_RegQueryValue WinAPI_RegRestoreKey WinAPI_RegSaveKey ' +
        'WinAPI_RegSetValue WinAPI_ReleaseCapture WinAPI_ReleaseDC ' +
        'WinAPI_ReleaseMutex WinAPI_ReleaseSemaphore ' +
        'WinAPI_ReleaseStream WinAPI_RemoveClipboardFormatListener ' +
        'WinAPI_RemoveDirectory WinAPI_RemoveFontMemResourceEx ' +
        'WinAPI_RemoveFontResourceEx WinAPI_RemoveWindowSubclass ' +
        'WinAPI_ReOpenFile WinAPI_ReplaceFile WinAPI_ReplaceTextDlg ' +
        'WinAPI_ResetEvent WinAPI_RestartDlg WinAPI_RestoreDC ' +
        'WinAPI_RGB WinAPI_RotatePoints WinAPI_RoundRect ' +
        'WinAPI_SaveDC WinAPI_SaveFileDlg WinAPI_SaveHBITMAPToFile ' +
        'WinAPI_SaveHICONToFile WinAPI_ScaleWindowExt ' +
        'WinAPI_ScreenToClient WinAPI_SearchPath WinAPI_SelectClipPath ' +
        'WinAPI_SelectClipRgn WinAPI_SelectObject ' +
        'WinAPI_SendMessageTimeout WinAPI_SetActiveWindow ' +
        'WinAPI_SetArcDirection WinAPI_SetBitmapBits ' +
        'WinAPI_SetBitmapDimensionEx WinAPI_SetBkColor ' +
        'WinAPI_SetBkMode WinAPI_SetBoundsRect WinAPI_SetBrushOrg ' +
        'WinAPI_SetCapture WinAPI_SetCaretBlinkTime WinAPI_SetCaretPos ' +
        'WinAPI_SetClassLongEx WinAPI_SetColorAdjustment ' +
        'WinAPI_SetCompression WinAPI_SetCurrentDirectory ' +
        'WinAPI_SetCurrentProcessExplicitAppUserModelID WinAPI_SetCursor ' +
        'WinAPI_SetDCBrushColor WinAPI_SetDCPenColor ' +
        'WinAPI_SetDefaultPrinter WinAPI_SetDeviceGammaRamp ' +
        'WinAPI_SetDIBColorTable WinAPI_SetDIBits ' +
        'WinAPI_SetDIBitsToDevice WinAPI_SetDllDirectory ' +
        'WinAPI_SetEndOfFile WinAPI_SetEnhMetaFileBits ' +
        'WinAPI_SetErrorMode WinAPI_SetEvent WinAPI_SetFileAttributes ' +
        'WinAPI_SetFileInformationByHandleEx WinAPI_SetFilePointer ' +
        'WinAPI_SetFilePointerEx WinAPI_SetFileShortName ' +
        'WinAPI_SetFileValidData WinAPI_SetFocus WinAPI_SetFont ' +
        'WinAPI_SetForegroundWindow WinAPI_SetFRBuffer ' +
        'WinAPI_SetGraphicsMode WinAPI_SetHandleInformation ' +
        'WinAPI_SetInformationJobObject WinAPI_SetKeyboardLayout ' +
        'WinAPI_SetKeyboardState WinAPI_SetLastError ' +
        'WinAPI_SetLayeredWindowAttributes WinAPI_SetLocaleInfo ' +
        'WinAPI_SetMapMode WinAPI_SetMessageExtraInfo WinAPI_SetParent ' +
        'WinAPI_SetPixel WinAPI_SetPolyFillMode ' +
        'WinAPI_SetPriorityClass WinAPI_SetProcessAffinityMask ' +
        'WinAPI_SetProcessShutdownParameters ' +
        'WinAPI_SetProcessWindowStation WinAPI_SetRectRgn ' +
        'WinAPI_SetROP2 WinAPI_SetSearchPathMode ' +
        'WinAPI_SetStretchBltMode WinAPI_SetSysColors ' +
        'WinAPI_SetSystemCursor WinAPI_SetTextAlign ' +
        'WinAPI_SetTextCharacterExtra WinAPI_SetTextColor ' +
        'WinAPI_SetTextJustification WinAPI_SetThemeAppProperties ' +
        'WinAPI_SetThreadDesktop WinAPI_SetThreadErrorMode ' +
        'WinAPI_SetThreadExecutionState WinAPI_SetThreadLocale ' +
        'WinAPI_SetThreadUILanguage WinAPI_SetTimer ' +
        'WinAPI_SetUDFColorMode WinAPI_SetUserGeoID ' +
        'WinAPI_SetUserObjectInformation WinAPI_SetVolumeMountPoint ' +
        'WinAPI_SetWindowDisplayAffinity WinAPI_SetWindowExt ' +
        'WinAPI_SetWindowLong WinAPI_SetWindowOrg ' +
        'WinAPI_SetWindowPlacement WinAPI_SetWindowPos ' +
        'WinAPI_SetWindowRgn WinAPI_SetWindowsHookEx ' +
        'WinAPI_SetWindowSubclass WinAPI_SetWindowText ' +
        'WinAPI_SetWindowTheme WinAPI_SetWinEventHook ' +
        'WinAPI_SetWorldTransform WinAPI_SfcIsFileProtected ' +
        'WinAPI_SfcIsKeyProtected WinAPI_ShellAboutDlg ' +
        'WinAPI_ShellAddToRecentDocs WinAPI_ShellChangeNotify ' +
        'WinAPI_ShellChangeNotifyDeregister ' +
        'WinAPI_ShellChangeNotifyRegister WinAPI_ShellCreateDirectory ' +
        'WinAPI_ShellEmptyRecycleBin WinAPI_ShellExecute ' +
        'WinAPI_ShellExecuteEx WinAPI_ShellExtractAssociatedIcon ' +
        'WinAPI_ShellExtractIcon WinAPI_ShellFileOperation ' +
        'WinAPI_ShellFlushSFCache WinAPI_ShellGetFileInfo ' +
        'WinAPI_ShellGetIconOverlayIndex WinAPI_ShellGetImageList ' +
        'WinAPI_ShellGetKnownFolderIDList WinAPI_ShellGetKnownFolderPath ' +
        'WinAPI_ShellGetLocalizedName WinAPI_ShellGetPathFromIDList ' +
        'WinAPI_ShellGetSetFolderCustomSettings WinAPI_ShellGetSettings ' +
        'WinAPI_ShellGetSpecialFolderLocation ' +
        'WinAPI_ShellGetSpecialFolderPath WinAPI_ShellGetStockIconInfo ' +
        'WinAPI_ShellILCreateFromPath WinAPI_ShellNotifyIcon ' +
        'WinAPI_ShellNotifyIconGetRect WinAPI_ShellObjectProperties ' +
        'WinAPI_ShellOpenFolderAndSelectItems WinAPI_ShellOpenWithDlg ' +
        'WinAPI_ShellQueryRecycleBin ' +
        'WinAPI_ShellQueryUserNotificationState ' +
        'WinAPI_ShellRemoveLocalizedName WinAPI_ShellRestricted ' +
        'WinAPI_ShellSetKnownFolderPath WinAPI_ShellSetLocalizedName ' +
        'WinAPI_ShellSetSettings WinAPI_ShellStartNetConnectionDlg ' +
        'WinAPI_ShellUpdateImage WinAPI_ShellUserAuthenticationDlg ' +
        'WinAPI_ShellUserAuthenticationDlgEx WinAPI_ShortToWord ' +
        'WinAPI_ShowCaret WinAPI_ShowCursor WinAPI_ShowError ' +
        'WinAPI_ShowLastError WinAPI_ShowMsg WinAPI_ShowOwnedPopups ' +
        'WinAPI_ShowWindow WinAPI_ShutdownBlockReasonCreate ' +
        'WinAPI_ShutdownBlockReasonDestroy ' +
        'WinAPI_ShutdownBlockReasonQuery WinAPI_SizeOfResource ' +
        'WinAPI_StretchBlt WinAPI_StretchDIBits ' +
        'WinAPI_StrFormatByteSize WinAPI_StrFormatByteSizeEx ' +
        'WinAPI_StrFormatKBSize WinAPI_StrFromTimeInterval ' +
        'WinAPI_StringFromGUID WinAPI_StringLenA WinAPI_StringLenW ' +
        'WinAPI_StrLen WinAPI_StrokeAndFillPath WinAPI_StrokePath ' +
        'WinAPI_StructToArray WinAPI_SubLangId WinAPI_SubtractRect ' +
        'WinAPI_SwapDWord WinAPI_SwapQWord WinAPI_SwapWord ' +
        'WinAPI_SwitchColor WinAPI_SwitchDesktop ' +
        'WinAPI_SwitchToThisWindow WinAPI_SystemParametersInfo ' +
        'WinAPI_TabbedTextOut WinAPI_TerminateJobObject ' +
        'WinAPI_TerminateProcess WinAPI_TextOut WinAPI_TileWindows ' +
        'WinAPI_TrackMouseEvent WinAPI_TransparentBlt ' +
        'WinAPI_TwipsPerPixelX WinAPI_TwipsPerPixelY ' +
        'WinAPI_UnhookWindowsHookEx WinAPI_UnhookWinEvent ' +
        'WinAPI_UnionRect WinAPI_UnionStruct WinAPI_UniqueHardwareID ' +
        'WinAPI_UnloadKeyboardLayout WinAPI_UnlockFile ' +
        'WinAPI_UnmapViewOfFile WinAPI_UnregisterApplicationRestart ' +
        'WinAPI_UnregisterClass WinAPI_UnregisterHotKey ' +
        'WinAPI_UnregisterPowerSettingNotification ' +
        'WinAPI_UpdateLayeredWindow WinAPI_UpdateLayeredWindowEx ' +
        'WinAPI_UpdateLayeredWindowIndirect WinAPI_UpdateResource ' +
        'WinAPI_UpdateWindow WinAPI_UrlApplyScheme ' +
        'WinAPI_UrlCanonicalize WinAPI_UrlCombine WinAPI_UrlCompare ' +
        'WinAPI_UrlCreateFromPath WinAPI_UrlFixup WinAPI_UrlGetPart ' +
        'WinAPI_UrlHash WinAPI_UrlIs WinAPI_UserHandleGrantAccess ' +
        'WinAPI_ValidateRect WinAPI_ValidateRgn WinAPI_VerQueryRoot ' +
        'WinAPI_VerQueryValue WinAPI_VerQueryValueEx ' +
        'WinAPI_WaitForInputIdle WinAPI_WaitForMultipleObjects ' +
        'WinAPI_WaitForSingleObject WinAPI_WideCharToMultiByte ' +
        'WinAPI_WidenPath WinAPI_WindowFromDC WinAPI_WindowFromPoint ' +
        'WinAPI_WordToShort WinAPI_Wow64EnableWow64FsRedirection ' +
        'WinAPI_WriteConsole WinAPI_WriteFile ' +
        'WinAPI_WriteProcessMemory WinAPI_ZeroMemory ' +
        'WinNet_AddConnection WinNet_AddConnection2 ' +
        'WinNet_AddConnection3 WinNet_CancelConnection ' +
        'WinNet_CancelConnection2 WinNet_CloseEnum ' +
        'WinNet_ConnectionDialog WinNet_ConnectionDialog1 ' +
        'WinNet_DisconnectDialog WinNet_DisconnectDialog1 ' +
        'WinNet_EnumResource WinNet_GetConnection ' +
        'WinNet_GetConnectionPerformance WinNet_GetLastError ' +
        'WinNet_GetNetworkInformation WinNet_GetProviderName ' +
        'WinNet_GetResourceInformation WinNet_GetResourceParent ' +
        'WinNet_GetUniversalName WinNet_GetUser WinNet_OpenEnum ' +
        'WinNet_RestoreConnection WinNet_UseConnection Word_Create ' +
        'Word_DocAdd Word_DocAttach Word_DocClose Word_DocExport ' +
        'Word_DocFind Word_DocFindReplace Word_DocGet ' +
        'Word_DocLinkAdd Word_DocLinkGet Word_DocOpen ' +
        'Word_DocPictureAdd Word_DocPrint Word_DocRangeSet ' +
        'Word_DocSave Word_DocSaveAs Word_DocTableRead ' +
        'Word_DocTableWrite Word_Quit',

        COMMENT = {
            variants: [
              hljs.COMMENT(';', '$', {relevance: 0}),
              hljs.COMMENT('#cs', '#ce'),
              hljs.COMMENT('#comments-start', '#comments-end')
            ]
        },

        VARIABLE = {
            className: 'variable',
            begin: '\\$[A-z0-9_]+'
        },

        STRING = {
            className: 'string',
            variants: [{
                begin: /"/,
                end: /"/,
                contains: [{
                    begin: /""/,
                    relevance: 0
                }]
            }, {
                begin: /'/,
                end: /'/,
                contains: [{
                    begin: /''/,
                    relevance: 0
                }]
            }]
        },

        NUMBER = {
            variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]
        },

        PREPROCESSOR = {
            className: 'preprocessor',
            begin: '#',
            end: '$',
            keywords: 'include include-once NoTrayIcon OnAutoItStartRegister RequireAdmin pragma ' +
                'Au3Stripper_Ignore_Funcs Au3Stripper_Ignore_Variables ' +
                'Au3Stripper_Off Au3Stripper_On Au3Stripper_Parameters ' +
                'AutoIt3Wrapper_Add_Constants AutoIt3Wrapper_Au3Check_Parameters ' +
                'AutoIt3Wrapper_Au3Check_Stop_OnWarning AutoIt3Wrapper_Aut2Exe ' +
                'AutoIt3Wrapper_AutoIt3 AutoIt3Wrapper_AutoIt3Dir ' +
                'AutoIt3Wrapper_Change2CUI AutoIt3Wrapper_Compile_Both ' +
                'AutoIt3Wrapper_Compression AutoIt3Wrapper_EndIf ' +
                'AutoIt3Wrapper_Icon AutoIt3Wrapper_If_Compile ' +
                'AutoIt3Wrapper_If_Run AutoIt3Wrapper_Jump_To_First_Error ' +
                'AutoIt3Wrapper_OutFile AutoIt3Wrapper_OutFile_Type ' +
                'AutoIt3Wrapper_OutFile_X64 AutoIt3Wrapper_PlugIn_Funcs ' +
                'AutoIt3Wrapper_Res_Comment Autoit3Wrapper_Res_Compatibility ' +
                'AutoIt3Wrapper_Res_Description AutoIt3Wrapper_Res_Field ' +
                'AutoIt3Wrapper_Res_File_Add AutoIt3Wrapper_Res_FileVersion ' +
                'AutoIt3Wrapper_Res_FileVersion_AutoIncrement ' +
                'AutoIt3Wrapper_Res_Icon_Add AutoIt3Wrapper_Res_Language ' +
                'AutoIt3Wrapper_Res_LegalCopyright ' +
                'AutoIt3Wrapper_Res_ProductVersion ' +
                'AutoIt3Wrapper_Res_requestedExecutionLevel ' +
                'AutoIt3Wrapper_Res_SaveSource AutoIt3Wrapper_Run_After ' +
                'AutoIt3Wrapper_Run_Au3Check AutoIt3Wrapper_Run_Au3Stripper ' +
                'AutoIt3Wrapper_Run_Before AutoIt3Wrapper_Run_Debug_Mode ' +
                'AutoIt3Wrapper_Run_SciTE_Minimized ' +
                'AutoIt3Wrapper_Run_SciTE_OutputPane_Minimized ' +
                'AutoIt3Wrapper_Run_Tidy AutoIt3Wrapper_ShowProgress ' +
                'AutoIt3Wrapper_Testing AutoIt3Wrapper_Tidy_Stop_OnError ' +
                'AutoIt3Wrapper_UPX_Parameters AutoIt3Wrapper_UseUPX ' +
                'AutoIt3Wrapper_UseX64 AutoIt3Wrapper_Version ' +
                'AutoIt3Wrapper_Versioning AutoIt3Wrapper_Versioning_Parameters ' +
                'Tidy_Off Tidy_On Tidy_Parameters EndRegion Region',
            contains: [{
                    begin: /\\\n/,
                    relevance: 0
                }, {
                    beginKeywords: 'include',
                    end: '$',
                    contains: [
                        STRING, {
                            className: 'string',
                            variants: [{
                                begin: '<',
                                end: '>'
                            }, {
                                begin: /"/,
                                end: /"/,
                                contains: [{
                                    begin: /""/,
                                    relevance: 0
                                }]
                            }, {
                                begin: /'/,
                                end: /'/,
                                contains: [{
                                    begin: /''/,
                                    relevance: 0
                                }]
                            }]
                        }
                    ]
                },
                STRING,
                COMMENT
            ]
        },

        CONSTANT = {
            className: 'constant',
            // begin: '@',
            // end: '$',
            // keywords: 'AppDataCommonDir AppDataDir AutoItExe AutoItPID AutoItVersion AutoItX64 COM_EventObj CommonFilesDir Compiled ComputerName ComSpec CPUArch CR CRLF DesktopCommonDir DesktopDepth DesktopDir DesktopHeight DesktopRefresh DesktopWidth DocumentsCommonDir error exitCode exitMethod extended FavoritesCommonDir FavoritesDir GUI_CtrlHandle GUI_CtrlId GUI_DragFile GUI_DragId GUI_DropId GUI_WinHandle HomeDrive HomePath HomeShare HotKeyPressed HOUR IPAddress1 IPAddress2 IPAddress3 IPAddress4 KBLayout LF LocalAppDataDir LogonDNSDomain LogonDomain LogonServer MDAY MIN MON MSEC MUILang MyDocumentsDir NumParams OSArch OSBuild OSLang OSServicePack OSType OSVersion ProgramFilesDir ProgramsCommonDir ProgramsDir ScriptDir ScriptFullPath ScriptLineNumber ScriptName SEC StartMenuCommonDir StartMenuDir StartupCommonDir StartupDir SW_DISABLE SW_ENABLE SW_HIDE SW_LOCK SW_MAXIMIZE SW_MINIMIZE SW_RESTORE SW_SHOW SW_SHOWDEFAULT SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_SHOWMINNOACTIVE SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNORMAL SW_UNLOCK SystemDir TAB TempDir TRAY_ID TrayIconFlashing TrayIconVisible UserName UserProfileDir WDAY WindowsDir WorkingDir YDAY YEAR',
            // relevance: 5
            begin: '@[A-z0-9_]+'
        },

        FUNCTION = {
            className: 'function',
            beginKeywords: 'Func',
            end: '$',
            excludeEnd: true,
            illegal: '\\$|\\[|%',
            contains: [
                hljs.UNDERSCORE_TITLE_MODE, {
                    className: 'params',
                    begin: '\\(',
                    end: '\\)',
                    contains: [
                        VARIABLE,
                        STRING,
                        NUMBER
                    ]
                }
            ]
        };

    return {
        case_insensitive: true,
        illegal: /\/\*/,
        keywords: {
            keyword: KEYWORDS,
            built_in: BUILT_IN,
            literal: LITERAL
        },
        contains: [
            COMMENT,
            VARIABLE,
            STRING,
            NUMBER,
            PREPROCESSOR,
            CONSTANT,
            FUNCTION
        ]
    }
});

hljs.registerLanguage('avrasm', function(hljs) {
  return {
    case_insensitive: true,
    lexemes: '\\.?' + hljs.IDENT_RE,
    keywords: {
      keyword:
        /* mnemonic */
        'adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs ' +
        'brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr ' +
        'clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor ' +
        'fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul ' +
        'muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs ' +
        'sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub ' +
        'subi swap tst wdr',
      built_in:
        /* general purpose registers */
        'r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 ' +
        'r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ' +
        /* IO Registers (ATMega128) */
        'ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h ' +
        'tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ' +
        'ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ' +
        'ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk ' +
        'tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ' +
        'ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr ' +
        'porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ' +
        'ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf',
      preprocessor:
        '.byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list ' +
        '.listmac .macro .nolist .org .set'
    },
    contains: [
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.COMMENT(
        ';',
        '$',
        {
          relevance: 0
        }
      ),
      hljs.C_NUMBER_MODE, // 0x..., decimal, float
      hljs.BINARY_NUMBER_MODE, // 0b...
      {
        className: 'number',
        begin: '\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)' // $..., 0o...
      },
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        begin: '\'', end: '[^\\\\]\'',
        illegal: '[^\\\\][^\']'
      },
      {className: 'label',  begin: '^[A-Za-z0-9_.$]+:'},
      {className: 'preprocessor', begin: '#', end: '$'},
      {  // подстановка в «.macro»
        className: 'localvars',
        begin: '@[0-9]+'
      }
    ]
  };
});

hljs.registerLanguage('axapta', function(hljs) {
  return {
    keywords: 'false int abstract private char boolean static null if for true ' +
      'while long throw finally protected final return void enum else ' +
      'break new catch byte super case short default double public try this switch ' +
      'continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count ' +
      'order group by asc desc index hint like dispaly edit client server ttsbegin ' +
      'ttscommit str real date container anytype common div mod',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'preprocessor',
        begin: '#', end: '$'
      },
      {
        className: 'class',
        beginKeywords: 'class interface', end: '{', excludeEnd: true,
        illegal: ':',
        contains: [
          {beginKeywords: 'extends implements'},
          hljs.UNDERSCORE_TITLE_MODE
        ]
      }
    ]
  };
});

hljs.registerLanguage('bash', function(hljs) {
  var VAR = {
    className: 'variable',
    variants: [
      {begin: /\$[\w\d#@][\w\d_]*/},
      {begin: /\$\{(.*?)}/}
    ]
  };
  var QUOTE_STRING = {
    className: 'string',
    begin: /"/, end: /"/,
    contains: [
      hljs.BACKSLASH_ESCAPE,
      VAR,
      {
        className: 'variable',
        begin: /\$\(/, end: /\)/,
        contains: [hljs.BACKSLASH_ESCAPE]
      }
    ]
  };
  var APOS_STRING = {
    className: 'string',
    begin: /'/, end: /'/
  };

  return {
    aliases: ['sh', 'zsh'],
    lexemes: /-?[a-z\.]+/,
    keywords: {
      keyword:
        'if then else elif fi for while in do done case esac function',
      literal:
        'true false',
      built_in:
        // Shell built-ins
        // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
        'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' +
        'trap umask unset ' +
        // Bash built-ins
        'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' +
        'read readarray source type typeset ulimit unalias ' +
        // Shell modifiers
        'set shopt ' +
        // Zsh built-ins
        'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' +
        'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' +
        'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' +
        'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' +
        'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' +
        'zpty zregexparse zsocket zstyle ztcp',
      operator:
        '-ne -eq -lt -gt -f -d -e -s -l -a' // relevance booster
    },
    contains: [
      {
        className: 'shebang',
        begin: /^#![^\n]+sh\s*$/,
        relevance: 10
      },
      {
        className: 'function',
        begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/,
        returnBegin: true,
        contains: [hljs.inherit(hljs.TITLE_MODE, {begin: /\w[\w\d_]*/})],
        relevance: 0
      },
      hljs.HASH_COMMENT_MODE,
      hljs.NUMBER_MODE,
      QUOTE_STRING,
      APOS_STRING,
      VAR
    ]
  };
});

hljs.registerLanguage('brainfuck', function(hljs){
  var LITERAL = {
    className: 'literal',
    begin: '[\\+\\-]',
    relevance: 0
  };
  return {
    aliases: ['bf'],
    contains: [
      hljs.COMMENT(
        '[^\\[\\]\\.,\\+\\-<> \r\n]',
        '[\\[\\]\\.,\\+\\-<> \r\n]',
        {
          returnEnd: true,
          relevance: 0
        }
      ),
      {
        className: 'title',
        begin: '[\\[\\]]',
        relevance: 0
      },
      {
        className: 'string',
        begin: '[\\.,]',
        relevance: 0
      },
      {
        // this mode works as the only relevance counter
        begin: /\+\+|\-\-/, returnBegin: true,
        contains: [LITERAL]
      },
      LITERAL
    ]
  };
});

hljs.registerLanguage('cal', function(hljs) {
  var KEYWORDS =
    'div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to ' +
    'until while with var';
  var LITERALS = 'false true';
  var COMMENT_MODES = [
    hljs.C_LINE_COMMENT_MODE,
    hljs.COMMENT(
      /\{/,
      /\}/,
      {
        relevance: 0
      }
    ),
    hljs.COMMENT(
      /\(\*/,
      /\*\)/,
      {
        relevance: 10
      }
    )
  ];
  var STRING = {
    className: 'string',
    begin: /'/, end: /'/,
    contains: [{begin: /''/}]
  };
  var CHAR_STRING = {
    className: 'string', begin: /(#\d+)+/
  };
  var DATE = {
      className: 'date',
      begin: '\\b\\d+(\\.\\d+)?(DT|D|T)',
      relevance: 0
  };
  var DBL_QUOTED_VARIABLE = {
      className: 'variable',
      begin: '"',
      end: '"'
  };

  var PROCEDURE = {
    className: 'function',
    beginKeywords: 'procedure', end: /[:;]/,
    keywords: 'procedure|10',
    contains: [
      hljs.TITLE_MODE,
      {
        className: 'params',
        begin: /\(/, end: /\)/,
        keywords: KEYWORDS,
        contains: [STRING, CHAR_STRING]
      }
    ].concat(COMMENT_MODES)
  };

  var OBJECT = {
    className: 'class',
    begin: 'OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\d+) ([^\\r\\n]+)',
    returnBegin: true,
    contains: [
      hljs.TITLE_MODE,
        PROCEDURE
    ]
  };

  return {
    case_insensitive: true,
    keywords: { keyword: KEYWORDS, literal: LITERALS },
    illegal: /\/\*/,
    contains: [
      STRING, CHAR_STRING,
      DATE, DBL_QUOTED_VARIABLE,
      hljs.NUMBER_MODE,
      OBJECT,
      PROCEDURE
    ]
  };
});

hljs.registerLanguage('capnproto', function(hljs) {
  return {
    aliases: ['capnp'],
    keywords: {
      keyword:
        'struct enum interface union group import using const annotation extends in of on as with from fixed',
      built_in:
        'Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 ' +
        'Text Data AnyPointer AnyStruct Capability List',
      literal:
        'true false'
    },
    contains: [
      hljs.QUOTE_STRING_MODE,
      hljs.NUMBER_MODE,
      hljs.HASH_COMMENT_MODE,
      {
        className: 'shebang',
        begin: /@0x[\w\d]{16};/,
        illegal: /\n/
      },
      {
        className: 'number',
        begin: /@\d+\b/
      },
      {
        className: 'class',
        beginKeywords: 'struct enum', end: /\{/,
        illegal: /\n/,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {
            starts: {endsWithParent: true, excludeEnd: true} // hack: eating everything after the first title
          })
        ]
      },
      {
        className: 'class',
        beginKeywords: 'interface', end: /\{/,
        illegal: /\n/,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {
            starts: {endsWithParent: true, excludeEnd: true} // hack: eating everything after the first title
          })
        ]
      }
    ]
  };
});

hljs.registerLanguage('ceylon', function(hljs) {
  // 2.3. Identifiers and keywords
  var KEYWORDS =
    'assembly module package import alias class interface object given value ' +
    'assign void function new of extends satisfies abstracts in out return ' +
    'break continue throw assert dynamic if else switch case for while try ' +
    'catch finally then let this outer super is exists nonempty';
  // 7.4.1 Declaration Modifiers
  var DECLARATION_MODIFIERS =
    'shared abstract formal default actual variable late native deprecated' +
    'final sealed annotation suppressWarnings small';
  // 7.4.2 Documentation
  var DOCUMENTATION =
    'doc by license see throws tagged';
  var LANGUAGE_ANNOTATIONS = DECLARATION_MODIFIERS + ' ' + DOCUMENTATION;
  var SUBST = {
    className: 'subst', excludeBegin: true, excludeEnd: true,
    begin: /``/, end: /``/,
    keywords: KEYWORDS,
    relevance: 10
  };
  var EXPRESSIONS = [
    {
      // verbatim string
      className: 'string',
      begin: '"""',
      end: '"""',
      relevance: 10
    },
    {
      // string literal or template
      className: 'string',
      begin: '"', end: '"',
      contains: [SUBST]
    },
    {
      // character literal
      className: 'string',
      begin: "'",
      end: "'"
    },
    {
      // numeric literal
      className: 'number',
      begin: '#[0-9a-fA-F_]+|\\$[01_]+|[0-9_]+(?:\\.[0-9_](?:[eE][+-]?\\d+)?)?[kMGTPmunpf]?',
      relevance: 0
    }
  ];
  SUBST.contains = EXPRESSIONS;

  return {
    keywords: {
      keyword: KEYWORDS,
      annotation: LANGUAGE_ANNOTATIONS
    },
    illegal: '\\$[^01]|#[^0-9a-fA-F]',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.COMMENT('/\\*', '\\*/', {contains: ['self']}),
      {
        // compiler annotation
        className: 'annotation',
        begin: '@[a-z]\\w*(?:\\:\"[^\"]*\")?'
      }
    ].concat(EXPRESSIONS)
  };
});

hljs.registerLanguage('clojure', function(hljs) {
  var keywords = {
    built_in:
      // Clojure keywords
      'def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem '+
      'quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? '+
      'set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? '+
      'class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? '+
      'string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . '+
      'inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last '+
      'drop-while while intern condp case reduced cycle split-at split-with repeat replicate '+
      'iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext '+
      'nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends '+
      'add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler '+
      'set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter '+
      'monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or '+
      'when when-not when-let comp juxt partial sequence memoize constantly complement identity assert '+
      'peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast '+
      'sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import '+
      'refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! '+
      'assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger '+
      'bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline '+
      'flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking '+
      'assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! '+
      'reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! '+
      'new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty '+
      'hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list '+
      'disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer '+
      'chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate '+
      'unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta '+
      'lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize'
   };

  var SYMBOLSTART = 'a-zA-Z_\\-!.?+*=<>&#\'';
  var SYMBOL_RE = '[' + SYMBOLSTART + '][' + SYMBOLSTART + '0-9/;:]*';
  var SIMPLE_NUMBER_RE = '[-+]?\\d+(\\.\\d+)?';

  var SYMBOL = {
    begin: SYMBOL_RE,
    relevance: 0
  };
  var NUMBER = {
    className: 'number', begin: SIMPLE_NUMBER_RE,
    relevance: 0
  };
  var STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null});
  var COMMENT = hljs.COMMENT(
    ';',
    '$',
    {
      relevance: 0
    }
  );
  var LITERAL = {
    className: 'literal',
    begin: /\b(true|false|nil)\b/
  };
  var COLLECTION = {
    className: 'collection',
    begin: '[\\[\\{]', end: '[\\]\\}]'
  };
  var HINT = {
    className: 'comment',
    begin: '\\^' + SYMBOL_RE
  };
  var HINT_COL = hljs.COMMENT('\\^\\{', '\\}');
  var KEY = {
    className: 'attribute',
    begin: '[:]' + SYMBOL_RE
  };
  var LIST = {
    className: 'list',
    begin: '\\(', end: '\\)'
  };
  var BODY = {
    endsWithParent: true,
    relevance: 0
  };
  var NAME = {
    keywords: keywords,
    lexemes: SYMBOL_RE,
    className: 'keyword', begin: SYMBOL_RE,
    starts: BODY
  };
  var DEFAULT_CONTAINS = [LIST, STRING, HINT, HINT_COL, COMMENT, KEY, COLLECTION, NUMBER, LITERAL, SYMBOL];

  LIST.contains = [hljs.COMMENT('comment', ''), NAME, BODY];
  BODY.contains = DEFAULT_CONTAINS;
  COLLECTION.contains = DEFAULT_CONTAINS;

  return {
    aliases: ['clj'],
    illegal: /\S/,
    contains: [LIST, STRING, HINT, HINT_COL, COMMENT, KEY, COLLECTION, NUMBER, LITERAL]
  }
});

hljs.registerLanguage('clojure-repl', function(hljs) {
  return {
    contains: [
      {
        className: 'prompt',
        begin: /^([\w.-]+|\s*#_)=>/,
        starts: {
          end: /$/,
          subLanguage: 'clojure'
        }
      }
    ]
  }
});

hljs.registerLanguage('cmake', function(hljs) {
  return {
    aliases: ['cmake.in'],
    case_insensitive: true,
    keywords: {
      keyword:
        'add_custom_command add_custom_target add_definitions add_dependencies ' +
        'add_executable add_library add_subdirectory add_test aux_source_directory ' +
        'break build_command cmake_minimum_required cmake_policy configure_file ' +
        'create_test_sourcelist define_property else elseif enable_language enable_testing ' +
        'endforeach endfunction endif endmacro endwhile execute_process export find_file ' +
        'find_library find_package find_path find_program fltk_wrap_ui foreach function ' +
        'get_cmake_property get_directory_property get_filename_component get_property ' +
        'get_source_file_property get_target_property get_test_property if include ' +
        'include_directories include_external_msproject include_regular_expression install ' +
        'link_directories load_cache load_command macro mark_as_advanced message option ' +
        'output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return ' +
        'separate_arguments set set_directory_properties set_property ' +
        'set_source_files_properties set_target_properties set_tests_properties site_name ' +
        'source_group string target_link_libraries try_compile try_run unset variable_watch ' +
        'while build_name exec_program export_library_dependencies install_files ' +
        'install_programs install_targets link_libraries make_directory remove subdir_depends ' +
        'subdirs use_mangled_mesa utility_source variable_requires write_file ' +
        'qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or',
      operator:
        'equal less greater strless strgreater strequal matches'
    },
    contains: [
      {
        className: 'envvar',
        begin: '\\${', end: '}'
      },
      hljs.HASH_COMMENT_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('coffeescript', function(hljs) {
  var KEYWORDS = {
    keyword:
      // JS keywords
      'in if for while finally new do return else break catch instanceof throw try this ' +
      'switch continue typeof delete debugger super ' +
      // Coffee keywords
      'then unless until loop of by when and or is isnt not',
    literal:
      // JS literals
      'true false null undefined ' +
      // Coffee literals
      'yes no on off',
    built_in:
      'npm require console print module global window document'
  };
  var JS_IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
  var SUBST = {
    className: 'subst',
    begin: /#\{/, end: /}/,
    keywords: KEYWORDS
  };
  var EXPRESSIONS = [
    hljs.BINARY_NUMBER_MODE,
    hljs.inherit(hljs.C_NUMBER_MODE, {starts: {end: '(\\s*/)?', relevance: 0}}), // a number tries to eat the following slash to prevent treating it as a regexp
    {
      className: 'string',
      variants: [
        {
          begin: /'''/, end: /'''/,
          contains: [hljs.BACKSLASH_ESCAPE]
        },
        {
          begin: /'/, end: /'/,
          contains: [hljs.BACKSLASH_ESCAPE]
        },
        {
          begin: /"""/, end: /"""/,
          contains: [hljs.BACKSLASH_ESCAPE, SUBST]
        },
        {
          begin: /"/, end: /"/,
          contains: [hljs.BACKSLASH_ESCAPE, SUBST]
        }
      ]
    },
    {
      className: 'regexp',
      variants: [
        {
          begin: '///', end: '///',
          contains: [SUBST, hljs.HASH_COMMENT_MODE]
        },
        {
          begin: '//[gim]*',
          relevance: 0
        },
        {
          // regex can't start with space to parse x / 2 / 3 as two divisions
          // regex can't start with *, and it supports an "illegal" in the main mode
          begin: /\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/
        }
      ]
    },
    {
      className: 'property',
      begin: '@' + JS_IDENT_RE
    },
    {
      begin: '`', end: '`',
      excludeBegin: true, excludeEnd: true,
      subLanguage: 'javascript'
    }
  ];
  SUBST.contains = EXPRESSIONS;

  var TITLE = hljs.inherit(hljs.TITLE_MODE, {begin: JS_IDENT_RE});
  var PARAMS_RE = '(\\(.*\\))?\\s*\\B[-=]>';
  var PARAMS = {
    className: 'params',
    begin: '\\([^\\(]', returnBegin: true,
    /* We need another contained nameless mode to not have every nested
    pair of parens to be called "params" */
    contains: [{
      begin: /\(/, end: /\)/,
      keywords: KEYWORDS,
      contains: ['self'].concat(EXPRESSIONS)
    }]
  };

  return {
    aliases: ['coffee', 'cson', 'iced'],
    keywords: KEYWORDS,
    illegal: /\/\*/,
    contains: EXPRESSIONS.concat([
      hljs.COMMENT('###', '###'),
      hljs.HASH_COMMENT_MODE,
      {
        className: 'function',
        begin: '^\\s*' + JS_IDENT_RE + '\\s*=\\s*' + PARAMS_RE, end: '[-=]>',
        returnBegin: true,
        contains: [TITLE, PARAMS]
      },
      {
        // anonymous function start
        begin: /[:\(,=]\s*/,
        relevance: 0,
        contains: [
          {
            className: 'function',
            begin: PARAMS_RE, end: '[-=]>',
            returnBegin: true,
            contains: [PARAMS]
          }
        ]
      },
      {
        className: 'class',
        beginKeywords: 'class',
        end: '$',
        illegal: /[:="\[\]]/,
        contains: [
          {
            beginKeywords: 'extends',
            endsWithParent: true,
            illegal: /[:="\[\]]/,
            contains: [TITLE]
          },
          TITLE
        ]
      },
      {
        className: 'attribute',
        begin: JS_IDENT_RE + ':', end: ':',
        returnBegin: true, returnEnd: true,
        relevance: 0
      }
    ])
  };
});

hljs.registerLanguage('cpp', function(hljs) {
  var CPP_PRIMATIVE_TYPES = {
    className: 'keyword',
    begin: '\\b[a-z\\d_]*_t\\b'
  };

  var STRINGS = {
    className: 'string',
    variants: [
      hljs.inherit(hljs.QUOTE_STRING_MODE, { begin: '((u8?|U)|L)?"' }),
      {
        begin: '(u8?|U)?R"', end: '"',
        contains: [hljs.BACKSLASH_ESCAPE]
      },
      {
        begin: '\'\\\\?.', end: '\'',
        illegal: '.'
      }
    ]
  };

  var NUMBERS = {
    className: 'number',
    variants: [
      { begin: '\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)' },
      { begin: hljs.C_NUMBER_RE }
    ]
  };

  var PREPROCESSOR =       {
    className: 'preprocessor',
    begin: '#', end: '$',
    keywords: 'if else elif endif define undef warning error line ' +
              'pragma ifdef ifndef',
    contains: [
      {
        begin: /\\\n/, relevance: 0
      },
      {
        beginKeywords: 'include', end: '$',
        contains: [
          STRINGS,
          {
            className: 'string',
            begin: '<', end: '>',
            illegal: '\\n',
          }
        ]
      },
      STRINGS,
      NUMBERS,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE
    ]
  };

  var FUNCTION_TITLE = hljs.IDENT_RE + '\\s*\\(';

  var CPP_KEYWORDS = {
    keyword: 'int float while private char catch export virtual operator sizeof ' +
      'dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace ' +
      'unsigned long volatile static protected bool template mutable if public friend ' +
      'do goto auto void enum else break extern using class asm case typeid ' +
      'short reinterpret_cast|10 default double register explicit signed typename try this ' +
      'switch continue inline delete alignof constexpr decltype ' +
      'noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary ' +
      'atomic_bool atomic_char atomic_schar ' +
      'atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong ' +
      'atomic_ullong',
    built_in: 'std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream ' +
      'auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set ' +
      'unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos ' +
      'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' +
      'fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' +
      'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' +
      'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' +
      'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' +
      'vfprintf vprintf vsprintf',
    literal: 'true false nullptr NULL'
  };

  return {
    aliases: ['c', 'cc', 'h', 'c++', 'h++', 'hpp'],
    keywords: CPP_KEYWORDS,
    illegal: '</',
    contains: [
      CPP_PRIMATIVE_TYPES,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      NUMBERS,
      STRINGS,
      PREPROCESSOR,
      {
        begin: '\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<', end: '>',
        keywords: CPP_KEYWORDS,
        contains: ['self', CPP_PRIMATIVE_TYPES]
      },
      {
        begin: hljs.IDENT_RE + '::',
        keywords: CPP_KEYWORDS
      },
      {
        // Expression keywords prevent 'keyword Name(...) or else if(...)' from
        // being recognized as a function definition
        beginKeywords: 'new throw return else',
        relevance: 0
      },
      {
        className: 'function',
        begin: '(' + hljs.IDENT_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
        returnBegin: true, end: /[{;=]/,
        excludeEnd: true,
        keywords: CPP_KEYWORDS,
        illegal: /[^\w\s\*&]/,
        contains: [
          {
            begin: FUNCTION_TITLE, returnBegin: true,
            contains: [hljs.TITLE_MODE],
            relevance: 0
          },
          {
            className: 'params',
            begin: /\(/, end: /\)/,
            keywords: CPP_KEYWORDS,
            relevance: 0,
            contains: [
              hljs.C_LINE_COMMENT_MODE,
              hljs.C_BLOCK_COMMENT_MODE,
              STRINGS,
              NUMBERS
            ]
          },
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE,
          PREPROCESSOR
        ]
      }
    ]
  };
});

hljs.registerLanguage('crmsh', function(hljs) {
  var RESOURCES = 'primitive rsc_template';

  var COMMANDS = 'group clone ms master location colocation order fencing_topology ' +
      'rsc_ticket acl_target acl_group user role ' +
      'tag xml';

  var PROPERTY_SETS = 'property rsc_defaults op_defaults';

  var KEYWORDS = 'params meta operations op rule attributes utilization';

  var OPERATORS = 'read write deny defined not_defined in_range date spec in ' +
      'ref reference attribute type xpath version and or lt gt tag ' +
      'lte gte eq ne \\';

  var TYPES = 'number string';

  var LITERALS = 'Master Started Slave Stopped start promote demote stop monitor true false';

  return {
    aliases: ['crm', 'pcmk'],
    case_insensitive: true,
    keywords: {
      keyword: KEYWORDS,
      operator: OPERATORS,
      type: TYPES,
      literal: LITERALS
    },
    contains: [
      hljs.HASH_COMMENT_MODE,
      {
        beginKeywords: 'node',
        starts: {
          className: 'identifier',
          end: '\\s*([\\w_-]+:)?',
          starts: {
            className: 'title',
            end: '\\s*[\\$\\w_][\\w_-]*'
          }
        }
      },
      {
        beginKeywords: RESOURCES,
        starts: {
          className: 'title',
          end: '\\s*[\\$\\w_][\\w_-]*',
          starts: {
            className: 'pragma',
            end: '\\s*@?[\\w_][\\w_\\.:-]*',
          }
        }
      },
      {
        begin: '\\b(' + COMMANDS.split(' ').join('|') + ')\\s+',
        keywords: COMMANDS,
        starts: {
          className: 'title',
          end: '[\\$\\w_][\\w_-]*',
        }
      },
      {
        beginKeywords: PROPERTY_SETS,
        starts: {
          className: 'title',
          end: '\\s*([\\w_-]+:)?'
        }
      },
      hljs.QUOTE_STRING_MODE,
      {
        className: 'pragma',
        begin: '(ocf|systemd|service|lsb):[\\w_:-]+',
        relevance: 0
      },
      {
        className: 'number',
        begin: '\\b\\d+(\\.\\d+)?(ms|s|h|m)?',
        relevance: 0
      },
      {
        className: 'number',
        begin: '[-]?(infinity|inf)',
        relevance: 0
      },
      {
        className: 'variable',
        begin: /([A-Za-z\$_\#][\w_-]+)=/,
        relevance: 0
      },
      {
        className: 'tag',
        begin: '</?',
        end: '/?>',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('crystal', function(hljs) {
  var NUM_SUFFIX = '(_[uif](8|16|32|64))?';
  var CRYSTAL_IDENT_RE = '[a-zA-Z_]\\w*[!?=]?';
  var RE_STARTER = '!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|' +
    '>>|>|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
  var CRYSTAL_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\][=?]?';
  var CRYSTAL_KEYWORDS = {
    keyword:
      'abstract alias as asm begin break case class def do else elsif end ensure enum extend for fun if ifdef ' +
      'include instance_sizeof is_a? lib macro module next of out pointerof private protected rescue responds_to? ' +
      'return require self sizeof struct super then type typeof union unless until when while with yield ' +
      '__DIR__ __FILE__ __LINE__',
    literal: 'false nil true'
  };
  var SUBST = {
    className: 'subst',
    begin: '#{', end: '}',
    keywords: CRYSTAL_KEYWORDS
  };
  var EXPANSION = {
    className: 'expansion',
    variants: [
      {begin: '\\{\\{', end: '\\}\\}'},
      {begin: '\\{%', end: '%\\}'}
    ],
    keywords: CRYSTAL_KEYWORDS,
    relevance: 10
  };

  function recursiveParen(begin, end) {
    var
    contains = [{begin: begin, end: end}];
    contains[0].contains = contains;
    return contains;
  }
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {begin: /'/, end: /'/},
      {begin: /"/, end: /"/},
      {begin: /`/, end: /`/},
      {begin: '%w?\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
      {begin: '%w?\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
      {begin: '%w?{', end: '}', contains: recursiveParen('{', '}')},
      {begin: '%w?<', end: '>', contains: recursiveParen('<', '>')},
      {begin: '%w?/', end: '/'},
      {begin: '%w?%', end: '%'},
      {begin: '%w?-', end: '-'},
      {begin: '%w?\\|', end: '\\|'},
    ],
    relevance: 0,
  };
  var REGEXP = {
    begin: '(' + RE_STARTER + ')\\s*',
    contains: [
      {
        className: 'regexp',
        contains: [hljs.BACKSLASH_ESCAPE, SUBST],
        variants: [
          {begin: '/', end: '/[a-z]*'},
          {begin: '%r\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
          {begin: '%r\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
          {begin: '%r{', end: '}', contains: recursiveParen('{', '}')},
          {begin: '%r<', end: '>', contains: recursiveParen('<', '>')},
          {begin: '%r/', end: '/'},
          {begin: '%r%', end: '%'},
          {begin: '%r-', end: '-'},
          {begin: '%r\\|', end: '\\|'},
        ]
      }
    ],
    relevance: 0
  };
  var REGEXP2 = {
    className: 'regexp',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {begin: '%r\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
      {begin: '%r\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
      {begin: '%r{', end: '}', contains: recursiveParen('{', '}')},
      {begin: '%r<', end: '>', contains: recursiveParen('<', '>')},
      {begin: '%r/', end: '/'},
      {begin: '%r%', end: '%'},
      {begin: '%r-', end: '-'},
      {begin: '%r\\|', end: '\\|'},
    ],
    relevance: 0
  };
  var ATTRIBUTE = {
    className: 'annotation',
    begin: '@\\[', end: '\\]',
    relevance: 5
  };
  var CRYSTAL_DEFAULT_CONTAINS = [
    EXPANSION,
    STRING,
    REGEXP,
    REGEXP2,
    ATTRIBUTE,
    hljs.HASH_COMMENT_MODE,
    {
      className: 'class',
      beginKeywords: 'class module struct', end: '$|;',
      illegal: /=/,
      contains: [
        hljs.HASH_COMMENT_MODE,
        hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
        {
          className: 'inheritance',
          begin: '<\\s*',
          contains: [{
            className: 'parent',
            begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
          }]
        }
      ]
    },
    {
      className: 'class',
      beginKeywords: 'lib enum union', end: '$|;',
      illegal: /=/,
      contains: [
        hljs.HASH_COMMENT_MODE,
        hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
      ],
      relevance: 10
    },
    {
      className: 'function',
      beginKeywords: 'def', end: /\B\b/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {
          begin: CRYSTAL_METHOD_RE,
          endsParent: true
        })
      ]
    },
    {
      className: 'function',
      beginKeywords: 'fun macro', end: /\B\b/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {
          begin: CRYSTAL_METHOD_RE,
          endsParent: true
        })
      ],
      relevance: 5
    },
    {
      className: 'constant',
      begin: '(::)?(\\b[A-Z]\\w*(::)?)+',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':',
      contains: [STRING, {begin: CRYSTAL_METHOD_RE}],
      relevance: 0
    },
    {
      className: 'number',
      variants: [
        { begin: '\\b0b([01_]*[01])' + NUM_SUFFIX },
        { begin: '\\b0o([0-7_]*[0-7])' + NUM_SUFFIX },
        { begin: '\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])' + NUM_SUFFIX },
        { begin: '\\b(([0-9][0-9_]*[0-9]|[0-9])(\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)' + NUM_SUFFIX}
      ],
      relevance: 0
    },
    {
      className: 'variable',
      begin: '(\\$\\W)|((\\$|\\@\\@?|%)(\\w+))'
    }
  ];
  SUBST.contains = CRYSTAL_DEFAULT_CONTAINS;
  ATTRIBUTE.contains = CRYSTAL_DEFAULT_CONTAINS;
  EXPANSION.contains = CRYSTAL_DEFAULT_CONTAINS.slice(1); // without EXPANSION

  return {
    aliases: ['cr'],
    lexemes: CRYSTAL_IDENT_RE,
    keywords: CRYSTAL_KEYWORDS,
    contains: CRYSTAL_DEFAULT_CONTAINS
  };
});

hljs.registerLanguage('cs', function(hljs) {
  var KEYWORDS =
    // Normal keywords.
    'abstract as base bool break byte case catch char checked const continue decimal dynamic ' +
    'default delegate do double else enum event explicit extern false finally fixed float ' +
    'for foreach goto if implicit in int interface internal is lock long null when ' +
    'object operator out override params private protected public readonly ref sbyte ' +
    'sealed short sizeof stackalloc static string struct switch this true try typeof ' +
    'uint ulong unchecked unsafe ushort using virtual volatile void while async ' +
    'protected public private internal ' +
    // Contextual keywords.
    'ascending descending from get group into join let orderby partial select set value var ' +
    'where yield';
  var GENERIC_IDENT_RE = hljs.IDENT_RE + '(<' + hljs.IDENT_RE + '>)?';
  return {
    aliases: ['csharp'],
    keywords: KEYWORDS,
    illegal: /::/,
    contains: [
      hljs.COMMENT(
        '///',
        '$',
        {
          returnBegin: true,
          contains: [
            {
              className: 'xmlDocTag',
              variants: [
                {
                  begin: '///', relevance: 0
                },
                {
                  begin: '<!--|-->'
                },
                {
                  begin: '</?', end: '>'
                }
              ]
            }
          ]
        }
      ),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'preprocessor',
        begin: '#', end: '$',
        keywords: 'if else elif endif define undef warning error line region endregion pragma checksum'
      },
      {
        className: 'string',
        begin: '@"', end: '"',
        contains: [{begin: '""'}]
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      {
        beginKeywords: 'class interface', end: /[{;=]/,
        illegal: /[^\s:]/,
        contains: [
          hljs.TITLE_MODE,
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE
        ]
      },
      {
        beginKeywords: 'namespace', end: /[{;=]/,
        illegal: /[^\s:]/,
        contains: [
          {
            // Customization of hljs.TITLE_MODE that allows '.'
            className: 'title',
            begin: '[a-zA-Z](\\.?\\w)*',
            relevance: 0
          },
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE
        ]
      },
      {
        // Expression keywords prevent 'keyword Name(...)' from being
        // recognized as a function definition
        beginKeywords: 'new return throw await',
        relevance: 0
      },
      {
        className: 'function',
        begin: '(' + GENERIC_IDENT_RE + '\\s+)+' + hljs.IDENT_RE + '\\s*\\(', returnBegin: true, end: /[{;=]/,
        excludeEnd: true,
        keywords: KEYWORDS,
        contains: [
          {
            begin: hljs.IDENT_RE + '\\s*\\(', returnBegin: true,
            contains: [hljs.TITLE_MODE],
            relevance: 0
          },
          {
            className: 'params',
            begin: /\(/, end: /\)/,
            excludeBegin: true,
            excludeEnd: true,
            keywords: KEYWORDS,
            relevance: 0,
            contains: [
              hljs.APOS_STRING_MODE,
              hljs.QUOTE_STRING_MODE,
              hljs.C_NUMBER_MODE,
              hljs.C_BLOCK_COMMENT_MODE
            ]
          },
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE
        ]
      }
    ]
  };
});

hljs.registerLanguage('css', function(hljs) {
  var IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
  var FUNCTION = {
    className: 'function',
    begin: IDENT_RE + '\\(',
    returnBegin: true,
    excludeEnd: true,
    end: '\\('
  };
  var RULE = {
    className: 'rule',
    begin: /[A-Z\_\.\-]+\s*:/, returnBegin: true, end: ';', endsWithParent: true,
    contains: [
      {
        className: 'attribute',
        begin: /\S/, end: ':', excludeEnd: true,
        starts: {
          className: 'value',
          endsWithParent: true, excludeEnd: true,
          contains: [
            FUNCTION,
            hljs.CSS_NUMBER_MODE,
            hljs.QUOTE_STRING_MODE,
            hljs.APOS_STRING_MODE,
            hljs.C_BLOCK_COMMENT_MODE,
            {
              className: 'hexcolor', begin: '#[0-9A-Fa-f]+'
            },
            {
              className: 'important', begin: '!important'
            }
          ]
        }
      }
    ]
  };

  return {
    case_insensitive: true,
    illegal: /[=\/|'\$]/,
    contains: [
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'id', begin: /\#[A-Za-z0-9_-]+/
      },
      {
        className: 'class', begin: /\.[A-Za-z0-9_-]+/
      },
      {
        className: 'attr_selector',
        begin: /\[/, end: /\]/,
        illegal: '$'
      },
      {
        className: 'pseudo',
        begin: /:(:)?[a-zA-Z0-9\_\-\+\(\)"']+/
      },
      {
        className: 'at_rule',
        begin: '@(font-face|page)',
        lexemes: '[a-z-]+',
        keywords: 'font-face page'
      },
      {
        className: 'at_rule',
        begin: '@', end: '[{;]', // at_rule eating first "{" is a good thing
                                 // because it doesn’t let it to be parsed as
                                 // a rule set but instead drops parser into
                                 // the default mode which is how it should be.
        contains: [
          {
            className: 'keyword',
            begin: /\S+/
          },
          {
            begin: /\s/, endsWithParent: true, excludeEnd: true,
            relevance: 0,
            contains: [
              FUNCTION,
              hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE,
              hljs.CSS_NUMBER_MODE
            ]
          }
        ]
      },
      {
        className: 'tag', begin: IDENT_RE,
        relevance: 0
      },
      {
        className: 'rules',
        begin: '{', end: '}',
        illegal: /\S/,
        contains: [
          hljs.C_BLOCK_COMMENT_MODE,
          RULE,
        ]
      }
    ]
  };
});

hljs.registerLanguage('d', /**
 * Known issues:
 *
 * - invalid hex string literals will be recognized as a double quoted strings
 *   but 'x' at the beginning of string will not be matched
 *
 * - delimited string literals are not checked for matching end delimiter
 *   (not possible to do with js regexp)
 *
 * - content of token string is colored as a string (i.e. no keyword coloring inside a token string)
 *   also, content of token string is not validated to contain only valid D tokens
 *
 * - special token sequence rule is not strictly following D grammar (anything following #line
 *   up to the end of line is matched as special token sequence)
 */

function(hljs) {
  /**
   * Language keywords
   *
   * @type {Object}
   */
  var D_KEYWORDS = {
    keyword:
      'abstract alias align asm assert auto body break byte case cast catch class ' +
      'const continue debug default delete deprecated do else enum export extern final ' +
      'finally for foreach foreach_reverse|10 goto if immutable import in inout int ' +
      'interface invariant is lazy macro mixin module new nothrow out override package ' +
      'pragma private protected public pure ref return scope shared static struct ' +
      'super switch synchronized template this throw try typedef typeid typeof union ' +
      'unittest version void volatile while with __FILE__ __LINE__ __gshared|10 ' +
      '__thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__',
    built_in:
      'bool cdouble cent cfloat char creal dchar delegate double dstring float function ' +
      'idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar ' +
      'wstring',
    literal:
      'false null true'
  };

  /**
   * Number literal regexps
   *
   * @type {String}
   */
  var decimal_integer_re = '(0|[1-9][\\d_]*)',
    decimal_integer_nosus_re = '(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)',
    binary_integer_re = '0[bB][01_]+',
    hexadecimal_digits_re = '([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)',
    hexadecimal_integer_re = '0[xX]' + hexadecimal_digits_re,

    decimal_exponent_re = '([eE][+-]?' + decimal_integer_nosus_re + ')',
    decimal_float_re = '(' + decimal_integer_nosus_re + '(\\.\\d*|' + decimal_exponent_re + ')|' +
                '\\d+\\.' + decimal_integer_nosus_re + decimal_integer_nosus_re + '|' +
                '\\.' + decimal_integer_re + decimal_exponent_re + '?' +
              ')',
    hexadecimal_float_re = '(0[xX](' +
                  hexadecimal_digits_re + '\\.' + hexadecimal_digits_re + '|'+
                  '\\.?' + hexadecimal_digits_re +
                 ')[pP][+-]?' + decimal_integer_nosus_re + ')',

    integer_re = '(' +
      decimal_integer_re + '|' +
      binary_integer_re  + '|' +
       hexadecimal_integer_re   +
    ')',

    float_re = '(' +
      hexadecimal_float_re + '|' +
      decimal_float_re  +
    ')';

  /**
   * Escape sequence supported in D string and character literals
   *
   * @type {String}
   */
  var escape_sequence_re = '\\\\(' +
              '[\'"\\?\\\\abfnrtv]|' +  // common escapes
              'u[\\dA-Fa-f]{4}|' +     // four hex digit unicode codepoint
              '[0-7]{1,3}|' +       // one to three octal digit ascii char code
              'x[\\dA-Fa-f]{2}|' +    // two hex digit ascii char code
              'U[\\dA-Fa-f]{8}' +      // eight hex digit unicode codepoint
              ')|' +
              '&[a-zA-Z\\d]{2,};';      // named character entity

  /**
   * D integer number literals
   *
   * @type {Object}
   */
  var D_INTEGER_MODE = {
    className: 'number',
      begin: '\\b' + integer_re + '(L|u|U|Lu|LU|uL|UL)?',
      relevance: 0
  };

  /**
   * [D_FLOAT_MODE description]
   * @type {Object}
   */
  var D_FLOAT_MODE = {
    className: 'number',
    begin: '\\b(' +
        float_re + '([fF]|L|i|[fF]i|Li)?|' +
        integer_re + '(i|[fF]i|Li)' +
      ')',
    relevance: 0
  };

  /**
   * D character literal
   *
   * @type {Object}
   */
  var D_CHARACTER_MODE = {
    className: 'string',
    begin: '\'(' + escape_sequence_re + '|.)', end: '\'',
    illegal: '.'
  };

  /**
   * D string escape sequence
   *
   * @type {Object}
   */
  var D_ESCAPE_SEQUENCE = {
    begin: escape_sequence_re,
    relevance: 0
  };

  /**
   * D double quoted string literal
   *
   * @type {Object}
   */
  var D_STRING_MODE = {
    className: 'string',
    begin: '"',
    contains: [D_ESCAPE_SEQUENCE],
    end: '"[cwd]?'
  };

  /**
   * D wysiwyg and delimited string literals
   *
   * @type {Object}
   */
  var D_WYSIWYG_DELIMITED_STRING_MODE = {
    className: 'string',
    begin: '[rq]"',
    end: '"[cwd]?',
    relevance: 5
  };

  /**
   * D alternate wysiwyg string literal
   *
   * @type {Object}
   */
  var D_ALTERNATE_WYSIWYG_STRING_MODE = {
    className: 'string',
    begin: '`',
    end: '`[cwd]?'
  };

  /**
   * D hexadecimal string literal
   *
   * @type {Object}
   */
  var D_HEX_STRING_MODE = {
    className: 'string',
    begin: 'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',
    relevance: 10
  };

  /**
   * D delimited string literal
   *
   * @type {Object}
   */
  var D_TOKEN_STRING_MODE = {
    className: 'string',
    begin: 'q"\\{',
    end: '\\}"'
  };

  /**
   * Hashbang support
   *
   * @type {Object}
   */
  var D_HASHBANG_MODE = {
    className: 'shebang',
    begin: '^#!',
    end: '$',
    relevance: 5
  };

  /**
   * D special token sequence
   *
   * @type {Object}
   */
  var D_SPECIAL_TOKEN_SEQUENCE_MODE = {
    className: 'preprocessor',
    begin: '#(line)',
    end: '$',
    relevance: 5
  };

  /**
   * D attributes
   *
   * @type {Object}
   */
  var D_ATTRIBUTE_MODE = {
    className: 'keyword',
    begin: '@[a-zA-Z_][a-zA-Z_\\d]*'
  };

  /**
   * D nesting comment
   *
   * @type {Object}
   */
  var D_NESTING_COMMENT_MODE = hljs.COMMENT(
    '\\/\\+',
    '\\+\\/',
    {
      contains: ['self'],
      relevance: 10
    }
  );

  return {
    lexemes: hljs.UNDERSCORE_IDENT_RE,
    keywords: D_KEYWORDS,
    contains: [
      hljs.C_LINE_COMMENT_MODE,
        hljs.C_BLOCK_COMMENT_MODE,
        D_NESTING_COMMENT_MODE,
        D_HEX_STRING_MODE,
        D_STRING_MODE,
        D_WYSIWYG_DELIMITED_STRING_MODE,
        D_ALTERNATE_WYSIWYG_STRING_MODE,
        D_TOKEN_STRING_MODE,
        D_FLOAT_MODE,
        D_INTEGER_MODE,
        D_CHARACTER_MODE,
        D_HASHBANG_MODE,
        D_SPECIAL_TOKEN_SEQUENCE_MODE,
        D_ATTRIBUTE_MODE
    ]
  };
});

hljs.registerLanguage('markdown', function(hljs) {
  return {
    aliases: ['md', 'mkdown', 'mkd'],
    contains: [
      // highlight headers
      {
        className: 'header',
        variants: [
          { begin: '^#{1,6}', end: '$' },
          { begin: '^.+?\\n[=-]{2,}$' }
        ]
      },
      // inline html
      {
        begin: '<', end: '>',
        subLanguage: 'xml',
        relevance: 0
      },
      // lists (indicators only)
      {
        className: 'bullet',
        begin: '^([*+-]|(\\d+\\.))\\s+'
      },
      // strong segments
      {
        className: 'strong',
        begin: '[*_]{2}.+?[*_]{2}'
      },
      // emphasis segments
      {
        className: 'emphasis',
        variants: [
          { begin: '\\*.+?\\*' },
          { begin: '_.+?_'
          , relevance: 0
          }
        ]
      },
      // blockquotes
      {
        className: 'blockquote',
        begin: '^>\\s+', end: '$'
      },
      // code snippets
      {
        className: 'code',
        variants: [
          { begin: '`.+?`' },
          { begin: '^( {4}|\t)', end: '$'
          , relevance: 0
          }
        ]
      },
      // horizontal rules
      {
        className: 'horizontal_rule',
        begin: '^[-\\*]{3,}', end: '$'
      },
      // using links - title and link
      {
        begin: '\\[.+?\\][\\(\\[].*?[\\)\\]]',
        returnBegin: true,
        contains: [
          {
            className: 'link_label',
            begin: '\\[', end: '\\]',
            excludeBegin: true,
            returnEnd: true,
            relevance: 0
          },
          {
            className: 'link_url',
            begin: '\\]\\(', end: '\\)',
            excludeBegin: true, excludeEnd: true
          },
          {
            className: 'link_reference',
            begin: '\\]\\[', end: '\\]',
            excludeBegin: true, excludeEnd: true
          }
        ],
        relevance: 10
      },
      {
        begin: '^\\[\.+\\]:',
        returnBegin: true,
        contains: [
          {
            className: 'link_reference',
            begin: '\\[', end: '\\]:',
            excludeBegin: true, excludeEnd: true,
            starts: {
              className: 'link_url',
              end: '$'
            }
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('dart', function (hljs) {
  var SUBST = {
    className: 'subst',
    begin: '\\$\\{', end: '}',
    keywords: 'true false null this is new super'
  };

  var STRING = {
    className: 'string',
    variants: [
      {
        begin: 'r\'\'\'', end: '\'\'\''
      },
      {
        begin: 'r"""', end: '"""'
      },
      {
        begin: 'r\'', end: '\'',
        illegal: '\\n'
      },
      {
        begin: 'r"', end: '"',
        illegal: '\\n'
      },
      {
        begin: '\'\'\'', end: '\'\'\'',
        contains: [hljs.BACKSLASH_ESCAPE, SUBST]
      },
      {
        begin: '"""', end: '"""',
        contains: [hljs.BACKSLASH_ESCAPE, SUBST]
      },
      {
        begin: '\'', end: '\'',
        illegal: '\\n',
        contains: [hljs.BACKSLASH_ESCAPE, SUBST]
      },
      {
        begin: '"', end: '"',
        illegal: '\\n',
        contains: [hljs.BACKSLASH_ESCAPE, SUBST]
      }
    ]
  };
  SUBST.contains = [
    hljs.C_NUMBER_MODE, STRING
  ];

  var KEYWORDS = {
    keyword: 'assert break case catch class const continue default do else enum extends false final finally for if ' +
      'in is new null rethrow return super switch this throw true try var void while with',
    literal: 'abstract as dynamic export external factory get implements import library operator part set static typedef',
    built_in:
      // dart:core
      'print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set ' +
      'Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num ' +
      // dart:html
      'document window querySelector querySelectorAll Element ElementList'
  };

  return {
    keywords: KEYWORDS,
    contains: [
      STRING,
      hljs.COMMENT(
        '/\\*\\*',
        '\\*/',
        {
          subLanguage: 'markdown'
        }
      ),
      hljs.COMMENT(
        '///',
        '$',
        {
          subLanguage: 'markdown'
        }
      ),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'class',
        beginKeywords: 'class interface', end: '{', excludeEnd: true,
        contains: [
          {
            beginKeywords: 'extends implements'
          },
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      hljs.C_NUMBER_MODE,
      {
        className: 'annotation', begin: '@[A-Za-z]+'
      },
      {
        begin: '=>' // No markup, just a relevance booster
      }
    ]
  }
});

hljs.registerLanguage('delphi', function(hljs) {
  var KEYWORDS =
    'exports register file shl array record property for mod while set ally label uses raise not ' +
    'stored class safecall var interface or private static exit index inherited to else stdcall ' +
    'override shr asm far resourcestring finalization packed virtual out and protected library do ' +
    'xorwrite goto near function end div overload object unit begin string on inline repeat until ' +
    'destructor write message program with read initialization except default nil if case cdecl in ' +
    'downto threadvar of try pascal const external constructor type public then implementation ' +
    'finally published procedure';
  var COMMENT_MODES = [
    hljs.C_LINE_COMMENT_MODE,
    hljs.COMMENT(
      /\{/,
      /\}/,
      {
        relevance: 0
      }
    ),
    hljs.COMMENT(
      /\(\*/,
      /\*\)/,
      {
        relevance: 10
      }
    )
  ];
  var STRING = {
    className: 'string',
    begin: /'/, end: /'/,
    contains: [{begin: /''/}]
  };
  var CHAR_STRING = {
    className: 'string', begin: /(#\d+)+/
  };
  var CLASS = {
    begin: hljs.IDENT_RE + '\\s*=\\s*class\\s*\\(', returnBegin: true,
    contains: [
      hljs.TITLE_MODE
    ]
  };
  var FUNCTION = {
    className: 'function',
    beginKeywords: 'function constructor destructor procedure', end: /[:;]/,
    keywords: 'function constructor|10 destructor|10 procedure|10',
    contains: [
      hljs.TITLE_MODE,
      {
        className: 'params',
        begin: /\(/, end: /\)/,
        keywords: KEYWORDS,
        contains: [STRING, CHAR_STRING]
      }
    ].concat(COMMENT_MODES)
  };
  return {
    case_insensitive: true,
    keywords: KEYWORDS,
    illegal: /"|\$[G-Zg-z]|\/\*|<\/|\|/,
    contains: [
      STRING, CHAR_STRING,
      hljs.NUMBER_MODE,
      CLASS,
      FUNCTION
    ].concat(COMMENT_MODES)
  };
});

hljs.registerLanguage('diff', function(hljs) {
  return {
    aliases: ['patch'],
    contains: [
      {
        className: 'chunk',
        relevance: 10,
        variants: [
          {begin: /^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},
          {begin: /^\*\*\* +\d+,\d+ +\*\*\*\*$/},
          {begin: /^\-\-\- +\d+,\d+ +\-\-\-\-$/}
        ]
      },
      {
        className: 'header',
        variants: [
          {begin: /Index: /, end: /$/},
          {begin: /=====/, end: /=====$/},
          {begin: /^\-\-\-/, end: /$/},
          {begin: /^\*{3} /, end: /$/},
          {begin: /^\+\+\+/, end: /$/},
          {begin: /\*{5}/, end: /\*{5}$/}
        ]
      },
      {
        className: 'addition',
        begin: '^\\+', end: '$'
      },
      {
        className: 'deletion',
        begin: '^\\-', end: '$'
      },
      {
        className: 'change',
        begin: '^\\!', end: '$'
      }
    ]
  };
});

hljs.registerLanguage('django', function(hljs) {
  var FILTER = {
    className: 'filter',
    begin: /\|[A-Za-z]+:?/,
    keywords:
      'truncatewords removetags linebreaksbr yesno get_digit timesince random striptags ' +
      'filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands ' +
      'title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode ' +
      'timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort ' +
      'dictsortreversed default_if_none pluralize lower join center default ' +
      'truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first ' +
      'escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize ' +
      'localtime utc timezone',
    contains: [
      {className: 'argument', begin: /"/, end: /"/},
      {className: 'argument', begin: /'/, end: /'/}
    ]
  };

  return {
    aliases: ['jinja'],
    case_insensitive: true,
    subLanguage: 'xml',
    contains: [
      hljs.COMMENT(/\{%\s*comment\s*%}/, /\{%\s*endcomment\s*%}/),
      hljs.COMMENT(/\{#/, /#}/),
      {
        className: 'template_tag',
        begin: /\{%/, end: /%}/,
        keywords:
          'comment endcomment load templatetag ifchanged endifchanged if endif firstof for ' +
          'endfor in ifnotequal endifnotequal widthratio extends include spaceless ' +
          'endspaceless regroup by as ifequal endifequal ssi now with cycle url filter ' +
          'endfilter debug block endblock else autoescape endautoescape csrf_token empty elif ' +
          'endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix ' +
          'plural get_current_language language get_available_languages ' +
          'get_current_language_bidi get_language_info get_language_info_list localize ' +
          'endlocalize localtime endlocaltime timezone endtimezone get_current_timezone ' +
          'verbatim',
        contains: [FILTER]
      },
      {
        className: 'variable',
        begin: /\{\{/, end: /}}/,
        contains: [FILTER]
      }
    ]
  };
});

hljs.registerLanguage('dns', function(hljs) {
  return {
    aliases: ['bind', 'zone'],
    keywords: {
      keyword:
        'IN A AAAA AFSDB APL CAA CDNSKEY CDS CERT CNAME DHCID DLV DNAME DNSKEY DS HIP IPSECKEY KEY KX ' +
        'LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR RRSIG RP SIG SOA SRV SSHFP TA TKEY TLSA TSIG TXT'
    },
    contains: [
      hljs.COMMENT(';', '$'),
      {
        className: 'operator',
        beginKeywords: '$TTL $GENERATE $INCLUDE $ORIGIN'
      },
      // IPv6
      {
        className: 'number',
        begin: '((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))'
      },
      // IPv4
      {
        className: 'number',
        begin: '((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])'
      }
    ]
  };
});

hljs.registerLanguage('dockerfile', function(hljs) {
  return {
    aliases: ['docker'],
    case_insensitive: true,
    keywords: {
      built_ins: 'from maintainer cmd expose add copy entrypoint volume user workdir onbuild run env label'
    },
    contains: [
      hljs.HASH_COMMENT_MODE,
      {
        keywords : {
          built_in: 'run cmd entrypoint volume add copy workdir onbuild label'
        },
        begin: /^ *(onbuild +)?(run|cmd|entrypoint|volume|add|copy|workdir|label) +/,
        starts: {
          end: /[^\\]\n/,
          subLanguage: 'bash'
        }
      },
      {
        keywords: {
          built_in: 'from maintainer expose env user onbuild'
        },
        begin: /^ *(onbuild +)?(from|maintainer|expose|env|user|onbuild) +/, end: /[^\\]\n/,
        contains: [
          hljs.APOS_STRING_MODE,
          hljs.QUOTE_STRING_MODE,
          hljs.NUMBER_MODE,
          hljs.HASH_COMMENT_MODE
        ]
      }
    ]
  }
});

hljs.registerLanguage('dos', function(hljs) {
  var COMMENT = hljs.COMMENT(
    /@?rem\b/, /$/,
    {
      relevance: 10
    }
  );
  var LABEL = {
    className: 'label',
    begin: '^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)',
    relevance: 0
  };
  return {
    aliases: ['bat', 'cmd'],
    case_insensitive: true,
    illegal: /\/\*/,
    keywords: {
      flow: 'if else goto for in do call exit not exist errorlevel defined',
      operator: 'equ neq lss leq gtr geq',
      keyword: 'shift cd dir echo setlocal endlocal set pause copy',
      stream: 'prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux',
      winutils: 'ping net ipconfig taskkill xcopy ren del',
      built_in: 'append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color ' +
        'comp compact convert date dir diskcomp diskcopy doskey erase fs ' +
        'find findstr format ftype graftabl help keyb label md mkdir mode more move path ' +
        'pause print popd pushd promt rd recover rem rename replace restore rmdir shift' +
        'sort start subst time title tree type ver verify vol'
    },
    contains: [
      {
        className: 'envvar', begin: /%%[^ ]|%[^ ]+?%|![^ ]+?!/
      },
      {
        className: 'function',
        begin: LABEL.begin, end: 'goto:eof',
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {begin: '([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*'}),
          COMMENT
        ]
      },
      {
        className: 'number', begin: '\\b\\d+',
        relevance: 0
      },
      COMMENT
    ]
  };
});

hljs.registerLanguage('dust', function(hljs) {
  var EXPRESSION_KEYWORDS = 'if eq ne lt lte gt gte select default math sep';
  return {
    aliases: ['dst'],
    case_insensitive: true,
    subLanguage: 'xml',
    contains: [
      {
        className: 'expression',
        begin: '{', end: '}',
        relevance: 0,
        contains: [
          {
            className: 'begin-block', begin: '\#[a-zA-Z\-\ \.]+',
            keywords: EXPRESSION_KEYWORDS
          },
          {
            className: 'string',
            begin: '"', end: '"'
          },
          {
            className: 'end-block', begin: '\\\/[a-zA-Z\-\ \.]+',
            keywords: EXPRESSION_KEYWORDS
          },
          {
            className: 'variable', begin: '[a-zA-Z\-\.]+',
            keywords: EXPRESSION_KEYWORDS,
            relevance: 0
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('elixir', function(hljs) {
  var ELIXIR_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?';
  var ELIXIR_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
  var ELIXIR_KEYWORDS =
    'and false then defined module in return redo retry end for true self when ' +
    'next until do begin unless nil break not case cond alias while ensure or ' +
    'include use alias fn quote';
  var SUBST = {
    className: 'subst',
    begin: '#\\{', end: '}',
    lexemes: ELIXIR_IDENT_RE,
    keywords: ELIXIR_KEYWORDS
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {
        begin: /'/, end: /'/
      },
      {
        begin: /"/, end: /"/
      }
    ]
  };
  var FUNCTION = {
    className: 'function',
    beginKeywords: 'def defp defmacro', end: /\B\b/, // the mode is ended by the title
    contains: [
      hljs.inherit(hljs.TITLE_MODE, {
        begin: ELIXIR_IDENT_RE,
        endsParent: true
      })
    ]
  };
  var CLASS = hljs.inherit(FUNCTION, {
    className: 'class',
    beginKeywords: 'defmodule defrecord', end: /\bdo\b|$|;/
  });
  var ELIXIR_DEFAULT_CONTAINS = [
    STRING,
    hljs.HASH_COMMENT_MODE,
    CLASS,
    FUNCTION,
    {
      className: 'constant',
      begin: '(\\b[A-Z_]\\w*(.)?)+',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':',
      contains: [STRING, {begin: ELIXIR_METHOD_RE}],
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ELIXIR_IDENT_RE + ':',
      relevance: 0
    },
    {
      className: 'number',
      begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
      relevance: 0
    },
    {
      className: 'variable',
      begin: '(\\$\\W)|((\\$|\\@\\@?)(\\w+))'
    },
    {
      begin: '->'
    },
    { // regexp container
      begin: '(' + hljs.RE_STARTERS_RE + ')\\s*',
      contains: [
        hljs.HASH_COMMENT_MODE,
        {
          className: 'regexp',
          illegal: '\\n',
          contains: [hljs.BACKSLASH_ESCAPE, SUBST],
          variants: [
            {
              begin: '/', end: '/[a-z]*'
            },
            {
              begin: '%r\\[', end: '\\][a-z]*'
            }
          ]
        }
      ],
      relevance: 0
    }
  ];
  SUBST.contains = ELIXIR_DEFAULT_CONTAINS;

  return {
    lexemes: ELIXIR_IDENT_RE,
    keywords: ELIXIR_KEYWORDS,
    contains: ELIXIR_DEFAULT_CONTAINS
  };
});

hljs.registerLanguage('elm', function(hljs) {
  var COMMENT_MODES = [
    hljs.COMMENT('--', '$'),
    hljs.COMMENT(
      '{-',
      '-}',
      {
        contains: ['self']
      }
    )
  ];

  var CONSTRUCTOR = {
    className: 'type',
    begin: '\\b[A-Z][\\w\']*', // TODO: other constructors (build-in, infix).
    relevance: 0
  };

  var LIST = {
    className: 'container',
    begin: '\\(', end: '\\)',
    illegal: '"',
    contains: [
      {className: 'type', begin: '\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?'}
    ].concat(COMMENT_MODES)
  };

  var RECORD = {
    className: 'container',
    begin: '{', end: '}',
    contains: LIST.contains
  };

  return {
    keywords:
      'let in if then else case of where module import exposing ' +
      'type alias as infix infixl infixr port',
    contains: [

      // Top-level constructions.

      {
        className: 'module',
        begin: '\\bmodule\\b', end: 'where',
        keywords: 'module where',
        contains: [LIST].concat(COMMENT_MODES),
        illegal: '\\W\\.|;'
      },
      {
        className: 'import',
        begin: '\\bimport\\b', end: '$',
        keywords: 'import|0 as exposing',
        contains: [LIST].concat(COMMENT_MODES),
        illegal: '\\W\\.|;'
      },
      {
        className: 'typedef',
        begin: '\\btype\\b', end: '$',
        keywords: 'type alias',
        contains: [CONSTRUCTOR, LIST, RECORD].concat(COMMENT_MODES)
      },
      {
        className: 'infix',
        beginKeywords: 'infix infixl infixr', end: '$',
        contains: [hljs.C_NUMBER_MODE].concat(COMMENT_MODES)
      },
      {
        className: 'foreign',
        begin: '\\bport\\b', end: '$',
        keywords: 'port',
        contains: COMMENT_MODES
      },

      // Literals and names.

      // TODO: characters.
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      CONSTRUCTOR,
      hljs.inherit(hljs.TITLE_MODE, {begin: '^[_a-z][\\w\']*'}),

      {begin: '->|<-'} // No markup, relevance booster
    ].concat(COMMENT_MODES)
  };
});

hljs.registerLanguage('ruby', function(hljs) {
  var RUBY_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
  var RUBY_KEYWORDS =
    'and false then defined module in return redo if BEGIN retry end for true self when ' +
    'next until do begin unless END rescue nil else break undef not super class case ' +
    'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor';
  var YARDOCTAG = {
    className: 'doctag',
    begin: '@[A-Za-z]+'
  };
  var IRB_OBJECT = {
    className: 'value',
    begin: '#<', end: '>'
  };
  var COMMENT_MODES = [
    hljs.COMMENT(
      '#',
      '$',
      {
        contains: [YARDOCTAG]
      }
    ),
    hljs.COMMENT(
      '^\\=begin',
      '^\\=end',
      {
        contains: [YARDOCTAG],
        relevance: 10
      }
    ),
    hljs.COMMENT('^__END__', '\\n$')
  ];
  var SUBST = {
    className: 'subst',
    begin: '#\\{', end: '}',
    keywords: RUBY_KEYWORDS
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {begin: /'/, end: /'/},
      {begin: /"/, end: /"/},
      {begin: /`/, end: /`/},
      {begin: '%[qQwWx]?\\(', end: '\\)'},
      {begin: '%[qQwWx]?\\[', end: '\\]'},
      {begin: '%[qQwWx]?{', end: '}'},
      {begin: '%[qQwWx]?<', end: '>'},
      {begin: '%[qQwWx]?/', end: '/'},
      {begin: '%[qQwWx]?%', end: '%'},
      {begin: '%[qQwWx]?-', end: '-'},
      {begin: '%[qQwWx]?\\|', end: '\\|'},
      {
        // \B in the beginning suppresses recognition of ?-sequences where ?
        // is the last character of a preceding identifier, as in: `func?4`
        begin: /\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/
      }
    ]
  };
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)',
    keywords: RUBY_KEYWORDS
  };

  var RUBY_DEFAULT_CONTAINS = [
    STRING,
    IRB_OBJECT,
    {
      className: 'class',
      beginKeywords: 'class module', end: '$|;',
      illegal: /=/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
        {
          className: 'inheritance',
          begin: '<\\s*',
          contains: [{
            className: 'parent',
            begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
          }]
        }
      ].concat(COMMENT_MODES)
    },
    {
      className: 'function',
      beginKeywords: 'def', end: '$|;',
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: RUBY_METHOD_RE}),
        PARAMS
      ].concat(COMMENT_MODES)
    },
    {
      className: 'constant',
      begin: '(::)?(\\b[A-Z]\\w*(::)?)+',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':',
      contains: [STRING, {begin: RUBY_METHOD_RE}],
      relevance: 0
    },
    {
      className: 'number',
      begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
      relevance: 0
    },
    {
      className: 'variable',
      begin: '(\\$\\W)|((\\$|\\@\\@?)(\\w+))'
    },
    { // regexp container
      begin: '(' + hljs.RE_STARTERS_RE + ')\\s*',
      contains: [
        IRB_OBJECT,
        {
          className: 'regexp',
          contains: [hljs.BACKSLASH_ESCAPE, SUBST],
          illegal: /\n/,
          variants: [
            {begin: '/', end: '/[a-z]*'},
            {begin: '%r{', end: '}[a-z]*'},
            {begin: '%r\\(', end: '\\)[a-z]*'},
            {begin: '%r!', end: '![a-z]*'},
            {begin: '%r\\[', end: '\\][a-z]*'}
          ]
        }
      ].concat(COMMENT_MODES),
      relevance: 0
    }
  ].concat(COMMENT_MODES);

  SUBST.contains = RUBY_DEFAULT_CONTAINS;
  PARAMS.contains = RUBY_DEFAULT_CONTAINS;

  var SIMPLE_PROMPT = "[>?]>";
  var DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+>";
  var RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>";

  var IRB_DEFAULT = [
    {
      begin: /^\s*=>/,
      className: 'status',
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    },
    {
      className: 'prompt',
      begin: '^('+SIMPLE_PROMPT+"|"+DEFAULT_PROMPT+'|'+RVM_PROMPT+')',
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    }
  ];

  return {
    aliases: ['rb', 'gemspec', 'podspec', 'thor', 'irb'],
    keywords: RUBY_KEYWORDS,
    illegal: /\/\*/,
    contains: COMMENT_MODES.concat(IRB_DEFAULT).concat(RUBY_DEFAULT_CONTAINS)
  };
});

hljs.registerLanguage('erb', function(hljs) {
  return {
    subLanguage: 'xml',
    contains: [
      hljs.COMMENT('<%#', '%>'),
      {
        begin: '<%[%=-]?', end: '[%-]?%>',
        subLanguage: 'ruby',
        excludeBegin: true,
        excludeEnd: true
      }
    ]
  };
});

hljs.registerLanguage('erlang-repl', function(hljs) {
  return {
    keywords: {
      special_functions:
        'spawn spawn_link self',
      reserved:
        'after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if ' +
        'let not of or orelse|10 query receive rem try when xor'
    },
    contains: [
      {
        className: 'prompt', begin: '^[0-9]+> ',
        relevance: 10
      },
      hljs.COMMENT('%', '$'),
      {
        className: 'number',
        begin: '\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)',
        relevance: 0
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'constant', begin: '\\?(::)?([A-Z]\\w*(::)?)+'
      },
      {
        className: 'arrow', begin: '->'
      },
      {
        className: 'ok', begin: 'ok'
      },
      {
        className: 'exclamation_mark', begin: '!'
      },
      {
        className: 'function_or_atom',
        begin: '(\\b[a-z\'][a-zA-Z0-9_\']*:[a-z\'][a-zA-Z0-9_\']*)|(\\b[a-z\'][a-zA-Z0-9_\']*)',
        relevance: 0
      },
      {
        className: 'variable',
        begin: '[A-Z][a-zA-Z0-9_\']*',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('erlang', function(hljs) {
  var BASIC_ATOM_RE = '[a-z\'][a-zA-Z0-9_\']*';
  var FUNCTION_NAME_RE = '(' + BASIC_ATOM_RE + ':' + BASIC_ATOM_RE + '|' + BASIC_ATOM_RE + ')';
  var ERLANG_RESERVED = {
    keyword:
      'after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if ' +
      'let not of orelse|10 query receive rem try when xor',
    literal:
      'false true'
  };

  var COMMENT = hljs.COMMENT('%', '$');
  var NUMBER = {
    className: 'number',
    begin: '\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)',
    relevance: 0
  };
  var NAMED_FUN = {
    begin: 'fun\\s+' + BASIC_ATOM_RE + '/\\d+'
  };
  var FUNCTION_CALL = {
    begin: FUNCTION_NAME_RE + '\\(', end: '\\)',
    returnBegin: true,
    relevance: 0,
    contains: [
      {
        className: 'function_name', begin: FUNCTION_NAME_RE,
        relevance: 0
      },
      {
        begin: '\\(', end: '\\)', endsWithParent: true,
        returnEnd: true,
        relevance: 0
        // "contains" defined later
      }
    ]
  };
  var TUPLE = {
    className: 'tuple',
    begin: '{', end: '}',
    relevance: 0
    // "contains" defined later
  };
  var VAR1 = {
    className: 'variable',
    begin: '\\b_([A-Z][A-Za-z0-9_]*)?',
    relevance: 0
  };
  var VAR2 = {
    className: 'variable',
    begin: '[A-Z][a-zA-Z0-9_]*',
    relevance: 0
  };
  var RECORD_ACCESS = {
    begin: '#' + hljs.UNDERSCORE_IDENT_RE,
    relevance: 0,
    returnBegin: true,
    contains: [
      {
        className: 'record_name',
        begin: '#' + hljs.UNDERSCORE_IDENT_RE,
        relevance: 0
      },
      {
        begin: '{', end: '}',
        relevance: 0
        // "contains" defined later
      }
    ]
  };

  var BLOCK_STATEMENTS = {
    beginKeywords: 'fun receive if try case', end: 'end',
    keywords: ERLANG_RESERVED
  };
  BLOCK_STATEMENTS.contains = [
    COMMENT,
    NAMED_FUN,
    hljs.inherit(hljs.APOS_STRING_MODE, {className: ''}),
    BLOCK_STATEMENTS,
    FUNCTION_CALL,
    hljs.QUOTE_STRING_MODE,
    NUMBER,
    TUPLE,
    VAR1, VAR2,
    RECORD_ACCESS
  ];

  var BASIC_MODES = [
    COMMENT,
    NAMED_FUN,
    BLOCK_STATEMENTS,
    FUNCTION_CALL,
    hljs.QUOTE_STRING_MODE,
    NUMBER,
    TUPLE,
    VAR1, VAR2,
    RECORD_ACCESS
  ];
  FUNCTION_CALL.contains[1].contains = BASIC_MODES;
  TUPLE.contains = BASIC_MODES;
  RECORD_ACCESS.contains[1].contains = BASIC_MODES;

  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)',
    contains: BASIC_MODES
  };
  return {
    aliases: ['erl'],
    keywords: ERLANG_RESERVED,
    illegal: '(</|\\*=|\\+=|-=|/\\*|\\*/|\\(\\*|\\*\\))',
    contains: [
      {
        className: 'function',
        begin: '^' + BASIC_ATOM_RE + '\\s*\\(', end: '->',
        returnBegin: true,
        illegal: '\\(|#|//|/\\*|\\\\|:|;',
        contains: [
          PARAMS,
          hljs.inherit(hljs.TITLE_MODE, {begin: BASIC_ATOM_RE})
        ],
        starts: {
          end: ';|\\.',
          keywords: ERLANG_RESERVED,
          contains: BASIC_MODES
        }
      },
      COMMENT,
      {
        className: 'pp',
        begin: '^-', end: '\\.',
        relevance: 0,
        excludeEnd: true,
        returnBegin: true,
        lexemes: '-' + hljs.IDENT_RE,
        keywords:
          '-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn ' +
          '-import -include -include_lib -compile -define -else -endif -file -behaviour ' +
          '-behavior -spec',
        contains: [PARAMS]
      },
      NUMBER,
      hljs.QUOTE_STRING_MODE,
      RECORD_ACCESS,
      VAR1, VAR2,
      TUPLE,
      {begin: /\.$/} // relevance booster
    ]
  };
});

hljs.registerLanguage('fix', function(hljs) {
  return {
    contains: [
    {
      begin: /[^\u2401\u0001]+/,
      end: /[\u2401\u0001]/,
      excludeEnd: true,
      returnBegin: true,
      returnEnd: false,
      contains: [
      {
        begin: /([^\u2401\u0001=]+)/,
        end: /=([^\u2401\u0001=]+)/,
        returnEnd: true,
        returnBegin: false,
        className: 'attribute'
      },
      {
        begin: /=/,
        end: /([\u2401\u0001])/,
        excludeEnd: true,
        excludeBegin: true,
        className: 'string'
      }]
    }],
    case_insensitive: true
  };
});

hljs.registerLanguage('fortran', function(hljs) {
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)'
  };

  var F_KEYWORDS = {
    constant: '.False. .True.',
    type: 'integer real character complex logical dimension allocatable|10 parameter ' +
      'external implicit|10 none double precision assign intent optional pointer ' +
      'target in out common equivalence data',
    keyword: 'kind do while private call intrinsic where elsewhere ' +
      'type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then ' +
      'public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. ' +
      'goto save else use module select case ' +
      'access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit ' +
      'continue format pause cycle exit ' +
      'c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg ' +
      'synchronous nopass non_overridable pass protected volatile abstract extends import ' +
      'non_intrinsic value deferred generic final enumerator class associate bind enum ' +
      'c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t ' +
      'c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double ' +
      'c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr ' +
      'c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated  c_f_pointer ' +
      'c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor ' +
      'numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ' +
      'ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive ' +
      'pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure',
    built_in: 'alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint ' +
      'dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl ' +
      'algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama ' +
      'iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod ' +
      'qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log ' +
      'log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate ' +
      'adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product ' +
      'eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul ' +
      'maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product ' +
      'radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind ' +
      'set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer ' +
      'dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ' +
      'ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode ' +
      'is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_of'  +
      'acosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 ' +
      'atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits ' +
      'bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr ' +
      'num_images parity popcnt poppar shifta shiftl shiftr this_image'
  };
  return {
    case_insensitive: true,
    aliases: ['f90', 'f95'],
    keywords: F_KEYWORDS,
    illegal: /\/\*/,
    contains: [
      hljs.inherit(hljs.APOS_STRING_MODE, {className: 'string', relevance: 0}),
      hljs.inherit(hljs.QUOTE_STRING_MODE, {className: 'string', relevance: 0}),
      {
        className: 'function',
        beginKeywords: 'subroutine function program',
        illegal: '[${=\\n]',
        contains: [hljs.UNDERSCORE_TITLE_MODE, PARAMS]
      },
      hljs.COMMENT('!', '$', {relevance: 0}),
      {
        className: 'number',
        begin: '(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('fsharp', function(hljs) {
  var TYPEPARAM = {
    begin: '<', end: '>',
    contains: [
      hljs.inherit(hljs.TITLE_MODE, {begin: /'[a-zA-Z0-9_]+/})
    ]
  };

  return {
    aliases: ['fs'],
    keywords:
      'abstract and as assert base begin class default delegate do done ' +
      'downcast downto elif else end exception extern false finally for ' +
      'fun function global if in inherit inline interface internal lazy let ' +
      'match member module mutable namespace new null of open or ' +
      'override private public rec return sig static struct then to ' +
      'true try type upcast use val void when while with yield',
    illegal: /\/\*/,
    contains: [
      {
        // monad builder keywords (matches before non-bang kws)
        className: 'keyword',
        begin: /\b(yield|return|let|do)!/
      },
      {
        className: 'string',
        begin: '@"', end: '"',
        contains: [{begin: '""'}]
      },
      {
        className: 'string',
        begin: '"""', end: '"""'
      },
      hljs.COMMENT('\\(\\*', '\\*\\)'),
      {
        className: 'class',
        beginKeywords: 'type', end: '\\(|=|$', excludeEnd: true,
        contains: [
          hljs.UNDERSCORE_TITLE_MODE,
          TYPEPARAM
        ]
      },
      {
        className: 'annotation',
        begin: '\\[<', end: '>\\]',
        relevance: 10
      },
      {
        className: 'attribute',
        begin: '\\B(\'[A-Za-z])\\b',
        contains: [hljs.BACKSLASH_ESCAPE]
      },
      hljs.C_LINE_COMMENT_MODE,
      hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
      hljs.C_NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('gams', function (hljs) {
  var KEYWORDS =
    'abort acronym acronyms alias all and assign binary card diag display else1 eps eq equation equations file files ' +
    'for1 free ge gt if inf integer le loop lt maximizing minimizing model models na ne negative no not option ' +
    'options or ord parameter parameters positive prod putpage puttl repeat sameas scalar scalars semicont semiint ' +
    'set1 sets smax smin solve sos1 sos2 sum system table then until using variable variables while1 xor yes';

  return {
    aliases: ['gms'],
    case_insensitive: true,
    keywords: KEYWORDS,
    contains: [
      {
        className: 'section',
        beginKeywords: 'sets parameters variables equations',
        end: ';',
        contains: [
          {
            begin: '/',
            end: '/',
            contains: [hljs.NUMBER_MODE]
          }
        ]
      },
      {
        className: 'string',
        begin: '\\*{3}', end: '\\*{3}'
      },
      hljs.NUMBER_MODE,
      {
        className: 'number',
        begin: '\\$[a-zA-Z0-9]+'
      }
    ]
  };
});

hljs.registerLanguage('gcode', function(hljs) {
    var GCODE_IDENT_RE = '[A-Z_][A-Z0-9_.]*';
    var GCODE_CLOSE_RE = '\\%';
    var GCODE_KEYWORDS = {
        literal:
            '',
        built_in:
            '',
        keyword:
            'IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT ' +
            'EQ LT GT NE GE LE OR XOR'
    };
    var GCODE_START = {
        className: 'preprocessor',
        begin: '([O])([0-9]+)'
    };
    var GCODE_CODE = [
        hljs.C_LINE_COMMENT_MODE,
        hljs.C_BLOCK_COMMENT_MODE,
        hljs.COMMENT(/\(/, /\)/),
        hljs.inherit(hljs.C_NUMBER_MODE, {begin: '([-+]?([0-9]*\\.?[0-9]+\\.?))|' + hljs.C_NUMBER_RE}),
        hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
        hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
        {
            className: 'keyword',
            begin: '([G])([0-9]+\\.?[0-9]?)'
        },
        {
            className: 'title',
            begin: '([M])([0-9]+\\.?[0-9]?)'
        },
        {
            className: 'title',
            begin: '(VC|VS|#)',
            end: '(\\d+)'
        },
        {
            className: 'title',
            begin: '(VZOFX|VZOFY|VZOFZ)'
        },
        {
            className: 'built_in',
            begin: '(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)',
            end: '([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])'
        },
        {
            className: 'label',
            variants: [
                {
                    begin: 'N', end: '\\d+',
                    illegal: '\\W'
                }
            ]
        }
    ];

    return {
        aliases: ['nc'],
        // Some implementations (CNC controls) of G-code are interoperable with uppercase and lowercase letters seamlessly.
        // However, most prefer all uppercase and uppercase is customary.
        case_insensitive: true,
        lexemes: GCODE_IDENT_RE,
        keywords: GCODE_KEYWORDS,
        contains: [
            {
                className: 'preprocessor',
                begin: GCODE_CLOSE_RE
            },
            GCODE_START
        ].concat(GCODE_CODE)
    };
});

hljs.registerLanguage('gherkin', function (hljs) {
  return {
    aliases: ['feature'],
    keywords: 'Feature Background Ability Business\ Need Scenario Scenarios Scenario\ Outline Scenario\ Template Examples Given And Then But When',
    contains: [
      {
        className: 'keyword',
        begin: '\\*'
      },
      hljs.COMMENT('@[^@\r\n\t ]+', '$'),
      {
        begin: '\\|', end: '\\|\\w*$',
        contains: [
          {
            className: 'string',
            begin: '[^|]+'
          }
        ]
      },
      {
        className: 'variable',
        begin: '<', end: '>'
      },
      hljs.HASH_COMMENT_MODE,
      {
        className: 'string',
        begin: '"""', end: '"""'
      },
      hljs.QUOTE_STRING_MODE
    ]
  };
});

hljs.registerLanguage('glsl', function(hljs) {
  return {
    keywords: {
      keyword:
        'atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default ' +
        'discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 ' +
        'dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray ' +
        'iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube ' +
        'iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect ' +
        'image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray ' +
        'isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer ' +
        'isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 ' +
        'mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict ' +
        'return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray ' +
        'sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow ' +
        'sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth ' +
        'struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray ' +
        'uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray ' +
        'usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer ' +
        'usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly',
      built_in:
        'gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial ' +
        'gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color ' +
        'gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord ' +
        'gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor ' +
        'gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial ' +
        'gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel ' +
        'gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize ' +
        'gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers ' +
        'gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs ' +
        'gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers ' +
        'gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents ' +
        'gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers ' +
        'gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents ' +
        'gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits ' +
        'gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents ' +
        'gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset ' +
        'gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms ' +
        'gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits ' +
        'gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents ' +
        'gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters ' +
        'gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents ' +
        'gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents ' +
        'gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits ' +
        'gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors ' +
        'gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs ' +
        'gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits ' +
        'gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffset'+
        'gl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose ' +
        'gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse ' +
        'gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose ' +
        'gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 ' +
        'gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix ' +
        'gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn ' +
        'gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn ' +
        'gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose ' +
        'gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition ' +
        'gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor ' +
        'gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID ' +
        'gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive ' +
        'abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement ' +
        'atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ' +
        'ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward ' +
        'findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan ' +
        'greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange ' +
        'imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended ' +
        'intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt ' +
        'isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier ' +
        'min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 ' +
        'packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract ' +
        'round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj ' +
        'shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture ' +
        'texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj ' +
        'texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod ' +
        'textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod ' +
        'textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod ' +
        'textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry ' +
        'uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 ' +
        'unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse',
      literal: 'true false'
    },
    illegal: '"',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'preprocessor',
        begin: '#', end: '$'
      }
    ]
  };
});

hljs.registerLanguage('go', function(hljs) {
  var GO_KEYWORDS = {
    keyword:
      'break default func interface select case map struct chan else goto package switch ' +
      'const fallthrough if range type continue for import return var go defer',
    constant:
       'true false iota nil',
    typename:
      'bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 ' +
      'uint16 uint32 uint64 int uint uintptr rune',
    built_in:
      'append cap close complex copy imag len make new panic print println real recover delete'
  };
  return {
    aliases: ["golang"],
    keywords: GO_KEYWORDS,
    illegal: '</',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        begin: '\'', end: '[^\\\\]\''
      },
      {
        className: 'string',
        begin: '`', end: '`'
      },
      {
        className: 'number',
        begin: hljs.C_NUMBER_RE + '[dflsi]?',
        relevance: 0
      },
      hljs.C_NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('golo', function(hljs) {
    return {
      keywords: {
        keyword:
          'println readln print import module function local return let var ' +
          'while for foreach times in case when match with break continue ' +
          'augment augmentation each find filter reduce ' +
          'if then else otherwise try catch finally raise throw orIfNull',
        typename:
          'DynamicObject|10 DynamicVariable struct Observable map set vector list array',
        literal:
          'true false null'
      },
      contains: [
        hljs.HASH_COMMENT_MODE,
        hljs.QUOTE_STRING_MODE,
        hljs.C_NUMBER_MODE,
        {
          className: 'annotation', begin: '@[A-Za-z]+'
        }
      ]
    }
});

hljs.registerLanguage('gradle', function(hljs) {
  return {
    case_insensitive: true,
    keywords: {
      keyword:
        'task project allprojects subprojects artifacts buildscript configurations ' +
        'dependencies repositories sourceSets description delete from into include ' +
        'exclude source classpath destinationDir includes options sourceCompatibility ' +
        'targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant ' +
        'def abstract break case catch continue default do else extends final finally ' +
        'for if implements instanceof native new private protected public return static ' +
        'switch synchronized throw throws transient try volatile while strictfp package ' +
        'import false null super this true antlrtask checkstyle codenarc copy boolean ' +
        'byte char class double float int interface long short void compile runTime ' +
        'file fileTree abs any append asList asWritable call collect compareTo count ' +
        'div dump each eachByte eachFile eachLine every find findAll flatten getAt ' +
        'getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods ' +
        'isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter ' +
        'newReader newWriter next plus pop power previous print println push putAt read ' +
        'readBytes readLines reverse reverseEach round size sort splitEachLine step subMap ' +
        'times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader ' +
        'withStream withWriter withWriterAppend write writeLine'
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.NUMBER_MODE,
      hljs.REGEXP_MODE

    ]
  }
});

hljs.registerLanguage('groovy', function(hljs) {
    return {
        keywords: {
            typename: 'byte short char int long boolean float double void',
            literal : 'true false null',
            keyword:
            // groovy specific keywords
            'def as in assert trait ' +
            // common keywords with Java
            'super this abstract static volatile transient public private protected synchronized final ' +
            'class interface enum if else for while switch case break default continue ' +
            'throw throws try catch finally implements extends new import package return instanceof'
        },

        contains: [
            hljs.COMMENT(
                '/\\*\\*',
                '\\*/',
                {
                    relevance : 0,
                    contains : [{
                        className : 'doctag',
                        begin : '@[A-Za-z]+'
                    }]
                }
            ),
            hljs.C_LINE_COMMENT_MODE,
            hljs.C_BLOCK_COMMENT_MODE,
            {
                className: 'string',
                begin: '"""', end: '"""'
            },
            {
                className: 'string',
                begin: "'''", end: "'''"
            },
            {
                className: 'string',
                begin: "\\$/", end: "/\\$",
                relevance: 10
            },
            hljs.APOS_STRING_MODE,
            {
                className: 'regexp',
                begin: /~?\/[^\/\n]+\//,
                contains: [
                    hljs.BACKSLASH_ESCAPE
                ]
            },
            hljs.QUOTE_STRING_MODE,
            {
                className: 'shebang',
                begin: "^#!/usr/bin/env", end: '$',
                illegal: '\n'
            },
            hljs.BINARY_NUMBER_MODE,
            {
                className: 'class',
                beginKeywords: 'class interface trait enum', end: '{',
                illegal: ':',
                contains: [
                    {beginKeywords: 'extends implements'},
                    hljs.UNDERSCORE_TITLE_MODE,
                ]
            },
            hljs.C_NUMBER_MODE,
            {
                className: 'annotation', begin: '@[A-Za-z]+'
            },
            {
                // highlight map keys and named parameters as strings
                className: 'string', begin: /[^\?]{0}[A-Za-z0-9_$]+ *:/
            },
            {
                // catch middle element of the ternary operator
                // to avoid highlight it as a label, named parameter, or map key
                begin: /\?/, end: /\:/
            },
            {
                // highlight labeled statements
                className: 'label', begin: '^\\s*[A-Za-z0-9_$]+:',
                relevance: 0
            },
        ],
        illegal: /#/
    }
});

hljs.registerLanguage('haml', // TODO support filter tags like :javascript, support inline HTML
function(hljs) {
  return {
    case_insensitive: true,
    contains: [
      {
        className: 'doctype',
        begin: '^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$',
        relevance: 10
      },
      // FIXME these comments should be allowed to span indented lines
      hljs.COMMENT(
        '^\\s*(!=#|=#|-#|/).*$',
        false,
        {
          relevance: 0
        }
      ),
      {
        begin: '^\\s*(-|=|!=)(?!#)',
        starts: {
          end: '\\n',
          subLanguage: 'ruby'
        }
      },
      {
        className: 'tag',
        begin: '^\\s*%',
        contains: [
          {
            className: 'title',
            begin: '\\w+'
          },
          {
            className: 'value',
            begin: '[#\\.][\\w-]+'
          },
          {
            begin: '{\\s*',
            end: '\\s*}',
            excludeEnd: true,
            contains: [
              {
                //className: 'attribute',
                begin: ':\\w+\\s*=>',
                end: ',\\s+',
                returnBegin: true,
                endsWithParent: true,
                contains: [
                  {
                    className: 'symbol',
                    begin: ':\\w+'
                  },
                  hljs.APOS_STRING_MODE,
                  hljs.QUOTE_STRING_MODE,
                  {
                    begin: '\\w+',
                    relevance: 0
                  }
                ]
              }
            ]
          },
          {
            begin: '\\(\\s*',
            end: '\\s*\\)',
            excludeEnd: true,
            contains: [
              {
                //className: 'attribute',
                begin: '\\w+\\s*=',
                end: '\\s+',
                returnBegin: true,
                endsWithParent: true,
                contains: [
                  {
                    className: 'attribute',
                    begin: '\\w+',
                    relevance: 0
                  },
                  hljs.APOS_STRING_MODE,
                  hljs.QUOTE_STRING_MODE,
                  {
                    begin: '\\w+',
                    relevance: 0
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        className: 'bullet',
        begin: '^\\s*[=~]\\s*',
        relevance: 0
      },
      {
        begin: '#{',
        starts: {
          end: '}',
          subLanguage: 'ruby'
        }
      }
    ]
  };
});

hljs.registerLanguage('handlebars', function(hljs) {
  var EXPRESSION_KEYWORDS = 'each in with if else unless bindattr action collection debugger log outlet template unbound view yield';
  return {
    aliases: ['hbs', 'html.hbs', 'html.handlebars'],
    case_insensitive: true,
    subLanguage: 'xml',
    contains: [
      {
        className: 'expression',
        begin: '{{', end: '}}',
        contains: [
          {
            className: 'begin-block', begin: '\#[a-zA-Z\-\ \.]+',
            keywords: EXPRESSION_KEYWORDS
          },
          {
            className: 'string',
            begin: '"', end: '"'
          },
          {
            className: 'end-block', begin: '\\\/[a-zA-Z\-\ \.]+',
            keywords: EXPRESSION_KEYWORDS
          },
          {
            className: 'variable', begin: '[a-zA-Z\-\.]+',
            keywords: EXPRESSION_KEYWORDS
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('haskell', function(hljs) {
  var COMMENT_MODES = [
    hljs.COMMENT('--', '$'),
    hljs.COMMENT(
      '{-',
      '-}',
      {
        contains: ['self']
      }
    )
  ];

  var PRAGMA = {
    className: 'pragma',
    begin: '{-#', end: '#-}'
  };

  var PREPROCESSOR = {
    className: 'preprocessor',
    begin: '^#', end: '$'
  };

  var CONSTRUCTOR = {
    className: 'type',
    begin: '\\b[A-Z][\\w\']*', // TODO: other constructors (build-in, infix).
    relevance: 0
  };

  var LIST = {
    className: 'container',
    begin: '\\(', end: '\\)',
    illegal: '"',
    contains: [
      PRAGMA,
      PREPROCESSOR,
      {className: 'type', begin: '\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?'},
      hljs.inherit(hljs.TITLE_MODE, {begin: '[_a-z][\\w\']*'})
    ].concat(COMMENT_MODES)
  };

  var RECORD = {
    className: 'container',
    begin: '{', end: '}',
    contains: LIST.contains
  };

  return {
    aliases: ['hs'],
    keywords:
      'let in if then else case of where do module import hiding ' +
      'qualified type data newtype deriving class instance as default ' +
      'infix infixl infixr foreign export ccall stdcall cplusplus ' +
      'jvm dotnet safe unsafe family forall mdo proc rec',
    contains: [

      // Top-level constructions.

      {
        className: 'module',
        begin: '\\bmodule\\b', end: 'where',
        keywords: 'module where',
        contains: [LIST].concat(COMMENT_MODES),
        illegal: '\\W\\.|;'
      },
      {
        className: 'import',
        begin: '\\bimport\\b', end: '$',
        keywords: 'import|0 qualified as hiding',
        contains: [LIST].concat(COMMENT_MODES),
        illegal: '\\W\\.|;'
      },

      {
        className: 'class',
        begin: '^(\\s*)?(class|instance)\\b', end: 'where',
        keywords: 'class family instance where',
        contains: [CONSTRUCTOR, LIST].concat(COMMENT_MODES)
      },
      {
        className: 'typedef',
        begin: '\\b(data|(new)?type)\\b', end: '$',
        keywords: 'data family type newtype deriving',
        contains: [PRAGMA, CONSTRUCTOR, LIST, RECORD].concat(COMMENT_MODES)
      },
      {
        className: 'default',
        beginKeywords: 'default', end: '$',
        contains: [CONSTRUCTOR, LIST].concat(COMMENT_MODES)
      },
      {
        className: 'infix',
        beginKeywords: 'infix infixl infixr', end: '$',
        contains: [hljs.C_NUMBER_MODE].concat(COMMENT_MODES)
      },
      {
        className: 'foreign',
        begin: '\\bforeign\\b', end: '$',
        keywords: 'foreign import export ccall stdcall cplusplus jvm ' +
                  'dotnet safe unsafe',
        contains: [CONSTRUCTOR, hljs.QUOTE_STRING_MODE].concat(COMMENT_MODES)
      },
      {
        className: 'shebang',
        begin: '#!\\/usr\\/bin\\/env\ runhaskell', end: '$'
      },

      // "Whitespaces".

      PRAGMA,
      PREPROCESSOR,

      // Literals and names.

      // TODO: characters.
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      CONSTRUCTOR,
      hljs.inherit(hljs.TITLE_MODE, {begin: '^[_a-z][\\w\']*'}),

      {begin: '->|<-'} // No markup, relevance booster
    ].concat(COMMENT_MODES)
  };
});

hljs.registerLanguage('haxe', function(hljs) {
  var IDENT_RE = '[a-zA-Z_$][a-zA-Z0-9_$]*';
  var IDENT_FUNC_RETURN_TYPE_RE = '([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)';

  return {
    aliases: ['hx'],
    keywords: {
      keyword: 'break callback case cast catch class continue default do dynamic else enum extends extern ' +
    'for function here if implements import in inline interface never new override package private ' +
    'public return static super switch this throw trace try typedef untyped using var while',
      literal: 'true false null'
    },
    contains: [
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'class',
        beginKeywords: 'class interface', end: '{', excludeEnd: true,
        contains: [
          {
            beginKeywords: 'extends implements'
          },
          hljs.TITLE_MODE
        ]
      },
      {
        className: 'preprocessor',
        begin: '#', end: '$',
        keywords: 'if else elseif end error'
      },
      {
        className: 'function',
        beginKeywords: 'function', end: '[{;]', excludeEnd: true,
        illegal: '\\S',
        contains: [
          hljs.TITLE_MODE,
          {
            className: 'params',
            begin: '\\(', end: '\\)',
            contains: [
              hljs.APOS_STRING_MODE,
              hljs.QUOTE_STRING_MODE,
              hljs.C_LINE_COMMENT_MODE,
              hljs.C_BLOCK_COMMENT_MODE
            ]
          },
          {
            className: 'type',
            begin: ':',
            end: IDENT_FUNC_RETURN_TYPE_RE,
            relevance: 10
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('http', function(hljs) {
  return {
    aliases: ['https'],
    illegal: '\\S',
    contains: [
      {
        className: 'status',
        begin: '^HTTP/[0-9\\.]+', end: '$',
        contains: [{className: 'number', begin: '\\b\\d{3}\\b'}]
      },
      {
        className: 'request',
        begin: '^[A-Z]+ (.*?) HTTP/[0-9\\.]+$', returnBegin: true, end: '$',
        contains: [
          {
            className: 'string',
            begin: ' ', end: ' ',
            excludeBegin: true, excludeEnd: true
          }
        ]
      },
      {
        className: 'attribute',
        begin: '^\\w', end: ': ', excludeEnd: true,
        illegal: '\\n|\\s|=',
        starts: {className: 'string', end: '$'}
      },
      {
        begin: '\\n\\n',
        starts: {subLanguage: [], endsWithParent: true}
      }
    ]
  };
});

hljs.registerLanguage('inform7', function(hljs) {
  var START_BRACKET = '\\[';
  var END_BRACKET = '\\]';
  return {
    aliases: ['i7'],
    case_insensitive: true,
    keywords: {
      // Some keywords more or less unique to I7, for relevance.
      keyword:
        // kind:
        'thing room person man woman animal container ' +
        'supporter backdrop door ' +
        // characteristic:
        'scenery open closed locked inside gender ' +
        // verb:
        'is are say understand ' +
        // misc keyword:
        'kind of rule'
    },
    contains: [
      {
        className: 'string',
        begin: '"', end: '"',
        relevance: 0,
        contains: [
          {
            className: 'subst',
            begin: START_BRACKET, end: END_BRACKET
          }
        ]
      },
      {
        className: 'title',
        begin: /^(Volume|Book|Part|Chapter|Section|Table)\b/,
        end: '$'
      },
      {
        // Rule definition
        // This is here for relevance.
        begin: /^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\b/,
        end: ':',
        contains: [
          {
            //Rule name
            begin: '\\b\\(This',
            end: '\\)'
          }
        ]
      },
      {
        className: 'comment',
        begin: START_BRACKET, end: END_BRACKET,
        contains: ['self']
      }
    ]
  };
});

hljs.registerLanguage('ini', function(hljs) {
  var STRING = {
    className: "string",
    contains: [hljs.BACKSLASH_ESCAPE],
    variants: [
      {
        begin: "'''", end: "'''",
        relevance: 10
      }, {
        begin: '"""', end: '"""',
        relevance: 10
      }, {
        begin: '"', end: '"'
      }, {
        begin: "'", end: "'"
      }
    ]
  };
  return {
    aliases: ['toml'],
    case_insensitive: true,
    illegal: /\S/,
    contains: [
      hljs.COMMENT(';', '$'),
      hljs.HASH_COMMENT_MODE,
      {
        className: 'title',
        begin: /^\s*\[+/, end: /\]+/
      },
      {
        className: 'setting',
        begin: /^[a-z0-9\[\]_-]+\s*=\s*/, end: '$',
        contains: [
          {
            className: 'value',
            endsWithParent: true,
            keywords: 'on off true false yes no',
            contains: [
              {
                className: 'variable',
                variants: [
                  {begin: /\$[\w\d"][\w\d_]*/},
                  {begin: /\$\{(.*?)}/}
                ]
              },
              STRING,
              {
                className: 'number',
                begin: /([\+\-]+)?[\d]+_[\d_]+/
              },
              hljs.NUMBER_MODE
            ],
            relevance: 0
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('irpf90', function(hljs) {
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)'
  };

  var F_KEYWORDS = {
    constant: '.False. .True.',
    type: 'integer real character complex logical dimension allocatable|10 parameter ' +
      'external implicit|10 none double precision assign intent optional pointer ' +
      'target in out common equivalence data',
    keyword: 'kind do while private call intrinsic where elsewhere ' +
      'type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then ' +
      'public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. ' +
      'goto save else use module select case ' +
      'access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit ' +
      'continue format pause cycle exit ' +
      'c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg ' +
      'synchronous nopass non_overridable pass protected volatile abstract extends import ' +
      'non_intrinsic value deferred generic final enumerator class associate bind enum ' +
      'c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t ' +
      'c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double ' +
      'c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr ' +
      'c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated  c_f_pointer ' +
      'c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor ' +
      'numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ' +
      'ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive ' +
      'pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure ' +
      // IRPF90 special keywords
      'begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch ' +
      'soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read',
    built_in: 'alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint ' +
      'dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl ' +
      'algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama ' +
      'iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod ' +
      'qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log ' +
      'log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate ' +
      'adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product ' +
      'eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul ' +
      'maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product ' +
      'radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind ' +
      'set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer ' +
      'dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ' +
      'ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode ' +
      'is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_of'  +
      'acosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 ' +
      'atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits ' +
      'bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr ' +
      'num_images parity popcnt poppar shifta shiftl shiftr this_image ' +
      // IRPF90 special built_ins
      'IRP_ALIGN irp_here'
  };
  return {
    case_insensitive: true,
    keywords: F_KEYWORDS,
    illegal: /\/\*/,
    contains: [
      hljs.inherit(hljs.APOS_STRING_MODE, {className: 'string', relevance: 0}),
      hljs.inherit(hljs.QUOTE_STRING_MODE, {className: 'string', relevance: 0}),
      {
        className: 'function',
        beginKeywords: 'subroutine function program',
        illegal: '[${=\\n]',
        contains: [hljs.UNDERSCORE_TITLE_MODE, PARAMS]
      },
      hljs.COMMENT('!', '$', {relevance: 0}),
      hljs.COMMENT('begin_doc', 'end_doc', {relevance: 10}),
      {
        className: 'number',
        begin: '(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('java', function(hljs) {
  var GENERIC_IDENT_RE = hljs.UNDERSCORE_IDENT_RE + '(<' + hljs.UNDERSCORE_IDENT_RE + '>)?';
  var KEYWORDS =
    'false synchronized int abstract float private char boolean static null if const ' +
    'for true while long strictfp finally protected import native final void ' +
    'enum else break transient catch instanceof byte super volatile case assert short ' +
    'package default double public try this switch continue throws protected public private';

  // https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html
  var JAVA_NUMBER_RE = '\\b' +
    '(' +
      '0[bB]([01]+[01_]+[01]+|[01]+)' + // 0b...
      '|' +
      '0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)' + // 0x...
      '|' +
      '(' +
        '([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?' +
        '|' +
        '\\.([\\d]+[\\d_]+[\\d]+|[\\d]+)' +
      ')' +
      '([eE][-+]?\\d+)?' + // octal, decimal, float
    ')' +
    '[lLfF]?';
  var JAVA_NUMBER_MODE = {
    className: 'number',
    begin: JAVA_NUMBER_RE,
    relevance: 0
  };

  return {
    aliases: ['jsp'],
    keywords: KEYWORDS,
    illegal: /<\/|#/,
    contains: [
      hljs.COMMENT(
        '/\\*\\*',
        '\\*/',
        {
          relevance : 0,
          contains : [{
            className : 'doctag',
            begin : '@[A-Za-z]+'
          }]
        }
      ),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'class',
        beginKeywords: 'class interface', end: /[{;=]/, excludeEnd: true,
        keywords: 'class interface',
        illegal: /[:"\[\]]/,
        contains: [
          {beginKeywords: 'extends implements'},
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        // Expression keywords prevent 'keyword Name(...)' from being
        // recognized as a function definition
        beginKeywords: 'new throw return else',
        relevance: 0
      },
      {
        className: 'function',
        begin: '(' + GENERIC_IDENT_RE + '\\s+)+' + hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true, end: /[{;=]/,
        excludeEnd: true,
        keywords: KEYWORDS,
        contains: [
          {
            begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true,
            relevance: 0,
            contains: [hljs.UNDERSCORE_TITLE_MODE]
          },
          {
            className: 'params',
            begin: /\(/, end: /\)/,
            keywords: KEYWORDS,
            relevance: 0,
            contains: [
              hljs.APOS_STRING_MODE,
              hljs.QUOTE_STRING_MODE,
              hljs.C_NUMBER_MODE,
              hljs.C_BLOCK_COMMENT_MODE
            ]
          },
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE
        ]
      },
      JAVA_NUMBER_MODE,
      {
        className: 'annotation', begin: '@[A-Za-z]+'
      }
    ]
  };
});

hljs.registerLanguage('javascript', function(hljs) {
  return {
    aliases: ['js'],
    keywords: {
      keyword:
        'in of if for while finally var new function do return void else break catch ' +
        'instanceof with throw case default try this switch continue typeof delete ' +
        'let yield const export super debugger as async await',
      literal:
        'true false null undefined NaN Infinity',
      built_in:
        'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent ' +
        'encodeURI encodeURIComponent escape unescape Object Function Boolean Error ' +
        'EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' +
        'TypeError URIError Number Math Date String RegExp Array Float32Array ' +
        'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' +
        'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' +
        'module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect ' +
        'Promise'
    },
    contains: [
      {
        className: 'pi',
        relevance: 10,
        begin: /^\s*['"]use (strict|asm)['"]/
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      { // template string
        className: 'string',
        begin: '`', end: '`',
        contains: [
          hljs.BACKSLASH_ESCAPE,
          {
            className: 'subst',
            begin: '\\$\\{', end: '\\}'
          }
        ]
      },
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'number',
        variants: [
          { begin: '\\b(0[bB][01]+)' },
          { begin: '\\b(0[oO][0-7]+)' },
          { begin: hljs.C_NUMBER_RE }
        ],
        relevance: 0
      },
      { // "value" container
        begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
        keywords: 'return throw case',
        contains: [
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE,
          hljs.REGEXP_MODE,
          { // E4X / JSX
            begin: /</, end: />\s*[);\]]/,
            relevance: 0,
            subLanguage: 'xml'
          }
        ],
        relevance: 0
      },
      {
        className: 'function',
        beginKeywords: 'function', end: /\{/, excludeEnd: true,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {begin: /[A-Za-z$_][0-9A-Za-z$_]*/}),
          {
            className: 'params',
            begin: /\(/, end: /\)/,
            excludeBegin: true,
            excludeEnd: true,
            contains: [
              hljs.C_LINE_COMMENT_MODE,
              hljs.C_BLOCK_COMMENT_MODE
            ]
          }
        ],
        illegal: /\[|%/
      },
      {
        begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
      },
      {
        begin: '\\.' + hljs.IDENT_RE, relevance: 0 // hack: prevents detection of keywords after dots
      },
      // ECMAScript 6 modules import
      {
        beginKeywords: 'import', end: '[;$]',
        keywords: 'import from as',
        contains: [
          hljs.APOS_STRING_MODE,
          hljs.QUOTE_STRING_MODE
        ]
      },
      { // ES6 class
        className: 'class',
        beginKeywords: 'class', end: /[{;=]/, excludeEnd: true,
        illegal: /[:"\[\]]/,
        contains: [
          {beginKeywords: 'extends'},
          hljs.UNDERSCORE_TITLE_MODE
        ]
      }
    ],
    illegal: /#/
  };
});

hljs.registerLanguage('json', function(hljs) {
  var LITERALS = {literal: 'true false null'};
  var TYPES = [
    hljs.QUOTE_STRING_MODE,
    hljs.C_NUMBER_MODE
  ];
  var VALUE_CONTAINER = {
    className: 'value',
    end: ',', endsWithParent: true, excludeEnd: true,
    contains: TYPES,
    keywords: LITERALS
  };
  var OBJECT = {
    begin: '{', end: '}',
    contains: [
      {
        className: 'attribute',
        begin: '\\s*"', end: '"\\s*:\\s*', excludeBegin: true, excludeEnd: true,
        contains: [hljs.BACKSLASH_ESCAPE],
        illegal: '\\n',
        starts: VALUE_CONTAINER
      }
    ],
    illegal: '\\S'
  };
  var ARRAY = {
    begin: '\\[', end: '\\]',
    contains: [hljs.inherit(VALUE_CONTAINER, {className: null})], // inherit is also a workaround for a bug that makes shared modes with endsWithParent compile only the ending of one of the parents
    illegal: '\\S'
  };
  TYPES.splice(TYPES.length, 0, OBJECT, ARRAY);
  return {
    contains: TYPES,
    keywords: LITERALS,
    illegal: '\\S'
  };
});

hljs.registerLanguage('julia', function(hljs) {
  // Since there are numerous special names in Julia, it is too much trouble
  // to maintain them by hand. Hence these names (i.e. keywords, literals and
  // built-ins) are automatically generated from Julia (v0.3.0) itself through
  // following scripts for each.

  var KEYWORDS = {
    // # keyword generator
    // println("\"in\",")
    // for kw in Base.REPLCompletions.complete_keyword("")
    //     println("\"$kw\",")
    // end
    keyword:
      'in abstract baremodule begin bitstype break catch ccall const continue do else elseif end export ' +
      'finally for function global if immutable import importall let local macro module quote return try type ' +
      'typealias using while',

    // # literal generator
    // println("\"true\",\n\"false\"")
    // for name in Base.REPLCompletions.completions("", 0)[1]
    //     try
    //         s = symbol(name)
    //         v = eval(s)
    //         if !isa(v, Function) &&
    //            !isa(v, DataType) &&
    //            !issubtype(typeof(v), Tuple) &&
    //            !isa(v, UnionType) &&
    //            !isa(v, Module) &&
    //            !isa(v, TypeConstructor) &&
    //            !isa(v, Colon)
    //             println("\"$name\",")
    //         end
    //     end
    // end
    literal:
      'true false ANY ARGS CPU_CORES C_NULL DL_LOAD_PATH DevNull ENDIAN_BOM ENV I|0 Inf Inf16 Inf32 ' +
      'InsertionSort JULIA_HOME LOAD_PATH MS_ASYNC MS_INVALIDATE MS_SYNC MergeSort NaN NaN16 NaN32 OS_NAME QuickSort ' +
      'RTLD_DEEPBIND RTLD_FIRST RTLD_GLOBAL RTLD_LAZY RTLD_LOCAL RTLD_NODELETE RTLD_NOLOAD RTLD_NOW RoundDown ' +
      'RoundFromZero RoundNearest RoundToZero RoundUp STDERR STDIN STDOUT VERSION WORD_SIZE catalan cglobal e|0 eu|0 ' +
      'eulergamma golden im nothing pi γ π φ',

    // # built_in generator:
    // for name in Base.REPLCompletions.completions("", 0)[1]
    //     try
    //         v = eval(symbol(name))
    //         if isa(v, DataType)
    //             println("\"$name\",")
    //         end
    //     end
    // end
    built_in:
      'ASCIIString AbstractArray AbstractRNG AbstractSparseArray Any ArgumentError Array Associative Base64Pipe ' +
      'Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError Box CFILE Cchar Cdouble Cfloat Char ' +
      'CharString Cint Clong Clonglong ClusterManager Cmd Coff_t Colon Complex Complex128 Complex32 Complex64 ' +
      'Condition Cptrdiff_t Cshort Csize_t Cssize_t Cuchar Cuint Culong Culonglong Cushort Cwchar_t DArray DataType ' +
      'DenseArray Diagonal Dict DimensionMismatch DirectIndexString Display DivideError DomainError EOFError ' +
      'EachLine Enumerate ErrorException Exception Expr Factorization FileMonitor FileOffset Filter Float16 Float32 ' +
      'Float64 FloatRange FloatingPoint Function GetfieldNode GotoNode Hermitian IO IOBuffer IOStream IPv4 IPv6 ' +
      'InexactError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException IntrinsicFunction KeyError ' +
      'LabelNode LambdaStaticData LineNumberNode LoadError LocalProcess MIME MathConst MemoryError MersenneTwister ' +
      'Method MethodError MethodTable Module NTuple NewvarNode Nothing Number ObjectIdDict OrdinalRange ' +
      'OverflowError ParseError PollingFileWatcher ProcessExitedException ProcessGroup Ptr QuoteNode Range Range1 ' +
      'Ranges Rational RawFD Real Regex RegexMatch RemoteRef RepString RevString RopeString RoundingMode Set ' +
      'SharedArray Signed SparseMatrixCSC StackOverflowError Stat StatStruct StepRange String SubArray SubString ' +
      'SymTridiagonal Symbol SymbolNode Symmetric SystemError Task TextDisplay Timer TmStruct TopNode Triangular ' +
      'Tridiagonal Type TypeConstructor TypeError TypeName TypeVar UTF16String UTF32String UTF8String UdpSocket ' +
      'Uint Uint128 Uint16 Uint32 Uint64 Uint8 UndefRefError UndefVarError UniformScaling UnionType UnitRange ' +
      'Unsigned Vararg VersionNumber WString WeakKeyDict WeakRef Woodbury Zip'
  };

  // ref: http://julia.readthedocs.org/en/latest/manual/variables/#allowed-variable-names
  var VARIABLE_NAME_RE = "[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*";

  // placeholder for recursive self-reference
  var DEFAULT = { lexemes: VARIABLE_NAME_RE, keywords: KEYWORDS };

  var TYPE_ANNOTATION = {
    className: "type-annotation",
    begin: /::/
  };

  var SUBTYPE = {
    className: "subtype",
    begin: /<:/
  };

  // ref: http://julia.readthedocs.org/en/latest/manual/integers-and-floating-point-numbers/
  var NUMBER = {
    className: "number",
    // supported numeric literals:
    //  * binary literal (e.g. 0x10)
    //  * octal literal (e.g. 0o76543210)
    //  * hexadecimal literal (e.g. 0xfedcba876543210)
    //  * hexadecimal floating point literal (e.g. 0x1p0, 0x1.2p2)
    //  * decimal literal (e.g. 9876543210, 100_000_000)
    //  * floating pointe literal (e.g. 1.2, 1.2f, .2, 1., 1.2e10, 1.2e-10)
    begin: /(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,
    relevance: 0
  };

  var CHAR = {
    className: "char",
    begin: /'(.|\\[xXuU][a-zA-Z0-9]+)'/
  };

  var INTERPOLATION = {
    className: 'subst',
    begin: /\$\(/, end: /\)/,
    keywords: KEYWORDS
  };

  var INTERPOLATED_VARIABLE = {
    className: 'variable',
    begin: "\\$" + VARIABLE_NAME_RE
  };

  // TODO: neatly escape normal code in string literal
  var STRING = {
    className: "string",
    contains: [hljs.BACKSLASH_ESCAPE, INTERPOLATION, INTERPOLATED_VARIABLE],
    variants: [
      { begin: /\w*"/, end: /"\w*/ },
      { begin: /\w*"""/, end: /"""\w*/ }
    ]
  };

  var COMMAND = {
    className: "string",
    contains: [hljs.BACKSLASH_ESCAPE, INTERPOLATION, INTERPOLATED_VARIABLE],
    begin: '`', end: '`'
  };

  var MACROCALL = {
    className: "macrocall",
    begin: "@" + VARIABLE_NAME_RE
  };

  var COMMENT = {
    className: "comment",
    variants: [
      { begin: "#=", end: "=#", relevance: 10 },
      { begin: '#', end: '$' }
    ]
  };

  DEFAULT.contains = [
    NUMBER,
    CHAR,
    TYPE_ANNOTATION,
    SUBTYPE,
    STRING,
    COMMAND,
    MACROCALL,
    COMMENT,
    hljs.HASH_COMMENT_MODE
  ];
  INTERPOLATION.contains = DEFAULT.contains;

  return DEFAULT;
});

hljs.registerLanguage('kotlin', function (hljs) {
  var KEYWORDS = 'val var get set class trait object public open private protected ' +
    'final enum if else do while for when break continue throw try catch finally ' +
    'import package is as in return fun override default companion reified inline volatile transient native';

  return {
    keywords: {
      typename: 'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',
      literal: 'true false null',
      keyword: KEYWORDS
    },
    contains : [
      hljs.COMMENT(
        '/\\*\\*',
        '\\*/',
        {
          relevance : 0,
          contains : [{
            className : 'doctag',
            begin : '@[A-Za-z]+'
          }]
        }
      ),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'type',
        begin: /</, end: />/,
        returnBegin: true,
        excludeEnd: false,
        relevance: 0
      },
      {
        className: 'function',
        beginKeywords: 'fun', end: '[(]|$',
        returnBegin: true,
        excludeEnd: true,
        keywords: KEYWORDS,
        illegal: /fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,
        relevance: 5,
        contains: [
          {
            begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true,
            relevance: 0,
            contains: [hljs.UNDERSCORE_TITLE_MODE]
          },
          {
            className: 'type',
            begin: /</, end: />/, keywords: 'reified',
            relevance: 0
          },
          {
            className: 'params',
            begin: /\(/, end: /\)/,
            keywords: KEYWORDS,
            relevance: 0,
            illegal: /\([^\(,\s:]+,/,
            contains: [
              {
                className: 'typename',
                begin: /:\s*/, end: /\s*[=\)]/, excludeBegin: true, returnEnd: true,
                relevance: 0
              }
            ]
          },
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE
        ]
      },
      {
        className: 'class',
        beginKeywords: 'class trait', end: /[:\{(]|$/,
        excludeEnd: true,
        illegal: 'extends implements',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE,
          {
            className: 'type',
            begin: /</, end: />/, excludeBegin: true, excludeEnd: true,
            relevance: 0
          },
          {
            className: 'typename',
            begin: /[,:]\s*/, end: /[<\(,]|$/, excludeBegin: true, returnEnd: true
          }
        ]
      },
      {
        className: 'variable', beginKeywords: 'var val', end: /\s*[=:$]/, excludeEnd: true
      },
      hljs.QUOTE_STRING_MODE,
      {
        className: 'shebang',
        begin: "^#!/usr/bin/env", end: '$',
        illegal: '\n'
      },
      hljs.C_NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('lasso', function(hljs) {
  var LASSO_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_.]*';
  var LASSO_ANGLE_RE = '<\\?(lasso(script)?|=)';
  var LASSO_CLOSE_RE = '\\]|\\?>';
  var LASSO_KEYWORDS = {
    literal:
      'true false none minimal full all void ' +
      'bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft',
    built_in:
      'array date decimal duration integer map pair string tag xml null ' +
      'boolean bytes keyword list locale queue set stack staticarray ' +
      'local var variable global data self inherited currentcapture givenblock',
    keyword:
      'error_code error_msg error_pop error_push error_reset cache ' +
      'database_names database_schemanames database_tablenames define_tag ' +
      'define_type email_batch encode_set html_comment handle handle_error ' +
      'header if inline iterate ljax_target link link_currentaction ' +
      'link_currentgroup link_currentrecord link_detail link_firstgroup ' +
      'link_firstrecord link_lastgroup link_lastrecord link_nextgroup ' +
      'link_nextrecord link_prevgroup link_prevrecord log loop ' +
      'namespace_using output_none portal private protect records referer ' +
      'referrer repeating resultset rows search_args search_arguments ' +
      'select sort_args sort_arguments thread_atomic value_list while ' +
      'abort case else if_empty if_false if_null if_true loop_abort ' +
      'loop_continue loop_count params params_up return return_value ' +
      'run_children soap_definetag soap_lastrequest soap_lastresponse ' +
      'tag_name ascending average by define descending do equals ' +
      'frozen group handle_failure import in into join let match max ' +
      'min on order parent protected provide public require returnhome ' +
      'skip split_thread sum take thread to trait type where with ' +
      'yield yieldhome'
  };
  var HTML_COMMENT = hljs.COMMENT(
    '<!--',
    '-->',
    {
      relevance: 0
    }
  );
  var LASSO_NOPROCESS = {
    className: 'preprocessor',
    begin: '\\[noprocess\\]',
    starts: {
      className: 'markup',
      end: '\\[/noprocess\\]',
      returnEnd: true,
      contains: [HTML_COMMENT]
    }
  };
  var LASSO_START = {
    className: 'preprocessor',
    begin: '\\[/noprocess|' + LASSO_ANGLE_RE
  };
  var LASSO_DATAMEMBER = {
    className: 'variable',
    begin: '\'' + LASSO_IDENT_RE + '\''
  };
  var LASSO_CODE = [
    hljs.COMMENT(
      '/\\*\\*!',
      '\\*/'
    ),
    hljs.C_LINE_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
    hljs.inherit(hljs.C_NUMBER_MODE, {begin: hljs.C_NUMBER_RE + '|(infinity|nan)\\b'}),
    hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
    hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
    {
      className: 'string',
      begin: '`', end: '`'
    },
    {
      className: 'variable',
      variants: [
        {
          begin: '[#$]' + LASSO_IDENT_RE
        },
        {
          begin: '#', end: '\\d+',
          illegal: '\\W'
        }
      ]
    },
    {
      className: 'tag',
      begin: '::\\s*', end: LASSO_IDENT_RE,
      illegal: '\\W'
    },
    {
      className: 'attribute',
      variants: [
        {
          begin: '-(?!infinity)' + hljs.UNDERSCORE_IDENT_RE,
          relevance: 0
        },
        {
          begin: '(\\.\\.\\.)'
        }
      ]
    },
    {
      className: 'subst',
      variants: [
        {
          begin: '->\\s*',
          contains: [LASSO_DATAMEMBER]
        },
        {
          begin: '->|\\\\|&&?|\\|\\||!(?!=|>)|(and|or|not)\\b',
          relevance: 0
        }
      ]
    },
    {
      className: 'built_in',
      begin: '\\.\\.?\\s*',
      relevance: 0,
      contains: [LASSO_DATAMEMBER]
    },
    {
      className: 'class',
      beginKeywords: 'define',
      returnEnd: true, end: '\\(|=>',
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: hljs.UNDERSCORE_IDENT_RE + '(=(?!>))?'})
      ]
    }
  ];
  return {
    aliases: ['ls', 'lassoscript'],
    case_insensitive: true,
    lexemes: LASSO_IDENT_RE + '|&[lg]t;',
    keywords: LASSO_KEYWORDS,
    contains: [
      {
        className: 'preprocessor',
        begin: LASSO_CLOSE_RE,
        relevance: 0,
        starts: {
          className: 'markup',
          end: '\\[|' + LASSO_ANGLE_RE,
          returnEnd: true,
          relevance: 0,
          contains: [HTML_COMMENT]
        }
      },
      LASSO_NOPROCESS,
      LASSO_START,
      {
        className: 'preprocessor',
        begin: '\\[no_square_brackets',
        starts: {
          end: '\\[/no_square_brackets\\]', // not implemented in the language
          lexemes: LASSO_IDENT_RE + '|&[lg]t;',
          keywords: LASSO_KEYWORDS,
          contains: [
            {
              className: 'preprocessor',
              begin: LASSO_CLOSE_RE,
              relevance: 0,
              starts: {
                className: 'markup',
                end: '\\[noprocess\\]|' + LASSO_ANGLE_RE,
                returnEnd: true,
                contains: [HTML_COMMENT]
              }
            },
            LASSO_NOPROCESS,
            LASSO_START
          ].concat(LASSO_CODE)
        }
      },
      {
        className: 'preprocessor',
        begin: '\\[',
        relevance: 0
      },
      {
        className: 'shebang',
        begin: '^#!.+lasso9\\b',
        relevance: 10
      }
    ].concat(LASSO_CODE)
  };
});

hljs.registerLanguage('less', function(hljs) {
  var IDENT_RE        = '[\\w-]+'; // yes, Less identifiers may begin with a digit
  var INTERP_IDENT_RE = '(' + IDENT_RE + '|@{' + IDENT_RE + '})';

  /* Generic Modes */

  var RULES = [], VALUE = []; // forward def. for recursive modes

  var STRING_MODE = function(c) { return {
    // Less strings are not multiline (also include '~' for more consistent coloring of "escaped" strings)
    className: 'string', begin: '~?' + c + '.*?' + c
  };};

  var IDENT_MODE = function(name, begin, relevance) { return {
    className: name, begin: begin, relevance: relevance
  };};

  var FUNCT_MODE = function(name, ident, obj) {
    return hljs.inherit({
        className: name, begin: ident + '\\(', end: '\\(',
        returnBegin: true, excludeEnd: true, relevance: 0
    }, obj);
  };

  var PARENS_MODE = {
    // used only to properly balance nested parens inside mixin call, def. arg list
    begin: '\\(', end: '\\)', contains: VALUE, relevance: 0
  };

  // generic Less highlighter (used almost everywhere except selectors):
  VALUE.push(
    hljs.C_LINE_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
    STRING_MODE("'"),
    STRING_MODE('"'),
    hljs.CSS_NUMBER_MODE, // fixme: it does not include dot for numbers like .5em :(
    IDENT_MODE('hexcolor', '#[0-9A-Fa-f]+\\b'),
    FUNCT_MODE('function', '(url|data-uri)', {
      starts: {className: 'string', end: '[\\)\\n]', excludeEnd: true}
    }),
    FUNCT_MODE('function', IDENT_RE),
    PARENS_MODE,
    IDENT_MODE('variable', '@@?' + IDENT_RE, 10),
    IDENT_MODE('variable', '@{'  + IDENT_RE + '}'),
    IDENT_MODE('built_in', '~?`[^`]*?`'), // inline javascript (or whatever host language) *multiline* string
    { // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding):
      className: 'attribute', begin: IDENT_RE + '\\s*:', end: ':', returnBegin: true, excludeEnd: true
    }
  );

  var VALUE_WITH_RULESETS = VALUE.concat({
    begin: '{', end: '}', contains: RULES
  });

  var MIXIN_GUARD_MODE = {
    beginKeywords: 'when', endsWithParent: true,
    contains: [{beginKeywords: 'and not'}].concat(VALUE) // using this form to override VALUE’s 'function' match
  };

  /* Rule-Level Modes */

  var RULE_MODE = {
    className: 'attribute',
    begin: INTERP_IDENT_RE, end: ':', excludeEnd: true,
    contains: [hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE],
    illegal: /\S/,
    starts: {end: '[;}]', returnEnd: true, contains: VALUE, illegal: '[<=$]'}
  };

  var AT_RULE_MODE = {
    className: 'at_rule', // highlight only at-rule keyword
    begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b',
    starts: {end: '[;{}]', returnEnd: true, contains: VALUE, relevance: 0}
  };

  // variable definitions and calls
  var VAR_RULE_MODE = {
    className: 'variable',
    variants: [
      // using more strict pattern for higher relevance to increase chances of Less detection.
      // this is *the only* Less specific statement used in most of the sources, so...
      // (we’ll still often loose to the css-parser unless there's '//' comment,
      // simply because 1 variable just can't beat 99 properties :)
      {begin: '@' + IDENT_RE + '\\s*:', relevance: 15},
      {begin: '@' + IDENT_RE}
    ],
    starts: {end: '[;}]', returnEnd: true, contains: VALUE_WITH_RULESETS}
  };

  var SELECTOR_MODE = {
    // first parse unambiguous selectors (i.e. those not starting with tag)
    // then fall into the scary lookahead-discriminator variant.
    // this mode also handles mixin definitions and calls
    variants: [{
      begin: '[\\.#:&\\[]', end: '[;{}]'  // mixin calls end with ';'
      }, {
      begin: INTERP_IDENT_RE + '[^;]*{',
      end: '{'
    }],
    returnBegin: true,
    returnEnd:   true,
    illegal: '[<=\'$"]',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      MIXIN_GUARD_MODE,
      IDENT_MODE('keyword',  'all\\b'),
      IDENT_MODE('variable', '@{'  + IDENT_RE + '}'),     // otherwise it’s identified as tag
      IDENT_MODE('tag',       INTERP_IDENT_RE + '%?', 0), // '%' for more consistent coloring of @keyframes "tags"
      IDENT_MODE('id',       '#'   + INTERP_IDENT_RE),
      IDENT_MODE('class',    '\\.' + INTERP_IDENT_RE, 0),
      IDENT_MODE('keyword',  '&', 0),
      FUNCT_MODE('pseudo',   ':not'),
      FUNCT_MODE('keyword',  ':extend'),
      IDENT_MODE('pseudo',   '::?' + INTERP_IDENT_RE),
      {className: 'attr_selector', begin: '\\[', end: '\\]'},
      {begin: '\\(', end: '\\)', contains: VALUE_WITH_RULESETS}, // argument list of parametric mixins
      {begin: '!important'} // eat !important after mixin call or it will be colored as tag
    ]
  };

  RULES.push(
    hljs.C_LINE_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
    AT_RULE_MODE,
    VAR_RULE_MODE,
    SELECTOR_MODE,
    RULE_MODE
  );

  return {
    case_insensitive: true,
    illegal: '[=>\'/<($"]',
    contains: RULES
  };
});

hljs.registerLanguage('lisp', function(hljs) {
  var LISP_IDENT_RE = '[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*';
  var MEC_RE = '\\|[^]*?\\|';
  var LISP_SIMPLE_NUMBER_RE = '(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?';
  var SHEBANG = {
    className: 'shebang',
    begin: '^#!', end: '$'
  };
  var LITERAL = {
    className: 'literal',
    begin: '\\b(t{1}|nil)\\b'
  };
  var NUMBER = {
    className: 'number',
    variants: [
      {begin: LISP_SIMPLE_NUMBER_RE, relevance: 0},
      {begin: '#(b|B)[0-1]+(/[0-1]+)?'},
      {begin: '#(o|O)[0-7]+(/[0-7]+)?'},
      {begin: '#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?'},
      {begin: '#(c|C)\\(' + LISP_SIMPLE_NUMBER_RE + ' +' + LISP_SIMPLE_NUMBER_RE, end: '\\)'}
    ]
  };
  var STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null});
  var COMMENT = hljs.COMMENT(
    ';', '$',
    {
      relevance: 0
    }
  );
  var VARIABLE = {
    className: 'variable',
    begin: '\\*', end: '\\*'
  };
  var KEYWORD = {
    className: 'keyword',
    begin: '[:&]' + LISP_IDENT_RE
  };
  var IDENT = {
    begin: LISP_IDENT_RE,
    relevance: 0
  };
  var MEC = {
    begin: MEC_RE
  };
  var QUOTED_LIST = {
    begin: '\\(', end: '\\)',
    contains: ['self', LITERAL, STRING, NUMBER, IDENT]
  };
  var QUOTED = {
    className: 'quoted',
    contains: [NUMBER, STRING, VARIABLE, KEYWORD, QUOTED_LIST, IDENT],
    variants: [
      {
        begin: '[\'`]\\(', end: '\\)'
      },
      {
        begin: '\\(quote ', end: '\\)',
        keywords: 'quote'
      },
      {
        begin: '\'' + MEC_RE
      }
    ]
  };
  var QUOTED_ATOM = {
    className: 'quoted',
    variants: [
      {begin: '\'' + LISP_IDENT_RE},
      {begin: '#\'' + LISP_IDENT_RE + '(::' + LISP_IDENT_RE + ')*'}
    ]
  };
  var LIST = {
    className: 'list',
    begin: '\\(\\s*', end: '\\)'
  };
  var BODY = {
    endsWithParent: true,
    relevance: 0
  };
  LIST.contains = [
    {
      className: 'keyword',
      variants: [
        {begin: LISP_IDENT_RE},
        {begin: MEC_RE}
      ]
    },
    BODY
  ];
  BODY.contains = [QUOTED, QUOTED_ATOM, LIST, LITERAL, NUMBER, STRING, COMMENT, VARIABLE, KEYWORD, MEC, IDENT];

  return {
    illegal: /\S/,
    contains: [
      NUMBER,
      SHEBANG,
      LITERAL,
      STRING,
      COMMENT,
      QUOTED,
      QUOTED_ATOM,
      LIST,
      IDENT
    ]
  };
});

hljs.registerLanguage('livecodeserver', function(hljs) {
  var VARIABLE = {
    className: 'variable', begin: '\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+',
    relevance: 0
  };
  var COMMENT_MODES = [
    hljs.C_BLOCK_COMMENT_MODE,
    hljs.HASH_COMMENT_MODE,
    hljs.COMMENT('--', '$'),
    hljs.COMMENT('[^:]//', '$')
  ];
  var TITLE1 = hljs.inherit(hljs.TITLE_MODE, {
    variants: [
      {begin: '\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*'},
      {begin: '\\b_[a-z0-9\\-]+'}
    ]
  });
  var TITLE2 = hljs.inherit(hljs.TITLE_MODE, {begin: '\\b([A-Za-z0-9_\\-]+)\\b'});
  return {
    case_insensitive: false,
    keywords: {
      keyword:
        '$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER ' +
        'codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph ' +
        'after byte bytes english the until http forever descending using line real8 with seventh ' +
        'for stdout finally element word words fourth before black ninth sixth characters chars stderr ' +
        'uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid ' +
        'at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 ' +
        'int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat ' +
        'end repeat URL in try into switch to words https token binfile each tenth as ticks tick ' +
        'system real4 by dateItems without char character ascending eighth whole dateTime numeric short ' +
        'first ftp integer abbreviated abbr abbrev private case while if',
      constant:
        'SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE ' +
        'QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO ' +
        'six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five ' +
        'quote empty one true return cr linefeed right backslash null seven tab three two ' +
        'RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK ' +
        'FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK',
      operator:
        'div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within ' +
        'contains ends with begins the keys of keys',
      built_in:
        'put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode ' +
        'base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum ' +
        'cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress ' +
        'constantNames cos date dateFormat decompress directories ' +
        'diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global ' +
        'globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset ' +
        'keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders ' +
        'libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 ' +
        'longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec ' +
        'millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar ' +
        'numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets ' +
        'paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation ' +
        'populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile ' +
        'revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull ' +
        'revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered ' +
        'revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames ' +
        'revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull ' +
        'revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections ' +
        'revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype ' +
        'revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext ' +
        'revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames ' +
        'revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase ' +
        'revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute ' +
        'revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces ' +
        'revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode ' +
        'revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling ' +
        'revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error ' +
        'revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute ' +
        'revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort ' +
        'revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree ' +
        'revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance ' +
        'sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound ' +
        'stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper ' +
        'transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames ' +
        'variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet ' +
        'xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process ' +
        'combine constant convert create new alias folder directory decrypt delete variable word line folder ' +
        'directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile ' +
        'libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback ' +
        'libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime ' +
        'libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename ' +
        'replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase ' +
        'revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees ' +
        'revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord ' +
        'revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase ' +
        'revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD ' +
        'revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost ' +
        'revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData ' +
        'revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel ' +
        'revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback ' +
        'revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop ' +
        'subtract union unload wait write'
    },
    contains: [
      VARIABLE,
      {
        className: 'keyword',
        begin: '\\bend\\sif\\b'
      },
      {
        className: 'function',
        beginKeywords: 'function', end: '$',
        contains: [
          VARIABLE,
          TITLE2,
          hljs.APOS_STRING_MODE,
          hljs.QUOTE_STRING_MODE,
          hljs.BINARY_NUMBER_MODE,
          hljs.C_NUMBER_MODE,
          TITLE1
        ]
      },
      {
        className: 'function',
        begin: '\\bend\\s+', end: '$',
        keywords: 'end',
        contains: [
          TITLE2,
          TITLE1
        ]
      },
      {
        className: 'command',
        beginKeywords: 'command on', end: '$',
        contains: [
          VARIABLE,
          TITLE2,
          hljs.APOS_STRING_MODE,
          hljs.QUOTE_STRING_MODE,
          hljs.BINARY_NUMBER_MODE,
          hljs.C_NUMBER_MODE,
          TITLE1
        ]
      },
      {
        className: 'preprocessor',
        variants: [
          {
            begin: '<\\?(rev|lc|livecode)',
            relevance: 10
          },
          { begin: '<\\?' },
          { begin: '\\?>' }
        ]
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.BINARY_NUMBER_MODE,
      hljs.C_NUMBER_MODE,
      TITLE1
    ].concat(COMMENT_MODES),
    illegal: ';$|^\\[|^='
  };
});

hljs.registerLanguage('livescript', function(hljs) {
  var KEYWORDS = {
    keyword:
      // JS keywords
      'in if for while finally new do return else break catch instanceof throw try this ' +
      'switch continue typeof delete debugger case default function var with ' +
      // LiveScript keywords
      'then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super ' +
      'case default function var void const let enum export import native ' +
      '__hasProp __extends __slice __bind __indexOf',
    literal:
      // JS literals
      'true false null undefined ' +
      // LiveScript literals
      'yes no on off it that void',
    built_in:
      'npm require console print module global window document'
  };
  var JS_IDENT_RE = '[A-Za-z$_](?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*';
  var TITLE = hljs.inherit(hljs.TITLE_MODE, {begin: JS_IDENT_RE});
  var SUBST = {
    className: 'subst',
    begin: /#\{/, end: /}/,
    keywords: KEYWORDS
  };
  var SUBST_SIMPLE = {
    className: 'subst',
    begin: /#[A-Za-z$_]/, end: /(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,
    keywords: KEYWORDS
  };
  var EXPRESSIONS = [
    hljs.BINARY_NUMBER_MODE,
    {
      className: 'number',
      begin: '(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)',
      relevance: 0,
      starts: {end: '(\\s*/)?', relevance: 0} // a number tries to eat the following slash to prevent treating it as a regexp
    },
    {
      className: 'string',
      variants: [
        {
          begin: /'''/, end: /'''/,
          contains: [hljs.BACKSLASH_ESCAPE]
        },
        {
          begin: /'/, end: /'/,
          contains: [hljs.BACKSLASH_ESCAPE]
        },
        {
          begin: /"""/, end: /"""/,
          contains: [hljs.BACKSLASH_ESCAPE, SUBST, SUBST_SIMPLE]
        },
        {
          begin: /"/, end: /"/,
          contains: [hljs.BACKSLASH_ESCAPE, SUBST, SUBST_SIMPLE]
        },
        {
          begin: /\\/, end: /(\s|$)/,
          excludeEnd: true
        }
      ]
    },
    {
      className: 'pi',
      variants: [
        {
          begin: '//', end: '//[gim]*',
          contains: [SUBST, hljs.HASH_COMMENT_MODE]
        },
        {
          // regex can't start with space to parse x / 2 / 3 as two divisions
          // regex can't start with *, and it supports an "illegal" in the main mode
          begin: /\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/
        }
      ]
    },
    {
      className: 'property',
      begin: '@' + JS_IDENT_RE
    },
    {
      begin: '``', end: '``',
      excludeBegin: true, excludeEnd: true,
      subLanguage: 'javascript'
    }
  ];
  SUBST.contains = EXPRESSIONS;

  var PARAMS = {
    className: 'params',
    begin: '\\(', returnBegin: true,
    /* We need another contained nameless mode to not have every nested
    pair of parens to be called "params" */
    contains: [
      {
        begin: /\(/, end: /\)/,
        keywords: KEYWORDS,
        contains: ['self'].concat(EXPRESSIONS)
      }
    ]
  };

  return {
    aliases: ['ls'],
    keywords: KEYWORDS,
    illegal: /\/\*/,
    contains: EXPRESSIONS.concat([
      hljs.COMMENT('\\/\\*', '\\*\\/'),
      hljs.HASH_COMMENT_MODE,
      {
        className: 'function',
        contains: [TITLE, PARAMS],
        returnBegin: true,
        variants: [
          {
            begin: '(' + JS_IDENT_RE + '\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?', end: '\\->\\*?'
          },
          {
            begin: '(' + JS_IDENT_RE + '\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?', end: '[-~]{1,2}>\\*?'
          },
          {
            begin: '(' + JS_IDENT_RE + '\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?', end: '!?[-~]{1,2}>\\*?'
          }
        ]
      },
      {
        className: 'class',
        beginKeywords: 'class',
        end: '$',
        illegal: /[:="\[\]]/,
        contains: [
          {
            beginKeywords: 'extends',
            endsWithParent: true,
            illegal: /[:="\[\]]/,
            contains: [TITLE]
          },
          TITLE
        ]
      },
      {
        className: 'attribute',
        begin: JS_IDENT_RE + ':', end: ':',
        returnBegin: true, returnEnd: true,
        relevance: 0
      }
    ])
  };
});

hljs.registerLanguage('lua', function(hljs) {
  var OPENING_LONG_BRACKET = '\\[=*\\[';
  var CLOSING_LONG_BRACKET = '\\]=*\\]';
  var LONG_BRACKETS = {
    begin: OPENING_LONG_BRACKET, end: CLOSING_LONG_BRACKET,
    contains: ['self']
  };
  var COMMENTS = [
    hljs.COMMENT('--(?!' + OPENING_LONG_BRACKET + ')', '$'),
    hljs.COMMENT(
      '--' + OPENING_LONG_BRACKET,
      CLOSING_LONG_BRACKET,
      {
        contains: [LONG_BRACKETS],
        relevance: 10
      }
    )
  ];
  return {
    lexemes: hljs.UNDERSCORE_IDENT_RE,
    keywords: {
      keyword:
        'and break do else elseif end false for if in local nil not or repeat return then ' +
        'true until while',
      built_in:
        '_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load ' +
        'loadfile loadstring module next pairs pcall print rawequal rawget rawset require ' +
        'select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug ' +
        'io math os package string table'
    },
    contains: COMMENTS.concat([
      {
        className: 'function',
        beginKeywords: 'function', end: '\\)',
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {begin: '([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*'}),
          {
            className: 'params',
            begin: '\\(', endsWithParent: true,
            contains: COMMENTS
          }
        ].concat(COMMENTS)
      },
      hljs.C_NUMBER_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        begin: OPENING_LONG_BRACKET, end: CLOSING_LONG_BRACKET,
        contains: [LONG_BRACKETS],
        relevance: 5
      }
    ])
  };
});

hljs.registerLanguage('makefile', function(hljs) {
  var VARIABLE = {
    className: 'variable',
    begin: /\$\(/, end: /\)/,
    contains: [hljs.BACKSLASH_ESCAPE]
  };
  return {
    aliases: ['mk', 'mak'],
    contains: [
      hljs.HASH_COMMENT_MODE,
      {
        begin: /^\w+\s*\W*=/, returnBegin: true,
        relevance: 0,
        starts: {
          className: 'constant',
          end: /\s*\W*=/, excludeEnd: true,
          starts: {
            end: /$/,
            relevance: 0,
            contains: [
              VARIABLE
            ]
          }
        }
      },
      {
        className: 'title',
        begin: /^[\w]+:\s*$/
      },
      {
        className: 'phony',
        begin: /^\.PHONY:/, end: /$/,
        keywords: '.PHONY', lexemes: /[\.\w]+/
      },
      {
        begin: /^\t+/, end: /$/,
        relevance: 0,
        contains: [
          hljs.QUOTE_STRING_MODE,
          VARIABLE
        ]
      }
    ]
  };
});

hljs.registerLanguage('mathematica', function(hljs) {
  return {
    aliases: ['mma'],
    lexemes: '(\\$|\\b)' + hljs.IDENT_RE + '\\b',
    keywords: 'AbelianGroup Abort AbortKernels AbortProtect Above Abs Absolute AbsoluteCorrelation AbsoluteCorrelationFunction AbsoluteCurrentValue AbsoluteDashing AbsoluteFileName AbsoluteOptions AbsolutePointSize AbsoluteThickness AbsoluteTime AbsoluteTiming AccountingForm Accumulate Accuracy AccuracyGoal ActionDelay ActionMenu ActionMenuBox ActionMenuBoxOptions Active ActiveItem ActiveStyle AcyclicGraphQ AddOnHelpPath AddTo AdjacencyGraph AdjacencyList AdjacencyMatrix AdjustmentBox AdjustmentBoxOptions AdjustTimeSeriesForecast AffineTransform After AiryAi AiryAiPrime AiryAiZero AiryBi AiryBiPrime AiryBiZero AlgebraicIntegerQ AlgebraicNumber AlgebraicNumberDenominator AlgebraicNumberNorm AlgebraicNumberPolynomial AlgebraicNumberTrace AlgebraicRules AlgebraicRulesData Algebraics AlgebraicUnitQ Alignment AlignmentMarker AlignmentPoint All AllowedDimensions AllowGroupClose AllowInlineCells AllowKernelInitialization AllowReverseGroupClose AllowScriptLevelChange AlphaChannel AlternatingGroup AlternativeHypothesis Alternatives AmbientLight Analytic AnchoredSearch And AndersonDarlingTest AngerJ AngleBracket AngularGauge Animate AnimationCycleOffset AnimationCycleRepetitions AnimationDirection AnimationDisplayTime AnimationRate AnimationRepetitions AnimationRunning Animator AnimatorBox AnimatorBoxOptions AnimatorElements Annotation Annuity AnnuityDue Antialiasing Antisymmetric Apart ApartSquareFree Appearance AppearanceElements AppellF1 Append AppendTo Apply ArcCos ArcCosh ArcCot ArcCoth ArcCsc ArcCsch ArcSec ArcSech ArcSin ArcSinDistribution ArcSinh ArcTan ArcTanh Arg ArgMax ArgMin ArgumentCountQ ARIMAProcess ArithmeticGeometricMean ARMAProcess ARProcess Array ArrayComponents ArrayDepth ArrayFlatten ArrayPad ArrayPlot ArrayQ ArrayReshape ArrayRules Arrays Arrow Arrow3DBox ArrowBox Arrowheads AspectRatio AspectRatioFixed Assert Assuming Assumptions AstronomicalData Asynchronous AsynchronousTaskObject AsynchronousTasks AtomQ Attributes AugmentedSymmetricPolynomial AutoAction AutoDelete AutoEvaluateEvents AutoGeneratedPackage AutoIndent AutoIndentSpacings AutoItalicWords AutoloadPath AutoMatch Automatic AutomaticImageSize AutoMultiplicationSymbol AutoNumberFormatting AutoOpenNotebooks AutoOpenPalettes AutorunSequencing AutoScaling AutoScroll AutoSpacing AutoStyleOptions AutoStyleWords Axes AxesEdge AxesLabel AxesOrigin AxesStyle Axis ' +
      'BabyMonsterGroupB Back Background BackgroundTasksSettings Backslash Backsubstitution Backward Band BandpassFilter BandstopFilter BarabasiAlbertGraphDistribution BarChart BarChart3D BarLegend BarlowProschanImportance BarnesG BarOrigin BarSpacing BartlettHannWindow BartlettWindow BaseForm Baseline BaselinePosition BaseStyle BatesDistribution BattleLemarieWavelet Because BeckmannDistribution Beep Before Begin BeginDialogPacket BeginFrontEndInteractionPacket BeginPackage BellB BellY Below BenfordDistribution BeniniDistribution BenktanderGibratDistribution BenktanderWeibullDistribution BernoulliB BernoulliDistribution BernoulliGraphDistribution BernoulliProcess BernsteinBasis BesselFilterModel BesselI BesselJ BesselJZero BesselK BesselY BesselYZero Beta BetaBinomialDistribution BetaDistribution BetaNegativeBinomialDistribution BetaPrimeDistribution BetaRegularized BetweennessCentrality BezierCurve BezierCurve3DBox BezierCurve3DBoxOptions BezierCurveBox BezierCurveBoxOptions BezierFunction BilateralFilter Binarize BinaryFormat BinaryImageQ BinaryRead BinaryReadList BinaryWrite BinCounts BinLists Binomial BinomialDistribution BinomialProcess BinormalDistribution BiorthogonalSplineWavelet BipartiteGraphQ BirnbaumImportance BirnbaumSaundersDistribution BitAnd BitClear BitGet BitLength BitNot BitOr BitSet BitShiftLeft BitShiftRight BitXor Black BlackmanHarrisWindow BlackmanNuttallWindow BlackmanWindow Blank BlankForm BlankNullSequence BlankSequence Blend Block BlockRandom BlomqvistBeta BlomqvistBetaTest Blue Blur BodePlot BohmanWindow Bold Bookmarks Boole BooleanConsecutiveFunction BooleanConvert BooleanCountingFunction BooleanFunction BooleanGraph BooleanMaxterms BooleanMinimize BooleanMinterms Booleans BooleanTable BooleanVariables BorderDimensions BorelTannerDistribution Bottom BottomHatTransform BoundaryStyle Bounds Box BoxBaselineShift BoxData BoxDimensions Boxed Boxes BoxForm BoxFormFormatTypes BoxFrame BoxID BoxMargins BoxMatrix BoxRatios BoxRotation BoxRotationPoint BoxStyle BoxWhiskerChart Bra BracketingBar BraKet BrayCurtisDistance BreadthFirstScan Break Brown BrownForsytheTest BrownianBridgeProcess BrowserCategory BSplineBasis BSplineCurve BSplineCurve3DBox BSplineCurveBox BSplineCurveBoxOptions BSplineFunction BSplineSurface BSplineSurface3DBox BubbleChart BubbleChart3D BubbleScale BubbleSizes BulletGauge BusinessDayQ ButterflyGraph ButterworthFilterModel Button ButtonBar ButtonBox ButtonBoxOptions ButtonCell ButtonContents ButtonData ButtonEvaluator ButtonExpandable ButtonFrame ButtonFunction ButtonMargins ButtonMinHeight ButtonNote ButtonNotebook ButtonSource ButtonStyle ButtonStyleMenuListing Byte ByteCount ByteOrdering ' +
      'C CachedValue CacheGraphics CalendarData CalendarType CallPacket CanberraDistance Cancel CancelButton CandlestickChart Cap CapForm CapitalDifferentialD CardinalBSplineBasis CarmichaelLambda Cases Cashflow Casoratian Catalan CatalanNumber Catch CauchyDistribution CauchyWindow CayleyGraph CDF CDFDeploy CDFInformation CDFWavelet Ceiling Cell CellAutoOverwrite CellBaseline CellBoundingBox CellBracketOptions CellChangeTimes CellContents CellContext CellDingbat CellDynamicExpression CellEditDuplicate CellElementsBoundingBox CellElementSpacings CellEpilog CellEvaluationDuplicate CellEvaluationFunction CellEventActions CellFrame CellFrameColor CellFrameLabelMargins CellFrameLabels CellFrameMargins CellGroup CellGroupData CellGrouping CellGroupingRules CellHorizontalScrolling CellID CellLabel CellLabelAutoDelete CellLabelMargins CellLabelPositioning CellMargins CellObject CellOpen CellPrint CellProlog Cells CellSize CellStyle CellTags CellularAutomaton CensoredDistribution Censoring Center CenterDot CentralMoment CentralMomentGeneratingFunction CForm ChampernowneNumber ChanVeseBinarize Character CharacterEncoding CharacterEncodingsPath CharacteristicFunction CharacteristicPolynomial CharacterRange Characters ChartBaseStyle ChartElementData ChartElementDataFunction ChartElementFunction ChartElements ChartLabels ChartLayout ChartLegends ChartStyle Chebyshev1FilterModel Chebyshev2FilterModel ChebyshevDistance ChebyshevT ChebyshevU Check CheckAbort CheckAll Checkbox CheckboxBar CheckboxBox CheckboxBoxOptions ChemicalData ChessboardDistance ChiDistribution ChineseRemainder ChiSquareDistribution ChoiceButtons ChoiceDialog CholeskyDecomposition Chop Circle CircleBox CircleDot CircleMinus CirclePlus CircleTimes CirculantGraph CityData Clear ClearAll ClearAttributes ClearSystemCache ClebschGordan ClickPane Clip ClipboardNotebook ClipFill ClippingStyle ClipPlanes ClipRange Clock ClockGauge ClockwiseContourIntegral Close Closed CloseKernels ClosenessCentrality Closing ClosingAutoSave ClosingEvent ClusteringComponents CMYKColor Coarse Coefficient CoefficientArrays CoefficientDomain CoefficientList CoefficientRules CoifletWavelet Collect Colon ColonForm ColorCombine ColorConvert ColorData ColorDataFunction ColorFunction ColorFunctionScaling Colorize ColorNegate ColorOutput ColorProfileData ColorQuantize ColorReplace ColorRules ColorSelectorSettings ColorSeparate ColorSetter ColorSetterBox ColorSetterBoxOptions ColorSlider ColorSpace Column ColumnAlignments ColumnBackgrounds ColumnForm ColumnLines ColumnsEqual ColumnSpacings ColumnWidths CommonDefaultFormatTypes Commonest CommonestFilter CommonUnits CommunityBoundaryStyle CommunityGraphPlot CommunityLabels CommunityRegionStyle CompatibleUnitQ CompilationOptions CompilationTarget Compile Compiled CompiledFunction Complement CompleteGraph CompleteGraphQ CompleteKaryTree CompletionsListPacket Complex Complexes ComplexExpand ComplexInfinity ComplexityFunction ComponentMeasurements ' +
      'ComponentwiseContextMenu Compose ComposeList ComposeSeries Composition CompoundExpression CompoundPoissonDistribution CompoundPoissonProcess CompoundRenewalProcess Compress CompressedData Condition ConditionalExpression Conditioned Cone ConeBox ConfidenceLevel ConfidenceRange ConfidenceTransform ConfigurationPath Congruent Conjugate ConjugateTranspose Conjunction Connect ConnectedComponents ConnectedGraphQ ConnesWindow ConoverTest ConsoleMessage ConsoleMessagePacket ConsolePrint Constant ConstantArray Constants ConstrainedMax ConstrainedMin ContentPadding ContentsBoundingBox ContentSelectable ContentSize Context ContextMenu Contexts ContextToFilename ContextToFileName Continuation Continue ContinuedFraction ContinuedFractionK ContinuousAction ContinuousMarkovProcess ContinuousTimeModelQ ContinuousWaveletData ContinuousWaveletTransform ContourDetect ContourGraphics ContourIntegral ContourLabels ContourLines ContourPlot ContourPlot3D Contours ContourShading ContourSmoothing ContourStyle ContraharmonicMean Control ControlActive ControlAlignment ControllabilityGramian ControllabilityMatrix ControllableDecomposition ControllableModelQ ControllerDuration ControllerInformation ControllerInformationData ControllerLinking ControllerManipulate ControllerMethod ControllerPath ControllerState ControlPlacement ControlsRendering ControlType Convergents ConversionOptions ConversionRules ConvertToBitmapPacket ConvertToPostScript ConvertToPostScriptPacket Convolve ConwayGroupCo1 ConwayGroupCo2 ConwayGroupCo3 CoordinateChartData CoordinatesToolOptions CoordinateTransform CoordinateTransformData CoprimeQ Coproduct CopulaDistribution Copyable CopyDirectory CopyFile CopyTag CopyToClipboard CornerFilter CornerNeighbors Correlation CorrelationDistance CorrelationFunction CorrelationTest Cos Cosh CoshIntegral CosineDistance CosineWindow CosIntegral Cot Coth Count CounterAssignments CounterBox CounterBoxOptions CounterClockwiseContourIntegral CounterEvaluator CounterFunction CounterIncrements CounterStyle CounterStyleMenuListing CountRoots CountryData Covariance CovarianceEstimatorFunction CovarianceFunction CoxianDistribution CoxIngersollRossProcess CoxModel CoxModelFit CramerVonMisesTest CreateArchive CreateDialog CreateDirectory CreateDocument CreateIntermediateDirectories CreatePalette CreatePalettePacket CreateScheduledTask CreateTemporary CreateWindow CriticalityFailureImportance CriticalitySuccessImportance CriticalSection Cross CrossingDetect CrossMatrix Csc Csch CubeRoot Cubics Cuboid CuboidBox Cumulant CumulantGeneratingFunction Cup CupCap Curl CurlyDoubleQuote CurlyQuote CurrentImage CurrentlySpeakingPacket CurrentValue CurvatureFlowFilter CurveClosed Cyan CycleGraph CycleIndexPolynomial Cycles CyclicGroup Cyclotomic Cylinder CylinderBox CylindricalDecomposition ' +
      'D DagumDistribution DamerauLevenshteinDistance DampingFactor Darker Dashed Dashing DataCompression DataDistribution DataRange DataReversed Date DateDelimiters DateDifference DateFunction DateList DateListLogPlot DateListPlot DatePattern DatePlus DateRange DateString DateTicksFormat DaubechiesWavelet DavisDistribution DawsonF DayCount DayCountConvention DayMatchQ DayName DayPlus DayRange DayRound DeBruijnGraph Debug DebugTag Decimal DeclareKnownSymbols DeclarePackage Decompose Decrement DedekindEta Default DefaultAxesStyle DefaultBaseStyle DefaultBoxStyle DefaultButton DefaultColor DefaultControlPlacement DefaultDuplicateCellStyle DefaultDuration DefaultElement DefaultFaceGridsStyle DefaultFieldHintStyle DefaultFont DefaultFontProperties DefaultFormatType DefaultFormatTypeForStyle DefaultFrameStyle DefaultFrameTicksStyle DefaultGridLinesStyle DefaultInlineFormatType DefaultInputFormatType DefaultLabelStyle DefaultMenuStyle DefaultNaturalLanguage DefaultNewCellStyle DefaultNewInlineCellStyle DefaultNotebook DefaultOptions DefaultOutputFormatType DefaultStyle DefaultStyleDefinitions DefaultTextFormatType DefaultTextInlineFormatType DefaultTicksStyle DefaultTooltipStyle DefaultValues Defer DefineExternal DefineInputStreamMethod DefineOutputStreamMethod Definition Degree DegreeCentrality DegreeGraphDistribution DegreeLexicographic DegreeReverseLexicographic Deinitialization Del Deletable Delete DeleteBorderComponents DeleteCases DeleteContents DeleteDirectory DeleteDuplicates DeleteFile DeleteSmallComponents DeleteWithContents DeletionWarning Delimiter DelimiterFlashTime DelimiterMatching Delimiters Denominator DensityGraphics DensityHistogram DensityPlot DependentVariables Deploy Deployed Depth DepthFirstScan Derivative DerivativeFilter DescriptorStateSpace DesignMatrix Det DGaussianWavelet DiacriticalPositioning Diagonal DiagonalMatrix Dialog DialogIndent DialogInput DialogLevel DialogNotebook DialogProlog DialogReturn DialogSymbols Diamond DiamondMatrix DiceDissimilarity DictionaryLookup DifferenceDelta DifferenceOrder DifferenceRoot DifferenceRootReduce Differences DifferentialD DifferentialRoot DifferentialRootReduce DifferentiatorFilter DigitBlock DigitBlockMinimum DigitCharacter DigitCount DigitQ DihedralGroup Dilation Dimensions DiracComb DiracDelta DirectedEdge DirectedEdges DirectedGraph DirectedGraphQ DirectedInfinity Direction Directive Directory DirectoryName DirectoryQ DirectoryStack DirichletCharacter DirichletConvolve DirichletDistribution DirichletL DirichletTransform DirichletWindow DisableConsolePrintPacket DiscreteChirpZTransform DiscreteConvolve DiscreteDelta DiscreteHadamardTransform DiscreteIndicator DiscreteLQEstimatorGains DiscreteLQRegulatorGains DiscreteLyapunovSolve DiscreteMarkovProcess DiscretePlot DiscretePlot3D DiscreteRatio DiscreteRiccatiSolve DiscreteShift DiscreteTimeModelQ DiscreteUniformDistribution DiscreteVariables DiscreteWaveletData DiscreteWaveletPacketTransform ' +
      'DiscreteWaveletTransform Discriminant Disjunction Disk DiskBox DiskMatrix Dispatch DispersionEstimatorFunction Display DisplayAllSteps DisplayEndPacket DisplayFlushImagePacket DisplayForm DisplayFunction DisplayPacket DisplayRules DisplaySetSizePacket DisplayString DisplayTemporary DisplayWith DisplayWithRef DisplayWithVariable DistanceFunction DistanceTransform Distribute Distributed DistributedContexts DistributeDefinitions DistributionChart DistributionDomain DistributionFitTest DistributionParameterAssumptions DistributionParameterQ Dithering Div Divergence Divide DivideBy Dividers Divisible Divisors DivisorSigma DivisorSum DMSList DMSString Do DockedCells DocumentNotebook DominantColors DOSTextFormat Dot DotDashed DotEqual Dotted DoubleBracketingBar DoubleContourIntegral DoubleDownArrow DoubleLeftArrow DoubleLeftRightArrow DoubleLeftTee DoubleLongLeftArrow DoubleLongLeftRightArrow DoubleLongRightArrow DoubleRightArrow DoubleRightTee DoubleUpArrow DoubleUpDownArrow DoubleVerticalBar DoublyInfinite Down DownArrow DownArrowBar DownArrowUpArrow DownLeftRightVector DownLeftTeeVector DownLeftVector DownLeftVectorBar DownRightTeeVector DownRightVector DownRightVectorBar Downsample DownTee DownTeeArrow DownValues DragAndDrop DrawEdges DrawFrontFaces DrawHighlighted Drop DSolve Dt DualLinearProgramming DualSystemsModel DumpGet DumpSave DuplicateFreeQ Dynamic DynamicBox DynamicBoxOptions DynamicEvaluationTimeout DynamicLocation DynamicModule DynamicModuleBox DynamicModuleBoxOptions DynamicModuleParent DynamicModuleValues DynamicName DynamicNamespace DynamicReference DynamicSetting DynamicUpdating DynamicWrapper DynamicWrapperBox DynamicWrapperBoxOptions ' +
      'E EccentricityCentrality EdgeAdd EdgeBetweennessCentrality EdgeCapacity EdgeCapForm EdgeColor EdgeConnectivity EdgeCost EdgeCount EdgeCoverQ EdgeDashing EdgeDelete EdgeDetect EdgeForm EdgeIndex EdgeJoinForm EdgeLabeling EdgeLabels EdgeLabelStyle EdgeList EdgeOpacity EdgeQ EdgeRenderingFunction EdgeRules EdgeShapeFunction EdgeStyle EdgeThickness EdgeWeight Editable EditButtonSettings EditCellTagsSettings EditDistance EffectiveInterest Eigensystem Eigenvalues EigenvectorCentrality Eigenvectors Element ElementData Eliminate EliminationOrder EllipticE EllipticExp EllipticExpPrime EllipticF EllipticFilterModel EllipticK EllipticLog EllipticNomeQ EllipticPi EllipticReducedHalfPeriods EllipticTheta EllipticThetaPrime EmitSound EmphasizeSyntaxErrors EmpiricalDistribution Empty EmptyGraphQ EnableConsolePrintPacket Enabled Encode End EndAdd EndDialogPacket EndFrontEndInteractionPacket EndOfFile EndOfLine EndOfString EndPackage EngineeringForm Enter EnterExpressionPacket EnterTextPacket Entropy EntropyFilter Environment Epilog Equal EqualColumns EqualRows EqualTilde EquatedTo Equilibrium EquirippleFilterKernel Equivalent Erf Erfc Erfi ErlangB ErlangC ErlangDistribution Erosion ErrorBox ErrorBoxOptions ErrorNorm ErrorPacket ErrorsDialogSettings EstimatedDistribution EstimatedProcess EstimatorGains EstimatorRegulator EuclideanDistance EulerE EulerGamma EulerianGraphQ EulerPhi Evaluatable Evaluate Evaluated EvaluatePacket EvaluationCell EvaluationCompletionAction EvaluationElements EvaluationMode EvaluationMonitor EvaluationNotebook EvaluationObject EvaluationOrder Evaluator EvaluatorNames EvenQ EventData EventEvaluator EventHandler EventHandlerTag EventLabels ExactBlackmanWindow ExactNumberQ ExactRootIsolation ExampleData Except ExcludedForms ExcludePods Exclusions ExclusionsStyle Exists Exit ExitDialog Exp Expand ExpandAll ExpandDenominator ExpandFileName ExpandNumerator Expectation ExpectationE ExpectedValue ExpGammaDistribution ExpIntegralE ExpIntegralEi Exponent ExponentFunction ExponentialDistribution ExponentialFamily ExponentialGeneratingFunction ExponentialMovingAverage ExponentialPowerDistribution ExponentPosition ExponentStep Export ExportAutoReplacements ExportPacket ExportString Expression ExpressionCell ExpressionPacket ExpToTrig ExtendedGCD Extension ExtentElementFunction ExtentMarkers ExtentSize ExternalCall ExternalDataCharacterEncoding Extract ExtractArchive ExtremeValueDistribution ' +
      'FaceForm FaceGrids FaceGridsStyle Factor FactorComplete Factorial Factorial2 FactorialMoment FactorialMomentGeneratingFunction FactorialPower FactorInteger FactorList FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList Fail FailureDistribution False FARIMAProcess FEDisableConsolePrintPacket FeedbackSector FeedbackSectorStyle FeedbackType FEEnableConsolePrintPacket Fibonacci FieldHint FieldHintStyle FieldMasked FieldSize File FileBaseName FileByteCount FileDate FileExistsQ FileExtension FileFormat FileHash FileInformation FileName FileNameDepth FileNameDialogSettings FileNameDrop FileNameJoin FileNames FileNameSetter FileNameSplit FileNameTake FilePrint FileType FilledCurve FilledCurveBox Filling FillingStyle FillingTransform FilterRules FinancialBond FinancialData FinancialDerivative FinancialIndicator Find FindArgMax FindArgMin FindClique FindClusters FindCurvePath FindDistributionParameters FindDivisions FindEdgeCover FindEdgeCut FindEulerianCycle FindFaces FindFile FindFit FindGeneratingFunction FindGeoLocation FindGeometricTransform FindGraphCommunities FindGraphIsomorphism FindGraphPartition FindHamiltonianCycle FindIndependentEdgeSet FindIndependentVertexSet FindInstance FindIntegerNullVector FindKClan FindKClique FindKClub FindKPlex FindLibrary FindLinearRecurrence FindList FindMaximum FindMaximumFlow FindMaxValue FindMinimum FindMinimumCostFlow FindMinimumCut FindMinValue FindPermutation FindPostmanTour FindProcessParameters FindRoot FindSequenceFunction FindSettings FindShortestPath FindShortestTour FindThreshold FindVertexCover FindVertexCut Fine FinishDynamic FiniteAbelianGroupCount FiniteGroupCount FiniteGroupData First FirstPassageTimeDistribution FischerGroupFi22 FischerGroupFi23 FischerGroupFi24Prime FisherHypergeometricDistribution FisherRatioTest FisherZDistribution Fit FitAll FittedModel FixedPoint FixedPointList FlashSelection Flat Flatten FlattenAt FlatTopWindow FlipView Floor FlushPrintOutputPacket Fold FoldList Font FontColor FontFamily FontForm FontName FontOpacity FontPostScriptName FontProperties FontReencoding FontSize FontSlant FontSubstitutions FontTracking FontVariations FontWeight For ForAll Format FormatRules FormatType FormatTypeAutoConvert FormatValues FormBox FormBoxOptions FortranForm Forward ForwardBackward Fourier FourierCoefficient FourierCosCoefficient FourierCosSeries FourierCosTransform FourierDCT FourierDCTFilter FourierDCTMatrix FourierDST FourierDSTMatrix FourierMatrix FourierParameters FourierSequenceTransform FourierSeries FourierSinCoefficient FourierSinSeries FourierSinTransform FourierTransform FourierTrigSeries FractionalBrownianMotionProcess FractionalPart FractionBox FractionBoxOptions FractionLine Frame FrameBox FrameBoxOptions Framed FrameInset FrameLabel Frameless FrameMargins FrameStyle FrameTicks FrameTicksStyle FRatioDistribution FrechetDistribution FreeQ FrequencySamplingFilterKernel FresnelC FresnelS Friday FrobeniusNumber FrobeniusSolve ' +
      'FromCharacterCode FromCoefficientRules FromContinuedFraction FromDate FromDigits FromDMS Front FrontEndDynamicExpression FrontEndEventActions FrontEndExecute FrontEndObject FrontEndResource FrontEndResourceString FrontEndStackSize FrontEndToken FrontEndTokenExecute FrontEndValueCache FrontEndVersion FrontFaceColor FrontFaceOpacity Full FullAxes FullDefinition FullForm FullGraphics FullOptions FullSimplify Function FunctionExpand FunctionInterpolation FunctionSpace FussellVeselyImportance ' +
      'GaborFilter GaborMatrix GaborWavelet GainMargins GainPhaseMargins Gamma GammaDistribution GammaRegularized GapPenalty Gather GatherBy GaugeFaceElementFunction GaugeFaceStyle GaugeFrameElementFunction GaugeFrameSize GaugeFrameStyle GaugeLabels GaugeMarkers GaugeStyle GaussianFilter GaussianIntegers GaussianMatrix GaussianWindow GCD GegenbauerC General GeneralizedLinearModelFit GenerateConditions GeneratedCell GeneratedParameters GeneratingFunction Generic GenericCylindricalDecomposition GenomeData GenomeLookup GeodesicClosing GeodesicDilation GeodesicErosion GeodesicOpening GeoDestination GeodesyData GeoDirection GeoDistance GeoGridPosition GeometricBrownianMotionProcess GeometricDistribution GeometricMean GeometricMeanFilter GeometricTransformation GeometricTransformation3DBox GeometricTransformation3DBoxOptions GeometricTransformationBox GeometricTransformationBoxOptions GeoPosition GeoPositionENU GeoPositionXYZ GeoProjectionData GestureHandler GestureHandlerTag Get GetBoundingBoxSizePacket GetContext GetEnvironment GetFileName GetFrontEndOptionsDataPacket GetLinebreakInformationPacket GetMenusPacket GetPageBreakInformationPacket Glaisher GlobalClusteringCoefficient GlobalPreferences GlobalSession Glow GoldenRatio GompertzMakehamDistribution GoodmanKruskalGamma GoodmanKruskalGammaTest Goto Grad Gradient GradientFilter GradientOrientationFilter Graph GraphAssortativity GraphCenter GraphComplement GraphData GraphDensity GraphDiameter GraphDifference GraphDisjointUnion ' +
      'GraphDistance GraphDistanceMatrix GraphElementData GraphEmbedding GraphHighlight GraphHighlightStyle GraphHub Graphics Graphics3D Graphics3DBox Graphics3DBoxOptions GraphicsArray GraphicsBaseline GraphicsBox GraphicsBoxOptions GraphicsColor GraphicsColumn GraphicsComplex GraphicsComplex3DBox GraphicsComplex3DBoxOptions GraphicsComplexBox GraphicsComplexBoxOptions GraphicsContents GraphicsData GraphicsGrid GraphicsGridBox GraphicsGroup GraphicsGroup3DBox GraphicsGroup3DBoxOptions GraphicsGroupBox GraphicsGroupBoxOptions GraphicsGrouping GraphicsHighlightColor GraphicsRow GraphicsSpacing GraphicsStyle GraphIntersection GraphLayout GraphLinkEfficiency GraphPeriphery GraphPlot GraphPlot3D GraphPower GraphPropertyDistribution GraphQ GraphRadius GraphReciprocity GraphRoot GraphStyle GraphUnion Gray GrayLevel GreatCircleDistance Greater GreaterEqual GreaterEqualLess GreaterFullEqual GreaterGreater GreaterLess GreaterSlantEqual GreaterTilde Green Grid GridBaseline GridBox GridBoxAlignment GridBoxBackground GridBoxDividers GridBoxFrame GridBoxItemSize GridBoxItemStyle GridBoxOptions GridBoxSpacings GridCreationSettings GridDefaultElement GridElementStyleOptions GridFrame GridFrameMargins GridGraph GridLines GridLinesStyle GroebnerBasis GroupActionBase GroupCentralizer GroupElementFromWord GroupElementPosition GroupElementQ GroupElements GroupElementToWord GroupGenerators GroupMultiplicationTable GroupOrbits GroupOrder GroupPageBreakWithin GroupSetwiseStabilizer GroupStabilizer GroupStabilizerChain Gudermannian GumbelDistribution ' +
      'HaarWavelet HadamardMatrix HalfNormalDistribution HamiltonianGraphQ HammingDistance HammingWindow HankelH1 HankelH2 HankelMatrix HannPoissonWindow HannWindow HaradaNortonGroupHN HararyGraph HarmonicMean HarmonicMeanFilter HarmonicNumber Hash HashTable Haversine HazardFunction Head HeadCompose Heads HeavisideLambda HeavisidePi HeavisideTheta HeldGroupHe HeldPart HelpBrowserLookup HelpBrowserNotebook HelpBrowserSettings HermiteDecomposition HermiteH HermitianMatrixQ HessenbergDecomposition Hessian HexadecimalCharacter Hexahedron HexahedronBox HexahedronBoxOptions HiddenSurface HighlightGraph HighlightImage HighpassFilter HigmanSimsGroupHS HilbertFilter HilbertMatrix Histogram Histogram3D HistogramDistribution HistogramList HistogramTransform HistogramTransformInterpolation HitMissTransform HITSCentrality HodgeDual HoeffdingD HoeffdingDTest Hold HoldAll HoldAllComplete HoldComplete HoldFirst HoldForm HoldPattern HoldRest HolidayCalendar HomeDirectory HomePage Horizontal HorizontalForm HorizontalGauge HorizontalScrollPosition HornerForm HotellingTSquareDistribution HoytDistribution HTMLSave Hue HumpDownHump HumpEqual HurwitzLerchPhi HurwitzZeta HyperbolicDistribution HypercubeGraph HyperexponentialDistribution Hyperfactorial Hypergeometric0F1 Hypergeometric0F1Regularized Hypergeometric1F1 Hypergeometric1F1Regularized Hypergeometric2F1 Hypergeometric2F1Regularized HypergeometricDistribution HypergeometricPFQ HypergeometricPFQRegularized HypergeometricU Hyperlink HyperlinkCreationSettings Hyphenation HyphenationOptions HypoexponentialDistribution HypothesisTestData ' +
      'I Identity IdentityMatrix If IgnoreCase Im Image Image3D Image3DSlices ImageAccumulate ImageAdd ImageAdjust ImageAlign ImageApply ImageAspectRatio ImageAssemble ImageCache ImageCacheValid ImageCapture ImageChannels ImageClip ImageColorSpace ImageCompose ImageConvolve ImageCooccurrence ImageCorners ImageCorrelate ImageCorrespondingPoints ImageCrop ImageData ImageDataPacket ImageDeconvolve ImageDemosaic ImageDifference ImageDimensions ImageDistance ImageEffect ImageFeatureTrack ImageFileApply ImageFileFilter ImageFileScan ImageFilter ImageForestingComponents ImageForwardTransformation ImageHistogram ImageKeypoints ImageLevels ImageLines ImageMargins ImageMarkers ImageMeasurements ImageMultiply ImageOffset ImagePad ImagePadding ImagePartition ImagePeriodogram ImagePerspectiveTransformation ImageQ ImageRangeCache ImageReflect ImageRegion ImageResize ImageResolution ImageRotate ImageRotated ImageScaled ImageScan ImageSize ImageSizeAction ImageSizeCache ImageSizeMultipliers ImageSizeRaw ImageSubtract ImageTake ImageTransformation ImageTrim ImageType ImageValue ImageValuePositions Implies Import ImportAutoReplacements ImportString ImprovementImportance In IncidenceGraph IncidenceList IncidenceMatrix IncludeConstantBasis IncludeFileExtension IncludePods IncludeSingularTerm Increment Indent IndentingNewlineSpacings IndentMaxFraction IndependenceTest IndependentEdgeSetQ IndependentUnit IndependentVertexSetQ Indeterminate IndexCreationOptions Indexed IndexGraph IndexTag Inequality InexactNumberQ InexactNumbers Infinity Infix Information Inherited InheritScope Initialization InitializationCell InitializationCellEvaluation InitializationCellWarning InlineCounterAssignments InlineCounterIncrements InlineRules Inner Inpaint Input InputAliases InputAssumptions InputAutoReplacements InputField InputFieldBox InputFieldBoxOptions InputForm InputGrouping InputNamePacket InputNotebook InputPacket InputSettings InputStream InputString InputStringPacket InputToBoxFormPacket Insert InsertionPointObject InsertResults Inset Inset3DBox Inset3DBoxOptions InsetBox InsetBoxOptions Install InstallService InString Integer IntegerDigits IntegerExponent IntegerLength IntegerPart IntegerPartitions IntegerQ Integers IntegerString Integral Integrate Interactive InteractiveTradingChart Interlaced Interleaving InternallyBalancedDecomposition InterpolatingFunction InterpolatingPolynomial Interpolation InterpolationOrder InterpolationPoints InterpolationPrecision Interpretation InterpretationBox InterpretationBoxOptions InterpretationFunction ' +
      'InterpretTemplate InterquartileRange Interrupt InterruptSettings Intersection Interval IntervalIntersection IntervalMemberQ IntervalUnion Inverse InverseBetaRegularized InverseCDF InverseChiSquareDistribution InverseContinuousWaveletTransform InverseDistanceTransform InverseEllipticNomeQ InverseErf InverseErfc InverseFourier InverseFourierCosTransform InverseFourierSequenceTransform InverseFourierSinTransform InverseFourierTransform InverseFunction InverseFunctions InverseGammaDistribution InverseGammaRegularized InverseGaussianDistribution InverseGudermannian InverseHaversine InverseJacobiCD InverseJacobiCN InverseJacobiCS InverseJacobiDC InverseJacobiDN InverseJacobiDS InverseJacobiNC InverseJacobiND InverseJacobiNS InverseJacobiSC InverseJacobiSD InverseJacobiSN InverseLaplaceTransform InversePermutation InverseRadon InverseSeries InverseSurvivalFunction InverseWaveletTransform InverseWeierstrassP InverseZTransform Invisible InvisibleApplication InvisibleTimes IrreduciblePolynomialQ IsolatingInterval IsomorphicGraphQ IsotopeData Italic Item ItemBox ItemBoxOptions ItemSize ItemStyle ItoProcess ' +
      'JaccardDissimilarity JacobiAmplitude Jacobian JacobiCD JacobiCN JacobiCS JacobiDC JacobiDN JacobiDS JacobiNC JacobiND JacobiNS JacobiP JacobiSC JacobiSD JacobiSN JacobiSymbol JacobiZeta JankoGroupJ1 JankoGroupJ2 JankoGroupJ3 JankoGroupJ4 JarqueBeraALMTest JohnsonDistribution Join Joined JoinedCurve JoinedCurveBox JoinForm JordanDecomposition JordanModelDecomposition ' +
      'K KagiChart KaiserBesselWindow KaiserWindow KalmanEstimator KalmanFilter KarhunenLoeveDecomposition KaryTree KatzCentrality KCoreComponents KDistribution KelvinBei KelvinBer KelvinKei KelvinKer KendallTau KendallTauTest KernelExecute KernelMixtureDistribution KernelObject Kernels Ket Khinchin KirchhoffGraph KirchhoffMatrix KleinInvariantJ KnightTourGraph KnotData KnownUnitQ KolmogorovSmirnovTest KroneckerDelta KroneckerModelDecomposition KroneckerProduct KroneckerSymbol KuiperTest KumaraswamyDistribution Kurtosis KuwaharaFilter ' +
      'Label Labeled LabeledSlider LabelingFunction LabelStyle LaguerreL LambdaComponents LambertW LanczosWindow LandauDistribution Language LanguageCategory LaplaceDistribution LaplaceTransform Laplacian LaplacianFilter LaplacianGaussianFilter Large Larger Last Latitude LatitudeLongitude LatticeData LatticeReduce Launch LaunchKernels LayeredGraphPlot LayerSizeFunction LayoutInformation LCM LeafCount LeapYearQ LeastSquares LeastSquaresFilterKernel Left LeftArrow LeftArrowBar LeftArrowRightArrow LeftDownTeeVector LeftDownVector LeftDownVectorBar LeftRightArrow LeftRightVector LeftTee LeftTeeArrow LeftTeeVector LeftTriangle LeftTriangleBar LeftTriangleEqual LeftUpDownVector LeftUpTeeVector LeftUpVector LeftUpVectorBar LeftVector LeftVectorBar LegendAppearance Legended LegendFunction LegendLabel LegendLayout LegendMargins LegendMarkers LegendMarkerSize LegendreP LegendreQ LegendreType Length LengthWhile LerchPhi Less LessEqual LessEqualGreater LessFullEqual LessGreater LessLess LessSlantEqual LessTilde LetterCharacter LetterQ Level LeveneTest LeviCivitaTensor LevyDistribution Lexicographic LibraryFunction LibraryFunctionError LibraryFunctionInformation LibraryFunctionLoad LibraryFunctionUnload LibraryLoad LibraryUnload LicenseID LiftingFilterData LiftingWaveletTransform LightBlue LightBrown LightCyan Lighter LightGray LightGreen Lighting LightingAngle LightMagenta LightOrange LightPink LightPurple LightRed LightSources LightYellow Likelihood Limit LimitsPositioning LimitsPositioningTokens LindleyDistribution Line Line3DBox LinearFilter LinearFractionalTransform LinearModelFit LinearOffsetFunction LinearProgramming LinearRecurrence LinearSolve LinearSolveFunction LineBox LineBreak LinebreakAdjustments LineBreakChart LineBreakWithin LineColor LineForm LineGraph LineIndent LineIndentMaxFraction LineIntegralConvolutionPlot LineIntegralConvolutionScale LineLegend LineOpacity LineSpacing LineWrapParts LinkActivate LinkClose LinkConnect LinkConnectedQ LinkCreate LinkError LinkFlush LinkFunction LinkHost LinkInterrupt LinkLaunch LinkMode LinkObject LinkOpen LinkOptions LinkPatterns LinkProtocol LinkRead LinkReadHeld LinkReadyQ Links LinkWrite LinkWriteHeld LiouvilleLambda List Listable ListAnimate ListContourPlot ListContourPlot3D ListConvolve ListCorrelate ListCurvePathPlot ListDeconvolve ListDensityPlot Listen ListFourierSequenceTransform ListInterpolation ListLineIntegralConvolutionPlot ListLinePlot ListLogLinearPlot ListLogLogPlot ListLogPlot ListPicker ListPickerBox ListPickerBoxBackground ListPickerBoxOptions ListPlay ListPlot ListPlot3D ListPointPlot3D ListPolarPlot ListQ ListStreamDensityPlot ListStreamPlot ListSurfacePlot3D ListVectorDensityPlot ListVectorPlot ListVectorPlot3D ListZTransform Literal LiteralSearch LocalClusteringCoefficient LocalizeVariables LocationEquivalenceTest LocationTest Locator LocatorAutoCreate LocatorBox LocatorBoxOptions LocatorCentering LocatorPane LocatorPaneBox LocatorPaneBoxOptions ' +
      'LocatorRegion Locked Log Log10 Log2 LogBarnesG LogGamma LogGammaDistribution LogicalExpand LogIntegral LogisticDistribution LogitModelFit LogLikelihood LogLinearPlot LogLogisticDistribution LogLogPlot LogMultinormalDistribution LogNormalDistribution LogPlot LogRankTest LogSeriesDistribution LongEqual Longest LongestAscendingSequence LongestCommonSequence LongestCommonSequencePositions LongestCommonSubsequence LongestCommonSubsequencePositions LongestMatch LongForm Longitude LongLeftArrow LongLeftRightArrow LongRightArrow Loopback LoopFreeGraphQ LowerCaseQ LowerLeftArrow LowerRightArrow LowerTriangularize LowpassFilter LQEstimatorGains LQGRegulator LQOutputRegulatorGains LQRegulatorGains LUBackSubstitution LucasL LuccioSamiComponents LUDecomposition LyapunovSolve LyonsGroupLy ' +
      'MachineID MachineName MachineNumberQ MachinePrecision MacintoshSystemPageSetup Magenta Magnification Magnify MainSolve MaintainDynamicCaches Majority MakeBoxes MakeExpression MakeRules MangoldtLambda ManhattanDistance Manipulate Manipulator MannWhitneyTest MantissaExponent Manual Map MapAll MapAt MapIndexed MAProcess MapThread MarcumQ MardiaCombinedTest MardiaKurtosisTest MardiaSkewnessTest MarginalDistribution MarkovProcessProperties Masking MatchingDissimilarity MatchLocalNameQ MatchLocalNames MatchQ Material MathematicaNotation MathieuC MathieuCharacteristicA MathieuCharacteristicB MathieuCharacteristicExponent MathieuCPrime MathieuGroupM11 MathieuGroupM12 MathieuGroupM22 MathieuGroupM23 MathieuGroupM24 MathieuS MathieuSPrime MathMLForm MathMLText Matrices MatrixExp MatrixForm MatrixFunction MatrixLog MatrixPlot MatrixPower MatrixQ MatrixRank Max MaxBend MaxDetect MaxExtraBandwidths MaxExtraConditions MaxFeatures MaxFilter Maximize MaxIterations MaxMemoryUsed MaxMixtureKernels MaxPlotPoints MaxPoints MaxRecursion MaxStableDistribution MaxStepFraction MaxSteps MaxStepSize MaxValue MaxwellDistribution McLaughlinGroupMcL Mean MeanClusteringCoefficient MeanDegreeConnectivity MeanDeviation MeanFilter MeanGraphDistance MeanNeighborDegree MeanShift MeanShiftFilter Median MedianDeviation MedianFilter Medium MeijerG MeixnerDistribution MemberQ MemoryConstrained MemoryInUse Menu MenuAppearance MenuCommandKey MenuEvaluator MenuItem MenuPacket MenuSortingValue MenuStyle MenuView MergeDifferences Mesh MeshFunctions MeshRange MeshShading MeshStyle Message MessageDialog MessageList MessageName MessageOptions MessagePacket Messages MessagesNotebook MetaCharacters MetaInformation Method MethodOptions MexicanHatWavelet MeyerWavelet Min MinDetect MinFilter MinimalPolynomial MinimalStateSpaceModel Minimize Minors MinRecursion MinSize MinStableDistribution Minus MinusPlus MinValue Missing MissingDataMethod MittagLefflerE MixedRadix MixedRadixQuantity MixtureDistribution Mod Modal Mode Modular ModularLambda Module Modulus MoebiusMu Moment Momentary MomentConvert MomentEvaluate MomentGeneratingFunction Monday Monitor MonomialList MonomialOrder MonsterGroupM MorletWavelet MorphologicalBinarize MorphologicalBranchPoints MorphologicalComponents MorphologicalEulerNumber MorphologicalGraph MorphologicalPerimeter MorphologicalTransform Most MouseAnnotation MouseAppearance MouseAppearanceTag MouseButtons Mouseover MousePointerNote MousePosition MovingAverage MovingMedian MoyalDistribution MultiedgeStyle MultilaunchWarning MultiLetterItalics MultiLetterStyle MultilineFunction Multinomial MultinomialDistribution MultinormalDistribution MultiplicativeOrder Multiplicity Multiselection MultivariateHypergeometricDistribution MultivariatePoissonDistribution MultivariateTDistribution ' +
      'N NakagamiDistribution NameQ Names NamespaceBox Nand NArgMax NArgMin NBernoulliB NCache NDSolve NDSolveValue Nearest NearestFunction NeedCurrentFrontEndPackagePacket NeedCurrentFrontEndSymbolsPacket NeedlemanWunschSimilarity Needs Negative NegativeBinomialDistribution NegativeMultinomialDistribution NeighborhoodGraph Nest NestedGreaterGreater NestedLessLess NestedScriptRules NestList NestWhile NestWhileList NevilleThetaC NevilleThetaD NevilleThetaN NevilleThetaS NewPrimitiveStyle NExpectation Next NextPrime NHoldAll NHoldFirst NHoldRest NicholsGridLines NicholsPlot NIntegrate NMaximize NMaxValue NMinimize NMinValue NominalVariables NonAssociative NoncentralBetaDistribution NoncentralChiSquareDistribution NoncentralFRatioDistribution NoncentralStudentTDistribution NonCommutativeMultiply NonConstants None NonlinearModelFit NonlocalMeansFilter NonNegative NonPositive Nor NorlundB Norm Normal NormalDistribution NormalGrouping Normalize NormalizedSquaredEuclideanDistance NormalsFunction NormFunction Not NotCongruent NotCupCap NotDoubleVerticalBar Notebook NotebookApply NotebookAutoSave NotebookClose NotebookConvertSettings NotebookCreate NotebookCreateReturnObject NotebookDefault NotebookDelete NotebookDirectory NotebookDynamicExpression NotebookEvaluate NotebookEventActions NotebookFileName NotebookFind NotebookFindReturnObject NotebookGet NotebookGetLayoutInformationPacket NotebookGetMisspellingsPacket NotebookInformation NotebookInterfaceObject NotebookLocate NotebookObject NotebookOpen NotebookOpenReturnObject NotebookPath NotebookPrint NotebookPut NotebookPutReturnObject NotebookRead NotebookResetGeneratedCells Notebooks NotebookSave NotebookSaveAs NotebookSelection NotebookSetupLayoutInformationPacket NotebooksMenu NotebookWrite NotElement NotEqualTilde NotExists NotGreater NotGreaterEqual NotGreaterFullEqual NotGreaterGreater NotGreaterLess NotGreaterSlantEqual NotGreaterTilde NotHumpDownHump NotHumpEqual NotLeftTriangle NotLeftTriangleBar NotLeftTriangleEqual NotLess NotLessEqual NotLessFullEqual NotLessGreater NotLessLess NotLessSlantEqual NotLessTilde NotNestedGreaterGreater NotNestedLessLess NotPrecedes NotPrecedesEqual NotPrecedesSlantEqual NotPrecedesTilde NotReverseElement NotRightTriangle NotRightTriangleBar NotRightTriangleEqual NotSquareSubset NotSquareSubsetEqual NotSquareSuperset NotSquareSupersetEqual NotSubset NotSubsetEqual NotSucceeds NotSucceedsEqual NotSucceedsSlantEqual NotSucceedsTilde NotSuperset NotSupersetEqual NotTilde NotTildeEqual NotTildeFullEqual NotTildeTilde NotVerticalBar NProbability NProduct NProductFactors NRoots NSolve NSum NSumTerms Null NullRecords NullSpace NullWords Number NumberFieldClassNumber NumberFieldDiscriminant NumberFieldFundamentalUnits NumberFieldIntegralBasis NumberFieldNormRepresentatives NumberFieldRegulator NumberFieldRootsOfUnity NumberFieldSignature NumberForm NumberFormat NumberMarks NumberMultiplier NumberPadding NumberPoint NumberQ NumberSeparator ' +
      'NumberSigns NumberString Numerator NumericFunction NumericQ NuttallWindow NValues NyquistGridLines NyquistPlot ' +
      'O ObservabilityGramian ObservabilityMatrix ObservableDecomposition ObservableModelQ OddQ Off Offset OLEData On ONanGroupON OneIdentity Opacity Open OpenAppend Opener OpenerBox OpenerBoxOptions OpenerView OpenFunctionInspectorPacket Opening OpenRead OpenSpecialOptions OpenTemporary OpenWrite Operate OperatingSystem OptimumFlowData Optional OptionInspectorSettings OptionQ Options OptionsPacket OptionsPattern OptionValue OptionValueBox OptionValueBoxOptions Or Orange Order OrderDistribution OrderedQ Ordering Orderless OrnsteinUhlenbeckProcess Orthogonalize Out Outer OutputAutoOverwrite OutputControllabilityMatrix OutputControllableModelQ OutputForm OutputFormData OutputGrouping OutputMathEditExpression OutputNamePacket OutputResponse OutputSizeLimit OutputStream Over OverBar OverDot Overflow OverHat Overlaps Overlay OverlayBox OverlayBoxOptions Overscript OverscriptBox OverscriptBoxOptions OverTilde OverVector OwenT OwnValues ' +
      'PackingMethod PaddedForm Padding PadeApproximant PadLeft PadRight PageBreakAbove PageBreakBelow PageBreakWithin PageFooterLines PageFooters PageHeaderLines PageHeaders PageHeight PageRankCentrality PageWidth PairedBarChart PairedHistogram PairedSmoothHistogram PairedTTest PairedZTest PaletteNotebook PalettePath Pane PaneBox PaneBoxOptions Panel PanelBox PanelBoxOptions Paneled PaneSelector PaneSelectorBox PaneSelectorBoxOptions PaperWidth ParabolicCylinderD ParagraphIndent ParagraphSpacing ParallelArray ParallelCombine ParallelDo ParallelEvaluate Parallelization Parallelize ParallelMap ParallelNeeds ParallelProduct ParallelSubmit ParallelSum ParallelTable ParallelTry Parameter ParameterEstimator ParameterMixtureDistribution ParameterVariables ParametricFunction ParametricNDSolve ParametricNDSolveValue ParametricPlot ParametricPlot3D ParentConnect ParentDirectory ParentForm Parenthesize ParentList ParetoDistribution Part PartialCorrelationFunction PartialD ParticleData Partition PartitionsP PartitionsQ ParzenWindow PascalDistribution PassEventsDown PassEventsUp Paste PasteBoxFormInlineCells PasteButton Path PathGraph PathGraphQ Pattern PatternSequence PatternTest PauliMatrix PaulWavelet Pause PausedTime PDF PearsonChiSquareTest PearsonCorrelationTest PearsonDistribution PerformanceGoal PeriodicInterpolation Periodogram PeriodogramArray PermutationCycles PermutationCyclesQ PermutationGroup PermutationLength PermutationList PermutationListQ PermutationMax PermutationMin PermutationOrder PermutationPower PermutationProduct PermutationReplace Permutations PermutationSupport Permute PeronaMalikFilter Perpendicular PERTDistribution PetersenGraph PhaseMargins Pi Pick PIDData PIDDerivativeFilter PIDFeedforward PIDTune Piecewise PiecewiseExpand PieChart PieChart3D PillaiTrace PillaiTraceTest Pink Pivoting PixelConstrained PixelValue PixelValuePositions Placed Placeholder PlaceholderReplace Plain PlanarGraphQ Play PlayRange Plot Plot3D Plot3Matrix PlotDivision PlotJoined PlotLabel PlotLayout PlotLegends PlotMarkers PlotPoints PlotRange PlotRangeClipping PlotRangePadding PlotRegion PlotStyle Plus PlusMinus Pochhammer PodStates PodWidth Point Point3DBox PointBox PointFigureChart PointForm PointLegend PointSize PoissonConsulDistribution PoissonDistribution PoissonProcess PoissonWindow PolarAxes PolarAxesOrigin PolarGridLines PolarPlot PolarTicks PoleZeroMarkers PolyaAeppliDistribution PolyGamma Polygon Polygon3DBox Polygon3DBoxOptions PolygonBox PolygonBoxOptions PolygonHoleScale PolygonIntersections PolygonScale PolyhedronData PolyLog PolynomialExtendedGCD PolynomialForm PolynomialGCD PolynomialLCM PolynomialMod PolynomialQ PolynomialQuotient PolynomialQuotientRemainder PolynomialReduce PolynomialRemainder Polynomials PopupMenu PopupMenuBox PopupMenuBoxOptions PopupView PopupWindow Position Positive PositiveDefiniteMatrixQ PossibleZeroQ Postfix PostScript Power PowerDistribution PowerExpand PowerMod PowerModList ' +
      'PowerSpectralDensity PowersRepresentations PowerSymmetricPolynomial Precedence PrecedenceForm Precedes PrecedesEqual PrecedesSlantEqual PrecedesTilde Precision PrecisionGoal PreDecrement PredictionRoot PreemptProtect PreferencesPath Prefix PreIncrement Prepend PrependTo PreserveImageOptions Previous PriceGraphDistribution PrimaryPlaceholder Prime PrimeNu PrimeOmega PrimePi PrimePowerQ PrimeQ Primes PrimeZetaP PrimitiveRoot PrincipalComponents PrincipalValue Print PrintAction PrintForm PrintingCopies PrintingOptions PrintingPageRange PrintingStartingPageNumber PrintingStyleEnvironment PrintPrecision PrintTemporary Prism PrismBox PrismBoxOptions PrivateCellOptions PrivateEvaluationOptions PrivateFontOptions PrivateFrontEndOptions PrivateNotebookOptions PrivatePaths Probability ProbabilityDistribution ProbabilityPlot ProbabilityPr ProbabilityScalePlot ProbitModelFit ProcessEstimator ProcessParameterAssumptions ProcessParameterQ ProcessStateDomain ProcessTimeDomain Product ProductDistribution ProductLog ProgressIndicator ProgressIndicatorBox ProgressIndicatorBoxOptions Projection Prolog PromptForm Properties Property PropertyList PropertyValue Proportion Proportional Protect Protected ProteinData Pruning PseudoInverse Purple Put PutAppend Pyramid PyramidBox PyramidBoxOptions ' +
      'QBinomial QFactorial QGamma QHypergeometricPFQ QPochhammer QPolyGamma QRDecomposition QuadraticIrrationalQ Quantile QuantilePlot Quantity QuantityForm QuantityMagnitude QuantityQ QuantityUnit Quartics QuartileDeviation Quartiles QuartileSkewness QueueingNetworkProcess QueueingProcess QueueProperties Quiet Quit Quotient QuotientRemainder ' +
      'RadialityCentrality RadicalBox RadicalBoxOptions RadioButton RadioButtonBar RadioButtonBox RadioButtonBoxOptions Radon RamanujanTau RamanujanTauL RamanujanTauTheta RamanujanTauZ Random RandomChoice RandomComplex RandomFunction RandomGraph RandomImage RandomInteger RandomPermutation RandomPrime RandomReal RandomSample RandomSeed RandomVariate RandomWalkProcess Range RangeFilter RangeSpecification RankedMax RankedMin Raster Raster3D Raster3DBox Raster3DBoxOptions RasterArray RasterBox RasterBoxOptions Rasterize RasterSize Rational RationalFunctions Rationalize Rationals Ratios Raw RawArray RawBoxes RawData RawMedium RayleighDistribution Re Read ReadList ReadProtected Real RealBlockDiagonalForm RealDigits RealExponent Reals Reap Record RecordLists RecordSeparators Rectangle RectangleBox RectangleBoxOptions RectangleChart RectangleChart3D RecurrenceFilter RecurrenceTable RecurringDigitsForm Red Reduce RefBox ReferenceLineStyle ReferenceMarkers ReferenceMarkerStyle Refine ReflectionMatrix ReflectionTransform Refresh RefreshRate RegionBinarize RegionFunction RegionPlot RegionPlot3D RegularExpression Regularization Reinstall Release ReleaseHold ReliabilityDistribution ReliefImage ReliefPlot Remove RemoveAlphaChannel RemoveAsynchronousTask Removed RemoveInputStreamMethod RemoveOutputStreamMethod RemoveProperty RemoveScheduledTask RenameDirectory RenameFile RenderAll RenderingOptions RenewalProcess RenkoChart Repeated RepeatedNull RepeatedString Replace ReplaceAll ReplaceHeldPart ReplaceImageValue ReplaceList ReplacePart ReplacePixelValue ReplaceRepeated Resampling Rescale RescalingTransform ResetDirectory ResetMenusPacket ResetScheduledTask Residue Resolve Rest Resultant ResumePacket Return ReturnExpressionPacket ReturnInputFormPacket ReturnPacket ReturnTextPacket Reverse ReverseBiorthogonalSplineWavelet ReverseElement ReverseEquilibrium ReverseGraph ReverseUpEquilibrium RevolutionAxis RevolutionPlot3D RGBColor RiccatiSolve RiceDistribution RidgeFilter RiemannR RiemannSiegelTheta RiemannSiegelZ Riffle Right RightArrow RightArrowBar RightArrowLeftArrow RightCosetRepresentative RightDownTeeVector RightDownVector RightDownVectorBar RightTee RightTeeArrow RightTeeVector RightTriangle RightTriangleBar RightTriangleEqual RightUpDownVector RightUpTeeVector RightUpVector RightUpVectorBar RightVector RightVectorBar RiskAchievementImportance RiskReductionImportance RogersTanimotoDissimilarity Root RootApproximant RootIntervals RootLocusPlot RootMeanSquare RootOfUnityQ RootReduce Roots RootSum Rotate RotateLabel RotateLeft RotateRight RotationAction RotationBox RotationBoxOptions RotationMatrix RotationTransform Round RoundImplies RoundingRadius Row RowAlignments RowBackgrounds RowBox RowHeights RowLines RowMinHeight RowReduce RowsEqual RowSpacings RSolve RudvalisGroupRu Rule RuleCondition RuleDelayed RuleForm RulerUnits Run RunScheduledTask RunThrough RuntimeAttributes RuntimeOptions RussellRaoDissimilarity ' +
      'SameQ SameTest SampleDepth SampledSoundFunction SampledSoundList SampleRate SamplingPeriod SARIMAProcess SARMAProcess SatisfiabilityCount SatisfiabilityInstances SatisfiableQ Saturday Save Saveable SaveAutoDelete SaveDefinitions SawtoothWave Scale Scaled ScaleDivisions ScaledMousePosition ScaleOrigin ScalePadding ScaleRanges ScaleRangeStyle ScalingFunctions ScalingMatrix ScalingTransform Scan ScheduledTaskActiveQ ScheduledTaskData ScheduledTaskObject ScheduledTasks SchurDecomposition ScientificForm ScreenRectangle ScreenStyleEnvironment ScriptBaselineShifts ScriptLevel ScriptMinSize ScriptRules ScriptSizeMultipliers Scrollbars ScrollingOptions ScrollPosition Sec Sech SechDistribution SectionGrouping SectorChart SectorChart3D SectorOrigin SectorSpacing SeedRandom Select Selectable SelectComponents SelectedCells SelectedNotebook Selection SelectionAnimate SelectionCell SelectionCellCreateCell SelectionCellDefaultStyle SelectionCellParentStyle SelectionCreateCell SelectionDebuggerTag SelectionDuplicateCell SelectionEvaluate SelectionEvaluateCreateCell SelectionMove SelectionPlaceholder SelectionSetStyle SelectWithContents SelfLoops SelfLoopStyle SemialgebraicComponentInstances SendMail Sequence SequenceAlignment SequenceForm SequenceHold SequenceLimit Series SeriesCoefficient SeriesData SessionTime Set SetAccuracy SetAlphaChannel SetAttributes Setbacks SetBoxFormNamesPacket SetDelayed SetDirectory SetEnvironment SetEvaluationNotebook SetFileDate SetFileLoadingContext SetNotebookStatusLine SetOptions SetOptionsPacket SetPrecision SetProperty SetSelectedNotebook SetSharedFunction SetSharedVariable SetSpeechParametersPacket SetStreamPosition SetSystemOptions Setter SetterBar SetterBox SetterBoxOptions Setting SetValue Shading Shallow ShannonWavelet ShapiroWilkTest Share Sharpen ShearingMatrix ShearingTransform ShenCastanMatrix Short ShortDownArrow Shortest ShortestMatch ShortestPathFunction ShortLeftArrow ShortRightArrow ShortUpArrow Show ShowAutoStyles ShowCellBracket ShowCellLabel ShowCellTags ShowClosedCellArea ShowContents ShowControls ShowCursorTracker ShowGroupOpenCloseIcon ShowGroupOpener ShowInvisibleCharacters ShowPageBreaks ShowPredictiveInterface ShowSelection ShowShortBoxForm ShowSpecialCharacters ShowStringCharacters ShowSyntaxStyles ShrinkingDelay ShrinkWrapBoundingBox SiegelTheta SiegelTukeyTest Sign Signature SignedRankTest SignificanceLevel SignPadding SignTest SimilarityRules SimpleGraph SimpleGraphQ Simplify Sin Sinc SinghMaddalaDistribution SingleEvaluation SingleLetterItalics SingleLetterStyle SingularValueDecomposition SingularValueList SingularValuePlot SingularValues Sinh SinhIntegral SinIntegral SixJSymbol Skeleton SkeletonTransform SkellamDistribution Skewness SkewNormalDistribution Skip SliceDistribution Slider Slider2D Slider2DBox Slider2DBoxOptions SliderBox SliderBoxOptions SlideView Slot SlotSequence Small SmallCircle Smaller SmithDelayCompensator SmithWatermanSimilarity ' +
      'SmoothDensityHistogram SmoothHistogram SmoothHistogram3D SmoothKernelDistribution SocialMediaData Socket SokalSneathDissimilarity Solve SolveAlways SolveDelayed Sort SortBy Sound SoundAndGraphics SoundNote SoundVolume Sow Space SpaceForm Spacer Spacings Span SpanAdjustments SpanCharacterRounding SpanFromAbove SpanFromBoth SpanFromLeft SpanLineThickness SpanMaxSize SpanMinSize SpanningCharacters SpanSymmetric SparseArray SpatialGraphDistribution Speak SpeakTextPacket SpearmanRankTest SpearmanRho Spectrogram SpectrogramArray Specularity SpellingCorrection SpellingDictionaries SpellingDictionariesPath SpellingOptions SpellingSuggestionsPacket Sphere SphereBox SphericalBesselJ SphericalBesselY SphericalHankelH1 SphericalHankelH2 SphericalHarmonicY SphericalPlot3D SphericalRegion SpheroidalEigenvalue SpheroidalJoiningFactor SpheroidalPS SpheroidalPSPrime SpheroidalQS SpheroidalQSPrime SpheroidalRadialFactor SpheroidalS1 SpheroidalS1Prime SpheroidalS2 SpheroidalS2Prime Splice SplicedDistribution SplineClosed SplineDegree SplineKnots SplineWeights Split SplitBy SpokenString Sqrt SqrtBox SqrtBoxOptions Square SquaredEuclideanDistance SquareFreeQ SquareIntersection SquaresR SquareSubset SquareSubsetEqual SquareSuperset SquareSupersetEqual SquareUnion SquareWave StabilityMargins StabilityMarginsStyle StableDistribution Stack StackBegin StackComplete StackInhibit StandardDeviation StandardDeviationFilter StandardForm Standardize StandbyDistribution Star StarGraph StartAsynchronousTask StartingStepSize StartOfLine StartOfString StartScheduledTask StartupSound StateDimensions StateFeedbackGains StateOutputEstimator StateResponse StateSpaceModel StateSpaceRealization StateSpaceTransform StationaryDistribution StationaryWaveletPacketTransform StationaryWaveletTransform StatusArea StatusCentrality StepMonitor StieltjesGamma StirlingS1 StirlingS2 StopAsynchronousTask StopScheduledTask StrataVariables StratonovichProcess StreamColorFunction StreamColorFunctionScaling StreamDensityPlot StreamPlot StreamPoints StreamPosition Streams StreamScale StreamStyle String StringBreak StringByteCount StringCases StringCount StringDrop StringExpression StringForm StringFormat StringFreeQ StringInsert StringJoin StringLength StringMatchQ StringPosition StringQ StringReplace StringReplaceList StringReplacePart StringReverse StringRotateLeft StringRotateRight StringSkeleton StringSplit StringTake StringToStream StringTrim StripBoxes StripOnInput StripWrapperBoxes StrokeForm StructuralImportance StructuredArray StructuredSelection StruveH StruveL Stub StudentTDistribution Style StyleBox StyleBoxAutoDelete StyleBoxOptions StyleData StyleDefinitions StyleForm StyleKeyMapping StyleMenuListing StyleNameDialogSettings StyleNames StylePrint StyleSheetPath Subfactorial Subgraph SubMinus SubPlus SubresultantPolynomialRemainders ' +
      'SubresultantPolynomials Subresultants Subscript SubscriptBox SubscriptBoxOptions Subscripted Subset SubsetEqual Subsets SubStar Subsuperscript SubsuperscriptBox SubsuperscriptBoxOptions Subtract SubtractFrom SubValues Succeeds SucceedsEqual SucceedsSlantEqual SucceedsTilde SuchThat Sum SumConvergence Sunday SuperDagger SuperMinus SuperPlus Superscript SuperscriptBox SuperscriptBoxOptions Superset SupersetEqual SuperStar Surd SurdForm SurfaceColor SurfaceGraphics SurvivalDistribution SurvivalFunction SurvivalModel SurvivalModelFit SuspendPacket SuzukiDistribution SuzukiGroupSuz SwatchLegend Switch Symbol SymbolName SymletWavelet Symmetric SymmetricGroup SymmetricMatrixQ SymmetricPolynomial SymmetricReduction Symmetrize SymmetrizedArray SymmetrizedArrayRules SymmetrizedDependentComponents SymmetrizedIndependentComponents SymmetrizedReplacePart SynchronousInitialization SynchronousUpdating Syntax SyntaxForm SyntaxInformation SyntaxLength SyntaxPacket SyntaxQ SystemDialogInput SystemException SystemHelpPath SystemInformation SystemInformationData SystemOpen SystemOptions SystemsModelDelay SystemsModelDelayApproximate SystemsModelDelete SystemsModelDimensions SystemsModelExtract SystemsModelFeedbackConnect SystemsModelLabels SystemsModelOrder SystemsModelParallelConnect SystemsModelSeriesConnect SystemsModelStateFeedbackConnect SystemStub ' +
      'Tab TabFilling Table TableAlignments TableDepth TableDirections TableForm TableHeadings TableSpacing TableView TableViewBox TabSpacings TabView TabViewBox TabViewBoxOptions TagBox TagBoxNote TagBoxOptions TaggingRules TagSet TagSetDelayed TagStyle TagUnset Take TakeWhile Tally Tan Tanh TargetFunctions TargetUnits TautologyQ TelegraphProcess TemplateBox TemplateBoxOptions TemplateSlotSequence TemporalData Temporary TemporaryVariable TensorContract TensorDimensions TensorExpand TensorProduct TensorQ TensorRank TensorReduce TensorSymmetry TensorTranspose TensorWedge Tetrahedron TetrahedronBox TetrahedronBoxOptions TeXForm TeXSave Text Text3DBox Text3DBoxOptions TextAlignment TextBand TextBoundingBox TextBox TextCell TextClipboardType TextData TextForm TextJustification TextLine TextPacket TextParagraph TextRecognize TextRendering TextStyle Texture TextureCoordinateFunction TextureCoordinateScaling Therefore ThermometerGauge Thick Thickness Thin Thinning ThisLink ThompsonGroupTh Thread ThreeJSymbol Threshold Through Throw Thumbnail Thursday Ticks TicksStyle Tilde TildeEqual TildeFullEqual TildeTilde TimeConstrained TimeConstraint Times TimesBy TimeSeriesForecast TimeSeriesInvertibility TimeUsed TimeValue TimeZone Timing Tiny TitleGrouping TitsGroupT ToBoxes ToCharacterCode ToColor ToContinuousTimeModel ToDate ToDiscreteTimeModel ToeplitzMatrix ToExpression ToFileName Together Toggle ToggleFalse Toggler TogglerBar TogglerBox TogglerBoxOptions ToHeldExpression ToInvertibleTimeSeries TokenWords Tolerance ToLowerCase ToNumberField TooBig Tooltip TooltipBox TooltipBoxOptions TooltipDelay TooltipStyle Top TopHatTransform TopologicalSort ToRadicals ToRules ToString Total TotalHeight TotalVariationFilter TotalWidth TouchscreenAutoZoom TouchscreenControlPlacement ToUpperCase Tr Trace TraceAbove TraceAction TraceBackward TraceDepth TraceDialog TraceForward TraceInternal TraceLevel TraceOff TraceOn TraceOriginal TracePrint TraceScan TrackedSymbols TradingChart TraditionalForm TraditionalFunctionNotation TraditionalNotation TraditionalOrder TransferFunctionCancel TransferFunctionExpand TransferFunctionFactor TransferFunctionModel TransferFunctionPoles TransferFunctionTransform TransferFunctionZeros TransformationFunction TransformationFunctions TransformationMatrix TransformedDistribution TransformedField Translate TranslationTransform TransparentColor Transpose TreeForm TreeGraph TreeGraphQ TreePlot TrendStyle TriangleWave TriangularDistribution Trig TrigExpand TrigFactor TrigFactorList Trigger TrigReduce TrigToExp TrimmedMean True TrueQ TruncatedDistribution TsallisQExponentialDistribution TsallisQGaussianDistribution TTest Tube TubeBezierCurveBox TubeBezierCurveBoxOptions TubeBox TubeBSplineCurveBox TubeBSplineCurveBoxOptions Tuesday TukeyLambdaDistribution TukeyWindow Tuples TuranGraph TuringMachine ' +
      'Transparent ' +
      'UnateQ Uncompress Undefined UnderBar Underflow Underlined Underoverscript UnderoverscriptBox UnderoverscriptBoxOptions Underscript UnderscriptBox UnderscriptBoxOptions UndirectedEdge UndirectedGraph UndirectedGraphQ UndocumentedTestFEParserPacket UndocumentedTestGetSelectionPacket Unequal Unevaluated UniformDistribution UniformGraphDistribution UniformSumDistribution Uninstall Union UnionPlus Unique UnitBox UnitConvert UnitDimensions Unitize UnitRootTest UnitSimplify UnitStep UnitTriangle UnitVector Unprotect UnsameQ UnsavedVariables Unset UnsetShared UntrackedVariables Up UpArrow UpArrowBar UpArrowDownArrow Update UpdateDynamicObjects UpdateDynamicObjectsSynchronous UpdateInterval UpDownArrow UpEquilibrium UpperCaseQ UpperLeftArrow UpperRightArrow UpperTriangularize Upsample UpSet UpSetDelayed UpTee UpTeeArrow UpValues URL URLFetch URLFetchAsynchronous URLSave URLSaveAsynchronous UseGraphicsRange Using UsingFrontEnd ' +
      'V2Get ValidationLength Value ValueBox ValueBoxOptions ValueForm ValueQ ValuesData Variables Variance VarianceEquivalenceTest VarianceEstimatorFunction VarianceGammaDistribution VarianceTest VectorAngle VectorColorFunction VectorColorFunctionScaling VectorDensityPlot VectorGlyphData VectorPlot VectorPlot3D VectorPoints VectorQ Vectors VectorScale VectorStyle Vee Verbatim Verbose VerboseConvertToPostScriptPacket VerifyConvergence VerifySolutions VerifyTestAssumptions Version VersionNumber VertexAdd VertexCapacity VertexColors VertexComponent VertexConnectivity VertexCoordinateRules VertexCoordinates VertexCorrelationSimilarity VertexCosineSimilarity VertexCount VertexCoverQ VertexDataCoordinates VertexDegree VertexDelete VertexDiceSimilarity VertexEccentricity VertexInComponent VertexInDegree VertexIndex VertexJaccardSimilarity VertexLabeling VertexLabels VertexLabelStyle VertexList VertexNormals VertexOutComponent VertexOutDegree VertexQ VertexRenderingFunction VertexReplace VertexShape VertexShapeFunction VertexSize VertexStyle VertexTextureCoordinates VertexWeight Vertical VerticalBar VerticalForm VerticalGauge VerticalSeparator VerticalSlider VerticalTilde ViewAngle ViewCenter ViewMatrix ViewPoint ViewPointSelectorSettings ViewPort ViewRange ViewVector ViewVertical VirtualGroupData Visible VisibleCell VoigtDistribution VonMisesDistribution ' +
      'WaitAll WaitAsynchronousTask WaitNext WaitUntil WakebyDistribution WalleniusHypergeometricDistribution WaringYuleDistribution WatershedComponents WatsonUSquareTest WattsStrogatzGraphDistribution WaveletBestBasis WaveletFilterCoefficients WaveletImagePlot WaveletListPlot WaveletMapIndexed WaveletMatrixPlot WaveletPhi WaveletPsi WaveletScale WaveletScalogram WaveletThreshold WeaklyConnectedComponents WeaklyConnectedGraphQ WeakStationarity WeatherData WeberE Wedge Wednesday WeibullDistribution WeierstrassHalfPeriods WeierstrassInvariants WeierstrassP WeierstrassPPrime WeierstrassSigma WeierstrassZeta WeightedAdjacencyGraph WeightedAdjacencyMatrix WeightedData WeightedGraphQ Weights WelchWindow WheelGraph WhenEvent Which While White Whitespace WhitespaceCharacter WhittakerM WhittakerW WienerFilter WienerProcess WignerD WignerSemicircleDistribution WilksW WilksWTest WindowClickSelect WindowElements WindowFloating WindowFrame WindowFrameElements WindowMargins WindowMovable WindowOpacity WindowSelected WindowSize WindowStatusArea WindowTitle WindowToolbars WindowWidth With WolframAlpha WolframAlphaDate WolframAlphaQuantity WolframAlphaResult Word WordBoundary WordCharacter WordData WordSearch WordSeparators WorkingPrecision Write WriteString Wronskian ' +
      'XMLElement XMLObject Xnor Xor ' +
      'Yellow YuleDissimilarity ' +
      'ZernikeR ZeroSymmetric ZeroTest ZeroWidthTimes Zeta ZetaZero ZipfDistribution ZTest ZTransform ' +
      '$Aborted $ActivationGroupID $ActivationKey $ActivationUserRegistered $AddOnsDirectory $AssertFunction $Assumptions $AsynchronousTask $BaseDirectory $BatchInput $BatchOutput $BoxForms $ByteOrdering $Canceled $CharacterEncoding $CharacterEncodings $CommandLine $CompilationTarget $ConditionHold $ConfiguredKernels $Context $ContextPath $ControlActiveSetting $CreationDate $CurrentLink $DateStringFormat $DefaultFont $DefaultFrontEnd $DefaultImagingDevice $DefaultPath $Display $DisplayFunction $DistributedContexts $DynamicEvaluation $Echo $Epilog $ExportFormats $Failed $FinancialDataSource $FormatType $FrontEnd $FrontEndSession $GeoLocation $HistoryLength $HomeDirectory $HTTPCookies $IgnoreEOF $ImagingDevices $ImportFormats $InitialDirectory $Input $InputFileName $InputStreamMethods $Inspector $InstallationDate $InstallationDirectory $InterfaceEnvironment $IterationLimit $KernelCount $KernelID $Language $LaunchDirectory $LibraryPath $LicenseExpirationDate $LicenseID $LicenseProcesses $LicenseServer $LicenseSubprocesses $LicenseType $Line $Linked $LinkSupported $LoadedFiles $MachineAddresses $MachineDomain $MachineDomains $MachineEpsilon $MachineID $MachineName $MachinePrecision $MachineType $MaxExtraPrecision $MaxLicenseProcesses $MaxLicenseSubprocesses $MaxMachineNumber $MaxNumber $MaxPiecewiseCases $MaxPrecision $MaxRootDegree $MessageGroups $MessageList $MessagePrePrint $Messages $MinMachineNumber $MinNumber $MinorReleaseNumber $MinPrecision $ModuleNumber $NetworkLicense $NewMessage $NewSymbol $Notebooks $NumberMarks $Off $OperatingSystem $Output $OutputForms $OutputSizeLimit $OutputStreamMethods $Packages $ParentLink $ParentProcessID $PasswordFile $PatchLevelID $Path $PathnameSeparator $PerformanceGoal $PipeSupported $Post $Pre $PreferencesDirectory $PrePrint $PreRead $PrintForms $PrintLiteral $ProcessID $ProcessorCount $ProcessorType $ProductInformation $ProgramName $RandomState $RecursionLimit $ReleaseNumber $RootDirectory $ScheduledTask $ScriptCommandLine $SessionID $SetParentLink $SharedFunctions $SharedVariables $SoundDisplay $SoundDisplayFunction $SuppressInputFormHeads $SynchronousEvaluation $SyntaxHandler $System $SystemCharacterEncoding $SystemID $SystemWordLength $TemporaryDirectory $TemporaryPrefix $TextStyle $TimedOut $TimeUnit $TimeZone $TopDirectory $TraceOff $TraceOn $TracePattern $TracePostAction $TracePreAction $Urgent $UserAddOnsDirectory $UserBaseDirectory $UserDocumentsDirectory $UserName $Version $VersionNumber',
    contains: [
      {
        className: "comment",
        begin: /\(\*/, end: /\*\)/
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'list',
        begin: /\{/, end: /\}/,
        illegal: /:/
      }
    ]
  };
});

hljs.registerLanguage('matlab', function(hljs) {
  var COMMON_CONTAINS = [
    hljs.C_NUMBER_MODE,
    {
      className: 'string',
      begin: '\'', end: '\'',
      contains: [hljs.BACKSLASH_ESCAPE, {begin: '\'\''}]
    }
  ];
  var TRANSPOSE = {
    relevance: 0,
    contains: [
      {
        className: 'operator', begin: /'['\.]*/
      }
    ]
  };

  return {
    keywords: {
      keyword:
        'break case catch classdef continue else elseif end enumerated events for function ' +
        'global if methods otherwise parfor persistent properties return spmd switch try while',
      built_in:
        'sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan ' +
        'atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot ' +
        'cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog ' +
        'realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal ' +
        'cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli ' +
        'besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma ' +
        'gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms ' +
        'nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones ' +
        'eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ' +
        'ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril ' +
        'triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute ' +
        'shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan ' +
        'isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal ' +
        'rosser toeplitz vander wilkinson'
    },
    illegal: '(//|"|#|/\\*|\\s+/\\w+)',
    contains: [
      {
        className: 'function',
        beginKeywords: 'function', end: '$',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE,
          {
              className: 'params',
              begin: '\\(', end: '\\)'
          },
          {
              className: 'params',
              begin: '\\[', end: '\\]'
          }
        ]
      },
      {
        begin: /[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,
        returnBegin: true,
        relevance: 0,
        contains: [
          {begin: /[a-zA-Z_][a-zA-Z_0-9]*/, relevance: 0},
          TRANSPOSE.contains[0]
        ]
      },
      {
        className: 'matrix',
        begin: '\\[', end: '\\]',
        contains: COMMON_CONTAINS,
        relevance: 0,
        starts: TRANSPOSE
      },
      {
        className: 'cell',
        begin: '\\{', end: /}/,
        contains: COMMON_CONTAINS,
        relevance: 0,
        starts: TRANSPOSE
      },
      {
        // transpose operators at the end of a function call
        begin: /\)/,
        relevance: 0,
        starts: TRANSPOSE
      },
      hljs.COMMENT('^\\s*\\%\\{\\s*$', '^\\s*\\%\\}\\s*$'),
      hljs.COMMENT('\\%', '$')
    ].concat(COMMON_CONTAINS)
  };
});

hljs.registerLanguage('mel', function(hljs) {
  return {
    keywords:
      'int float string vector matrix if else switch case default while do for in break ' +
      'continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic ' +
      'addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey ' +
      'affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve ' +
      'alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor ' +
      'animDisplay animView annotate appendStringArray applicationName applyAttrPreset ' +
      'applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx ' +
      'artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu ' +
      'artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand ' +
      'assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface ' +
      'attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu ' +
      'attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp ' +
      'attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery ' +
      'autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults ' +
      'bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership ' +
      'bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType ' +
      'boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu ' +
      'buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge ' +
      'cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch ' +
      'catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox ' +
      'character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp ' +
      'checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip ' +
      'clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore ' +
      'closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter ' +
      'cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color ' +
      'colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp ' +
      'colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem ' +
      'componentEditor compositingInterop computePolysetVolume condition cone confirmDialog ' +
      'connectAttr connectControl connectDynamic connectJoint connectionInfo constrain ' +
      'constrainValue constructionHistory container containsMultibyte contextInfo control ' +
      'convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation ' +
      'convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache ' +
      'cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel ' +
      'cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver ' +
      'cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor ' +
      'createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer ' +
      'createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse ' +
      'currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx ' +
      'curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface ' +
      'curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox ' +
      'defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete ' +
      'deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes ' +
      'delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo ' +
      'dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable ' +
      'disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected ' +
      'displayColor displayCull displayLevelOfDetail displayPref displayRGBColor ' +
      'displaySmoothness displayStats displayString displaySurface distanceDimContext ' +
      'distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct ' +
      'doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator ' +
      'duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression ' +
      'dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor ' +
      'dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers ' +
      'editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor ' +
      'editorTemplate effector emit emitter enableDevice encodeString endString endsWith env ' +
      'equivalent equivalentTol erf error eval evalDeferred evalEcho event ' +
      'exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp ' +
      'expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof ' +
      'fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo ' +
      'filetest filletCurve filter filterCurve filterExpand filterStudioImport ' +
      'findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster ' +
      'finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar ' +
      'floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo ' +
      'fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint ' +
      'frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss ' +
      'geometryConstraint getApplicationVersionAsFloat getAttr getClassification ' +
      'getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes ' +
      'getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender ' +
      'glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl ' +
      'gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid ' +
      'gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap ' +
      'HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor ' +
      'HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached ' +
      'HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel ' +
      'headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey ' +
      'hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender ' +
      'hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox ' +
      'iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ' +
      'ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ' +
      'ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform ' +
      'insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance ' +
      'instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp ' +
      'interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf ' +
      'isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect ' +
      'itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx ' +
      'jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner ' +
      'keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx ' +
      'keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx ' +
      'keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx ' +
      'keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor ' +
      'layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList ' +
      'lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep ' +
      'listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory ' +
      'listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation ' +
      'listNodeTypes listPanelCategories listRelatives listSets listTransforms ' +
      'listUnselected listerEditor loadFluid loadNewShelf loadPlugin ' +
      'loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log ' +
      'longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive ' +
      'makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext ' +
      'manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx ' +
      'manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout ' +
      'menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp ' +
      'mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move ' +
      'moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute ' +
      'nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast ' +
      'nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint ' +
      'normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect ' +
      'nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref ' +
      'nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType ' +
      'objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface ' +
      'offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit ' +
      'orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier ' +
      'paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration ' +
      'panelHistory paramDimContext paramDimension paramLocator parent parentConstraint ' +
      'particle particleExists particleInstancer particleRenderInfo partition pasteKey ' +
      'pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture ' +
      'pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo ' +
      'pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult ' +
      'pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend ' +
      'polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal ' +
      'polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge ' +
      'polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge ' +
      'polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet ' +
      'polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet ' +
      'polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection ' +
      'polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge ' +
      'polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet ' +
      'polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix ' +
      'polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut ' +
      'polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet ' +
      'polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge ' +
      'polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex ' +
      'polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection ' +
      'polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection ' +
      'polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint ' +
      'polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate ' +
      'polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge ' +
      'polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing ' +
      'polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet ' +
      'polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace ' +
      'popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer ' +
      'projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx ' +
      'propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd ' +
      'python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection ' +
      'radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl ' +
      'readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference ' +
      'referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE ' +
      'registerPluginResource rehash reloadImage removeJoint removeMultiInstance ' +
      'removePanelCategory rename renameAttr renameSelectionList renameUI render ' +
      'renderGlobalsNode renderInfo renderLayerButton renderLayerParent ' +
      'renderLayerPostProcess renderLayerUnparent renderManip renderPartition ' +
      'renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor ' +
      'renderWindowSelectContext renderer reorder reorderDeformers requires reroot ' +
      'resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget ' +
      'reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx ' +
      'rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout ' +
      'runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage ' +
      'saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale ' +
      'scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor ' +
      'sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable ' +
      'scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt ' +
      'searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey ' +
      'selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType ' +
      'selectedNodes selectionConnection separator setAttr setAttrEnumResource ' +
      'setAttrMapping setAttrNiceNameResource setConstraintRestPosition ' +
      'setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr ' +
      'setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe ' +
      'setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag ' +
      'setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject ' +
      'setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets ' +
      'shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare ' +
      'shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField ' +
      'shortNameOf showHelp showHidden showManipCtx showSelectionInTitle ' +
      'showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface ' +
      'size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep ' +
      'snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound ' +
      'soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort ' +
      'spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString ' +
      'startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp ' +
      'stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex ' +
      'stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex ' +
      'stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString ' +
      'stringToStringArray strip stripPrefixFromName stroke subdAutoProjection ' +
      'subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV ' +
      'subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror ' +
      'subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease ' +
      'subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring ' +
      'surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton ' +
      'symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext ' +
      'texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext ' +
      'texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text ' +
      'textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList ' +
      'textToShelf textureDisplacePlane textureHairColor texturePlacementContext ' +
      'textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath ' +
      'toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower ' +
      'toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper ' +
      'trace track trackCtx transferAttributes transformCompare transformLimits translator ' +
      'trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence ' +
      'twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit ' +
      'unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink ' +
      'uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane ' +
      'viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex ' +
      'waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire ' +
      'wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform',
    illegal: '</',
    contains: [
      hljs.C_NUMBER_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        begin: '`', end: '`',
        contains: [hljs.BACKSLASH_ESCAPE]
      },
      {
        className: 'variable',
        variants: [
          {begin: '\\$\\d'},
          {begin: '[\\$\\%\\@](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)'},
          {begin: '\\*(\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)', relevance: 0}
        ]
      },
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE
    ]
  };
});

hljs.registerLanguage('mercury', function(hljs) {
  var KEYWORDS = {
    keyword:
      'module use_module import_module include_module end_module initialise ' +
      'mutable initialize finalize finalise interface implementation pred ' +
      'mode func type inst solver any_pred any_func is semidet det nondet ' +
      'multi erroneous failure cc_nondet cc_multi typeclass instance where ' +
      'pragma promise external trace atomic or_else require_complete_switch ' +
      'require_det require_semidet require_multi require_nondet ' +
      'require_cc_multi require_cc_nondet require_erroneous require_failure',
    pragma:
      'inline no_inline type_spec source_file fact_table obsolete memo ' +
      'loop_check minimal_model terminates does_not_terminate ' +
      'check_termination promise_equivalent_clauses',
    preprocessor:
      'foreign_proc foreign_decl foreign_code foreign_type ' +
      'foreign_import_module foreign_export_enum foreign_export ' +
      'foreign_enum may_call_mercury will_not_call_mercury thread_safe ' +
      'not_thread_safe maybe_thread_safe promise_pure promise_semipure ' +
      'tabled_for_io local untrailed trailed attach_to_io_state ' +
      'can_pass_as_mercury_type stable will_not_throw_exception ' +
      'may_modify_trail will_not_modify_trail may_duplicate ' +
      'may_not_duplicate affects_liveness does_not_affect_liveness ' +
      'doesnt_affect_liveness no_sharing unknown_sharing sharing',
    built_in:
      'some all not if then else true fail false try catch catch_any ' +
      'semidet_true semidet_false semidet_fail impure_true impure semipure'
  };

  var TODO = {
    className: 'label',
    begin: 'XXX', end: '$', endsWithParent: true,
    relevance: 0
  };
  var COMMENT = hljs.inherit(hljs.C_LINE_COMMENT_MODE, {begin: '%'});
  var CCOMMENT = hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, {relevance: 0});
  COMMENT.contains.push(TODO);
  CCOMMENT.contains.push(TODO);

  var NUMCODE = {
    className: 'number',
    begin: "0'.\\|0[box][0-9a-fA-F]*"
  };

  var ATOM = hljs.inherit(hljs.APOS_STRING_MODE, {relevance: 0});
  var STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, {relevance: 0});
  var STRING_FMT = {
    className: 'constant',
    begin: '\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]',
    relevance: 0
  };
  STRING.contains.push(STRING_FMT);

  var IMPLICATION = {
    className: 'built_in',
    variants: [
      {begin: '<=>'},
      {begin: '<=', relevance: 0},
      {begin: '=>', relevance: 0},
      {begin: '/\\\\'},
      {begin: '\\\\/'}
    ]
  };

  var HEAD_BODY_CONJUNCTION = {
    className: 'built_in',
    variants: [
      {begin: ':-\\|-->'},
      {begin: '=', relevance: 0}
    ]
  };

  return {
    aliases: ['m', 'moo'],
    keywords: KEYWORDS,
    contains: [
      IMPLICATION,
      HEAD_BODY_CONJUNCTION,
      COMMENT,
      CCOMMENT,
      NUMCODE,
      hljs.NUMBER_MODE,
      ATOM,
      STRING,
      {begin: /:-/} // relevance booster
    ]
  };
});

hljs.registerLanguage('mizar', function(hljs) {
  return {
    keywords:
      'environ vocabularies notations constructors definitions ' +
      'registrations theorems schemes requirements begin end definition ' +
      'registration cluster existence pred func defpred deffunc theorem ' +
      'proof let take assume then thus hence ex for st holds consider ' +
      'reconsider such that and in provided of as from be being by means ' +
      'equals implies iff redefine define now not or attr is mode ' +
      'suppose per cases set thesis contradiction scheme reserve struct ' +
      'correctness compatibility coherence symmetry assymetry ' +
      'reflexivity irreflexivity connectedness uniqueness commutativity ' +
      'idempotence involutiveness projectivity',
    contains: [
      hljs.COMMENT('::', '$')
    ]
  };
});

hljs.registerLanguage('perl', function(hljs) {
  var PERL_KEYWORDS = 'getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ' +
    'ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime ' +
    'readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qq' +
    'fileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent ' +
    'shutdown dump chomp connect getsockname die socketpair close flock exists index shmget' +
    'sub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr ' +
    'unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 ' +
    'getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline ' +
    'endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand ' +
    'mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink ' +
    'getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr ' +
    'untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link ' +
    'getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller ' +
    'lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and ' +
    'sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 ' +
    'chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach ' +
    'tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedir' +
    'ioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe ' +
    'atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when';
  var SUBST = {
    className: 'subst',
    begin: '[$@]\\{', end: '\\}',
    keywords: PERL_KEYWORDS
  };
  var METHOD = {
    begin: '->{', end: '}'
    // contains defined later
  };
  var VAR = {
    className: 'variable',
    variants: [
      {begin: /\$\d/},
      {begin: /[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},
      {begin: /[\$%@][^\s\w{]/, relevance: 0}
    ]
  };
  var STRING_CONTAINS = [hljs.BACKSLASH_ESCAPE, SUBST, VAR];
  var PERL_DEFAULT_CONTAINS = [
    VAR,
    hljs.HASH_COMMENT_MODE,
    hljs.COMMENT(
      '^\\=\\w',
      '\\=cut',
      {
        endsWithParent: true
      }
    ),
    METHOD,
    {
      className: 'string',
      contains: STRING_CONTAINS,
      variants: [
        {
          begin: 'q[qwxr]?\\s*\\(', end: '\\)',
          relevance: 5
        },
        {
          begin: 'q[qwxr]?\\s*\\[', end: '\\]',
          relevance: 5
        },
        {
          begin: 'q[qwxr]?\\s*\\{', end: '\\}',
          relevance: 5
        },
        {
          begin: 'q[qwxr]?\\s*\\|', end: '\\|',
          relevance: 5
        },
        {
          begin: 'q[qwxr]?\\s*\\<', end: '\\>',
          relevance: 5
        },
        {
          begin: 'qw\\s+q', end: 'q',
          relevance: 5
        },
        {
          begin: '\'', end: '\'',
          contains: [hljs.BACKSLASH_ESCAPE]
        },
        {
          begin: '"', end: '"'
        },
        {
          begin: '`', end: '`',
          contains: [hljs.BACKSLASH_ESCAPE]
        },
        {
          begin: '{\\w+}',
          contains: [],
          relevance: 0
        },
        {
          begin: '\-?\\w+\\s*\\=\\>',
          contains: [],
          relevance: 0
        }
      ]
    },
    {
      className: 'number',
      begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
      relevance: 0
    },
    { // regexp container
      begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',
      keywords: 'split return print reverse grep',
      relevance: 0,
      contains: [
        hljs.HASH_COMMENT_MODE,
        {
          className: 'regexp',
          begin: '(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*',
          relevance: 10
        },
        {
          className: 'regexp',
          begin: '(m|qr)?/', end: '/[a-z]*',
          contains: [hljs.BACKSLASH_ESCAPE],
          relevance: 0 // allows empty "//" which is a common comment delimiter in other languages
        }
      ]
    },
    {
      className: 'sub',
      beginKeywords: 'sub', end: '(\\s*\\(.*?\\))?[;{]',
      relevance: 5
    },
    {
      className: 'operator',
      begin: '-\\w\\b',
      relevance: 0
    },
    {
      begin: "^__DATA__$",
      end: "^__END__$",
      subLanguage: 'mojolicious',
      contains: [
        {
            begin: "^@@.*",
            end: "$",
            className: "comment"
        }
      ]
    }
  ];
  SUBST.contains = PERL_DEFAULT_CONTAINS;
  METHOD.contains = PERL_DEFAULT_CONTAINS;

  return {
    aliases: ['pl'],
    keywords: PERL_KEYWORDS,
    contains: PERL_DEFAULT_CONTAINS
  };
});

hljs.registerLanguage('mojolicious', function(hljs) {
  return {
    subLanguage: 'xml',
    contains: [
      {
        className: 'preprocessor',
        begin: '^__(END|DATA)__$'
      },
    // mojolicious line
      {
        begin: "^\\s*%{1,2}={0,2}", end: '$',
        subLanguage: 'perl'
      },
    // mojolicious block
      {
        begin: "<%{1,2}={0,2}",
        end: "={0,1}%>",
        subLanguage: 'perl',
        excludeBegin: true,
        excludeEnd: true
      }
    ]
  };
});

hljs.registerLanguage('monkey', function(hljs) {
  var NUMBER = {
    className: 'number', relevance: 0,
    variants: [
      {
        begin: '[$][a-fA-F0-9]+'
      },
      hljs.NUMBER_MODE
    ]
  };

  return {
    case_insensitive: true,
    keywords: {
      keyword: 'public private property continue exit extern new try catch ' +
        'eachin not abstract final select case default const local global field ' +
        'end if then else elseif endif while wend repeat until forever for to step next return module inline throw',

      built_in: 'DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil ' +
        'Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI',

      literal: 'true false null and or shl shr mod'
    },
    illegal: /\/\*/,
    contains: [
      hljs.COMMENT('#rem', '#end'),
      hljs.COMMENT(
        "'",
        '$',
        {
          relevance: 0
        }
      ),
      {
        className: 'function',
        beginKeywords: 'function method', end: '[(=:]|$',
        illegal: /\n/,
        contains: [
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        className: 'class',
        beginKeywords: 'class interface', end: '$',
        contains: [
          {
            beginKeywords: 'extends implements'
          },
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        className: 'variable',
        begin: '\\b(self|super)\\b'
      },
      {
        className: 'preprocessor',
        beginKeywords: 'import',
        end: '$'
      },
      {
        className: 'preprocessor',
        begin: '\\s*#', end: '$',
        keywords: 'if else elseif endif end then'
      },
      {
        className: 'pi',
        begin: '^\\s*strict\\b'
      },
      {
        beginKeywords: 'alias', end: '=',
        contains: [hljs.UNDERSCORE_TITLE_MODE]
      },
      hljs.QUOTE_STRING_MODE,
      NUMBER
    ]
  }
});

hljs.registerLanguage('nginx', function(hljs) {
  var VAR = {
    className: 'variable',
    variants: [
      {begin: /\$\d+/},
      {begin: /\$\{/, end: /}/},
      {begin: '[\\$\\@]' + hljs.UNDERSCORE_IDENT_RE}
    ]
  };
  var DEFAULT = {
    endsWithParent: true,
    lexemes: '[a-z/_]+',
    keywords: {
      built_in:
        'on off yes no true false none blocked debug info notice warn error crit ' +
        'select break last permanent redirect kqueue rtsig epoll poll /dev/poll'
    },
    relevance: 0,
    illegal: '=>',
    contains: [
      hljs.HASH_COMMENT_MODE,
      {
        className: 'string',
        contains: [hljs.BACKSLASH_ESCAPE, VAR],
        variants: [
          {begin: /"/, end: /"/},
          {begin: /'/, end: /'/}
        ]
      },
      {
        className: 'url',
        begin: '([a-z]+):/', end: '\\s', endsWithParent: true, excludeEnd: true,
        contains: [VAR]
      },
      {
        className: 'regexp',
        contains: [hljs.BACKSLASH_ESCAPE, VAR],
        variants: [
          {begin: "\\s\\^", end: "\\s|{|;", returnEnd: true},
          // regexp locations (~, ~*)
          {begin: "~\\*?\\s+", end: "\\s|{|;", returnEnd: true},
          // *.example.com
          {begin: "\\*(\\.[a-z\\-]+)+"},
          // sub.example.*
          {begin: "([a-z\\-]+\\.)+\\*"}
        ]
      },
      // IP
      {
        className: 'number',
        begin: '\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b'
      },
      // units
      {
        className: 'number',
        begin: '\\b\\d+[kKmMgGdshdwy]*\\b',
        relevance: 0
      },
      VAR
    ]
  };

  return {
    aliases: ['nginxconf'],
    contains: [
      hljs.HASH_COMMENT_MODE,
      {
        begin: hljs.UNDERSCORE_IDENT_RE + '\\s', end: ';|{', returnBegin: true,
        contains: [
          {
            className: 'title',
            begin: hljs.UNDERSCORE_IDENT_RE,
            starts: DEFAULT
          }
        ],
        relevance: 0
      }
    ],
    illegal: '[^\\s\\}]'
  };
});

hljs.registerLanguage('nimrod', function(hljs) {
  return {
    aliases: ['nim'],
    keywords: {
      keyword: 'addr and as asm bind block break|0 case|0 cast const|0 continue|0 converter discard distinct|10 div do elif else|0 end|0 enum|0 except export finally for from generic if|0 import|0 in include|0 interface is isnot|10 iterator|10 let|0 macro method|10 mixin mod nil not notin|10 object|0 of or out proc|10 ptr raise ref|10 return shl shr static template try|0 tuple type|0 using|0 var|0 when while|0 with without xor yield',
      literal: 'shared guarded stdin stdout stderr result|10 true false'
    },
    contains: [ {
        className: 'decorator', // Actually pragma
        begin: /{\./,
        end: /\.}/,
        relevance: 10
      }, {
        className: 'string',
        begin: /[a-zA-Z]\w*"/,
        end: /"/,
        contains: [{begin: /""/}]
      }, {
        className: 'string',
        begin: /([a-zA-Z]\w*)?"""/,
        end: /"""/
      },
      hljs.QUOTE_STRING_MODE,
      {
        className: 'type',
        begin: /\b[A-Z]\w+\b/,
        relevance: 0
      }, {
        className: 'type',
        begin: /\b(int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|float|float32|float64|bool|char|string|cstring|pointer|expr|stmt|void|auto|any|range|array|openarray|varargs|seq|set|clong|culong|cchar|cschar|cshort|cint|csize|clonglong|cfloat|cdouble|clongdouble|cuchar|cushort|cuint|culonglong|cstringarray|semistatic)\b/
      }, {
        className: 'number',
        begin: /\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/,
        relevance: 0
      }, {
        className: 'number',
        begin: /\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/,
        relevance: 0
      }, {
        className: 'number',
        begin: /\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/,
        relevance: 0
      }, {
        className: 'number',
        begin: /\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/,
        relevance: 0
      },
      hljs.HASH_COMMENT_MODE
    ]
  }
});

hljs.registerLanguage('nix', function(hljs) {
  var NIX_KEYWORDS = {
    keyword: 'rec with let in inherit assert if else then',
    constant: 'true false or and null',
    built_in:
      'import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation'
  };
  var ANTIQUOTE = {
    className: 'subst',
    begin: /\$\{/,
    end: /}/,
    keywords: NIX_KEYWORDS
  };
  var ATTRS = {
    className: 'variable',
    // TODO: we have to figure out a way how to exclude \s*=
    begin: /[a-zA-Z0-9-_]+(\s*=)/,
    relevance: 0
  };
  var SINGLE_QUOTE = {
    className: 'string',
    begin: "''",
    end: "''",
    contains: [
      ANTIQUOTE
    ]
  };
  var DOUBLE_QUOTE = {
    className: 'string',
    begin: '"',
    end: '"',
    contains: [
      ANTIQUOTE
    ]
  };
  var EXPRESSIONS = [
    hljs.NUMBER_MODE,
    hljs.HASH_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
    SINGLE_QUOTE,
    DOUBLE_QUOTE,
    ATTRS
  ];
  ANTIQUOTE.contains = EXPRESSIONS;
  return {
    aliases: ["nixos"],
    keywords: NIX_KEYWORDS,
    contains: EXPRESSIONS
  };
});

hljs.registerLanguage('nsis', function(hljs) {
  var CONSTANTS = {
    className: 'symbol',
    begin: '\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)'
  };

  var DEFINES = {
    // ${defines}
    className: 'constant',
    begin: '\\$+{[a-zA-Z0-9_]+}'
  };

  var VARIABLES = {
    // $variables
    className: 'variable',
    begin: '\\$+[a-zA-Z0-9_]+',
    illegal: '\\(\\){}'
  };

  var LANGUAGES = {
    // $(language_strings)
    className: 'constant',
    begin: '\\$+\\([a-zA-Z0-9_]+\\)'
  };

  var PARAMETERS = {
    // command parameters
    className: 'params',
    begin: '(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)'
  };

  var COMPILER ={
    // !compiler_flags
    className: 'constant',
    begin: '\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)'
  };

  return {
    case_insensitive: false,
    keywords: {
      keyword:
      'Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption SubSectionEnd Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle',
      literal:
      'admin all auto both colored current false force hide highest lastused leave listonly none normal notset off on open print show silent silentlog smooth textonly true user '
    },
    contains: [
      hljs.HASH_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'string',
        begin: '"', end: '"',
        illegal: '\\n',
        contains: [
          { // $\n, $\r, $\t, $$
            className: 'symbol',
            begin: '\\$(\\\\(n|r|t)|\\$)'
          },
          CONSTANTS,
          DEFINES,
          VARIABLES,
          LANGUAGES
        ]
      },
      hljs.COMMENT(
        ';',
        '$',
        {
          relevance: 0
        }
      ),
      {
        className: 'function',
        beginKeywords: 'Function PageEx Section SectionGroup SubSection', end: '$'
      },
      COMPILER,
      DEFINES,
      VARIABLES,
      LANGUAGES,
      PARAMETERS,
      hljs.NUMBER_MODE,
      { // plug::ins
        className: 'literal',
        begin: hljs.IDENT_RE + '::' + hljs.IDENT_RE
      }
    ]
  };
});

hljs.registerLanguage('objectivec', function(hljs) {
  var API_CLASS = {
    className: 'built_in',
    begin: '(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\w+',
  };
  var OBJC_KEYWORDS = {
    keyword:
      'int float while char export sizeof typedef const struct for union ' +
      'unsigned long volatile static bool mutable if do return goto void ' +
      'enum else break extern asm case short default double register explicit ' +
      'signed typename this switch continue wchar_t inline readonly assign ' +
      'readwrite self @synchronized id typeof ' +
      'nonatomic super unichar IBOutlet IBAction strong weak copy ' +
      'in out inout bycopy byref oneway __strong __weak __block __autoreleasing ' +
      '@private @protected @public @try @property @end @throw @catch @finally ' +
      '@autoreleasepool @synthesize @dynamic @selector @optional @required',
    literal:
      'false true FALSE TRUE nil YES NO NULL',
    built_in:
      'BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once'
  };
  var LEXEMES = /[a-zA-Z@][a-zA-Z0-9_]*/;
  var CLASS_KEYWORDS = '@interface @class @protocol @implementation';
  return {
    aliases: ['mm', 'objc', 'obj-c'],
    keywords: OBJC_KEYWORDS,
    lexemes: LEXEMES,
    illegal: '</',
    contains: [
      API_CLASS,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.C_NUMBER_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        variants: [
          {
            begin: '@"', end: '"',
            illegal: '\\n',
            contains: [hljs.BACKSLASH_ESCAPE]
          },
          {
            begin: '\'', end: '[^\\\\]\'',
            illegal: '[^\\\\][^\']'
          }
        ]
      },
      {
        className: 'preprocessor',
        begin: '#',
        end: '$',
        contains: [
          {
            className: 'title',
            variants: [
              { begin: '\"', end: '\"' },
              { begin: '<', end: '>' }
            ]
          }
        ]
      },
      {
        className: 'class',
        begin: '(' + CLASS_KEYWORDS.split(' ').join('|') + ')\\b', end: '({|$)', excludeEnd: true,
        keywords: CLASS_KEYWORDS, lexemes: LEXEMES,
        contains: [
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        className: 'variable',
        begin: '\\.'+hljs.UNDERSCORE_IDENT_RE,
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('ocaml', function(hljs) {
  /* missing support for heredoc-like string (OCaml 4.0.2+) */
  return {
    aliases: ['ml'],
    keywords: {
      keyword:
        'and as assert asr begin class constraint do done downto else end ' +
        'exception external for fun function functor if in include ' +
        'inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method ' +
        'mod module mutable new object of open! open or private rec sig struct ' +
        'then to try type val! val virtual when while with ' +
        /* camlp4 */
        'parser value',
      built_in:
        /* built-in types */
        'array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit ' +
        /* (some) types in Pervasives */
        'in_channel out_channel ref',
      literal:
        'true false'
    },
    illegal: /\/\/|>>/,
    lexemes: '[a-z_]\\w*!?',
    contains: [
      {
        className: 'literal',
        begin: '\\[(\\|\\|)?\\]|\\(\\)',
        relevance: 0
      },
      hljs.COMMENT(
        '\\(\\*',
        '\\*\\)',
        {
          contains: ['self']
        }
      ),
      { /* type variable */
        className: 'symbol',
        begin: '\'[A-Za-z_](?!\')[\\w\']*'
        /* the grammar is ambiguous on how 'a'b should be interpreted but not the compiler */
      },
      { /* polymorphic variant */
        className: 'tag',
        begin: '`[A-Z][\\w\']*'
      },
      { /* module or constructor */
        className: 'type',
        begin: '\\b[A-Z][\\w\']*',
        relevance: 0
      },
      { /* don't color identifiers, but safely catch all identifiers with '*/
        begin: '[a-z_]\\w*\'[\\w\']*'
      },
      hljs.inherit(hljs.APOS_STRING_MODE, {className: 'char', relevance: 0}),
      hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
      {
        className: 'number',
        begin:
          '\\b(0[xX][a-fA-F0-9_]+[Lln]?|' +
          '0[oO][0-7_]+[Lln]?|' +
          '0[bB][01_]+[Lln]?|' +
          '[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)',
        relevance: 0
      },
      {
        begin: /[-=]>/ // relevance booster
      }
    ]
  }
});

hljs.registerLanguage('openscad', function(hljs) {
	var SPECIAL_VARS = {
		className: 'keyword',
		begin: '\\$(f[asn]|t|vp[rtd]|children)'
	},
	LITERALS = {
		className: 'literal',
		begin: 'false|true|PI|undef'
	},
	NUMBERS = {
		className: 'number',
		begin: '\\b\\d+(\\.\\d+)?(e-?\\d+)?', //adds 1e5, 1e-10
		relevance: 0
	},
	STRING = hljs.inherit(hljs.QUOTE_STRING_MODE,{illegal: null}),
	PREPRO = {
		className: 'preprocessor',
		keywords: 'include use',
		begin: 'include|use <',
		end: '>'
	},
	PARAMS = {
		className: 'params',
		begin: '\\(', end: '\\)',
		contains: ['self', NUMBERS, STRING, SPECIAL_VARS, LITERALS]
	},
	MODIFIERS = {
		className: 'built_in',
		begin: '[*!#%]',
		relevance: 0
	},
	FUNCTIONS = {
		className: 'function',
		beginKeywords: 'module function',
		end: '\\=|\\{',
		contains: [PARAMS, hljs.UNDERSCORE_TITLE_MODE]
	};

	return {
		aliases: ['scad'],
		keywords: {
			keyword: 'function module include use for intersection_for if else \\%',
			literal: 'false true PI undef',
			built_in: 'circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign'
		},
		contains: [
			hljs.C_LINE_COMMENT_MODE,
			hljs.C_BLOCK_COMMENT_MODE,
			NUMBERS,
			PREPRO,
			STRING,
			SPECIAL_VARS,
			MODIFIERS,
			FUNCTIONS
		]
	}
});

hljs.registerLanguage('oxygene', function(hljs) {
  var OXYGENE_KEYWORDS = 'abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue '+
    'create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false '+
    'final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited '+
    'inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of '+
    'old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly '+
    'record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple '+
    'type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal '+
    'register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained';
  var CURLY_COMMENT =  hljs.COMMENT(
    '{',
    '}',
    {
      relevance: 0
    }
  );
  var PAREN_COMMENT = hljs.COMMENT(
    '\\(\\*',
    '\\*\\)',
    {
      relevance: 10
    }
  );
  var STRING = {
    className: 'string',
    begin: '\'', end: '\'',
    contains: [{begin: '\'\''}]
  };
  var CHAR_STRING = {
    className: 'string', begin: '(#\\d+)+'
  };
  var FUNCTION = {
    className: 'function',
    beginKeywords: 'function constructor destructor procedure method', end: '[:;]',
    keywords: 'function constructor|10 destructor|10 procedure|10 method|10',
    contains: [
      hljs.TITLE_MODE,
      {
        className: 'params',
        begin: '\\(', end: '\\)',
        keywords: OXYGENE_KEYWORDS,
        contains: [STRING, CHAR_STRING]
      },
      CURLY_COMMENT, PAREN_COMMENT
    ]
  };
  return {
    case_insensitive: true,
    keywords: OXYGENE_KEYWORDS,
    illegal: '("|\\$[G-Zg-z]|\\/\\*|</|=>|->)',
    contains: [
      CURLY_COMMENT, PAREN_COMMENT, hljs.C_LINE_COMMENT_MODE,
      STRING, CHAR_STRING,
      hljs.NUMBER_MODE,
      FUNCTION,
      {
        className: 'class',
        begin: '=\\bclass\\b', end: 'end;',
        keywords: OXYGENE_KEYWORDS,
        contains: [
          STRING, CHAR_STRING,
          CURLY_COMMENT, PAREN_COMMENT, hljs.C_LINE_COMMENT_MODE,
          FUNCTION
        ]
      }
    ]
  };
});

hljs.registerLanguage('parser3', function(hljs) {
  var CURLY_SUBCOMMENT = hljs.COMMENT(
    '{',
    '}',
    {
      contains: ['self']
    }
  );
  return {
    subLanguage: 'xml', relevance: 0,
    contains: [
      hljs.COMMENT('^#', '$'),
      hljs.COMMENT(
        '\\^rem{',
        '}',
        {
          relevance: 10,
          contains: [
            CURLY_SUBCOMMENT
          ]
        }
      ),
      {
        className: 'preprocessor',
        begin: '^@(?:BASE|USE|CLASS|OPTIONS)$',
        relevance: 10
      },
      {
        className: 'title',
        begin: '@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$'
      },
      {
        className: 'variable',
        begin: '\\$\\{?[\\w\\-\\.\\:]+\\}?'
      },
      {
        className: 'keyword',
        begin: '\\^[\\w\\-\\.\\:]+'
      },
      {
        className: 'number',
        begin: '\\^#[0-9a-fA-F]+'
      },
      hljs.C_NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('pf', function(hljs) {
  var MACRO = {
    className: 'variable',
    begin: /\$[\w\d#@][\w\d_]*/
  };
  var TABLE = {
    className: 'variable',
    begin: /</, end: />/
  };
  var QUOTE_STRING = {
    className: 'string',
    begin: /"/, end: /"/
  };

  return {
    aliases: ['pf.conf'],
    lexemes: /[a-z0-9_<>-]+/,
    keywords: {
      built_in: /* block match pass are "actions" in pf.conf(5), the rest are
                 * lexically similar top-level commands.
                 */
        'block match pass load anchor|5 antispoof|10 set table',
      keyword:
        'in out log quick on rdomain inet inet6 proto from port os to route' +
        'allow-opts divert-packet divert-reply divert-to flags group icmp-type' +
        'icmp6-type label once probability recieved-on rtable prio queue' +
        'tos tag tagged user keep fragment for os drop' +
        'af-to|10 binat-to|10 nat-to|10 rdr-to|10 bitmask least-stats random round-robin' +
        'source-hash static-port' +
        'dup-to reply-to route-to' +
        'parent bandwidth default min max qlimit' +
        'block-policy debug fingerprints hostid limit loginterface optimization' +
        'reassemble ruleset-optimization basic none profile skip state-defaults' +
        'state-policy timeout' +
        'const counters persist' +
        'no modulate synproxy state|5 floating if-bound no-sync pflow|10 sloppy' +
        'source-track global rule max-src-nodes max-src-states max-src-conn' +
        'max-src-conn-rate overload flush' +
        'scrub|5 max-mss min-ttl no-df|10 random-id',
      literal:
        'all any no-route self urpf-failed egress|5 unknown'
    },
    contains: [
      hljs.HASH_COMMENT_MODE,
      hljs.NUMBER_MODE,
      hljs.QUOTE_STRING_MODE,
      MACRO,
      TABLE
    ]
  };
});

hljs.registerLanguage('php', function(hljs) {
  var VARIABLE = {
    className: 'variable', begin: '\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
  };
  var PREPROCESSOR = {
    className: 'preprocessor', begin: /<\?(php)?|\?>/
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, PREPROCESSOR],
    variants: [
      {
        begin: 'b"', end: '"'
      },
      {
        begin: 'b\'', end: '\''
      },
      hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
      hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null})
    ]
  };
  var NUMBER = {variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]};
  return {
    aliases: ['php3', 'php4', 'php5', 'php6'],
    case_insensitive: true,
    keywords:
      'and include_once list abstract global private echo interface as static endswitch ' +
      'array null if endwhile or const for endforeach self var while isset public ' +
      'protected exit foreach throw elseif include __FILE__ empty require_once do xor ' +
      'return parent clone use __CLASS__ __LINE__ else break print eval new ' +
      'catch __METHOD__ case exception default die require __FUNCTION__ ' +
      'enddeclare final try switch continue endfor endif declare unset true false ' +
      'trait goto instanceof insteadof __DIR__ __NAMESPACE__ ' +
      'yield finally',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.HASH_COMMENT_MODE,
      hljs.COMMENT(
        '/\\*',
        '\\*/',
        {
          contains: [
            {
              className: 'doctag',
              begin: '@[A-Za-z]+'
            },
            PREPROCESSOR
          ]
        }
      ),
      hljs.COMMENT(
        '__halt_compiler.+?;',
        false,
        {
          endsWithParent: true,
          keywords: '__halt_compiler',
          lexemes: hljs.UNDERSCORE_IDENT_RE
        }
      ),
      {
        className: 'string',
        begin: /<<<['"]?\w+['"]?$/, end: /^\w+;?$/,
        contains: [
          hljs.BACKSLASH_ESCAPE,
          {
            className: 'subst',
            variants: [
              {begin: /\$\w+/},
              {begin: /\{\$/, end: /\}/}
            ]
          }
        ]
      },
      PREPROCESSOR,
      VARIABLE,
      {
        // swallow composed identifiers to avoid parsing them as keywords
        begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/
      },
      {
        className: 'function',
        beginKeywords: 'function', end: /[;{]/, excludeEnd: true,
        illegal: '\\$|\\[|%',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE,
          {
            className: 'params',
            begin: '\\(', end: '\\)',
            contains: [
              'self',
              VARIABLE,
              hljs.C_BLOCK_COMMENT_MODE,
              STRING,
              NUMBER
            ]
          }
        ]
      },
      {
        className: 'class',
        beginKeywords: 'class interface', end: '{', excludeEnd: true,
        illegal: /[:\(\$"]/,
        contains: [
          {beginKeywords: 'extends implements'},
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        beginKeywords: 'namespace', end: ';',
        illegal: /[\.']/,
        contains: [hljs.UNDERSCORE_TITLE_MODE]
      },
      {
        beginKeywords: 'use', end: ';',
        contains: [hljs.UNDERSCORE_TITLE_MODE]
      },
      {
        begin: '=>' // No markup, just a relevance booster
      },
      STRING,
      NUMBER
    ]
  };
});

hljs.registerLanguage('powershell', function(hljs) {
  var backtickEscape = {
    begin: '`[\\s\\S]',
    relevance: 0
  };
  var VAR = {
    className: 'variable',
    variants: [
      {begin: /\$[\w\d][\w\d_:]*/}
    ]
  };
  var QUOTE_STRING = {
    className: 'string',
    begin: /"/, end: /"/,
    contains: [
      backtickEscape,
      VAR,
      {
        className: 'variable',
        begin: /\$[A-z]/, end: /[^A-z]/
      }
    ]
  };
  var APOS_STRING = {
    className: 'string',
    begin: /'/, end: /'/
  };

  return {
    aliases: ['ps'],
    lexemes: /-?[A-z\.\-]+/,
    case_insensitive: true,
    keywords: {
      keyword: 'if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch',
      literal: '$null $true $false',
      built_in: 'Add-Content Add-History Add-Member Add-PSSnapin Clear-Content Clear-Item Clear-Item Property Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ConvertTo-Html ConvertTo-SecureString Copy-Item Copy-ItemProperty Export-Alias Export-Clixml Export-Console Export-Csv ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item Join-Path Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug Set-Service Set-TraceSource Set-Variable Sort-Object Split-Path Start-Service Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where-Object Write-Debug Write-Error Write-Host Write-Output Write-Progress Write-Verbose Write-Warning',
      operator: '-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace'
    },
    contains: [
      hljs.HASH_COMMENT_MODE,
      hljs.NUMBER_MODE,
      QUOTE_STRING,
      APOS_STRING,
      VAR
    ]
  };
});

hljs.registerLanguage('processing', function(hljs) {
  return {
    keywords: {
      keyword: 'BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color ' +
        'double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject ' +
        'Object StringDict StringList Table TableRow XML ' +
        // Java keywords
        'false synchronized int abstract float private char boolean static null if const ' +
        'for true while long throw strictfp finally protected import native final return void ' +
        'enum else break transient new catch instanceof byte super volatile case assert short ' +
        'package default double public try this switch continue throws protected public private',
      constant: 'P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI',
      variable: 'displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key ' +
        'keyCode pixels focused frameCount frameRate height width',
      title: 'setup draw',
      built_in: 'size createGraphics beginDraw createShape loadShape PShape arc ellipse line point ' +
        'quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint ' +
        'curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex ' +
        'endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap ' +
        'strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased ' +
        'mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour ' +
        'millis minute month second year background clear colorMode fill noFill noStroke stroke alpha ' +
        'blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY ' +
        'screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ' +
        'ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle ' +
        'pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf ' +
        'nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset ' +
        'box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings ' +
        'loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput ' +
        'createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings ' +
        'saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale ' +
        'shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal ' +
        'pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap ' +
        'blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont ' +
        'loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil ' +
        'constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees ' +
        'radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed'
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('profile', function(hljs) {
  return {
    contains: [
      hljs.C_NUMBER_MODE,
      {
        className: 'built_in',
        begin: '{', end: '}$',
        excludeBegin: true, excludeEnd: true,
        contains: [hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE],
        relevance: 0
      },
      {
        className: 'filename',
        begin: '[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}', end: ':',
        excludeEnd: true
      },
      {
        className: 'header',
        begin: '(ncalls|tottime|cumtime)', end: '$',
        keywords: 'ncalls tottime|10 cumtime|10 filename',
        relevance: 10
      },
      {
        className: 'summary',
        begin: 'function calls', end: '$',
        contains: [hljs.C_NUMBER_MODE],
        relevance: 10
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'function',
        begin: '\\(', end: '\\)$',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE
        ],
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('prolog', function(hljs) {

  var ATOM = {

    className: 'atom',
    begin: /[a-z][A-Za-z0-9_]*/,
    relevance: 0
  };

  var VAR = {

    className: 'name',
    variants: [
      {begin: /[A-Z][a-zA-Z0-9_]*/},
      {begin: /_[A-Za-z0-9_]*/},
    ],
    relevance: 0
  };

  var PARENTED = {

    begin: /\(/,
    end: /\)/,
    relevance: 0
  };

  var LIST = {

    begin: /\[/,
    end: /\]/
  };

  var LINE_COMMENT = {

    className: 'comment',
    begin: /%/, end: /$/,
    contains: [hljs.PHRASAL_WORDS_MODE]
  };

  var BACKTICK_STRING = {

    className: 'string',
    begin: /`/, end: /`/,
    contains: [hljs.BACKSLASH_ESCAPE]
  };

  var CHAR_CODE = {

    className: 'string', // 0'a etc.
    begin: /0\'(\\\'|.)/
  };

  var SPACE_CODE = {

    className: 'string',
    begin: /0\'\\s/ // 0'\s
  };

  var PRED_OP = { // relevance booster
    begin: /:-/
  };

  var inner = [

    ATOM,
    VAR,
    PARENTED,
    PRED_OP,
    LIST,
    LINE_COMMENT,
    hljs.C_BLOCK_COMMENT_MODE,
    hljs.QUOTE_STRING_MODE,
    hljs.APOS_STRING_MODE,
    BACKTICK_STRING,
    CHAR_CODE,
    SPACE_CODE,
    hljs.C_NUMBER_MODE
  ];

  PARENTED.contains = inner;
  LIST.contains = inner;

  return {
    contains: inner.concat([
      {begin: /\.$/} // relevance booster
    ])
  };
});

hljs.registerLanguage('protobuf', function(hljs) {
  return {
    keywords: {
      keyword: 'package import option optional required repeated group',
      built_in: 'double float int32 int64 uint32 uint64 sint32 sint64 ' +
        'fixed32 fixed64 sfixed32 sfixed64 bool string bytes',
      literal: 'true false'
    },
    contains: [
      hljs.QUOTE_STRING_MODE,
      hljs.NUMBER_MODE,
      hljs.C_LINE_COMMENT_MODE,
      {
        className: 'class',
        beginKeywords: 'message enum service', end: /\{/,
        illegal: /\n/,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {
            starts: {endsWithParent: true, excludeEnd: true} // hack: eating everything after the first title
          })
        ]
      },
      {
        className: 'function',
        beginKeywords: 'rpc',
        end: /;/, excludeEnd: true,
        keywords: 'rpc returns'
      },
      {
        className: 'constant',
        begin: /^\s*[A-Z_]+/,
        end: /\s*=/, excludeEnd: true
      }
    ]
  };
});

hljs.registerLanguage('puppet', function(hljs) {

  var PUPPET_KEYWORDS = {
    keyword:
    /* language keywords */
      'and case default else elsif false if in import enherits node or true undef unless main settings $string ',
    literal:
    /* metaparameters */
      'alias audit before loglevel noop require subscribe tag ' +
    /* normal attributes */
      'owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check ' +
      'en_address ip_address realname command environment hour monute month monthday special target weekday '+
      'creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore ' +
      'links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source ' +
      'souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid '+
      'ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel ' +
      'native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options ' +
      'device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use ' +
      'message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform ' +
      'responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running ' +
      'start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age ' +
      'password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled ' +
      'enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist ' +
      'priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey ' +
      'sslverify mounted',
    built_in:
    /* core facts */
      'architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers ' +
      'domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces '+
      'ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion ' +
      'kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease ' +
      'lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major ' +
      'macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease '+
      'operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion '+
      'rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced '+
      'selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime '+
      'uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version'
  };

  var COMMENT = hljs.COMMENT('#', '$');

  var IDENT_RE = '([A-Za-z_]|::)(\\w|::)*';

  var TITLE = hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE});

  var VARIABLE = {className: 'variable', begin: '\\$' + IDENT_RE};

  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, VARIABLE],
    variants: [
      {begin: /'/, end: /'/},
      {begin: /"/, end: /"/}
    ]
  };

  return {
    aliases: ['pp'],
    contains: [
      COMMENT,
      VARIABLE,
      STRING,
      {
        beginKeywords: 'class', end: '\\{|;',
        illegal: /=/,
        contains: [TITLE, COMMENT]
      },
      {
        beginKeywords: 'define', end: /\{/,
        contains: [
          {
            className: 'title', begin: hljs.IDENT_RE, endsParent: true
          }
        ]
      },
      {
        begin: hljs.IDENT_RE + '\\s+\\{', returnBegin: true,
        end: /\S/,
        contains: [
          {
            className: 'name',
            begin: hljs.IDENT_RE
          },
          {
            begin: /\{/, end: /\}/,
            keywords: PUPPET_KEYWORDS,
            relevance: 0,
            contains: [
              STRING,
              COMMENT,
              {
                begin:'[a-zA-Z_]+\\s*=>'
              },
              {
                className: 'number',
                begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
                relevance: 0
              },
              VARIABLE
            ]
          }
        ],
        relevance: 0
      }
    ]
  }
});

hljs.registerLanguage('python', function(hljs) {
  var PROMPT = {
    className: 'prompt',  begin: /^(>>>|\.\.\.) /
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE],
    variants: [
      {
        begin: /(u|b)?r?'''/, end: /'''/,
        contains: [PROMPT],
        relevance: 10
      },
      {
        begin: /(u|b)?r?"""/, end: /"""/,
        contains: [PROMPT],
        relevance: 10
      },
      {
        begin: /(u|r|ur)'/, end: /'/,
        relevance: 10
      },
      {
        begin: /(u|r|ur)"/, end: /"/,
        relevance: 10
      },
      {
        begin: /(b|br)'/, end: /'/
      },
      {
        begin: /(b|br)"/, end: /"/
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE
    ]
  };
  var NUMBER = {
    className: 'number', relevance: 0,
    variants: [
      {begin: hljs.BINARY_NUMBER_RE + '[lLjJ]?'},
      {begin: '\\b(0o[0-7]+)[lLjJ]?'},
      {begin: hljs.C_NUMBER_RE + '[lLjJ]?'}
    ]
  };
  var PARAMS = {
    className: 'params',
    begin: /\(/, end: /\)/,
    contains: ['self', PROMPT, NUMBER, STRING]
  };
  return {
    aliases: ['py', 'gyp'],
    keywords: {
      keyword:
        'and elif is global as in if from raise for except finally print import pass return ' +
        'exec else break not with class assert yield try while continue del or def lambda ' +
        'async await nonlocal|10 None True False',
      built_in:
        'Ellipsis NotImplemented'
    },
    illegal: /(<\/|->|\?)/,
    contains: [
      PROMPT,
      NUMBER,
      STRING,
      hljs.HASH_COMMENT_MODE,
      {
        variants: [
          {className: 'function', beginKeywords: 'def', relevance: 10},
          {className: 'class', beginKeywords: 'class'}
        ],
        end: /:/,
        illegal: /[${=;\n,]/,
        contains: [hljs.UNDERSCORE_TITLE_MODE, PARAMS]
      },
      {
        className: 'decorator',
        begin: /^[\t ]*@/, end: /$/
      },
      {
        begin: /\b(print|exec)\(/ // don’t highlight keywords-turned-functions in Python 3
      }
    ]
  };
});

hljs.registerLanguage('q', function(hljs) {
  var Q_KEYWORDS = {
  keyword:
    'do while select delete by update from',
  constant:
    '0b 1b',
  built_in:
    'neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum',
  typename:
    '`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid'
  };
  return {
  aliases:['k', 'kdb'],
  keywords: Q_KEYWORDS,
  lexemes: /\b(`?)[A-Za-z0-9_]+\b/,
  contains: [
  hljs.C_LINE_COMMENT_MODE,
    hljs.QUOTE_STRING_MODE,
    hljs.C_NUMBER_MODE
     ]
  };
});

hljs.registerLanguage('r', function(hljs) {
  var IDENT_RE = '([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*';

  return {
    contains: [
      hljs.HASH_COMMENT_MODE,
      {
        begin: IDENT_RE,
        lexemes: IDENT_RE,
        keywords: {
          keyword:
            'function if in break next repeat else for return switch while try tryCatch ' +
            'stop warning require library attach detach source setMethod setGeneric ' +
            'setGroupGeneric setClass ...',
          literal:
            'NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 ' +
            'NA_complex_|10'
        },
        relevance: 0
      },
      {
        // hex value
        className: 'number',
        begin: "0[xX][0-9a-fA-F]+[Li]?\\b",
        relevance: 0
      },
      {
        // explicit integer
        className: 'number',
        begin: "\\d+(?:[eE][+\\-]?\\d*)?L\\b",
        relevance: 0
      },
      {
        // number with trailing decimal
        className: 'number',
        begin: "\\d+\\.(?!\\d)(?:i\\b)?",
        relevance: 0
      },
      {
        // number
        className: 'number',
        begin: "\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",
        relevance: 0
      },
      {
        // number with leading decimal
        className: 'number',
        begin: "\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",
        relevance: 0
      },

      {
        // escaped identifier
        begin: '`',
        end: '`',
        relevance: 0
      },

      {
        className: 'string',
        contains: [hljs.BACKSLASH_ESCAPE],
        variants: [
          {begin: '"', end: '"'},
          {begin: "'", end: "'"}
        ]
      }
    ]
  };
});

hljs.registerLanguage('rib', function(hljs) {
  return {
    keywords:
      'ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis ' +
      'Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone ' +
      'CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail ' +
      'DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format ' +
      'FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry ' +
      'Hider Hyperboloid Identity Illuminate Imager Interior LightSource ' +
      'MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte ' +
      'MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option ' +
      'Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples ' +
      'PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection ' +
      'Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ' +
      'ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere ' +
      'SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd ' +
      'TransformPoints Translate TrimCurve WorldBegin WorldEnd',
    illegal: '</',
    contains: [
      hljs.HASH_COMMENT_MODE,
      hljs.C_NUMBER_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE
    ]
  };
});

hljs.registerLanguage('roboconf', function(hljs) {
  var IDENTIFIER = '[a-zA-Z-_][^\n{\r\n]+\\{';

  return {
    aliases: ['graph', 'instances'],
    case_insensitive: true,
    keywords: 'import',
    contains: [
      // Facet sections
      {
        className: 'facet',
        begin: '^facet ' + IDENTIFIER,
        end: '}',
        keywords: 'facet installer exports children extends',
        contains: [
          hljs.HASH_COMMENT_MODE
        ]
      },

      // Instance sections
      {
        className: 'instance-of',
        begin: '^instance of ' + IDENTIFIER,
        end: '}',
        keywords: 'name count channels instance-data instance-state instance of',
        contains: [
          // Instance overridden properties
          {
            className: 'keyword',
            begin: '[a-zA-Z-_]+( |\t)*:'
          },
          hljs.HASH_COMMENT_MODE
        ]
      },

      // Component sections
      {
        className: 'component',
        begin: '^' + IDENTIFIER,
        end: '}',
        lexemes: '\\(?[a-zA-Z]+\\)?',
        keywords: 'installer exports children extends imports facets alias (optional)',
        contains: [
          // Imported component variables
          {
            className: 'string',
            begin: '\\.[a-zA-Z-_]+',
            end: '\\s|,|;',
            excludeEnd: true
          },
          hljs.HASH_COMMENT_MODE
        ]
      },

      // Comments
      hljs.HASH_COMMENT_MODE
    ]
  };
});

hljs.registerLanguage('rsl', function(hljs) {
  return {
    keywords: {
      keyword:
        'float color point normal vector matrix while for if do return else break extern continue',
      built_in:
        'abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise ' +
        'clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp ' +
        'faceforward filterstep floor format fresnel incident length lightsource log match ' +
        'max min mod noise normalize ntransform opposite option phong pnoise pow printf ' +
        'ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp ' +
        'setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan ' +
        'texture textureinfo trace transform vtransform xcomp ycomp zcomp'
    },
    illegal: '</',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.APOS_STRING_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'preprocessor',
        begin: '#', end: '$'
      },
      {
        className: 'shader',
        beginKeywords: 'surface displacement light volume imager', end: '\\('
      },
      {
        className: 'shading',
        beginKeywords: 'illuminate illuminance gather', end: '\\('
      }
    ]
  };
});

hljs.registerLanguage('ruleslanguage', function(hljs) {
  return {
    keywords: {
       keyword: 'BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE ' +
         'INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 ' +
         'INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 ' +
         'INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 ' +
         'INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 ' +
         'INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 ' +
         'INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 ' +
         'INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 ' +
         'INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 ' +
         'INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 ' +
         'INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 ' +
         'INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 ' +
         'INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 ' +
         'INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 ' +
         'INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 ' +
         'MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER ' +
         'OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE ' +
         'NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH ' +
         'IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND ' +
         'UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ' +
         'ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE ' +
         'GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE ' +
         'SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING ' +
         'DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF ' +
         'MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY ' +
         'YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE ' +
         'COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR ' +
         'READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ' +
         'ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE ' +
         'EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE ' +
         'SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL ' +
         'COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN ' +
         'MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING ' +
         'FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ' +
         'NUMDAYS READ_DATE STAGING',
       built_in: 'IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML ' +
         'DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT ' +
         'DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE ' +
         'DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT ' +
         'DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME'
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'array',
        variants: [
          {begin: '#\\s+[a-zA-Z\\ \\.]*', relevance: 0}, // looks like #-comment
          {begin: '#[a-zA-Z\\ \\.]+'}
        ]
      }
    ]
  };
});

hljs.registerLanguage('rust', function(hljs) {
  var NUM_SUFFIX = '([uif](8|16|32|64|size))\?';
  var BLOCK_COMMENT = hljs.inherit(hljs.C_BLOCK_COMMENT_MODE);
  BLOCK_COMMENT.contains.push('self');
  return {
    aliases: ['rs'],
    keywords: {
      keyword:
        'alignof as be box break const continue crate do else enum extern ' +
        'false fn for if impl in let loop match mod mut offsetof once priv ' +
        'proc pub pure ref return self Self sizeof static struct super trait true ' +
        'type typeof unsafe unsized use virtual while where yield ' +
        'int i8 i16 i32 i64 ' +
        'uint u8 u32 u64 ' +
        'float f32 f64 ' +
        'str char bool',
      built_in:
        // prelude
        'Copy Send Sized Sync Drop Fn FnMut FnOnce drop Box ToOwned Clone ' +
        'PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator ' +
        'Extend IntoIterator DoubleEndedIterator ExactSizeIterator Option ' +
        'Some None Result Ok Err SliceConcatExt String ToString Vec ' +
        // macros
        'assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! ' +
        'debug_assert! debug_assert_eq! env! panic! file! format! format_args! ' +
        'include_bin! include_str! line! local_data_key! module_path! ' +
        'option_env! print! println! select! stringify! try! unimplemented! ' +
        'unreachable! vec! write! writeln!'
    },
    lexemes: hljs.IDENT_RE + '!?',
    illegal: '</',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      BLOCK_COMMENT,
      hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
      {
        className: 'string',
        variants: [
           { begin: /r(#*)".*?"\1(?!#)/ },
           { begin: /'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/ },
           { begin: /'[a-zA-Z_][a-zA-Z0-9_]*/ }
        ]
      },
      {
        className: 'number',
        variants: [
          { begin: '\\b0b([01_]+)' + NUM_SUFFIX },
          { begin: '\\b0o([0-7_]+)' + NUM_SUFFIX },
          { begin: '\\b0x([A-Fa-f0-9_]+)' + NUM_SUFFIX },
          { begin: '\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)' +
                   NUM_SUFFIX
          }
        ],
        relevance: 0
      },
      {
        className: 'function',
        beginKeywords: 'fn', end: '(\\(|<)', excludeEnd: true,
        contains: [hljs.UNDERSCORE_TITLE_MODE]
      },
      {
        className: 'preprocessor',
        begin: '#\\!?\\[', end: '\\]'
      },
      {
        beginKeywords: 'type', end: '(=|<)',
        contains: [hljs.UNDERSCORE_TITLE_MODE],
        illegal: '\\S'
      },
      {
        beginKeywords: 'trait enum', end: '{',
        contains: [
          hljs.inherit(hljs.UNDERSCORE_TITLE_MODE, {endsParent: true})
        ],
        illegal: '[\\w\\d]'
      },
      {
        begin: hljs.IDENT_RE + '::'
      },
      {
        begin: '->'
      }
    ]
  };
});

hljs.registerLanguage('scala', function(hljs) {

  var ANNOTATION = {
    className: 'annotation', begin: '@[A-Za-z]+'
  };

  var STRING = {
    className: 'string',
    begin: 'u?r?"""', end: '"""',
    relevance: 10
  };

  var SYMBOL = {
    className: 'symbol',
    begin: '\'\\w[\\w\\d_]*(?!\')'
  };

  var TYPE = {
    className: 'type',
    begin: '\\b[A-Z][A-Za-z0-9_]*',
    relevance: 0
  };

  var NAME = {
    className: 'title',
    begin: /[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,
    relevance: 0
  };

  var CLASS = {
    className: 'class',
    beginKeywords: 'class object trait type',
    end: /[:={\[(\n;]/,
    contains: [{className: 'keyword', beginKeywords: 'extends with', relevance: 10}, NAME]
  };

  var METHOD = {
    className: 'function',
    beginKeywords: 'def',
    end: /[:={\[(\n;]/,
    contains: [NAME]
  };

  return {
    keywords: {
      literal: 'true false null',
      keyword: 'type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit'
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      STRING,
      hljs.QUOTE_STRING_MODE,
      SYMBOL,
      TYPE,
      METHOD,
      CLASS,
      hljs.C_NUMBER_MODE,
      ANNOTATION
    ]
  };
});

hljs.registerLanguage('scheme', function(hljs) {
  var SCHEME_IDENT_RE = '[^\\(\\)\\[\\]\\{\\}",\'`;#|\\\\\\s]+';
  var SCHEME_SIMPLE_NUMBER_RE = '(\\-|\\+)?\\d+([./]\\d+)?';
  var SCHEME_COMPLEX_NUMBER_RE = SCHEME_SIMPLE_NUMBER_RE + '[+\\-]' + SCHEME_SIMPLE_NUMBER_RE + 'i';
  var BUILTINS = {
    built_in:
      'case-lambda call/cc class define-class exit-handler field import ' +
      'inherit init-field interface let*-values let-values let/ec mixin ' +
      'opt-lambda override protect provide public rename require ' +
      'require-for-syntax syntax syntax-case syntax-error unit/sig unless ' +
      'when with-syntax and begin call-with-current-continuation ' +
      'call-with-input-file call-with-output-file case cond define ' +
      'define-syntax delay do dynamic-wind else for-each if lambda let let* ' +
      'let-syntax letrec letrec-syntax map or syntax-rules \' * + , ,@ - ... / ' +
      '; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan ' +
      'boolean? caar cadr call-with-input-file call-with-output-file ' +
      'call-with-values car cdddar cddddr cdr ceiling char->integer ' +
      'char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? ' +
      'char-downcase char-lower-case? char-numeric? char-ready? char-upcase ' +
      'char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? ' +
      'char? close-input-port close-output-port complex? cons cos ' +
      'current-input-port current-output-port denominator display eof-object? ' +
      'eq? equal? eqv? eval even? exact->inexact exact? exp expt floor ' +
      'force gcd imag-part inexact->exact inexact? input-port? integer->char ' +
      'integer? interaction-environment lcm length list list->string ' +
      'list->vector list-ref list-tail list? load log magnitude make-polar ' +
      'make-rectangular make-string make-vector max member memq memv min ' +
      'modulo negative? newline not null-environment null? number->string ' +
      'number? numerator odd? open-input-file open-output-file output-port? ' +
      'pair? peek-char port? positive? procedure? quasiquote quote quotient ' +
      'rational? rationalize read read-char real-part real? remainder reverse ' +
      'round scheme-report-environment set! set-car! set-cdr! sin sqrt string ' +
      'string->list string->number string->symbol string-append string-ci<=? ' +
      'string-ci<? string-ci=? string-ci>=? string-ci>? string-copy ' +
      'string-fill! string-length string-ref string-set! string<=? string<? ' +
      'string=? string>=? string>? string? substring symbol->string symbol? ' +
      'tan transcript-off transcript-on truncate values vector ' +
      'vector->list vector-fill! vector-length vector-ref vector-set! ' +
      'with-input-from-file with-output-to-file write write-char zero?'
  };

  var SHEBANG = {
    className: 'shebang',
    begin: '^#!',
    end: '$'
  };

  var LITERAL = {
    className: 'literal',
    begin: '(#t|#f|#\\\\' + SCHEME_IDENT_RE + '|#\\\\.)'
  };

  var NUMBER = {
    className: 'number',
    variants: [
      { begin: SCHEME_SIMPLE_NUMBER_RE, relevance: 0 },
      { begin: SCHEME_COMPLEX_NUMBER_RE, relevance: 0 },
      { begin: '#b[0-1]+(/[0-1]+)?' },
      { begin: '#o[0-7]+(/[0-7]+)?' },
      { begin: '#x[0-9a-f]+(/[0-9a-f]+)?' }
    ]
  };

  var STRING = hljs.QUOTE_STRING_MODE;

  var REGULAR_EXPRESSION = {
    className: 'regexp',
    begin: '#[pr]x"',
    end: '[^\\\\]"'
  };

  var COMMENT_MODES = [
    hljs.COMMENT(
      ';',
      '$',
      {
        relevance: 0
      }
    ),
    hljs.COMMENT('#\\|', '\\|#')
  ];

  var IDENT = {
    begin: SCHEME_IDENT_RE,
    relevance: 0
  };

  var QUOTED_IDENT = {
    className: 'variable',
    begin: '\'' + SCHEME_IDENT_RE
  };

  var BODY = {
    endsWithParent: true,
    relevance: 0
  };

  var LIST = {
    className: 'list',
    variants: [
      { begin: '\\(', end: '\\)' },
      { begin: '\\[', end: '\\]' }
    ],
    contains: [
      {
        className: 'keyword',
        begin: SCHEME_IDENT_RE,
        lexemes: SCHEME_IDENT_RE,
        keywords: BUILTINS
      },
      BODY
    ]
  };

  BODY.contains = [LITERAL, NUMBER, STRING, IDENT, QUOTED_IDENT, LIST].concat(COMMENT_MODES);

  return {
    illegal: /\S/,
    contains: [SHEBANG, NUMBER, STRING, QUOTED_IDENT, LIST].concat(COMMENT_MODES)
  };
});

hljs.registerLanguage('scilab', function(hljs) {

  var COMMON_CONTAINS = [
    hljs.C_NUMBER_MODE,
    {
      className: 'string',
      begin: '\'|\"', end: '\'|\"',
      contains: [hljs.BACKSLASH_ESCAPE, {begin: '\'\''}]
    }
  ];

  return {
    aliases: ['sci'],
    keywords: {
      keyword: 'abort break case clear catch continue do elseif else endfunction end for function'+
        'global if pause return resume select try then while'+
        '%f %F %t %T %pi %eps %inf %nan %e %i %z %s',
      built_in: // Scilab has more than 2000 functions. Just list the most commons
       'abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error'+
       'exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty'+
       'isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log'+
       'max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real'+
       'round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan'+
       'type typename warning zeros matrix'
    },
    illegal: '("|#|/\\*|\\s+/\\w+)',
    contains: [
      {
        className: 'function',
        beginKeywords: 'function endfunction', end: '$',
        keywords: 'function endfunction|10',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE,
          {
            className: 'params',
            begin: '\\(', end: '\\)'
          }
        ]
      },
      {
        className: 'transposed_variable',
        begin: '[a-zA-Z_][a-zA-Z_0-9]*(\'+[\\.\']*|[\\.\']+)', end: '',
        relevance: 0
      },
      {
        className: 'matrix',
        begin: '\\[', end: '\\]\'*[\\.\']*',
        relevance: 0,
        contains: COMMON_CONTAINS
      },
      hljs.COMMENT('//', '$')
    ].concat(COMMON_CONTAINS)
  };
});

hljs.registerLanguage('scss', function(hljs) {
  var IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
  var VARIABLE = {
    className: 'variable',
    begin: '(\\$' + IDENT_RE + ')\\b'
  };
  var FUNCTION = {
    className: 'function',
    begin: IDENT_RE + '\\(',
    returnBegin: true,
    excludeEnd: true,
    end: '\\('
  };
  var HEXCOLOR = {
    className: 'hexcolor', begin: '#[0-9A-Fa-f]+'
  };
  var DEF_INTERNALS = {
    className: 'attribute',
    begin: '[A-Z\\_\\.\\-]+', end: ':',
    excludeEnd: true,
    illegal: '[^\\s]',
    starts: {
      className: 'value',
      endsWithParent: true, excludeEnd: true,
      contains: [
        FUNCTION,
        HEXCOLOR,
        hljs.CSS_NUMBER_MODE,
        hljs.QUOTE_STRING_MODE,
        hljs.APOS_STRING_MODE,
        hljs.C_BLOCK_COMMENT_MODE,
        {
          className: 'important', begin: '!important'
        }
      ]
    }
  };
  return {
    case_insensitive: true,
    illegal: '[=/|\']',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      FUNCTION,
      {
        className: 'id', begin: '\\#[A-Za-z0-9_-]+',
        relevance: 0
      },
      {
        className: 'class', begin: '\\.[A-Za-z0-9_-]+',
        relevance: 0
      },
      {
        className: 'attr_selector',
        begin: '\\[', end: '\\]',
        illegal: '$'
      },
      {
        className: 'tag', // begin: IDENT_RE, end: '[,|\\s]'
        begin: '\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b',
        relevance: 0
      },
      {
        className: 'pseudo',
        begin: ':(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)'
      },
      {
        className: 'pseudo',
        begin: '::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)'
      },
      VARIABLE,
      {
        className: 'attribute',
        begin: '\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b',
        illegal: '[^\\s]'
      },
      {
        className: 'value',
        begin: '\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b'
      },
      {
        className: 'value',
        begin: ':', end: ';',
        contains: [
          FUNCTION,
          VARIABLE,
          HEXCOLOR,
          hljs.CSS_NUMBER_MODE,
          hljs.QUOTE_STRING_MODE,
          hljs.APOS_STRING_MODE,
          {
            className: 'important', begin: '!important'
          }
        ]
      },
      {
        className: 'at_rule',
        begin: '@', end: '[{;]',
        keywords: 'mixin include extend for if else each while charset import debug media page content font-face namespace warn',
        contains: [
          FUNCTION,
          VARIABLE,
          hljs.QUOTE_STRING_MODE,
          hljs.APOS_STRING_MODE,
          HEXCOLOR,
          hljs.CSS_NUMBER_MODE,
          {
            className: 'preprocessor',
            begin: '\\s[A-Za-z0-9_.-]+',
            relevance: 0
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('smali', function(hljs) {
  var smali_instr_low_prio = ['add', 'and', 'cmp', 'cmpg', 'cmpl', 'const', 'div', 'double', 'float', 'goto', 'if', 'int', 'long', 'move', 'mul', 'neg', 'new', 'nop', 'not', 'or', 'rem', 'return', 'shl', 'shr', 'sput', 'sub', 'throw', 'ushr', 'xor'];
  var smali_instr_high_prio = ['aget', 'aput', 'array', 'check', 'execute', 'fill', 'filled', 'goto/16', 'goto/32', 'iget', 'instance', 'invoke', 'iput', 'monitor', 'packed', 'sget', 'sparse'];
  var smali_keywords = ['transient', 'constructor', 'abstract', 'final', 'synthetic', 'public', 'private', 'protected', 'static', 'bridge', 'system'];
  return {
    aliases: ['smali'],
    contains: [
      {
        className: 'string',
        begin: '"', end: '"',
        relevance: 0
      },
      hljs.COMMENT(
        '#',
        '$',
        {
          relevance: 0
        }
      ),
      {
        className: 'keyword',
        begin: '\\s*\\.end\\s[a-zA-Z0-9]*',
        relevance: 1
      },
      {
        className: 'keyword',
        begin: '^[ ]*\\.[a-zA-Z]*',
        relevance: 0
      },
      {
        className: 'keyword',
        begin: '\\s:[a-zA-Z_0-9]*',
        relevance: 0
      },
      {
        className: 'keyword',
        begin: '\\s('+smali_keywords.join('|')+')',
        relevance: 1
      },
      {
        className: 'keyword',
        begin: '\\[',
        relevance: 0
      },
      {
        className: 'instruction',
        begin: '\\s('+smali_instr_low_prio.join('|')+')\\s',
        relevance: 1
      },
      {
        className: 'instruction',
        begin: '\\s('+smali_instr_low_prio.join('|')+')((\\-|/)[a-zA-Z0-9]+)+\\s',
        relevance: 10
      },
      {
        className: 'instruction',
        begin: '\\s('+smali_instr_high_prio.join('|')+')((\\-|/)[a-zA-Z0-9]+)*\\s',
        relevance: 10
      },
      {
        className: 'class',
        begin: 'L[^\(;:\n]*;',
        relevance: 0
      },
      {
        className: 'function',
        begin: '( |->)[^(\n ;"]*\\(',
        relevance: 0
      },
      {
        className: 'function',
        begin: '\\)',
        relevance: 0
      },
      {
        className: 'variable',
        begin: '[vp][0-9]+',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('smalltalk', function(hljs) {
  var VAR_IDENT_RE = '[a-z][a-zA-Z0-9_]*';
  var CHAR = {
    className: 'char',
    begin: '\\$.{1}'
  };
  var SYMBOL = {
    className: 'symbol',
    begin: '#' + hljs.UNDERSCORE_IDENT_RE
  };
  return {
    aliases: ['st'],
    keywords: 'self super nil true false thisContext', // only 6
    contains: [
      hljs.COMMENT('"', '"'),
      hljs.APOS_STRING_MODE,
      {
        className: 'class',
        begin: '\\b[A-Z][A-Za-z0-9_]*',
        relevance: 0
      },
      {
        className: 'method',
        begin: VAR_IDENT_RE + ':',
        relevance: 0
      },
      hljs.C_NUMBER_MODE,
      SYMBOL,
      CHAR,
      {
        className: 'localvars',
        // This looks more complicated than needed to avoid combinatorial
        // explosion under V8. It effectively means `| var1 var2 ... |` with
        // whitespace adjacent to `|` being optional.
        begin: '\\|[ ]*' + VAR_IDENT_RE + '([ ]+' + VAR_IDENT_RE + ')*[ ]*\\|',
        returnBegin: true, end: /\|/,
        illegal: /\S/,
        contains: [{begin: '(\\|[ ]*)?' + VAR_IDENT_RE}]
      },
      {
        className: 'array',
        begin: '\\#\\(', end: '\\)',
        contains: [
          hljs.APOS_STRING_MODE,
          CHAR,
          hljs.C_NUMBER_MODE,
          SYMBOL
        ]
      }
    ]
  };
});

hljs.registerLanguage('sml', function(hljs) {
  return {
    aliases: ['ml'],
    keywords: {
      keyword:
        /* according to Definition of Standard ML 97  */
        'abstype and andalso as case datatype do else end eqtype ' +
        'exception fn fun functor handle if in include infix infixr ' +
        'let local nonfix of op open orelse raise rec sharing sig ' +
        'signature struct structure then type val with withtype where while',
      built_in:
        /* built-in types according to basis library */
        'array bool char exn int list option order real ref string substring vector unit word',
      literal:
        'true false NONE SOME LESS EQUAL GREATER nil'
    },
    illegal: /\/\/|>>/,
    lexemes: '[a-z_]\\w*!?',
    contains: [
      {
        className: 'literal',
        begin: '\\[(\\|\\|)?\\]|\\(\\)'
      },
      hljs.COMMENT(
        '\\(\\*',
        '\\*\\)',
        {
          contains: ['self']
        }
      ),
      { /* type variable */
        className: 'symbol',
        begin: '\'[A-Za-z_](?!\')[\\w\']*'
        /* the grammar is ambiguous on how 'a'b should be interpreted but not the compiler */
      },
      { /* polymorphic variant */
        className: 'tag',
        begin: '`[A-Z][\\w\']*'
      },
      { /* module or constructor */
        className: 'type',
        begin: '\\b[A-Z][\\w\']*',
        relevance: 0
      },
      { /* don't color identifiers, but safely catch all identifiers with '*/
        begin: '[a-z_]\\w*\'[\\w\']*'
      },
      hljs.inherit(hljs.APOS_STRING_MODE, {className: 'char', relevance: 0}),
      hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
      {
        className: 'number',
        begin:
          '\\b(0[xX][a-fA-F0-9_]+[Lln]?|' +
          '0[oO][0-7_]+[Lln]?|' +
          '0[bB][01_]+[Lln]?|' +
          '[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)',
        relevance: 0
      },
      {
        begin: /[-=]>/ // relevance booster
      }
    ]
  };
});

hljs.registerLanguage('sqf', function(hljs) {
  var allCommands = ['!', '-', '+', '!=', '%', '&&', '*', '/', '=', '==', '>', '>=', '<', '<=', 'or', 'plus', '^', ':', '>>', 'abs', 'accTime', 'acos', 'action', 'actionKeys', 'actionKeysImages', 'actionKeysNames', 'actionKeysNamesArray', 'actionName', 'activateAddons', 'activatedAddons', 'activateKey', 'addAction', 'addBackpack', 'addBackpackCargo', 'addBackpackCargoGlobal', 'addBackpackGlobal', 'addCamShake', 'addCuratorAddons', 'addCuratorCameraArea', 'addCuratorEditableObjects', 'addCuratorEditingArea', 'addCuratorPoints', 'addEditorObject', 'addEventHandler', 'addGoggles', 'addGroupIcon', 'addHandgunItem', 'addHeadgear', 'addItem', 'addItemCargo', 'addItemCargoGlobal', 'addItemPool', 'addItemToBackpack', 'addItemToUniform', 'addItemToVest', 'addLiveStats', 'addMagazine', 'addMagazine array', 'addMagazineAmmoCargo', 'addMagazineCargo', 'addMagazineCargoGlobal', 'addMagazineGlobal', 'addMagazinePool', 'addMagazines', 'addMagazineTurret', 'addMenu', 'addMenuItem', 'addMissionEventHandler', 'addMPEventHandler', 'addMusicEventHandler', 'addPrimaryWeaponItem', 'addPublicVariableEventHandler', 'addRating', 'addResources', 'addScore', 'addScoreSide', 'addSecondaryWeaponItem', 'addSwitchableUnit', 'addTeamMember', 'addToRemainsCollector', 'addUniform', 'addVehicle', 'addVest', 'addWaypoint', 'addWeapon', 'addWeaponCargo', 'addWeaponCargoGlobal', 'addWeaponGlobal', 'addWeaponPool', 'addWeaponTurret', 'agent', 'agents', 'AGLToASL', 'aimedAtTarget', 'aimPos', 'airDensityRTD', 'airportSide', 'AISFinishHeal', 'alive', 'allControls', 'allCurators', 'allDead', 'allDeadMen', 'allDisplays', 'allGroups', 'allMapMarkers', 'allMines', 'allMissionObjects', 'allow3DMode', 'allowCrewInImmobile', 'allowCuratorLogicIgnoreAreas', 'allowDamage', 'allowDammage', 'allowFileOperations', 'allowFleeing', 'allowGetIn', 'allPlayers', 'allSites', 'allTurrets', 'allUnits', 'allUnitsUAV', 'allVariables', 'ammo', 'and', 'animate', 'animateDoor', 'animationPhase', 'animationState', 'append', 'armoryPoints', 'arrayIntersect', 'asin', 'ASLToAGL', 'ASLToATL', 'assert', 'assignAsCargo', 'assignAsCargoIndex', 'assignAsCommander', 'assignAsDriver', 'assignAsGunner', 'assignAsTurret', 'assignCurator', 'assignedCargo', 'assignedCommander', 'assignedDriver', 'assignedGunner', 'assignedItems', 'assignedTarget', 'assignedTeam', 'assignedVehicle', 'assignedVehicleRole', 'assignItem', 'assignTeam', 'assignToAirport', 'atan', 'atan2', 'atg', 'ATLToASL', 'attachedObject', 'attachedObjects', 'attachedTo', 'attachObject', 'attachTo', 'attackEnabled', 'backpack', 'backpackCargo', 'backpackContainer', 'backpackItems', 'backpackMagazines', 'backpackSpaceFor', 'behaviour', 'benchmark', 'binocular', 'blufor', 'boundingBox', 'boundingBoxReal', 'boundingCenter', 'breakOut', 'breakTo', 'briefingName', 'buildingExit', 'buildingPos', 'buttonAction', 'buttonSetAction', 'cadetMode', 'call', 'callExtension', 'camCommand', 'camCommit', 'camCommitPrepared', 'camCommitted', 'camConstuctionSetParams', 'camCreate', 'camDestroy', 'cameraEffect', 'cameraEffectEnableHUD', 'cameraInterest', 'cameraOn', 'cameraView', 'campaignConfigFile', 'camPreload', 'camPreloaded', 'camPrepareBank', 'camPrepareDir', 'camPrepareDive', 'camPrepareFocus', 'camPrepareFov', 'camPrepareFovRange', 'camPreparePos', 'camPrepareRelPos', 'camPrepareTarget', 'camSetBank', 'camSetDir', 'camSetDive', 'camSetFocus', 'camSetFov', 'camSetFovRange', 'camSetPos', 'camSetRelPos', 'camSetTarget', 'camTarget', 'camUseNVG', 'canAdd', 'canAddItemToBackpack', 'canAddItemToUniform', 'canAddItemToVest', 'cancelSimpleTaskDestination', 'canFire', 'canMove', 'canSlingLoad', 'canStand', 'canUnloadInCombat', 'captive', 'captiveNum', 'case', 'catch', 'cbChecked', 'cbSetChecked', 'ceil', 'cheatsEnabled', 'checkAIFeature', 'civilian', 'className', 'clearAllItemsFromBackpack', 'clearBackpackCargo', 'clearBackpackCargoGlobal', 'clearGroupIcons', 'clearItemCargo', 'clearItemCargoGlobal', 'clearItemPool', 'clearMagazineCargo', 'clearMagazineCargoGlobal', 'clearMagazinePool', 'clearOverlay', 'clearRadio', 'clearWeaponCargo', 'clearWeaponCargoGlobal', 'clearWeaponPool', 'closeDialog', 'closeDisplay', 'closeOverlay', 'collapseObjectTree', 'combatMode', 'commandArtilleryFire', 'commandChat', 'commander', 'commandFire', 'commandFollow', 'commandFSM', 'commandGetOut', 'commandingMenu', 'commandMove', 'commandRadio', 'commandStop', 'commandTarget', 'commandWatch', 'comment', 'commitOverlay', 'compile', 'compileFinal', 'completedFSM', 'composeText', 'configClasses', 'configFile', 'configHierarchy', 'configName', 'configProperties', 'configSourceMod', 'configSourceModList', 'connectTerminalToUAV', 'controlNull', 'controlsGroupCtrl', 'copyFromClipboard', 'copyToClipboard', 'copyWaypoints', 'cos', 'count', 'countEnemy', 'countFriendly', 'countSide', 'countType', 'countUnknown', 'createAgent', 'createCenter', 'createDialog', 'createDiaryLink', 'createDiaryRecord', 'createDiarySubject', 'createDisplay', 'createGearDialog', 'createGroup', 'createGuardedPoint', 'createLocation', 'createMarker', 'createMarkerLocal', 'createMenu', 'createMine', 'createMissionDisplay', 'createSimpleTask', 'createSite', 'createSoundSource', 'createTask', 'createTeam', 'createTrigger', 'createUnit', 'createUnit array', 'createVehicle', 'createVehicle array', 'createVehicleCrew', 'createVehicleLocal', 'crew', 'ctrlActivate', 'ctrlAddEventHandler', 'ctrlAutoScrollDelay', 'ctrlAutoScrollRewind', 'ctrlAutoScrollSpeed', 'ctrlChecked', 'ctrlClassName', 'ctrlCommit', 'ctrlCommitted', 'ctrlCreate', 'ctrlDelete', 'ctrlEnable', 'ctrlEnabled', 'ctrlFade', 'ctrlHTMLLoaded', 'ctrlIDC', 'ctrlIDD', 'ctrlMapAnimAdd', 'ctrlMapAnimClear', 'ctrlMapAnimCommit', 'ctrlMapAnimDone', 'ctrlMapCursor', 'ctrlMapMouseOver', 'ctrlMapScale', 'ctrlMapScreenToWorld', 'ctrlMapWorldToScreen', 'ctrlModel', 'ctrlModelDirAndUp', 'ctrlModelScale', 'ctrlParent', 'ctrlPosition', 'ctrlRemoveAllEventHandlers', 'ctrlRemoveEventHandler', 'ctrlScale', 'ctrlSetActiveColor', 'ctrlSetAutoScrollDelay', 'ctrlSetAutoScrollRewind', 'ctrlSetAutoScrollSpeed', 'ctrlSetBackgroundColor', 'ctrlSetChecked', 'ctrlSetEventHandler', 'ctrlSetFade', 'ctrlSetFocus', 'ctrlSetFont', 'ctrlSetFontH1', 'ctrlSetFontH1B', 'ctrlSetFontH2', 'ctrlSetFontH2B', 'ctrlSetFontH3', 'ctrlSetFontH3B', 'ctrlSetFontH4', 'ctrlSetFontH4B', 'ctrlSetFontH5', 'ctrlSetFontH5B', 'ctrlSetFontH6', 'ctrlSetFontH6B', 'ctrlSetFontHeight', 'ctrlSetFontHeightH1', 'ctrlSetFontHeightH2', 'ctrlSetFontHeightH3', 'ctrlSetFontHeightH4', 'ctrlSetFontHeightH5', 'ctrlSetFontHeightH6', 'ctrlSetFontP', 'ctrlSetFontPB', 'ctrlSetForegroundColor', 'ctrlSetModel', 'ctrlSetModelDirAndUp', 'ctrlSetModelScale', 'ctrlSetPosition', 'ctrlSetScale', 'ctrlSetStructuredText', 'ctrlSetText', 'ctrlSetTextColor', 'ctrlSetTooltip', 'ctrlSetTooltipColorBox', 'ctrlSetTooltipColorShade', 'ctrlSetTooltipColorText', 'ctrlShow', 'ctrlShown', 'ctrlText', 'ctrlTextHeight', 'ctrlType', 'ctrlVisible', 'curatorAddons', 'curatorCamera', 'curatorCameraArea', 'curatorCameraAreaCeiling', 'curatorCoef', 'curatorEditableObjects', 'curatorEditingArea', 'curatorEditingAreaType', 'curatorMouseOver', 'curatorPoints', 'curatorRegisteredObjects', 'curatorSelected', 'curatorWaypointCost', 'currentChannel', 'currentCommand', 'currentMagazine', 'currentMagazineDetail', 'currentMagazineDetailTurret', 'currentMagazineTurret', 'currentMuzzle', 'currentNamespace', 'currentTask', 'currentTasks', 'currentThrowable', 'currentVisionMode', 'currentWaypoint', 'currentWeapon', 'currentWeaponMode', 'currentWeaponTurret', 'currentZeroing', 'cursorTarget', 'customChat', 'customRadio', 'cutFadeOut', 'cutObj', 'cutRsc', 'cutText', 'damage', 'date', 'dateToNumber', 'daytime', 'deActivateKey', 'debriefingText', 'debugFSM', 'debugLog', 'default', 'deg', 'deleteAt', 'deleteCenter', 'deleteCollection', 'deleteEditorObject', 'deleteGroup', 'deleteIdentity', 'deleteLocation', 'deleteMarker', 'deleteMarkerLocal', 'deleteRange', 'deleteResources', 'deleteSite', 'deleteStatus', 'deleteTeam', 'deleteVehicle', 'deleteVehicleCrew', 'deleteWaypoint', 'detach', 'detectedMines', 'diag activeMissionFSMs', 'diag activeSQFScripts', 'diag activeSQSScripts', 'diag captureFrame', 'diag captureSlowFrame', 'diag fps', 'diag fpsMin', 'diag frameNo', 'diag log', 'diag logSlowFrame', 'diag tickTime', 'dialog', 'diarySubjectExists', 'didJIP', 'didJIPOwner', 'difficulty', 'difficultyEnabled', 'difficultyEnabledRTD', 'direction', 'directSay', 'disableAI', 'disableCollisionWith', 'disableConversation', 'disableDebriefingStats', 'disableSerialization', 'disableTIEquipment', 'disableUAVConnectability', 'disableUserInput', 'displayAddEventHandler', 'displayCtrl', 'displayNull', 'displayRemoveAllEventHandlers', 'displayRemoveEventHandler', 'displaySetEventHandler', 'dissolveTeam', 'distance', 'distance2D', 'distanceSqr', 'distributionRegion', 'do', 'doArtilleryFire', 'doFire', 'doFollow', 'doFSM', 'doGetOut', 'doMove', 'doorPhase', 'doStop', 'doTarget', 'doWatch', 'drawArrow', 'drawEllipse', 'drawIcon', 'drawIcon3D', 'drawLine', 'drawLine3D', 'drawLink', 'drawLocation', 'drawRectangle', 'driver', 'drop', 'east', 'echo', 'editObject', 'editorSetEventHandler', 'effectiveCommander', 'else', 'emptyPositions', 'enableAI', 'enableAIFeature', 'enableAttack', 'enableCamShake', 'enableCaustics', 'enableCollisionWith', 'enableCopilot', 'enableDebriefingStats', 'enableDiagLegend', 'enableEndDialog', 'enableEngineArtillery', 'enableEnvironment', 'enableFatigue', 'enableGunLights', 'enableIRLasers', 'enableMimics', 'enablePersonTurret', 'enableRadio', 'enableReload', 'enableRopeAttach', 'enableSatNormalOnDetail', 'enableSaving', 'enableSentences', 'enableSimulation', 'enableSimulationGlobal', 'enableTeamSwitch', 'enableUAVConnectability', 'enableUAVWaypoints', 'endLoadingScreen', 'endMission', 'engineOn', 'enginesIsOnRTD', 'enginesRpmRTD', 'enginesTorqueRTD', 'entities', 'estimatedEndServerTime', 'estimatedTimeLeft', 'evalObjectArgument', 'everyBackpack', 'everyContainer', 'exec', 'execEditorScript', 'execFSM', 'execVM', 'exit', 'exitWith', 'exp', 'expectedDestination', 'eyeDirection', 'eyePos', 'face', 'faction', 'fadeMusic', 'fadeRadio', 'fadeSound', 'fadeSpeech', 'failMission', 'false', 'fillWeaponsFromPool', 'find', 'findCover', 'findDisplay', 'findEditorObject', 'findEmptyPosition', 'findEmptyPositionReady', 'findNearestEnemy', 'finishMissionInit', 'finite', 'fire', 'fireAtTarget', 'firstBackpack', 'flag', 'flagOwner', 'fleeing', 'floor', 'flyInHeight', 'fog', 'fogForecast', 'fogParams', 'for', 'forceAddUniform', 'forceEnd', 'forceMap', 'forceRespawn', 'forceSpeed', 'forceWalk', 'forceWeaponFire', 'forceWeatherChange', 'forEach', 'forEachMember', 'forEachMemberAgent', 'forEachMemberTeam', 'format', 'formation', 'formationDirection', 'formationLeader', 'formationMembers', 'formationPosition', 'formationTask', 'formatText', 'formLeader', 'freeLook', 'from', 'fromEditor', 'fuel', 'fullCrew', 'gearSlotAmmoCount', 'gearSlotData', 'getAllHitPointsDamage', 'getAmmoCargo', 'getArray', 'getArtilleryAmmo', 'getArtilleryComputerSettings', 'getArtilleryETA', 'getAssignedCuratorLogic', 'getAssignedCuratorUnit', 'getBackpackCargo', 'getBleedingRemaining', 'getBurningValue', 'getCargoIndex', 'getCenterOfMass', 'getClientState', 'getConnectedUAV', 'getDammage', 'getDescription', 'getDir', 'getDirVisual', 'getDLCs', 'getEditorCamera', 'getEditorMode', 'getEditorObjectScope', 'getElevationOffset', 'getFatigue', 'getFriend', 'getFSMVariable', 'getFuelCargo', 'getGroupIcon', 'getGroupIconParams', 'getGroupIcons', 'getHideFrom', 'getHit', 'getHitIndex', 'getHitPointDamage', 'getItemCargo', 'getMagazineCargo', 'getMarkerColor', 'getMarkerPos', 'getMarkerSize', 'getMarkerType', 'getMass', 'getModelInfo', 'getNumber', 'getObjectArgument', 'getObjectChildren', 'getObjectDLC', 'getObjectMaterials', 'getObjectProxy', 'getObjectTextures', 'getObjectType', 'getObjectViewDistance', 'getOxygenRemaining', 'getPersonUsedDLCs', 'getPlayerChannel', 'getPlayerUID', 'getPos', 'getPosASL', 'getPosASLVisual', 'getPosASLW', 'getPosATL', 'getPosATLVisual', 'getPosVisual', 'getPosWorld', 'getRepairCargo', 'getResolution', 'getShadowDistance', 'getSlingLoad', 'getSpeed', 'getSuppression', 'getTerrainHeightASL', 'getText', 'getVariable', 'getWeaponCargo', 'getWPPos', 'glanceAt', 'globalChat', 'globalRadio', 'goggles', 'goto', 'group', 'groupChat', 'groupFromNetId', 'groupIconSelectable', 'groupIconsVisible', 'groupId', 'groupOwner', 'groupRadio', 'groupSelectedUnits', 'groupSelectUnit', 'grpNull', 'gunner', 'gusts', 'halt', 'handgunItems', 'handgunMagazine', 'handgunWeapon', 'handsHit', 'hasInterface', 'hasWeapon', 'hcAllGroups', 'hcGroupParams', 'hcLeader', 'hcRemoveAllGroups', 'hcRemoveGroup', 'hcSelected', 'hcSelectGroup', 'hcSetGroup', 'hcShowBar', 'hcShownBar', 'headgear', 'hideBody', 'hideObject', 'hideObjectGlobal', 'hint', 'hintC', 'hintCadet', 'hintSilent', 'hmd', 'hostMission', 'htmlLoad', 'HUDMovementLevels', 'humidity', 'if', 'image', 'importAllGroups', 'importance', 'in', 'incapacitatedState', 'independent', 'inflame', 'inflamed', 'inGameUISetEventHandler', 'inheritsFrom', 'initAmbientLife', 'inputAction', 'inRangeOfArtillery', 'insertEditorObject', 'intersect', 'isAbleToBreathe', 'isAgent', 'isArray', 'isAutoHoverOn', 'isAutonomous', 'isAutotest', 'isBleeding', 'isBurning', 'isClass', 'isCollisionLightOn', 'isCopilotEnabled', 'isDedicated', 'isDLCAvailable', 'isEngineOn', 'isEqualTo', 'isFlashlightOn', 'isFlatEmpty', 'isForcedWalk', 'isFormationLeader', 'isHidden', 'isInRemainsCollector', 'isInstructorFigureEnabled', 'isIRLaserOn', 'isKeyActive', 'isKindOf', 'isLightOn', 'isLocalized', 'isManualFire', 'isMarkedForCollection', 'isMultiplayer', 'isNil', 'isNull', 'isNumber', 'isObjectHidden', 'isObjectRTD', 'isOnRoad', 'isPipEnabled', 'isPlayer', 'isRealTime', 'isServer', 'isShowing3DIcons', 'isSteamMission', 'isStreamFriendlyUIEnabled', 'isText', 'isTouchingGround', 'isTurnedOut', 'isTutHintsEnabled', 'isUAVConnectable', 'isUAVConnected', 'isUniformAllowed', 'isWalking', 'isWeaponDeployed', 'isWeaponRested', 'itemCargo', 'items', 'itemsWithMagazines', 'join', 'joinAs', 'joinAsSilent', 'joinSilent', 'joinString', 'kbAddDatabase', 'kbAddDatabaseTargets', 'kbAddTopic', 'kbHasTopic', 'kbReact', 'kbRemoveTopic', 'kbTell', 'kbWasSaid', 'keyImage', 'keyName', 'knowsAbout', 'land', 'landAt', 'landResult', 'language', 'laserTarget', 'lbAdd', 'lbClear', 'lbColor', 'lbCurSel', 'lbData', 'lbDelete', 'lbIsSelected', 'lbPicture', 'lbSelection', 'lbSetColor', 'lbSetCurSel', 'lbSetData', 'lbSetPicture', 'lbSetPictureColor', 'lbSetPictureColorDisabled', 'lbSetPictureColorSelected', 'lbSetSelectColor', 'lbSetSelectColorRight', 'lbSetSelected', 'lbSetTooltip', 'lbSetValue', 'lbSize', 'lbSort', 'lbSortByValue', 'lbText', 'lbValue', 'leader', 'leaderboardDeInit', 'leaderboardGetRows', 'leaderboardInit', 'leaveVehicle', 'libraryCredits', 'libraryDisclaimers', 'lifeState', 'lightAttachObject', 'lightDetachObject', 'lightIsOn', 'lightnings', 'limitSpeed', 'linearConversion', 'lineBreak', 'lineIntersects', 'lineIntersectsObjs', 'lineIntersectsSurfaces', 'lineIntersectsWith', 'linkItem', 'list', 'listObjects', 'ln', 'lnbAddArray', 'lnbAddColumn', 'lnbAddRow', 'lnbClear', 'lnbColor', 'lnbCurSelRow', 'lnbData', 'lnbDeleteColumn', 'lnbDeleteRow', 'lnbGetColumnsPosition', 'lnbPicture', 'lnbSetColor', 'lnbSetColumnsPos', 'lnbSetCurSelRow', 'lnbSetData', 'lnbSetPicture', 'lnbSetText', 'lnbSetValue', 'lnbSize', 'lnbText', 'lnbValue', 'load', 'loadAbs', 'loadBackpack', 'loadFile', 'loadGame', 'loadIdentity', 'loadMagazine', 'loadOverlay', 'loadStatus', 'loadUniform', 'loadVest', 'local', 'localize', 'locationNull', 'locationPosition', 'lock', 'lockCameraTo', 'lockCargo', 'lockDriver', 'locked', 'lockedCargo', 'lockedDriver', 'lockedTurret', 'lockTurret', 'lockWP', 'log', 'logEntities', 'lookAt', 'lookAtPos', 'magazineCargo', 'magazines', 'magazinesAllTurrets', 'magazinesAmmo', 'magazinesAmmoCargo', 'magazinesAmmoFull', 'magazinesDetail', 'magazinesDetailBackpack', 'magazinesDetailUniform', 'magazinesDetailVest', 'magazinesTurret', 'magazineTurretAmmo', 'mapAnimAdd', 'mapAnimClear', 'mapAnimCommit', 'mapAnimDone', 'mapCenterOnCamera', 'mapGridPosition', 'markAsFinishedOnSteam', 'markerAlpha', 'markerBrush', 'markerColor', 'markerDir', 'markerPos', 'markerShape', 'markerSize', 'markerText', 'markerType', 'max', 'members', 'min', 'mineActive', 'mineDetectedBy', 'missionConfigFile', 'missionName', 'missionNamespace', 'missionStart', 'mod', 'modelToWorld', 'modelToWorldVisual', 'moonIntensity', 'morale', 'move', 'moveInAny', 'moveInCargo', 'moveInCommander', 'moveInDriver', 'moveInGunner', 'moveInTurret', 'moveObjectToEnd', 'moveOut', 'moveTime', 'moveTo', 'moveToCompleted', 'moveToFailed', 'musicVolume', 'name', 'name location', 'nameSound', 'nearEntities', 'nearestBuilding', 'nearestLocation', 'nearestLocations', 'nearestLocationWithDubbing', 'nearestObject', 'nearestObjects', 'nearObjects', 'nearObjectsReady', 'nearRoads', 'nearSupplies', 'nearTargets', 'needReload', 'netId', 'netObjNull', 'newOverlay', 'nextMenuItemIndex', 'nextWeatherChange', 'nil', 'nMenuItems', 'not', 'numberToDate', 'objectCurators', 'objectFromNetId', 'objectParent', 'objNull', 'objStatus', 'onBriefingGroup', 'onBriefingNotes', 'onBriefingPlan', 'onBriefingTeamSwitch', 'onCommandModeChanged', 'onDoubleClick', 'onEachFrame', 'onGroupIconClick', 'onGroupIconOverEnter', 'onGroupIconOverLeave', 'onHCGroupSelectionChanged', 'onMapSingleClick', 'onPlayerConnected', 'onPlayerDisconnected', 'onPreloadFinished', 'onPreloadStarted', 'onShowNewObject', 'onTeamSwitch', 'openCuratorInterface', 'openMap', 'openYoutubeVideo', 'opfor', 'or', 'orderGetIn', 'overcast', 'overcastForecast', 'owner', 'param', 'params', 'parseNumber', 'parseText', 'parsingNamespace', 'particlesQuality', 'pi', 'pickWeaponPool', 'pitch', 'playableSlotsNumber', 'playableUnits', 'playAction', 'playActionNow', 'player', 'playerRespawnTime', 'playerSide', 'playersNumber', 'playGesture', 'playMission', 'playMove', 'playMoveNow', 'playMusic', 'playScriptedMission', 'playSound', 'playSound3D', 'position', 'positionCameraToWorld', 'posScreenToWorld', 'posWorldToScreen', 'ppEffectAdjust', 'ppEffectCommit', 'ppEffectCommitted', 'ppEffectCreate', 'ppEffectDestroy', 'ppEffectEnable', 'ppEffectForceInNVG', 'precision', 'preloadCamera', 'preloadObject', 'preloadSound', 'preloadTitleObj', 'preloadTitleRsc', 'preprocessFile', 'preprocessFileLineNumbers', 'primaryWeapon', 'primaryWeaponItems', 'primaryWeaponMagazine', 'priority', 'private', 'processDiaryLink', 'productVersion', 'profileName', 'profileNamespace', 'profileNameSteam', 'progressLoadingScreen', 'progressPosition', 'progressSetPosition', 'publicVariable', 'publicVariableClient', 'publicVariableServer', 'pushBack', 'putWeaponPool', 'queryItemsPool', 'queryMagazinePool', 'queryWeaponPool', 'rad', 'radioChannelAdd', 'radioChannelCreate', 'radioChannelRemove', 'radioChannelSetCallSign', 'radioChannelSetLabel', 'radioVolume', 'rain', 'rainbow', 'random', 'rank', 'rankId', 'rating', 'rectangular', 'registeredTasks', 'registerTask', 'reload', 'reloadEnabled', 'remoteControl', 'remoteExec', 'remoteExecCall', 'removeAction', 'removeAllActions', 'removeAllAssignedItems', 'removeAllContainers', 'removeAllCuratorAddons', 'removeAllCuratorCameraAreas', 'removeAllCuratorEditingAreas', 'removeAllEventHandlers', 'removeAllHandgunItems', 'removeAllItems', 'removeAllItemsWithMagazines', 'removeAllMissionEventHandlers', 'removeAllMPEventHandlers', 'removeAllMusicEventHandlers', 'removeAllPrimaryWeaponItems', 'removeAllWeapons', 'removeBackpack', 'removeBackpackGlobal', 'removeCuratorAddons', 'removeCuratorCameraArea', 'removeCuratorEditableObjects', 'removeCuratorEditingArea', 'removeDrawIcon', 'removeDrawLinks', 'removeEventHandler', 'removeFromRemainsCollector', 'removeGoggles', 'removeGroupIcon', 'removeHandgunItem', 'removeHeadgear', 'removeItem', 'removeItemFromBackpack', 'removeItemFromUniform', 'removeItemFromVest', 'removeItems', 'removeMagazine', 'removeMagazineGlobal', 'removeMagazines', 'removeMagazinesTurret', 'removeMagazineTurret', 'removeMenuItem', 'removeMissionEventHandler', 'removeMPEventHandler', 'removeMusicEventHandler', 'removePrimaryWeaponItem', 'removeSecondaryWeaponItem', 'removeSimpleTask', 'removeSwitchableUnit', 'removeTeamMember', 'removeUniform', 'removeVest', 'removeWeapon', 'removeWeaponGlobal', 'removeWeaponTurret', 'requiredVersion', 'resetCamShake', 'resetSubgroupDirection', 'resistance', 'resize', 'resources', 'respawnVehicle', 'restartEditorCamera', 'reveal', 'revealMine', 'reverse', 'reversedMouseY', 'roadsConnectedTo', 'roleDescription', 'ropeAttachedObjects', 'ropeAttachedTo', 'ropeAttachEnabled', 'ropeAttachTo', 'ropeCreate', 'ropeCut', 'ropeEndPosition', 'ropeLength', 'ropes', 'ropeUnwind', 'ropeUnwound', 'rotorsForcesRTD', 'rotorsRpmRTD', 'round', 'runInitScript', 'safeZoneH', 'safeZoneW', 'safeZoneWAbs', 'safeZoneX', 'safeZoneXAbs', 'safeZoneY', 'saveGame', 'saveIdentity', 'saveJoysticks', 'saveOverlay', 'saveProfileNamespace', 'saveStatus', 'saveVar', 'savingEnabled', 'say', 'say2D', 'say3D', 'scopeName', 'score', 'scoreSide', 'screenToWorld', 'scriptDone', 'scriptName', 'scriptNull', 'scudState', 'secondaryWeapon', 'secondaryWeaponItems', 'secondaryWeaponMagazine', 'select', 'selectBestPlaces', 'selectDiarySubject', 'selectedEditorObjects', 'selectEditorObject', 'selectionPosition', 'selectLeader', 'selectNoPlayer', 'selectPlayer', 'selectWeapon', 'selectWeaponTurret', 'sendAUMessage', 'sendSimpleCommand', 'sendTask', 'sendTaskResult', 'sendUDPMessage', 'serverCommand', 'serverCommandAvailable', 'serverCommandExecutable', 'serverName', 'serverTime', 'set', 'setAccTime', 'setAirportSide', 'setAmmo', 'setAmmoCargo', 'setAperture', 'setApertureNew', 'setArmoryPoints', 'setAttributes', 'setAutonomous', 'setBehaviour', 'setBleedingRemaining', 'setCameraInterest', 'setCamShakeDefParams', 'setCamShakeParams', 'setCamUseTi', 'setCaptive', 'setCenterOfMass', 'setCollisionLight', 'setCombatMode', 'setCompassOscillation', 'setCuratorCameraAreaCeiling', 'setCuratorCoef', 'setCuratorEditingAreaType', 'setCuratorWaypointCost', 'setCurrentChannel', 'setCurrentTask', 'setCurrentWaypoint', 'setDamage', 'setDammage', 'setDate', 'setDebriefingText', 'setDefaultCamera', 'setDestination', 'setDetailMapBlendPars', 'setDir', 'setDirection', 'setDrawIcon', 'setDropInterval', 'setEditorMode', 'setEditorObjectScope', 'setEffectCondition', 'setFace', 'setFaceAnimation', 'setFatigue', 'setFlagOwner', 'setFlagSide', 'setFlagTexture', 'setFog', 'setFog array', 'setFormation', 'setFormationTask', 'setFormDir', 'setFriend', 'setFromEditor', 'setFSMVariable', 'setFuel', 'setFuelCargo', 'setGroupIcon', 'setGroupIconParams', 'setGroupIconsSelectable', 'setGroupIconsVisible', 'setGroupId', 'setGroupIdGlobal', 'setGroupOwner', 'setGusts', 'setHideBehind', 'setHit', 'setHitIndex', 'setHitPointDamage', 'setHorizonParallaxCoef', 'setHUDMovementLevels', 'setIdentity', 'setImportance', 'setLeader', 'setLightAmbient', 'setLightAttenuation', 'setLightBrightness', 'setLightColor', 'setLightDayLight', 'setLightFlareMaxDistance', 'setLightFlareSize', 'setLightIntensity', 'setLightnings', 'setLightUseFlare', 'setLocalWindParams', 'setMagazineTurretAmmo', 'setMarkerAlpha', 'setMarkerAlphaLocal', 'setMarkerBrush', 'setMarkerBrushLocal', 'setMarkerColor', 'setMarkerColorLocal', 'setMarkerDir', 'setMarkerDirLocal', 'setMarkerPos', 'setMarkerPosLocal', 'setMarkerShape', 'setMarkerShapeLocal', 'setMarkerSize', 'setMarkerSizeLocal', 'setMarkerText', 'setMarkerTextLocal', 'setMarkerType', 'setMarkerTypeLocal', 'setMass', 'setMimic', 'setMousePosition', 'setMusicEffect', 'setMusicEventHandler', 'setName', 'setNameSound', 'setObjectArguments', 'setObjectMaterial', 'setObjectProxy', 'setObjectTexture', 'setObjectTextureGlobal', 'setObjectViewDistance', 'setOvercast', 'setOwner', 'setOxygenRemaining', 'setParticleCircle', 'setParticleClass', 'setParticleFire', 'setParticleParams', 'setParticleRandom', 'setPilotLight', 'setPiPEffect', 'setPitch', 'setPlayable', 'setPlayerRespawnTime', 'setPos', 'setPosASL', 'setPosASL2', 'setPosASLW', 'setPosATL', 'setPosition', 'setPosWorld', 'setRadioMsg', 'setRain', 'setRainbow', 'setRandomLip', 'setRank', 'setRectangular', 'setRepairCargo', 'setShadowDistance', 'setSide', 'setSimpleTaskDescription', 'setSimpleTaskDestination', 'setSimpleTaskTarget', 'setSimulWeatherLayers', 'setSize', 'setSkill', 'setSkill array', 'setSlingLoad', 'setSoundEffect', 'setSpeaker', 'setSpeech', 'setSpeedMode', 'setStatValue', 'setSuppression', 'setSystemOfUnits', 'setTargetAge', 'setTaskResult', 'setTaskState', 'setTerrainGrid', 'setText', 'setTimeMultiplier', 'setTitleEffect', 'setTriggerActivation', 'setTriggerArea', 'setTriggerStatements', 'setTriggerText', 'setTriggerTimeout', 'setTriggerType', 'setType', 'setUnconscious', 'setUnitAbility', 'setUnitPos', 'setUnitPosWeak', 'setUnitRank', 'setUnitRecoilCoefficient', 'setUnloadInCombat', 'setUserActionText', 'setVariable', 'setVectorDir', 'setVectorDirAndUp', 'setVectorUp', 'setVehicleAmmo', 'setVehicleAmmoDef', 'setVehicleArmor', 'setVehicleId', 'setVehicleLock', 'setVehiclePosition', 'setVehicleTiPars', 'setVehicleVarName', 'setVelocity', 'setVelocityTransformation', 'setViewDistance', 'setVisibleIfTreeCollapsed', 'setWaves', 'setWaypointBehaviour', 'setWaypointCombatMode', 'setWaypointCompletionRadius', 'setWaypointDescription', 'setWaypointFormation', 'setWaypointHousePosition', 'setWaypointLoiterRadius', 'setWaypointLoiterType', 'setWaypointName', 'setWaypointPosition', 'setWaypointScript', 'setWaypointSpeed', 'setWaypointStatements', 'setWaypointTimeout', 'setWaypointType', 'setWaypointVisible', 'setWeaponReloadingTime', 'setWind', 'setWindDir', 'setWindForce', 'setWindStr', 'setWPPos', 'show3DIcons', 'showChat', 'showCinemaBorder', 'showCommandingMenu', 'showCompass', 'showCuratorCompass', 'showGPS', 'showHUD', 'showLegend', 'showMap', 'shownArtilleryComputer', 'shownChat', 'shownCompass', 'shownCuratorCompass', 'showNewEditorObject', 'shownGPS', 'shownHUD', 'shownMap', 'shownPad', 'shownRadio', 'shownUAVFeed', 'shownWarrant', 'shownWatch', 'showPad', 'showRadio', 'showSubtitles', 'showUAVFeed', 'showWarrant', 'showWatch', 'showWaypoint', 'side', 'sideChat', 'sideEnemy', 'sideFriendly', 'sideLogic', 'sideRadio', 'sideUnknown', 'simpleTasks', 'simulationEnabled', 'simulCloudDensity', 'simulCloudOcclusion', 'simulInClouds', 'simulWeatherSync', 'sin', 'size', 'sizeOf', 'skill', 'skillFinal', 'skipTime', 'sleep', 'sliderPosition', 'sliderRange', 'sliderSetPosition', 'sliderSetRange', 'sliderSetSpeed', 'sliderSpeed', 'slingLoadAssistantShown', 'soldierMagazines', 'someAmmo', 'sort', 'soundVolume', 'spawn', 'speaker', 'speed', 'speedMode', 'splitString', 'sqrt', 'squadParams', 'stance', 'startLoadingScreen', 'step', 'stop', 'stopped', 'str', 'sunOrMoon', 'supportInfo', 'suppressFor', 'surfaceIsWater', 'surfaceNormal', 'surfaceType', 'swimInDepth', 'switch', 'switchableUnits', 'switchAction', 'switchCamera', 'switchGesture', 'switchLight', 'switchMove', 'synchronizedObjects', 'synchronizedTriggers', 'synchronizedWaypoints', 'synchronizeObjectsAdd', 'synchronizeObjectsRemove', 'synchronizeTrigger', 'synchronizeWaypoint', 'synchronizeWaypoint trigger', 'systemChat', 'systemOfUnits', 'tan', 'targetKnowledge', 'targetsAggregate', 'targetsQuery', 'taskChildren', 'taskCompleted', 'taskDescription', 'taskDestination', 'taskHint', 'taskNull', 'taskParent', 'taskResult', 'taskState', 'teamMember', 'teamMemberNull', 'teamName', 'teams', 'teamSwitch', 'teamSwitchEnabled', 'teamType', 'terminate', 'terrainIntersect', 'terrainIntersectASL', 'text', 'text location', 'textLog', 'textLogFormat', 'tg', 'then', 'throw', 'time', 'timeMultiplier', 'titleCut', 'titleFadeOut', 'titleObj', 'titleRsc', 'titleText', 'to', 'toArray', 'toLower', 'toString', 'toUpper', 'triggerActivated', 'triggerActivation', 'triggerArea', 'triggerAttachedVehicle', 'triggerAttachObject', 'triggerAttachVehicle', 'triggerStatements', 'triggerText', 'triggerTimeout', 'triggerTimeoutCurrent', 'triggerType', 'true', 'try', 'turretLocal', 'turretOwner', 'turretUnit', 'tvAdd', 'tvClear', 'tvCollapse', 'tvCount', 'tvCurSel', 'tvData', 'tvDelete', 'tvExpand', 'tvPicture', 'tvSetCurSel', 'tvSetData', 'tvSetPicture', 'tvSetPictureColor', 'tvSetTooltip', 'tvSetValue', 'tvSort', 'tvSortByValue', 'tvText', 'tvValue', 'type', 'typeName', 'typeOf', 'UAVControl', 'uiNamespace', 'uiSleep', 'unassignCurator', 'unassignItem', 'unassignTeam', 'unassignVehicle', 'underwater', 'uniform', 'uniformContainer', 'uniformItems', 'uniformMagazines', 'unitAddons', 'unitBackpack', 'unitPos', 'unitReady', 'unitRecoilCoefficient', 'units', 'unitsBelowHeight', 'unlinkItem', 'unlockAchievement', 'unregisterTask', 'updateDrawIcon', 'updateMenuItem', 'updateObjectTree', 'useAudioTimeForMoves', 'vectorAdd', 'vectorCos', 'vectorCrossProduct', 'vectorDiff', 'vectorDir', 'vectorDirVisual', 'vectorDistance', 'vectorDistanceSqr', 'vectorDotProduct', 'vectorFromTo', 'vectorMagnitude', 'vectorMagnitudeSqr', 'vectorMultiply', 'vectorNormalized', 'vectorUp', 'vectorUpVisual', 'vehicle', 'vehicleChat', 'vehicleRadio', 'vehicles', 'vehicleVarName', 'velocity', 'velocityModelSpace', 'verifySignature', 'vest', 'vestContainer', 'vestItems', 'vestMagazines', 'viewDistance', 'visibleCompass', 'visibleGPS', 'visibleMap', 'visiblePosition', 'visiblePositionASL', 'visibleWatch', 'waitUntil', 'waves', 'waypointAttachedObject', 'waypointAttachedVehicle', 'waypointAttachObject', 'waypointAttachVehicle', 'waypointBehaviour', 'waypointCombatMode', 'waypointCompletionRadius', 'waypointDescription', 'waypointFormation', 'waypointHousePosition', 'waypointLoiterRadius', 'waypointLoiterType', 'waypointName', 'waypointPosition', 'waypoints', 'waypointScript', 'waypointsEnabledUAV', 'waypointShow', 'waypointSpeed', 'waypointStatements', 'waypointTimeout', 'waypointTimeoutCurrent', 'waypointType', 'waypointVisible', 'weaponAccessories', 'weaponCargo', 'weaponDirection', 'weaponLowered', 'weapons', 'weaponsItems', 'weaponsItemsCargo', 'weaponState', 'weaponsTurret', 'weightRTD', 'west', 'WFSideText', 'while', 'wind', 'windDir', 'windStr', 'wingsForcesRTD', 'with', 'worldName', 'worldSize', 'worldToModel', 'worldToModelVisual', 'worldToScreen'];
  var control = ['case', 'catch', 'default', 'do', 'else', 'exit', 'exitWith|5', 'for', 'forEach', 'from', 'if', 'switch', 'then', 'throw', 'to', 'try', 'while', 'with'];
  var operators = ['!', '-', '+', '!=', '%', '&&', '*', '/', '=', '==', '>', '>=', '<', '<=', '^', ':', '>>'];
  var specials = ['_forEachIndex|10', '_this|10', '_x|10'];
  var literals = ['true', 'false', 'nil'];
  var builtins = allCommands.filter(function (command) {
    return control.indexOf(command) == -1 &&
        literals.indexOf(command) == -1 &&
        operators.indexOf(command) == -1;
  });
  //Note: operators will not be treated as builtins due to the lexeme rules
  builtins = builtins.concat(specials);

  // In SQF strings, quotes matching the start are escaped by adding a consecutive.
  // Example of single escaped quotes: " "" " and  ' '' '.
  var STRINGS = {
    className: 'string',
    relevance: 0,
    variants: [
      {
        begin: '"',
        end: '"',
        contains: [{begin: '""'}]
      },
      {
        begin: '\'',
        end: '\'',
        contains: [{begin: '\'\''}]
      }
    ]
  };

  var NUMBERS = {
    className: 'number',
    begin: hljs.NUMBER_RE,
    relevance: 0
  };

  // Preprocessor definitions borrowed from C++
  var PREPROCESSOR_STRINGS = {
    className: 'string',
    variants: [
      hljs.QUOTE_STRING_MODE,
      {
        begin: '\'\\\\?.', end: '\'',
        illegal: '.'
      }
    ]
  };

  var PREPROCESSOR =       {
    className: 'preprocessor',
    begin: '#', end: '$',
    keywords: 'if else elif endif define undef warning error line ' +
              'pragma ifdef ifndef',
    contains: [
      {
        begin: /\\\n/, relevance: 0
      },
      {
        beginKeywords: 'include', end: '$',
        contains: [
          PREPROCESSOR_STRINGS,
          {
            className: 'string',
            begin: '<', end: '>',
            illegal: '\\n',
          }
        ]
      },
      PREPROCESSOR_STRINGS,
      NUMBERS,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE
    ]
  };

  return {
    aliases: ['sqf'],
    case_insensitive: true,
    keywords: {
      keyword: control.join(' '),
      built_in: builtins.join(' '),
      literal: literals.join(' ')
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      NUMBERS,
      STRINGS,
      PREPROCESSOR
    ]
  };
});

hljs.registerLanguage('sql', function(hljs) {
  var COMMENT_MODE = hljs.COMMENT('--', '$');
  return {
    case_insensitive: true,
    illegal: /[<>{}*]/,
    contains: [
      {
        className: 'operator',
        beginKeywords:
          'begin end start commit rollback savepoint lock alter create drop rename call ' +
          'delete do handler insert load replace select truncate update set show pragma grant ' +
          'merge describe use explain help declare prepare execute deallocate release ' +
          'unlock purge reset change stop analyze cache flush optimize repair kill ' +
          'install uninstall checksum restore check backup revoke',
        end: /;/, endsWithParent: true,
        keywords: {
          keyword:
            'abort abs absolute acc acce accep accept access accessed accessible account acos action activate add ' +
            'addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias ' +
            'allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply ' +
            'archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan ' +
            'atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid ' +
            'authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile ' +
            'before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float ' +
            'binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound ' +
            'buffer_cache buffer_pool build bulk by byte byteordermark bytes c cache caching call calling cancel ' +
            'capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base ' +
            'char_length character_length characters characterset charindex charset charsetform charsetid check ' +
            'checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close ' +
            'cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation ' +
            'collect colu colum column column_value columns columns_updated comment commit compact compatibility ' +
            'compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn ' +
            'connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection ' +
            'consider consistent constant constraint constraints constructor container content contents context ' +
            'contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost ' +
            'count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation ' +
            'critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user ' +
            'cursor curtime customdatum cycle d data database databases datafile datafiles datalength date_add ' +
            'date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts ' +
            'day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate ' +
            'declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults ' +
            'deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank ' +
            'depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor ' +
            'deterministic diagnostics difference dimension direct_load directory disable disable_all ' +
            'disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div ' +
            'do document domain dotnet double downgrade drop dumpfile duplicate duration e each edition editionable ' +
            'editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt ' +
            'end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors ' +
            'escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding ' +
            'execu execut execute exempt exists exit exp expire explain export export_set extended extent external ' +
            'external_1 external_2 externally extract f failed failed_login_attempts failover failure far fast ' +
            'feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final ' +
            'finish first first_value fixed flash_cache flashback floor flush following follows for forall force ' +
            'form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ' +
            'ftp full function g general generated get get_format get_lock getdate getutcdate global global_name ' +
            'globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups ' +
            'gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex ' +
            'hierarchy high high_priority hosts hour http i id ident_current ident_incr ident_seed identified ' +
            'identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment ' +
            'index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile ' +
            'initial initialized initially initrans inmemory inner innodb input insert install instance instantiable ' +
            'instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat ' +
            'is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists ' +
            'k keep keep_duplicates key keys kill l language large last last_day last_insert_id last_value lax lcase ' +
            'lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit ' +
            'lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate ' +
            'locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call ' +
            'logoff logon logs long loop low low_priority lower lpad lrtrim ltrim m main make_set makedate maketime ' +
            'managed management manual map mapping mask master master_pos_wait match matched materialized max ' +
            'maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans ' +
            'md5 measures median medium member memcompress memory merge microsecond mid migration min minextents ' +
            'minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month ' +
            'months mount move movement multiset mutex n name name_const names nan national native natural nav nchar ' +
            'nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile ' +
            'nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile ' +
            'nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder ' +
            'nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck ' +
            'noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe ' +
            'nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ' +
            'ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old ' +
            'on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date ' +
            'oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary ' +
            'out outer outfile outline output over overflow overriding p package pad parallel parallel_enable ' +
            'parameters parent parse partial partition partitions pascal passing password password_grace_time ' +
            'password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex ' +
            'pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc ' +
            'performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin ' +
            'policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction ' +
            'prediction_cost prediction_details prediction_probability prediction_set prepare present preserve ' +
            'prior priority private private_sga privileges procedural procedure procedure_analyze processlist ' +
            'profiles project prompt protection public publishingservername purge quarter query quick quiesce quota ' +
            'quotename radians raise rand range rank raw read reads readsize rebuild record records ' +
            'recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh ' +
            'regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy ' +
            'reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename ' +
            'repair repeat replace replicate replication required reset resetlogs resize resource respect restore ' +
            'restricted result result_cache resumable resume retention return returning returns reuse reverse revoke ' +
            'right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows ' +
            'rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll ' +
            'sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select ' +
            'self sequence sequential serializable server servererror session session_user sessions_per_user set ' +
            'sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor ' +
            'si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin ' +
            'size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex ' +
            'source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows ' +
            'sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone ' +
            'standby start starting startup statement static statistics stats_binomial_test stats_crosstab ' +
            'stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep ' +
            'stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev ' +
            'stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate ' +
            'subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum ' +
            'suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate ' +
            'sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime t table tables tablespace tan tdo ' +
            'template temporary terminated tertiary_weights test than then thread through tier ties time time_format ' +
            'time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr ' +
            'timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking ' +
            'transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate ' +
            'try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress ' +
            'under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot ' +
            'unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert ' +
            'url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date ' +
            'utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var ' +
            'var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray ' +
            'verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear ' +
            'wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped ' +
            'xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces ' +
            'xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek',
          literal:
            'true false null',
          built_in:
            'array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number ' +
            'numeric real record serial serial8 smallint text varchar varying void'
        },
        contains: [
          {
            className: 'string',
            begin: '\'', end: '\'',
            contains: [hljs.BACKSLASH_ESCAPE, {begin: '\'\''}]
          },
          {
            className: 'string',
            begin: '"', end: '"',
            contains: [hljs.BACKSLASH_ESCAPE, {begin: '""'}]
          },
          {
            className: 'string',
            begin: '`', end: '`',
            contains: [hljs.BACKSLASH_ESCAPE]
          },
          hljs.C_NUMBER_MODE,
          hljs.C_BLOCK_COMMENT_MODE,
          COMMENT_MODE
        ]
      },
      hljs.C_BLOCK_COMMENT_MODE,
      COMMENT_MODE
    ]
  };
});

hljs.registerLanguage('stata', function(hljs) {
  return {
    aliases: ['do', 'ado'],
    case_insensitive: true,
    keywords: 'if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5',
        contains: [
      {
        className: 'label',
        variants: [
          {begin: "\\$\\{?[a-zA-Z0-9_]+\\}?"},
          {begin: "`[a-zA-Z0-9_]+'"}

        ]
      },
      {
        className: 'string',
        variants: [
          {begin: '`"[^\r\n]*?"\''},
          {begin: '"[^\r\n"]*"'}
        ]
      },

      {
        className: 'literal',
        variants: [
          {
            begin: '\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)'
          }
        ]
      },

      hljs.COMMENT('^[ \t]*\\*.*$', false),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE
    ]
  };
});

hljs.registerLanguage('step21', function(hljs) {
  var STEP21_IDENT_RE = '[A-Z_][A-Z0-9_.]*';
  var STEP21_CLOSE_RE = 'END-ISO-10303-21;';
  var STEP21_KEYWORDS = {
    literal: '',
    built_in: '',
    keyword:
    'HEADER ENDSEC DATA'
  };
  var STEP21_START = {
    className: 'preprocessor',
    begin: 'ISO-10303-21;',
    relevance: 10
  };
  var STEP21_CODE = [
    hljs.C_LINE_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
    hljs.COMMENT('/\\*\\*!', '\\*/'),
    hljs.C_NUMBER_MODE,
    hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
    hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}),
    {
      className: 'string',
      begin: "'", end: "'"
    },
    {
      className: 'label',
      variants: [
        {
          begin: '#', end: '\\d+',
          illegal: '\\W'
        }
      ]
    }
  ];

  return {
    aliases: ['p21', 'step', 'stp'],
    case_insensitive: true, // STEP 21 is case insensitive in theory, in practice all non-comments are capitalized.
    lexemes: STEP21_IDENT_RE,
    keywords: STEP21_KEYWORDS,
    contains: [
      {
        className: 'preprocessor',
        begin: STEP21_CLOSE_RE,
        relevance: 10
      },
      STEP21_START
    ].concat(STEP21_CODE)
  };
});

hljs.registerLanguage('stylus', function(hljs) {

  var VARIABLE = {
    className: 'variable',
    begin: '\\$' + hljs.IDENT_RE
  };

  var HEX_COLOR = {
    className: 'hexcolor',
    begin: '#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})',
    relevance: 10
  };

  var AT_KEYWORDS = [
    'charset',
    'css',
    'debug',
    'extend',
    'font-face',
    'for',
    'import',
    'include',
    'media',
    'mixin',
    'page',
    'warn',
    'while'
  ];

  var PSEUDO_SELECTORS = [
    'after',
    'before',
    'first-letter',
    'first-line',
    'active',
    'first-child',
    'focus',
    'hover',
    'lang',
    'link',
    'visited'
  ];

  var TAGS = [
    'a',
    'abbr',
    'address',
    'article',
    'aside',
    'audio',
    'b',
    'blockquote',
    'body',
    'button',
    'canvas',
    'caption',
    'cite',
    'code',
    'dd',
    'del',
    'details',
    'dfn',
    'div',
    'dl',
    'dt',
    'em',
    'fieldset',
    'figcaption',
    'figure',
    'footer',
    'form',
    'h1',
    'h2',
    'h3',
    'h4',
    'h5',
    'h6',
    'header',
    'hgroup',
    'html',
    'i',
    'iframe',
    'img',
    'input',
    'ins',
    'kbd',
    'label',
    'legend',
    'li',
    'mark',
    'menu',
    'nav',
    'object',
    'ol',
    'p',
    'q',
    'quote',
    'samp',
    'section',
    'span',
    'strong',
    'summary',
    'sup',
    'table',
    'tbody',
    'td',
    'textarea',
    'tfoot',
    'th',
    'thead',
    'time',
    'tr',
    'ul',
    'var',
    'video'
  ];

  var TAG_END = '[\\.\\s\\n\\[\\:,]';

  var ATTRIBUTES = [
    'align-content',
    'align-items',
    'align-self',
    'animation',
    'animation-delay',
    'animation-direction',
    'animation-duration',
    'animation-fill-mode',
    'animation-iteration-count',
    'animation-name',
    'animation-play-state',
    'animation-timing-function',
    'auto',
    'backface-visibility',
    'background',
    'background-attachment',
    'background-clip',
    'background-color',
    'background-image',
    'background-origin',
    'background-position',
    'background-repeat',
    'background-size',
    'border',
    'border-bottom',
    'border-bottom-color',
    'border-bottom-left-radius',
    'border-bottom-right-radius',
    'border-bottom-style',
    'border-bottom-width',
    'border-collapse',
    'border-color',
    'border-image',
    'border-image-outset',
    'border-image-repeat',
    'border-image-slice',
    'border-image-source',
    'border-image-width',
    'border-left',
    'border-left-color',
    'border-left-style',
    'border-left-width',
    'border-radius',
    'border-right',
    'border-right-color',
    'border-right-style',
    'border-right-width',
    'border-spacing',
    'border-style',
    'border-top',
    'border-top-color',
    'border-top-left-radius',
    'border-top-right-radius',
    'border-top-style',
    'border-top-width',
    'border-width',
    'bottom',
    'box-decoration-break',
    'box-shadow',
    'box-sizing',
    'break-after',
    'break-before',
    'break-inside',
    'caption-side',
    'clear',
    'clip',
    'clip-path',
    'color',
    'column-count',
    'column-fill',
    'column-gap',
    'column-rule',
    'column-rule-color',
    'column-rule-style',
    'column-rule-width',
    'column-span',
    'column-width',
    'columns',
    'content',
    'counter-increment',
    'counter-reset',
    'cursor',
    'direction',
    'display',
    'empty-cells',
    'filter',
    'flex',
    'flex-basis',
    'flex-direction',
    'flex-flow',
    'flex-grow',
    'flex-shrink',
    'flex-wrap',
    'float',
    'font',
    'font-family',
    'font-feature-settings',
    'font-kerning',
    'font-language-override',
    'font-size',
    'font-size-adjust',
    'font-stretch',
    'font-style',
    'font-variant',
    'font-variant-ligatures',
    'font-weight',
    'height',
    'hyphens',
    'icon',
    'image-orientation',
    'image-rendering',
    'image-resolution',
    'ime-mode',
    'inherit',
    'initial',
    'justify-content',
    'left',
    'letter-spacing',
    'line-height',
    'list-style',
    'list-style-image',
    'list-style-position',
    'list-style-type',
    'margin',
    'margin-bottom',
    'margin-left',
    'margin-right',
    'margin-top',
    'marks',
    'mask',
    'max-height',
    'max-width',
    'min-height',
    'min-width',
    'nav-down',
    'nav-index',
    'nav-left',
    'nav-right',
    'nav-up',
    'none',
    'normal',
    'object-fit',
    'object-position',
    'opacity',
    'order',
    'orphans',
    'outline',
    'outline-color',
    'outline-offset',
    'outline-style',
    'outline-width',
    'overflow',
    'overflow-wrap',
    'overflow-x',
    'overflow-y',
    'padding',
    'padding-bottom',
    'padding-left',
    'padding-right',
    'padding-top',
    'page-break-after',
    'page-break-before',
    'page-break-inside',
    'perspective',
    'perspective-origin',
    'pointer-events',
    'position',
    'quotes',
    'resize',
    'right',
    'tab-size',
    'table-layout',
    'text-align',
    'text-align-last',
    'text-decoration',
    'text-decoration-color',
    'text-decoration-line',
    'text-decoration-style',
    'text-indent',
    'text-overflow',
    'text-rendering',
    'text-shadow',
    'text-transform',
    'text-underline-position',
    'top',
    'transform',
    'transform-origin',
    'transform-style',
    'transition',
    'transition-delay',
    'transition-duration',
    'transition-property',
    'transition-timing-function',
    'unicode-bidi',
    'vertical-align',
    'visibility',
    'white-space',
    'widows',
    'width',
    'word-break',
    'word-spacing',
    'word-wrap',
    'z-index'
  ];

  // illegals
  var ILLEGAL = [
    '\\{',
    '\\}',
    '\\?',
    '(\\bReturn\\b)', // monkey
    '(\\bEnd\\b)', // monkey
    '(\\bend\\b)', // vbscript
    ';', // sql
    '#\\s', // markdown
    '\\*\\s', // markdown
    '===\\s', // markdown
    '\\|',
    '%', // prolog
  ];

  return {
    aliases: ['styl'],
    case_insensitive: false,
    illegal: '(' + ILLEGAL.join('|') + ')',
    keywords: 'if else for in',
    contains: [

      // strings
      hljs.QUOTE_STRING_MODE,
      hljs.APOS_STRING_MODE,

      // comments
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,

      // hex colors
      HEX_COLOR,

      // class tag
      {
        begin: '\\.[a-zA-Z][a-zA-Z0-9_-]*' + TAG_END,
        returnBegin: true,
        contains: [
          {className: 'class', begin: '\\.[a-zA-Z][a-zA-Z0-9_-]*'}
        ]
      },

      // id tag
      {
        begin: '\\#[a-zA-Z][a-zA-Z0-9_-]*' + TAG_END,
        returnBegin: true,
        contains: [
          {className: 'id', begin: '\\#[a-zA-Z][a-zA-Z0-9_-]*'}
        ]
      },

      // tags
      {
        begin: '\\b(' + TAGS.join('|') + ')' + TAG_END,
        returnBegin: true,
        contains: [
          {className: 'tag', begin: '\\b[a-zA-Z][a-zA-Z0-9_-]*'}
        ]
      },

      // psuedo selectors
      {
        className: 'pseudo',
        begin: '&?:?:\\b(' + PSEUDO_SELECTORS.join('|') + ')' + TAG_END
      },

      // @ keywords
      {
        className: 'at_rule',
        begin: '\@(' + AT_KEYWORDS.join('|') + ')\\b'
      },

      // variables
      VARIABLE,

      // dimension
      hljs.CSS_NUMBER_MODE,

      // number
      hljs.NUMBER_MODE,

      // functions
      //  - only from beginning of line + whitespace
      {
        className: 'function',
        begin: '\\b[a-zA-Z][a-zA-Z0-9_\-]*\\(.*\\)',
        illegal: '[\\n]',
        returnBegin: true,
        contains: [
          {className: 'title', begin: '\\b[a-zA-Z][a-zA-Z0-9_\-]*'},
          {
            className: 'params',
            begin: /\(/,
            end: /\)/,
            contains: [
              HEX_COLOR,
              VARIABLE,
              hljs.APOS_STRING_MODE,
              hljs.CSS_NUMBER_MODE,
              hljs.NUMBER_MODE,
              hljs.QUOTE_STRING_MODE
            ]
          }
        ]
      },

      // attributes
      //  - only from beginning of line + whitespace
      //  - must have whitespace after it
      {
        className: 'attribute',
        begin: '\\b(' + ATTRIBUTES.reverse().join('|') + ')\\b'
      }
    ]
  };
});

hljs.registerLanguage('swift', function(hljs) {
  var SWIFT_KEYWORDS = {
      keyword: '__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity ' +
        'break case catch class continue convenience default defer deinit didSet do ' +
        'dynamic dynamicType else enum extension fallthrough false final for func ' +
        'get guard if import in indirect infix init inout internal is lazy left let ' +
        'mutating nil none nonmutating operator optional override postfix precedence ' +
        'prefix private protocol Protocol public repeat required rethrows return ' +
        'right self Self set static struct subscript super switch throw throws true ' +
        'try try! try? Type typealias unowned var weak where while willSet',
      literal: 'true false nil',
      built_in: 'abs advance alignof alignofValue anyGenerator assert assertionFailure ' +
        'bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC ' +
        'bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros ' +
        'debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords ' +
        'enumerate equal fatalError filter find getBridgedObjectiveCType getVaList ' +
        'indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC ' +
        'isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare ' +
        'map max maxElement min minElement numericCast overlaps partition posix ' +
        'precondition preconditionFailure print println quickSort readLine reduce reflect ' +
        'reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split ' +
        'startsWith stride strideof strideofValue swap toString transcode ' +
        'underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap ' +
        'unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer ' +
        'withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers ' +
        'withUnsafePointer withUnsafePointers withVaList zip'
    };

  var TYPE = {
    className: 'type',
    begin: '\\b[A-Z][\\w\']*',
    relevance: 0
  };
  var BLOCK_COMMENT = hljs.COMMENT(
    '/\\*',
    '\\*/',
    {
      contains: ['self']
    }
  );
  var SUBST = {
    className: 'subst',
    begin: /\\\(/, end: '\\)',
    keywords: SWIFT_KEYWORDS,
    contains: [] // assigned later
  };
  var NUMBERS = {
      className: 'number',
      begin: '\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b',
      relevance: 0
  };
  var QUOTE_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {
    contains: [SUBST, hljs.BACKSLASH_ESCAPE]
  });
  SUBST.contains = [NUMBERS];

  return {
    keywords: SWIFT_KEYWORDS,
    contains: [
      QUOTE_STRING_MODE,
      hljs.C_LINE_COMMENT_MODE,
      BLOCK_COMMENT,
      TYPE,
      NUMBERS,
      {
        className: 'func',
        beginKeywords: 'func', end: '{', excludeEnd: true,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {
            begin: /[A-Za-z$_][0-9A-Za-z$_]*/,
            illegal: /\(/
          }),
          {
            className: 'generics',
            begin: /</, end: />/,
            illegal: />/
          },
          {
            className: 'params',
            begin: /\(/, end: /\)/, endsParent: true,
            keywords: SWIFT_KEYWORDS,
            contains: [
              'self',
              NUMBERS,
              QUOTE_STRING_MODE,
              hljs.C_BLOCK_COMMENT_MODE,
              {begin: ':'} // relevance booster
            ],
            illegal: /["']/
          }
        ],
        illegal: /\[|%/
      },
      {
        className: 'class',
        beginKeywords: 'struct protocol class extension enum',
        keywords: SWIFT_KEYWORDS,
        end: '\\{',
        excludeEnd: true,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {begin: /[A-Za-z$_][0-9A-Za-z$_]*/})
        ]
      },
      {
        className: 'preprocessor', // @attributes
        begin: '(@warn_unused_result|@exported|@lazy|@noescape|' +
                  '@NSCopying|@NSManaged|@objc|@convention|@required|' +
                  '@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|' +
                  '@infix|@prefix|@postfix|@autoclosure|@testable|@available|' +
                  '@nonobjc|@NSApplicationMain|@UIApplicationMain)'

      },
      {
        beginKeywords: 'import', end: /$/,
        contains: [hljs.C_LINE_COMMENT_MODE, BLOCK_COMMENT]
      }
    ]
  };
});

hljs.registerLanguage('tcl', function(hljs) {
  return {
    aliases: ['tk'],
    keywords: 'after append apply array auto_execok auto_import auto_load auto_mkindex ' +
      'auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock ' +
      'close concat continue dde dict encoding eof error eval exec exit expr fblocked ' +
      'fconfigure fcopy file fileevent filename flush for foreach format gets glob global ' +
      'history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list ' +
      'llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 '+
      'mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex '+
      'platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename '+
      'return safe scan seek set socket source split string subst switch tcl_endOfWord '+
      'tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter '+
      'tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update '+
      'uplevel upvar variable vwait while',
    contains: [
      hljs.COMMENT(';[ \\t]*#', '$'),
      hljs.COMMENT('^[ \\t]*#', '$'),
      {
        beginKeywords: 'proc',
        end: '[\\{]',
        excludeEnd: true,
        contains: [
          {
            className: 'symbol',
            begin: '[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*',
            end: '[ \\t\\n\\r]',
            endsWithParent: true,
            excludeEnd: true
          }
        ]
      },
      {
        className: 'variable',
        excludeEnd: true,
        variants: [
          {
            begin: '\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)',
            end: '[^a-zA-Z0-9_\\}\\$]'
          },
          {
            begin: '\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*',
            end: '(\\))?[^a-zA-Z0-9_\\}\\$]'
          }
        ]
      },
      {
        className: 'string',
        contains: [hljs.BACKSLASH_ESCAPE],
        variants: [
          hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
          hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null})
        ]
      },
      {
        className: 'number',
        variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]
      }
    ]
  }
});

hljs.registerLanguage('tex', function(hljs) {
  var COMMAND1 = {
    className: 'command',
    begin: '\\\\[a-zA-Zа-яА-я]+[\\*]?'
  };
  var COMMAND2 = {
    className: 'command',
    begin: '\\\\[^a-zA-Zа-яА-я0-9]'
  };
  var SPECIAL = {
    className: 'special',
    begin: '[{}\\[\\]\\&#~]',
    relevance: 0
  };

  return {
    contains: [
      { // parameter
        begin: '\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?',
        returnBegin: true,
        contains: [
          COMMAND1, COMMAND2,
          {
            className: 'number',
            begin: ' *=', end: '-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?',
            excludeBegin: true
          }
        ],
        relevance: 10
      },
      COMMAND1, COMMAND2,
      SPECIAL,
      {
        className: 'formula',
        begin: '\\$\\$', end: '\\$\\$',
        contains: [COMMAND1, COMMAND2, SPECIAL],
        relevance: 0
      },
      {
        className: 'formula',
        begin: '\\$', end: '\\$',
        contains: [COMMAND1, COMMAND2, SPECIAL],
        relevance: 0
      },
      hljs.COMMENT(
        '%',
        '$',
        {
          relevance: 0
        }
      )
    ]
  };
});

hljs.registerLanguage('thrift', function(hljs) {
  var BUILT_IN_TYPES = 'bool byte i16 i32 i64 double string binary';
  return {
    keywords: {
      keyword:
        'namespace const typedef struct enum service exception void oneway set list map required optional',
      built_in:
        BUILT_IN_TYPES,
      literal:
        'true false'
    },
    contains: [
      hljs.QUOTE_STRING_MODE,
      hljs.NUMBER_MODE,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'class',
        beginKeywords: 'struct enum service exception', end: /\{/,
        illegal: /\n/,
        contains: [
          hljs.inherit(hljs.TITLE_MODE, {
            starts: {endsWithParent: true, excludeEnd: true} // hack: eating everything after the first title
          })
        ]
      },
      {
        begin: '\\b(set|list|map)\\s*<', end: '>',
        keywords: BUILT_IN_TYPES,
        contains: ['self']
      }
    ]
  };
});

hljs.registerLanguage('tp', function(hljs) {
  var TPID = {
    className: 'number',
    begin: '[1-9][0-9]*', /* no leading zeros */
    relevance: 0
  };
  var TPLABEL = {
    className: 'comment',
    begin: ':[^\\]]+'
  };
  var TPDATA = {
    className: 'built_in',
    begin: '(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER|\
    TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\[', end: '\\]',
    contains: [
      'self',
      TPID,
      TPLABEL
    ]
  };
  var TPIO = {
    className: 'built_in',
    begin: '(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\[', end: '\\]',
    contains: [
      'self',
      TPID,
      hljs.QUOTE_STRING_MODE, /* for pos section at bottom */
      TPLABEL
    ]
  };

  return {
    keywords: {
      keyword:
        'ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB ' +
        'DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC ' +
        'IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE ' +
        'PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET ' +
        'Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN ' +
        'SUBSTR FINDSTR VOFFSET',
      constant:
        'ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET'
    },
    contains: [
      TPDATA,
      TPIO,
      {
        className: 'keyword',
        begin: '/(PROG|ATTR|MN|POS|END)\\b'
      },
      {
        /* this is for cases like ,CALL */
        className: 'keyword',
        begin: '(CALL|RUN|POINT_LOGIC|LBL)\\b'
      },
      {
        /* this is for cases like CNT100 where the default lexemes do not
         * separate the keyword and the number */
        className: 'keyword',
        begin: '\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)'
      },
      {
        /* to catch numbers that do not have a word boundary on the left */
        className: 'number',
        begin: '\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\b',
        relevance: 0
      },
      hljs.COMMENT('//', '[;$]'),
      hljs.COMMENT('!', '[;$]'),
      hljs.COMMENT('--eg:', '$'),
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        begin: '\'', end: '\''
      },
      hljs.C_NUMBER_MODE,
      {
        className: 'variable',
        begin: '\\$[A-Za-z0-9_]+'
      }
    ]
  };
});

hljs.registerLanguage('twig', function(hljs) {
  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)'
  };

  var FUNCTION_NAMES = 'attribute block constant cycle date dump include ' +
                  'max min parent random range source template_from_string';

  var FUNCTIONS = {
    className: 'function',
    beginKeywords: FUNCTION_NAMES,
    relevance: 0,
    contains: [
      PARAMS
    ]
  };

  var FILTER = {
    className: 'filter',
    begin: /\|[A-Za-z_]+:?/,
    keywords:
      'abs batch capitalize convert_encoding date date_modify default ' +
      'escape first format join json_encode keys last length lower ' +
      'merge nl2br number_format raw replace reverse round slice sort split ' +
      'striptags title trim upper url_encode',
    contains: [
      FUNCTIONS
    ]
  };

  var TAGS = 'autoescape block do embed extends filter flush for ' +
    'if import include macro sandbox set spaceless use verbatim';

  TAGS = TAGS + ' ' + TAGS.split(' ').map(function(t){return 'end' + t}).join(' ');

  return {
    aliases: ['craftcms'],
    case_insensitive: true,
    subLanguage: 'xml',
    contains: [
      hljs.COMMENT(/\{#/, /#}/),
      {
        className: 'template_tag',
        begin: /\{%/, end: /%}/,
        keywords: TAGS,
        contains: [FILTER, FUNCTIONS]
      },
      {
        className: 'variable',
        begin: /\{\{/, end: /}}/,
        contains: [FILTER, FUNCTIONS]
      }
    ]
  };
});

hljs.registerLanguage('typescript', function(hljs) {
  var KEYWORDS = {
    keyword:
      'in if for while finally var new function|0 do return void else break catch ' +
      'instanceof with throw case default try this switch continue typeof delete ' +
      'let yield const class public private protected get set super ' +
      'static implements enum export import declare type namespace abstract',
    literal:
      'true false null undefined NaN Infinity',
    built_in:
      'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent ' +
      'encodeURI encodeURIComponent escape unescape Object Function Boolean Error ' +
      'EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' +
      'TypeError URIError Number Math Date String RegExp Array Float32Array ' +
      'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' +
      'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' +
      'module console window document any number boolean string void'
  };

  return {
    aliases: ['ts'],
    keywords: KEYWORDS,
    contains: [
      {
        className: 'pi',
        begin: /^\s*['"]use strict['"]/,
        relevance: 0
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'number',
        variants: [
          { begin: '\\b(0[bB][01]+)' },
          { begin: '\\b(0[oO][0-7]+)' },
          { begin: hljs.C_NUMBER_RE }
        ],
        relevance: 0
      },
      { // "value" container
        begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
        keywords: 'return throw case',
        contains: [
          hljs.C_LINE_COMMENT_MODE,
          hljs.C_BLOCK_COMMENT_MODE,
          hljs.REGEXP_MODE
        ],
        relevance: 0
      },
      {
        className: 'function',
        begin: 'function', end: /[\{;]/, excludeEnd: true,
        keywords: KEYWORDS,
        contains: [
          'self',
          hljs.inherit(hljs.TITLE_MODE, {begin: /[A-Za-z$_][0-9A-Za-z$_]*/}),
          {
            className: 'params',
            begin: /\(/, end: /\)/,
            excludeBegin: true,
            excludeEnd: true,
            keywords: KEYWORDS,
            contains: [
              hljs.C_LINE_COMMENT_MODE,
              hljs.C_BLOCK_COMMENT_MODE
            ],
            illegal: /["'\(]/
          }
        ],
        illegal: /\[|%/,
        relevance: 0 // () => {} is more typical in TypeScript
      },
      {
        className: 'constructor',
        beginKeywords: 'constructor', end: /\{/, excludeEnd: true,
        relevance: 10
      },
      {
        className: 'module',
        beginKeywords: 'module', end: /\{/, excludeEnd: true
      },
      {
        className: 'interface',
        beginKeywords: 'interface', end: /\{/, excludeEnd: true,
        keywords: 'interface extends'
      },
      {
        begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
      },
      {
        begin: '\\.' + hljs.IDENT_RE, relevance: 0 // hack: prevents detection of keywords after dots
      }
    ]
  };
});

hljs.registerLanguage('vala', function(hljs) {
  return {
    keywords: {
      keyword:
        // Value types
        'char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 ' +
        'uint16 uint32 uint64 float double bool struct enum string void ' +
        // Reference types
        'weak unowned owned ' +
        // Modifiers
        'async signal static abstract interface override ' +
        // Control Structures
        'while do for foreach else switch case break default return try catch ' +
        // Visibility
        'public private protected internal ' +
        // Other
        'using new this get set const stdout stdin stderr var',
      built_in:
        'DBus GLib CCode Gee Object',
      literal:
        'false true null'
    },
    contains: [
      {
        className: 'class',
        beginKeywords: 'class interface delegate namespace', end: '{', excludeEnd: true,
        illegal: '[^,:\\n\\s\\.]',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'string',
        begin: '"""', end: '"""',
        relevance: 5
      },
      hljs.APOS_STRING_MODE,
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE,
      {
        className: 'preprocessor',
        begin: '^#', end: '$',
        relevance: 2
      },
      {
        className: 'constant',
        begin: ' [A-Z_]+ ',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('vbnet', function(hljs) {
  return {
    aliases: ['vb'],
    case_insensitive: true,
    keywords: {
      keyword:
        'addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval ' + /* a-b */
        'call case catch class compare const continue custom declare default delegate dim distinct do ' + /* c-d */
        'each equals else elseif end enum erase error event exit explicit finally for friend from function ' + /* e-f */
        'get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue ' + /* g-i */
        'join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass ' + /* j-m */
        'namespace narrowing new next not notinheritable notoverridable ' + /* n */
        'of off on operator option optional or order orelse overloads overridable overrides ' + /* o */
        'paramarray partial preserve private property protected public ' + /* p */
        'raiseevent readonly redim rem removehandler resume return ' + /* r */
        'select set shadows shared skip static step stop structure strict sub synclock ' + /* s */
        'take text then throw to try unicode until using when where while widening with withevents writeonly xor', /* t-x */
      built_in:
        'boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype ' +  /* b-c */
        'date decimal directcast double gettype getxmlnamespace iif integer long object ' + /* d-o */
        'sbyte short single string trycast typeof uinteger ulong ushort', /* s-u */
      literal:
        'true false nothing'
    },
    illegal: '//|{|}|endif|gosub|variant|wend', /* reserved deprecated keywords */
    contains: [
      hljs.inherit(hljs.QUOTE_STRING_MODE, {contains: [{begin: '""'}]}),
      hljs.COMMENT(
        '\'',
        '$',
        {
          returnBegin: true,
          contains: [
            {
              className: 'xmlDocTag',
              begin: '\'\'\'|<!--|-->',
              contains: [hljs.PHRASAL_WORDS_MODE]
            },
            {
              className: 'xmlDocTag',
              begin: '</?', end: '>',
              contains: [hljs.PHRASAL_WORDS_MODE]
            }
          ]
        }
      ),
      hljs.C_NUMBER_MODE,
      {
        className: 'preprocessor',
        begin: '#', end: '$',
        keywords: 'if else elseif end region externalsource'
      }
    ]
  };
});

hljs.registerLanguage('vbscript', function(hljs) {
  return {
    aliases: ['vbs'],
    case_insensitive: true,
    keywords: {
      keyword:
        'call class const dim do loop erase execute executeglobal exit for each next function ' +
        'if then else on error option explicit new private property let get public randomize ' +
        'redim rem select case set stop sub while wend with end to elseif is or xor and not ' +
        'class_initialize class_terminate default preserve in me byval byref step resume goto',
      built_in:
        'lcase month vartype instrrev ubound setlocale getobject rgb getref string ' +
        'weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency ' +
        'conversions csng timevalue second year space abs clng timeserial fixs len asc ' +
        'isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate ' +
        'instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex ' +
        'chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim ' +
        'strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion ' +
        'scriptengine split scriptengineminorversion cint sin datepart ltrim sqr ' +
        'scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw ' +
        'chrw regexp server response request cstr err',
      literal:
        'true false null nothing empty'
    },
    illegal: '//',
    contains: [
      hljs.inherit(hljs.QUOTE_STRING_MODE, {contains: [{begin: '""'}]}),
      hljs.COMMENT(
        /'/,
        /$/,
        {
          relevance: 0
        }
      ),
      hljs.C_NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('vbscript-html', function(hljs) {
  return {
    subLanguage: 'xml',
    contains: [
      {
        begin: '<%', end: '%>',
        subLanguage: 'vbscript'
      }
    ]
  };
});

hljs.registerLanguage('verilog', function(hljs) {
  return {
    aliases: ['v'],
    case_insensitive: true,
    keywords: {
      keyword:
        'always and assign begin buf bufif0 bufif1 case casex casez cmos deassign ' +
        'default defparam disable edge else end endcase endfunction endmodule ' +
        'endprimitive endspecify endtable endtask event for force forever fork ' +
        'function if ifnone initial inout input join macromodule module nand ' +
        'negedge nmos nor not notif0 notif1 or output parameter pmos posedge ' +
        'primitive pulldown pullup rcmos release repeat rnmos rpmos rtran ' +
        'rtranif0 rtranif1 specify specparam table task timescale tran ' +
        'tranif0 tranif1 wait while xnor xor',
      typename:
        'highz0 highz1 integer large medium pull0 pull1 real realtime reg ' +
        'scalared signed small strong0 strong1 supply0 supply0 supply1 supply1 ' +
        'time tri tri0 tri1 triand trior trireg vectored wand weak0 weak1 wire wor'
    },
    contains: [
      hljs.C_BLOCK_COMMENT_MODE,
      hljs.C_LINE_COMMENT_MODE,
      hljs.QUOTE_STRING_MODE,
      {
        className: 'number',
        begin: '\\b(\\d+\'(b|h|o|d|B|H|O|D))?[0-9xzXZ]+',
        contains: [hljs.BACKSLASH_ESCAPE],
        relevance: 0
      },
      /* ports in instances */
      {
        className: 'typename',
        begin: '\\.\\w+',
        relevance: 0
      },
      /* parameters to instances */
      {
        className: 'value',
        begin: '#\\((?!parameter).+\\)'
      },
      /* operators */
      {
        className: 'keyword',
        begin: '\\+|-|\\*|/|%|<|>|=|#|`|\\!|&|\\||@|:|\\^|~|\\{|\\}',
        relevance: 0
      }
    ]
  }; // return
});

hljs.registerLanguage('vhdl', function(hljs) {
  // Regular expression for VHDL numeric literals.

  // Decimal literal:
  var INTEGER_RE = '\\d(_|\\d)*';
  var EXPONENT_RE = '[eE][-+]?' + INTEGER_RE;
  var DECIMAL_LITERAL_RE = INTEGER_RE + '(\\.' + INTEGER_RE + ')?' + '(' + EXPONENT_RE + ')?';
  // Based literal:
  var BASED_INTEGER_RE = '\\w+';
  var BASED_LITERAL_RE = INTEGER_RE + '#' + BASED_INTEGER_RE + '(\\.' + BASED_INTEGER_RE + ')?' + '#' + '(' + EXPONENT_RE + ')?';

  var NUMBER_RE = '\\b(' + BASED_LITERAL_RE + '|' + DECIMAL_LITERAL_RE + ')';

  return {
    case_insensitive: true,
    keywords: {
      keyword:
        'abs access after alias all and architecture array assert attribute begin block ' +
        'body buffer bus case component configuration constant context cover disconnect ' +
        'downto default else elsif end entity exit fairness file for force function generate ' +
        'generic group guarded if impure in inertial inout is label library linkage literal ' +
        'loop map mod nand new next nor not null of on open or others out package port ' +
        'postponed procedure process property protected pure range record register reject ' +
        'release rem report restrict restrict_guarantee return rol ror select sequence ' +
        'severity shared signal sla sll sra srl strong subtype then to transport type ' +
        'unaffected units until use variable vmode vprop vunit wait when while with xnor xor',
      typename:
        'boolean bit character severity_level integer time delay_length natural positive ' +
        'string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector ' +
        'std_logic std_logic_vector unsigned signed boolean_vector integer_vector ' +
        'real_vector time_vector'
    },
    illegal: '{',
    contains: [
      hljs.C_BLOCK_COMMENT_MODE,        // VHDL-2008 block commenting.
      hljs.COMMENT('--', '$'),
      hljs.QUOTE_STRING_MODE,
      {
        className: 'number',
        begin: NUMBER_RE,
        relevance: 0
      },
      {
        className: 'literal',
        begin: '\'(U|X|0|1|Z|W|L|H|-)\'',
        contains: [hljs.BACKSLASH_ESCAPE]
      },
      {
        className: 'attribute',
        begin: '\'[A-Za-z](_?[A-Za-z0-9])*',
        contains: [hljs.BACKSLASH_ESCAPE]
      }
    ]
  };
});

hljs.registerLanguage('vim', function(hljs) {
  return {
    lexemes: /[!#@\w]+/,
    keywords: {
      keyword: //ex command
        // express version except: ! & * < = > !! # @ @@
        'N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope '+
        'cp cpf cq cr cs cst cu cuna cunme cw d|0 delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu g|0 go gr grepa gu gv ha h|0 helpf helpg helpt hi hid his i|0 ia iabc if ij il im imapc '+
        'ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs n|0 new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 '+
        'profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf q|0 quita qa r|0 rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv s|0 sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor '+
        'so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync t|0 tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew '+
        'tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up v|0 ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ '+
        // full version
        'Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload '+
        'bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap '+
        'cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor '+
        'endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap '+
        'imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview '+
        'lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap '+
        'nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext '+
        'ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding '+
        'scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace '+
        'startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious '+'trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew '+
        'vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank',
      built_in: //built in func
        'abs acos add and append argc argidx argv asin atan atan2 browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call ceil changenr char2nr cindent clearmatches col complete complete_add complete_check confirm copy cos cosh count cscope_connection cursor '+
        'deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists exp expand extend feedkeys filereadable filewritable filter finddir findfile float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function '+
        'garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getmatches getpid getpos getqflist getreg getregtype gettabvar gettabwinvar getwinposx getwinposy getwinvar glob globpath has has_key '+
        'haslocaldir hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert invert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime log log10 luaeval map maparg mapcheck '+
        'match matchadd matcharg matchdelete matchend matchlist matchstr max min mkdir mode mzeval nextnonblank nr2char or pathshorten pow prevnonblank printf pumvisible py3eval pyeval range readfile reltime reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat '+
        'resolve reverse round screenattr screenchar screencol screenrow search searchdecl searchpair searchpairpos searchpos server2client serverlist setbufvar setcmdpos setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar setwinvar sha256 shellescape shiftwidth simplify sin '+
        'sinh sort soundfold spellbadword spellsuggest split sqrt str2float str2nr strchars strdisplaywidth strftime stridx string strlen strpart strridx strtrans strwidth submatch substitute synconcealed synID synIDattr '+
        'synIDtrans synstack system tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname tolower toupper tr trunc type undofile undotree values virtcol visualmode wildmenumode winbufnr wincol winheight winline winnr winrestcmd winrestview winsaveview winwidth writefile xor'
    },
    illegal: /[{:]/,
    contains: [
      hljs.NUMBER_MODE,
      hljs.APOS_STRING_MODE,
      {
        className: 'string',
        // quote with escape, comment as quote
        begin: /"((\\")|[^"\n])*("|\n)/
      },
      {
        className: 'variable',
        begin: /[bwtglsav]:[\w\d_]*/
      },
      {
        className: 'function',
        beginKeywords: 'function function!', end: '$',
        relevance: 0,
        contains: [
          hljs.TITLE_MODE,
          {
            className: 'params',
            begin: '\\(', end: '\\)'
          }
        ]
      }
    ]
  };
});

hljs.registerLanguage('x86asm', function(hljs) {
  return {
    case_insensitive: true,
    lexemes: '\\.?' + hljs.IDENT_RE,
    keywords: {
      keyword:
        'lock rep repe repz repne repnz xaquire xrelease bnd nobnd ' +
        'aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63',
      literal:
        // Instruction pointer
        'ip eip rip ' +
        // 8-bit registers
        'al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ' +
        // 16-bit registers
        'ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w ' +
        // 32-bit registers
        'eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d ' +
        // 64-bit registers
        'rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 ' +
        // Segment registers
        'cs ds es fs gs ss ' +
        // Floating point stack registers
        'st st0 st1 st2 st3 st4 st5 st6 st7 ' +
        // MMX Registers
        'mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 ' +
        // SSE registers
        'xmm0  xmm1  xmm2  xmm3  xmm4  xmm5  xmm6  xmm7  xmm8  xmm9 xmm10  xmm11 xmm12 xmm13 xmm14 xmm15 ' +
        'xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ' +
        // AVX registers
        'ymm0  ymm1  ymm2  ymm3  ymm4  ymm5  ymm6  ymm7  ymm8  ymm9 ymm10  ymm11 ymm12 ymm13 ymm14 ymm15 ' +
        'ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 ' +
        // AVX-512F registers
        'zmm0  zmm1  zmm2  zmm3  zmm4  zmm5  zmm6  zmm7  zmm8  zmm9 zmm10  zmm11 zmm12 zmm13 zmm14 zmm15 ' +
        'zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 ' +
        // AVX-512F mask registers
        'k0 k1 k2 k3 k4 k5 k6 k7 ' +
        // Bound (MPX) register
        'bnd0 bnd1 bnd2 bnd3 ' +
        // Special register
        'cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 ' +
        // NASM altreg package
        'r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b ' +
        'r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d ' +
        'r0h r1h r2h r3h ' +
        'r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l',

      pseudo:
        'db dw dd dq dt ddq do dy dz ' +
        'resb resw resd resq rest resdq reso resy resz ' +
        'incbin equ times',

      preprocessor:
        '%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif ' +
        '%ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep ' +
        '%endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment ' +
        '.nolist ' +
        'byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr ' +
        '__FILE__ __LINE__ __SECT__  __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ ' +
        '__UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__  __PASS__ struc endstruc istruc at iend ' +
        'align alignb sectalign daz nodaz up down zero default option assume public ',

      built_in:
        'bits use16 use32 use64 default section segment absolute extern global common cpu float ' +
        '__utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ ' +
        '__float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ ' +
        '__Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e ' +
        'float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__'
    },
    contains: [
      hljs.COMMENT(
        ';',
        '$',
        {
          relevance: 0
        }
      ),
      {
        className: 'number',
        variants: [
          // Float number and x87 BCD
          {
            begin: '\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|' +
                   '(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b',
            relevance: 0
          },

          // Hex number in $
          { begin: '\\$[0-9][0-9A-Fa-f]*', relevance: 0 },

          // Number in H,D,T,Q,O,B,Y suffix
          { begin: '\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b' },

          // Number in X,D,T,Q,O,B,Y prefix
          { begin: '\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b'}
        ]
      },
      // Double quote string
      hljs.QUOTE_STRING_MODE,
      {
        className: 'string',
        variants: [
          // Single-quoted string
          { begin: '\'', end: '[^\\\\]\'' },
          // Backquoted string
          { begin: '`', end: '[^\\\\]`' },
          // Section name
          { begin: '\\.[A-Za-z0-9]+' }
        ],
        relevance: 0
      },
      {
        className: 'label',
        variants: [
          // Global label and local label
          { begin: '^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)' },
          // Macro-local label
          { begin: '^\\s*%%[A-Za-z0-9_$#@~.?]*:' }
        ],
        relevance: 0
      },
      // Macro parameter
      {
        className: 'argument',
        begin: '%[0-9]+',
        relevance: 0
      },
      // Macro parameter
      {
        className: 'built_in',
        begin: '%!\S+',
        relevance: 0
      }
    ]
  };
});

hljs.registerLanguage('xl', function(hljs) {
  var BUILTIN_MODULES =
    'ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo ' +
    'StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts';

  var XL_KEYWORDS = {
    keyword: 'if then else do while until for loop import with is as where when by data constant',
    literal: 'true false nil',
    type: 'integer real text name boolean symbol infix prefix postfix block tree',
    built_in: 'in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at',
    module: BUILTIN_MODULES,
    id:
      'text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle ' +
      'fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture ' +
      'scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle ' +
      'circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x ' +
      'mouse_?y mouse_buttons'
  };

  var XL_CONSTANT = {
    className: 'constant',
    begin: '[A-Z][A-Z_0-9]+',
    relevance: 0
  };
  var XL_VARIABLE = {
    className: 'variable',
    begin: '([A-Z][a-z_0-9]+)+',
    relevance: 0
  };
  var XL_ID = {
    className: 'id',
    begin: '[a-z][a-z_0-9]+',
    relevance: 0
  };

  var DOUBLE_QUOTE_TEXT = {
    className: 'string',
    begin: '"', end: '"', illegal: '\\n'
  };
  var SINGLE_QUOTE_TEXT = {
    className: 'string',
    begin: '\'', end: '\'', illegal: '\\n'
  };
  var LONG_TEXT = {
    className: 'string',
    begin: '<<', end: '>>'
  };
  var BASED_NUMBER = {
    className: 'number',
    begin: '[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?',
    relevance: 10
  };
  var IMPORT = {
    className: 'import',
    beginKeywords: 'import', end: '$',
    keywords: {
      keyword: 'import',
      module: BUILTIN_MODULES
    },
    relevance: 0,
    contains: [DOUBLE_QUOTE_TEXT]
  };
  var FUNCTION_DEFINITION = {
    className: 'function',
    begin: '[a-z].*->'
  };
  return {
    aliases: ['tao'],
    lexemes: /[a-zA-Z][a-zA-Z0-9_?]*/,
    keywords: XL_KEYWORDS,
    contains: [
    hljs.C_LINE_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
    DOUBLE_QUOTE_TEXT,
    SINGLE_QUOTE_TEXT,
    LONG_TEXT,
    FUNCTION_DEFINITION,
    IMPORT,
    XL_CONSTANT,
    XL_VARIABLE,
    XL_ID,
    BASED_NUMBER,
    hljs.NUMBER_MODE
    ]
  };
});

hljs.registerLanguage('xquery', function(hljs) {
  var KEYWORDS = 'for let if while then else return where group by xquery encoding version' +
    'module namespace boundary-space preserve strip default collation base-uri ordering' +
    'copy-namespaces order declare import schema namespace function option in allowing empty' +
    'at tumbling window sliding window start when only end when previous next stable ascending' +
    'descending empty greatest least some every satisfies switch case typeswitch try catch and' +
    'or to union intersect instance of treat as castable cast map array delete insert into' +
    'replace value rename copy modify update';
  var LITERAL = 'false true xs:string xs:integer element item xs:date xs:datetime xs:float xs:double xs:decimal QName xs:anyURI xs:long xs:int xs:short xs:byte attribute';
  var VAR = {
    className: 'variable',
    begin: /\$[a-zA-Z0-9\-]+/,
    relevance: 5
  };

  var NUMBER = {
    className: 'number',
    begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
    relevance: 0
  };

  var STRING = {
    className: 'string',
    variants: [
      {begin: /"/, end: /"/, contains: [{begin: /""/, relevance: 0}]},
      {begin: /'/, end: /'/, contains: [{begin: /''/, relevance: 0}]}
    ]
  };

  var ANNOTATION = {
    className: 'decorator',
    begin: '%\\w+'
  };

  var COMMENT = {
    className: 'comment',
    begin: '\\(:', end: ':\\)',
    relevance: 10,
    contains: [
      {
        className: 'doc', begin: '@\\w+'
      }
    ]
  };

  var METHOD = {
    begin: '{', end: '}'
  };

  var CONTAINS = [
    VAR,
    STRING,
    NUMBER,
    COMMENT,
    ANNOTATION,
    METHOD
  ];
  METHOD.contains = CONTAINS;


  return {
    aliases: ['xpath', 'xq'],
    case_insensitive: false,
    lexemes: /[a-zA-Z\$][a-zA-Z0-9_:\-]*/,
    illegal: /(proc)|(abstract)|(extends)|(until)|(#)/,
    keywords: {
      keyword: KEYWORDS,
      literal: LITERAL
    },
    contains: CONTAINS
  };
});

hljs.registerLanguage('zephir', function(hljs) {
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE],
    variants: [
      {
        begin: 'b"', end: '"'
      },
      {
        begin: 'b\'', end: '\''
      },
      hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
      hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null})
    ]
  };
  var NUMBER = {variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]};
  return {
    aliases: ['zep'],
    case_insensitive: true,
    keywords:
    'and include_once list abstract global private echo interface as static endswitch ' +
    'array null if endwhile or const for endforeach self var let while isset public ' +
    'protected exit foreach throw elseif include __FILE__ empty require_once do xor ' +
    'return parent clone use __CLASS__ __LINE__ else break print eval new ' +
    'catch __METHOD__ case exception default die require __FUNCTION__ ' +
    'enddeclare final try switch continue endfor endif declare unset true false ' +
    'trait goto instanceof insteadof __DIR__ __NAMESPACE__ ' +
    'yield finally int uint long ulong char uchar double float bool boolean string' +
    'likely unlikely',
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.HASH_COMMENT_MODE,
      hljs.COMMENT(
        '/\\*',
        '\\*/',
        {
          contains: [
            {
              className: 'doctag',
              begin: '@[A-Za-z]+'
            }
          ]
        }
      ),
      hljs.COMMENT(
        '__halt_compiler.+?;',
        false,
        {
          endsWithParent: true,
          keywords: '__halt_compiler',
          lexemes: hljs.UNDERSCORE_IDENT_RE
        }
      ),
      {
        className: 'string',
        begin: '<<<[\'"]?\\w+[\'"]?$', end: '^\\w+;',
        contains: [hljs.BACKSLASH_ESCAPE]
      },
      {
        // swallow composed identifiers to avoid parsing them as keywords
        begin: /(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/
      },
      {
        className: 'function',
        beginKeywords: 'function', end: /[;{]/, excludeEnd: true,
        illegal: '\\$|\\[|%',
        contains: [
          hljs.UNDERSCORE_TITLE_MODE,
          {
            className: 'params',
            begin: '\\(', end: '\\)',
            contains: [
              'self',
              hljs.C_BLOCK_COMMENT_MODE,
              STRING,
              NUMBER
            ]
          }
        ]
      },
      {
        className: 'class',
        beginKeywords: 'class interface', end: '{', excludeEnd: true,
        illegal: /[:\(\$"]/,
        contains: [
          {beginKeywords: 'extends implements'},
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      {
        beginKeywords: 'namespace', end: ';',
        illegal: /[\.']/,
        contains: [hljs.UNDERSCORE_TITLE_MODE]
      },
      {
        beginKeywords: 'use', end: ';',
        contains: [hljs.UNDERSCORE_TITLE_MODE]
      },
      {
        begin: '=>' // No markup, just a relevance booster
      },
      STRING,
      NUMBER
    ]
  };
});

  return hljs;
}));

/**
* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
*  
* Version - 0.99.00.beta 
* Copyright (c) 2012 Vadim Kiryukhin
* vkiryukhin @ gmail.com
* http://www.eslinstructor.net/vkbeautify/
* 
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
*   Pretty print
*
*        vkbeautify.xml(text [,indent_pattern]);
*        vkbeautify.json(text [,indent_pattern]);
*        vkbeautify.css(text [,indent_pattern]);
*        vkbeautify.sql(text [,indent_pattern]);
*
*        @text - String; text to beatufy;
*        @indent_pattern - Integer | String;
*                Integer:  number of white spaces;
*                String:   character string to visualize indentation ( can also be a set of white spaces )
*   Minify
*
*        vkbeautify.xmlmin(text [,preserve_comments]);
*        vkbeautify.jsonmin(text);
*        vkbeautify.cssmin(text [,preserve_comments]);
*        vkbeautify.sqlmin(text);
*
*        @text - String; text to minify;
*        @preserve_comments - Bool; [optional];
*                Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
*
*   Examples:
*        vkbeautify.xml(text); // pretty print XML
*        vkbeautify.json(text, 4 ); // pretty print JSON
*        vkbeautify.css(text, '. . . .'); // pretty print CSS
*        vkbeautify.sql(text, '----'); // pretty print SQL
*
*        vkbeautify.xmlmin(text, true);// minify XML, preserve comments
*        vkbeautify.jsonmin(text);// minify JSON
*        vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
*        vkbeautify.sqlmin(text);// minify SQL
*
*/

(function() {

function createShiftArr(step) {

	var space = '    ';
	
	if ( isNaN(parseInt(step)) ) {  // argument is string
		space = step;
	} else { // argument is integer
		switch(step) {
			case 1: space = ' '; break;
			case 2: space = '  '; break;
			case 3: space = '   '; break;
			case 4: space = '    '; break;
			case 5: space = '     '; break;
			case 6: space = '      '; break;
			case 7: space = '       '; break;
			case 8: space = '        '; break;
			case 9: space = '         '; break;
			case 10: space = '          '; break;
			case 11: space = '           '; break;
			case 12: space = '            '; break;
		}
	}

	var shift = ['\n']; // array of shifts
	for(ix=0;ix<100;ix++){
		shift.push(shift[ix]+space); 
	}
	return shift;
}

function vkbeautify(){
	this.step = '    '; // 4 spaces
	this.shift = createShiftArr(this.step);
};

vkbeautify.prototype.xml = function(text,step) {

	var ar = text.replace(/>\s{0,}</g,"><")
				 .replace(/</g,"~::~<")
				 .replace(/\s*xmlns\:/g,"~::~xmlns:")
				 .replace(/\s*xmlns\=/g,"~::~xmlns=")
				 .split('~::~'),
		len = ar.length,
		inComment = false,
		deep = 0,
		str = '',
		ix = 0,
		shift = step ? createShiftArr(step) : this.shift;

		for(ix=0;ix<len;ix++) {
			// start comment or <![CDATA[...]]> or <!DOCTYPE //
			if(ar[ix].search(/<!/) > -1) { 
				str += shift[deep]+ar[ix];
				inComment = true; 
				// end comment  or <![CDATA[...]]> //
				if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) { 
					inComment = false; 
				}
			} else 
			// end comment  or <![CDATA[...]]> //
			if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) { 
				str += ar[ix];
				inComment = false; 
			} else 
			// <elm></elm> //
			if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
				/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) { 
				str += ar[ix];
				if(!inComment) deep--;
			} else
			 // <elm> //
			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
				str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
			} else 
			 // <elm>...</elm> //
			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
			} else 
			// </elm> //
			if(ar[ix].search(/<\//) > -1) { 
				str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
			} else 
			// <elm/> //
			if(ar[ix].search(/\/>/) > -1 ) { 
				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
			} else 
			// <? xml ... ?> //
			if(ar[ix].search(/<\?/) > -1) { 
				str += shift[deep]+ar[ix];
			} else 
			// xmlns //
			if( ar[ix].search(/xmlns\:/) > -1  || ar[ix].search(/xmlns\=/) > -1) { 
				str += shift[deep]+ar[ix];
			} 
			
			else {
				str += ar[ix];
			}
		}
		
	return  (str[0] == '\n') ? str.slice(1) : str;
}

vkbeautify.prototype.json = function(text,step) {

	var step = step ? step : this.step;
	
	if (typeof JSON === 'undefined' ) return text; 
	
	if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
	if ( typeof text === "object" ) return JSON.stringify(text, null, step);
		
	return text; // text is not string nor object
}

vkbeautify.prototype.css = function(text, step) {

	var ar = text.replace(/\s{1,}/g,' ')
				.replace(/\{/g,"{~::~")
				.replace(/\}/g,"~::~}~::~")
				.replace(/\;/g,";~::~")
				.replace(/\/\*/g,"~::~/*")
				.replace(/\*\//g,"*/~::~")
				.replace(/~::~\s{0,}~::~/g,"~::~")
				.split('~::~'),
		len = ar.length,
		deep = 0,
		str = '',
		ix = 0,
		shift = step ? createShiftArr(step) : this.shift;
		
		for(ix=0;ix<len;ix++) {

			if( /\{/.exec(ar[ix]))  { 
				str += shift[deep++]+ar[ix];
			} else 
			if( /\}/.exec(ar[ix]))  { 
				str += shift[--deep]+ar[ix];
			} else
			if( /\*\\/.exec(ar[ix]))  { 
				str += shift[deep]+ar[ix];
			}
			else {
				str += shift[deep]+ar[ix];
			}
		}
		return str.replace(/^\n{1,}/,'');
}

//----------------------------------------------------------------------------

function isSubquery(str, parenthesisLevel) {
	return  parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
}

function split_sql(str, tab) {

	return str.replace(/\s{1,}/g," ")

				.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
				.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
				.replace(/ CASE /ig,"~::~"+tab+"CASE ")
				.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
				.replace(/ END /ig,"~::~"+tab+"END ")
				.replace(/ FROM /ig,"~::~FROM ")
				.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
				.replace(/ HAVING /ig,"~::~HAVING ")
				//.replace(/ SET /ig," SET~::~")
				.replace(/ IN /ig," IN ")
				
				.replace(/ JOIN /ig,"~::~JOIN ")
				.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
				.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
				.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
				.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
				
				.replace(/ ON /ig,"~::~"+tab+"ON ")
				.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
				.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
				.replace(/ OVER /ig,"~::~"+tab+"OVER ")

				.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
				.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
				
				.replace(/ THEN /ig," THEN~::~"+tab+"")
				.replace(/ UNION /ig,"~::~UNION~::~")
				.replace(/ USING /ig,"~::~USING ")
				.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
				.replace(/ WHERE /ig,"~::~WHERE ")
				.replace(/ WITH /ig,"~::~WITH ")
				
				//.replace(/\,\s{0,}\(/ig,",~::~( ")
				//.replace(/\,/ig,",~::~"+tab+tab+"")

				.replace(/ ALL /ig," ALL ")
				.replace(/ AS /ig," AS ")
				.replace(/ ASC /ig," ASC ")	
				.replace(/ DESC /ig," DESC ")	
				.replace(/ DISTINCT /ig," DISTINCT ")
				.replace(/ EXISTS /ig," EXISTS ")
				.replace(/ NOT /ig," NOT ")
				.replace(/ NULL /ig," NULL ")
				.replace(/ LIKE /ig," LIKE ")
				.replace(/\s{0,}SELECT /ig,"SELECT ")
				.replace(/\s{0,}UPDATE /ig,"UPDATE ")
				.replace(/ SET /ig," SET ")
							
				.replace(/~::~{1,}/g,"~::~")
				.split('~::~');
}

vkbeautify.prototype.sql = function(text,step) {

	var ar_by_quote = text.replace(/\s{1,}/g," ")
							.replace(/\'/ig,"~::~\'")
							.split('~::~'),
		len = ar_by_quote.length,
		ar = [],
		deep = 0,
		tab = this.step,//+this.step,
		inComment = true,
		inQuote = false,
		parenthesisLevel = 0,
		str = '',
		ix = 0,
		shift = step ? createShiftArr(step) : this.shift;;

		for(ix=0;ix<len;ix++) {
			if(ix%2) {
				ar = ar.concat(ar_by_quote[ix]);
			} else {
				ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
			}
		}
		
		len = ar.length;
		for(ix=0;ix<len;ix++) {
			
			parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
			
			if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix]))  { 
				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
			} 
			
			if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix]))  { 
				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
			} 
			
			if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix]))  { 
				deep++;
				str += shift[deep]+ar[ix];
			} else 
			if( /\'/.exec(ar[ix]) )  { 
				if(parenthesisLevel<1 && deep) {
					deep--;
				}
				str += ar[ix];
			}
			else  { 
				str += shift[deep]+ar[ix];
				if(parenthesisLevel<1 && deep) {
					deep--;
				}
			} 
			var junk = 0;
		}

		str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
		return str;
}


vkbeautify.prototype.xmlmin = function(text, preserveComments) {

	var str = preserveComments ? text
							   : text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
									 .replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
	return  str.replace(/>\s{0,}</g,"><"); 
}

vkbeautify.prototype.jsonmin = function(text) {

	if (typeof JSON === 'undefined' ) return text; 
	
	return JSON.stringify(JSON.parse(text), null, 0); 
				
}

vkbeautify.prototype.cssmin = function(text, preserveComments) {
	
	var str = preserveComments ? text
							   : text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;

	return str.replace(/\s{1,}/g,' ')
			  .replace(/\{\s{1,}/g,"{")
			  .replace(/\}\s{1,}/g,"}")
			  .replace(/\;\s{1,}/g,";")
			  .replace(/\/\*\s{1,}/g,"/*")
			  .replace(/\*\/\s{1,}/g,"*/");
}

vkbeautify.prototype.sqlmin = function(text) {
	return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
}

window.vkbeautify = new vkbeautify();

})();


/*!
 * jQuery JavaScript Library v2.1.4
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2015-04-28T16:01Z
 */

(function( global, factory ) {

	if ( typeof module === "object" && typeof module.exports === "object" ) {
		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "jQuery requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		factory( global );
	}

// Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

// Support: Firefox 18+
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
//

var arr = [];

var slice = arr.slice;

var concat = arr.concat;

var push = arr.push;

var indexOf = arr.indexOf;

var class2type = {};

var toString = class2type.toString;

var hasOwn = class2type.hasOwnProperty;

var support = {};



var
	// Use the correct document accordingly with window argument (sandbox)
	document = window.document,

	version = "2.1.4",

	// Define a local copy of jQuery
	jQuery = function( selector, context ) {
		// The jQuery object is actually just the init constructor 'enhanced'
		// Need init if jQuery is called (just allow error to be thrown if not included)
		return new jQuery.fn.init( selector, context );
	},

	// Support: Android<4.1
	// Make sure we trim BOM and NBSP
	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,

	// Matches dashed string for camelizing
	rmsPrefix = /^-ms-/,
	rdashAlpha = /-([\da-z])/gi,

	// Used by jQuery.camelCase as callback to replace()
	fcamelCase = function( all, letter ) {
		return letter.toUpperCase();
	};

jQuery.fn = jQuery.prototype = {
	// The current version of jQuery being used
	jquery: version,

	constructor: jQuery,

	// Start with an empty selector
	selector: "",

	// The default length of a jQuery object is 0
	length: 0,

	toArray: function() {
		return slice.call( this );
	},

	// Get the Nth element in the matched element set OR
	// Get the whole matched element set as a clean array
	get: function( num ) {
		return num != null ?

			// Return just the one element from the set
			( num < 0 ? this[ num + this.length ] : this[ num ] ) :

			// Return all the elements in a clean array
			slice.call( this );
	},

	// Take an array of elements and push it onto the stack
	// (returning the new matched element set)
	pushStack: function( elems ) {

		// Build a new jQuery matched element set
		var ret = jQuery.merge( this.constructor(), elems );

		// Add the old object onto the stack (as a reference)
		ret.prevObject = this;
		ret.context = this.context;

		// Return the newly-formed element set
		return ret;
	},

	// Execute a callback for every element in the matched set.
	// (You can seed the arguments with an array of args, but this is
	// only used internally.)
	each: function( callback, args ) {
		return jQuery.each( this, callback, args );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map(this, function( elem, i ) {
			return callback.call( elem, i, elem );
		}));
	},

	slice: function() {
		return this.pushStack( slice.apply( this, arguments ) );
	},

	first: function() {
		return this.eq( 0 );
	},

	last: function() {
		return this.eq( -1 );
	},

	eq: function( i ) {
		var len = this.length,
			j = +i + ( i < 0 ? len : 0 );
		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
	},

	end: function() {
		return this.prevObject || this.constructor(null);
	},

	// For internal use only.
	// Behaves like an Array's method, not like a jQuery method.
	push: push,
	sort: arr.sort,
	splice: arr.splice
};

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[0] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;

		// Skip the boolean and the target
		target = arguments[ i ] || {};
		i++;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
		target = {};
	}

	// Extend jQuery itself if only one argument is passed
	if ( i === length ) {
		target = this;
		i--;
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values
		if ( (options = arguments[ i ]) != null ) {
			// Extend the base object
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				// Prevent never-ending loop
				if ( target === copy ) {
					continue;
				}

				// Recurse if we're merging plain objects or arrays
				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
					if ( copyIsArray ) {
						copyIsArray = false;
						clone = src && jQuery.isArray(src) ? src : [];

					} else {
						clone = src && jQuery.isPlainObject(src) ? src : {};
					}

					// Never move original objects, clone them
					target[ name ] = jQuery.extend( deep, clone, copy );

				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};

jQuery.extend({
	// Unique for each copy of jQuery on the page
	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),

	// Assume jQuery is ready without the ready module
	isReady: true,

	error: function( msg ) {
		throw new Error( msg );
	},

	noop: function() {},

	isFunction: function( obj ) {
		return jQuery.type(obj) === "function";
	},

	isArray: Array.isArray,

	isWindow: function( obj ) {
		return obj != null && obj === obj.window;
	},

	isNumeric: function( obj ) {
		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
		// subtraction forces infinities to NaN
		// adding 1 corrects loss of precision from parseFloat (#15100)
		return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
	},

	isPlainObject: function( obj ) {
		// Not plain objects:
		// - Any object or value whose internal [[Class]] property is not "[object Object]"
		// - DOM nodes
		// - window
		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
			return false;
		}

		if ( obj.constructor &&
				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
			return false;
		}

		// If the function hasn't returned already, we're confident that
		// |obj| is a plain object, created by {} or constructed with new Object
		return true;
	},

	isEmptyObject: function( obj ) {
		var name;
		for ( name in obj ) {
			return false;
		}
		return true;
	},

	type: function( obj ) {
		if ( obj == null ) {
			return obj + "";
		}
		// Support: Android<4.0, iOS<6 (functionish RegExp)
		return typeof obj === "object" || typeof obj === "function" ?
			class2type[ toString.call(obj) ] || "object" :
			typeof obj;
	},

	// Evaluates a script in a global context
	globalEval: function( code ) {
		var script,
			indirect = eval;

		code = jQuery.trim( code );

		if ( code ) {
			// If the code includes a valid, prologue position
			// strict mode pragma, execute code by injecting a
			// script tag into the document.
			if ( code.indexOf("use strict") === 1 ) {
				script = document.createElement("script");
				script.text = code;
				document.head.appendChild( script ).parentNode.removeChild( script );
			} else {
			// Otherwise, avoid the DOM node creation, insertion
			// and removal by using an indirect global eval
				indirect( code );
			}
		}
	},

	// Convert dashed to camelCase; used by the css and data modules
	// Support: IE9-11+
	// Microsoft forgot to hump their vendor prefix (#9572)
	camelCase: function( string ) {
		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
	},

	nodeName: function( elem, name ) {
		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	},

	// args is for internal usage only
	each: function( obj, callback, args ) {
		var value,
			i = 0,
			length = obj.length,
			isArray = isArraylike( obj );

		if ( args ) {
			if ( isArray ) {
				for ( ; i < length; i++ ) {
					value = callback.apply( obj[ i ], args );

					if ( value === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					value = callback.apply( obj[ i ], args );

					if ( value === false ) {
						break;
					}
				}
			}

		// A special, fast, case for the most common use of each
		} else {
			if ( isArray ) {
				for ( ; i < length; i++ ) {
					value = callback.call( obj[ i ], i, obj[ i ] );

					if ( value === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					value = callback.call( obj[ i ], i, obj[ i ] );

					if ( value === false ) {
						break;
					}
				}
			}
		}

		return obj;
	},

	// Support: Android<4.1
	trim: function( text ) {
		return text == null ?
			"" :
			( text + "" ).replace( rtrim, "" );
	},

	// results is for internal usage only
	makeArray: function( arr, results ) {
		var ret = results || [];

		if ( arr != null ) {
			if ( isArraylike( Object(arr) ) ) {
				jQuery.merge( ret,
					typeof arr === "string" ?
					[ arr ] : arr
				);
			} else {
				push.call( ret, arr );
			}
		}

		return ret;
	},

	inArray: function( elem, arr, i ) {
		return arr == null ? -1 : indexOf.call( arr, elem, i );
	},

	merge: function( first, second ) {
		var len = +second.length,
			j = 0,
			i = first.length;

		for ( ; j < len; j++ ) {
			first[ i++ ] = second[ j ];
		}

		first.length = i;

		return first;
	},

	grep: function( elems, callback, invert ) {
		var callbackInverse,
			matches = [],
			i = 0,
			length = elems.length,
			callbackExpect = !invert;

		// Go through the array, only saving the items
		// that pass the validator function
		for ( ; i < length; i++ ) {
			callbackInverse = !callback( elems[ i ], i );
			if ( callbackInverse !== callbackExpect ) {
				matches.push( elems[ i ] );
			}
		}

		return matches;
	},

	// arg is for internal usage only
	map: function( elems, callback, arg ) {
		var value,
			i = 0,
			length = elems.length,
			isArray = isArraylike( elems ),
			ret = [];

		// Go through the array, translating each of the items to their new values
		if ( isArray ) {
			for ( ; i < length; i++ ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret.push( value );
				}
			}

		// Go through every key on the object,
		} else {
			for ( i in elems ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret.push( value );
				}
			}
		}

		// Flatten any nested arrays
		return concat.apply( [], ret );
	},

	// A global GUID counter for objects
	guid: 1,

	// Bind a function to a context, optionally partially applying any
	// arguments.
	proxy: function( fn, context ) {
		var tmp, args, proxy;

		if ( typeof context === "string" ) {
			tmp = fn[ context ];
			context = fn;
			fn = tmp;
		}

		// Quick check to determine if target is callable, in the spec
		// this throws a TypeError, but we will just return undefined.
		if ( !jQuery.isFunction( fn ) ) {
			return undefined;
		}

		// Simulated bind
		args = slice.call( arguments, 2 );
		proxy = function() {
			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
		};

		// Set the guid of unique handler to the same of original handler, so it can be removed
		proxy.guid = fn.guid = fn.guid || jQuery.guid++;

		return proxy;
	},

	now: Date.now,

	// jQuery.support is not used in Core but other projects attach their
	// properties to it so it needs to exist.
	support: support
});

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

function isArraylike( obj ) {

	// Support: iOS 8.2 (not reproducible in simulator)
	// `in` check used to prevent JIT error (gh-2145)
	// hasOwn isn't used here due to false negatives
	// regarding Nodelist length in IE
	var length = "length" in obj && obj.length,
		type = jQuery.type( obj );

	if ( type === "function" || jQuery.isWindow( obj ) ) {
		return false;
	}

	if ( obj.nodeType === 1 && length ) {
		return true;
	}

	return type === "array" || length === 0 ||
		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}
var Sizzle =
/*!
 * Sizzle CSS Selector Engine v2.2.0-pre
 * http://sizzlejs.com/
 *
 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2014-12-16
 */
(function( window ) {

var i,
	support,
	Expr,
	getText,
	isXML,
	tokenize,
	compile,
	select,
	outermostContext,
	sortInput,
	hasDuplicate,

	// Local document vars
	setDocument,
	document,
	docElem,
	documentIsHTML,
	rbuggyQSA,
	rbuggyMatches,
	matches,
	contains,

	// Instance-specific data
	expando = "sizzle" + 1 * new Date(),
	preferredDoc = window.document,
	dirruns = 0,
	done = 0,
	classCache = createCache(),
	tokenCache = createCache(),
	compilerCache = createCache(),
	sortOrder = function( a, b ) {
		if ( a === b ) {
			hasDuplicate = true;
		}
		return 0;
	},

	// General-purpose constants
	MAX_NEGATIVE = 1 << 31,

	// Instance methods
	hasOwn = ({}).hasOwnProperty,
	arr = [],
	pop = arr.pop,
	push_native = arr.push,
	push = arr.push,
	slice = arr.slice,
	// Use a stripped-down indexOf as it's faster than native
	// http://jsperf.com/thor-indexof-vs-for/5
	indexOf = function( list, elem ) {
		var i = 0,
			len = list.length;
		for ( ; i < len; i++ ) {
			if ( list[i] === elem ) {
				return i;
			}
		}
		return -1;
	},

	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",

	// Regular expressions

	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
	whitespace = "[\\x20\\t\\r\\n\\f]",
	// http://www.w3.org/TR/css3-syntax/#characters
	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",

	// Loosely modeled on CSS identifier characters
	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
	identifier = characterEncoding.replace( "w", "w#" ),

	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
		// Operator (capture 2)
		"*([*^$|!~]?=)" + whitespace +
		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
		"*\\]",

	pseudos = ":(" + characterEncoding + ")(?:\\((" +
		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
		// 1. quoted (capture 3; capture 4 or capture 5)
		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
		// 2. simple (capture 6)
		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
		// 3. anything else (capture 2)
		".*" +
		")\\)|)",

	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
	rwhitespace = new RegExp( whitespace + "+", "g" ),
	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),

	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),

	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),

	rpseudo = new RegExp( pseudos ),
	ridentifier = new RegExp( "^" + identifier + "$" ),

	matchExpr = {
		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
		"ATTR": new RegExp( "^" + attributes ),
		"PSEUDO": new RegExp( "^" + pseudos ),
		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
		// For use in libraries implementing .is()
		// We use this for POS matching in `select`
		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
	},

	rinputs = /^(?:input|select|textarea|button)$/i,
	rheader = /^h\d$/i,

	rnative = /^[^{]+\{\s*\[native \w/,

	// Easily-parseable/retrievable ID or TAG or CLASS selectors
	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

	rsibling = /[+~]/,
	rescape = /'|\\/g,

	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
	funescape = function( _, escaped, escapedWhitespace ) {
		var high = "0x" + escaped - 0x10000;
		// NaN means non-codepoint
		// Support: Firefox<24
		// Workaround erroneous numeric interpretation of +"0x"
		return high !== high || escapedWhitespace ?
			escaped :
			high < 0 ?
				// BMP codepoint
				String.fromCharCode( high + 0x10000 ) :
				// Supplemental Plane codepoint (surrogate pair)
				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
	},

	// Used for iframes
	// See setDocument()
	// Removing the function wrapper causes a "Permission Denied"
	// error in IE
	unloadHandler = function() {
		setDocument();
	};

// Optimize for push.apply( _, NodeList )
try {
	push.apply(
		(arr = slice.call( preferredDoc.childNodes )),
		preferredDoc.childNodes
	);
	// Support: Android<4.0
	// Detect silently failing push.apply
	arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
	push = { apply: arr.length ?

		// Leverage slice if possible
		function( target, els ) {
			push_native.apply( target, slice.call(els) );
		} :

		// Support: IE<9
		// Otherwise append directly
		function( target, els ) {
			var j = target.length,
				i = 0;
			// Can't trust NodeList.length
			while ( (target[j++] = els[i++]) ) {}
			target.length = j - 1;
		}
	};
}

function Sizzle( selector, context, results, seed ) {
	var match, elem, m, nodeType,
		// QSA vars
		i, groups, old, nid, newContext, newSelector;

	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
		setDocument( context );
	}

	context = context || document;
	results = results || [];
	nodeType = context.nodeType;

	if ( typeof selector !== "string" || !selector ||
		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

		return results;
	}

	if ( !seed && documentIsHTML ) {

		// Try to shortcut find operations when possible (e.g., not under DocumentFragment)
		if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
			// Speed-up: Sizzle("#ID")
			if ( (m = match[1]) ) {
				if ( nodeType === 9 ) {
					elem = context.getElementById( m );
					// Check parentNode to catch when Blackberry 4.6 returns
					// nodes that are no longer in the document (jQuery #6963)
					if ( elem && elem.parentNode ) {
						// Handle the case where IE, Opera, and Webkit return items
						// by name instead of ID
						if ( elem.id === m ) {
							results.push( elem );
							return results;
						}
					} else {
						return results;
					}
				} else {
					// Context is not a document
					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
						contains( context, elem ) && elem.id === m ) {
						results.push( elem );
						return results;
					}
				}

			// Speed-up: Sizzle("TAG")
			} else if ( match[2] ) {
				push.apply( results, context.getElementsByTagName( selector ) );
				return results;

			// Speed-up: Sizzle(".CLASS")
			} else if ( (m = match[3]) && support.getElementsByClassName ) {
				push.apply( results, context.getElementsByClassName( m ) );
				return results;
			}
		}

		// QSA path
		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
			nid = old = expando;
			newContext = context;
			newSelector = nodeType !== 1 && selector;

			// qSA works strangely on Element-rooted queries
			// We can work around this by specifying an extra ID on the root
			// and working up from there (Thanks to Andrew Dupont for the technique)
			// IE 8 doesn't work on object elements
			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
				groups = tokenize( selector );

				if ( (old = context.getAttribute("id")) ) {
					nid = old.replace( rescape, "\\$&" );
				} else {
					context.setAttribute( "id", nid );
				}
				nid = "[id='" + nid + "'] ";

				i = groups.length;
				while ( i-- ) {
					groups[i] = nid + toSelector( groups[i] );
				}
				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
				newSelector = groups.join(",");
			}

			if ( newSelector ) {
				try {
					push.apply( results,
						newContext.querySelectorAll( newSelector )
					);
					return results;
				} catch(qsaError) {
				} finally {
					if ( !old ) {
						context.removeAttribute("id");
					}
				}
			}
		}
	}

	// All others
	return select( selector.replace( rtrim, "$1" ), context, results, seed );
}

/**
 * Create key-value caches of limited size
 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
 *	deleting the oldest entry
 */
function createCache() {
	var keys = [];

	function cache( key, value ) {
		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
		if ( keys.push( key + " " ) > Expr.cacheLength ) {
			// Only keep the most recent entries
			delete cache[ keys.shift() ];
		}
		return (cache[ key + " " ] = value);
	}
	return cache;
}

/**
 * Mark a function for special use by Sizzle
 * @param {Function} fn The function to mark
 */
function markFunction( fn ) {
	fn[ expando ] = true;
	return fn;
}

/**
 * Support testing using an element
 * @param {Function} fn Passed the created div and expects a boolean result
 */
function assert( fn ) {
	var div = document.createElement("div");

	try {
		return !!fn( div );
	} catch (e) {
		return false;
	} finally {
		// Remove from its parent by default
		if ( div.parentNode ) {
			div.parentNode.removeChild( div );
		}
		// release memory in IE
		div = null;
	}
}

/**
 * Adds the same handler for all of the specified attrs
 * @param {String} attrs Pipe-separated list of attributes
 * @param {Function} handler The method that will be applied
 */
function addHandle( attrs, handler ) {
	var arr = attrs.split("|"),
		i = attrs.length;

	while ( i-- ) {
		Expr.attrHandle[ arr[i] ] = handler;
	}
}

/**
 * Checks document order of two siblings
 * @param {Element} a
 * @param {Element} b
 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
 */
function siblingCheck( a, b ) {
	var cur = b && a,
		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
			( ~b.sourceIndex || MAX_NEGATIVE ) -
			( ~a.sourceIndex || MAX_NEGATIVE );

	// Use IE sourceIndex if available on both nodes
	if ( diff ) {
		return diff;
	}

	// Check if b follows a
	if ( cur ) {
		while ( (cur = cur.nextSibling) ) {
			if ( cur === b ) {
				return -1;
			}
		}
	}

	return a ? 1 : -1;
}

/**
 * Returns a function to use in pseudos for input types
 * @param {String} type
 */
function createInputPseudo( type ) {
	return function( elem ) {
		var name = elem.nodeName.toLowerCase();
		return name === "input" && elem.type === type;
	};
}

/**
 * Returns a function to use in pseudos for buttons
 * @param {String} type
 */
function createButtonPseudo( type ) {
	return function( elem ) {
		var name = elem.nodeName.toLowerCase();
		return (name === "input" || name === "button") && elem.type === type;
	};
}

/**
 * Returns a function to use in pseudos for positionals
 * @param {Function} fn
 */
function createPositionalPseudo( fn ) {
	return markFunction(function( argument ) {
		argument = +argument;
		return markFunction(function( seed, matches ) {
			var j,
				matchIndexes = fn( [], seed.length, argument ),
				i = matchIndexes.length;

			// Match elements found at the specified indexes
			while ( i-- ) {
				if ( seed[ (j = matchIndexes[i]) ] ) {
					seed[j] = !(matches[j] = seed[j]);
				}
			}
		});
	});
}

/**
 * Checks a node for validity as a Sizzle context
 * @param {Element|Object=} context
 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
 */
function testContext( context ) {
	return context && typeof context.getElementsByTagName !== "undefined" && context;
}

// Expose support vars for convenience
support = Sizzle.support = {};

/**
 * Detects XML nodes
 * @param {Element|Object} elem An element or a document
 * @returns {Boolean} True iff elem is a non-HTML XML node
 */
isXML = Sizzle.isXML = function( elem ) {
	// documentElement is verified for cases where it doesn't yet exist
	// (such as loading iframes in IE - #4833)
	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
	return documentElement ? documentElement.nodeName !== "HTML" : false;
};

/**
 * Sets document-related variables once based on the current document
 * @param {Element|Object} [doc] An element or document object to use to set the document
 * @returns {Object} Returns the current document
 */
setDocument = Sizzle.setDocument = function( node ) {
	var hasCompare, parent,
		doc = node ? node.ownerDocument || node : preferredDoc;

	// If no document and documentElement is available, return
	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
		return document;
	}

	// Set our document
	document = doc;
	docElem = doc.documentElement;
	parent = doc.defaultView;

	// Support: IE>8
	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
	// IE6-8 do not support the defaultView property so parent will be undefined
	if ( parent && parent !== parent.top ) {
		// IE11 does not have attachEvent, so all must suffer
		if ( parent.addEventListener ) {
			parent.addEventListener( "unload", unloadHandler, false );
		} else if ( parent.attachEvent ) {
			parent.attachEvent( "onunload", unloadHandler );
		}
	}

	/* Support tests
	---------------------------------------------------------------------- */
	documentIsHTML = !isXML( doc );

	/* Attributes
	---------------------------------------------------------------------- */

	// Support: IE<8
	// Verify that getAttribute really returns attributes and not properties
	// (excepting IE8 booleans)
	support.attributes = assert(function( div ) {
		div.className = "i";
		return !div.getAttribute("className");
	});

	/* getElement(s)By*
	---------------------------------------------------------------------- */

	// Check if getElementsByTagName("*") returns only elements
	support.getElementsByTagName = assert(function( div ) {
		div.appendChild( doc.createComment("") );
		return !div.getElementsByTagName("*").length;
	});

	// Support: IE<9
	support.getElementsByClassName = rnative.test( doc.getElementsByClassName );

	// Support: IE<10
	// Check if getElementById returns elements by name
	// The broken getElementById methods don't pick up programatically-set names,
	// so use a roundabout getElementsByName test
	support.getById = assert(function( div ) {
		docElem.appendChild( div ).id = expando;
		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
	});

	// ID find and filter
	if ( support.getById ) {
		Expr.find["ID"] = function( id, context ) {
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
				var m = context.getElementById( id );
				// Check parentNode to catch when Blackberry 4.6 returns
				// nodes that are no longer in the document #6963
				return m && m.parentNode ? [ m ] : [];
			}
		};
		Expr.filter["ID"] = function( id ) {
			var attrId = id.replace( runescape, funescape );
			return function( elem ) {
				return elem.getAttribute("id") === attrId;
			};
		};
	} else {
		// Support: IE6/7
		// getElementById is not reliable as a find shortcut
		delete Expr.find["ID"];

		Expr.filter["ID"] =  function( id ) {
			var attrId = id.replace( runescape, funescape );
			return function( elem ) {
				var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
				return node && node.value === attrId;
			};
		};
	}

	// Tag
	Expr.find["TAG"] = support.getElementsByTagName ?
		function( tag, context ) {
			if ( typeof context.getElementsByTagName !== "undefined" ) {
				return context.getElementsByTagName( tag );

			// DocumentFragment nodes don't have gEBTN
			} else if ( support.qsa ) {
				return context.querySelectorAll( tag );
			}
		} :

		function( tag, context ) {
			var elem,
				tmp = [],
				i = 0,
				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
				results = context.getElementsByTagName( tag );

			// Filter out possible comments
			if ( tag === "*" ) {
				while ( (elem = results[i++]) ) {
					if ( elem.nodeType === 1 ) {
						tmp.push( elem );
					}
				}

				return tmp;
			}
			return results;
		};

	// Class
	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
		if ( documentIsHTML ) {
			return context.getElementsByClassName( className );
		}
	};

	/* QSA/matchesSelector
	---------------------------------------------------------------------- */

	// QSA and matchesSelector support

	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
	rbuggyMatches = [];

	// qSa(:focus) reports false when true (Chrome 21)
	// We allow this because of a bug in IE8/9 that throws an error
	// whenever `document.activeElement` is accessed on an iframe
	// So, we allow :focus to pass through QSA all the time to avoid the IE error
	// See http://bugs.jquery.com/ticket/13378
	rbuggyQSA = [];

	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
		// Build QSA regex
		// Regex strategy adopted from Diego Perini
		assert(function( div ) {
			// Select is set to empty string on purpose
			// This is to test IE's treatment of not explicitly
			// setting a boolean content attribute,
			// since its presence should be enough
			// http://bugs.jquery.com/ticket/12359
			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
				"<select id='" + expando + "-\f]' msallowcapture=''>" +
				"<option selected=''></option></select>";

			// Support: IE8, Opera 11-12.16
			// Nothing should be selected when empty strings follow ^= or $= or *=
			// The test attribute must be unknown in Opera but "safe" for WinRT
			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
			}

			// Support: IE8
			// Boolean attributes and "value" are not treated correctly
			if ( !div.querySelectorAll("[selected]").length ) {
				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
			}

			// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
				rbuggyQSA.push("~=");
			}

			// Webkit/Opera - :checked should return selected option elements
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			// IE8 throws error here and will not see later tests
			if ( !div.querySelectorAll(":checked").length ) {
				rbuggyQSA.push(":checked");
			}

			// Support: Safari 8+, iOS 8+
			// https://bugs.webkit.org/show_bug.cgi?id=136851
			// In-page `selector#id sibing-combinator selector` fails
			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
				rbuggyQSA.push(".#.+[+~]");
			}
		});

		assert(function( div ) {
			// Support: Windows 8 Native Apps
			// The type and name attributes are restricted during .innerHTML assignment
			var input = doc.createElement("input");
			input.setAttribute( "type", "hidden" );
			div.appendChild( input ).setAttribute( "name", "D" );

			// Support: IE8
			// Enforce case-sensitivity of name attribute
			if ( div.querySelectorAll("[name=d]").length ) {
				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
			}

			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
			// IE8 throws error here and will not see later tests
			if ( !div.querySelectorAll(":enabled").length ) {
				rbuggyQSA.push( ":enabled", ":disabled" );
			}

			// Opera 10-11 does not throw on post-comma invalid pseudos
			div.querySelectorAll("*,:x");
			rbuggyQSA.push(",.*:");
		});
	}

	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
		docElem.webkitMatchesSelector ||
		docElem.mozMatchesSelector ||
		docElem.oMatchesSelector ||
		docElem.msMatchesSelector) )) ) {

		assert(function( div ) {
			// Check to see if it's possible to do matchesSelector
			// on a disconnected node (IE 9)
			support.disconnectedMatch = matches.call( div, "div" );

			// This should fail with an exception
			// Gecko does not error, returns false instead
			matches.call( div, "[s!='']:x" );
			rbuggyMatches.push( "!=", pseudos );
		});
	}

	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );

	/* Contains
	---------------------------------------------------------------------- */
	hasCompare = rnative.test( docElem.compareDocumentPosition );

	// Element contains another
	// Purposefully does not implement inclusive descendent
	// As in, an element does not contain itself
	contains = hasCompare || rnative.test( docElem.contains ) ?
		function( a, b ) {
			var adown = a.nodeType === 9 ? a.documentElement : a,
				bup = b && b.parentNode;
			return a === bup || !!( bup && bup.nodeType === 1 && (
				adown.contains ?
					adown.contains( bup ) :
					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
			));
		} :
		function( a, b ) {
			if ( b ) {
				while ( (b = b.parentNode) ) {
					if ( b === a ) {
						return true;
					}
				}
			}
			return false;
		};

	/* Sorting
	---------------------------------------------------------------------- */

	// Document order sorting
	sortOrder = hasCompare ?
	function( a, b ) {

		// Flag for duplicate removal
		if ( a === b ) {
			hasDuplicate = true;
			return 0;
		}

		// Sort on method existence if only one input has compareDocumentPosition
		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
		if ( compare ) {
			return compare;
		}

		// Calculate position if both inputs belong to the same document
		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
			a.compareDocumentPosition( b ) :

			// Otherwise we know they are disconnected
			1;

		// Disconnected nodes
		if ( compare & 1 ||
			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {

			// Choose the first element that is related to our preferred document
			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
				return -1;
			}
			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
				return 1;
			}

			// Maintain original order
			return sortInput ?
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
				0;
		}

		return compare & 4 ? -1 : 1;
	} :
	function( a, b ) {
		// Exit early if the nodes are identical
		if ( a === b ) {
			hasDuplicate = true;
			return 0;
		}

		var cur,
			i = 0,
			aup = a.parentNode,
			bup = b.parentNode,
			ap = [ a ],
			bp = [ b ];

		// Parentless nodes are either documents or disconnected
		if ( !aup || !bup ) {
			return a === doc ? -1 :
				b === doc ? 1 :
				aup ? -1 :
				bup ? 1 :
				sortInput ?
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
				0;

		// If the nodes are siblings, we can do a quick check
		} else if ( aup === bup ) {
			return siblingCheck( a, b );
		}

		// Otherwise we need full lists of their ancestors for comparison
		cur = a;
		while ( (cur = cur.parentNode) ) {
			ap.unshift( cur );
		}
		cur = b;
		while ( (cur = cur.parentNode) ) {
			bp.unshift( cur );
		}

		// Walk down the tree looking for a discrepancy
		while ( ap[i] === bp[i] ) {
			i++;
		}

		return i ?
			// Do a sibling check if the nodes have a common ancestor
			siblingCheck( ap[i], bp[i] ) :

			// Otherwise nodes in our document sort first
			ap[i] === preferredDoc ? -1 :
			bp[i] === preferredDoc ? 1 :
			0;
	};

	return doc;
};

Sizzle.matches = function( expr, elements ) {
	return Sizzle( expr, null, null, elements );
};

Sizzle.matchesSelector = function( elem, expr ) {
	// Set document vars if needed
	if ( ( elem.ownerDocument || elem ) !== document ) {
		setDocument( elem );
	}

	// Make sure that attribute selectors are quoted
	expr = expr.replace( rattributeQuotes, "='$1']" );

	if ( support.matchesSelector && documentIsHTML &&
		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {

		try {
			var ret = matches.call( elem, expr );

			// IE 9's matchesSelector returns false on disconnected nodes
			if ( ret || support.disconnectedMatch ||
					// As well, disconnected nodes are said to be in a document
					// fragment in IE 9
					elem.document && elem.document.nodeType !== 11 ) {
				return ret;
			}
		} catch (e) {}
	}

	return Sizzle( expr, document, null, [ elem ] ).length > 0;
};

Sizzle.contains = function( context, elem ) {
	// Set document vars if needed
	if ( ( context.ownerDocument || context ) !== document ) {
		setDocument( context );
	}
	return contains( context, elem );
};

Sizzle.attr = function( elem, name ) {
	// Set document vars if needed
	if ( ( elem.ownerDocument || elem ) !== document ) {
		setDocument( elem );
	}

	var fn = Expr.attrHandle[ name.toLowerCase() ],
		// Don't get fooled by Object.prototype properties (jQuery #13807)
		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
			fn( elem, name, !documentIsHTML ) :
			undefined;

	return val !== undefined ?
		val :
		support.attributes || !documentIsHTML ?
			elem.getAttribute( name ) :
			(val = elem.getAttributeNode(name)) && val.specified ?
				val.value :
				null;
};

Sizzle.error = function( msg ) {
	throw new Error( "Syntax error, unrecognized expression: " + msg );
};

/**
 * Document sorting and removing duplicates
 * @param {ArrayLike} results
 */
Sizzle.uniqueSort = function( results ) {
	var elem,
		duplicates = [],
		j = 0,
		i = 0;

	// Unless we *know* we can detect duplicates, assume their presence
	hasDuplicate = !support.detectDuplicates;
	sortInput = !support.sortStable && results.slice( 0 );
	results.sort( sortOrder );

	if ( hasDuplicate ) {
		while ( (elem = results[i++]) ) {
			if ( elem === results[ i ] ) {
				j = duplicates.push( i );
			}
		}
		while ( j-- ) {
			results.splice( duplicates[ j ], 1 );
		}
	}

	// Clear input after sorting to release objects
	// See https://github.com/jquery/sizzle/pull/225
	sortInput = null;

	return results;
};

/**
 * Utility function for retrieving the text value of an array of DOM nodes
 * @param {Array|Element} elem
 */
getText = Sizzle.getText = function( elem ) {
	var node,
		ret = "",
		i = 0,
		nodeType = elem.nodeType;

	if ( !nodeType ) {
		// If no nodeType, this is expected to be an array
		while ( (node = elem[i++]) ) {
			// Do not traverse comment nodes
			ret += getText( node );
		}
	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
		// Use textContent for elements
		// innerText usage removed for consistency of new lines (jQuery #11153)
		if ( typeof elem.textContent === "string" ) {
			return elem.textContent;
		} else {
			// Traverse its children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				ret += getText( elem );
			}
		}
	} else if ( nodeType === 3 || nodeType === 4 ) {
		return elem.nodeValue;
	}
	// Do not include comment or processing instruction nodes

	return ret;
};

Expr = Sizzle.selectors = {

	// Can be adjusted by the user
	cacheLength: 50,

	createPseudo: markFunction,

	match: matchExpr,

	attrHandle: {},

	find: {},

	relative: {
		">": { dir: "parentNode", first: true },
		" ": { dir: "parentNode" },
		"+": { dir: "previousSibling", first: true },
		"~": { dir: "previousSibling" }
	},

	preFilter: {
		"ATTR": function( match ) {
			match[1] = match[1].replace( runescape, funescape );

			// Move the given value to match[3] whether quoted or unquoted
			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );

			if ( match[2] === "~=" ) {
				match[3] = " " + match[3] + " ";
			}

			return match.slice( 0, 4 );
		},

		"CHILD": function( match ) {
			/* matches from matchExpr["CHILD"]
				1 type (only|nth|...)
				2 what (child|of-type)
				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
				4 xn-component of xn+y argument ([+-]?\d*n|)
				5 sign of xn-component
				6 x of xn-component
				7 sign of y-component
				8 y of y-component
			*/
			match[1] = match[1].toLowerCase();

			if ( match[1].slice( 0, 3 ) === "nth" ) {
				// nth-* requires argument
				if ( !match[3] ) {
					Sizzle.error( match[0] );
				}

				// numeric x and y parameters for Expr.filter.CHILD
				// remember that false/true cast respectively to 0/1
				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );

			// other types prohibit arguments
			} else if ( match[3] ) {
				Sizzle.error( match[0] );
			}

			return match;
		},

		"PSEUDO": function( match ) {
			var excess,
				unquoted = !match[6] && match[2];

			if ( matchExpr["CHILD"].test( match[0] ) ) {
				return null;
			}

			// Accept quoted arguments as-is
			if ( match[3] ) {
				match[2] = match[4] || match[5] || "";

			// Strip excess characters from unquoted arguments
			} else if ( unquoted && rpseudo.test( unquoted ) &&
				// Get excess from tokenize (recursively)
				(excess = tokenize( unquoted, true )) &&
				// advance to the next closing parenthesis
				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {

				// excess is a negative index
				match[0] = match[0].slice( 0, excess );
				match[2] = unquoted.slice( 0, excess );
			}

			// Return only captures needed by the pseudo filter method (type and argument)
			return match.slice( 0, 3 );
		}
	},

	filter: {

		"TAG": function( nodeNameSelector ) {
			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
			return nodeNameSelector === "*" ?
				function() { return true; } :
				function( elem ) {
					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
				};
		},

		"CLASS": function( className ) {
			var pattern = classCache[ className + " " ];

			return pattern ||
				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
				classCache( className, function( elem ) {
					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
				});
		},

		"ATTR": function( name, operator, check ) {
			return function( elem ) {
				var result = Sizzle.attr( elem, name );

				if ( result == null ) {
					return operator === "!=";
				}
				if ( !operator ) {
					return true;
				}

				result += "";

				return operator === "=" ? result === check :
					operator === "!=" ? result !== check :
					operator === "^=" ? check && result.indexOf( check ) === 0 :
					operator === "*=" ? check && result.indexOf( check ) > -1 :
					operator === "$=" ? check && result.slice( -check.length ) === check :
					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
					false;
			};
		},

		"CHILD": function( type, what, argument, first, last ) {
			var simple = type.slice( 0, 3 ) !== "nth",
				forward = type.slice( -4 ) !== "last",
				ofType = what === "of-type";

			return first === 1 && last === 0 ?

				// Shortcut for :nth-*(n)
				function( elem ) {
					return !!elem.parentNode;
				} :

				function( elem, context, xml ) {
					var cache, outerCache, node, diff, nodeIndex, start,
						dir = simple !== forward ? "nextSibling" : "previousSibling",
						parent = elem.parentNode,
						name = ofType && elem.nodeName.toLowerCase(),
						useCache = !xml && !ofType;

					if ( parent ) {

						// :(first|last|only)-(child|of-type)
						if ( simple ) {
							while ( dir ) {
								node = elem;
								while ( (node = node[ dir ]) ) {
									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
										return false;
									}
								}
								// Reverse direction for :only-* (if we haven't yet done so)
								start = dir = type === "only" && !start && "nextSibling";
							}
							return true;
						}

						start = [ forward ? parent.firstChild : parent.lastChild ];

						// non-xml :nth-child(...) stores cache data on `parent`
						if ( forward && useCache ) {
							// Seek `elem` from a previously-cached index
							outerCache = parent[ expando ] || (parent[ expando ] = {});
							cache = outerCache[ type ] || [];
							nodeIndex = cache[0] === dirruns && cache[1];
							diff = cache[0] === dirruns && cache[2];
							node = nodeIndex && parent.childNodes[ nodeIndex ];

							while ( (node = ++nodeIndex && node && node[ dir ] ||

								// Fallback to seeking `elem` from the start
								(diff = nodeIndex = 0) || start.pop()) ) {

								// When found, cache indexes on `parent` and break
								if ( node.nodeType === 1 && ++diff && node === elem ) {
									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
									break;
								}
							}

						// Use previously-cached element index if available
						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
							diff = cache[1];

						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
						} else {
							// Use the same loop as above to seek `elem` from the start
							while ( (node = ++nodeIndex && node && node[ dir ] ||
								(diff = nodeIndex = 0) || start.pop()) ) {

								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
									// Cache the index of each encountered element
									if ( useCache ) {
										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
									}

									if ( node === elem ) {
										break;
									}
								}
							}
						}

						// Incorporate the offset, then check against cycle size
						diff -= last;
						return diff === first || ( diff % first === 0 && diff / first >= 0 );
					}
				};
		},

		"PSEUDO": function( pseudo, argument ) {
			// pseudo-class names are case-insensitive
			// http://www.w3.org/TR/selectors/#pseudo-classes
			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
			// Remember that setFilters inherits from pseudos
			var args,
				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
					Sizzle.error( "unsupported pseudo: " + pseudo );

			// The user may use createPseudo to indicate that
			// arguments are needed to create the filter function
			// just as Sizzle does
			if ( fn[ expando ] ) {
				return fn( argument );
			}

			// But maintain support for old signatures
			if ( fn.length > 1 ) {
				args = [ pseudo, pseudo, "", argument ];
				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
					markFunction(function( seed, matches ) {
						var idx,
							matched = fn( seed, argument ),
							i = matched.length;
						while ( i-- ) {
							idx = indexOf( seed, matched[i] );
							seed[ idx ] = !( matches[ idx ] = matched[i] );
						}
					}) :
					function( elem ) {
						return fn( elem, 0, args );
					};
			}

			return fn;
		}
	},

	pseudos: {
		// Potentially complex pseudos
		"not": markFunction(function( selector ) {
			// Trim the selector passed to compile
			// to avoid treating leading and trailing
			// spaces as combinators
			var input = [],
				results = [],
				matcher = compile( selector.replace( rtrim, "$1" ) );

			return matcher[ expando ] ?
				markFunction(function( seed, matches, context, xml ) {
					var elem,
						unmatched = matcher( seed, null, xml, [] ),
						i = seed.length;

					// Match elements unmatched by `matcher`
					while ( i-- ) {
						if ( (elem = unmatched[i]) ) {
							seed[i] = !(matches[i] = elem);
						}
					}
				}) :
				function( elem, context, xml ) {
					input[0] = elem;
					matcher( input, null, xml, results );
					// Don't keep the element (issue #299)
					input[0] = null;
					return !results.pop();
				};
		}),

		"has": markFunction(function( selector ) {
			return function( elem ) {
				return Sizzle( selector, elem ).length > 0;
			};
		}),

		"contains": markFunction(function( text ) {
			text = text.replace( runescape, funescape );
			return function( elem ) {
				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
			};
		}),

		// "Whether an element is represented by a :lang() selector
		// is based solely on the element's language value
		// being equal to the identifier C,
		// or beginning with the identifier C immediately followed by "-".
		// The matching of C against the element's language value is performed case-insensitively.
		// The identifier C does not have to be a valid language name."
		// http://www.w3.org/TR/selectors/#lang-pseudo
		"lang": markFunction( function( lang ) {
			// lang value must be a valid identifier
			if ( !ridentifier.test(lang || "") ) {
				Sizzle.error( "unsupported lang: " + lang );
			}
			lang = lang.replace( runescape, funescape ).toLowerCase();
			return function( elem ) {
				var elemLang;
				do {
					if ( (elemLang = documentIsHTML ?
						elem.lang :
						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {

						elemLang = elemLang.toLowerCase();
						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
					}
				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
				return false;
			};
		}),

		// Miscellaneous
		"target": function( elem ) {
			var hash = window.location && window.location.hash;
			return hash && hash.slice( 1 ) === elem.id;
		},

		"root": function( elem ) {
			return elem === docElem;
		},

		"focus": function( elem ) {
			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
		},

		// Boolean properties
		"enabled": function( elem ) {
			return elem.disabled === false;
		},

		"disabled": function( elem ) {
			return elem.disabled === true;
		},

		"checked": function( elem ) {
			// In CSS3, :checked should return both checked and selected elements
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			var nodeName = elem.nodeName.toLowerCase();
			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
		},

		"selected": function( elem ) {
			// Accessing this property makes selected-by-default
			// options in Safari work properly
			if ( elem.parentNode ) {
				elem.parentNode.selectedIndex;
			}

			return elem.selected === true;
		},

		// Contents
		"empty": function( elem ) {
			// http://www.w3.org/TR/selectors/#empty-pseudo
			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
			//   but not by others (comment: 8; processing instruction: 7; etc.)
			// nodeType < 6 works because attributes (2) do not appear as children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				if ( elem.nodeType < 6 ) {
					return false;
				}
			}
			return true;
		},

		"parent": function( elem ) {
			return !Expr.pseudos["empty"]( elem );
		},

		// Element/input types
		"header": function( elem ) {
			return rheader.test( elem.nodeName );
		},

		"input": function( elem ) {
			return rinputs.test( elem.nodeName );
		},

		"button": function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === "button" || name === "button";
		},

		"text": function( elem ) {
			var attr;
			return elem.nodeName.toLowerCase() === "input" &&
				elem.type === "text" &&

				// Support: IE<8
				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
		},

		// Position-in-collection
		"first": createPositionalPseudo(function() {
			return [ 0 ];
		}),

		"last": createPositionalPseudo(function( matchIndexes, length ) {
			return [ length - 1 ];
		}),

		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
			return [ argument < 0 ? argument + length : argument ];
		}),

		"even": createPositionalPseudo(function( matchIndexes, length ) {
			var i = 0;
			for ( ; i < length; i += 2 ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		}),

		"odd": createPositionalPseudo(function( matchIndexes, length ) {
			var i = 1;
			for ( ; i < length; i += 2 ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		}),

		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
			var i = argument < 0 ? argument + length : argument;
			for ( ; --i >= 0; ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		}),

		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
			var i = argument < 0 ? argument + length : argument;
			for ( ; ++i < length; ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		})
	}
};

Expr.pseudos["nth"] = Expr.pseudos["eq"];

// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
	Expr.pseudos[ i ] = createInputPseudo( i );
}
for ( i in { submit: true, reset: true } ) {
	Expr.pseudos[ i ] = createButtonPseudo( i );
}

// Easy API for creating new setFilters
function setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();

tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
	var matched, match, tokens, type,
		soFar, groups, preFilters,
		cached = tokenCache[ selector + " " ];

	if ( cached ) {
		return parseOnly ? 0 : cached.slice( 0 );
	}

	soFar = selector;
	groups = [];
	preFilters = Expr.preFilter;

	while ( soFar ) {

		// Comma and first run
		if ( !matched || (match = rcomma.exec( soFar )) ) {
			if ( match ) {
				// Don't consume trailing commas as valid
				soFar = soFar.slice( match[0].length ) || soFar;
			}
			groups.push( (tokens = []) );
		}

		matched = false;

		// Combinators
		if ( (match = rcombinators.exec( soFar )) ) {
			matched = match.shift();
			tokens.push({
				value: matched,
				// Cast descendant combinators to space
				type: match[0].replace( rtrim, " " )
			});
			soFar = soFar.slice( matched.length );
		}

		// Filters
		for ( type in Expr.filter ) {
			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
				(match = preFilters[ type ]( match ))) ) {
				matched = match.shift();
				tokens.push({
					value: matched,
					type: type,
					matches: match
				});
				soFar = soFar.slice( matched.length );
			}
		}

		if ( !matched ) {
			break;
		}
	}

	// Return the length of the invalid excess
	// if we're just parsing
	// Otherwise, throw an error or return tokens
	return parseOnly ?
		soFar.length :
		soFar ?
			Sizzle.error( selector ) :
			// Cache the tokens
			tokenCache( selector, groups ).slice( 0 );
};

function toSelector( tokens ) {
	var i = 0,
		len = tokens.length,
		selector = "";
	for ( ; i < len; i++ ) {
		selector += tokens[i].value;
	}
	return selector;
}

function addCombinator( matcher, combinator, base ) {
	var dir = combinator.dir,
		checkNonElements = base && dir === "parentNode",
		doneName = done++;

	return combinator.first ?
		// Check against closest ancestor/preceding element
		function( elem, context, xml ) {
			while ( (elem = elem[ dir ]) ) {
				if ( elem.nodeType === 1 || checkNonElements ) {
					return matcher( elem, context, xml );
				}
			}
		} :

		// Check against all ancestor/preceding elements
		function( elem, context, xml ) {
			var oldCache, outerCache,
				newCache = [ dirruns, doneName ];

			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
			if ( xml ) {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						if ( matcher( elem, context, xml ) ) {
							return true;
						}
					}
				}
			} else {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						outerCache = elem[ expando ] || (elem[ expando ] = {});
						if ( (oldCache = outerCache[ dir ]) &&
							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {

							// Assign to newCache so results back-propagate to previous elements
							return (newCache[ 2 ] = oldCache[ 2 ]);
						} else {
							// Reuse newcache so results back-propagate to previous elements
							outerCache[ dir ] = newCache;

							// A match means we're done; a fail means we have to keep checking
							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
								return true;
							}
						}
					}
				}
			}
		};
}

function elementMatcher( matchers ) {
	return matchers.length > 1 ?
		function( elem, context, xml ) {
			var i = matchers.length;
			while ( i-- ) {
				if ( !matchers[i]( elem, context, xml ) ) {
					return false;
				}
			}
			return true;
		} :
		matchers[0];
}

function multipleContexts( selector, contexts, results ) {
	var i = 0,
		len = contexts.length;
	for ( ; i < len; i++ ) {
		Sizzle( selector, contexts[i], results );
	}
	return results;
}

function condense( unmatched, map, filter, context, xml ) {
	var elem,
		newUnmatched = [],
		i = 0,
		len = unmatched.length,
		mapped = map != null;

	for ( ; i < len; i++ ) {
		if ( (elem = unmatched[i]) ) {
			if ( !filter || filter( elem, context, xml ) ) {
				newUnmatched.push( elem );
				if ( mapped ) {
					map.push( i );
				}
			}
		}
	}

	return newUnmatched;
}

function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
	if ( postFilter && !postFilter[ expando ] ) {
		postFilter = setMatcher( postFilter );
	}
	if ( postFinder && !postFinder[ expando ] ) {
		postFinder = setMatcher( postFinder, postSelector );
	}
	return markFunction(function( seed, results, context, xml ) {
		var temp, i, elem,
			preMap = [],
			postMap = [],
			preexisting = results.length,

			// Get initial elements from seed or context
			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),

			// Prefilter to get matcher input, preserving a map for seed-results synchronization
			matcherIn = preFilter && ( seed || !selector ) ?
				condense( elems, preMap, preFilter, context, xml ) :
				elems,

			matcherOut = matcher ?
				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?

					// ...intermediate processing is necessary
					[] :

					// ...otherwise use results directly
					results :
				matcherIn;

		// Find primary matches
		if ( matcher ) {
			matcher( matcherIn, matcherOut, context, xml );
		}

		// Apply postFilter
		if ( postFilter ) {
			temp = condense( matcherOut, postMap );
			postFilter( temp, [], context, xml );

			// Un-match failing elements by moving them back to matcherIn
			i = temp.length;
			while ( i-- ) {
				if ( (elem = temp[i]) ) {
					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
				}
			}
		}

		if ( seed ) {
			if ( postFinder || preFilter ) {
				if ( postFinder ) {
					// Get the final matcherOut by condensing this intermediate into postFinder contexts
					temp = [];
					i = matcherOut.length;
					while ( i-- ) {
						if ( (elem = matcherOut[i]) ) {
							// Restore matcherIn since elem is not yet a final match
							temp.push( (matcherIn[i] = elem) );
						}
					}
					postFinder( null, (matcherOut = []), temp, xml );
				}

				// Move matched elements from seed to results to keep them synchronized
				i = matcherOut.length;
				while ( i-- ) {
					if ( (elem = matcherOut[i]) &&
						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {

						seed[temp] = !(results[temp] = elem);
					}
				}
			}

		// Add elements to results, through postFinder if defined
		} else {
			matcherOut = condense(
				matcherOut === results ?
					matcherOut.splice( preexisting, matcherOut.length ) :
					matcherOut
			);
			if ( postFinder ) {
				postFinder( null, results, matcherOut, xml );
			} else {
				push.apply( results, matcherOut );
			}
		}
	});
}

function matcherFromTokens( tokens ) {
	var checkContext, matcher, j,
		len = tokens.length,
		leadingRelative = Expr.relative[ tokens[0].type ],
		implicitRelative = leadingRelative || Expr.relative[" "],
		i = leadingRelative ? 1 : 0,

		// The foundational matcher ensures that elements are reachable from top-level context(s)
		matchContext = addCombinator( function( elem ) {
			return elem === checkContext;
		}, implicitRelative, true ),
		matchAnyContext = addCombinator( function( elem ) {
			return indexOf( checkContext, elem ) > -1;
		}, implicitRelative, true ),
		matchers = [ function( elem, context, xml ) {
			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
				(checkContext = context).nodeType ?
					matchContext( elem, context, xml ) :
					matchAnyContext( elem, context, xml ) );
			// Avoid hanging onto element (issue #299)
			checkContext = null;
			return ret;
		} ];

	for ( ; i < len; i++ ) {
		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
		} else {
			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );

			// Return special upon seeing a positional matcher
			if ( matcher[ expando ] ) {
				// Find the next relative operator (if any) for proper handling
				j = ++i;
				for ( ; j < len; j++ ) {
					if ( Expr.relative[ tokens[j].type ] ) {
						break;
					}
				}
				return setMatcher(
					i > 1 && elementMatcher( matchers ),
					i > 1 && toSelector(
						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
					).replace( rtrim, "$1" ),
					matcher,
					i < j && matcherFromTokens( tokens.slice( i, j ) ),
					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
					j < len && toSelector( tokens )
				);
			}
			matchers.push( matcher );
		}
	}

	return elementMatcher( matchers );
}

function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
	var bySet = setMatchers.length > 0,
		byElement = elementMatchers.length > 0,
		superMatcher = function( seed, context, xml, results, outermost ) {
			var elem, j, matcher,
				matchedCount = 0,
				i = "0",
				unmatched = seed && [],
				setMatched = [],
				contextBackup = outermostContext,
				// We must always have either seed elements or outermost context
				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
				// Use integer dirruns iff this is the outermost matcher
				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
				len = elems.length;

			if ( outermost ) {
				outermostContext = context !== document && context;
			}

			// Add elements passing elementMatchers directly to results
			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
			// Support: IE<9, Safari
			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
				if ( byElement && elem ) {
					j = 0;
					while ( (matcher = elementMatchers[j++]) ) {
						if ( matcher( elem, context, xml ) ) {
							results.push( elem );
							break;
						}
					}
					if ( outermost ) {
						dirruns = dirrunsUnique;
					}
				}

				// Track unmatched elements for set filters
				if ( bySet ) {
					// They will have gone through all possible matchers
					if ( (elem = !matcher && elem) ) {
						matchedCount--;
					}

					// Lengthen the array for every element, matched or not
					if ( seed ) {
						unmatched.push( elem );
					}
				}
			}

			// Apply set filters to unmatched elements
			matchedCount += i;
			if ( bySet && i !== matchedCount ) {
				j = 0;
				while ( (matcher = setMatchers[j++]) ) {
					matcher( unmatched, setMatched, context, xml );
				}

				if ( seed ) {
					// Reintegrate element matches to eliminate the need for sorting
					if ( matchedCount > 0 ) {
						while ( i-- ) {
							if ( !(unmatched[i] || setMatched[i]) ) {
								setMatched[i] = pop.call( results );
							}
						}
					}

					// Discard index placeholder values to get only actual matches
					setMatched = condense( setMatched );
				}

				// Add matches to results
				push.apply( results, setMatched );

				// Seedless set matches succeeding multiple successful matchers stipulate sorting
				if ( outermost && !seed && setMatched.length > 0 &&
					( matchedCount + setMatchers.length ) > 1 ) {

					Sizzle.uniqueSort( results );
				}
			}

			// Override manipulation of globals by nested matchers
			if ( outermost ) {
				dirruns = dirrunsUnique;
				outermostContext = contextBackup;
			}

			return unmatched;
		};

	return bySet ?
		markFunction( superMatcher ) :
		superMatcher;
}

compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
	var i,
		setMatchers = [],
		elementMatchers = [],
		cached = compilerCache[ selector + " " ];

	if ( !cached ) {
		// Generate a function of recursive functions that can be used to check each element
		if ( !match ) {
			match = tokenize( selector );
		}
		i = match.length;
		while ( i-- ) {
			cached = matcherFromTokens( match[i] );
			if ( cached[ expando ] ) {
				setMatchers.push( cached );
			} else {
				elementMatchers.push( cached );
			}
		}

		// Cache the compiled function
		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );

		// Save selector and tokenization
		cached.selector = selector;
	}
	return cached;
};

/**
 * A low-level selection function that works with Sizzle's compiled
 *  selector functions
 * @param {String|Function} selector A selector or a pre-compiled
 *  selector function built with Sizzle.compile
 * @param {Element} context
 * @param {Array} [results]
 * @param {Array} [seed] A set of elements to match against
 */
select = Sizzle.select = function( selector, context, results, seed ) {
	var i, tokens, token, type, find,
		compiled = typeof selector === "function" && selector,
		match = !seed && tokenize( (selector = compiled.selector || selector) );

	results = results || [];

	// Try to minimize operations if there is no seed and only one group
	if ( match.length === 1 ) {

		// Take a shortcut and set the context if the root selector is an ID
		tokens = match[0] = match[0].slice( 0 );
		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
				support.getById && context.nodeType === 9 && documentIsHTML &&
				Expr.relative[ tokens[1].type ] ) {

			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
			if ( !context ) {
				return results;

			// Precompiled matchers will still verify ancestry, so step up a level
			} else if ( compiled ) {
				context = context.parentNode;
			}

			selector = selector.slice( tokens.shift().value.length );
		}

		// Fetch a seed set for right-to-left matching
		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
		while ( i-- ) {
			token = tokens[i];

			// Abort if we hit a combinator
			if ( Expr.relative[ (type = token.type) ] ) {
				break;
			}
			if ( (find = Expr.find[ type ]) ) {
				// Search, expanding context for leading sibling combinators
				if ( (seed = find(
					token.matches[0].replace( runescape, funescape ),
					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
				)) ) {

					// If seed is empty or no tokens remain, we can return early
					tokens.splice( i, 1 );
					selector = seed.length && toSelector( tokens );
					if ( !selector ) {
						push.apply( results, seed );
						return results;
					}

					break;
				}
			}
		}
	}

	// Compile and execute a filtering function if one is not provided
	// Provide `match` to avoid retokenization if we modified the selector above
	( compiled || compile( selector, match ) )(
		seed,
		context,
		!documentIsHTML,
		results,
		rsibling.test( selector ) && testContext( context.parentNode ) || context
	);
	return results;
};

// One-time assignments

// Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;

// Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = !!hasDuplicate;

// Initialize against the default document
setDocument();

// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
// Detached nodes confoundingly follow *each other*
support.sortDetached = assert(function( div1 ) {
	// Should return 1, but returns 4 (following)
	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
});

// Support: IE<8
// Prevent attribute/property "interpolation"
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !assert(function( div ) {
	div.innerHTML = "<a href='#'></a>";
	return div.firstChild.getAttribute("href") === "#" ;
}) ) {
	addHandle( "type|href|height|width", function( elem, name, isXML ) {
		if ( !isXML ) {
			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
		}
	});
}

// Support: IE<9
// Use defaultValue in place of getAttribute("value")
if ( !support.attributes || !assert(function( div ) {
	div.innerHTML = "<input/>";
	div.firstChild.setAttribute( "value", "" );
	return div.firstChild.getAttribute( "value" ) === "";
}) ) {
	addHandle( "value", function( elem, name, isXML ) {
		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
			return elem.defaultValue;
		}
	});
}

// Support: IE<9
// Use getAttributeNode to fetch booleans when getAttribute lies
if ( !assert(function( div ) {
	return div.getAttribute("disabled") == null;
}) ) {
	addHandle( booleans, function( elem, name, isXML ) {
		var val;
		if ( !isXML ) {
			return elem[ name ] === true ? name.toLowerCase() :
					(val = elem.getAttributeNode( name )) && val.specified ?
					val.value :
				null;
		}
	});
}

return Sizzle;

})( window );



jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;



var rneedsContext = jQuery.expr.match.needsContext;

var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);



var risSimple = /^.[^:#\[\.,]*$/;

// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
	if ( jQuery.isFunction( qualifier ) ) {
		return jQuery.grep( elements, function( elem, i ) {
			/* jshint -W018 */
			return !!qualifier.call( elem, i, elem ) !== not;
		});

	}

	if ( qualifier.nodeType ) {
		return jQuery.grep( elements, function( elem ) {
			return ( elem === qualifier ) !== not;
		});

	}

	if ( typeof qualifier === "string" ) {
		if ( risSimple.test( qualifier ) ) {
			return jQuery.filter( qualifier, elements, not );
		}

		qualifier = jQuery.filter( qualifier, elements );
	}

	return jQuery.grep( elements, function( elem ) {
		return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
	});
}

jQuery.filter = function( expr, elems, not ) {
	var elem = elems[ 0 ];

	if ( not ) {
		expr = ":not(" + expr + ")";
	}

	return elems.length === 1 && elem.nodeType === 1 ?
		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
			return elem.nodeType === 1;
		}));
};

jQuery.fn.extend({
	find: function( selector ) {
		var i,
			len = this.length,
			ret = [],
			self = this;

		if ( typeof selector !== "string" ) {
			return this.pushStack( jQuery( selector ).filter(function() {
				for ( i = 0; i < len; i++ ) {
					if ( jQuery.contains( self[ i ], this ) ) {
						return true;
					}
				}
			}) );
		}

		for ( i = 0; i < len; i++ ) {
			jQuery.find( selector, self[ i ], ret );
		}

		// Needed because $( selector, context ) becomes $( context ).find( selector )
		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
		ret.selector = this.selector ? this.selector + " " + selector : selector;
		return ret;
	},
	filter: function( selector ) {
		return this.pushStack( winnow(this, selector || [], false) );
	},
	not: function( selector ) {
		return this.pushStack( winnow(this, selector || [], true) );
	},
	is: function( selector ) {
		return !!winnow(
			this,

			// If this is a positional/relative selector, check membership in the returned set
			// so $("p:first").is("p:last") won't return true for a doc with two "p".
			typeof selector === "string" && rneedsContext.test( selector ) ?
				jQuery( selector ) :
				selector || [],
			false
		).length;
	}
});


// Initialize a jQuery object


// A central reference to the root jQuery(document)
var rootjQuery,

	// A simple way to check for HTML strings
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
	// Strict HTML recognition (#11290: must start with <)
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

	init = jQuery.fn.init = function( selector, context ) {
		var match, elem;

		// HANDLE: $(""), $(null), $(undefined), $(false)
		if ( !selector ) {
			return this;
		}

		// Handle HTML strings
		if ( typeof selector === "string" ) {
			if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
				// Assume that strings that start and end with <> are HTML and skip the regex check
				match = [ null, selector, null ];

			} else {
				match = rquickExpr.exec( selector );
			}

			// Match html or make sure no context is specified for #id
			if ( match && (match[1] || !context) ) {

				// HANDLE: $(html) -> $(array)
				if ( match[1] ) {
					context = context instanceof jQuery ? context[0] : context;

					// Option to run scripts is true for back-compat
					// Intentionally let the error be thrown if parseHTML is not present
					jQuery.merge( this, jQuery.parseHTML(
						match[1],
						context && context.nodeType ? context.ownerDocument || context : document,
						true
					) );

					// HANDLE: $(html, props)
					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
						for ( match in context ) {
							// Properties of context are called as methods if possible
							if ( jQuery.isFunction( this[ match ] ) ) {
								this[ match ]( context[ match ] );

							// ...and otherwise set as attributes
							} else {
								this.attr( match, context[ match ] );
							}
						}
					}

					return this;

				// HANDLE: $(#id)
				} else {
					elem = document.getElementById( match[2] );

					// Support: Blackberry 4.6
					// gEBID returns nodes no longer in the document (#6963)
					if ( elem && elem.parentNode ) {
						// Inject the element directly into the jQuery object
						this.length = 1;
						this[0] = elem;
					}

					this.context = document;
					this.selector = selector;
					return this;
				}

			// HANDLE: $(expr, $(...))
			} else if ( !context || context.jquery ) {
				return ( context || rootjQuery ).find( selector );

			// HANDLE: $(expr, context)
			// (which is just equivalent to: $(context).find(expr)
			} else {
				return this.constructor( context ).find( selector );
			}

		// HANDLE: $(DOMElement)
		} else if ( selector.nodeType ) {
			this.context = this[0] = selector;
			this.length = 1;
			return this;

		// HANDLE: $(function)
		// Shortcut for document ready
		} else if ( jQuery.isFunction( selector ) ) {
			return typeof rootjQuery.ready !== "undefined" ?
				rootjQuery.ready( selector ) :
				// Execute immediately if ready is not present
				selector( jQuery );
		}

		if ( selector.selector !== undefined ) {
			this.selector = selector.selector;
			this.context = selector.context;
		}

		return jQuery.makeArray( selector, this );
	};

// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;

// Initialize central reference
rootjQuery = jQuery( document );


var rparentsprev = /^(?:parents|prev(?:Until|All))/,
	// Methods guaranteed to produce a unique set when starting from a unique set
	guaranteedUnique = {
		children: true,
		contents: true,
		next: true,
		prev: true
	};

jQuery.extend({
	dir: function( elem, dir, until ) {
		var matched = [],
			truncate = until !== undefined;

		while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
			if ( elem.nodeType === 1 ) {
				if ( truncate && jQuery( elem ).is( until ) ) {
					break;
				}
				matched.push( elem );
			}
		}
		return matched;
	},

	sibling: function( n, elem ) {
		var matched = [];

		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				matched.push( n );
			}
		}

		return matched;
	}
});

jQuery.fn.extend({
	has: function( target ) {
		var targets = jQuery( target, this ),
			l = targets.length;

		return this.filter(function() {
			var i = 0;
			for ( ; i < l; i++ ) {
				if ( jQuery.contains( this, targets[i] ) ) {
					return true;
				}
			}
		});
	},

	closest: function( selectors, context ) {
		var cur,
			i = 0,
			l = this.length,
			matched = [],
			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
				jQuery( selectors, context || this.context ) :
				0;

		for ( ; i < l; i++ ) {
			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
				// Always skip document fragments
				if ( cur.nodeType < 11 && (pos ?
					pos.index(cur) > -1 :

					// Don't pass non-elements to Sizzle
					cur.nodeType === 1 &&
						jQuery.find.matchesSelector(cur, selectors)) ) {

					matched.push( cur );
					break;
				}
			}
		}

		return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
	},

	// Determine the position of an element within the set
	index: function( elem ) {

		// No argument, return index in parent
		if ( !elem ) {
			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
		}

		// Index in selector
		if ( typeof elem === "string" ) {
			return indexOf.call( jQuery( elem ), this[ 0 ] );
		}

		// Locate the position of the desired element
		return indexOf.call( this,

			// If it receives a jQuery object, the first element is used
			elem.jquery ? elem[ 0 ] : elem
		);
	},

	add: function( selector, context ) {
		return this.pushStack(
			jQuery.unique(
				jQuery.merge( this.get(), jQuery( selector, context ) )
			)
		);
	},

	addBack: function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter(selector)
		);
	}
});

function sibling( cur, dir ) {
	while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
	return cur;
}

jQuery.each({
	parent: function( elem ) {
		var parent = elem.parentNode;
		return parent && parent.nodeType !== 11 ? parent : null;
	},
	parents: function( elem ) {
		return jQuery.dir( elem, "parentNode" );
	},
	parentsUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "parentNode", until );
	},
	next: function( elem ) {
		return sibling( elem, "nextSibling" );
	},
	prev: function( elem ) {
		return sibling( elem, "previousSibling" );
	},
	nextAll: function( elem ) {
		return jQuery.dir( elem, "nextSibling" );
	},
	prevAll: function( elem ) {
		return jQuery.dir( elem, "previousSibling" );
	},
	nextUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "nextSibling", until );
	},
	prevUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "previousSibling", until );
	},
	siblings: function( elem ) {
		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
	},
	children: function( elem ) {
		return jQuery.sibling( elem.firstChild );
	},
	contents: function( elem ) {
		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
	}
}, function( name, fn ) {
	jQuery.fn[ name ] = function( until, selector ) {
		var matched = jQuery.map( this, fn, until );

		if ( name.slice( -5 ) !== "Until" ) {
			selector = until;
		}

		if ( selector && typeof selector === "string" ) {
			matched = jQuery.filter( selector, matched );
		}

		if ( this.length > 1 ) {
			// Remove duplicates
			if ( !guaranteedUnique[ name ] ) {
				jQuery.unique( matched );
			}

			// Reverse order for parents* and prev-derivatives
			if ( rparentsprev.test( name ) ) {
				matched.reverse();
			}
		}

		return this.pushStack( matched );
	};
});
var rnotwhite = (/\S+/g);



// String to Object options format cache
var optionsCache = {};

// Convert String-formatted options into Object-formatted ones and store in cache
function createOptions( options ) {
	var object = optionsCache[ options ] = {};
	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
		object[ flag ] = true;
	});
	return object;
}

/*
 * Create a callback list using the following parameters:
 *
 *	options: an optional list of space-separated options that will change how
 *			the callback list behaves or a more traditional option object
 *
 * By default a callback list will act like an event callback list and can be
 * "fired" multiple times.
 *
 * Possible options:
 *
 *	once:			will ensure the callback list can only be fired once (like a Deferred)
 *
 *	memory:			will keep track of previous values and will call any callback added
 *					after the list has been fired right away with the latest "memorized"
 *					values (like a Deferred)
 *
 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
 *
 *	stopOnFalse:	interrupt callings when a callback returns false
 *
 */
jQuery.Callbacks = function( options ) {

	// Convert options from String-formatted to Object-formatted if needed
	// (we check in cache first)
	options = typeof options === "string" ?
		( optionsCache[ options ] || createOptions( options ) ) :
		jQuery.extend( {}, options );

	var // Last fire value (for non-forgettable lists)
		memory,
		// Flag to know if list was already fired
		fired,
		// Flag to know if list is currently firing
		firing,
		// First callback to fire (used internally by add and fireWith)
		firingStart,
		// End of the loop when firing
		firingLength,
		// Index of currently firing callback (modified by remove if needed)
		firingIndex,
		// Actual callback list
		list = [],
		// Stack of fire calls for repeatable lists
		stack = !options.once && [],
		// Fire callbacks
		fire = function( data ) {
			memory = options.memory && data;
			fired = true;
			firingIndex = firingStart || 0;
			firingStart = 0;
			firingLength = list.length;
			firing = true;
			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
					memory = false; // To prevent further calls using add
					break;
				}
			}
			firing = false;
			if ( list ) {
				if ( stack ) {
					if ( stack.length ) {
						fire( stack.shift() );
					}
				} else if ( memory ) {
					list = [];
				} else {
					self.disable();
				}
			}
		},
		// Actual Callbacks object
		self = {
			// Add a callback or a collection of callbacks to the list
			add: function() {
				if ( list ) {
					// First, we save the current length
					var start = list.length;
					(function add( args ) {
						jQuery.each( args, function( _, arg ) {
							var type = jQuery.type( arg );
							if ( type === "function" ) {
								if ( !options.unique || !self.has( arg ) ) {
									list.push( arg );
								}
							} else if ( arg && arg.length && type !== "string" ) {
								// Inspect recursively
								add( arg );
							}
						});
					})( arguments );
					// Do we need to add the callbacks to the
					// current firing batch?
					if ( firing ) {
						firingLength = list.length;
					// With memory, if we're not firing then
					// we should call right away
					} else if ( memory ) {
						firingStart = start;
						fire( memory );
					}
				}
				return this;
			},
			// Remove a callback from the list
			remove: function() {
				if ( list ) {
					jQuery.each( arguments, function( _, arg ) {
						var index;
						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
							list.splice( index, 1 );
							// Handle firing indexes
							if ( firing ) {
								if ( index <= firingLength ) {
									firingLength--;
								}
								if ( index <= firingIndex ) {
									firingIndex--;
								}
							}
						}
					});
				}
				return this;
			},
			// Check if a given callback is in the list.
			// If no argument is given, return whether or not list has callbacks attached.
			has: function( fn ) {
				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
			},
			// Remove all callbacks from the list
			empty: function() {
				list = [];
				firingLength = 0;
				return this;
			},
			// Have the list do nothing anymore
			disable: function() {
				list = stack = memory = undefined;
				return this;
			},
			// Is it disabled?
			disabled: function() {
				return !list;
			},
			// Lock the list in its current state
			lock: function() {
				stack = undefined;
				if ( !memory ) {
					self.disable();
				}
				return this;
			},
			// Is it locked?
			locked: function() {
				return !stack;
			},
			// Call all callbacks with the given context and arguments
			fireWith: function( context, args ) {
				if ( list && ( !fired || stack ) ) {
					args = args || [];
					args = [ context, args.slice ? args.slice() : args ];
					if ( firing ) {
						stack.push( args );
					} else {
						fire( args );
					}
				}
				return this;
			},
			// Call all the callbacks with the given arguments
			fire: function() {
				self.fireWith( this, arguments );
				return this;
			},
			// To know if the callbacks have already been called at least once
			fired: function() {
				return !!fired;
			}
		};

	return self;
};


jQuery.extend({

	Deferred: function( func ) {
		var tuples = [
				// action, add listener, listener list, final state
				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
				[ "notify", "progress", jQuery.Callbacks("memory") ]
			],
			state = "pending",
			promise = {
				state: function() {
					return state;
				},
				always: function() {
					deferred.done( arguments ).fail( arguments );
					return this;
				},
				then: function( /* fnDone, fnFail, fnProgress */ ) {
					var fns = arguments;
					return jQuery.Deferred(function( newDefer ) {
						jQuery.each( tuples, function( i, tuple ) {
							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
							// deferred[ done | fail | progress ] for forwarding actions to newDefer
							deferred[ tuple[1] ](function() {
								var returned = fn && fn.apply( this, arguments );
								if ( returned && jQuery.isFunction( returned.promise ) ) {
									returned.promise()
										.done( newDefer.resolve )
										.fail( newDefer.reject )
										.progress( newDefer.notify );
								} else {
									newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
								}
							});
						});
						fns = null;
					}).promise();
				},
				// Get a promise for this deferred
				// If obj is provided, the promise aspect is added to the object
				promise: function( obj ) {
					return obj != null ? jQuery.extend( obj, promise ) : promise;
				}
			},
			deferred = {};

		// Keep pipe for back-compat
		promise.pipe = promise.then;

		// Add list-specific methods
		jQuery.each( tuples, function( i, tuple ) {
			var list = tuple[ 2 ],
				stateString = tuple[ 3 ];

			// promise[ done | fail | progress ] = list.add
			promise[ tuple[1] ] = list.add;

			// Handle state
			if ( stateString ) {
				list.add(function() {
					// state = [ resolved | rejected ]
					state = stateString;

				// [ reject_list | resolve_list ].disable; progress_list.lock
				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
			}

			// deferred[ resolve | reject | notify ]
			deferred[ tuple[0] ] = function() {
				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
				return this;
			};
			deferred[ tuple[0] + "With" ] = list.fireWith;
		});

		// Make the deferred a promise
		promise.promise( deferred );

		// Call given func if any
		if ( func ) {
			func.call( deferred, deferred );
		}

		// All done!
		return deferred;
	},

	// Deferred helper
	when: function( subordinate /* , ..., subordinateN */ ) {
		var i = 0,
			resolveValues = slice.call( arguments ),
			length = resolveValues.length,

			// the count of uncompleted subordinates
			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

			// Update function for both resolve and progress values
			updateFunc = function( i, contexts, values ) {
				return function( value ) {
					contexts[ i ] = this;
					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
					if ( values === progressValues ) {
						deferred.notifyWith( contexts, values );
					} else if ( !( --remaining ) ) {
						deferred.resolveWith( contexts, values );
					}
				};
			},

			progressValues, progressContexts, resolveContexts;

		// Add listeners to Deferred subordinates; treat others as resolved
		if ( length > 1 ) {
			progressValues = new Array( length );
			progressContexts = new Array( length );
			resolveContexts = new Array( length );
			for ( ; i < length; i++ ) {
				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
					resolveValues[ i ].promise()
						.done( updateFunc( i, resolveContexts, resolveValues ) )
						.fail( deferred.reject )
						.progress( updateFunc( i, progressContexts, progressValues ) );
				} else {
					--remaining;
				}
			}
		}

		// If we're not waiting on anything, resolve the master
		if ( !remaining ) {
			deferred.resolveWith( resolveContexts, resolveValues );
		}

		return deferred.promise();
	}
});


// The deferred used on DOM ready
var readyList;

jQuery.fn.ready = function( fn ) {
	// Add the callback
	jQuery.ready.promise().done( fn );

	return this;
};

jQuery.extend({
	// Is the DOM ready to be used? Set to true once it occurs.
	isReady: false,

	// A counter to track how many items to wait for before
	// the ready event fires. See #6781
	readyWait: 1,

	// Hold (or release) the ready event
	holdReady: function( hold ) {
		if ( hold ) {
			jQuery.readyWait++;
		} else {
			jQuery.ready( true );
		}
	},

	// Handle when the DOM is ready
	ready: function( wait ) {

		// Abort if there are pending holds or we're already ready
		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
			return;
		}

		// Remember that the DOM is ready
		jQuery.isReady = true;

		// If a normal DOM Ready event fired, decrement, and wait if need be
		if ( wait !== true && --jQuery.readyWait > 0 ) {
			return;
		}

		// If there are functions bound, to execute
		readyList.resolveWith( document, [ jQuery ] );

		// Trigger any bound ready events
		if ( jQuery.fn.triggerHandler ) {
			jQuery( document ).triggerHandler( "ready" );
			jQuery( document ).off( "ready" );
		}
	}
});

/**
 * The ready event handler and self cleanup method
 */
function completed() {
	document.removeEventListener( "DOMContentLoaded", completed, false );
	window.removeEventListener( "load", completed, false );
	jQuery.ready();
}

jQuery.ready.promise = function( obj ) {
	if ( !readyList ) {

		readyList = jQuery.Deferred();

		// Catch cases where $(document).ready() is called after the browser event has already occurred.
		// We once tried to use readyState "interactive" here, but it caused issues like the one
		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
		if ( document.readyState === "complete" ) {
			// Handle it asynchronously to allow scripts the opportunity to delay ready
			setTimeout( jQuery.ready );

		} else {

			// Use the handy event callback
			document.addEventListener( "DOMContentLoaded", completed, false );

			// A fallback to window.onload, that will always work
			window.addEventListener( "load", completed, false );
		}
	}
	return readyList.promise( obj );
};

// Kick off the DOM ready check even if the user does not
jQuery.ready.promise();




// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
	var i = 0,
		len = elems.length,
		bulk = key == null;

	// Sets many values
	if ( jQuery.type( key ) === "object" ) {
		chainable = true;
		for ( i in key ) {
			jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
		}

	// Sets one value
	} else if ( value !== undefined ) {
		chainable = true;

		if ( !jQuery.isFunction( value ) ) {
			raw = true;
		}

		if ( bulk ) {
			// Bulk operations run against the entire set
			if ( raw ) {
				fn.call( elems, value );
				fn = null;

			// ...except when executing function values
			} else {
				bulk = fn;
				fn = function( elem, key, value ) {
					return bulk.call( jQuery( elem ), value );
				};
			}
		}

		if ( fn ) {
			for ( ; i < len; i++ ) {
				fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
			}
		}
	}

	return chainable ?
		elems :

		// Gets
		bulk ?
			fn.call( elems ) :
			len ? fn( elems[0], key ) : emptyGet;
};


/**
 * Determines whether an object can have data
 */
jQuery.acceptData = function( owner ) {
	// Accepts only:
	//  - Node
	//    - Node.ELEMENT_NODE
	//    - Node.DOCUMENT_NODE
	//  - Object
	//    - Any
	/* jshint -W018 */
	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};


function Data() {
	// Support: Android<4,
	// Old WebKit does not have Object.preventExtensions/freeze method,
	// return new empty object instead with no [[set]] accessor
	Object.defineProperty( this.cache = {}, 0, {
		get: function() {
			return {};
		}
	});

	this.expando = jQuery.expando + Data.uid++;
}

Data.uid = 1;
Data.accepts = jQuery.acceptData;

Data.prototype = {
	key: function( owner ) {
		// We can accept data for non-element nodes in modern browsers,
		// but we should not, see #8335.
		// Always return the key for a frozen object.
		if ( !Data.accepts( owner ) ) {
			return 0;
		}

		var descriptor = {},
			// Check if the owner object already has a cache key
			unlock = owner[ this.expando ];

		// If not, create one
		if ( !unlock ) {
			unlock = Data.uid++;

			// Secure it in a non-enumerable, non-writable property
			try {
				descriptor[ this.expando ] = { value: unlock };
				Object.defineProperties( owner, descriptor );

			// Support: Android<4
			// Fallback to a less secure definition
			} catch ( e ) {
				descriptor[ this.expando ] = unlock;
				jQuery.extend( owner, descriptor );
			}
		}

		// Ensure the cache object
		if ( !this.cache[ unlock ] ) {
			this.cache[ unlock ] = {};
		}

		return unlock;
	},
	set: function( owner, data, value ) {
		var prop,
			// There may be an unlock assigned to this node,
			// if there is no entry for this "owner", create one inline
			// and set the unlock as though an owner entry had always existed
			unlock = this.key( owner ),
			cache = this.cache[ unlock ];

		// Handle: [ owner, key, value ] args
		if ( typeof data === "string" ) {
			cache[ data ] = value;

		// Handle: [ owner, { properties } ] args
		} else {
			// Fresh assignments by object are shallow copied
			if ( jQuery.isEmptyObject( cache ) ) {
				jQuery.extend( this.cache[ unlock ], data );
			// Otherwise, copy the properties one-by-one to the cache object
			} else {
				for ( prop in data ) {
					cache[ prop ] = data[ prop ];
				}
			}
		}
		return cache;
	},
	get: function( owner, key ) {
		// Either a valid cache is found, or will be created.
		// New caches will be created and the unlock returned,
		// allowing direct access to the newly created
		// empty data object. A valid owner object must be provided.
		var cache = this.cache[ this.key( owner ) ];

		return key === undefined ?
			cache : cache[ key ];
	},
	access: function( owner, key, value ) {
		var stored;
		// In cases where either:
		//
		//   1. No key was specified
		//   2. A string key was specified, but no value provided
		//
		// Take the "read" path and allow the get method to determine
		// which value to return, respectively either:
		//
		//   1. The entire cache object
		//   2. The data stored at the key
		//
		if ( key === undefined ||
				((key && typeof key === "string") && value === undefined) ) {

			stored = this.get( owner, key );

			return stored !== undefined ?
				stored : this.get( owner, jQuery.camelCase(key) );
		}

		// [*]When the key is not a string, or both a key and value
		// are specified, set or extend (existing objects) with either:
		//
		//   1. An object of properties
		//   2. A key and value
		//
		this.set( owner, key, value );

		// Since the "set" path can have two possible entry points
		// return the expected data based on which path was taken[*]
		return value !== undefined ? value : key;
	},
	remove: function( owner, key ) {
		var i, name, camel,
			unlock = this.key( owner ),
			cache = this.cache[ unlock ];

		if ( key === undefined ) {
			this.cache[ unlock ] = {};

		} else {
			// Support array or space separated string of keys
			if ( jQuery.isArray( key ) ) {
				// If "name" is an array of keys...
				// When data is initially created, via ("key", "val") signature,
				// keys will be converted to camelCase.
				// Since there is no way to tell _how_ a key was added, remove
				// both plain key and camelCase key. #12786
				// This will only penalize the array argument path.
				name = key.concat( key.map( jQuery.camelCase ) );
			} else {
				camel = jQuery.camelCase( key );
				// Try the string as a key before any manipulation
				if ( key in cache ) {
					name = [ key, camel ];
				} else {
					// If a key with the spaces exists, use it.
					// Otherwise, create an array by matching non-whitespace
					name = camel;
					name = name in cache ?
						[ name ] : ( name.match( rnotwhite ) || [] );
				}
			}

			i = name.length;
			while ( i-- ) {
				delete cache[ name[ i ] ];
			}
		}
	},
	hasData: function( owner ) {
		return !jQuery.isEmptyObject(
			this.cache[ owner[ this.expando ] ] || {}
		);
	},
	discard: function( owner ) {
		if ( owner[ this.expando ] ) {
			delete this.cache[ owner[ this.expando ] ];
		}
	}
};
var data_priv = new Data();

var data_user = new Data();



//	Implementation Summary
//
//	1. Enforce API surface and semantic compatibility with 1.9.x branch
//	2. Improve the module's maintainability by reducing the storage
//		paths to a single mechanism.
//	3. Use the same single mechanism to support "private" and "user" data.
//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
//	5. Avoid exposing implementation details on user objects (eg. expando properties)
//	6. Provide a clear path for implementation upgrade to WeakMap in 2014

var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
	rmultiDash = /([A-Z])/g;

function dataAttr( elem, key, data ) {
	var name;

	// If nothing was found internally, try to fetch any
	// data from the HTML5 data-* attribute
	if ( data === undefined && elem.nodeType === 1 ) {
		name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
		data = elem.getAttribute( name );

		if ( typeof data === "string" ) {
			try {
				data = data === "true" ? true :
					data === "false" ? false :
					data === "null" ? null :
					// Only convert to a number if it doesn't change the string
					+data + "" === data ? +data :
					rbrace.test( data ) ? jQuery.parseJSON( data ) :
					data;
			} catch( e ) {}

			// Make sure we set the data so it isn't changed later
			data_user.set( elem, key, data );
		} else {
			data = undefined;
		}
	}
	return data;
}

jQuery.extend({
	hasData: function( elem ) {
		return data_user.hasData( elem ) || data_priv.hasData( elem );
	},

	data: function( elem, name, data ) {
		return data_user.access( elem, name, data );
	},

	removeData: function( elem, name ) {
		data_user.remove( elem, name );
	},

	// TODO: Now that all calls to _data and _removeData have been replaced
	// with direct calls to data_priv methods, these can be deprecated.
	_data: function( elem, name, data ) {
		return data_priv.access( elem, name, data );
	},

	_removeData: function( elem, name ) {
		data_priv.remove( elem, name );
	}
});

jQuery.fn.extend({
	data: function( key, value ) {
		var i, name, data,
			elem = this[ 0 ],
			attrs = elem && elem.attributes;

		// Gets all values
		if ( key === undefined ) {
			if ( this.length ) {
				data = data_user.get( elem );

				if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
					i = attrs.length;
					while ( i-- ) {

						// Support: IE11+
						// The attrs elements can be null (#14894)
						if ( attrs[ i ] ) {
							name = attrs[ i ].name;
							if ( name.indexOf( "data-" ) === 0 ) {
								name = jQuery.camelCase( name.slice(5) );
								dataAttr( elem, name, data[ name ] );
							}
						}
					}
					data_priv.set( elem, "hasDataAttrs", true );
				}
			}

			return data;
		}

		// Sets multiple values
		if ( typeof key === "object" ) {
			return this.each(function() {
				data_user.set( this, key );
			});
		}

		return access( this, function( value ) {
			var data,
				camelKey = jQuery.camelCase( key );

			// The calling jQuery object (element matches) is not empty
			// (and therefore has an element appears at this[ 0 ]) and the
			// `value` parameter was not undefined. An empty jQuery object
			// will result in `undefined` for elem = this[ 0 ] which will
			// throw an exception if an attempt to read a data cache is made.
			if ( elem && value === undefined ) {
				// Attempt to get data from the cache
				// with the key as-is
				data = data_user.get( elem, key );
				if ( data !== undefined ) {
					return data;
				}

				// Attempt to get data from the cache
				// with the key camelized
				data = data_user.get( elem, camelKey );
				if ( data !== undefined ) {
					return data;
				}

				// Attempt to "discover" the data in
				// HTML5 custom data-* attrs
				data = dataAttr( elem, camelKey, undefined );
				if ( data !== undefined ) {
					return data;
				}

				// We tried really hard, but the data doesn't exist.
				return;
			}

			// Set the data...
			this.each(function() {
				// First, attempt to store a copy or reference of any
				// data that might've been store with a camelCased key.
				var data = data_user.get( this, camelKey );

				// For HTML5 data-* attribute interop, we have to
				// store property names with dashes in a camelCase form.
				// This might not apply to all properties...*
				data_user.set( this, camelKey, value );

				// *... In the case of properties that might _actually_
				// have dashes, we need to also store a copy of that
				// unchanged property.
				if ( key.indexOf("-") !== -1 && data !== undefined ) {
					data_user.set( this, key, value );
				}
			});
		}, null, value, arguments.length > 1, null, true );
	},

	removeData: function( key ) {
		return this.each(function() {
			data_user.remove( this, key );
		});
	}
});


jQuery.extend({
	queue: function( elem, type, data ) {
		var queue;

		if ( elem ) {
			type = ( type || "fx" ) + "queue";
			queue = data_priv.get( elem, type );

			// Speed up dequeue by getting out quickly if this is just a lookup
			if ( data ) {
				if ( !queue || jQuery.isArray( data ) ) {
					queue = data_priv.access( elem, type, jQuery.makeArray(data) );
				} else {
					queue.push( data );
				}
			}
			return queue || [];
		}
	},

	dequeue: function( elem, type ) {
		type = type || "fx";

		var queue = jQuery.queue( elem, type ),
			startLength = queue.length,
			fn = queue.shift(),
			hooks = jQuery._queueHooks( elem, type ),
			next = function() {
				jQuery.dequeue( elem, type );
			};

		// If the fx queue is dequeued, always remove the progress sentinel
		if ( fn === "inprogress" ) {
			fn = queue.shift();
			startLength--;
		}

		if ( fn ) {

			// Add a progress sentinel to prevent the fx queue from being
			// automatically dequeued
			if ( type === "fx" ) {
				queue.unshift( "inprogress" );
			}

			// Clear up the last queue stop function
			delete hooks.stop;
			fn.call( elem, next, hooks );
		}

		if ( !startLength && hooks ) {
			hooks.empty.fire();
		}
	},

	// Not public - generate a queueHooks object, or return the current one
	_queueHooks: function( elem, type ) {
		var key = type + "queueHooks";
		return data_priv.get( elem, key ) || data_priv.access( elem, key, {
			empty: jQuery.Callbacks("once memory").add(function() {
				data_priv.remove( elem, [ type + "queue", key ] );
			})
		});
	}
});

jQuery.fn.extend({
	queue: function( type, data ) {
		var setter = 2;

		if ( typeof type !== "string" ) {
			data = type;
			type = "fx";
			setter--;
		}

		if ( arguments.length < setter ) {
			return jQuery.queue( this[0], type );
		}

		return data === undefined ?
			this :
			this.each(function() {
				var queue = jQuery.queue( this, type, data );

				// Ensure a hooks for this queue
				jQuery._queueHooks( this, type );

				if ( type === "fx" && queue[0] !== "inprogress" ) {
					jQuery.dequeue( this, type );
				}
			});
	},
	dequeue: function( type ) {
		return this.each(function() {
			jQuery.dequeue( this, type );
		});
	},
	clearQueue: function( type ) {
		return this.queue( type || "fx", [] );
	},
	// Get a promise resolved when queues of a certain type
	// are emptied (fx is the type by default)
	promise: function( type, obj ) {
		var tmp,
			count = 1,
			defer = jQuery.Deferred(),
			elements = this,
			i = this.length,
			resolve = function() {
				if ( !( --count ) ) {
					defer.resolveWith( elements, [ elements ] );
				}
			};

		if ( typeof type !== "string" ) {
			obj = type;
			type = undefined;
		}
		type = type || "fx";

		while ( i-- ) {
			tmp = data_priv.get( elements[ i ], type + "queueHooks" );
			if ( tmp && tmp.empty ) {
				count++;
				tmp.empty.add( resolve );
			}
		}
		resolve();
		return defer.promise( obj );
	}
});
var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;

var cssExpand = [ "Top", "Right", "Bottom", "Left" ];

var isHidden = function( elem, el ) {
		// isHidden might be called from jQuery#filter function;
		// in that case, element will be second argument
		elem = el || elem;
		return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
	};

var rcheckableType = (/^(?:checkbox|radio)$/i);



(function() {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement( "input" );

	// Support: Safari<=5.1
	// Check state lost if the name is set (#11217)
	// Support: Windows Web Apps (WWA)
	// `name` and `type` must use .setAttribute for WWA (#14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute( "checked", "checked" );
	input.setAttribute( "name", "t" );

	div.appendChild( input );

	// Support: Safari<=5.1, Android<4.2
	// Older WebKit doesn't clone checked state correctly in fragments
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// Support: IE<=11+
	// Make sure textarea (and checkbox) defaultValue is properly cloned
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
})();
var strundefined = typeof undefined;



support.focusinBubbles = "onfocusin" in window;


var
	rkeyEvent = /^key/,
	rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;

function returnTrue() {
	return true;
}

function returnFalse() {
	return false;
}

function safeActiveElement() {
	try {
		return document.activeElement;
	} catch ( err ) { }
}

/*
 * Helper functions for managing events -- not part of the public interface.
 * Props to Dean Edwards' addEvent library for many of the ideas.
 */
jQuery.event = {

	global: {},

	add: function( elem, types, handler, data, selector ) {

		var handleObjIn, eventHandle, tmp,
			events, t, handleObj,
			special, handlers, type, namespaces, origType,
			elemData = data_priv.get( elem );

		// Don't attach events to noData or text/comment nodes (but allow plain objects)
		if ( !elemData ) {
			return;
		}

		// Caller can pass in an object of custom data in lieu of the handler
		if ( handler.handler ) {
			handleObjIn = handler;
			handler = handleObjIn.handler;
			selector = handleObjIn.selector;
		}

		// Make sure that the handler has a unique ID, used to find/remove it later
		if ( !handler.guid ) {
			handler.guid = jQuery.guid++;
		}

		// Init the element's event structure and main handler, if this is the first
		if ( !(events = elemData.events) ) {
			events = elemData.events = {};
		}
		if ( !(eventHandle = elemData.handle) ) {
			eventHandle = elemData.handle = function( e ) {
				// Discard the second event of a jQuery.event.trigger() and
				// when an event is called after a page has unloaded
				return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
			};
		}

		// Handle multiple events separated by a space
		types = ( types || "" ).match( rnotwhite ) || [ "" ];
		t = types.length;
		while ( t-- ) {
			tmp = rtypenamespace.exec( types[t] ) || [];
			type = origType = tmp[1];
			namespaces = ( tmp[2] || "" ).split( "." ).sort();

			// There *must* be a type, no attaching namespace-only handlers
			if ( !type ) {
				continue;
			}

			// If event changes its type, use the special event handlers for the changed type
			special = jQuery.event.special[ type ] || {};

			// If selector defined, determine special event api type, otherwise given type
			type = ( selector ? special.delegateType : special.bindType ) || type;

			// Update special based on newly reset type
			special = jQuery.event.special[ type ] || {};

			// handleObj is passed to all event handlers
			handleObj = jQuery.extend({
				type: type,
				origType: origType,
				data: data,
				handler: handler,
				guid: handler.guid,
				selector: selector,
				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
				namespace: namespaces.join(".")
			}, handleObjIn );

			// Init the event handler queue if we're the first
			if ( !(handlers = events[ type ]) ) {
				handlers = events[ type ] = [];
				handlers.delegateCount = 0;

				// Only use addEventListener if the special events handler returns false
				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
					if ( elem.addEventListener ) {
						elem.addEventListener( type, eventHandle, false );
					}
				}
			}

			if ( special.add ) {
				special.add.call( elem, handleObj );

				if ( !handleObj.handler.guid ) {
					handleObj.handler.guid = handler.guid;
				}
			}

			// Add to the element's handler list, delegates in front
			if ( selector ) {
				handlers.splice( handlers.delegateCount++, 0, handleObj );
			} else {
				handlers.push( handleObj );
			}

			// Keep track of which events have ever been used, for event optimization
			jQuery.event.global[ type ] = true;
		}

	},

	// Detach an event or set of events from an element
	remove: function( elem, types, handler, selector, mappedTypes ) {

		var j, origCount, tmp,
			events, t, handleObj,
			special, handlers, type, namespaces, origType,
			elemData = data_priv.hasData( elem ) && data_priv.get( elem );

		if ( !elemData || !(events = elemData.events) ) {
			return;
		}

		// Once for each type.namespace in types; type may be omitted
		types = ( types || "" ).match( rnotwhite ) || [ "" ];
		t = types.length;
		while ( t-- ) {
			tmp = rtypenamespace.exec( types[t] ) || [];
			type = origType = tmp[1];
			namespaces = ( tmp[2] || "" ).split( "." ).sort();

			// Unbind all events (on this namespace, if provided) for the element
			if ( !type ) {
				for ( type in events ) {
					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
				}
				continue;
			}

			special = jQuery.event.special[ type ] || {};
			type = ( selector ? special.delegateType : special.bindType ) || type;
			handlers = events[ type ] || [];
			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );

			// Remove matching events
			origCount = j = handlers.length;
			while ( j-- ) {
				handleObj = handlers[ j ];

				if ( ( mappedTypes || origType === handleObj.origType ) &&
					( !handler || handler.guid === handleObj.guid ) &&
					( !tmp || tmp.test( handleObj.namespace ) ) &&
					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
					handlers.splice( j, 1 );

					if ( handleObj.selector ) {
						handlers.delegateCount--;
					}
					if ( special.remove ) {
						special.remove.call( elem, handleObj );
					}
				}
			}

			// Remove generic event handler if we removed something and no more handlers exist
			// (avoids potential for endless recursion during removal of special event handlers)
			if ( origCount && !handlers.length ) {
				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
					jQuery.removeEvent( elem, type, elemData.handle );
				}

				delete events[ type ];
			}
		}

		// Remove the expando if it's no longer used
		if ( jQuery.isEmptyObject( events ) ) {
			delete elemData.handle;
			data_priv.remove( elem, "events" );
		}
	},

	trigger: function( event, data, elem, onlyHandlers ) {

		var i, cur, tmp, bubbleType, ontype, handle, special,
			eventPath = [ elem || document ],
			type = hasOwn.call( event, "type" ) ? event.type : event,
			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];

		cur = tmp = elem = elem || document;

		// Don't do events on text and comment nodes
		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
			return;
		}

		// focus/blur morphs to focusin/out; ensure we're not firing them right now
		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
			return;
		}

		if ( type.indexOf(".") >= 0 ) {
			// Namespaced trigger; create a regexp to match event type in handle()
			namespaces = type.split(".");
			type = namespaces.shift();
			namespaces.sort();
		}
		ontype = type.indexOf(":") < 0 && "on" + type;

		// Caller can pass in a jQuery.Event object, Object, or just an event type string
		event = event[ jQuery.expando ] ?
			event :
			new jQuery.Event( type, typeof event === "object" && event );

		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
		event.isTrigger = onlyHandlers ? 2 : 3;
		event.namespace = namespaces.join(".");
		event.namespace_re = event.namespace ?
			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
			null;

		// Clean up the event in case it is being reused
		event.result = undefined;
		if ( !event.target ) {
			event.target = elem;
		}

		// Clone any incoming data and prepend the event, creating the handler arg list
		data = data == null ?
			[ event ] :
			jQuery.makeArray( data, [ event ] );

		// Allow special events to draw outside the lines
		special = jQuery.event.special[ type ] || {};
		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
			return;
		}

		// Determine event propagation path in advance, per W3C events spec (#9951)
		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {

			bubbleType = special.delegateType || type;
			if ( !rfocusMorph.test( bubbleType + type ) ) {
				cur = cur.parentNode;
			}
			for ( ; cur; cur = cur.parentNode ) {
				eventPath.push( cur );
				tmp = cur;
			}

			// Only add window if we got to document (e.g., not plain obj or detached DOM)
			if ( tmp === (elem.ownerDocument || document) ) {
				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
			}
		}

		// Fire handlers on the event path
		i = 0;
		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {

			event.type = i > 1 ?
				bubbleType :
				special.bindType || type;

			// jQuery handler
			handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
			if ( handle ) {
				handle.apply( cur, data );
			}

			// Native handler
			handle = ontype && cur[ ontype ];
			if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
				event.result = handle.apply( cur, data );
				if ( event.result === false ) {
					event.preventDefault();
				}
			}
		}
		event.type = type;

		// If nobody prevented the default action, do it now
		if ( !onlyHandlers && !event.isDefaultPrevented() ) {

			if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
				jQuery.acceptData( elem ) ) {

				// Call a native DOM method on the target with the same name name as the event.
				// Don't do default actions on window, that's where global variables be (#6170)
				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {

					// Don't re-trigger an onFOO event when we call its FOO() method
					tmp = elem[ ontype ];

					if ( tmp ) {
						elem[ ontype ] = null;
					}

					// Prevent re-triggering of the same event, since we already bubbled it above
					jQuery.event.triggered = type;
					elem[ type ]();
					jQuery.event.triggered = undefined;

					if ( tmp ) {
						elem[ ontype ] = tmp;
					}
				}
			}
		}

		return event.result;
	},

	dispatch: function( event ) {

		// Make a writable jQuery.Event from the native event object
		event = jQuery.event.fix( event );

		var i, j, ret, matched, handleObj,
			handlerQueue = [],
			args = slice.call( arguments ),
			handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
			special = jQuery.event.special[ event.type ] || {};

		// Use the fix-ed jQuery.Event rather than the (read-only) native event
		args[0] = event;
		event.delegateTarget = this;

		// Call the preDispatch hook for the mapped type, and let it bail if desired
		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
			return;
		}

		// Determine handlers
		handlerQueue = jQuery.event.handlers.call( this, event, handlers );

		// Run delegates first; they may want to stop propagation beneath us
		i = 0;
		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
			event.currentTarget = matched.elem;

			j = 0;
			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {

				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
				// a subset or equal to those in the bound event (both can have no namespace).
				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {

					event.handleObj = handleObj;
					event.data = handleObj.data;

					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
							.apply( matched.elem, args );

					if ( ret !== undefined ) {
						if ( (event.result = ret) === false ) {
							event.preventDefault();
							event.stopPropagation();
						}
					}
				}
			}
		}

		// Call the postDispatch hook for the mapped type
		if ( special.postDispatch ) {
			special.postDispatch.call( this, event );
		}

		return event.result;
	},

	handlers: function( event, handlers ) {
		var i, matches, sel, handleObj,
			handlerQueue = [],
			delegateCount = handlers.delegateCount,
			cur = event.target;

		// Find delegate handlers
		// Black-hole SVG <use> instance trees (#13180)
		// Avoid non-left-click bubbling in Firefox (#3861)
		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {

			for ( ; cur !== this; cur = cur.parentNode || this ) {

				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
				if ( cur.disabled !== true || event.type !== "click" ) {
					matches = [];
					for ( i = 0; i < delegateCount; i++ ) {
						handleObj = handlers[ i ];

						// Don't conflict with Object.prototype properties (#13203)
						sel = handleObj.selector + " ";

						if ( matches[ sel ] === undefined ) {
							matches[ sel ] = handleObj.needsContext ?
								jQuery( sel, this ).index( cur ) >= 0 :
								jQuery.find( sel, this, null, [ cur ] ).length;
						}
						if ( matches[ sel ] ) {
							matches.push( handleObj );
						}
					}
					if ( matches.length ) {
						handlerQueue.push({ elem: cur, handlers: matches });
					}
				}
			}
		}

		// Add the remaining (directly-bound) handlers
		if ( delegateCount < handlers.length ) {
			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
		}

		return handlerQueue;
	},

	// Includes some event props shared by KeyEvent and MouseEvent
	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),

	fixHooks: {},

	keyHooks: {
		props: "char charCode key keyCode".split(" "),
		filter: function( event, original ) {

			// Add which for key events
			if ( event.which == null ) {
				event.which = original.charCode != null ? original.charCode : original.keyCode;
			}

			return event;
		}
	},

	mouseHooks: {
		props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
		filter: function( event, original ) {
			var eventDoc, doc, body,
				button = original.button;

			// Calculate pageX/Y if missing and clientX/Y available
			if ( event.pageX == null && original.clientX != null ) {
				eventDoc = event.target.ownerDocument || document;
				doc = eventDoc.documentElement;
				body = eventDoc.body;

				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
			}

			// Add which for click: 1 === left; 2 === middle; 3 === right
			// Note: button is not normalized, so don't use it
			if ( !event.which && button !== undefined ) {
				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
			}

			return event;
		}
	},

	fix: function( event ) {
		if ( event[ jQuery.expando ] ) {
			return event;
		}

		// Create a writable copy of the event object and normalize some properties
		var i, prop, copy,
			type = event.type,
			originalEvent = event,
			fixHook = this.fixHooks[ type ];

		if ( !fixHook ) {
			this.fixHooks[ type ] = fixHook =
				rmouseEvent.test( type ) ? this.mouseHooks :
				rkeyEvent.test( type ) ? this.keyHooks :
				{};
		}
		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;

		event = new jQuery.Event( originalEvent );

		i = copy.length;
		while ( i-- ) {
			prop = copy[ i ];
			event[ prop ] = originalEvent[ prop ];
		}

		// Support: Cordova 2.5 (WebKit) (#13255)
		// All events should have a target; Cordova deviceready doesn't
		if ( !event.target ) {
			event.target = document;
		}

		// Support: Safari 6.0+, Chrome<28
		// Target should not be a text node (#504, #13143)
		if ( event.target.nodeType === 3 ) {
			event.target = event.target.parentNode;
		}

		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
	},

	special: {
		load: {
			// Prevent triggered image.load events from bubbling to window.load
			noBubble: true
		},
		focus: {
			// Fire native event if possible so blur/focus sequence is correct
			trigger: function() {
				if ( this !== safeActiveElement() && this.focus ) {
					this.focus();
					return false;
				}
			},
			delegateType: "focusin"
		},
		blur: {
			trigger: function() {
				if ( this === safeActiveElement() && this.blur ) {
					this.blur();
					return false;
				}
			},
			delegateType: "focusout"
		},
		click: {
			// For checkbox, fire native event so checked state will be right
			trigger: function() {
				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
					this.click();
					return false;
				}
			},

			// For cross-browser consistency, don't fire native .click() on links
			_default: function( event ) {
				return jQuery.nodeName( event.target, "a" );
			}
		},

		beforeunload: {
			postDispatch: function( event ) {

				// Support: Firefox 20+
				// Firefox doesn't alert if the returnValue field is not set.
				if ( event.result !== undefined && event.originalEvent ) {
					event.originalEvent.returnValue = event.result;
				}
			}
		}
	},

	simulate: function( type, elem, event, bubble ) {
		// Piggyback on a donor event to simulate a different one.
		// Fake originalEvent to avoid donor's stopPropagation, but if the
		// simulated event prevents default then we do the same on the donor.
		var e = jQuery.extend(
			new jQuery.Event(),
			event,
			{
				type: type,
				isSimulated: true,
				originalEvent: {}
			}
		);
		if ( bubble ) {
			jQuery.event.trigger( e, null, elem );
		} else {
			jQuery.event.dispatch.call( elem, e );
		}
		if ( e.isDefaultPrevented() ) {
			event.preventDefault();
		}
	}
};

jQuery.removeEvent = function( elem, type, handle ) {
	if ( elem.removeEventListener ) {
		elem.removeEventListener( type, handle, false );
	}
};

jQuery.Event = function( src, props ) {
	// Allow instantiation without the 'new' keyword
	if ( !(this instanceof jQuery.Event) ) {
		return new jQuery.Event( src, props );
	}

	// Event object
	if ( src && src.type ) {
		this.originalEvent = src;
		this.type = src.type;

		// Events bubbling up the document may have been marked as prevented
		// by a handler lower down the tree; reflect the correct value.
		this.isDefaultPrevented = src.defaultPrevented ||
				src.defaultPrevented === undefined &&
				// Support: Android<4.0
				src.returnValue === false ?
			returnTrue :
			returnFalse;

	// Event type
	} else {
		this.type = src;
	}

	// Put explicitly provided properties onto the event object
	if ( props ) {
		jQuery.extend( this, props );
	}

	// Create a timestamp if incoming event doesn't have one
	this.timeStamp = src && src.timeStamp || jQuery.now();

	// Mark it as fixed
	this[ jQuery.expando ] = true;
};

// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
	isDefaultPrevented: returnFalse,
	isPropagationStopped: returnFalse,
	isImmediatePropagationStopped: returnFalse,

	preventDefault: function() {
		var e = this.originalEvent;

		this.isDefaultPrevented = returnTrue;

		if ( e && e.preventDefault ) {
			e.preventDefault();
		}
	},
	stopPropagation: function() {
		var e = this.originalEvent;

		this.isPropagationStopped = returnTrue;

		if ( e && e.stopPropagation ) {
			e.stopPropagation();
		}
	},
	stopImmediatePropagation: function() {
		var e = this.originalEvent;

		this.isImmediatePropagationStopped = returnTrue;

		if ( e && e.stopImmediatePropagation ) {
			e.stopImmediatePropagation();
		}

		this.stopPropagation();
	}
};

// Create mouseenter/leave events using mouseover/out and event-time checks
// Support: Chrome 15+
jQuery.each({
	mouseenter: "mouseover",
	mouseleave: "mouseout",
	pointerenter: "pointerover",
	pointerleave: "pointerout"
}, function( orig, fix ) {
	jQuery.event.special[ orig ] = {
		delegateType: fix,
		bindType: fix,

		handle: function( event ) {
			var ret,
				target = this,
				related = event.relatedTarget,
				handleObj = event.handleObj;

			// For mousenter/leave call the handler if related is outside the target.
			// NB: No relatedTarget if the mouse left/entered the browser window
			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
				event.type = handleObj.origType;
				ret = handleObj.handler.apply( this, arguments );
				event.type = fix;
			}
			return ret;
		}
	};
});

// Support: Firefox, Chrome, Safari
// Create "bubbling" focus and blur events
if ( !support.focusinBubbles ) {
	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {

		// Attach a single capturing handler on the document while someone wants focusin/focusout
		var handler = function( event ) {
				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
			};

		jQuery.event.special[ fix ] = {
			setup: function() {
				var doc = this.ownerDocument || this,
					attaches = data_priv.access( doc, fix );

				if ( !attaches ) {
					doc.addEventListener( orig, handler, true );
				}
				data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
			},
			teardown: function() {
				var doc = this.ownerDocument || this,
					attaches = data_priv.access( doc, fix ) - 1;

				if ( !attaches ) {
					doc.removeEventListener( orig, handler, true );
					data_priv.remove( doc, fix );

				} else {
					data_priv.access( doc, fix, attaches );
				}
			}
		};
	});
}

jQuery.fn.extend({

	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
		var origFn, type;

		// Types can be a map of types/handlers
		if ( typeof types === "object" ) {
			// ( types-Object, selector, data )
			if ( typeof selector !== "string" ) {
				// ( types-Object, data )
				data = data || selector;
				selector = undefined;
			}
			for ( type in types ) {
				this.on( type, selector, data, types[ type ], one );
			}
			return this;
		}

		if ( data == null && fn == null ) {
			// ( types, fn )
			fn = selector;
			data = selector = undefined;
		} else if ( fn == null ) {
			if ( typeof selector === "string" ) {
				// ( types, selector, fn )
				fn = data;
				data = undefined;
			} else {
				// ( types, data, fn )
				fn = data;
				data = selector;
				selector = undefined;
			}
		}
		if ( fn === false ) {
			fn = returnFalse;
		} else if ( !fn ) {
			return this;
		}

		if ( one === 1 ) {
			origFn = fn;
			fn = function( event ) {
				// Can use an empty set, since event contains the info
				jQuery().off( event );
				return origFn.apply( this, arguments );
			};
			// Use same guid so caller can remove using origFn
			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
		}
		return this.each( function() {
			jQuery.event.add( this, types, fn, data, selector );
		});
	},
	one: function( types, selector, data, fn ) {
		return this.on( types, selector, data, fn, 1 );
	},
	off: function( types, selector, fn ) {
		var handleObj, type;
		if ( types && types.preventDefault && types.handleObj ) {
			// ( event )  dispatched jQuery.Event
			handleObj = types.handleObj;
			jQuery( types.delegateTarget ).off(
				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
				handleObj.selector,
				handleObj.handler
			);
			return this;
		}
		if ( typeof types === "object" ) {
			// ( types-object [, selector] )
			for ( type in types ) {
				this.off( type, selector, types[ type ] );
			}
			return this;
		}
		if ( selector === false || typeof selector === "function" ) {
			// ( types [, fn] )
			fn = selector;
			selector = undefined;
		}
		if ( fn === false ) {
			fn = returnFalse;
		}
		return this.each(function() {
			jQuery.event.remove( this, types, fn, selector );
		});
	},

	trigger: function( type, data ) {
		return this.each(function() {
			jQuery.event.trigger( type, data, this );
		});
	},
	triggerHandler: function( type, data ) {
		var elem = this[0];
		if ( elem ) {
			return jQuery.event.trigger( type, data, elem, true );
		}
	}
});


var
	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
	rtagName = /<([\w:]+)/,
	rhtml = /<|&#?\w+;/,
	rnoInnerhtml = /<(?:script|style|link)/i,
	// checked="checked" or checked
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
	rscriptType = /^$|\/(?:java|ecma)script/i,
	rscriptTypeMasked = /^true\/(.*)/,
	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,

	// We have to close these tags to support XHTML (#13200)
	wrapMap = {

		// Support: IE9
		option: [ 1, "<select multiple='multiple'>", "</select>" ],

		thead: [ 1, "<table>", "</table>" ],
		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],

		_default: [ 0, "", "" ]
	};

// Support: IE9
wrapMap.optgroup = wrapMap.option;

wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;

// Support: 1.x compatibility
// Manipulating tables requires a tbody
function manipulationTarget( elem, content ) {
	return jQuery.nodeName( elem, "table" ) &&
		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?

		elem.getElementsByTagName("tbody")[0] ||
			elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
		elem;
}

// Replace/restore the type attribute of script elements for safe DOM manipulation
function disableScript( elem ) {
	elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
	return elem;
}
function restoreScript( elem ) {
	var match = rscriptTypeMasked.exec( elem.type );

	if ( match ) {
		elem.type = match[ 1 ];
	} else {
		elem.removeAttribute("type");
	}

	return elem;
}

// Mark scripts as having already been evaluated
function setGlobalEval( elems, refElements ) {
	var i = 0,
		l = elems.length;

	for ( ; i < l; i++ ) {
		data_priv.set(
			elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
		);
	}
}

function cloneCopyEvent( src, dest ) {
	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;

	if ( dest.nodeType !== 1 ) {
		return;
	}

	// 1. Copy private data: events, handlers, etc.
	if ( data_priv.hasData( src ) ) {
		pdataOld = data_priv.access( src );
		pdataCur = data_priv.set( dest, pdataOld );
		events = pdataOld.events;

		if ( events ) {
			delete pdataCur.handle;
			pdataCur.events = {};

			for ( type in events ) {
				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
					jQuery.event.add( dest, type, events[ type ][ i ] );
				}
			}
		}
	}

	// 2. Copy user data
	if ( data_user.hasData( src ) ) {
		udataOld = data_user.access( src );
		udataCur = jQuery.extend( {}, udataOld );

		data_user.set( dest, udataCur );
	}
}

function getAll( context, tag ) {
	var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
			context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
			[];

	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
		jQuery.merge( [ context ], ret ) :
		ret;
}

// Fix IE bugs, see support tests
function fixInput( src, dest ) {
	var nodeName = dest.nodeName.toLowerCase();

	// Fails to persist the checked state of a cloned checkbox or radio button.
	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
		dest.checked = src.checked;

	// Fails to return the selected option to the default selected state when cloning options
	} else if ( nodeName === "input" || nodeName === "textarea" ) {
		dest.defaultValue = src.defaultValue;
	}
}

jQuery.extend({
	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
		var i, l, srcElements, destElements,
			clone = elem.cloneNode( true ),
			inPage = jQuery.contains( elem.ownerDocument, elem );

		// Fix IE cloning issues
		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
				!jQuery.isXMLDoc( elem ) ) {

			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
			destElements = getAll( clone );
			srcElements = getAll( elem );

			for ( i = 0, l = srcElements.length; i < l; i++ ) {
				fixInput( srcElements[ i ], destElements[ i ] );
			}
		}

		// Copy the events from the original to the clone
		if ( dataAndEvents ) {
			if ( deepDataAndEvents ) {
				srcElements = srcElements || getAll( elem );
				destElements = destElements || getAll( clone );

				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
				}
			} else {
				cloneCopyEvent( elem, clone );
			}
		}

		// Preserve script evaluation history
		destElements = getAll( clone, "script" );
		if ( destElements.length > 0 ) {
			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
		}

		// Return the cloned set
		return clone;
	},

	buildFragment: function( elems, context, scripts, selection ) {
		var elem, tmp, tag, wrap, contains, j,
			fragment = context.createDocumentFragment(),
			nodes = [],
			i = 0,
			l = elems.length;

		for ( ; i < l; i++ ) {
			elem = elems[ i ];

			if ( elem || elem === 0 ) {

				// Add nodes directly
				if ( jQuery.type( elem ) === "object" ) {
					// Support: QtWebKit, PhantomJS
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );

				// Convert non-html into a text node
				} else if ( !rhtml.test( elem ) ) {
					nodes.push( context.createTextNode( elem ) );

				// Convert html into DOM nodes
				} else {
					tmp = tmp || fragment.appendChild( context.createElement("div") );

					// Deserialize a standard representation
					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
					wrap = wrapMap[ tag ] || wrapMap._default;
					tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];

					// Descend through wrappers to the right content
					j = wrap[ 0 ];
					while ( j-- ) {
						tmp = tmp.lastChild;
					}

					// Support: QtWebKit, PhantomJS
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, tmp.childNodes );

					// Remember the top-level container
					tmp = fragment.firstChild;

					// Ensure the created nodes are orphaned (#12392)
					tmp.textContent = "";
				}
			}
		}

		// Remove wrapper from fragment
		fragment.textContent = "";

		i = 0;
		while ( (elem = nodes[ i++ ]) ) {

			// #4087 - If origin and destination elements are the same, and this is
			// that element, do not do anything
			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
				continue;
			}

			contains = jQuery.contains( elem.ownerDocument, elem );

			// Append to fragment
			tmp = getAll( fragment.appendChild( elem ), "script" );

			// Preserve script evaluation history
			if ( contains ) {
				setGlobalEval( tmp );
			}

			// Capture executables
			if ( scripts ) {
				j = 0;
				while ( (elem = tmp[ j++ ]) ) {
					if ( rscriptType.test( elem.type || "" ) ) {
						scripts.push( elem );
					}
				}
			}
		}

		return fragment;
	},

	cleanData: function( elems ) {
		var data, elem, type, key,
			special = jQuery.event.special,
			i = 0;

		for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
			if ( jQuery.acceptData( elem ) ) {
				key = elem[ data_priv.expando ];

				if ( key && (data = data_priv.cache[ key ]) ) {
					if ( data.events ) {
						for ( type in data.events ) {
							if ( special[ type ] ) {
								jQuery.event.remove( elem, type );

							// This is a shortcut to avoid jQuery.event.remove's overhead
							} else {
								jQuery.removeEvent( elem, type, data.handle );
							}
						}
					}
					if ( data_priv.cache[ key ] ) {
						// Discard any remaining `private` data
						delete data_priv.cache[ key ];
					}
				}
			}
			// Discard any remaining `user` data
			delete data_user.cache[ elem[ data_user.expando ] ];
		}
	}
});

jQuery.fn.extend({
	text: function( value ) {
		return access( this, function( value ) {
			return value === undefined ?
				jQuery.text( this ) :
				this.empty().each(function() {
					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
						this.textContent = value;
					}
				});
		}, null, value, arguments.length );
	},

	append: function() {
		return this.domManip( arguments, function( elem ) {
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
				var target = manipulationTarget( this, elem );
				target.appendChild( elem );
			}
		});
	},

	prepend: function() {
		return this.domManip( arguments, function( elem ) {
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
				var target = manipulationTarget( this, elem );
				target.insertBefore( elem, target.firstChild );
			}
		});
	},

	before: function() {
		return this.domManip( arguments, function( elem ) {
			if ( this.parentNode ) {
				this.parentNode.insertBefore( elem, this );
			}
		});
	},

	after: function() {
		return this.domManip( arguments, function( elem ) {
			if ( this.parentNode ) {
				this.parentNode.insertBefore( elem, this.nextSibling );
			}
		});
	},

	remove: function( selector, keepData /* Internal Use Only */ ) {
		var elem,
			elems = selector ? jQuery.filter( selector, this ) : this,
			i = 0;

		for ( ; (elem = elems[i]) != null; i++ ) {
			if ( !keepData && elem.nodeType === 1 ) {
				jQuery.cleanData( getAll( elem ) );
			}

			if ( elem.parentNode ) {
				if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
					setGlobalEval( getAll( elem, "script" ) );
				}
				elem.parentNode.removeChild( elem );
			}
		}

		return this;
	},

	empty: function() {
		var elem,
			i = 0;

		for ( ; (elem = this[i]) != null; i++ ) {
			if ( elem.nodeType === 1 ) {

				// Prevent memory leaks
				jQuery.cleanData( getAll( elem, false ) );

				// Remove any remaining nodes
				elem.textContent = "";
			}
		}

		return this;
	},

	clone: function( dataAndEvents, deepDataAndEvents ) {
		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

		return this.map(function() {
			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
		});
	},

	html: function( value ) {
		return access( this, function( value ) {
			var elem = this[ 0 ] || {},
				i = 0,
				l = this.length;

			if ( value === undefined && elem.nodeType === 1 ) {
				return elem.innerHTML;
			}

			// See if we can take a shortcut and just use innerHTML
			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

				value = value.replace( rxhtmlTag, "<$1></$2>" );

				try {
					for ( ; i < l; i++ ) {
						elem = this[ i ] || {};

						// Remove element nodes and prevent memory leaks
						if ( elem.nodeType === 1 ) {
							jQuery.cleanData( getAll( elem, false ) );
							elem.innerHTML = value;
						}
					}

					elem = 0;

				// If using innerHTML throws an exception, use the fallback method
				} catch( e ) {}
			}

			if ( elem ) {
				this.empty().append( value );
			}
		}, null, value, arguments.length );
	},

	replaceWith: function() {
		var arg = arguments[ 0 ];

		// Make the changes, replacing each context element with the new content
		this.domManip( arguments, function( elem ) {
			arg = this.parentNode;

			jQuery.cleanData( getAll( this ) );

			if ( arg ) {
				arg.replaceChild( elem, this );
			}
		});

		// Force removal if there was no new content (e.g., from empty arguments)
		return arg && (arg.length || arg.nodeType) ? this : this.remove();
	},

	detach: function( selector ) {
		return this.remove( selector, true );
	},

	domManip: function( args, callback ) {

		// Flatten any nested arrays
		args = concat.apply( [], args );

		var fragment, first, scripts, hasScripts, node, doc,
			i = 0,
			l = this.length,
			set = this,
			iNoClone = l - 1,
			value = args[ 0 ],
			isFunction = jQuery.isFunction( value );

		// We can't cloneNode fragments that contain checked, in WebKit
		if ( isFunction ||
				( l > 1 && typeof value === "string" &&
					!support.checkClone && rchecked.test( value ) ) ) {
			return this.each(function( index ) {
				var self = set.eq( index );
				if ( isFunction ) {
					args[ 0 ] = value.call( this, index, self.html() );
				}
				self.domManip( args, callback );
			});
		}

		if ( l ) {
			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
			first = fragment.firstChild;

			if ( fragment.childNodes.length === 1 ) {
				fragment = first;
			}

			if ( first ) {
				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
				hasScripts = scripts.length;

				// Use the original fragment for the last item instead of the first because it can end up
				// being emptied incorrectly in certain situations (#8070).
				for ( ; i < l; i++ ) {
					node = fragment;

					if ( i !== iNoClone ) {
						node = jQuery.clone( node, true, true );

						// Keep references to cloned scripts for later restoration
						if ( hasScripts ) {
							// Support: QtWebKit
							// jQuery.merge because push.apply(_, arraylike) throws
							jQuery.merge( scripts, getAll( node, "script" ) );
						}
					}

					callback.call( this[ i ], node, i );
				}

				if ( hasScripts ) {
					doc = scripts[ scripts.length - 1 ].ownerDocument;

					// Reenable scripts
					jQuery.map( scripts, restoreScript );

					// Evaluate executable scripts on first document insertion
					for ( i = 0; i < hasScripts; i++ ) {
						node = scripts[ i ];
						if ( rscriptType.test( node.type || "" ) &&
							!data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {

							if ( node.src ) {
								// Optional AJAX dependency, but won't run scripts if not present
								if ( jQuery._evalUrl ) {
									jQuery._evalUrl( node.src );
								}
							} else {
								jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
							}
						}
					}
				}
			}
		}

		return this;
	}
});

jQuery.each({
	appendTo: "append",
	prependTo: "prepend",
	insertBefore: "before",
	insertAfter: "after",
	replaceAll: "replaceWith"
}, function( name, original ) {
	jQuery.fn[ name ] = function( selector ) {
		var elems,
			ret = [],
			insert = jQuery( selector ),
			last = insert.length - 1,
			i = 0;

		for ( ; i <= last; i++ ) {
			elems = i === last ? this : this.clone( true );
			jQuery( insert[ i ] )[ original ]( elems );

			// Support: QtWebKit
			// .get() because push.apply(_, arraylike) throws
			push.apply( ret, elems.get() );
		}

		return this.pushStack( ret );
	};
});


var iframe,
	elemdisplay = {};

/**
 * Retrieve the actual display of a element
 * @param {String} name nodeName of the element
 * @param {Object} doc Document object
 */
// Called only from within defaultDisplay
function actualDisplay( name, doc ) {
	var style,
		elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),

		// getDefaultComputedStyle might be reliably used only on attached element
		display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?

			// Use of this method is a temporary fix (more like optimization) until something better comes along,
			// since it was removed from specification and supported only in FF
			style.display : jQuery.css( elem[ 0 ], "display" );

	// We don't have any data stored on the element,
	// so use "detach" method as fast way to get rid of the element
	elem.detach();

	return display;
}

/**
 * Try to determine the default display value of an element
 * @param {String} nodeName
 */
function defaultDisplay( nodeName ) {
	var doc = document,
		display = elemdisplay[ nodeName ];

	if ( !display ) {
		display = actualDisplay( nodeName, doc );

		// If the simple way fails, read from inside an iframe
		if ( display === "none" || !display ) {

			// Use the already-created iframe if possible
			iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );

			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
			doc = iframe[ 0 ].contentDocument;

			// Support: IE
			doc.write();
			doc.close();

			display = actualDisplay( nodeName, doc );
			iframe.detach();
		}

		// Store the correct default display
		elemdisplay[ nodeName ] = display;
	}

	return display;
}
var rmargin = (/^margin/);

var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );

var getStyles = function( elem ) {
		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
		// IE throws on elements created in popups
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
		if ( elem.ownerDocument.defaultView.opener ) {
			return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
		}

		return window.getComputedStyle( elem, null );
	};



function curCSS( elem, name, computed ) {
	var width, minWidth, maxWidth, ret,
		style = elem.style;

	computed = computed || getStyles( elem );

	// Support: IE9
	// getPropertyValue is only needed for .css('filter') (#12537)
	if ( computed ) {
		ret = computed.getPropertyValue( name ) || computed[ name ];
	}

	if ( computed ) {

		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
			ret = jQuery.style( elem, name );
		}

		// Support: iOS < 6
		// A tribute to the "awesome hack by Dean Edwards"
		// iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
		// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
		if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {

			// Remember the original values
			width = style.width;
			minWidth = style.minWidth;
			maxWidth = style.maxWidth;

			// Put in the new values to get a computed value out
			style.minWidth = style.maxWidth = style.width = ret;
			ret = computed.width;

			// Revert the changed values
			style.width = width;
			style.minWidth = minWidth;
			style.maxWidth = maxWidth;
		}
	}

	return ret !== undefined ?
		// Support: IE
		// IE returns zIndex value as an integer.
		ret + "" :
		ret;
}


function addGetHookIf( conditionFn, hookFn ) {
	// Define the hook, we'll check on the first run if it's really needed.
	return {
		get: function() {
			if ( conditionFn() ) {
				// Hook not needed (or it's not possible to use it due
				// to missing dependency), remove it.
				delete this.get;
				return;
			}

			// Hook needed; redefine it so that the support test is not executed again.
			return (this.get = hookFn).apply( this, arguments );
		}
	};
}


(function() {
	var pixelPositionVal, boxSizingReliableVal,
		docElem = document.documentElement,
		container = document.createElement( "div" ),
		div = document.createElement( "div" );

	if ( !div.style ) {
		return;
	}

	// Support: IE9-11+
	// Style of cloned element affects source element cloned (#8908)
	div.style.backgroundClip = "content-box";
	div.cloneNode( true ).style.backgroundClip = "";
	support.clearCloneStyle = div.style.backgroundClip === "content-box";

	container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
		"position:absolute";
	container.appendChild( div );

	// Executing both pixelPosition & boxSizingReliable tests require only one layout
	// so they're executed at the same time to save the second computation.
	function computePixelPositionAndBoxSizingReliable() {
		div.style.cssText =
			// Support: Firefox<29, Android 2.3
			// Vendor-prefix box-sizing
			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
			"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
			"border:1px;padding:1px;width:4px;position:absolute";
		div.innerHTML = "";
		docElem.appendChild( container );

		var divStyle = window.getComputedStyle( div, null );
		pixelPositionVal = divStyle.top !== "1%";
		boxSizingReliableVal = divStyle.width === "4px";

		docElem.removeChild( container );
	}

	// Support: node.js jsdom
	// Don't assume that getComputedStyle is a property of the global object
	if ( window.getComputedStyle ) {
		jQuery.extend( support, {
			pixelPosition: function() {

				// This test is executed only once but we still do memoizing
				// since we can use the boxSizingReliable pre-computing.
				// No need to check if the test was already performed, though.
				computePixelPositionAndBoxSizingReliable();
				return pixelPositionVal;
			},
			boxSizingReliable: function() {
				if ( boxSizingReliableVal == null ) {
					computePixelPositionAndBoxSizingReliable();
				}
				return boxSizingReliableVal;
			},
			reliableMarginRight: function() {

				// Support: Android 2.3
				// Check if div with explicit width and no margin-right incorrectly
				// gets computed margin-right based on width of container. (#3333)
				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
				// This support function is only executed once so no memoizing is needed.
				var ret,
					marginDiv = div.appendChild( document.createElement( "div" ) );

				// Reset CSS: box-sizing; display; margin; border; padding
				marginDiv.style.cssText = div.style.cssText =
					// Support: Firefox<29, Android 2.3
					// Vendor-prefix box-sizing
					"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
					"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
				marginDiv.style.marginRight = marginDiv.style.width = "0";
				div.style.width = "1px";
				docElem.appendChild( container );

				ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );

				docElem.removeChild( container );
				div.removeChild( marginDiv );

				return ret;
			}
		});
	}
})();


// A method for quickly swapping in/out CSS properties to get correct calculations.
jQuery.swap = function( elem, options, callback, args ) {
	var ret, name,
		old = {};

	// Remember the old values, and insert the new ones
	for ( name in options ) {
		old[ name ] = elem.style[ name ];
		elem.style[ name ] = options[ name ];
	}

	ret = callback.apply( elem, args || [] );

	// Revert the old values
	for ( name in options ) {
		elem.style[ name ] = old[ name ];
	}

	return ret;
};


var
	// Swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
	rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),

	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
	cssNormalTransform = {
		letterSpacing: "0",
		fontWeight: "400"
	},

	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];

// Return a css property mapped to a potentially vendor prefixed property
function vendorPropName( style, name ) {

	// Shortcut for names that are not vendor prefixed
	if ( name in style ) {
		return name;
	}

	// Check for vendor prefixed names
	var capName = name[0].toUpperCase() + name.slice(1),
		origName = name,
		i = cssPrefixes.length;

	while ( i-- ) {
		name = cssPrefixes[ i ] + capName;
		if ( name in style ) {
			return name;
		}
	}

	return origName;
}

function setPositiveNumber( elem, value, subtract ) {
	var matches = rnumsplit.exec( value );
	return matches ?
		// Guard against undefined "subtract", e.g., when used as in cssHooks
		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
		value;
}

function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
	var i = extra === ( isBorderBox ? "border" : "content" ) ?
		// If we already have the right measurement, avoid augmentation
		4 :
		// Otherwise initialize for horizontal or vertical properties
		name === "width" ? 1 : 0,

		val = 0;

	for ( ; i < 4; i += 2 ) {
		// Both box models exclude margin, so add it if we want it
		if ( extra === "margin" ) {
			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
		}

		if ( isBorderBox ) {
			// border-box includes padding, so remove it if we want content
			if ( extra === "content" ) {
				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
			}

			// At this point, extra isn't border nor margin, so remove border
			if ( extra !== "margin" ) {
				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}
		} else {
			// At this point, extra isn't content, so add padding
			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );

			// At this point, extra isn't content nor padding, so add border
			if ( extra !== "padding" ) {
				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}
		}
	}

	return val;
}

function getWidthOrHeight( elem, name, extra ) {

	// Start with offset property, which is equivalent to the border-box value
	var valueIsBorderBox = true,
		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
		styles = getStyles( elem ),
		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";

	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
	if ( val <= 0 || val == null ) {
		// Fall back to computed then uncomputed css if necessary
		val = curCSS( elem, name, styles );
		if ( val < 0 || val == null ) {
			val = elem.style[ name ];
		}

		// Computed unit is not pixels. Stop here and return.
		if ( rnumnonpx.test(val) ) {
			return val;
		}

		// Check for style in case a browser which returns unreliable values
		// for getComputedStyle silently falls back to the reliable elem.style
		valueIsBorderBox = isBorderBox &&
			( support.boxSizingReliable() || val === elem.style[ name ] );

		// Normalize "", auto, and prepare for extra
		val = parseFloat( val ) || 0;
	}

	// Use the active box-sizing model to add/subtract irrelevant styles
	return ( val +
		augmentWidthOrHeight(
			elem,
			name,
			extra || ( isBorderBox ? "border" : "content" ),
			valueIsBorderBox,
			styles
		)
	) + "px";
}

function showHide( elements, show ) {
	var display, elem, hidden,
		values = [],
		index = 0,
		length = elements.length;

	for ( ; index < length; index++ ) {
		elem = elements[ index ];
		if ( !elem.style ) {
			continue;
		}

		values[ index ] = data_priv.get( elem, "olddisplay" );
		display = elem.style.display;
		if ( show ) {
			// Reset the inline display of this element to learn if it is
			// being hidden by cascaded rules or not
			if ( !values[ index ] && display === "none" ) {
				elem.style.display = "";
			}

			// Set elements which have been overridden with display: none
			// in a stylesheet to whatever the default browser style is
			// for such an element
			if ( elem.style.display === "" && isHidden( elem ) ) {
				values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
			}
		} else {
			hidden = isHidden( elem );

			if ( display !== "none" || !hidden ) {
				data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
			}
		}
	}

	// Set the display of most of the elements in a second loop
	// to avoid the constant reflow
	for ( index = 0; index < length; index++ ) {
		elem = elements[ index ];
		if ( !elem.style ) {
			continue;
		}
		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
			elem.style.display = show ? values[ index ] || "" : "none";
		}
	}

	return elements;
}

jQuery.extend({

	// Add in style property hooks for overriding the default
	// behavior of getting and setting a style property
	cssHooks: {
		opacity: {
			get: function( elem, computed ) {
				if ( computed ) {

					// We should always get a number back from opacity
					var ret = curCSS( elem, "opacity" );
					return ret === "" ? "1" : ret;
				}
			}
		}
	},

	// Don't automatically add "px" to these possibly-unitless properties
	cssNumber: {
		"columnCount": true,
		"fillOpacity": true,
		"flexGrow": true,
		"flexShrink": true,
		"fontWeight": true,
		"lineHeight": true,
		"opacity": true,
		"order": true,
		"orphans": true,
		"widows": true,
		"zIndex": true,
		"zoom": true
	},

	// Add in properties whose names you wish to fix before
	// setting or getting the value
	cssProps: {
		"float": "cssFloat"
	},

	// Get and set the style property on a DOM Node
	style: function( elem, name, value, extra ) {

		// Don't set styles on text and comment nodes
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
			return;
		}

		// Make sure that we're working with the right name
		var ret, type, hooks,
			origName = jQuery.camelCase( name ),
			style = elem.style;

		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );

		// Gets hook for the prefixed version, then unprefixed version
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// Check if we're setting a value
		if ( value !== undefined ) {
			type = typeof value;

			// Convert "+=" or "-=" to relative numbers (#7345)
			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
				// Fixes bug #9237
				type = "number";
			}

			// Make sure that null and NaN values aren't set (#7116)
			if ( value == null || value !== value ) {
				return;
			}

			// If a number, add 'px' to the (except for certain CSS properties)
			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
				value += "px";
			}

			// Support: IE9-11+
			// background-* props affect original clone's values
			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
				style[ name ] = "inherit";
			}

			// If a hook was provided, use that value, otherwise just set the specified value
			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
				style[ name ] = value;
			}

		} else {
			// If a hook was provided get the non-computed value from there
			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
				return ret;
			}

			// Otherwise just get the value from the style object
			return style[ name ];
		}
	},

	css: function( elem, name, extra, styles ) {
		var val, num, hooks,
			origName = jQuery.camelCase( name );

		// Make sure that we're working with the right name
		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );

		// Try prefixed name followed by the unprefixed name
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// If a hook was provided get the computed value from there
		if ( hooks && "get" in hooks ) {
			val = hooks.get( elem, true, extra );
		}

		// Otherwise, if a way to get the computed value exists, use that
		if ( val === undefined ) {
			val = curCSS( elem, name, styles );
		}

		// Convert "normal" to computed value
		if ( val === "normal" && name in cssNormalTransform ) {
			val = cssNormalTransform[ name ];
		}

		// Make numeric if forced or a qualifier was provided and val looks numeric
		if ( extra === "" || extra ) {
			num = parseFloat( val );
			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
		}
		return val;
	}
});

jQuery.each([ "height", "width" ], function( i, name ) {
	jQuery.cssHooks[ name ] = {
		get: function( elem, computed, extra ) {
			if ( computed ) {

				// Certain elements can have dimension info if we invisibly show them
				// but it must have a current display style that would benefit
				return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
					jQuery.swap( elem, cssShow, function() {
						return getWidthOrHeight( elem, name, extra );
					}) :
					getWidthOrHeight( elem, name, extra );
			}
		},

		set: function( elem, value, extra ) {
			var styles = extra && getStyles( elem );
			return setPositiveNumber( elem, value, extra ?
				augmentWidthOrHeight(
					elem,
					name,
					extra,
					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
					styles
				) : 0
			);
		}
	};
});

// Support: Android 2.3
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
	function( elem, computed ) {
		if ( computed ) {
			return jQuery.swap( elem, { "display": "inline-block" },
				curCSS, [ elem, "marginRight" ] );
		}
	}
);

// These hooks are used by animate to expand properties
jQuery.each({
	margin: "",
	padding: "",
	border: "Width"
}, function( prefix, suffix ) {
	jQuery.cssHooks[ prefix + suffix ] = {
		expand: function( value ) {
			var i = 0,
				expanded = {},

				// Assumes a single number if not a string
				parts = typeof value === "string" ? value.split(" ") : [ value ];

			for ( ; i < 4; i++ ) {
				expanded[ prefix + cssExpand[ i ] + suffix ] =
					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
			}

			return expanded;
		}
	};

	if ( !rmargin.test( prefix ) ) {
		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
	}
});

jQuery.fn.extend({
	css: function( name, value ) {
		return access( this, function( elem, name, value ) {
			var styles, len,
				map = {},
				i = 0;

			if ( jQuery.isArray( name ) ) {
				styles = getStyles( elem );
				len = name.length;

				for ( ; i < len; i++ ) {
					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
				}

				return map;
			}

			return value !== undefined ?
				jQuery.style( elem, name, value ) :
				jQuery.css( elem, name );
		}, name, value, arguments.length > 1 );
	},
	show: function() {
		return showHide( this, true );
	},
	hide: function() {
		return showHide( this );
	},
	toggle: function( state ) {
		if ( typeof state === "boolean" ) {
			return state ? this.show() : this.hide();
		}

		return this.each(function() {
			if ( isHidden( this ) ) {
				jQuery( this ).show();
			} else {
				jQuery( this ).hide();
			}
		});
	}
});


function Tween( elem, options, prop, end, easing ) {
	return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;

Tween.prototype = {
	constructor: Tween,
	init: function( elem, options, prop, end, easing, unit ) {
		this.elem = elem;
		this.prop = prop;
		this.easing = easing || "swing";
		this.options = options;
		this.start = this.now = this.cur();
		this.end = end;
		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
	},
	cur: function() {
		var hooks = Tween.propHooks[ this.prop ];

		return hooks && hooks.get ?
			hooks.get( this ) :
			Tween.propHooks._default.get( this );
	},
	run: function( percent ) {
		var eased,
			hooks = Tween.propHooks[ this.prop ];

		if ( this.options.duration ) {
			this.pos = eased = jQuery.easing[ this.easing ](
				percent, this.options.duration * percent, 0, 1, this.options.duration
			);
		} else {
			this.pos = eased = percent;
		}
		this.now = ( this.end - this.start ) * eased + this.start;

		if ( this.options.step ) {
			this.options.step.call( this.elem, this.now, this );
		}

		if ( hooks && hooks.set ) {
			hooks.set( this );
		} else {
			Tween.propHooks._default.set( this );
		}
		return this;
	}
};

Tween.prototype.init.prototype = Tween.prototype;

Tween.propHooks = {
	_default: {
		get: function( tween ) {
			var result;

			if ( tween.elem[ tween.prop ] != null &&
				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
				return tween.elem[ tween.prop ];
			}

			// Passing an empty string as a 3rd parameter to .css will automatically
			// attempt a parseFloat and fallback to a string if the parse fails.
			// Simple values such as "10px" are parsed to Float;
			// complex values such as "rotate(1rad)" are returned as-is.
			result = jQuery.css( tween.elem, tween.prop, "" );
			// Empty strings, null, undefined and "auto" are converted to 0.
			return !result || result === "auto" ? 0 : result;
		},
		set: function( tween ) {
			// Use step hook for back compat.
			// Use cssHook if its there.
			// Use .style if available and use plain properties where available.
			if ( jQuery.fx.step[ tween.prop ] ) {
				jQuery.fx.step[ tween.prop ]( tween );
			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
			} else {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	}
};

// Support: IE9
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
	set: function( tween ) {
		if ( tween.elem.nodeType && tween.elem.parentNode ) {
			tween.elem[ tween.prop ] = tween.now;
		}
	}
};

jQuery.easing = {
	linear: function( p ) {
		return p;
	},
	swing: function( p ) {
		return 0.5 - Math.cos( p * Math.PI ) / 2;
	}
};

jQuery.fx = Tween.prototype.init;

// Back Compat <1.8 extension point
jQuery.fx.step = {};




var
	fxNow, timerId,
	rfxtypes = /^(?:toggle|show|hide)$/,
	rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
	rrun = /queueHooks$/,
	animationPrefilters = [ defaultPrefilter ],
	tweeners = {
		"*": [ function( prop, value ) {
			var tween = this.createTween( prop, value ),
				target = tween.cur(),
				parts = rfxnum.exec( value ),
				unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

				// Starting value computation is required for potential unit mismatches
				start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
					rfxnum.exec( jQuery.css( tween.elem, prop ) ),
				scale = 1,
				maxIterations = 20;

			if ( start && start[ 3 ] !== unit ) {
				// Trust units reported by jQuery.css
				unit = unit || start[ 3 ];

				// Make sure we update the tween properties later on
				parts = parts || [];

				// Iteratively approximate from a nonzero starting point
				start = +target || 1;

				do {
					// If previous iteration zeroed out, double until we get *something*.
					// Use string for doubling so we don't accidentally see scale as unchanged below
					scale = scale || ".5";

					// Adjust and apply
					start = start / scale;
					jQuery.style( tween.elem, prop, start + unit );

				// Update scale, tolerating zero or NaN from tween.cur(),
				// break the loop if scale is unchanged or perfect, or if we've just had enough
				} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
			}

			// Update tween properties
			if ( parts ) {
				start = tween.start = +start || +target || 0;
				tween.unit = unit;
				// If a +=/-= token was provided, we're doing a relative animation
				tween.end = parts[ 1 ] ?
					start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
					+parts[ 2 ];
			}

			return tween;
		} ]
	};

// Animations created synchronously will run synchronously
function createFxNow() {
	setTimeout(function() {
		fxNow = undefined;
	});
	return ( fxNow = jQuery.now() );
}

// Generate parameters to create a standard animation
function genFx( type, includeWidth ) {
	var which,
		i = 0,
		attrs = { height: type };

	// If we include width, step value is 1 to do all cssExpand values,
	// otherwise step value is 2 to skip over Left and Right
	includeWidth = includeWidth ? 1 : 0;
	for ( ; i < 4 ; i += 2 - includeWidth ) {
		which = cssExpand[ i ];
		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
	}

	if ( includeWidth ) {
		attrs.opacity = attrs.width = type;
	}

	return attrs;
}

function createTween( value, prop, animation ) {
	var tween,
		collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
		index = 0,
		length = collection.length;
	for ( ; index < length; index++ ) {
		if ( (tween = collection[ index ].call( animation, prop, value )) ) {

			// We're done with this property
			return tween;
		}
	}
}

function defaultPrefilter( elem, props, opts ) {
	/* jshint validthis: true */
	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
		anim = this,
		orig = {},
		style = elem.style,
		hidden = elem.nodeType && isHidden( elem ),
		dataShow = data_priv.get( elem, "fxshow" );

	// Handle queue: false promises
	if ( !opts.queue ) {
		hooks = jQuery._queueHooks( elem, "fx" );
		if ( hooks.unqueued == null ) {
			hooks.unqueued = 0;
			oldfire = hooks.empty.fire;
			hooks.empty.fire = function() {
				if ( !hooks.unqueued ) {
					oldfire();
				}
			};
		}
		hooks.unqueued++;

		anim.always(function() {
			// Ensure the complete handler is called before this completes
			anim.always(function() {
				hooks.unqueued--;
				if ( !jQuery.queue( elem, "fx" ).length ) {
					hooks.empty.fire();
				}
			});
		});
	}

	// Height/width overflow pass
	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
		// Make sure that nothing sneaks out
		// Record all 3 overflow attributes because IE9-10 do not
		// change the overflow attribute when overflowX and
		// overflowY are set to the same value
		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

		// Set display property to inline-block for height/width
		// animations on inline elements that are having width/height animated
		display = jQuery.css( elem, "display" );

		// Test default display if display is currently "none"
		checkDisplay = display === "none" ?
			data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;

		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
			style.display = "inline-block";
		}
	}

	if ( opts.overflow ) {
		style.overflow = "hidden";
		anim.always(function() {
			style.overflow = opts.overflow[ 0 ];
			style.overflowX = opts.overflow[ 1 ];
			style.overflowY = opts.overflow[ 2 ];
		});
	}

	// show/hide pass
	for ( prop in props ) {
		value = props[ prop ];
		if ( rfxtypes.exec( value ) ) {
			delete props[ prop ];
			toggle = toggle || value === "toggle";
			if ( value === ( hidden ? "hide" : "show" ) ) {

				// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
					hidden = true;
				} else {
					continue;
				}
			}
			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );

		// Any non-fx value stops us from restoring the original display value
		} else {
			display = undefined;
		}
	}

	if ( !jQuery.isEmptyObject( orig ) ) {
		if ( dataShow ) {
			if ( "hidden" in dataShow ) {
				hidden = dataShow.hidden;
			}
		} else {
			dataShow = data_priv.access( elem, "fxshow", {} );
		}

		// Store state if its toggle - enables .stop().toggle() to "reverse"
		if ( toggle ) {
			dataShow.hidden = !hidden;
		}
		if ( hidden ) {
			jQuery( elem ).show();
		} else {
			anim.done(function() {
				jQuery( elem ).hide();
			});
		}
		anim.done(function() {
			var prop;

			data_priv.remove( elem, "fxshow" );
			for ( prop in orig ) {
				jQuery.style( elem, prop, orig[ prop ] );
			}
		});
		for ( prop in orig ) {
			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );

			if ( !( prop in dataShow ) ) {
				dataShow[ prop ] = tween.start;
				if ( hidden ) {
					tween.end = tween.start;
					tween.start = prop === "width" || prop === "height" ? 1 : 0;
				}
			}
		}

	// If this is a noop like .hide().hide(), restore an overwritten display value
	} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
		style.display = display;
	}
}

function propFilter( props, specialEasing ) {
	var index, name, easing, value, hooks;

	// camelCase, specialEasing and expand cssHook pass
	for ( index in props ) {
		name = jQuery.camelCase( index );
		easing = specialEasing[ name ];
		value = props[ index ];
		if ( jQuery.isArray( value ) ) {
			easing = value[ 1 ];
			value = props[ index ] = value[ 0 ];
		}

		if ( index !== name ) {
			props[ name ] = value;
			delete props[ index ];
		}

		hooks = jQuery.cssHooks[ name ];
		if ( hooks && "expand" in hooks ) {
			value = hooks.expand( value );
			delete props[ name ];

			// Not quite $.extend, this won't overwrite existing keys.
			// Reusing 'index' because we have the correct "name"
			for ( index in value ) {
				if ( !( index in props ) ) {
					props[ index ] = value[ index ];
					specialEasing[ index ] = easing;
				}
			}
		} else {
			specialEasing[ name ] = easing;
		}
	}
}

function Animation( elem, properties, options ) {
	var result,
		stopped,
		index = 0,
		length = animationPrefilters.length,
		deferred = jQuery.Deferred().always( function() {
			// Don't match elem in the :animated selector
			delete tick.elem;
		}),
		tick = function() {
			if ( stopped ) {
				return false;
			}
			var currentTime = fxNow || createFxNow(),
				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
				// Support: Android 2.3
				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
				temp = remaining / animation.duration || 0,
				percent = 1 - temp,
				index = 0,
				length = animation.tweens.length;

			for ( ; index < length ; index++ ) {
				animation.tweens[ index ].run( percent );
			}

			deferred.notifyWith( elem, [ animation, percent, remaining ]);

			if ( percent < 1 && length ) {
				return remaining;
			} else {
				deferred.resolveWith( elem, [ animation ] );
				return false;
			}
		},
		animation = deferred.promise({
			elem: elem,
			props: jQuery.extend( {}, properties ),
			opts: jQuery.extend( true, { specialEasing: {} }, options ),
			originalProperties: properties,
			originalOptions: options,
			startTime: fxNow || createFxNow(),
			duration: options.duration,
			tweens: [],
			createTween: function( prop, end ) {
				var tween = jQuery.Tween( elem, animation.opts, prop, end,
						animation.opts.specialEasing[ prop ] || animation.opts.easing );
				animation.tweens.push( tween );
				return tween;
			},
			stop: function( gotoEnd ) {
				var index = 0,
					// If we are going to the end, we want to run all the tweens
					// otherwise we skip this part
					length = gotoEnd ? animation.tweens.length : 0;
				if ( stopped ) {
					return this;
				}
				stopped = true;
				for ( ; index < length ; index++ ) {
					animation.tweens[ index ].run( 1 );
				}

				// Resolve when we played the last frame; otherwise, reject
				if ( gotoEnd ) {
					deferred.resolveWith( elem, [ animation, gotoEnd ] );
				} else {
					deferred.rejectWith( elem, [ animation, gotoEnd ] );
				}
				return this;
			}
		}),
		props = animation.props;

	propFilter( props, animation.opts.specialEasing );

	for ( ; index < length ; index++ ) {
		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
		if ( result ) {
			return result;
		}
	}

	jQuery.map( props, createTween, animation );

	if ( jQuery.isFunction( animation.opts.start ) ) {
		animation.opts.start.call( elem, animation );
	}

	jQuery.fx.timer(
		jQuery.extend( tick, {
			elem: elem,
			anim: animation,
			queue: animation.opts.queue
		})
	);

	// attach callbacks from options
	return animation.progress( animation.opts.progress )
		.done( animation.opts.done, animation.opts.complete )
		.fail( animation.opts.fail )
		.always( animation.opts.always );
}

jQuery.Animation = jQuery.extend( Animation, {

	tweener: function( props, callback ) {
		if ( jQuery.isFunction( props ) ) {
			callback = props;
			props = [ "*" ];
		} else {
			props = props.split(" ");
		}

		var prop,
			index = 0,
			length = props.length;

		for ( ; index < length ; index++ ) {
			prop = props[ index ];
			tweeners[ prop ] = tweeners[ prop ] || [];
			tweeners[ prop ].unshift( callback );
		}
	},

	prefilter: function( callback, prepend ) {
		if ( prepend ) {
			animationPrefilters.unshift( callback );
		} else {
			animationPrefilters.push( callback );
		}
	}
});

jQuery.speed = function( speed, easing, fn ) {
	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
		complete: fn || !fn && easing ||
			jQuery.isFunction( speed ) && speed,
		duration: speed,
		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
	};

	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;

	// Normalize opt.queue - true/undefined/null -> "fx"
	if ( opt.queue == null || opt.queue === true ) {
		opt.queue = "fx";
	}

	// Queueing
	opt.old = opt.complete;

	opt.complete = function() {
		if ( jQuery.isFunction( opt.old ) ) {
			opt.old.call( this );
		}

		if ( opt.queue ) {
			jQuery.dequeue( this, opt.queue );
		}
	};

	return opt;
};

jQuery.fn.extend({
	fadeTo: function( speed, to, easing, callback ) {

		// Show any hidden elements after setting opacity to 0
		return this.filter( isHidden ).css( "opacity", 0 ).show()

			// Animate to the value specified
			.end().animate({ opacity: to }, speed, easing, callback );
	},
	animate: function( prop, speed, easing, callback ) {
		var empty = jQuery.isEmptyObject( prop ),
			optall = jQuery.speed( speed, easing, callback ),
			doAnimation = function() {
				// Operate on a copy of prop so per-property easing won't be lost
				var anim = Animation( this, jQuery.extend( {}, prop ), optall );

				// Empty animations, or finishing resolves immediately
				if ( empty || data_priv.get( this, "finish" ) ) {
					anim.stop( true );
				}
			};
			doAnimation.finish = doAnimation;

		return empty || optall.queue === false ?
			this.each( doAnimation ) :
			this.queue( optall.queue, doAnimation );
	},
	stop: function( type, clearQueue, gotoEnd ) {
		var stopQueue = function( hooks ) {
			var stop = hooks.stop;
			delete hooks.stop;
			stop( gotoEnd );
		};

		if ( typeof type !== "string" ) {
			gotoEnd = clearQueue;
			clearQueue = type;
			type = undefined;
		}
		if ( clearQueue && type !== false ) {
			this.queue( type || "fx", [] );
		}

		return this.each(function() {
			var dequeue = true,
				index = type != null && type + "queueHooks",
				timers = jQuery.timers,
				data = data_priv.get( this );

			if ( index ) {
				if ( data[ index ] && data[ index ].stop ) {
					stopQueue( data[ index ] );
				}
			} else {
				for ( index in data ) {
					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
						stopQueue( data[ index ] );
					}
				}
			}

			for ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
					timers[ index ].anim.stop( gotoEnd );
					dequeue = false;
					timers.splice( index, 1 );
				}
			}

			// Start the next in the queue if the last step wasn't forced.
			// Timers currently will call their complete callbacks, which
			// will dequeue but only if they were gotoEnd.
			if ( dequeue || !gotoEnd ) {
				jQuery.dequeue( this, type );
			}
		});
	},
	finish: function( type ) {
		if ( type !== false ) {
			type = type || "fx";
		}
		return this.each(function() {
			var index,
				data = data_priv.get( this ),
				queue = data[ type + "queue" ],
				hooks = data[ type + "queueHooks" ],
				timers = jQuery.timers,
				length = queue ? queue.length : 0;

			// Enable finishing flag on private data
			data.finish = true;

			// Empty the queue first
			jQuery.queue( this, type, [] );

			if ( hooks && hooks.stop ) {
				hooks.stop.call( this, true );
			}

			// Look for any active animations, and finish them
			for ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
					timers[ index ].anim.stop( true );
					timers.splice( index, 1 );
				}
			}

			// Look for any animations in the old queue and finish them
			for ( index = 0; index < length; index++ ) {
				if ( queue[ index ] && queue[ index ].finish ) {
					queue[ index ].finish.call( this );
				}
			}

			// Turn off finishing flag
			delete data.finish;
		});
	}
});

jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
	var cssFn = jQuery.fn[ name ];
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		return speed == null || typeof speed === "boolean" ?
			cssFn.apply( this, arguments ) :
			this.animate( genFx( name, true ), speed, easing, callback );
	};
});

// Generate shortcuts for custom animations
jQuery.each({
	slideDown: genFx("show"),
	slideUp: genFx("hide"),
	slideToggle: genFx("toggle"),
	fadeIn: { opacity: "show" },
	fadeOut: { opacity: "hide" },
	fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		return this.animate( props, speed, easing, callback );
	};
});

jQuery.timers = [];
jQuery.fx.tick = function() {
	var timer,
		i = 0,
		timers = jQuery.timers;

	fxNow = jQuery.now();

	for ( ; i < timers.length; i++ ) {
		timer = timers[ i ];
		// Checks the timer has not already been removed
		if ( !timer() && timers[ i ] === timer ) {
			timers.splice( i--, 1 );
		}
	}

	if ( !timers.length ) {
		jQuery.fx.stop();
	}
	fxNow = undefined;
};

jQuery.fx.timer = function( timer ) {
	jQuery.timers.push( timer );
	if ( timer() ) {
		jQuery.fx.start();
	} else {
		jQuery.timers.pop();
	}
};

jQuery.fx.interval = 13;

jQuery.fx.start = function() {
	if ( !timerId ) {
		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
	}
};

jQuery.fx.stop = function() {
	clearInterval( timerId );
	timerId = null;
};

jQuery.fx.speeds = {
	slow: 600,
	fast: 200,
	// Default speed
	_default: 400
};


// Based off of the plugin by Clint Helfers, with permission.
// http://blindsignals.com/index.php/2009/07/jquery-delay/
jQuery.fn.delay = function( time, type ) {
	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
	type = type || "fx";

	return this.queue( type, function( next, hooks ) {
		var timeout = setTimeout( next, time );
		hooks.stop = function() {
			clearTimeout( timeout );
		};
	});
};


(function() {
	var input = document.createElement( "input" ),
		select = document.createElement( "select" ),
		opt = select.appendChild( document.createElement( "option" ) );

	input.type = "checkbox";

	// Support: iOS<=5.1, Android<=4.2+
	// Default value for a checkbox should be "on"
	support.checkOn = input.value !== "";

	// Support: IE<=11+
	// Must access selectedIndex to make default options select
	support.optSelected = opt.selected;

	// Support: Android<=2.3
	// Options inside disabled selects are incorrectly marked as disabled
	select.disabled = true;
	support.optDisabled = !opt.disabled;

	// Support: IE<=11+
	// An input loses its value after becoming a radio
	input = document.createElement( "input" );
	input.value = "t";
	input.type = "radio";
	support.radioValue = input.value === "t";
})();


var nodeHook, boolHook,
	attrHandle = jQuery.expr.attrHandle;

jQuery.fn.extend({
	attr: function( name, value ) {
		return access( this, jQuery.attr, name, value, arguments.length > 1 );
	},

	removeAttr: function( name ) {
		return this.each(function() {
			jQuery.removeAttr( this, name );
		});
	}
});

jQuery.extend({
	attr: function( elem, name, value ) {
		var hooks, ret,
			nType = elem.nodeType;

		// don't get/set attributes on text, comment and attribute nodes
		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
			return;
		}

		// Fallback to prop when attributes are not supported
		if ( typeof elem.getAttribute === strundefined ) {
			return jQuery.prop( elem, name, value );
		}

		// All attributes are lowercase
		// Grab necessary hook if one is defined
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
			name = name.toLowerCase();
			hooks = jQuery.attrHooks[ name ] ||
				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
		}

		if ( value !== undefined ) {

			if ( value === null ) {
				jQuery.removeAttr( elem, name );

			} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
				return ret;

			} else {
				elem.setAttribute( name, value + "" );
				return value;
			}

		} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
			return ret;

		} else {
			ret = jQuery.find.attr( elem, name );

			// Non-existent attributes return null, we normalize to undefined
			return ret == null ?
				undefined :
				ret;
		}
	},

	removeAttr: function( elem, value ) {
		var name, propName,
			i = 0,
			attrNames = value && value.match( rnotwhite );

		if ( attrNames && elem.nodeType === 1 ) {
			while ( (name = attrNames[i++]) ) {
				propName = jQuery.propFix[ name ] || name;

				// Boolean attributes get special treatment (#10870)
				if ( jQuery.expr.match.bool.test( name ) ) {
					// Set corresponding property to false
					elem[ propName ] = false;
				}

				elem.removeAttribute( name );
			}
		}
	},

	attrHooks: {
		type: {
			set: function( elem, value ) {
				if ( !support.radioValue && value === "radio" &&
					jQuery.nodeName( elem, "input" ) ) {
					var val = elem.value;
					elem.setAttribute( "type", value );
					if ( val ) {
						elem.value = val;
					}
					return value;
				}
			}
		}
	}
});

// Hooks for boolean attributes
boolHook = {
	set: function( elem, value, name ) {
		if ( value === false ) {
			// Remove boolean attributes when set to false
			jQuery.removeAttr( elem, name );
		} else {
			elem.setAttribute( name, name );
		}
		return name;
	}
};
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
	var getter = attrHandle[ name ] || jQuery.find.attr;

	attrHandle[ name ] = function( elem, name, isXML ) {
		var ret, handle;
		if ( !isXML ) {
			// Avoid an infinite loop by temporarily removing this function from the getter
			handle = attrHandle[ name ];
			attrHandle[ name ] = ret;
			ret = getter( elem, name, isXML ) != null ?
				name.toLowerCase() :
				null;
			attrHandle[ name ] = handle;
		}
		return ret;
	};
});




var rfocusable = /^(?:input|select|textarea|button)$/i;

jQuery.fn.extend({
	prop: function( name, value ) {
		return access( this, jQuery.prop, name, value, arguments.length > 1 );
	},

	removeProp: function( name ) {
		return this.each(function() {
			delete this[ jQuery.propFix[ name ] || name ];
		});
	}
});

jQuery.extend({
	propFix: {
		"for": "htmlFor",
		"class": "className"
	},

	prop: function( elem, name, value ) {
		var ret, hooks, notxml,
			nType = elem.nodeType;

		// Don't get/set properties on text, comment and attribute nodes
		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
			return;
		}

		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );

		if ( notxml ) {
			// Fix name and attach hooks
			name = jQuery.propFix[ name ] || name;
			hooks = jQuery.propHooks[ name ];
		}

		if ( value !== undefined ) {
			return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
				ret :
				( elem[ name ] = value );

		} else {
			return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
				ret :
				elem[ name ];
		}
	},

	propHooks: {
		tabIndex: {
			get: function( elem ) {
				return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
					elem.tabIndex :
					-1;
			}
		}
	}
});

if ( !support.optSelected ) {
	jQuery.propHooks.selected = {
		get: function( elem ) {
			var parent = elem.parentNode;
			if ( parent && parent.parentNode ) {
				parent.parentNode.selectedIndex;
			}
			return null;
		}
	};
}

jQuery.each([
	"tabIndex",
	"readOnly",
	"maxLength",
	"cellSpacing",
	"cellPadding",
	"rowSpan",
	"colSpan",
	"useMap",
	"frameBorder",
	"contentEditable"
], function() {
	jQuery.propFix[ this.toLowerCase() ] = this;
});




var rclass = /[\t\r\n\f]/g;

jQuery.fn.extend({
	addClass: function( value ) {
		var classes, elem, cur, clazz, j, finalValue,
			proceed = typeof value === "string" && value,
			i = 0,
			len = this.length;

		if ( jQuery.isFunction( value ) ) {
			return this.each(function( j ) {
				jQuery( this ).addClass( value.call( this, j, this.className ) );
			});
		}

		if ( proceed ) {
			// The disjunction here is for better compressibility (see removeClass)
			classes = ( value || "" ).match( rnotwhite ) || [];

			for ( ; i < len; i++ ) {
				elem = this[ i ];
				cur = elem.nodeType === 1 && ( elem.className ?
					( " " + elem.className + " " ).replace( rclass, " " ) :
					" "
				);

				if ( cur ) {
					j = 0;
					while ( (clazz = classes[j++]) ) {
						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
							cur += clazz + " ";
						}
					}

					// only assign if different to avoid unneeded rendering.
					finalValue = jQuery.trim( cur );
					if ( elem.className !== finalValue ) {
						elem.className = finalValue;
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		var classes, elem, cur, clazz, j, finalValue,
			proceed = arguments.length === 0 || typeof value === "string" && value,
			i = 0,
			len = this.length;

		if ( jQuery.isFunction( value ) ) {
			return this.each(function( j ) {
				jQuery( this ).removeClass( value.call( this, j, this.className ) );
			});
		}
		if ( proceed ) {
			classes = ( value || "" ).match( rnotwhite ) || [];

			for ( ; i < len; i++ ) {
				elem = this[ i ];
				// This expression is here for better compressibility (see addClass)
				cur = elem.nodeType === 1 && ( elem.className ?
					( " " + elem.className + " " ).replace( rclass, " " ) :
					""
				);

				if ( cur ) {
					j = 0;
					while ( (clazz = classes[j++]) ) {
						// Remove *all* instances
						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
							cur = cur.replace( " " + clazz + " ", " " );
						}
					}

					// Only assign if different to avoid unneeded rendering.
					finalValue = value ? jQuery.trim( cur ) : "";
					if ( elem.className !== finalValue ) {
						elem.className = finalValue;
					}
				}
			}
		}

		return this;
	},

	toggleClass: function( value, stateVal ) {
		var type = typeof value;

		if ( typeof stateVal === "boolean" && type === "string" ) {
			return stateVal ? this.addClass( value ) : this.removeClass( value );
		}

		if ( jQuery.isFunction( value ) ) {
			return this.each(function( i ) {
				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
			});
		}

		return this.each(function() {
			if ( type === "string" ) {
				// Toggle individual class names
				var className,
					i = 0,
					self = jQuery( this ),
					classNames = value.match( rnotwhite ) || [];

				while ( (className = classNames[ i++ ]) ) {
					// Check each className given, space separated list
					if ( self.hasClass( className ) ) {
						self.removeClass( className );
					} else {
						self.addClass( className );
					}
				}

			// Toggle whole class name
			} else if ( type === strundefined || type === "boolean" ) {
				if ( this.className ) {
					// store className if set
					data_priv.set( this, "__className__", this.className );
				}

				// If the element has a class name or if we're passed `false`,
				// then remove the whole classname (if there was one, the above saved it).
				// Otherwise bring back whatever was previously saved (if anything),
				// falling back to the empty string if nothing was stored.
				this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
			}
		});
	},

	hasClass: function( selector ) {
		var className = " " + selector + " ",
			i = 0,
			l = this.length;
		for ( ; i < l; i++ ) {
			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
				return true;
			}
		}

		return false;
	}
});




var rreturn = /\r/g;

jQuery.fn.extend({
	val: function( value ) {
		var hooks, ret, isFunction,
			elem = this[0];

		if ( !arguments.length ) {
			if ( elem ) {
				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];

				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
					return ret;
				}

				ret = elem.value;

				return typeof ret === "string" ?
					// Handle most common string cases
					ret.replace(rreturn, "") :
					// Handle cases where value is null/undef or number
					ret == null ? "" : ret;
			}

			return;
		}

		isFunction = jQuery.isFunction( value );

		return this.each(function( i ) {
			var val;

			if ( this.nodeType !== 1 ) {
				return;
			}

			if ( isFunction ) {
				val = value.call( this, i, jQuery( this ).val() );
			} else {
				val = value;
			}

			// Treat null/undefined as ""; convert numbers to string
			if ( val == null ) {
				val = "";

			} else if ( typeof val === "number" ) {
				val += "";

			} else if ( jQuery.isArray( val ) ) {
				val = jQuery.map( val, function( value ) {
					return value == null ? "" : value + "";
				});
			}

			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];

			// If set returns undefined, fall back to normal setting
			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
				this.value = val;
			}
		});
	}
});

jQuery.extend({
	valHooks: {
		option: {
			get: function( elem ) {
				var val = jQuery.find.attr( elem, "value" );
				return val != null ?
					val :
					// Support: IE10-11+
					// option.text throws exceptions (#14686, #14858)
					jQuery.trim( jQuery.text( elem ) );
			}
		},
		select: {
			get: function( elem ) {
				var value, option,
					options = elem.options,
					index = elem.selectedIndex,
					one = elem.type === "select-one" || index < 0,
					values = one ? null : [],
					max = one ? index + 1 : options.length,
					i = index < 0 ?
						max :
						one ? index : 0;

				// Loop through all the selected options
				for ( ; i < max; i++ ) {
					option = options[ i ];

					// IE6-9 doesn't update selected after form reset (#2551)
					if ( ( option.selected || i === index ) &&
							// Don't return options that are disabled or in a disabled optgroup
							( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {

						// Get the specific value for the option
						value = jQuery( option ).val();

						// We don't need an array for one selects
						if ( one ) {
							return value;
						}

						// Multi-Selects return an array
						values.push( value );
					}
				}

				return values;
			},

			set: function( elem, value ) {
				var optionSet, option,
					options = elem.options,
					values = jQuery.makeArray( value ),
					i = options.length;

				while ( i-- ) {
					option = options[ i ];
					if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
						optionSet = true;
					}
				}

				// Force browsers to behave consistently when non-matching value is set
				if ( !optionSet ) {
					elem.selectedIndex = -1;
				}
				return values;
			}
		}
	}
});

// Radios and checkboxes getter/setter
jQuery.each([ "radio", "checkbox" ], function() {
	jQuery.valHooks[ this ] = {
		set: function( elem, value ) {
			if ( jQuery.isArray( value ) ) {
				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
			}
		}
	};
	if ( !support.checkOn ) {
		jQuery.valHooks[ this ].get = function( elem ) {
			return elem.getAttribute("value") === null ? "on" : elem.value;
		};
	}
});




// Return jQuery for attributes-only inclusion


jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {

	// Handle event binding
	jQuery.fn[ name ] = function( data, fn ) {
		return arguments.length > 0 ?
			this.on( name, null, data, fn ) :
			this.trigger( name );
	};
});

jQuery.fn.extend({
	hover: function( fnOver, fnOut ) {
		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
	},

	bind: function( types, data, fn ) {
		return this.on( types, null, data, fn );
	},
	unbind: function( types, fn ) {
		return this.off( types, null, fn );
	},

	delegate: function( selector, types, data, fn ) {
		return this.on( types, selector, data, fn );
	},
	undelegate: function( selector, types, fn ) {
		// ( namespace ) or ( selector, types [, fn] )
		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
	}
});


var nonce = jQuery.now();

var rquery = (/\?/);



// Support: Android 2.3
// Workaround failure to string-cast null input
jQuery.parseJSON = function( data ) {
	return JSON.parse( data + "" );
};


// Cross-browser xml parsing
jQuery.parseXML = function( data ) {
	var xml, tmp;
	if ( !data || typeof data !== "string" ) {
		return null;
	}

	// Support: IE9
	try {
		tmp = new DOMParser();
		xml = tmp.parseFromString( data, "text/xml" );
	} catch ( e ) {
		xml = undefined;
	}

	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
		jQuery.error( "Invalid XML: " + data );
	}
	return xml;
};


var
	rhash = /#.*$/,
	rts = /([?&])_=[^&]*/,
	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
	// #7653, #8125, #8152: local protocol detection
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
	rnoContent = /^(?:GET|HEAD)$/,
	rprotocol = /^\/\//,
	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,

	/* Prefilters
	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
	 * 2) These are called:
	 *    - BEFORE asking for a transport
	 *    - AFTER param serialization (s.data is a string if s.processData is true)
	 * 3) key is the dataType
	 * 4) the catchall symbol "*" can be used
	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
	 */
	prefilters = {},

	/* Transports bindings
	 * 1) key is the dataType
	 * 2) the catchall symbol "*" can be used
	 * 3) selection will start with transport dataType and THEN go to "*" if needed
	 */
	transports = {},

	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
	allTypes = "*/".concat( "*" ),

	// Document location
	ajaxLocation = window.location.href,

	// Segment location into parts
	ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];

// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) {

	// dataTypeExpression is optional and defaults to "*"
	return function( dataTypeExpression, func ) {

		if ( typeof dataTypeExpression !== "string" ) {
			func = dataTypeExpression;
			dataTypeExpression = "*";
		}

		var dataType,
			i = 0,
			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];

		if ( jQuery.isFunction( func ) ) {
			// For each dataType in the dataTypeExpression
			while ( (dataType = dataTypes[i++]) ) {
				// Prepend if requested
				if ( dataType[0] === "+" ) {
					dataType = dataType.slice( 1 ) || "*";
					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );

				// Otherwise append
				} else {
					(structure[ dataType ] = structure[ dataType ] || []).push( func );
				}
			}
		}
	};
}

// Base inspection function for prefilters and transports
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {

	var inspected = {},
		seekingTransport = ( structure === transports );

	function inspect( dataType ) {
		var selected;
		inspected[ dataType ] = true;
		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
			if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
				options.dataTypes.unshift( dataTypeOrTransport );
				inspect( dataTypeOrTransport );
				return false;
			} else if ( seekingTransport ) {
				return !( selected = dataTypeOrTransport );
			}
		});
		return selected;
	}

	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
}

// A special extend for ajax options
// that takes "flat" options (not to be deep extended)
// Fixes #9887
function ajaxExtend( target, src ) {
	var key, deep,
		flatOptions = jQuery.ajaxSettings.flatOptions || {};

	for ( key in src ) {
		if ( src[ key ] !== undefined ) {
			( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
		}
	}
	if ( deep ) {
		jQuery.extend( true, target, deep );
	}

	return target;
}

/* Handles responses to an ajax request:
 * - finds the right dataType (mediates between content-type and expected dataType)
 * - returns the corresponding response
 */
function ajaxHandleResponses( s, jqXHR, responses ) {

	var ct, type, finalDataType, firstDataType,
		contents = s.contents,
		dataTypes = s.dataTypes;

	// Remove auto dataType and get content-type in the process
	while ( dataTypes[ 0 ] === "*" ) {
		dataTypes.shift();
		if ( ct === undefined ) {
			ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
		}
	}

	// Check if we're dealing with a known content-type
	if ( ct ) {
		for ( type in contents ) {
			if ( contents[ type ] && contents[ type ].test( ct ) ) {
				dataTypes.unshift( type );
				break;
			}
		}
	}

	// Check to see if we have a response for the expected dataType
	if ( dataTypes[ 0 ] in responses ) {
		finalDataType = dataTypes[ 0 ];
	} else {
		// Try convertible dataTypes
		for ( type in responses ) {
			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
				finalDataType = type;
				break;
			}
			if ( !firstDataType ) {
				firstDataType = type;
			}
		}
		// Or just use first one
		finalDataType = finalDataType || firstDataType;
	}

	// If we found a dataType
	// We add the dataType to the list if needed
	// and return the corresponding response
	if ( finalDataType ) {
		if ( finalDataType !== dataTypes[ 0 ] ) {
			dataTypes.unshift( finalDataType );
		}
		return responses[ finalDataType ];
	}
}

/* Chain conversions given the request and the original response
 * Also sets the responseXXX fields on the jqXHR instance
 */
function ajaxConvert( s, response, jqXHR, isSuccess ) {
	var conv2, current, conv, tmp, prev,
		converters = {},
		// Work with a copy of dataTypes in case we need to modify it for conversion
		dataTypes = s.dataTypes.slice();

	// Create converters map with lowercased keys
	if ( dataTypes[ 1 ] ) {
		for ( conv in s.converters ) {
			converters[ conv.toLowerCase() ] = s.converters[ conv ];
		}
	}

	current = dataTypes.shift();

	// Convert to each sequential dataType
	while ( current ) {

		if ( s.responseFields[ current ] ) {
			jqXHR[ s.responseFields[ current ] ] = response;
		}

		// Apply the dataFilter if provided
		if ( !prev && isSuccess && s.dataFilter ) {
			response = s.dataFilter( response, s.dataType );
		}

		prev = current;
		current = dataTypes.shift();

		if ( current ) {

		// There's only work to do if current dataType is non-auto
			if ( current === "*" ) {

				current = prev;

			// Convert response if prev dataType is non-auto and differs from current
			} else if ( prev !== "*" && prev !== current ) {

				// Seek a direct converter
				conv = converters[ prev + " " + current ] || converters[ "* " + current ];

				// If none found, seek a pair
				if ( !conv ) {
					for ( conv2 in converters ) {

						// If conv2 outputs current
						tmp = conv2.split( " " );
						if ( tmp[ 1 ] === current ) {

							// If prev can be converted to accepted input
							conv = converters[ prev + " " + tmp[ 0 ] ] ||
								converters[ "* " + tmp[ 0 ] ];
							if ( conv ) {
								// Condense equivalence converters
								if ( conv === true ) {
									conv = converters[ conv2 ];

								// Otherwise, insert the intermediate dataType
								} else if ( converters[ conv2 ] !== true ) {
									current = tmp[ 0 ];
									dataTypes.unshift( tmp[ 1 ] );
								}
								break;
							}
						}
					}
				}

				// Apply converter (if not an equivalence)
				if ( conv !== true ) {

					// Unless errors are allowed to bubble, catch and return them
					if ( conv && s[ "throws" ] ) {
						response = conv( response );
					} else {
						try {
							response = conv( response );
						} catch ( e ) {
							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
						}
					}
				}
			}
		}
	}

	return { state: "success", data: response };
}

jQuery.extend({

	// Counter for holding the number of active queries
	active: 0,

	// Last-Modified header cache for next request
	lastModified: {},
	etag: {},

	ajaxSettings: {
		url: ajaxLocation,
		type: "GET",
		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
		global: true,
		processData: true,
		async: true,
		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
		/*
		timeout: 0,
		data: null,
		dataType: null,
		username: null,
		password: null,
		cache: null,
		throws: false,
		traditional: false,
		headers: {},
		*/

		accepts: {
			"*": allTypes,
			text: "text/plain",
			html: "text/html",
			xml: "application/xml, text/xml",
			json: "application/json, text/javascript"
		},

		contents: {
			xml: /xml/,
			html: /html/,
			json: /json/
		},

		responseFields: {
			xml: "responseXML",
			text: "responseText",
			json: "responseJSON"
		},

		// Data converters
		// Keys separate source (or catchall "*") and destination types with a single space
		converters: {

			// Convert anything to text
			"* text": String,

			// Text to html (true = no transformation)
			"text html": true,

			// Evaluate text as a json expression
			"text json": jQuery.parseJSON,

			// Parse text as xml
			"text xml": jQuery.parseXML
		},

		// For options that shouldn't be deep extended:
		// you can add your own custom options here if
		// and when you create one that shouldn't be
		// deep extended (see ajaxExtend)
		flatOptions: {
			url: true,
			context: true
		}
	},

	// Creates a full fledged settings object into target
	// with both ajaxSettings and settings fields.
	// If target is omitted, writes into ajaxSettings.
	ajaxSetup: function( target, settings ) {
		return settings ?

			// Building a settings object
			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :

			// Extending ajaxSettings
			ajaxExtend( jQuery.ajaxSettings, target );
	},

	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
	ajaxTransport: addToPrefiltersOrTransports( transports ),

	// Main method
	ajax: function( url, options ) {

		// If url is an object, simulate pre-1.5 signature
		if ( typeof url === "object" ) {
			options = url;
			url = undefined;
		}

		// Force options to be an object
		options = options || {};

		var transport,
			// URL without anti-cache param
			cacheURL,
			// Response headers
			responseHeadersString,
			responseHeaders,
			// timeout handle
			timeoutTimer,
			// Cross-domain detection vars
			parts,
			// To know if global events are to be dispatched
			fireGlobals,
			// Loop variable
			i,
			// Create the final options object
			s = jQuery.ajaxSetup( {}, options ),
			// Callbacks context
			callbackContext = s.context || s,
			// Context for global events is callbackContext if it is a DOM node or jQuery collection
			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
				jQuery( callbackContext ) :
				jQuery.event,
			// Deferreds
			deferred = jQuery.Deferred(),
			completeDeferred = jQuery.Callbacks("once memory"),
			// Status-dependent callbacks
			statusCode = s.statusCode || {},
			// Headers (they are sent all at once)
			requestHeaders = {},
			requestHeadersNames = {},
			// The jqXHR state
			state = 0,
			// Default abort message
			strAbort = "canceled",
			// Fake xhr
			jqXHR = {
				readyState: 0,

				// Builds headers hashtable if needed
				getResponseHeader: function( key ) {
					var match;
					if ( state === 2 ) {
						if ( !responseHeaders ) {
							responseHeaders = {};
							while ( (match = rheaders.exec( responseHeadersString )) ) {
								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
							}
						}
						match = responseHeaders[ key.toLowerCase() ];
					}
					return match == null ? null : match;
				},

				// Raw string
				getAllResponseHeaders: function() {
					return state === 2 ? responseHeadersString : null;
				},

				// Caches the header
				setRequestHeader: function( name, value ) {
					var lname = name.toLowerCase();
					if ( !state ) {
						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
						requestHeaders[ name ] = value;
					}
					return this;
				},

				// Overrides response content-type header
				overrideMimeType: function( type ) {
					if ( !state ) {
						s.mimeType = type;
					}
					return this;
				},

				// Status-dependent callbacks
				statusCode: function( map ) {
					var code;
					if ( map ) {
						if ( state < 2 ) {
							for ( code in map ) {
								// Lazy-add the new callback in a way that preserves old ones
								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
							}
						} else {
							// Execute the appropriate callbacks
							jqXHR.always( map[ jqXHR.status ] );
						}
					}
					return this;
				},

				// Cancel the request
				abort: function( statusText ) {
					var finalText = statusText || strAbort;
					if ( transport ) {
						transport.abort( finalText );
					}
					done( 0, finalText );
					return this;
				}
			};

		// Attach deferreds
		deferred.promise( jqXHR ).complete = completeDeferred.add;
		jqXHR.success = jqXHR.done;
		jqXHR.error = jqXHR.fail;

		// Remove hash character (#7531: and string promotion)
		// Add protocol if not provided (prefilters might expect it)
		// Handle falsy url in the settings object (#10093: consistency with old signature)
		// We also use the url parameter if available
		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
			.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );

		// Alias method option to type as per ticket #12004
		s.type = options.method || options.type || s.method || s.type;

		// Extract dataTypes list
		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];

		// A cross-domain request is in order when we have a protocol:host:port mismatch
		if ( s.crossDomain == null ) {
			parts = rurl.exec( s.url.toLowerCase() );
			s.crossDomain = !!( parts &&
				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
			);
		}

		// Convert data if not already a string
		if ( s.data && s.processData && typeof s.data !== "string" ) {
			s.data = jQuery.param( s.data, s.traditional );
		}

		// Apply prefilters
		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );

		// If request was aborted inside a prefilter, stop there
		if ( state === 2 ) {
			return jqXHR;
		}

		// We can fire global events as of now if asked to
		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
		fireGlobals = jQuery.event && s.global;

		// Watch for a new set of requests
		if ( fireGlobals && jQuery.active++ === 0 ) {
			jQuery.event.trigger("ajaxStart");
		}

		// Uppercase the type
		s.type = s.type.toUpperCase();

		// Determine if request has content
		s.hasContent = !rnoContent.test( s.type );

		// Save the URL in case we're toying with the If-Modified-Since
		// and/or If-None-Match header later on
		cacheURL = s.url;

		// More options handling for requests with no content
		if ( !s.hasContent ) {

			// If data is available, append data to url
			if ( s.data ) {
				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
				// #9682: remove data so that it's not used in an eventual retry
				delete s.data;
			}

			// Add anti-cache in url if needed
			if ( s.cache === false ) {
				s.url = rts.test( cacheURL ) ?

					// If there is already a '_' parameter, set its value
					cacheURL.replace( rts, "$1_=" + nonce++ ) :

					// Otherwise add one to the end
					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
			}
		}

		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
		if ( s.ifModified ) {
			if ( jQuery.lastModified[ cacheURL ] ) {
				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
			}
			if ( jQuery.etag[ cacheURL ] ) {
				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
			}
		}

		// Set the correct header, if data is being sent
		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
			jqXHR.setRequestHeader( "Content-Type", s.contentType );
		}

		// Set the Accepts header for the server, depending on the dataType
		jqXHR.setRequestHeader(
			"Accept",
			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
				s.accepts[ "*" ]
		);

		// Check for headers option
		for ( i in s.headers ) {
			jqXHR.setRequestHeader( i, s.headers[ i ] );
		}

		// Allow custom headers/mimetypes and early abort
		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
			// Abort if not done already and return
			return jqXHR.abort();
		}

		// Aborting is no longer a cancellation
		strAbort = "abort";

		// Install callbacks on deferreds
		for ( i in { success: 1, error: 1, complete: 1 } ) {
			jqXHR[ i ]( s[ i ] );
		}

		// Get transport
		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );

		// If no transport, we auto-abort
		if ( !transport ) {
			done( -1, "No Transport" );
		} else {
			jqXHR.readyState = 1;

			// Send global event
			if ( fireGlobals ) {
				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
			}
			// Timeout
			if ( s.async && s.timeout > 0 ) {
				timeoutTimer = setTimeout(function() {
					jqXHR.abort("timeout");
				}, s.timeout );
			}

			try {
				state = 1;
				transport.send( requestHeaders, done );
			} catch ( e ) {
				// Propagate exception as error if not done
				if ( state < 2 ) {
					done( -1, e );
				// Simply rethrow otherwise
				} else {
					throw e;
				}
			}
		}

		// Callback for when everything is done
		function done( status, nativeStatusText, responses, headers ) {
			var isSuccess, success, error, response, modified,
				statusText = nativeStatusText;

			// Called once
			if ( state === 2 ) {
				return;
			}

			// State is "done" now
			state = 2;

			// Clear timeout if it exists
			if ( timeoutTimer ) {
				clearTimeout( timeoutTimer );
			}

			// Dereference transport for early garbage collection
			// (no matter how long the jqXHR object will be used)
			transport = undefined;

			// Cache response headers
			responseHeadersString = headers || "";

			// Set readyState
			jqXHR.readyState = status > 0 ? 4 : 0;

			// Determine if successful
			isSuccess = status >= 200 && status < 300 || status === 304;

			// Get response data
			if ( responses ) {
				response = ajaxHandleResponses( s, jqXHR, responses );
			}

			// Convert no matter what (that way responseXXX fields are always set)
			response = ajaxConvert( s, response, jqXHR, isSuccess );

			// If successful, handle type chaining
			if ( isSuccess ) {

				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
				if ( s.ifModified ) {
					modified = jqXHR.getResponseHeader("Last-Modified");
					if ( modified ) {
						jQuery.lastModified[ cacheURL ] = modified;
					}
					modified = jqXHR.getResponseHeader("etag");
					if ( modified ) {
						jQuery.etag[ cacheURL ] = modified;
					}
				}

				// if no content
				if ( status === 204 || s.type === "HEAD" ) {
					statusText = "nocontent";

				// if not modified
				} else if ( status === 304 ) {
					statusText = "notmodified";

				// If we have data, let's convert it
				} else {
					statusText = response.state;
					success = response.data;
					error = response.error;
					isSuccess = !error;
				}
			} else {
				// Extract error from statusText and normalize for non-aborts
				error = statusText;
				if ( status || !statusText ) {
					statusText = "error";
					if ( status < 0 ) {
						status = 0;
					}
				}
			}

			// Set data for the fake xhr object
			jqXHR.status = status;
			jqXHR.statusText = ( nativeStatusText || statusText ) + "";

			// Success/Error
			if ( isSuccess ) {
				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
			} else {
				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
			}

			// Status-dependent callbacks
			jqXHR.statusCode( statusCode );
			statusCode = undefined;

			if ( fireGlobals ) {
				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
					[ jqXHR, s, isSuccess ? success : error ] );
			}

			// Complete
			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );

			if ( fireGlobals ) {
				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
				// Handle the global AJAX counter
				if ( !( --jQuery.active ) ) {
					jQuery.event.trigger("ajaxStop");
				}
			}
		}

		return jqXHR;
	},

	getJSON: function( url, data, callback ) {
		return jQuery.get( url, data, callback, "json" );
	},

	getScript: function( url, callback ) {
		return jQuery.get( url, undefined, callback, "script" );
	}
});

jQuery.each( [ "get", "post" ], function( i, method ) {
	jQuery[ method ] = function( url, data, callback, type ) {
		// Shift arguments if data argument was omitted
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = undefined;
		}

		return jQuery.ajax({
			url: url,
			type: method,
			dataType: type,
			data: data,
			success: callback
		});
	};
});


jQuery._evalUrl = function( url ) {
	return jQuery.ajax({
		url: url,
		type: "GET",
		dataType: "script",
		async: false,
		global: false,
		"throws": true
	});
};


jQuery.fn.extend({
	wrapAll: function( html ) {
		var wrap;

		if ( jQuery.isFunction( html ) ) {
			return this.each(function( i ) {
				jQuery( this ).wrapAll( html.call(this, i) );
			});
		}

		if ( this[ 0 ] ) {

			// The elements to wrap the target around
			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );

			if ( this[ 0 ].parentNode ) {
				wrap.insertBefore( this[ 0 ] );
			}

			wrap.map(function() {
				var elem = this;

				while ( elem.firstElementChild ) {
					elem = elem.firstElementChild;
				}

				return elem;
			}).append( this );
		}

		return this;
	},

	wrapInner: function( html ) {
		if ( jQuery.isFunction( html ) ) {
			return this.each(function( i ) {
				jQuery( this ).wrapInner( html.call(this, i) );
			});
		}

		return this.each(function() {
			var self = jQuery( this ),
				contents = self.contents();

			if ( contents.length ) {
				contents.wrapAll( html );

			} else {
				self.append( html );
			}
		});
	},

	wrap: function( html ) {
		var isFunction = jQuery.isFunction( html );

		return this.each(function( i ) {
			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
		});
	},

	unwrap: function() {
		return this.parent().each(function() {
			if ( !jQuery.nodeName( this, "body" ) ) {
				jQuery( this ).replaceWith( this.childNodes );
			}
		}).end();
	}
});


jQuery.expr.filters.hidden = function( elem ) {
	// Support: Opera <= 12.12
	// Opera reports offsetWidths and offsetHeights less than zero on some elements
	return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
};
jQuery.expr.filters.visible = function( elem ) {
	return !jQuery.expr.filters.hidden( elem );
};




var r20 = /%20/g,
	rbracket = /\[\]$/,
	rCRLF = /\r?\n/g,
	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
	rsubmittable = /^(?:input|select|textarea|keygen)/i;

function buildParams( prefix, obj, traditional, add ) {
	var name;

	if ( jQuery.isArray( obj ) ) {
		// Serialize array item.
		jQuery.each( obj, function( i, v ) {
			if ( traditional || rbracket.test( prefix ) ) {
				// Treat each array item as a scalar.
				add( prefix, v );

			} else {
				// Item is non-scalar (array or object), encode its numeric index.
				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
			}
		});

	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
		// Serialize object item.
		for ( name in obj ) {
			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
		}

	} else {
		// Serialize scalar item.
		add( prefix, obj );
	}
}

// Serialize an array of form elements or a set of
// key/values into a query string
jQuery.param = function( a, traditional ) {
	var prefix,
		s = [],
		add = function( key, value ) {
			// If value is a function, invoke it and return its value
			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
		};

	// Set traditional to true for jQuery <= 1.3.2 behavior.
	if ( traditional === undefined ) {
		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
	}

	// If an array was passed in, assume that it is an array of form elements.
	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
		// Serialize the form elements
		jQuery.each( a, function() {
			add( this.name, this.value );
		});

	} else {
		// If traditional, encode the "old" way (the way 1.3.2 or older
		// did it), otherwise encode params recursively.
		for ( prefix in a ) {
			buildParams( prefix, a[ prefix ], traditional, add );
		}
	}

	// Return the resulting serialization
	return s.join( "&" ).replace( r20, "+" );
};

jQuery.fn.extend({
	serialize: function() {
		return jQuery.param( this.serializeArray() );
	},
	serializeArray: function() {
		return this.map(function() {
			// Can add propHook for "elements" to filter or add form elements
			var elements = jQuery.prop( this, "elements" );
			return elements ? jQuery.makeArray( elements ) : this;
		})
		.filter(function() {
			var type = this.type;

			// Use .is( ":disabled" ) so that fieldset[disabled] works
			return this.name && !jQuery( this ).is( ":disabled" ) &&
				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
				( this.checked || !rcheckableType.test( type ) );
		})
		.map(function( i, elem ) {
			var val = jQuery( this ).val();

			return val == null ?
				null :
				jQuery.isArray( val ) ?
					jQuery.map( val, function( val ) {
						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
					}) :
					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
		}).get();
	}
});


jQuery.ajaxSettings.xhr = function() {
	try {
		return new XMLHttpRequest();
	} catch( e ) {}
};

var xhrId = 0,
	xhrCallbacks = {},
	xhrSuccessStatus = {
		// file protocol always yields status code 0, assume 200
		0: 200,
		// Support: IE9
		// #1450: sometimes IE returns 1223 when it should be 204
		1223: 204
	},
	xhrSupported = jQuery.ajaxSettings.xhr();

// Support: IE9
// Open requests must be manually aborted on unload (#5280)
// See https://support.microsoft.com/kb/2856746 for more info
if ( window.attachEvent ) {
	window.attachEvent( "onunload", function() {
		for ( var key in xhrCallbacks ) {
			xhrCallbacks[ key ]();
		}
	});
}

support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
support.ajax = xhrSupported = !!xhrSupported;

jQuery.ajaxTransport(function( options ) {
	var callback;

	// Cross domain only allowed if supported through XMLHttpRequest
	if ( support.cors || xhrSupported && !options.crossDomain ) {
		return {
			send: function( headers, complete ) {
				var i,
					xhr = options.xhr(),
					id = ++xhrId;

				xhr.open( options.type, options.url, options.async, options.username, options.password );

				// Apply custom fields if provided
				if ( options.xhrFields ) {
					for ( i in options.xhrFields ) {
						xhr[ i ] = options.xhrFields[ i ];
					}
				}

				// Override mime type if needed
				if ( options.mimeType && xhr.overrideMimeType ) {
					xhr.overrideMimeType( options.mimeType );
				}

				// X-Requested-With header
				// For cross-domain requests, seeing as conditions for a preflight are
				// akin to a jigsaw puzzle, we simply never set it to be sure.
				// (it can always be set on a per-request basis or even using ajaxSetup)
				// For same-domain requests, won't change header if already provided.
				if ( !options.crossDomain && !headers["X-Requested-With"] ) {
					headers["X-Requested-With"] = "XMLHttpRequest";
				}

				// Set headers
				for ( i in headers ) {
					xhr.setRequestHeader( i, headers[ i ] );
				}

				// Callback
				callback = function( type ) {
					return function() {
						if ( callback ) {
							delete xhrCallbacks[ id ];
							callback = xhr.onload = xhr.onerror = null;

							if ( type === "abort" ) {
								xhr.abort();
							} else if ( type === "error" ) {
								complete(
									// file: protocol always yields status 0; see #8605, #14207
									xhr.status,
									xhr.statusText
								);
							} else {
								complete(
									xhrSuccessStatus[ xhr.status ] || xhr.status,
									xhr.statusText,
									// Support: IE9
									// Accessing binary-data responseText throws an exception
									// (#11426)
									typeof xhr.responseText === "string" ? {
										text: xhr.responseText
									} : undefined,
									xhr.getAllResponseHeaders()
								);
							}
						}
					};
				};

				// Listen to events
				xhr.onload = callback();
				xhr.onerror = callback("error");

				// Create the abort callback
				callback = xhrCallbacks[ id ] = callback("abort");

				try {
					// Do send the request (this may raise an exception)
					xhr.send( options.hasContent && options.data || null );
				} catch ( e ) {
					// #14683: Only rethrow if this hasn't been notified as an error yet
					if ( callback ) {
						throw e;
					}
				}
			},

			abort: function() {
				if ( callback ) {
					callback();
				}
			}
		};
	}
});




// Install script dataType
jQuery.ajaxSetup({
	accepts: {
		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
	},
	contents: {
		script: /(?:java|ecma)script/
	},
	converters: {
		"text script": function( text ) {
			jQuery.globalEval( text );
			return text;
		}
	}
});

// Handle cache's special case and crossDomain
jQuery.ajaxPrefilter( "script", function( s ) {
	if ( s.cache === undefined ) {
		s.cache = false;
	}
	if ( s.crossDomain ) {
		s.type = "GET";
	}
});

// Bind script tag hack transport
jQuery.ajaxTransport( "script", function( s ) {
	// This transport only deals with cross domain requests
	if ( s.crossDomain ) {
		var script, callback;
		return {
			send: function( _, complete ) {
				script = jQuery("<script>").prop({
					async: true,
					charset: s.scriptCharset,
					src: s.url
				}).on(
					"load error",
					callback = function( evt ) {
						script.remove();
						callback = null;
						if ( evt ) {
							complete( evt.type === "error" ? 404 : 200, evt.type );
						}
					}
				);
				document.head.appendChild( script[ 0 ] );
			},
			abort: function() {
				if ( callback ) {
					callback();
				}
			}
		};
	}
});




var oldCallbacks = [],
	rjsonp = /(=)\?(?=&|$)|\?\?/;

// Default jsonp settings
jQuery.ajaxSetup({
	jsonp: "callback",
	jsonpCallback: function() {
		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
		this[ callback ] = true;
		return callback;
	}
});

// Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {

	var callbackName, overwritten, responseContainer,
		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
			"url" :
			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
		);

	// Handle iff the expected data type is "jsonp" or we have a parameter to set
	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {

		// Get callback name, remembering preexisting value associated with it
		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
			s.jsonpCallback() :
			s.jsonpCallback;

		// Insert callback into url or form data
		if ( jsonProp ) {
			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
		} else if ( s.jsonp !== false ) {
			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
		}

		// Use data converter to retrieve json after script execution
		s.converters["script json"] = function() {
			if ( !responseContainer ) {
				jQuery.error( callbackName + " was not called" );
			}
			return responseContainer[ 0 ];
		};

		// force json dataType
		s.dataTypes[ 0 ] = "json";

		// Install callback
		overwritten = window[ callbackName ];
		window[ callbackName ] = function() {
			responseContainer = arguments;
		};

		// Clean-up function (fires after converters)
		jqXHR.always(function() {
			// Restore preexisting value
			window[ callbackName ] = overwritten;

			// Save back as free
			if ( s[ callbackName ] ) {
				// make sure that re-using the options doesn't screw things around
				s.jsonpCallback = originalSettings.jsonpCallback;

				// save the callback name for future use
				oldCallbacks.push( callbackName );
			}

			// Call if it was a function and we have a response
			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
				overwritten( responseContainer[ 0 ] );
			}

			responseContainer = overwritten = undefined;
		});

		// Delegate to script
		return "script";
	}
});




// data: string of html
// context (optional): If specified, the fragment will be created in this context, defaults to document
// keepScripts (optional): If true, will include scripts passed in the html string
jQuery.parseHTML = function( data, context, keepScripts ) {
	if ( !data || typeof data !== "string" ) {
		return null;
	}
	if ( typeof context === "boolean" ) {
		keepScripts = context;
		context = false;
	}
	context = context || document;

	var parsed = rsingleTag.exec( data ),
		scripts = !keepScripts && [];

	// Single tag
	if ( parsed ) {
		return [ context.createElement( parsed[1] ) ];
	}

	parsed = jQuery.buildFragment( [ data ], context, scripts );

	if ( scripts && scripts.length ) {
		jQuery( scripts ).remove();
	}

	return jQuery.merge( [], parsed.childNodes );
};


// Keep a copy of the old load method
var _load = jQuery.fn.load;

/**
 * Load a url into a page
 */
jQuery.fn.load = function( url, params, callback ) {
	if ( typeof url !== "string" && _load ) {
		return _load.apply( this, arguments );
	}

	var selector, type, response,
		self = this,
		off = url.indexOf(" ");

	if ( off >= 0 ) {
		selector = jQuery.trim( url.slice( off ) );
		url = url.slice( 0, off );
	}

	// If it's a function
	if ( jQuery.isFunction( params ) ) {

		// We assume that it's the callback
		callback = params;
		params = undefined;

	// Otherwise, build a param string
	} else if ( params && typeof params === "object" ) {
		type = "POST";
	}

	// If we have elements to modify, make the request
	if ( self.length > 0 ) {
		jQuery.ajax({
			url: url,

			// if "type" variable is undefined, then "GET" method will be used
			type: type,
			dataType: "html",
			data: params
		}).done(function( responseText ) {

			// Save response for use in complete callback
			response = arguments;

			self.html( selector ?

				// If a selector was specified, locate the right elements in a dummy div
				// Exclude scripts to avoid IE 'Permission Denied' errors
				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :

				// Otherwise use the full result
				responseText );

		}).complete( callback && function( jqXHR, status ) {
			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
		});
	}

	return this;
};




// Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
	jQuery.fn[ type ] = function( fn ) {
		return this.on( type, fn );
	};
});




jQuery.expr.filters.animated = function( elem ) {
	return jQuery.grep(jQuery.timers, function( fn ) {
		return elem === fn.elem;
	}).length;
};




var docElem = window.document.documentElement;

/**
 * Gets a window from an element
 */
function getWindow( elem ) {
	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}

jQuery.offset = {
	setOffset: function( elem, options, i ) {
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
			position = jQuery.css( elem, "position" ),
			curElem = jQuery( elem ),
			props = {};

		// Set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		curOffset = curElem.offset();
		curCSSTop = jQuery.css( elem, "top" );
		curCSSLeft = jQuery.css( elem, "left" );
		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
			( curCSSTop + curCSSLeft ).indexOf("auto") > -1;

		// Need to be able to calculate position if either
		// top or left is auto and position is either absolute or fixed
		if ( calculatePosition ) {
			curPosition = curElem.position();
			curTop = curPosition.top;
			curLeft = curPosition.left;

		} else {
			curTop = parseFloat( curCSSTop ) || 0;
			curLeft = parseFloat( curCSSLeft ) || 0;
		}

		if ( jQuery.isFunction( options ) ) {
			options = options.call( elem, i, curOffset );
		}

		if ( options.top != null ) {
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		if ( options.left != null ) {
			props.left = ( options.left - curOffset.left ) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );

		} else {
			curElem.css( props );
		}
	}
};

jQuery.fn.extend({
	offset: function( options ) {
		if ( arguments.length ) {
			return options === undefined ?
				this :
				this.each(function( i ) {
					jQuery.offset.setOffset( this, options, i );
				});
		}

		var docElem, win,
			elem = this[ 0 ],
			box = { top: 0, left: 0 },
			doc = elem && elem.ownerDocument;

		if ( !doc ) {
			return;
		}

		docElem = doc.documentElement;

		// Make sure it's not a disconnected DOM node
		if ( !jQuery.contains( docElem, elem ) ) {
			return box;
		}

		// Support: BlackBerry 5, iOS 3 (original iPhone)
		// If we don't have gBCR, just use 0,0 rather than error
		if ( typeof elem.getBoundingClientRect !== strundefined ) {
			box = elem.getBoundingClientRect();
		}
		win = getWindow( doc );
		return {
			top: box.top + win.pageYOffset - docElem.clientTop,
			left: box.left + win.pageXOffset - docElem.clientLeft
		};
	},

	position: function() {
		if ( !this[ 0 ] ) {
			return;
		}

		var offsetParent, offset,
			elem = this[ 0 ],
			parentOffset = { top: 0, left: 0 };

		// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
		if ( jQuery.css( elem, "position" ) === "fixed" ) {
			// Assume getBoundingClientRect is there when computed position is fixed
			offset = elem.getBoundingClientRect();

		} else {
			// Get *real* offsetParent
			offsetParent = this.offsetParent();

			// Get correct offsets
			offset = this.offset();
			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
				parentOffset = offsetParent.offset();
			}

			// Add offsetParent borders
			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
		}

		// Subtract parent offsets and element margins
		return {
			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
		};
	},

	offsetParent: function() {
		return this.map(function() {
			var offsetParent = this.offsetParent || docElem;

			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
				offsetParent = offsetParent.offsetParent;
			}

			return offsetParent || docElem;
		});
	}
});

// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
	var top = "pageYOffset" === prop;

	jQuery.fn[ method ] = function( val ) {
		return access( this, function( elem, method, val ) {
			var win = getWindow( elem );

			if ( val === undefined ) {
				return win ? win[ prop ] : elem[ method ];
			}

			if ( win ) {
				win.scrollTo(
					!top ? val : window.pageXOffset,
					top ? val : window.pageYOffset
				);

			} else {
				elem[ method ] = val;
			}
		}, method, val, arguments.length, null );
	};
});

// Support: Safari<7+, Chrome<37+
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) {
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
		function( elem, computed ) {
			if ( computed ) {
				computed = curCSS( elem, prop );
				// If curCSS returns percentage, fallback to offset
				return rnumnonpx.test( computed ) ?
					jQuery( elem ).position()[ prop ] + "px" :
					computed;
			}
		}
	);
});


// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
		// Margin is only for outerHeight, outerWidth
		jQuery.fn[ funcName ] = function( margin, value ) {
			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );

			return access( this, function( elem, type, value ) {
				var doc;

				if ( jQuery.isWindow( elem ) ) {
					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
					// isn't a whole lot we can do. See pull request at this URL for discussion:
					// https://github.com/jquery/jquery/pull/764
					return elem.document.documentElement[ "client" + name ];
				}

				// Get document width or height
				if ( elem.nodeType === 9 ) {
					doc = elem.documentElement;

					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
					// whichever is greatest
					return Math.max(
						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
						elem.body[ "offset" + name ], doc[ "offset" + name ],
						doc[ "client" + name ]
					);
				}

				return value === undefined ?
					// Get width or height on the element, requesting but not forcing parseFloat
					jQuery.css( elem, type, extra ) :

					// Set width or height on the element
					jQuery.style( elem, type, value, extra );
			}, type, chainable ? margin : undefined, chainable, null );
		};
	});
});


// The number of elements contained in the matched element set
jQuery.fn.size = function() {
	return this.length;
};

jQuery.fn.andSelf = jQuery.fn.addBack;




// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.

// Note that for maximum portability, libraries that are not jQuery should
// declare themselves as anonymous modules, and avoid setting a global if an
// AMD loader is present. jQuery is a special case. For more information, see
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

if ( typeof define === "function" && define.amd ) {
	define( "jquery", [], function() {
		return jQuery;
	});
}




var
	// Map over jQuery in case of overwrite
	_jQuery = window.jQuery,

	// Map over the $ in case of overwrite
	_$ = window.$;

jQuery.noConflict = function( deep ) {
	if ( window.$ === jQuery ) {
		window.$ = _$;
	}

	if ( deep && window.jQuery === jQuery ) {
		window.jQuery = _jQuery;
	}

	return jQuery;
};

// Expose jQuery and $ identifiers, even in AMD
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if ( typeof noGlobal === strundefined ) {
	window.jQuery = window.$ = jQuery;
}




return jQuery;

}));

/*! VelocityJS.org (1.0.0). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */

/*************************
   Velocity jQuery Shim
*************************/

/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */

/* This file contains the jQuery functions that Velocity relies on, thereby removing Velocity's dependency on a full copy of jQuery, and allowing it to work in any environment. */
/* These shimmed functions are only used if jQuery isn't present. If both this shim and jQuery are loaded, Velocity defaults to jQuery proper. */
/* Browser support: Using this shim instead of jQuery proper removes support for IE8. */

;(function (window) {
    /***************
         Setup
    ***************/

    /* If jQuery is already loaded, there's no point in loading this shim. */
    if (window.jQuery) {
        return;
    }

    /* jQuery base. */
    var $ = function (selector, context) {
        return new $.fn.init(selector, context);
    };

    /********************
       Private Methods
    ********************/

    /* jQuery */
    $.isWindow = function (obj) {
        /* jshint eqeqeq: false */
        return obj != null && obj == obj.window;
    };

    /* jQuery */
    $.type = function (obj) {
        if (obj == null) {
            return obj + "";
        }

        return typeof obj === "object" || typeof obj === "function" ?
            class2type[toString.call(obj)] || "object" :
            typeof obj;
    };

    /* jQuery */
    $.isArray = Array.isArray || function (obj) {
        return $.type(obj) === "array";
    };

    /* jQuery */
    function isArraylike (obj) {
        var length = obj.length,
            type = $.type(obj);

        if (type === "function" || $.isWindow(obj)) {
            return false;
        }

        if (obj.nodeType === 1 && length) {
            return true;
        }

        return type === "array" || length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj;
    }

    /***************
       $ Methods
    ***************/

    /* jQuery: Support removed for IE<9. */
    $.isPlainObject = function (obj) {
        var key;

        if (!obj || $.type(obj) !== "object" || obj.nodeType || $.isWindow(obj)) {
            return false;
        }

        try {
            if (obj.constructor &&
                !hasOwn.call(obj, "constructor") &&
                !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
                return false;
            }
        } catch (e) {
            return false;
        }

        for (key in obj) {}

        return key === undefined || hasOwn.call(obj, key);
    };

    /* jQuery */
    $.each = function(obj, callback, args) {
        var value,
            i = 0,
            length = obj.length,
            isArray = isArraylike(obj);

        if (args) {
            if (isArray) {
                for (; i < length; i++) {
                    value = callback.apply(obj[i], args);

                    if (value === false) {
                        break;
                    }
                }
            } else {
                for (i in obj) {
                    value = callback.apply(obj[i], args);

                    if (value === false) {
                        break;
                    }
                }
            }

        } else {
            if (isArray) {
                for (; i < length; i++) {
                    value = callback.call(obj[i], i, obj[i]);

                    if (value === false) {
                        break;
                    }
                }
            } else {
                for (i in obj) {
                    value = callback.call(obj[i], i, obj[i]);

                    if (value === false) {
                        break;
                    }
                }
            }
        }

        return obj;
    };

    /* Custom */
    $.data = function (node, key, value) {
        /* $.getData() */
        if (value === undefined) {
            var id = node[$.expando],
                store = id && cache[id];

            if (key === undefined) {
                return store;
            } else if (store) {
                if (key in store) {
                    return store[key];
                }
            }
        /* $.setData() */
        } else if (key !== undefined) {
            var id = node[$.expando] || (node[$.expando] = ++$.uuid);

            cache[id] = cache[id] || {};
            cache[id][key] = value;

            return value;
        }
    };

    /* Custom */
    $.removeData = function (node, keys) {
        var id = node[$.expando],
            store = id && cache[id];

        if (store) {
            $.each(keys, function(_, key) {
                delete store[key];
            });
        }
    };

    /* jQuery */
    $.extend = function () {
        var src, copyIsArray, copy, name, options, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;

        if (typeof target === "boolean") {
            deep = target;

            target = arguments[i] || {};
            i++;
        }

        if (typeof target !== "object" && $.type(target) !== "function") {
            target = {};
        }

        if (i === length) {
            target = this;
            i--;
        }

        for (; i < length; i++) {
            if ((options = arguments[i]) != null) {
                for (name in options) {
                    src = target[name];
                    copy = options[name];

                    if (target === copy) {
                        continue;
                    }

                    if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
                        if (copyIsArray) {
                            copyIsArray = false;
                            clone = src && $.isArray(src) ? src : [];

                        } else {
                            clone = src && $.isPlainObject(src) ? src : {};
                        }

                        target[name] = $.extend(deep, clone, copy);

                    } else if (copy !== undefined) {
                        target[name] = copy;
                    }
                }
            }
        }

        return target;
    };

    /* jQuery 1.4.3 */
    $.queue = function (elem, type, data) {
        function $makeArray (arr, results) {
            var ret = results || [];

            if (arr != null) {
                if (isArraylike(Object(arr))) {
                    /* $.merge */
                    (function(first, second) {
                        var len = +second.length,
                            j = 0,
                            i = first.length;

                        while (j < len) {
                            first[i++] = second[j++];
                        }

                        if (len !== len) {
                            while (second[j] !== undefined) {
                                first[i++] = second[j++];
                            }
                        }

                        first.length = i;

                        return first;
                    })(ret, typeof arr === "string" ? [arr] : arr);
                } else {
                    [].push.call(ret, arr);
                }
            }

            return ret;
        }

        if (!elem) {
            return;
        }

        type = (type || "fx") + "queue";

        var q = $.data(elem, type);

        if (!data) {
            return q || [];
        }

        if (!q || $.isArray(data)) {
            q = $.data(elem, type, $makeArray(data));
        } else {
            q.push(data);
        }

        return q;
    };

    /* jQuery 1.4.3 */
    $.dequeue = function (elems, type) {
        /* Custom: Embed element iteration. */
        $.each(elems.nodeType ? [ elems ] : elems, function(i, elem) {
            type = type || "fx";

            var queue = $.queue(elem, type),
                fn = queue.shift();

            if (fn === "inprogress") {
                fn = queue.shift();
            }

            if (fn) {
                if (type === "fx") {
                    queue.unshift("inprogress");
                }

                fn.call(elem, function() {
                    $.dequeue(elem, type);
                });
            }
        });
    };

    /******************
       $.fn Methods
    ******************/

    /* jQuery */
    $.fn = $.prototype = {
        init: function (selector) {
            /* Just return the element wrapped inside an array; don't proceed with the actual jQuery node wrapping process. */
            if (selector.nodeType) {
                this[0] = selector;

                return this;
            } else {
                throw new Error("Not a DOM node.");
            }
        },

        offset: function () {
            /* jQuery altered code: Dropped disconnected DOM node checking. */
            var box = this[0].getBoundingClientRect ? this[0].getBoundingClientRect() : { top: 0, left: 0 };

            return {
                top: box.top + (window.pageYOffset || document.scrollTop  || 0)  - (document.clientTop  || 0),
                left: box.left + (window.pageXOffset || document.scrollLeft  || 0) - (document.clientLeft || 0)
            };
        },

        position: function () {
            /* jQuery */
            function offsetParent() {
                var offsetParent = this.offsetParent || document;

                while (offsetParent && (!offsetParent.nodeType.toLowerCase === "html" && offsetParent.style.position === "static")) {
                    offsetParent = offsetParent.offsetParent;
                }

                return offsetParent || document;
            }

            /* Zepto */
            var elem = this[0],
                offsetParent = offsetParent.apply(elem),
                offset = this.offset(),
                parentOffset = /^(?:body|html)$/i.test(offsetParent.nodeName) ? { top: 0, left: 0 } : $(offsetParent).offset()

            offset.top -= parseFloat(elem.style.marginTop) || 0;
            offset.left -= parseFloat(elem.style.marginLeft) || 0;

            if (offsetParent.style) {
                parentOffset.top += parseFloat(offsetParent.style.borderTopWidth) || 0
                parentOffset.left += parseFloat(offsetParent.style.borderLeftWidth) || 0
            }

            return {
                top: offset.top - parentOffset.top,
                left: offset.left - parentOffset.left
            };
        }
    };

    /**********************
       Private Variables
    **********************/

    /* For $.data() */
    var cache = {};
    $.expando = "velocity" + (new Date().getTime());
    $.uuid = 0;

    /* For $.queue() */
    var class2type = {},
        hasOwn = class2type.hasOwnProperty,
        toString = class2type.toString;

    var types = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
    for (var i = 0; i < types.length; i++) {
        class2type["[object " + types[i] + "]"] = types[i].toLowerCase();
    }

    /* Makes $(node) possible, without having to call init. */
    $.fn.init.prototype = $.fn;

    /* Globalize Velocity onto the window, and assign its Utilities property. */
    window.Velocity = { Utilities: $ };
})(window);

/******************
    Velocity.js
******************/

;(function (factory) {
    /* CommonJS module. */
    if (typeof module === "object" && typeof module.exports === "object") {
        module.exports = factory();
    /* AMD module. */
    } else if (typeof define === "function" && define.amd) {
        define(factory);
    /* Browser globals. */
    } else {
        factory();
    }
}(function() {
return function (global, window, document, undefined) {

    /***************
        Summary
    ***************/

    /*
    - CSS: CSS stack that works independently from the rest of Velocity.
    - animate(): Core animation method that iterates over the targeted elements and queues the incoming call onto each element individually.
      - Pre-Queueing: Prepare the element for animation by instantiating its data cache and processing the call's options.
      - Queueing: The logic that runs once the call has reached its point of execution in the element's $.queue() stack.
                  Most logic is placed here to avoid risking it becoming stale (if the element's properties have changed).
      - Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.
    - tick(): The single requestAnimationFrame loop responsible for tweening all in-progress calls.
    - completeCall(): Handles the cleanup process for each Velocity call.
    */

    /*********************
       Helper Functions
    *********************/

    /* IE detection. Gist: https://gist.github.com/julianshapiro/9098609 */
    var IE = (function() {
        if (document.documentMode) {
            return document.documentMode;
        } else {
            for (var i = 7; i > 4; i--) {
                var div = document.createElement("div");

                div.innerHTML = "<!--[if IE " + i + "]><span></span><![endif]-->";

                if (div.getElementsByTagName("span").length) {
                    div = null;

                    return i;
                }
            }
        }

        return undefined;
    })();

    /* rAF shim. Gist: https://gist.github.com/julianshapiro/9497513 */
    var rAFShim = (function() {
        var timeLast = 0;

        return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
            var timeCurrent = (new Date()).getTime(),
                timeDelta;

            /* Dynamically set delay on a per-tick basis to match 60fps. */
            /* Technique by Erik Moller. MIT license: https://gist.github.com/paulirish/1579671 */
            timeDelta = Math.max(0, 16 - (timeCurrent - timeLast));
            timeLast = timeCurrent + timeDelta;

            return setTimeout(function() { callback(timeCurrent + timeDelta); }, timeDelta);
        };
    })();

    /* Array compacting. Copyright Lo-Dash. MIT License: https://github.com/lodash/lodash/blob/master/LICENSE.txt */
    function compactSparseArray (array) {
        var index = -1,
            length = array ? array.length : 0,
            result = [];

        while (++index < length) {
            var value = array[index];

            if (value) {
                result.push(value);
            }
        }

        return result;
    }

    function sanitizeElements (elements) {
        /* Unwrap jQuery/Zepto objects. */
        if (Type.isWrapped(elements)) {
            elements = [].slice.call(elements);
        /* Wrap a single element in an array so that $.each() can iterate with the element instead of its node's children. */
        } else if (Type.isNode(elements)) {
            elements = [ elements ];
        }

        return elements;
    }

    var Type = {
        isString: function (variable) {
            return (typeof variable === "string");
        },
        isArray: Array.isArray || function (variable) {
            return Object.prototype.toString.call(variable) === "[object Array]";
        },
        isFunction: function (variable) {
            return Object.prototype.toString.call(variable) === "[object Function]";
        },
        isNode: function (variable) {
            return variable && variable.nodeType;
        },
        /* Copyright Martin Bohm. MIT License: https://gist.github.com/Tomalak/818a78a226a0738eaade */
        isNodeList: function (variable) {
            return typeof variable === "object" &&
                /^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(variable)) &&
                variable.length !== undefined &&
                (variable.length === 0 || (typeof variable[0] === "object" && variable[0].nodeType > 0));
        },
        /* Determine if variable is a wrapped jQuery or Zepto element. */
        isWrapped: function (variable) {
            return variable && (variable.jquery || (window.Zepto && window.Zepto.zepto.isZ(variable)));
        },
        isSVG: function (variable) {
            return window.SVGElement && (variable instanceof window.SVGElement);
        },
        isEmptyObject: function (variable) {
            for (var name in variable) {
                return false;
            }

            return true;
        }
    };

    /*****************
       Dependencies
    *****************/

    var $,
        isJQuery = false;

    if (global.fn && global.fn.jquery) {
        $ = global;
        isJQuery = true;
    } else {
        $ = window.Velocity.Utilities;
    }

    if (IE <= 8 && !isJQuery) {
        throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");
    } else if (IE <= 7) {
        /* Revert to jQuery's $.animate(), and lose Velocity's extra features. */
        jQuery.fn.velocity = jQuery.fn.animate;

        /* Now that $.fn.velocity is aliased, abort this Velocity declaration. */
        return;
    }

    /*****************
        Constants
    *****************/

    var DURATION_DEFAULT = 400,
        EASING_DEFAULT = "swing";

    /*************
        State
    *************/

    /* Note: The global object also doubles as a publicly-accessible data store for the purposes of unit testing. */
    /* Note: Alias the lowercase and uppercase variants of "velocity" to minimize user confusion due to the lowercase nature of the $.fn extension. */
    var Velocity = {
        /* Container for page-wide Velocity state data. */
        State: {
            /* Detect mobile devices to determine if mobileHA should be turned on. */
            isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
            /* The mobileHA option's behavior changes on older Android devices (Gingerbread, versions 2.3.3-2.3.7). */
            isAndroid: /Android/i.test(navigator.userAgent),
            isGingerbread: /Android 2\.3\.[3-7]/i.test(navigator.userAgent),
            isChrome: window.chrome,
            isFirefox: /Firefox/i.test(navigator.userAgent),
            /* Create a cached element for re-use when checking for CSS property prefixes. */
            prefixElement: document.createElement("div"),
            /* Cache every prefix match to avoid repeating lookups. */
            prefixMatches: {},
            /* Cache the anchor used for animating window scrolling. */
            scrollAnchor: null,
            /* Cache the property names associated with the scroll anchor. */
            scrollPropertyLeft: null,
            scrollPropertyTop: null,
            /* Keep track of whether our RAF tick is running. */
            isTicking: false,
            /* Container for every in-progress call to Velocity. */
            calls: []
        },
        /* Velocity's custom CSS stack. Made global for unit testing. */
        CSS: { /* Defined below. */ },
        /* Defined by Velocity's optional jQuery shim. */
        Utilities: $,
        /* Container for the user's custom animation redirects that are referenced by name in place of a properties map object. */
        Redirects: { /* Manually registered by the user. */ },
        Easings: { /* Defined below. */ },
        /* Attempt to use ES6 Promises by default. Users can override this with a third-party promises library. */
        Promise: window.Promise,
        /* Page-wide option defaults, which can be overriden by the user. */
        defaults: {
            queue: "",
            duration: DURATION_DEFAULT,
            easing: EASING_DEFAULT,
            begin: undefined,
            complete: undefined,
            progress: undefined,
            display: undefined,
            visibility: undefined,
            loop: false,
            delay: false,
            mobileHA: true,
            /* Set to false to prevent property values from being cached between consecutive Velocity-initiated chain calls. */
            _cacheValues: true
        },
        /* A design goal of Velocity is to cache data wherever possible in order to avoid DOM requerying.
           Accordingly, each element has a data cache instantiated on it. */
        init: function (element) {
            $.data(element, "velocity", {
                /* Store whether this is an SVG element, since its properties are retrieved and updated differently than standard HTML elements. */
                isSVG: Type.isSVG(element),
                /* Keep track of whether the element is currently being animated by Velocity.
                   This is used to ensure that property values are not transferred between non-consecutive (stale) calls. */
                isAnimating: false,
                /* A reference to the element's live computedStyle object. Learn more here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */
                computedStyle: null,
                /* Tween data is cached for each animation on the element so that data can be passed across calls --
                   in particular, end values are used as subsequent start values in consecutive Velocity calls. */
                tweensContainer: null,
                /* The full root property values of each CSS hook being animated on this element are cached so that:
                   1) Concurrently-animating hooks sharing the same root can have their root values' merged into one while tweening.
                   2) Post-hook-injection root values can be transferred over to consecutively chained Velocity calls as starting root values. */
                rootPropertyValueCache: {},
                /* A cache for transform updates, which must be manually flushed via CSS.flushTransformCache(). */
                transformCache: {}
            });
        },
        /* A parallel to jQuery's $.css(), used for getting/setting Velocity's hooked CSS properties. */
        hook: null, /* Defined below. */
        /* Velocity-wide animation time remapping for testing purposes. */
        mock: false,
        version: { major: 1, minor: 1, patch: 0 },
        /* Set to 1 or 2 (most verbose) to output debug info to console. */
        debug: false
    };

    /* Retrieve the appropriate scroll anchor and property name for the browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY */
    if (window.pageYOffset !== undefined) {
        Velocity.State.scrollAnchor = window;
        Velocity.State.scrollPropertyLeft = "pageXOffset";
        Velocity.State.scrollPropertyTop = "pageYOffset";
    } else {
        Velocity.State.scrollAnchor = document.documentElement || document.body.parentNode || document.body;
        Velocity.State.scrollPropertyLeft = "scrollLeft";
        Velocity.State.scrollPropertyTop = "scrollTop";
    }

    /* Shorthand alias for jQuery's $.data() utility. */
    function Data (element) {
        /* Hardcode a reference to the plugin name. */
        var response = $.data(element, "velocity");

        /* jQuery <=1.4.2 returns null instead of undefined when no match is found. We normalize this behavior. */
        return response === null ? undefined : response;
    };

    /**************
        Easing
    **************/

    /* Step easing generator. */
    function generateStep (steps) {
        return function (p) {
            return Math.round(p * steps) * (1 / steps);
        };
    }

    /* Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */
    function generateBezier (mX1, mY1, mX2, mY2) {
        var NEWTON_ITERATIONS = 4,
            NEWTON_MIN_SLOPE = 0.001,
            SUBDIVISION_PRECISION = 0.0000001,
            SUBDIVISION_MAX_ITERATIONS = 10,
            kSplineTableSize = 11,
            kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),
            float32ArraySupported = "Float32Array" in window;

        /* Must contain four arguments. */
        if (arguments.length !== 4) {
            return false;
        }

        /* Arguments must be numbers. */
        for (var i = 0; i < 4; ++i) {
            if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) {
                return false;
            }
        }

        /* X values must be in the [0, 1] range. */
        mX1 = Math.min(mX1, 1);
        mX2 = Math.min(mX2, 1);
        mX1 = Math.max(mX1, 0);
        mX2 = Math.max(mX2, 0);

        var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);

        function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
        function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
        function C (aA1)      { return 3.0 * aA1; }

        function calcBezier (aT, aA1, aA2) {
            return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;
        }

        function getSlope (aT, aA1, aA2) {
            return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
        }

        function newtonRaphsonIterate (aX, aGuessT) {
            for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
                var currentSlope = getSlope(aGuessT, mX1, mX2);

                if (currentSlope === 0.0) return aGuessT;

                var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
                aGuessT -= currentX / currentSlope;
            }

            return aGuessT;
        }

        function calcSampleValues () {
            for (var i = 0; i < kSplineTableSize; ++i) {
                mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
            }
        }

        function binarySubdivide (aX, aA, aB) {
            var currentX, currentT, i = 0;

            do {
                currentT = aA + (aB - aA) / 2.0;
                currentX = calcBezier(currentT, mX1, mX2) - aX;
                if (currentX > 0.0) {
                  aB = currentT;
                } else {
                  aA = currentT;
                }
            } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);

            return currentT;
        }

        function getTForX (aX) {
            var intervalStart = 0.0,
                currentSample = 1,
                lastSample = kSplineTableSize - 1;

            for (; currentSample != lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
                intervalStart += kSampleStepSize;
            }

            --currentSample;

            var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]),
                guessForT = intervalStart + dist * kSampleStepSize,
                initialSlope = getSlope(guessForT, mX1, mX2);

            if (initialSlope >= NEWTON_MIN_SLOPE) {
                return newtonRaphsonIterate(aX, guessForT);
            } else if (initialSlope == 0.0) {
                return guessForT;
            } else {
                return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);
            }
        }

        var _precomputed = false;

        function precompute() {
            _precomputed = true;
            if (mX1 != mY1 || mX2 != mY2) calcSampleValues();
        }

        var f = function (aX) {
            if (!_precomputed) precompute();
            if (mX1 === mY1 && mX2 === mY2) return aX;
            if (aX === 0) return 0;
            if (aX === 1) return 1;

            return calcBezier(getTForX(aX), mY1, mY2);
        };

        f.getControlPoints = function() { return [{ x: mX1, y: mY1 }, { x: mX2, y: mY2 }]; };

        var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")";
        f.toString = function () { return str; };

        return f;
    }

    /* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */
    /* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass
       then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */
    var generateSpringRK4 = (function () {
        function springAccelerationForState (state) {
            return (-state.tension * state.x) - (state.friction * state.v);
        }

        function springEvaluateStateWithDerivative (initialState, dt, derivative) {
            var state = {
                x: initialState.x + derivative.dx * dt,
                v: initialState.v + derivative.dv * dt,
                tension: initialState.tension,
                friction: initialState.friction
            };

            return { dx: state.v, dv: springAccelerationForState(state) };
        }

        function springIntegrateState (state, dt) {
            var a = {
                    dx: state.v,
                    dv: springAccelerationForState(state)
                },
                b = springEvaluateStateWithDerivative(state, dt * 0.5, a),
                c = springEvaluateStateWithDerivative(state, dt * 0.5, b),
                d = springEvaluateStateWithDerivative(state, dt, c),
                dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),
                dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);

            state.x = state.x + dxdt * dt;
            state.v = state.v + dvdt * dt;

            return state;
        }

        return function springRK4Factory (tension, friction, duration) {

            var initState = {
                    x: -1,
                    v: 0,
                    tension: null,
                    friction: null
                },
                path = [0],
                time_lapsed = 0,
                tolerance = 1 / 10000,
                DT = 16 / 1000,
                have_duration, dt, last_state;

            tension = parseFloat(tension) || 500;
            friction = parseFloat(friction) || 20;
            duration = duration || null;

            initState.tension = tension;
            initState.friction = friction;

            have_duration = duration !== null;

            /* Calculate the actual time it takes for this animation to complete with the provided conditions. */
            if (have_duration) {
                /* Run the simulation without a duration. */
                time_lapsed = springRK4Factory(tension, friction);
                /* Compute the adjusted time delta. */
                dt = time_lapsed / duration * DT;
            } else {
                dt = DT;
            }

            while (true) {
                /* Next/step function .*/
                last_state = springIntegrateState(last_state || initState, dt);
                /* Store the position. */
                path.push(1 + last_state.x);
                time_lapsed += 16;
                /* If the change threshold is reached, break. */
                if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {
                    break;
                }
            }

            /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the
               computed path and returns a snapshot of the position according to a given percentComplete. */
            return !have_duration ? time_lapsed : function(percentComplete) { return path[ (percentComplete * (path.length - 1)) | 0 ]; };
        };
    }());

    /* jQuery easings. */
    Velocity.Easings = {
        linear: function(p) { return p; },
        swing: function(p) { return 0.5 - Math.cos( p * Math.PI ) / 2 },
        /* Bonus "spring" easing, which is a less exaggerated version of easeInOutElastic. */
        spring: function(p) { return 1 - (Math.cos(p * 4.5 * Math.PI) * Math.exp(-p * 6)); }
    };

    /* CSS3 and Robert Penner easings. */
    $.each(
        [
            [ "ease", [ 0.25, 0.1, 0.25, 1.0 ] ],
            [ "ease-in", [ 0.42, 0.0, 1.00, 1.0 ] ],
            [ "ease-out", [ 0.00, 0.0, 0.58, 1.0 ] ],
            [ "ease-in-out", [ 0.42, 0.0, 0.58, 1.0 ] ],
            [ "easeInSine", [ 0.47, 0, 0.745, 0.715 ] ],
            [ "easeOutSine", [ 0.39, 0.575, 0.565, 1 ] ],
            [ "easeInOutSine", [ 0.445, 0.05, 0.55, 0.95 ] ],
            [ "easeInQuad", [ 0.55, 0.085, 0.68, 0.53 ] ],
            [ "easeOutQuad", [ 0.25, 0.46, 0.45, 0.94 ] ],
            [ "easeInOutQuad", [ 0.455, 0.03, 0.515, 0.955 ] ],
            [ "easeInCubic", [ 0.55, 0.055, 0.675, 0.19 ] ],
            [ "easeOutCubic", [ 0.215, 0.61, 0.355, 1 ] ],
            [ "easeInOutCubic", [ 0.645, 0.045, 0.355, 1 ] ],
            [ "easeInQuart", [ 0.895, 0.03, 0.685, 0.22 ] ],
            [ "easeOutQuart", [ 0.165, 0.84, 0.44, 1 ] ],
            [ "easeInOutQuart", [ 0.77, 0, 0.175, 1 ] ],
            [ "easeInQuint", [ 0.755, 0.05, 0.855, 0.06 ] ],
            [ "easeOutQuint", [ 0.23, 1, 0.32, 1 ] ],
            [ "easeInOutQuint", [ 0.86, 0, 0.07, 1 ] ],
            [ "easeInExpo", [ 0.95, 0.05, 0.795, 0.035 ] ],
            [ "easeOutExpo", [ 0.19, 1, 0.22, 1 ] ],
            [ "easeInOutExpo", [ 1, 0, 0, 1 ] ],
            [ "easeInCirc", [ 0.6, 0.04, 0.98, 0.335 ] ],
            [ "easeOutCirc", [ 0.075, 0.82, 0.165, 1 ] ],
            [ "easeInOutCirc", [ 0.785, 0.135, 0.15, 0.86 ] ]
        ], function(i, easingArray) {
            Velocity.Easings[easingArray[0]] = generateBezier.apply(null, easingArray[1]);
        });

    /* Determine the appropriate easing type given an easing input. */
    function getEasing(value, duration) {
        var easing = value;

        /* The easing option can either be a string that references a pre-registered easing,
           or it can be a two-/four-item array of integers to be converted into a bezier/spring function. */
        if (Type.isString(value)) {
            /* Ensure that the easing has been assigned to jQuery's Velocity.Easings object. */
            if (!Velocity.Easings[value]) {
                easing = false;
            }
        } else if (Type.isArray(value) && value.length === 1) {
            easing = generateStep.apply(null, value);
        } else if (Type.isArray(value) && value.length === 2) {
            /* springRK4 must be passed the animation's duration. */
            /* Note: If the springRK4 array contains non-numbers, generateSpringRK4() returns an easing
               function generated with default tension and friction values. */
            easing = generateSpringRK4.apply(null, value.concat([ duration ]));
        } else if (Type.isArray(value) && value.length === 4) {
            /* Note: If the bezier array contains non-numbers, generateBezier() returns false. */
            easing = generateBezier.apply(null, value);
        } else {
            easing = false;
        }

        /* Revert to the Velocity-wide default easing type, or fall back to "swing" (which is also jQuery's default)
           if the Velocity-wide default has been incorrectly modified. */
        if (easing === false) {
            if (Velocity.Easings[Velocity.defaults.easing]) {
                easing = Velocity.defaults.easing;
            } else {
                easing = EASING_DEFAULT;
            }
        }

        return easing;
    }

    /*****************
        CSS Stack
    *****************/

    /* The CSS object is a highly condensed and performant CSS stack that fully replaces jQuery's.
       It handles the validation, getting, and setting of both standard CSS properties and CSS property hooks. */
    /* Note: A "CSS" shorthand is aliased so that our code is easier to read. */
    var CSS = Velocity.CSS = {

        /*************
            RegEx
        *************/

        RegEx: {
            isHex: /^#([A-f\d]{3}){1,2}$/i,
            /* Unwrap a property value's surrounding text, e.g. "rgba(4, 3, 2, 1)" ==> "4, 3, 2, 1" and "rect(4px 3px 2px 1px)" ==> "4px 3px 2px 1px". */
            valueUnwrap: /^[A-z]+\((.*)\)$/i,
            wrappedValueAlreadyExtracted: /[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,
            /* Split a multi-value property into an array of subvalues, e.g. "rgba(4, 3, 2, 1) 4px 3px 2px 1px" ==> [ "rgba(4, 3, 2, 1)", "4px", "3px", "2px", "1px" ]. */
            valueSplit: /([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/ig
        },

        /************
            Lists
        ************/

        Lists: {
            colors: [ "fill", "stroke", "stopColor", "color", "backgroundColor", "borderColor", "borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor", "outlineColor" ],
            transformsBase: [ "translateX", "translateY", "scale", "scaleX", "scaleY", "skewX", "skewY", "rotateZ" ],
            transforms3D: [ "transformPerspective", "translateZ", "scaleZ", "rotateX", "rotateY" ]
        },

        /************
            Hooks
        ************/

        /* Hooks allow a subproperty (e.g. "boxShadowBlur") of a compound-value CSS property
           (e.g. "boxShadow: X Y Blur Spread Color") to be animated as if it were a discrete property. */
        /* Note: Beyond enabling fine-grained property animation, hooking is necessary since Velocity only
           tweens properties with single numeric values; unlike CSS transitions, Velocity does not interpolate compound-values. */
        Hooks: {
            /********************
                Registration
            ********************/

            /* Templates are a concise way of indicating which subproperties must be individually registered for each compound-value CSS property. */
            /* Each template consists of the compound-value's base name, its constituent subproperty names, and those subproperties' default values. */
            templates: {
                "textShadow": [ "Color X Y Blur", "black 0px 0px 0px" ],
                /* Todo: Add support for inset boxShadows. (webkit places it last whereas IE places it first.) */
                "boxShadow": [ "Color X Y Blur Spread", "black 0px 0px 0px 0px" ],
                "clip": [ "Top Right Bottom Left", "0px 0px 0px 0px" ],
                "backgroundPosition": [ "X Y", "0% 0%" ],
                "transformOrigin": [ "X Y Z", "50% 50% 0px" ],
                "perspectiveOrigin": [ "X Y", "50% 50%" ]
            },

            /* A "registered" hook is one that has been converted from its template form into a live,
               tweenable property. It contains data to associate it with its root property. */
            registered: {
                /* Note: A registered hook looks like this ==> textShadowBlur: [ "textShadow", 3 ],
                   which consists of the subproperty's name, the associated root property's name,
                   and the subproperty's position in the root's value. */
            },
            /* Convert the templates into individual hooks then append them to the registered object above. */
            register: function () {
                /* Color hooks registration: Colors are defaulted to white -- as opposed to black -- since colors that are
                   currently set to "transparent" default to their respective template below when color-animated,
                   and white is typically a closer match to transparent than black is. An exception is made for text ("color"),
                   which is almost always set closer to black than white. */
                for (var i = 0; i < CSS.Lists.colors.length; i++) {
                    var rgbComponents = (CSS.Lists.colors[i] === "color") ? "0 0 0 1" : "255 255 255 1";
                    CSS.Hooks.templates[CSS.Lists.colors[i]] = [ "Red Green Blue Alpha", rgbComponents ];
                }

                var rootProperty,
                    hookTemplate,
                    hookNames;

                /* In IE, color values inside compound-value properties are positioned at the end the value instead of at the beginning.
                   Thus, we re-arrange the templates accordingly. */
                if (IE) {
                    for (rootProperty in CSS.Hooks.templates) {
                        hookTemplate = CSS.Hooks.templates[rootProperty];
                        hookNames = hookTemplate[0].split(" ");

                        var defaultValues = hookTemplate[1].match(CSS.RegEx.valueSplit);

                        if (hookNames[0] === "Color") {
                            /* Reposition both the hook's name and its default value to the end of their respective strings. */
                            hookNames.push(hookNames.shift());
                            defaultValues.push(defaultValues.shift());

                            /* Replace the existing template for the hook's root property. */
                            CSS.Hooks.templates[rootProperty] = [ hookNames.join(" "), defaultValues.join(" ") ];
                        }
                    }
                }

                /* Hook registration. */
                for (rootProperty in CSS.Hooks.templates) {
                    hookTemplate = CSS.Hooks.templates[rootProperty];
                    hookNames = hookTemplate[0].split(" ");

                    for (var i in hookNames) {
                        var fullHookName = rootProperty + hookNames[i],
                            hookPosition = i;

                        /* For each hook, register its full name (e.g. textShadowBlur) with its root property (e.g. textShadow)
                           and the hook's position in its template's default value string. */
                        CSS.Hooks.registered[fullHookName] = [ rootProperty, hookPosition ];
                    }
                }
            },

            /*****************************
               Injection and Extraction
            *****************************/

            /* Look up the root property associated with the hook (e.g. return "textShadow" for "textShadowBlur"). */
            /* Since a hook cannot be set directly (the browser won't recognize it), style updating for hooks is routed through the hook's root property. */
            getRoot: function (property) {
                var hookData = CSS.Hooks.registered[property];

                if (hookData) {
                    return hookData[0];
                } else {
                    /* If there was no hook match, return the property name untouched. */
                    return property;
                }
            },
            /* Convert any rootPropertyValue, null or otherwise, into a space-delimited list of hook values so that
               the targeted hook can be injected or extracted at its standard position. */
            cleanRootPropertyValue: function(rootProperty, rootPropertyValue) {
                /* If the rootPropertyValue is wrapped with "rgb()", "clip()", etc., remove the wrapping to normalize the value before manipulation. */
                if (CSS.RegEx.valueUnwrap.test(rootPropertyValue)) {
                    rootPropertyValue = rootPropertyValue.match(CSS.RegEx.valueUnwrap)[1];
                }

                /* If rootPropertyValue is a CSS null-value (from which there's inherently no hook value to extract),
                   default to the root's default value as defined in CSS.Hooks.templates. */
                /* Note: CSS null-values include "none", "auto", and "transparent". They must be converted into their
                   zero-values (e.g. textShadow: "none" ==> textShadow: "0px 0px 0px black") for hook manipulation to proceed. */
                if (CSS.Values.isCSSNullValue(rootPropertyValue)) {
                    rootPropertyValue = CSS.Hooks.templates[rootProperty][1];
                }

                return rootPropertyValue;
            },
            /* Extracted the hook's value from its root property's value. This is used to get the starting value of an animating hook. */
            extractValue: function (fullHookName, rootPropertyValue) {
                var hookData = CSS.Hooks.registered[fullHookName];

                if (hookData) {
                    var hookRoot = hookData[0],
                        hookPosition = hookData[1];

                    rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);

                    /* Split rootPropertyValue into its constituent hook values then grab the desired hook at its standard position. */
                    return rootPropertyValue.toString().match(CSS.RegEx.valueSplit)[hookPosition];
                } else {
                    /* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */
                    return rootPropertyValue;
                }
            },
            /* Inject the hook's value into its root property's value. This is used to piece back together the root property
               once Velocity has updated one of its individually hooked values through tweening. */
            injectValue: function (fullHookName, hookValue, rootPropertyValue) {
                var hookData = CSS.Hooks.registered[fullHookName];

                if (hookData) {
                    var hookRoot = hookData[0],
                        hookPosition = hookData[1],
                        rootPropertyValueParts,
                        rootPropertyValueUpdated;

                    rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);

                    /* Split rootPropertyValue into its individual hook values, replace the targeted value with hookValue,
                       then reconstruct the rootPropertyValue string. */
                    rootPropertyValueParts = rootPropertyValue.toString().match(CSS.RegEx.valueSplit);
                    rootPropertyValueParts[hookPosition] = hookValue;
                    rootPropertyValueUpdated = rootPropertyValueParts.join(" ");

                    return rootPropertyValueUpdated;
                } else {
                    /* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */
                    return rootPropertyValue;
                }
            }
        },

        /*******************
           Normalizations
        *******************/

        /* Normalizations standardize CSS property manipulation by pollyfilling browser-specific implementations (e.g. opacity)
           and reformatting special properties (e.g. clip, rgba) to look like standard ones. */
        Normalizations: {
            /* Normalizations are passed a normalization target (either the property's name, its extracted value, or its injected value),
               the targeted element (which may need to be queried), and the targeted property value. */
            registered: {
                clip: function (type, element, propertyValue) {
                    switch (type) {
                        case "name":
                            return "clip";
                        /* Clip needs to be unwrapped and stripped of its commas during extraction. */
                        case "extract":
                            var extracted;

                            /* If Velocity also extracted this value, skip extraction. */
                            if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {
                                extracted = propertyValue;
                            } else {
                                /* Remove the "rect()" wrapper. */
                                extracted = propertyValue.toString().match(CSS.RegEx.valueUnwrap);

                                /* Strip off commas. */
                                extracted = extracted ? extracted[1].replace(/,(\s+)?/g, " ") : propertyValue;
                            }

                            return extracted;
                        /* Clip needs to be re-wrapped during injection. */
                        case "inject":
                            return "rect(" + propertyValue + ")";
                    }
                },

                blur: function(type, element, propertyValue) {
                    switch (type) {
                        case "name":
                            return "-webkit-filter";
                        case "extract":
                            var extracted = parseFloat(propertyValue);

                            /* If extracted is NaN, meaning the value isn't already extracted. */
                            if (!(extracted || extracted === 0)) {
                                var blurComponent = propertyValue.toString().match(/blur\(([0-9]+[A-z]+)\)/i);

                                /* If the filter string had a blur component, return just the blur value and unit type. */
                                if (blurComponent) {
                                    extracted = blurComponent[1];
                                /* If the component doesn't exist, default blur to 0. */
                                } else {
                                    extracted = 0;
                                }
                            }

                            return extracted;
                        /* Blur needs to be re-wrapped during injection. */
                        case "inject":
                            /* For the blur effect to be fully de-applied, it needs to be set to "none" instead of 0. */
                            if (!parseFloat(propertyValue)) {
                                return "none";
                            } else {
                                return "blur(" + propertyValue + ")";
                            }
                    }
                },

                /* <=IE8 do not support the standard opacity property. They use filter:alpha(opacity=INT) instead. */
                opacity: function (type, element, propertyValue) {
                    if (IE <= 8) {
                        switch (type) {
                            case "name":
                                return "filter";
                            case "extract":
                                /* <=IE8 return a "filter" value of "alpha(opacity=\d{1,3})".
                                   Extract the value and convert it to a decimal value to match the standard CSS opacity property's formatting. */
                                var extracted = propertyValue.toString().match(/alpha\(opacity=(.*)\)/i);

                                if (extracted) {
                                    /* Convert to decimal value. */
                                    propertyValue = extracted[1] / 100;
                                } else {
                                    /* When extracting opacity, default to 1 since a null value means opacity hasn't been set. */
                                    propertyValue = 1;
                                }

                                return propertyValue;
                            case "inject":
                                /* Opacified elements are required to have their zoom property set to a non-zero value. */
                                element.style.zoom = 1;

                                /* Setting the filter property on elements with certain font property combinations can result in a
                                   highly unappealing ultra-bolding effect. There's no way to remedy this throughout a tween, but dropping the
                                   value altogether (when opacity hits 1) at leasts ensures that the glitch is gone post-tweening. */
                                if (parseFloat(propertyValue) >= 1) {
                                    return "";
                                } else {
                                  /* As per the filter property's spec, convert the decimal value to a whole number and wrap the value. */
                                  return "alpha(opacity=" + parseInt(parseFloat(propertyValue) * 100, 10) + ")";
                                }
                        }
                    /* With all other browsers, normalization is not required; return the same values that were passed in. */
                    } else {
                        switch (type) {
                            case "name":
                                return "opacity";
                            case "extract":
                                return propertyValue;
                            case "inject":
                                return propertyValue;
                        }
                    }
                }
            },

            /*****************************
                Batched Registrations
            *****************************/

            /* Note: Batched normalizations extend the CSS.Normalizations.registered object. */
            register: function () {

                /*****************
                    Transforms
                *****************/

                /* Transforms are the subproperties contained by the CSS "transform" property. Transforms must undergo normalization
                   so that they can be referenced in a properties map by their individual names. */
                /* Note: When transforms are "set", they are actually assigned to a per-element transformCache. When all transform
                   setting is complete complete, CSS.flushTransformCache() must be manually called to flush the values to the DOM.
                   Transform setting is batched in this way to improve performance: the transform style only needs to be updated
                   once when multiple transform subproperties are being animated simultaneously. */
                /* Note: IE9 and Android Gingerbread have support for 2D -- but not 3D -- transforms. Since animating unsupported
                   transform properties results in the browser ignoring the *entire* transform string, we prevent these 3D values
                   from being normalized for these browsers so that tweening skips these properties altogether
                   (since it will ignore them as being unsupported by the browser.) */
                if (!(IE <= 9) && !Velocity.State.isGingerbread) {
                    /* Note: Since the standalone CSS "perspective" property and the CSS transform "perspective" subproperty
                    share the same name, the latter is given a unique token within Velocity: "transformPerspective". */
                    CSS.Lists.transformsBase = CSS.Lists.transformsBase.concat(CSS.Lists.transforms3D);
                }

                for (var i = 0; i < CSS.Lists.transformsBase.length; i++) {
                    /* Wrap the dynamically generated normalization function in a new scope so that transformName's value is
                    paired with its respective function. (Otherwise, all functions would take the final for loop's transformName.) */
                    (function() {
                        var transformName = CSS.Lists.transformsBase[i];

                        CSS.Normalizations.registered[transformName] = function (type, element, propertyValue) {
                            switch (type) {
                                /* The normalized property name is the parent "transform" property -- the property that is actually set in CSS. */
                                case "name":
                                    return "transform";
                                /* Transform values are cached onto a per-element transformCache object. */
                                case "extract":
                                    /* If this transform has yet to be assigned a value, return its null value. */
                                    if (Data(element) === undefined || Data(element).transformCache[transformName] === undefined) {
                                        /* Scale CSS.Lists.transformsBase default to 1 whereas all other transform properties default to 0. */
                                        return /^scale/i.test(transformName) ? 1 : 0;
                                    /* When transform values are set, they are wrapped in parentheses as per the CSS spec.
                                       Thus, when extracting their values (for tween calculations), we strip off the parentheses. */
                                    } else {
                                        return Data(element).transformCache[transformName].replace(/[()]/g, "");
                                    }
                                case "inject":
                                    var invalid = false;

                                    /* If an individual transform property contains an unsupported unit type, the browser ignores the *entire* transform property.
                                       Thus, protect users from themselves by skipping setting for transform values supplied with invalid unit types. */
                                    /* Switch on the base transform type; ignore the axis by removing the last letter from the transform's name. */
                                    switch (transformName.substr(0, transformName.length - 1)) {
                                        /* Whitelist unit types for each transform. */
                                        case "translate":
                                            invalid = !/(%|px|em|rem|vw|vh|\d)$/i.test(propertyValue);
                                            break;
                                        /* Since an axis-free "scale" property is supported as well, a little hack is used here to detect it by chopping off its last letter. */
                                        case "scal":
                                        case "scale":
                                            /* Chrome on Android has a bug in which scaled elements blur if their initial scale
                                               value is below 1 (which can happen with forcefeeding). Thus, we detect a yet-unset scale property
                                               and ensure that its first value is always 1. More info: http://stackoverflow.com/questions/10417890/css3-animations-with-transform-causes-blurred-elements-on-webkit/10417962#10417962 */
                                            if (Velocity.State.isAndroid && Data(element).transformCache[transformName] === undefined && propertyValue < 1) {
                                                propertyValue = 1;
                                            }

                                            invalid = !/(\d)$/i.test(propertyValue);
                                            break;
                                        case "skew":
                                            invalid = !/(deg|\d)$/i.test(propertyValue);
                                            break;
                                        case "rotate":
                                            invalid = !/(deg|\d)$/i.test(propertyValue);
                                            break;
                                    }

                                    if (!invalid) {
                                        /* As per the CSS spec, wrap the value in parentheses. */
                                        Data(element).transformCache[transformName] = "(" + propertyValue + ")";
                                    }

                                    /* Although the value is set on the transformCache object, return the newly-updated value for the calling code to process as normal. */
                                    return Data(element).transformCache[transformName];
                            }
                        };
                    })();
                }

                /*************
                    Colors
                *************/

                /* Since Velocity only animates a single numeric value per property, color animation is achieved by hooking the individual RGBA components of CSS color properties.
                   Accordingly, color values must be normalized (e.g. "#ff0000", "red", and "rgb(255, 0, 0)" ==> "255 0 0 1") so that their components can be injected/extracted by CSS.Hooks logic. */
                for (var i = 0; i < CSS.Lists.colors.length; i++) {
                    /* Wrap the dynamically generated normalization function in a new scope so that colorName's value is paired with its respective function.
                       (Otherwise, all functions would take the final for loop's colorName.) */
                    (function () {
                        var colorName = CSS.Lists.colors[i];

                        /* Note: In IE<=8, which support rgb but not rgba, color properties are reverted to rgb by stripping off the alpha component. */
                        CSS.Normalizations.registered[colorName] = function(type, element, propertyValue) {
                            switch (type) {
                                case "name":
                                    return colorName;
                                /* Convert all color values into the rgb format. (Old IE can return hex values and color names instead of rgb/rgba.) */
                                case "extract":
                                    var extracted;

                                    /* If the color is already in its hookable form (e.g. "255 255 255 1") due to having been previously extracted, skip extraction. */
                                    if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {
                                        extracted = propertyValue;
                                    } else {
                                        var converted,
                                            colorNames = {
                                                black: "rgb(0, 0, 0)",
                                                blue: "rgb(0, 0, 255)",
                                                gray: "rgb(128, 128, 128)",
                                                green: "rgb(0, 128, 0)",
                                                red: "rgb(255, 0, 0)",
                                                white: "rgb(255, 255, 255)"
                                            };

                                        /* Convert color names to rgb. */
                                        if (/^[A-z]+$/i.test(propertyValue)) {
                                            if (colorNames[propertyValue] !== undefined) {
                                                converted = colorNames[propertyValue]
                                            } else {
                                                /* If an unmatched color name is provided, default to black. */
                                                converted = colorNames.black;
                                            }
                                        /* Convert hex values to rgb. */
                                        } else if (CSS.RegEx.isHex.test(propertyValue)) {
                                            converted = "rgb(" + CSS.Values.hexToRgb(propertyValue).join(" ") + ")";
                                        /* If the provided color doesn't match any of the accepted color formats, default to black. */
                                        } else if (!(/^rgba?\(/i.test(propertyValue))) {
                                            converted = colorNames.black;
                                        }

                                        /* Remove the surrounding "rgb/rgba()" string then replace commas with spaces and strip
                                           repeated spaces (in case the value included spaces to begin with). */
                                        extracted = (converted || propertyValue).toString().match(CSS.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g, " ");
                                    }

                                    /* So long as this isn't <=IE8, add a fourth (alpha) component if it's missing and default it to 1 (visible). */
                                    if (!(IE <= 8) && extracted.split(" ").length === 3) {
                                        extracted += " 1";
                                    }

                                    return extracted;
                                case "inject":
                                    /* If this is IE<=8 and an alpha component exists, strip it off. */
                                    if (IE <= 8) {
                                        if (propertyValue.split(" ").length === 4) {
                                            propertyValue = propertyValue.split(/\s+/).slice(0, 3).join(" ");
                                        }
                                    /* Otherwise, add a fourth (alpha) component if it's missing and default it to 1 (visible). */
                                    } else if (propertyValue.split(" ").length === 3) {
                                        propertyValue += " 1";
                                    }

                                    /* Re-insert the browser-appropriate wrapper("rgb/rgba()"), insert commas, and strip off decimal units
                                       on all values but the fourth (R, G, and B only accept whole numbers). */
                                    return (IE <= 8 ? "rgb" : "rgba") + "(" + propertyValue.replace(/\s+/g, ",").replace(/\.(\d)+(?=,)/g, "") + ")";
                            }
                        };
                    })();
                }
            }
        },

        /************************
           CSS Property Names
        ************************/

        Names: {
            /* Camelcase a property name into its JavaScript notation (e.g. "background-color" ==> "backgroundColor").
               Camelcasing is used to normalize property names between and across calls. */
            camelCase: function (property) {
                return property.replace(/-(\w)/g, function (match, subMatch) {
                    return subMatch.toUpperCase();
                });
            },

            /* For SVG elements, some properties (namely, dimensional ones) are GET/SET via the element's HTML attributes (instead of via CSS styles). */
            SVGAttribute: function (property) {
                var SVGAttributes = "width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";

                /* Certain browsers require an SVG transform to be applied as an attribute. (Otherwise, application via CSS is preferable due to 3D support.) */
                if (IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) {
                    SVGAttributes += "|transform";
                }

                return new RegExp("^(" + SVGAttributes + ")$", "i").test(property);
            },

            /* Determine whether a property should be set with a vendor prefix. */
            /* If a prefixed version of the property exists, return it. Otherwise, return the original property name.
               If the property is not at all supported by the browser, return a false flag. */
            prefixCheck: function (property) {
                /* If this property has already been checked, return the cached value. */
                if (Velocity.State.prefixMatches[property]) {
                    return [ Velocity.State.prefixMatches[property], true ];
                } else {
                    var vendors = [ "", "Webkit", "Moz", "ms", "O" ];

                    for (var i = 0, vendorsLength = vendors.length; i < vendorsLength; i++) {
                        var propertyPrefixed;

                        if (i === 0) {
                            propertyPrefixed = property;
                        } else {
                            /* Capitalize the first letter of the property to conform to JavaScript vendor prefix notation (e.g. webkitFilter). */
                            propertyPrefixed = vendors[i] + property.replace(/^\w/, function(match) { return match.toUpperCase(); });
                        }

                        /* Check if the browser supports this property as prefixed. */
                        if (Type.isString(Velocity.State.prefixElement.style[propertyPrefixed])) {
                            /* Cache the match. */
                            Velocity.State.prefixMatches[property] = propertyPrefixed;

                            return [ propertyPrefixed, true ];
                        }
                    }

                    /* If the browser doesn't support this property in any form, include a false flag so that the caller can decide how to proceed. */
                    return [ property, false ];
                }
            }
        },

        /************************
           CSS Property Values
        ************************/

        Values: {
            /* Hex to RGB conversion. Copyright Tim Down: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb */
            hexToRgb: function (hex) {
                var shortformRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i,
                    longformRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,
                    rgbParts;

                hex = hex.replace(shortformRegex, function (m, r, g, b) {
                    return r + r + g + g + b + b;
                });

                rgbParts = longformRegex.exec(hex);

                return rgbParts ? [ parseInt(rgbParts[1], 16), parseInt(rgbParts[2], 16), parseInt(rgbParts[3], 16) ] : [ 0, 0, 0 ];
            },

            isCSSNullValue: function (value) {
                /* The browser defaults CSS values that have not been set to either 0 or one of several possible null-value strings.
                   Thus, we check for both falsiness and these special strings. */
                /* Null-value checking is performed to default the special strings to 0 (for the sake of tweening) or their hook
                   templates as defined as CSS.Hooks (for the sake of hook injection/extraction). */
                /* Note: Chrome returns "rgba(0, 0, 0, 0)" for an undefined color whereas IE returns "transparent". */
                return (value == 0 || /^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(value));
            },

            /* Retrieve a property's default unit type. Used for assigning a unit type when one is not supplied by the user. */
            getUnitType: function (property) {
                if (/^(rotate|skew)/i.test(property)) {
                    return "deg";
                } else if (/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(property)) {
                    /* The above properties are unitless. */
                    return "";
                } else {
                    /* Default to px for all other properties. */
                    return "px";
                }
            },

            /* HTML elements default to an associated display type when they're not set to display:none. */
            /* Note: This function is used for correctly setting the non-"none" display value in certain Velocity redirects, such as fadeIn/Out. */
            getDisplayType: function (element) {
                var tagName = element && element.tagName.toString().toLowerCase();

                if (/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(tagName)) {
                    return "inline";
                } else if (/^(li)$/i.test(tagName)) {
                    return "list-item";
                } else if (/^(tr)$/i.test(tagName)) {
                    return "table-row";
                /* Default to "block" when no match is found. */
                } else {
                    return "block";
                }
            },

            /* The class add/remove functions are used to temporarily apply a "velocity-animating" class to elements while they're animating. */
            addClass: function (element, className) {
                if (element.classList) {
                    element.classList.add(className);
                } else {
                    element.className += (element.className.length ? " " : "") + className;
                }
            },

            removeClass: function (element, className) {
                if (element.classList) {
                    element.classList.remove(className);
                } else {
                    element.className = element.className.toString().replace(new RegExp("(^|\\s)" + className.split(" ").join("|") + "(\\s|$)", "gi"), " ");
                }
            }
        },

        /****************************
           Style Getting & Setting
        ****************************/

        /* The singular getPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */
        getPropertyValue: function (element, property, rootPropertyValue, forceStyleLookup) {
            /* Get an element's computed property value. */
            /* Note: Retrieving the value of a CSS property cannot simply be performed by checking an element's
               style attribute (which only reflects user-defined values). Instead, the browser must be queried for a property's
               *computed* value. You can read more about getComputedStyle here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */
            function computePropertyValue (element, property) {
                /* When box-sizing isn't set to border-box, height and width style values are incorrectly computed when an
                   element's scrollbars are visible (which expands the element's dimensions). Thus, we defer to the more accurate
                   offsetHeight/Width property, which includes the total dimensions for interior, border, padding, and scrollbar.
                   We subtract border and padding to get the sum of interior + scrollbar. */
                var computedValue = 0;

                /* IE<=8 doesn't support window.getComputedStyle, thus we defer to jQuery, which has an extensive array
                   of hacks to accurately retrieve IE8 property values. Re-implementing that logic here is not worth bloating the
                   codebase for a dying browser. The performance repercussions of using jQuery here are minimal since
                   Velocity is optimized to rarely (and sometimes never) query the DOM. Further, the $.css() codepath isn't that slow. */
                if (IE <= 8) {
                    computedValue = $.css(element, property); /* GET */
                /* All other browsers support getComputedStyle. The returned live object reference is cached onto its
                   associated element so that it does not need to be refetched upon every GET. */
                } else {
                    /* Browsers do not return height and width values for elements that are set to display:"none". Thus, we temporarily
                       toggle display to the element type's default value. */
                    var toggleDisplay = false;

                    if (/^(width|height)$/.test(property) && CSS.getPropertyValue(element, "display") === 0) {
                        toggleDisplay = true;
                        CSS.setPropertyValue(element, "display", CSS.Values.getDisplayType(element));
                    }

                    function revertDisplay () {
                        if (toggleDisplay) {
                            CSS.setPropertyValue(element, "display", "none");
                        }
                    }

                    if (!forceStyleLookup) {
                        if (property === "height" && CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() !== "border-box") {
                            var contentBoxHeight = element.offsetHeight - (parseFloat(CSS.getPropertyValue(element, "borderTopWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "borderBottomWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingTop")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingBottom")) || 0);
                            revertDisplay();

                            return contentBoxHeight;
                        } else if (property === "width" && CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() !== "border-box") {
                            var contentBoxWidth = element.offsetWidth - (parseFloat(CSS.getPropertyValue(element, "borderLeftWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "borderRightWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingLeft")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingRight")) || 0);
                            revertDisplay();

                            return contentBoxWidth;
                        }
                    }

                    var computedStyle;

                    /* For elements that Velocity hasn't been called on directly (e.g. when Velocity queries the DOM on behalf
                       of a parent of an element its animating), perform a direct getComputedStyle lookup since the object isn't cached. */
                    if (Data(element) === undefined) {
                        computedStyle = window.getComputedStyle(element, null); /* GET */
                    /* If the computedStyle object has yet to be cached, do so now. */
                    } else if (!Data(element).computedStyle) {
                        computedStyle = Data(element).computedStyle = window.getComputedStyle(element, null); /* GET */
                    /* If computedStyle is cached, use it. */
                    } else {
                        computedStyle = Data(element).computedStyle;
                    }

                    /* IE and Firefox do not return a value for the generic borderColor -- they only return individual values for each border side's color.
                       As a polyfill for querying individual border side colors, just return the top border's color. */
                    if ((IE || Velocity.State.isFirefox) && property === "borderColor") {
                        property = "borderTopColor";
                    }

                    /* IE9 has a bug in which the "filter" property must be accessed from computedStyle using the getPropertyValue method
                       instead of a direct property lookup. The getPropertyValue method is slower than a direct lookup, which is why we avoid it by default. */
                    if (IE === 9 && property === "filter") {
                        computedValue = computedStyle.getPropertyValue(property); /* GET */
                    } else {
                        computedValue = computedStyle[property];
                    }

                    /* Fall back to the property's style value (if defined) when computedValue returns nothing,
                       which can happen when the element hasn't been painted. */
                    if (computedValue === "" || computedValue === null) {
                        computedValue = element.style[property];
                    }

                    revertDisplay();
                }

                /* For top, right, bottom, and left (TRBL) values that are set to "auto" on elements of "fixed" or "absolute" position,
                   defer to jQuery for converting "auto" to a numeric value. (For elements with a "static" or "relative" position, "auto" has the same
                   effect as being set to 0, so no conversion is necessary.) */
                /* An example of why numeric conversion is necessary: When an element with "position:absolute" has an untouched "left"
                   property, which reverts to "auto", left's value is 0 relative to its parent element, but is often non-zero relative
                   to its *containing* (not parent) element, which is the nearest "position:relative" ancestor or the viewport (and always the viewport in the case of "position:fixed"). */
                if (computedValue === "auto" && /^(top|right|bottom|left)$/i.test(property)) {
                    var position = computePropertyValue(element, "position"); /* GET */

                    /* For absolute positioning, jQuery's $.position() only returns values for top and left;
                       right and bottom will have their "auto" value reverted to 0. */
                    /* Note: A jQuery object must be created here since jQuery doesn't have a low-level alias for $.position().
                       Not a big deal since we're currently in a GET batch anyway. */
                    if (position === "fixed" || (position === "absolute" && /top|left/i.test(property))) {
                        /* Note: jQuery strips the pixel unit from its returned values; we re-add it here to conform with computePropertyValue's behavior. */
                        computedValue = $(element).position()[property] + "px"; /* GET */
                    }
                }

                return computedValue;
            }

            var propertyValue;

            /* If this is a hooked property (e.g. "clipLeft" instead of the root property of "clip"),
               extract the hook's value from a normalized rootPropertyValue using CSS.Hooks.extractValue(). */
            if (CSS.Hooks.registered[property]) {
                var hook = property,
                    hookRoot = CSS.Hooks.getRoot(hook);

                /* If a cached rootPropertyValue wasn't passed in (which Velocity always attempts to do in order to avoid requerying the DOM),
                   query the DOM for the root property's value. */
                if (rootPropertyValue === undefined) {
                    /* Since the browser is now being directly queried, use the official post-prefixing property name for this lookup. */
                    rootPropertyValue = CSS.getPropertyValue(element, CSS.Names.prefixCheck(hookRoot)[0]); /* GET */
                }

                /* If this root has a normalization registered, peform the associated normalization extraction. */
                if (CSS.Normalizations.registered[hookRoot]) {
                    rootPropertyValue = CSS.Normalizations.registered[hookRoot]("extract", element, rootPropertyValue);
                }

                /* Extract the hook's value. */
                propertyValue = CSS.Hooks.extractValue(hook, rootPropertyValue);

            /* If this is a normalized property (e.g. "opacity" becomes "filter" in <=IE8) or "translateX" becomes "transform"),
               normalize the property's name and value, and handle the special case of transforms. */
            /* Note: Normalizing a property is mutually exclusive from hooking a property since hook-extracted values are strictly
               numerical and therefore do not require normalization extraction. */
            } else if (CSS.Normalizations.registered[property]) {
                var normalizedPropertyName,
                    normalizedPropertyValue;

                normalizedPropertyName = CSS.Normalizations.registered[property]("name", element);

                /* Transform values are calculated via normalization extraction (see below), which checks against the element's transformCache.
                   At no point do transform GETs ever actually query the DOM; initial stylesheet values are never processed.
                   This is because parsing 3D transform matrices is not always accurate and would bloat our codebase;
                   thus, normalization extraction defaults initial transform values to their zero-values (e.g. 1 for scaleX and 0 for translateX). */
                if (normalizedPropertyName !== "transform") {
                    normalizedPropertyValue = computePropertyValue(element, CSS.Names.prefixCheck(normalizedPropertyName)[0]); /* GET */

                    /* If the value is a CSS null-value and this property has a hook template, use that zero-value template so that hooks can be extracted from it. */
                    if (CSS.Values.isCSSNullValue(normalizedPropertyValue) && CSS.Hooks.templates[property]) {
                        normalizedPropertyValue = CSS.Hooks.templates[property][1];
                    }
                }

                propertyValue = CSS.Normalizations.registered[property]("extract", element, normalizedPropertyValue);
            }

            /* If a (numeric) value wasn't produced via hook extraction or normalization, query the DOM. */
            if (!/^[\d-]/.test(propertyValue)) {
                /* For SVG elements, dimensional properties (which SVGAttribute() detects) are tweened via
                   their HTML attribute values instead of their CSS style values. */
                if (Data(element) && Data(element).isSVG && CSS.Names.SVGAttribute(property)) {
                    /* Since the height/width attribute values must be set manually, they don't reflect computed values.
                       Thus, we use use getBBox() to ensure we always get values for elements with undefined height/width attributes. */
                    if (/^(height|width)$/i.test(property)) {
                        propertyValue = element.getBBox()[property];
                    /* Otherwise, access the attribute value directly. */
                    } else {
                        propertyValue = element.getAttribute(property);
                    }
                } else {
                    propertyValue = computePropertyValue(element, CSS.Names.prefixCheck(property)[0]); /* GET */
                }
            }

            /* Since property lookups are for animation purposes (which entails computing the numeric delta between start and end values),
               convert CSS null-values to an integer of value 0. */
            if (CSS.Values.isCSSNullValue(propertyValue)) {
                propertyValue = 0;
            }

            if (Velocity.debug >= 2) console.log("Get " + property + ": " + propertyValue);

            return propertyValue;
        },

        /* The singular setPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */
        setPropertyValue: function(element, property, propertyValue, rootPropertyValue, scrollData) {
            var propertyName = property;

            /* In order to be subjected to call options and element queueing, scroll animation is routed through Velocity as if it were a standard CSS property. */
            if (property === "scroll") {
                /* If a container option is present, scroll the container instead of the browser window. */
                if (scrollData.container) {
                    scrollData.container["scroll" + scrollData.direction] = propertyValue;
                /* Otherwise, Velocity defaults to scrolling the browser window. */
                } else {
                    if (scrollData.direction === "Left") {
                        window.scrollTo(propertyValue, scrollData.alternateValue);
                    } else {
                        window.scrollTo(scrollData.alternateValue, propertyValue);
                    }
                }
            } else {
                /* Transforms (translateX, rotateZ, etc.) are applied to a per-element transformCache object, which is manually flushed via flushTransformCache().
                   Thus, for now, we merely cache transforms being SET. */
                if (CSS.Normalizations.registered[property] && CSS.Normalizations.registered[property]("name", element) === "transform") {
                    /* Perform a normalization injection. */
                    /* Note: The normalization logic handles the transformCache updating. */
                    CSS.Normalizations.registered[property]("inject", element, propertyValue);

                    propertyName = "transform";
                    propertyValue = Data(element).transformCache[property];
                } else {
                    /* Inject hooks. */
                    if (CSS.Hooks.registered[property]) {
                        var hookName = property,
                            hookRoot = CSS.Hooks.getRoot(property);

                        /* If a cached rootPropertyValue was not provided, query the DOM for the hookRoot's current value. */
                        rootPropertyValue = rootPropertyValue || CSS.getPropertyValue(element, hookRoot); /* GET */

                        propertyValue = CSS.Hooks.injectValue(hookName, propertyValue, rootPropertyValue);
                        property = hookRoot;
                    }

                    /* Normalize names and values. */
                    if (CSS.Normalizations.registered[property]) {
                        propertyValue = CSS.Normalizations.registered[property]("inject", element, propertyValue);
                        property = CSS.Normalizations.registered[property]("name", element);
                    }

                    /* Assign the appropriate vendor prefix before performing an official style update. */
                    propertyName = CSS.Names.prefixCheck(property)[0];

                    /* A try/catch is used for IE<=8, which throws an error when "invalid" CSS values are set, e.g. a negative width.
                       Try/catch is avoided for other browsers since it incurs a performance overhead. */
                    if (IE <= 8) {
                        try {
                            element.style[propertyName] = propertyValue;
                        } catch (error) { if (Velocity.debug) console.log("Browser does not support [" + propertyValue + "] for [" + propertyName + "]"); }
                    /* SVG elements have their dimensional properties (width, height, x, y, cx, etc.) applied directly as attributes instead of as styles. */
                    /* Note: IE8 does not support SVG elements, so it's okay that we skip it for SVG animation. */
                    } else if (Data(element) && Data(element).isSVG && CSS.Names.SVGAttribute(property)) {
                        /* Note: For SVG attributes, vendor-prefixed property names are never used. */
                        /* Note: Not all CSS properties can be animated via attributes, but the browser won't throw an error for unsupported properties. */
                        element.setAttribute(property, propertyValue);
                    } else {
                        element.style[propertyName] = propertyValue;
                    }

                    if (Velocity.debug >= 2) console.log("Set " + property + " (" + propertyName + "): " + propertyValue);
                }
            }

            /* Return the normalized property name and value in case the caller wants to know how these values were modified before being applied to the DOM. */
            return [ propertyName, propertyValue ];
        },

        /* To increase performance by batching transform updates into a single SET, transforms are not directly applied to an element until flushTransformCache() is called. */
        /* Note: Velocity applies transform properties in the same order that they are chronogically introduced to the element's CSS styles. */
        flushTransformCache: function(element) {
            var transformString = "";

            /* Certain browsers require that SVG transforms be applied as an attribute. However, the SVG transform attribute takes a modified version of CSS's transform string
               (units are dropped and, except for skewX/Y, subproperties are merged into their master property -- e.g. scaleX and scaleY are merged into scale(X Y). */
            if ((IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) && Data(element).isSVG) {
                /* Since transform values are stored in their parentheses-wrapped form, we use a helper function to strip out their numeric values.
                   Further, SVG transform properties only take unitless (representing pixels) values, so it's okay that parseFloat() strips the unit suffixed to the float value. */
                function getTransformFloat (transformProperty) {
                    return parseFloat(CSS.getPropertyValue(element, transformProperty));
                }

                /* Create an object to organize all the transforms that we'll apply to the SVG element. To keep the logic simple,
                   we process *all* transform properties -- even those that may not be explicitly applied (since they default to their zero-values anyway). */
                var SVGTransforms = {
                    translate: [ getTransformFloat("translateX"), getTransformFloat("translateY") ],
                    skewX: [ getTransformFloat("skewX") ], skewY: [ getTransformFloat("skewY") ],
                    /* If the scale property is set (non-1), use that value for the scaleX and scaleY values
                       (this behavior mimics the result of animating all these properties at once on HTML elements). */
                    scale: getTransformFloat("scale") !== 1 ? [ getTransformFloat("scale"), getTransformFloat("scale") ] : [ getTransformFloat("scaleX"), getTransformFloat("scaleY") ],
                    /* Note: SVG's rotate transform takes three values: rotation degrees followed by the X and Y values
                       defining the rotation's origin point. We ignore the origin values (default them to 0). */
                    rotate: [ getTransformFloat("rotateZ"), 0, 0 ]
                };

                /* Iterate through the transform properties in the user-defined property map order.
                   (This mimics the behavior of non-SVG transform animation.) */
                $.each(Data(element).transformCache, function(transformName) {
                    /* Except for with skewX/Y, revert the axis-specific transform subproperties to their axis-free master
                       properties so that they match up with SVG's accepted transform properties. */
                    if (/^translate/i.test(transformName)) {
                        transformName = "translate";
                    } else if (/^scale/i.test(transformName)) {
                        transformName = "scale";
                    } else if (/^rotate/i.test(transformName)) {
                        transformName = "rotate";
                    }

                    /* Check that we haven't yet deleted the property from the SVGTransforms container. */
                    if (SVGTransforms[transformName]) {
                        /* Append the transform property in the SVG-supported transform format. As per the spec, surround the space-delimited values in parentheses. */
                        transformString += transformName + "(" + SVGTransforms[transformName].join(" ") + ")" + " ";

                        /* After processing an SVG transform property, delete it from the SVGTransforms container so we don't
                           re-insert the same master property if we encounter another one of its axis-specific properties. */
                        delete SVGTransforms[transformName];
                    }
                });
            } else {
                var transformValue,
                    perspective;

                /* Transform properties are stored as members of the transformCache object. Concatenate all the members into a string. */
                $.each(Data(element).transformCache, function(transformName) {
                    transformValue = Data(element).transformCache[transformName];

                    /* Transform's perspective subproperty must be set first in order to take effect. Store it temporarily. */
                    if (transformName === "transformPerspective") {
                        perspective = transformValue;
                        return true;
                    }

                    /* IE9 only supports one rotation type, rotateZ, which it refers to as "rotate". */
                    if (IE === 9 && transformName === "rotateZ") {
                        transformName = "rotate";
                    }

                    transformString += transformName + transformValue + " ";
                });

                /* If present, set the perspective subproperty first. */
                if (perspective) {
                    transformString = "perspective" + perspective + " " + transformString;
                }
            }

            CSS.setPropertyValue(element, "transform", transformString);
        }
    };

    /* Register hooks and normalizations. */
    CSS.Hooks.register();
    CSS.Normalizations.register();

    /* Allow hook setting in the same fashion as jQuery's $.css(). */
    Velocity.hook = function (elements, arg2, arg3) {
        var value = undefined;

        elements = sanitizeElements(elements);

        $.each(elements, function(i, element) {
            /* Initialize Velocity's per-element data cache if this element hasn't previously been animated. */
            if (Data(element) === undefined) {
                Velocity.init(element);
            }

            /* Get property value. If an element set was passed in, only return the value for the first element. */
            if (arg3 === undefined) {
                if (value === undefined) {
                    value = Velocity.CSS.getPropertyValue(element, arg2);
                }
            /* Set property value. */
            } else {
                /* sPV returns an array of the normalized propertyName/propertyValue pair used to update the DOM. */
                var adjustedSet = Velocity.CSS.setPropertyValue(element, arg2, arg3);

                /* Transform properties don't automatically set. They have to be flushed to the DOM. */
                if (adjustedSet[0] === "transform") {
                    Velocity.CSS.flushTransformCache(element);
                }

                value = adjustedSet;
            }
        });

        return value;
    };

    /*****************
        Animation
    *****************/

    var animate = function() {

        /******************
            Call Chain
        ******************/

        /* Logic for determining what to return to the call stack when exiting out of Velocity. */
        function getChain () {
            /* If we are using the utility function, attempt to return this call's promise. If no promise library was detected,
               default to null instead of returning the targeted elements so that utility function's return value is standardized. */
            if (isUtility) {
                return promiseData.promise || null;
            /* Otherwise, if we're using $.fn, return the jQuery-/Zepto-wrapped element set. */
            } else {
                return elementsWrapped;
            }
        }

        /*************************
           Arguments Assignment
        *************************/

        /* To allow for expressive CoffeeScript code, Velocity supports an alternative syntax in which "properties" and "options"
           objects are defined on a container object that's passed in as Velocity's sole argument. */
        /* Note: Some browsers automatically populate arguments with a "properties" object. We detect it by checking for its default "names" property. */
        var syntacticSugar = (arguments[0] && (($.isPlainObject(arguments[0].properties) && !arguments[0].properties.names) || Type.isString(arguments[0].properties))),
            /* Whether Velocity was called via the utility function (as opposed to on a jQuery/Zepto object). */
            isUtility,
            /* When Velocity is called via the utility function ($.Velocity()/Velocity()), elements are explicitly
               passed in as the first parameter. Thus, argument positioning varies. We normalize them here. */
            elementsWrapped,
            argumentIndex;

        var elements,
            propertiesMap,
            options;

        /* Detect jQuery/Zepto elements being animated via the $.fn method. */
        if (Type.isWrapped(this)) {
            isUtility = false;

            argumentIndex = 0;
            elements = this;
            elementsWrapped = this;
        /* Otherwise, raw elements are being animated via the utility function. */
        } else {
            isUtility = true;

            argumentIndex = 1;
            elements = syntacticSugar ? arguments[0].elements : arguments[0];
        }

        elements = sanitizeElements(elements);

        if (!elements) {
            return;
        }

        if (syntacticSugar) {
            propertiesMap = arguments[0].properties;
            options = arguments[0].options;
        } else {
            propertiesMap = arguments[argumentIndex];
            options = arguments[argumentIndex + 1];
        }

        /* The length of the element set (in the form of a nodeList or an array of elements) is defaulted to 1 in case a
           single raw DOM element is passed in (which doesn't contain a length property). */
        var elementsLength = elements.length,
            elementsIndex = 0;

        /***************************
            Argument Overloading
        ***************************/

        /* Support is included for jQuery's argument overloading: $.animate(propertyMap [, duration] [, easing] [, complete]).
           Overloading is detected by checking for the absence of an object being passed into options. */
        /* Note: The stop action does not accept animation options, and is therefore excluded from this check. */
        if (propertiesMap !== "stop" && !$.isPlainObject(options)) {
            /* The utility function shifts all arguments one position to the right, so we adjust for that offset. */
            var startingArgumentPosition = argumentIndex + 1;

            options = {};

            /* Iterate through all options arguments */
            for (var i = startingArgumentPosition; i < arguments.length; i++) {
                /* Treat a number as a duration. Parse it out. */
                /* Note: The following RegEx will return true if passed an array with a number as its first item.
                   Thus, arrays are skipped from this check. */
                if (!Type.isArray(arguments[i]) && (/^(fast|normal|slow)$/i.test(arguments[i]) || /^\d/.test(arguments[i]))) {
                    options.duration = arguments[i];
                /* Treat strings and arrays as easings. */
                } else if (Type.isString(arguments[i]) || Type.isArray(arguments[i])) {
                    options.easing = arguments[i];
                /* Treat a function as a complete callback. */
                } else if (Type.isFunction(arguments[i])) {
                    options.complete = arguments[i];
                }
            }
        }

        /***************
            Promises
        ***************/

        var promiseData = {
                promise: null,
                resolver: null,
                rejecter: null
            };

        /* If this call was made via the utility function (which is the default method of invocation when jQuery/Zepto are not being used), and if
           promise support was detected, create a promise object for this call and store references to its resolver and rejecter methods. The resolve
           method is used when a call completes naturally or is prematurely stopped by the user. In both cases, completeCall() handles the associated
           call cleanup and promise resolving logic. The reject method is used when an invalid set of arguments is passed into a Velocity call. */
        /* Note: Velocity employs a call-based queueing architecture, which means that stopping an animating element actually stops the full call that
           triggered it -- not that one element exclusively. Similarly, there is one promise per call, and all elements targeted by a Velocity call are
           grouped together for the purposes of resolving and rejecting a promise. */
        if (isUtility && Velocity.Promise) {
            promiseData.promise = new Velocity.Promise(function (resolve, reject) {
                promiseData.resolver = resolve;
                promiseData.rejecter = reject;
            });
        }

        /*********************
           Action Detection
        *********************/

        /* Velocity's behavior is categorized into "actions": Elements can either be specially scrolled into view,
           or they can be started, stopped, or reversed. If a literal or referenced properties map is passed in as Velocity's
           first argument, the associated action is "start". Alternatively, "scroll", "reverse", or "stop" can be passed in instead of a properties map. */
        var action;

        switch (propertiesMap) {
            case "scroll":
                action = "scroll";
                break;

            case "reverse":
                action = "reverse";
                break;

            case "stop":
                /*******************
                    Action: Stop
                *******************/

                /* Clear the currently-active delay on each targeted element. */
                $.each(elements, function(i, element) {
                    if (Data(element) && Data(element).delayTimer) {
                        /* Stop the timer from triggering its cached next() function. */
                        clearTimeout(Data(element).delayTimer.setTimeout);

                        /* Manually call the next() function so that the subsequent queue items can progress. */
                        if (Data(element).delayTimer.next) {
                            Data(element).delayTimer.next();
                        }

                        delete Data(element).delayTimer;
                    }
                });

                var callsToStop = [];

                /* When the stop action is triggered, the elements' currently active call is immediately stopped. The active call might have
                   been applied to multiple elements, in which case all of the call's elements will be subjected to stopping. When an element
                   is stopped, the next item in its animation queue is immediately triggered. */
                /* An additional argument may be passed in to clear an element's remaining queued calls. Either true (which defaults to the "fx" queue)
                   or a custom queue string can be passed in. */
                /* Note: The stop command runs prior to Queueing since its behavior is intended to take effect *immediately*,
                   regardless of the element's current queue state. */

                /* Iterate through every active call. */
                $.each(Velocity.State.calls, function(i, activeCall) {
                    /* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
                    if (activeCall) {
                        /* Iterate through the active call's targeted elements. */
                        $.each(activeCall[1], function(k, activeElement) {
                            var queueName = Type.isString(options) ? options : "";

                            if (options !== undefined && activeCall[2].queue !== queueName) {
                                return true;
                            }

                            /* Iterate through the calls targeted by the stop command. */
                            $.each(elements, function(l, element) {
                                /* Check that this call was applied to the target element. */
                                if (element === activeElement) {
                                    /* Optionally clear the remaining queued calls. */
                                    if (options !== undefined) {
                                        /* Iterate through the items in the element's queue. */
                                        $.each($.queue(element, queueName), function(_, item) {
                                            /* The queue array can contain an "inprogress" string, which we skip. */
                                            if (Type.isFunction(item)) {
                                                /* Pass the item's callback a flag indicating that we want to abort from the queue call.
                                                   (Specifically, the queue will resolve the call's associated promise then abort.)  */
                                                item(null, true);
                                            }
                                        });

                                        /* Clearing the $.queue() array is achieved by resetting it to []. */
                                        $.queue(element, queueName, []);
                                    }

                                    if (Data(element) && queueName === "") {
                                        /* Since "reverse" uses cached start values (the previous call's endValues),
                                           these values must be changed to reflect the final value that the elements were actually tweened to. */
                                        $.each(Data(element).tweensContainer, function(m, activeTween) {
                                            activeTween.endValue = activeTween.currentValue;
                                        });
                                    }

                                    callsToStop.push(i);
                                }
                            });
                        });
                    }
                });

                /* Prematurely call completeCall() on each matched active call, passing an additional flag to indicate
                   that the complete callback and display:none setting should be skipped since we're completing prematurely. */
                $.each(callsToStop, function(i, j) {
                    completeCall(j, true);
                });

                if (promiseData.promise) {
                    /* Immediately resolve the promise associated with this stop call since stop runs synchronously. */
                    promiseData.resolver(elements);
                }

                /* Since we're stopping, and not proceeding with queueing, exit out of Velocity. */
                return getChain();

            default:
                /* Treat a non-empty plain object as a literal properties map. */
                if ($.isPlainObject(propertiesMap) && !Type.isEmptyObject(propertiesMap)) {
                    action = "start";

                /****************
                    Redirects
                ****************/

                /* Check if a string matches a registered redirect (see Redirects above). */
                } else if (Type.isString(propertiesMap) && Velocity.Redirects[propertiesMap]) {
                    var opts = $.extend({}, options),
                        durationOriginal = opts.duration,
                        delayOriginal = opts.delay || 0;

                    /* If the backwards option was passed in, reverse the element set so that elements animate from the last to the first. */
                    if (opts.backwards === true) {
                        elements = $.extend(true, [], elements).reverse();
                    }

                    /* Individually trigger the redirect for each element in the set to prevent users from having to handle iteration logic in their redirect. */
                    $.each(elements, function(elementIndex, element) {
                        /* If the stagger option was passed in, successively delay each element by the stagger value (in ms). Retain the original delay value. */
                        if (parseFloat(opts.stagger)) {
                            opts.delay = delayOriginal + (parseFloat(opts.stagger) * elementIndex);
                        } else if (Type.isFunction(opts.stagger)) {
                            opts.delay = delayOriginal + opts.stagger.call(element, elementIndex, elementsLength);
                        }

                        /* If the drag option was passed in, successively increase/decrease (depending on the presense of opts.backwards)
                           the duration of each element's animation, using floors to prevent producing very short durations. */
                        if (opts.drag) {
                            /* Default the duration of UI pack effects (callouts and transitions) to 1000ms instead of the usual default duration of 400ms. */
                            opts.duration = parseFloat(durationOriginal) || (/^(callout|transition)/.test(propertiesMap) ? 1000 : DURATION_DEFAULT);

                            /* For each element, take the greater duration of: A) animation completion percentage relative to the original duration,
                               B) 75% of the original duration, or C) a 200ms fallback (in case duration is already set to a low value).
                               The end result is a baseline of 75% of the redirect's duration that increases/decreases as the end of the element set is approached. */
                            opts.duration = Math.max(opts.duration * (opts.backwards ? 1 - elementIndex/elementsLength : (elementIndex + 1) / elementsLength), opts.duration * 0.75, 200);
                        }

                        /* Pass in the call's opts object so that the redirect can optionally extend it. It defaults to an empty object instead of null to
                           reduce the opts checking logic required inside the redirect. */
                        Velocity.Redirects[propertiesMap].call(element, element, opts || {}, elementIndex, elementsLength, elements, promiseData.promise ? promiseData : undefined);
                    });

                    /* Since the animation logic resides within the redirect's own code, abort the remainder of this call.
                       (The performance overhead up to this point is virtually non-existant.) */
                    /* Note: The jQuery call chain is kept intact by returning the complete element set. */
                    return getChain();
                } else {
                    var abortError = "Velocity: First argument (" + propertiesMap + ") was not a property map, a known action, or a registered redirect. Aborting.";

                    if (promiseData.promise) {
                        promiseData.rejecter(new Error(abortError));
                    } else {
                        console.log(abortError);
                    }

                    return getChain();
                }
        }

        /**************************
            Call-Wide Variables
        **************************/

        /* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements
           being animated in a single Velocity call. Calculating unit ratios necessitates DOM querying and updating, and is therefore
           avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale
           conversion metrics across Velocity animations that are not immediately consecutively chained. */
        var callUnitConversionData = {
                lastParent: null,
                lastPosition: null,
                lastFontSize: null,
                lastPercentToPxWidth: null,
                lastPercentToPxHeight: null,
                lastEmToPx: null,
                remToPx: null,
                vwToPx: null,
                vhToPx: null
            };

        /* A container for all the ensuing tween data and metadata associated with this call. This container gets pushed to the page-wide
           Velocity.State.calls array that is processed during animation ticking. */
        var call = [];

        /************************
           Element Processing
        ************************/

        /* Element processing consists of three parts -- data processing that cannot go stale and data processing that *can* go stale (i.e. third-party style modifications):
           1) Pre-Queueing: Element-wide variables, including the element's data storage, are instantiated. Call options are prepared. If triggered, the Stop action is executed.
           2) Queueing: The logic that runs once this call has reached its point of execution in the element's $.queue() stack. Most logic is placed here to avoid risking it becoming stale.
           3) Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.
        */

        function processElement () {

            /*************************
               Part I: Pre-Queueing
            *************************/

            /***************************
               Element-Wide Variables
            ***************************/

            var element = this,
                /* The runtime opts object is the extension of the current call's options and Velocity's page-wide option defaults. */
                opts = $.extend({}, Velocity.defaults, options),
                /* A container for the processed data associated with each property in the propertyMap.
                   (Each property in the map produces its own "tween".) */
                tweensContainer = {},
                elementUnitConversionData;

            /******************
               Element Init
            ******************/

            if (Data(element) === undefined) {
                Velocity.init(element);
            }

            /******************
               Option: Delay
            ******************/

            /* Since queue:false doesn't respect the item's existing queue, we avoid injecting its delay here (it's set later on). */
            /* Note: Velocity rolls its own delay function since jQuery doesn't have a utility alias for $.fn.delay()
               (and thus requires jQuery element creation, which we avoid since its overhead includes DOM querying). */
            if (parseFloat(opts.delay) && opts.queue !== false) {
                $.queue(element, opts.queue, function(next) {
                    /* This is a flag used to indicate to the upcoming completeCall() function that this queue entry was initiated by Velocity. See completeCall() for further details. */
                    Velocity.velocityQueueEntryFlag = true;

                    /* The ensuing queue item (which is assigned to the "next" argument that $.queue() automatically passes in) will be triggered after a setTimeout delay.
                       The setTimeout is stored so that it can be subjected to clearTimeout() if this animation is prematurely stopped via Velocity's "stop" command. */
                    Data(element).delayTimer = {
                        setTimeout: setTimeout(next, parseFloat(opts.delay)),
                        next: next
                    };
                });
            }

            /*********************
               Option: Duration
            *********************/

            /* Support for jQuery's named durations. */
            switch (opts.duration.toString().toLowerCase()) {
                case "fast":
                    opts.duration = 200;
                    break;

                case "normal":
                    opts.duration = DURATION_DEFAULT;
                    break;

                case "slow":
                    opts.duration = 600;
                    break;

                default:
                    /* Remove the potential "ms" suffix and default to 1 if the user is attempting to set a duration of 0 (in order to produce an immediate style change). */
                    opts.duration = parseFloat(opts.duration) || 1;
            }

            /************************
               Global Option: Mock
            ************************/

            if (Velocity.mock !== false) {
                /* In mock mode, all animations are forced to 1ms so that they occur immediately upon the next rAF tick.
                   Alternatively, a multiplier can be passed in to time remap all delays and durations. */
                if (Velocity.mock === true) {
                    opts.duration = opts.delay = 1;
                } else {
                    opts.duration *= parseFloat(Velocity.mock) || 1;
                    opts.delay *= parseFloat(Velocity.mock) || 1;
                }
            }

            /*******************
               Option: Easing
            *******************/

            opts.easing = getEasing(opts.easing, opts.duration);

            /**********************
               Option: Callbacks
            **********************/

            /* Callbacks must functions. Otherwise, default to null. */
            if (opts.begin && !Type.isFunction(opts.begin)) {
                opts.begin = null;
            }

            if (opts.progress && !Type.isFunction(opts.progress)) {
                opts.progress = null;
            }

            if (opts.complete && !Type.isFunction(opts.complete)) {
                opts.complete = null;
            }

            /*********************************
               Option: Display & Visibility
            *********************************/

            /* Refer to Velocity's documentation (VelocityJS.org/#displayAndVisibility) for a description of the display and visibility options' behavior. */
            /* Note: We strictly check for undefined instead of falsiness because display accepts an empty string value. */
            if (opts.display !== undefined && opts.display !== null) {
                opts.display = opts.display.toString().toLowerCase();

                /* Users can pass in a special "auto" value to instruct Velocity to set the element to its default display value. */
                if (opts.display === "auto") {
                    opts.display = Velocity.CSS.Values.getDisplayType(element);
                }
            }

            if (opts.visibility !== undefined && opts.visibility !== null) {
                opts.visibility = opts.visibility.toString().toLowerCase();
            }

            /**********************
               Option: mobileHA
            **********************/

            /* When set to true, and if this is a mobile device, mobileHA automatically enables hardware acceleration (via a null transform hack)
               on animating elements. HA is removed from the element at the completion of its animation. */
            /* Note: Android Gingerbread doesn't support HA. If a null transform hack (mobileHA) is in fact set, it will prevent other tranform subproperties from taking effect. */
            /* Note: You can read more about the use of mobileHA in Velocity's documentation: VelocityJS.org/#mobileHA. */
            opts.mobileHA = (opts.mobileHA && Velocity.State.isMobile && !Velocity.State.isGingerbread);

            /***********************
               Part II: Queueing
            ***********************/

            /* When a set of elements is targeted by a Velocity call, the set is broken up and each element has the current Velocity call individually queued onto it.
               In this way, each element's existing queue is respected; some elements may already be animating and accordingly should not have this current Velocity call triggered immediately. */
            /* In each queue, tween data is processed for each animating property then pushed onto the call-wide calls array. When the last element in the set has had its tweens processed,
               the call array is pushed to Velocity.State.calls for live processing by the requestAnimationFrame tick. */
            function buildQueue (next) {

                /*******************
                   Option: Begin
                *******************/

                /* The begin callback is fired once per call -- not once per elemenet -- and is passed the full raw DOM element set as both its context and its first argument. */
                if (opts.begin && elementsIndex === 0) {
                    /* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */
                    try {
                        opts.begin.call(elements, elements);
                    } catch (error) {
                        setTimeout(function() { throw error; }, 1);
                    }
                }

                /*****************************************
                   Tween Data Construction (for Scroll)
                *****************************************/

                /* Note: In order to be subjected to chaining and animation options, scroll's tweening is routed through Velocity as if it were a standard CSS property animation. */
                if (action === "scroll") {
                    /* The scroll action uniquely takes an optional "offset" option -- specified in pixels -- that offsets the targeted scroll position. */
                    var scrollDirection = (/^x$/i.test(opts.axis) ? "Left" : "Top"),
                        scrollOffset = parseFloat(opts.offset) || 0,
                        scrollPositionCurrent,
                        scrollPositionCurrentAlternate,
                        scrollPositionEnd;

                    /* Scroll also uniquely takes an optional "container" option, which indicates the parent element that should be scrolled --
                       as opposed to the browser window itself. This is useful for scrolling toward an element that's inside an overflowing parent element. */
                    if (opts.container) {
                        /* Ensure that either a jQuery object or a raw DOM element was passed in. */
                        if (Type.isWrapped(opts.container) || Type.isNode(opts.container)) {
                            /* Extract the raw DOM element from the jQuery wrapper. */
                            opts.container = opts.container[0] || opts.container;
                            /* Note: Unlike other properties in Velocity, the browser's scroll position is never cached since it so frequently changes
                               (due to the user's natural interaction with the page). */
                            scrollPositionCurrent = opts.container["scroll" + scrollDirection]; /* GET */

                            /* $.position() values are relative to the container's currently viewable area (without taking into account the container's true dimensions
                               -- say, for example, if the container was not overflowing). Thus, the scroll end value is the sum of the child element's position *and*
                               the scroll container's current scroll position. */
                            /* Note: jQuery does not offer a utility alias for $.position(), so we have to incur jQuery object conversion here.
                               This syncs up with an ensuing batch of GETs, so it fortunately does not trigger layout thrashing. */
                            scrollPositionEnd = (scrollPositionCurrent + $(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; /* GET */
                        /* If a value other than a jQuery object or a raw DOM element was passed in, default to null so that this option is ignored. */
                        } else {
                            opts.container = null;
                        }
                    } else {
                        /* If the window itself is being scrolled -- not a containing element -- perform a live scroll position lookup using
                           the appropriate cached property names (which differ based on browser type). */
                        scrollPositionCurrent = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + scrollDirection]]; /* GET */
                        /* When scrolling the browser window, cache the alternate axis's current value since window.scrollTo() doesn't let us change only one value at a time. */
                        scrollPositionCurrentAlternate = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + (scrollDirection === "Left" ? "Top" : "Left")]]; /* GET */

                        /* Unlike $.position(), $.offset() values are relative to the browser window's true dimensions -- not merely its currently viewable area --
                           and therefore end values do not need to be compounded onto current values. */
                        scrollPositionEnd = $(element).offset()[scrollDirection.toLowerCase()] + scrollOffset; /* GET */
                    }

                    /* Since there's only one format that scroll's associated tweensContainer can take, we create it manually. */
                    tweensContainer = {
                        scroll: {
                            rootPropertyValue: false,
                            startValue: scrollPositionCurrent,
                            currentValue: scrollPositionCurrent,
                            endValue: scrollPositionEnd,
                            unitType: "",
                            easing: opts.easing,
                            scrollData: {
                                container: opts.container,
                                direction: scrollDirection,
                                alternateValue: scrollPositionCurrentAlternate
                            }
                        },
                        element: element
                    };

                    if (Velocity.debug) console.log("tweensContainer (scroll): ", tweensContainer.scroll, element);

                /******************************************
                   Tween Data Construction (for Reverse)
                ******************************************/

                /* Reverse acts like a "start" action in that a property map is animated toward. The only difference is
                   that the property map used for reverse is the inverse of the map used in the previous call. Thus, we manipulate
                   the previous call to construct our new map: use the previous map's end values as our new map's start values. Copy over all other data. */
                /* Note: Reverse can be directly called via the "reverse" parameter, or it can be indirectly triggered via the loop option. (Loops are composed of multiple reverses.) */
                /* Note: Reverse calls do not need to be consecutively chained onto a currently-animating element in order to operate on cached values;
                   there is no harm to reverse being called on a potentially stale data cache since reverse's behavior is simply defined
                   as reverting to the element's values as they were prior to the previous *Velocity* call. */
                } else if (action === "reverse") {
                    /* Abort if there is no prior animation data to reverse to. */
                    if (!Data(element).tweensContainer) {
                        /* Dequeue the element so that this queue entry releases itself immediately, allowing subsequent queue entries to run. */
                        $.dequeue(element, opts.queue);

                        return;
                    } else {
                        /*********************
                           Options Parsing
                        *********************/

                        /* If the element was hidden via the display option in the previous call,
                           revert display to "auto" prior to reversal so that the element is visible again. */
                        if (Data(element).opts.display === "none") {
                            Data(element).opts.display = "auto";
                        }

                        if (Data(element).opts.visibility === "hidden") {
                            Data(element).opts.visibility = "visible";
                        }

                        /* If the loop option was set in the previous call, disable it so that "reverse" calls aren't recursively generated.
                           Further, remove the previous call's callback options; typically, users do not want these to be refired. */
                        Data(element).opts.loop = false;
                        Data(element).opts.begin = null;
                        Data(element).opts.complete = null;

                        /* Since we're extending an opts object that has already been extended with the defaults options object,
                           we remove non-explicitly-defined properties that are auto-assigned values. */
                        if (!options.easing) {
                            delete opts.easing;
                        }

                        if (!options.duration) {
                            delete opts.duration;
                        }

                        /* The opts object used for reversal is an extension of the options object optionally passed into this
                           reverse call plus the options used in the previous Velocity call. */
                        opts = $.extend({}, Data(element).opts, opts);

                        /*************************************
                           Tweens Container Reconstruction
                        *************************************/

                        /* Create a deepy copy (indicated via the true flag) of the previous call's tweensContainer. */
                        var lastTweensContainer = $.extend(true, {}, Data(element).tweensContainer);

                        /* Manipulate the previous tweensContainer by replacing its end values and currentValues with its start values. */
                        for (var lastTween in lastTweensContainer) {
                            /* In addition to tween data, tweensContainers contain an element property that we ignore here. */
                            if (lastTween !== "element") {
                                var lastStartValue = lastTweensContainer[lastTween].startValue;

                                lastTweensContainer[lastTween].startValue = lastTweensContainer[lastTween].currentValue = lastTweensContainer[lastTween].endValue;
                                lastTweensContainer[lastTween].endValue = lastStartValue;

                                /* Easing is the only option that embeds into the individual tween data (since it can be defined on a per-property basis).
                                   Accordingly, every property's easing value must be updated when an options object is passed in with a reverse call.
                                   The side effect of this extensibility is that all per-property easing values are forcefully reset to the new value. */
                                if (!Type.isEmptyObject(options)) {
                                    lastTweensContainer[lastTween].easing = opts.easing;
                                }

                                if (Velocity.debug) console.log("reverse tweensContainer (" + lastTween + "): " + JSON.stringify(lastTweensContainer[lastTween]), element);
                            }
                        }

                        tweensContainer = lastTweensContainer;
                    }

                /*****************************************
                   Tween Data Construction (for Start)
                *****************************************/

                } else if (action === "start") {

                    /*************************
                        Value Transferring
                    *************************/

                    /* If this queue entry follows a previous Velocity-initiated queue entry *and* if this entry was created
                       while the element was in the process of being animated by Velocity, then this current call is safe to use
                       the end values from the prior call as its start values. Velocity attempts to perform this value transfer
                       process whenever possible in order to avoid requerying the DOM. */
                    /* If values aren't transferred from a prior call and start values were not forcefed by the user (more on this below),
                       then the DOM is queried for the element's current values as a last resort. */
                    /* Note: Conversely, animation reversal (and looping) *always* perform inter-call value transfers; they never requery the DOM. */
                    var lastTweensContainer;

                    /* The per-element isAnimating flag is used to indicate whether it's safe (i.e. the data isn't stale)
                       to transfer over end values to use as start values. If it's set to true and there is a previous
                       Velocity call to pull values from, do so. */
                    if (Data(element).tweensContainer && Data(element).isAnimating === true) {
                        lastTweensContainer = Data(element).tweensContainer;
                    }

                    /***************************
                       Tween Data Calculation
                    ***************************/

                    /* This function parses property data and defaults endValue, easing, and startValue as appropriate. */
                    /* Property map values can either take the form of 1) a single value representing the end value,
                       or 2) an array in the form of [ endValue, [, easing] [, startValue] ].
                       The optional third parameter is a forcefed startValue to be used instead of querying the DOM for
                       the element's current value. Read Velocity's docmentation to learn more about forcefeeding: VelocityJS.org/#forcefeeding */
                    function parsePropertyValue (valueData, skipResolvingEasing) {
                        var endValue = undefined,
                            easing = undefined,
                            startValue = undefined;

                        /* Handle the array format, which can be structured as one of three potential overloads:
                           A) [ endValue, easing, startValue ], B) [ endValue, easing ], or C) [ endValue, startValue ] */
                        if (Type.isArray(valueData)) {
                            /* endValue is always the first item in the array. Don't bother validating endValue's value now
                               since the ensuing property cycling logic does that. */
                            endValue = valueData[0];

                            /* Two-item array format: If the second item is a number, function, or hex string, treat it as a
                               start value since easings can only be non-hex strings or arrays. */
                            if ((!Type.isArray(valueData[1]) && /^[\d-]/.test(valueData[1])) || Type.isFunction(valueData[1]) || CSS.RegEx.isHex.test(valueData[1])) {
                                startValue = valueData[1];
                            /* Two or three-item array: If the second item is a non-hex string or an array, treat it as an easing. */
                            } else if ((Type.isString(valueData[1]) && !CSS.RegEx.isHex.test(valueData[1])) || Type.isArray(valueData[1])) {
                                easing = skipResolvingEasing ? valueData[1] : getEasing(valueData[1], opts.duration);

                                /* Don't bother validating startValue's value now since the ensuing property cycling logic inherently does that. */
                                if (valueData[2] !== undefined) {
                                    startValue = valueData[2];
                                }
                            }
                        /* Handle the single-value format. */
                        } else {
                            endValue = valueData;
                        }

                        /* Default to the call's easing if a per-property easing type was not defined. */
                        if (!skipResolvingEasing) {
                            easing = easing || opts.easing;
                        }

                        /* If functions were passed in as values, pass the function the current element as its context,
                           plus the element's index and the element set's size as arguments. Then, assign the returned value. */
                        if (Type.isFunction(endValue)) {
                            endValue = endValue.call(element, elementsIndex, elementsLength);
                        }

                        if (Type.isFunction(startValue)) {
                            startValue = startValue.call(element, elementsIndex, elementsLength);
                        }

                        /* Allow startValue to be left as undefined to indicate to the ensuing code that its value was not forcefed. */
                        return [ endValue || 0, easing, startValue ];
                    }

                    /* Cycle through each property in the map, looking for shorthand color properties (e.g. "color" as opposed to "colorRed"). Inject the corresponding
                       colorRed, colorGreen, and colorBlue RGB component tweens into the propertiesMap (which Velocity understands) and remove the shorthand property. */
                    $.each(propertiesMap, function(property, value) {
                        /* Find shorthand color properties that have been passed a hex string. */
                        if (RegExp("^" + CSS.Lists.colors.join("$|^") + "$").test(property)) {
                            /* Parse the value data for each shorthand. */
                            var valueData = parsePropertyValue(value, true),
                                endValue = valueData[0],
                                easing = valueData[1],
                                startValue = valueData[2];

                            if (CSS.RegEx.isHex.test(endValue)) {
                                /* Convert the hex strings into their RGB component arrays. */
                                var colorComponents = [ "Red", "Green", "Blue" ],
                                    endValueRGB = CSS.Values.hexToRgb(endValue),
                                    startValueRGB = startValue ? CSS.Values.hexToRgb(startValue) : undefined;

                                /* Inject the RGB component tweens into propertiesMap. */
                                for (var i = 0; i < colorComponents.length; i++) {
                                    var dataArray = [ endValueRGB[i] ];

                                    if (easing) {
                                        dataArray.push(easing);
                                    }

                                    if (startValueRGB !== undefined) {
                                        dataArray.push(startValueRGB[i]);
                                    }

                                    propertiesMap[property + colorComponents[i]] = dataArray;
                                }

                                /* Remove the intermediary shorthand property entry now that we've processed it. */
                                delete propertiesMap[property];
                            }
                        }
                    });

                    /* Create a tween out of each property, and append its associated data to tweensContainer. */
                    for (var property in propertiesMap) {

                        /**************************
                           Start Value Sourcing
                        **************************/

                        /* Parse out endValue, easing, and startValue from the property's data. */
                        var valueData = parsePropertyValue(propertiesMap[property]),
                            endValue = valueData[0],
                            easing = valueData[1],
                            startValue = valueData[2];

                        /* Now that the original property name's format has been used for the parsePropertyValue() lookup above,
                           we force the property to its camelCase styling to normalize it for manipulation. */
                        property = CSS.Names.camelCase(property);

                        /* In case this property is a hook, there are circumstances where we will intend to work on the hook's root property and not the hooked subproperty. */
                        var rootProperty = CSS.Hooks.getRoot(property),
                            rootPropertyValue = false;

                        /* Properties that are not supported by the browser (and do not have an associated normalization) will
                           inherently produce no style changes when set, so they are skipped in order to decrease animation tick overhead.
                           Property support is determined via prefixCheck(), which returns a false flag when no supported is detected. */
                        /* Note: Since SVG elements have some of their properties directly applied as HTML attributes,
                           there is no way to check for their explicit browser support, and so we skip skip this check for them. */
                        if (!Data(element).isSVG && CSS.Names.prefixCheck(rootProperty)[1] === false && CSS.Normalizations.registered[rootProperty] === undefined) {
                            if (Velocity.debug) console.log("Skipping [" + rootProperty + "] due to a lack of browser support.");

                            continue;
                        }

                        /* If the display option is being set to a non-"none" (e.g. "block") and opacity (filter on IE<=8) is being
                           animated to an endValue of non-zero, the user's intention is to fade in from invisible, thus we forcefeed opacity
                           a startValue of 0 if its startValue hasn't already been sourced by value transferring or prior forcefeeding. */
                        if (((opts.display !== undefined && opts.display !== null && opts.display !== "none") || (opts.visibility !== undefined && opts.visibility !== "hidden")) && /opacity|filter/.test(property) && !startValue && endValue !== 0) {
                            startValue = 0;
                        }

                        /* If values have been transferred from the previous Velocity call, extract the endValue and rootPropertyValue
                           for all of the current call's properties that were *also* animated in the previous call. */
                        /* Note: Value transferring can optionally be disabled by the user via the _cacheValues option. */
                        if (opts._cacheValues && lastTweensContainer && lastTweensContainer[property]) {
                            if (startValue === undefined) {
                                startValue = lastTweensContainer[property].endValue + lastTweensContainer[property].unitType;
                            }

                            /* The previous call's rootPropertyValue is extracted from the element's data cache since that's the
                               instance of rootPropertyValue that gets freshly updated by the tweening process, whereas the rootPropertyValue
                               attached to the incoming lastTweensContainer is equal to the root property's value prior to any tweening. */
                            rootPropertyValue = Data(element).rootPropertyValueCache[rootProperty];
                        /* If values were not transferred from a previous Velocity call, query the DOM as needed. */
                        } else {
                            /* Handle hooked properties. */
                            if (CSS.Hooks.registered[property]) {
                               if (startValue === undefined) {
                                    rootPropertyValue = CSS.getPropertyValue(element, rootProperty); /* GET */
                                    /* Note: The following getPropertyValue() call does not actually trigger a DOM query;
                                       getPropertyValue() will extract the hook from rootPropertyValue. */
                                    startValue = CSS.getPropertyValue(element, property, rootPropertyValue);
                                /* If startValue is already defined via forcefeeding, do not query the DOM for the root property's value;
                                   just grab rootProperty's zero-value template from CSS.Hooks. This overwrites the element's actual
                                   root property value (if one is set), but this is acceptable since the primary reason users forcefeed is
                                   to avoid DOM queries, and thus we likewise avoid querying the DOM for the root property's value. */
                                } else {
                                    /* Grab this hook's zero-value template, e.g. "0px 0px 0px black". */
                                    rootPropertyValue = CSS.Hooks.templates[rootProperty][1];
                                }
                            /* Handle non-hooked properties that haven't already been defined via forcefeeding. */
                            } else if (startValue === undefined) {
                                startValue = CSS.getPropertyValue(element, property); /* GET */
                            }
                        }

                        /**************************
                           Value Data Extraction
                        **************************/

                        var separatedValue,
                            endValueUnitType,
                            startValueUnitType,
                            operator = false;

                        /* Separates a property value into its numeric value and its unit type. */
                        function separateValue (property, value) {
                            var unitType,
                                numericValue;

                            numericValue = (value || "0")
                                .toString()
                                .toLowerCase()
                                /* Match the unit type at the end of the value. */
                                .replace(/[%A-z]+$/, function(match) {
                                    /* Grab the unit type. */
                                    unitType = match;

                                    /* Strip the unit type off of value. */
                                    return "";
                                });

                            /* If no unit type was supplied, assign one that is appropriate for this property (e.g. "deg" for rotateZ or "px" for width). */
                            if (!unitType) {
                                unitType = CSS.Values.getUnitType(property);
                            }

                            return [ numericValue, unitType ];
                        }

                        /* Separate startValue. */
                        separatedValue = separateValue(property, startValue);
                        startValue = separatedValue[0];
                        startValueUnitType = separatedValue[1];

                        /* Separate endValue, and extract a value operator (e.g. "+=", "-=") if one exists. */
                        separatedValue = separateValue(property, endValue);
                        endValue = separatedValue[0].replace(/^([+-\/*])=/, function(match, subMatch) {
                            operator = subMatch;

                            /* Strip the operator off of the value. */
                            return "";
                        });
                        endValueUnitType = separatedValue[1];

                        /* Parse float values from endValue and startValue. Default to 0 if NaN is returned. */
                        startValue = parseFloat(startValue) || 0;
                        endValue = parseFloat(endValue) || 0;

                        /***************************************
                           Property-Specific Value Conversion
                        ***************************************/

                        /* Custom support for properties that don't actually accept the % unit type, but where pollyfilling is trivial and relatively foolproof. */
                        if (endValueUnitType === "%") {
                            /* A %-value fontSize/lineHeight is relative to the parent's fontSize (as opposed to the parent's dimensions),
                               which is identical to the em unit's behavior, so we piggyback off of that. */
                            if (/^(fontSize|lineHeight)$/.test(property)) {
                                /* Convert % into an em decimal value. */
                                endValue = endValue / 100;
                                endValueUnitType = "em";
                            /* For scaleX and scaleY, convert the value into its decimal format and strip off the unit type. */
                            } else if (/^scale/.test(property)) {
                                endValue = endValue / 100;
                                endValueUnitType = "";
                            /* For RGB components, take the defined percentage of 255 and strip off the unit type. */
                            } else if (/(Red|Green|Blue)$/i.test(property)) {
                                endValue = (endValue / 100) * 255;
                                endValueUnitType = "";
                            }
                        }

                        /***************************
                           Unit Ratio Calculation
                        ***************************/

                        /* When queried, the browser returns (most) CSS property values in pixels. Therefore, if an endValue with a unit type of
                           %, em, or rem is animated toward, startValue must be converted from pixels into the same unit type as endValue in order
                           for value manipulation logic (increment/decrement) to proceed. Further, if the startValue was forcefed or transferred
                           from a previous call, startValue may also not be in pixels. Unit conversion logic therefore consists of two steps:
                           1) Calculating the ratio of %/em/rem/vh/vw relative to pixels
                           2) Converting startValue into the same unit of measurement as endValue based on these ratios. */
                        /* Unit conversion ratios are calculated by inserting a sibling node next to the target node, copying over its position property,
                           setting values with the target unit type then comparing the returned pixel value. */
                        /* Note: Even if only one of these unit types is being animated, all unit ratios are calculated at once since the overhead
                           of batching the SETs and GETs together upfront outweights the potential overhead
                           of layout thrashing caused by re-querying for uncalculated ratios for subsequently-processed properties. */
                        /* Todo: Shift this logic into the calls' first tick instance so that it's synced with RAF. */
                        function calculateUnitRatios () {

                            /************************
                                Same Ratio Checks
                            ************************/

                            /* The properties below are used to determine whether the element differs sufficiently from this call's
                               previously iterated element to also differ in its unit conversion ratios. If the properties match up with those
                               of the prior element, the prior element's conversion ratios are used. Like most optimizations in Velocity,
                               this is done to minimize DOM querying. */
                            var sameRatioIndicators = {
                                    myParent: element.parentNode || document.body, /* GET */
                                    position: CSS.getPropertyValue(element, "position"), /* GET */
                                    fontSize: CSS.getPropertyValue(element, "fontSize") /* GET */
                                },
                                /* Determine if the same % ratio can be used. % is based on the element's position value and its parent's width and height dimensions. */
                                samePercentRatio = ((sameRatioIndicators.position === callUnitConversionData.lastPosition) && (sameRatioIndicators.myParent === callUnitConversionData.lastParent)),
                                /* Determine if the same em ratio can be used. em is relative to the element's fontSize. */
                                sameEmRatio = (sameRatioIndicators.fontSize === callUnitConversionData.lastFontSize);

                            /* Store these ratio indicators call-wide for the next element to compare against. */
                            callUnitConversionData.lastParent = sameRatioIndicators.myParent;
                            callUnitConversionData.lastPosition = sameRatioIndicators.position;
                            callUnitConversionData.lastFontSize = sameRatioIndicators.fontSize;

                            /***************************
                               Element-Specific Units
                            ***************************/

                            /* Note: IE8 rounds to the nearest pixel when returning CSS values, thus we perform conversions using a measurement
                               of 100 (instead of 1) to give our ratios a precision of at least 2 decimal values. */
                            var measurement = 100,
                                unitRatios = {};

                            if (!sameEmRatio || !samePercentRatio) {
                                var dummy = Data(element).isSVG ? document.createElementNS("http://www.w3.org/2000/svg", "rect") : document.createElement("div");

                                Velocity.init(dummy);
                                sameRatioIndicators.myParent.appendChild(dummy);

                                /* To accurately and consistently calculate conversion ratios, the element's cascaded overflow and box-sizing are stripped.
                                   Similarly, since width/height can be artificially constrained by their min-/max- equivalents, these are controlled for as well. */
                                /* Note: Overflow must be also be controlled for per-axis since the overflow property overwrites its per-axis values. */
                                $.each([ "overflow", "overflowX", "overflowY" ], function(i, property) {
                                    Velocity.CSS.setPropertyValue(dummy, property, "hidden");
                                });
                                Velocity.CSS.setPropertyValue(dummy, "position", sameRatioIndicators.position);
                                Velocity.CSS.setPropertyValue(dummy, "fontSize", sameRatioIndicators.fontSize);
                                Velocity.CSS.setPropertyValue(dummy, "boxSizing", "content-box");

                                /* width and height act as our proxy properties for measuring the horizontal and vertical % ratios. */
                                $.each([ "minWidth", "maxWidth", "width", "minHeight", "maxHeight", "height" ], function(i, property) {
                                    Velocity.CSS.setPropertyValue(dummy, property, measurement + "%");
                                });
                                /* paddingLeft arbitrarily acts as our proxy property for the em ratio. */
                                Velocity.CSS.setPropertyValue(dummy, "paddingLeft", measurement + "em");

                                /* Divide the returned value by the measurement to get the ratio between 1% and 1px. Default to 1 since working with 0 can produce Infinite. */
                                unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth = (parseFloat(CSS.getPropertyValue(dummy, "width", null, true)) || 1) / measurement; /* GET */
                                unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight = (parseFloat(CSS.getPropertyValue(dummy, "height", null, true)) || 1) / measurement; /* GET */
                                unitRatios.emToPx = callUnitConversionData.lastEmToPx = (parseFloat(CSS.getPropertyValue(dummy, "paddingLeft")) || 1) / measurement; /* GET */

                                sameRatioIndicators.myParent.removeChild(dummy);
                            } else {
                                unitRatios.emToPx = callUnitConversionData.lastEmToPx;
                                unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth;
                                unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight;
                            }

                            /***************************
                               Element-Agnostic Units
                            ***************************/

                            /* Whereas % and em ratios are determined on a per-element basis, the rem unit only needs to be checked
                               once per call since it's exclusively dependant upon document.body's fontSize. If this is the first time
                               that calculateUnitRatios() is being run during this call, remToPx will still be set to its default value of null,
                               so we calculate it now. */
                            if (callUnitConversionData.remToPx === null) {
                                /* Default to browsers' default fontSize of 16px in the case of 0. */
                                callUnitConversionData.remToPx = parseFloat(CSS.getPropertyValue(document.body, "fontSize")) || 16; /* GET */
                            }

                            /* Similarly, viewport units are %-relative to the window's inner dimensions. */
                            if (callUnitConversionData.vwToPx === null) {
                                callUnitConversionData.vwToPx = parseFloat(window.innerWidth) / 100; /* GET */
                                callUnitConversionData.vhToPx = parseFloat(window.innerHeight) / 100; /* GET */
                            }

                            unitRatios.remToPx = callUnitConversionData.remToPx;
                            unitRatios.vwToPx = callUnitConversionData.vwToPx;
                            unitRatios.vhToPx = callUnitConversionData.vhToPx;

                            if (Velocity.debug >= 1) console.log("Unit ratios: " + JSON.stringify(unitRatios), element);

                            return unitRatios;
                        }

                        /********************
                           Unit Conversion
                        ********************/

                        /* The * and / operators, which are not passed in with an associated unit, inherently use startValue's unit. Skip value and unit conversion. */
                        if (/[\/*]/.test(operator)) {
                            endValueUnitType = startValueUnitType;
                        /* If startValue and endValue differ in unit type, convert startValue into the same unit type as endValue so that if endValueUnitType
                           is a relative unit (%, em, rem), the values set during tweening will continue to be accurately relative even if the metrics they depend
                           on are dynamically changing during the course of the animation. Conversely, if we always normalized into px and used px for setting values, the px ratio
                           would become stale if the original unit being animated toward was relative and the underlying metrics change during the animation. */
                        /* Since 0 is 0 in any unit type, no conversion is necessary when startValue is 0 -- we just start at 0 with endValueUnitType. */
                        } else if ((startValueUnitType !== endValueUnitType) && startValue !== 0) {
                            /* Unit conversion is also skipped when endValue is 0, but *startValueUnitType* must be used for tween values to remain accurate. */
                            /* Note: Skipping unit conversion here means that if endValueUnitType was originally a relative unit, the animation won't relatively
                               match the underlying metrics if they change, but this is acceptable since we're animating toward invisibility instead of toward visibility,
                               which remains past the point of the animation's completion. */
                            if (endValue === 0) {
                                endValueUnitType = startValueUnitType;
                            } else {
                                /* By this point, we cannot avoid unit conversion (it's undesirable since it causes layout thrashing).
                                   If we haven't already, we trigger calculateUnitRatios(), which runs once per element per call. */
                                elementUnitConversionData = elementUnitConversionData || calculateUnitRatios();

                                /* The following RegEx matches CSS properties that have their % values measured relative to the x-axis. */
                                /* Note: W3C spec mandates that all of margin and padding's properties (even top and bottom) are %-relative to the *width* of the parent element. */
                                var axis = (/margin|padding|left|right|width|text|word|letter/i.test(property) || /X$/.test(property) || property === "x") ? "x" : "y";

                                /* In order to avoid generating n^2 bespoke conversion functions, unit conversion is a two-step process:
                                   1) Convert startValue into pixels. 2) Convert this new pixel value into endValue's unit type. */
                                switch (startValueUnitType) {
                                    case "%":
                                        /* Note: translateX and translateY are the only properties that are %-relative to an element's own dimensions -- not its parent's dimensions.
                                           Velocity does not include a special conversion process to account for this behavior. Therefore, animating translateX/Y from a % value
                                           to a non-% value will produce an incorrect start value. Fortunately, this sort of cross-unit conversion is rarely done by users in practice. */
                                        startValue *= (axis === "x" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);
                                        break;

                                    case "px":
                                        /* px acts as our midpoint in the unit conversion process; do nothing. */
                                        break;

                                    default:
                                        startValue *= elementUnitConversionData[startValueUnitType + "ToPx"];
                                }

                                /* Invert the px ratios to convert into to the target unit. */
                                switch (endValueUnitType) {
                                    case "%":
                                        startValue *= 1 / (axis === "x" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);
                                        break;

                                    case "px":
                                        /* startValue is already in px, do nothing; we're done. */
                                        break;

                                    default:
                                        startValue *= 1 / elementUnitConversionData[endValueUnitType + "ToPx"];
                                }
                            }
                        }

                        /*********************
                           Relative Values
                        *********************/

                        /* Operator logic must be performed last since it requires unit-normalized start and end values. */
                        /* Note: Relative *percent values* do not behave how most people think; while one would expect "+=50%"
                           to increase the property 1.5x its current value, it in fact increases the percent units in absolute terms:
                           50 points is added on top of the current % value. */
                        switch (operator) {
                            case "+":
                                endValue = startValue + endValue;
                                break;

                            case "-":
                                endValue = startValue - endValue;
                                break;

                            case "*":
                                endValue = startValue * endValue;
                                break;

                            case "/":
                                endValue = startValue / endValue;
                                break;
                        }

                        /**************************
                           tweensContainer Push
                        **************************/

                        /* Construct the per-property tween object, and push it to the element's tweensContainer. */
                        tweensContainer[property] = {
                            rootPropertyValue: rootPropertyValue,
                            startValue: startValue,
                            currentValue: startValue,
                            endValue: endValue,
                            unitType: endValueUnitType,
                            easing: easing
                        };

                        if (Velocity.debug) console.log("tweensContainer (" + property + "): " + JSON.stringify(tweensContainer[property]), element);
                    }

                    /* Along with its property data, store a reference to the element itself onto tweensContainer. */
                    tweensContainer.element = element;
                }

                /*****************
                    Call Push
                *****************/

                /* Note: tweensContainer can be empty if all of the properties in this call's property map were skipped due to not
                   being supported by the browser. The element property is used for checking that the tweensContainer has been appended to. */
                if (tweensContainer.element) {
                    /* Apply the "velocity-animating" indicator class. */
                    CSS.Values.addClass(element, "velocity-animating");

                    /* The call array houses the tweensContainers for each element being animated in the current call. */
                    call.push(tweensContainer);

                    /* Store the tweensContainer and options if we're working on the default effects queue, so that they can be used by the reverse command. */
                    if (opts.queue === "") {
                        Data(element).tweensContainer = tweensContainer;
                        Data(element).opts = opts;
                    }

                    /* Switch on the element's animating flag. */
                    Data(element).isAnimating = true;

                    /* Once the final element in this call's element set has been processed, push the call array onto
                       Velocity.State.calls for the animation tick to immediately begin processing. */
                    if (elementsIndex === elementsLength - 1) {
                        /* To speed up iterating over this array, it is compacted (falsey items -- calls that have completed -- are removed)
                           when its length has ballooned to a point that can impact tick performance. This only becomes necessary when animation
                           has been continuous with many elements over a long period of time; whenever all active calls are completed, completeCall() clears Velocity.State.calls. */
                        if (Velocity.State.calls.length > 10000) {
                            Velocity.State.calls = compactSparseArray(Velocity.State.calls);
                        }

                        /* Add the current call plus its associated metadata (the element set and the call's options) onto the global call container.
                           Anything on this call container is subjected to tick() processing. */
                        Velocity.State.calls.push([ call, elements, opts, null, promiseData.resolver ]);

                        /* If the animation tick isn't running, start it. (Velocity shuts it off when there are no active calls to process.) */
                        if (Velocity.State.isTicking === false) {
                            Velocity.State.isTicking = true;

                            /* Start the tick loop. */
                            tick();
                        }
                    } else {
                        elementsIndex++;
                    }
                }
            }

            /* When the queue option is set to false, the call skips the element's queue and fires immediately. */
            if (opts.queue === false) {
                /* Since this buildQueue call doesn't respect the element's existing queue (which is where a delay option would have been appended),
                   we manually inject the delay property here with an explicit setTimeout. */
                if (opts.delay) {
                    setTimeout(buildQueue, opts.delay);
                } else {
                    buildQueue();
                }
            /* Otherwise, the call undergoes element queueing as normal. */
            /* Note: To interoperate with jQuery, Velocity uses jQuery's own $.queue() stack for queuing logic. */
            } else {
                $.queue(element, opts.queue, function(next, clearQueue) {
                    /* If the clearQueue flag was passed in by the stop command, resolve this call's promise. (Promises can only be resolved once,
                       so it's fine if this is repeatedly triggered for each element in the associated call.) */
                    if (clearQueue === true) {
                        if (promiseData.promise) {
                            promiseData.resolver(elements);
                        }

                        /* Do not continue with animation queueing. */
                        return true;
                    }

                    /* This flag indicates to the upcoming completeCall() function that this queue entry was initiated by Velocity.
                       See completeCall() for further details. */
                    Velocity.velocityQueueEntryFlag = true;

                    buildQueue(next);
                });
            }

            /*********************
                Auto-Dequeuing
            *********************/

            /* As per jQuery's $.queue() behavior, to fire the first non-custom-queue entry on an element, the element
               must be dequeued if its queue stack consists *solely* of the current call. (This can be determined by checking
               for the "inprogress" item that jQuery prepends to active queue stack arrays.) Regardless, whenever the element's
               queue is further appended with additional items -- including $.delay()'s or even $.animate() calls, the queue's
               first entry is automatically fired. This behavior contrasts that of custom queues, which never auto-fire. */
            /* Note: When an element set is being subjected to a non-parallel Velocity call, the animation will not begin until
               each one of the elements in the set has reached the end of its individually pre-existing queue chain. */
            /* Note: Unfortunately, most people don't fully grasp jQuery's powerful, yet quirky, $.queue() function.
               Lean more here: http://stackoverflow.com/questions/1058158/can-somebody-explain-jquery-queue-to-me */
            if ((opts.queue === "" || opts.queue === "fx") && $.queue(element)[0] !== "inprogress") {
                $.dequeue(element);
            }
        }

        /**************************
           Element Set Iteration
        **************************/

        /* If the "nodeType" property exists on the elements variable, we're animating a single element.
           Place it in an array so that $.each() can iterate over it. */
        $.each(elements, function(i, element) {
            /* Ensure each element in a set has a nodeType (is a real element) to avoid throwing errors. */
            if (Type.isNode(element)) {
                processElement.call(element);
            }
        });

        /******************
           Option: Loop
        ******************/

        /* The loop option accepts an integer indicating how many times the element should loop between the values in the
           current call's properties map and the element's property values prior to this call. */
        /* Note: The loop option's logic is performed here -- after element processing -- because the current call needs
           to undergo its queue insertion prior to the loop option generating its series of constituent "reverse" calls,
           which chain after the current call. Two reverse calls (two "alternations") constitute one loop. */
        var opts = $.extend({}, Velocity.defaults, options),
            reverseCallsCount;

        opts.loop = parseInt(opts.loop);
        reverseCallsCount = (opts.loop * 2) - 1;

        if (opts.loop) {
            /* Double the loop count to convert it into its appropriate number of "reverse" calls.
               Subtract 1 from the resulting value since the current call is included in the total alternation count. */
            for (var x = 0; x < reverseCallsCount; x++) {
                /* Since the logic for the reverse action occurs inside Queueing and therefore this call's options object
                   isn't parsed until then as well, the current call's delay option must be explicitly passed into the reverse
                   call so that the delay logic that occurs inside *Pre-Queueing* can process it. */
                var reverseOptions = {
                    delay: opts.delay,
                    progress: opts.progress
                };

                /* If a complete callback was passed into this call, transfer it to the loop redirect's final "reverse" call
                   so that it's triggered when the entire redirect is complete (and not when the very first animation is complete). */
                if (x === reverseCallsCount - 1) {
                    reverseOptions.display = opts.display;
                    reverseOptions.visibility = opts.visibility;
                    reverseOptions.complete = opts.complete;
                }

                animate(elements, "reverse", reverseOptions);
            }
        }

        /***************
            Chaining
        ***************/

        /* Return the elements back to the call chain, with wrapped elements taking precedence in case Velocity was called via the $.fn. extension. */
        return getChain();
    };

    /* Turn Velocity into the animation function, extended with the pre-existing Velocity object. */
    Velocity = $.extend(animate, Velocity);
    /* For legacy support, also expose the literal animate method. */
    Velocity.animate = animate;

    /**************
        Timing
    **************/

    /* Ticker function. */
    var ticker = window.requestAnimationFrame || rAFShim;

    /* Inactive browser tabs pause rAF, which results in all active animations immediately sprinting to their completion states when the tab refocuses.
       To get around this, we dynamically switch rAF to setTimeout (which the browser *doesn't* pause) when the tab loses focus. We skip this for mobile
       devices to avoid wasting battery power on inactive tabs. */
    /* Note: Tab focus detection doesn't work on older versions of IE, but that's okay since they don't support rAF to begin with. */
    if (!Velocity.State.isMobile && document.hidden !== undefined) {
        document.addEventListener("visibilitychange", function() {
            /* Reassign the rAF function (which the global tick() function uses) based on the tab's focus state. */
            if (document.hidden) {
                ticker = function(callback) {
                    /* The tick function needs a truthy first argument in order to pass its internal timestamp check. */
                    return setTimeout(function() { callback(true) }, 16);
                };

                /* The rAF loop has been paused by the browser, so we manually restart the tick. */
                tick();
            } else {
                ticker = window.requestAnimationFrame || rAFShim;
            }
        });
    }

    /************
        Tick
    ************/

    /* Note: All calls to Velocity are pushed to the Velocity.State.calls array, which is fully iterated through upon each tick. */
    function tick (timestamp) {
        /* An empty timestamp argument indicates that this is the first tick occurence since ticking was turned on.
           We leverage this metadata to fully ignore the first tick pass since RAF's initial pass is fired whenever
           the browser's next tick sync time occurs, which results in the first elements subjected to Velocity
           calls being animated out of sync with any elements animated immediately thereafter. In short, we ignore
           the first RAF tick pass so that elements being immediately consecutively animated -- instead of simultaneously animated
           by the same Velocity call -- are properly batched into the same initial RAF tick and consequently remain in sync thereafter. */
        if (timestamp) {
            /* We ignore RAF's high resolution timestamp since it can be significantly offset when the browser is
               under high stress; we opt for choppiness over allowing the browser to drop huge chunks of frames. */
            var timeCurrent = (new Date).getTime();

            /********************
               Call Iteration
            ********************/

            /* Iterate through each active call. */
            for (var i = 0, callsLength = Velocity.State.calls.length; i < callsLength; i++) {
                /* When a Velocity call is completed, its Velocity.State.calls entry is set to false. Continue on to the next call. */
                if (!Velocity.State.calls[i]) {
                    continue;
                }

                /************************
                   Call-Wide Variables
                ************************/

                var callContainer = Velocity.State.calls[i],
                    call = callContainer[0],
                    opts = callContainer[2],
                    timeStart = callContainer[3],
                    firstTick = !!timeStart;

                /* If timeStart is undefined, then this is the first time that this call has been processed by tick().
                   We assign timeStart now so that its value is as close to the real animation start time as possible.
                   (Conversely, had timeStart been defined when this call was added to Velocity.State.calls, the delay
                   between that time and now would cause the first few frames of the tween to be skipped since
                   percentComplete is calculated relative to timeStart.) */
                /* Further, subtract 16ms (the approximate resolution of RAF) from the current time value so that the
                   first tick iteration isn't wasted by animating at 0% tween completion, which would produce the
                   same style value as the element's current value. */
                if (!timeStart) {
                    timeStart = Velocity.State.calls[i][3] = timeCurrent - 16;
                }

                /* The tween's completion percentage is relative to the tween's start time, not the tween's start value
                   (which would result in unpredictable tween durations since JavaScript's timers are not particularly accurate).
                   Accordingly, we ensure that percentComplete does not exceed 1. */
                var percentComplete = Math.min((timeCurrent - timeStart) / opts.duration, 1);

                /**********************
                   Element Iteration
                **********************/

                /* For every call, iterate through each of the elements in its set. */
                for (var j = 0, callLength = call.length; j < callLength; j++) {
                    var tweensContainer = call[j],
                        element = tweensContainer.element;

                    /* Check to see if this element has been deleted midway through the animation by checking for the
                       continued existence of its data cache. If it's gone, skip animating this element. */
                    if (!Data(element)) {
                        continue;
                    }

                    var transformPropertyExists = false;

                    /**********************************
                       Display & Visibility Toggling
                    **********************************/

                    /* If the display option is set to non-"none", set it upfront so that the element can become visible before tweening begins.
                       (Otherwise, display's "none" value is set in completeCall() once the animation has completed.) */
                    if (opts.display !== undefined && opts.display !== null && opts.display !== "none") {
                        if (opts.display === "flex") {
                            var flexValues = [ "-webkit-box", "-moz-box", "-ms-flexbox", "-webkit-flex" ];

                            $.each(flexValues, function(i, flexValue) {
                                CSS.setPropertyValue(element, "display", flexValue);
                            });
                        }

                        CSS.setPropertyValue(element, "display", opts.display);
                    }

                    /* Same goes with the visibility option, but its "none" equivalent is "hidden". */
                    if (opts.visibility !== undefined && opts.visibility !== "hidden") {
                        CSS.setPropertyValue(element, "visibility", opts.visibility);
                    }

                    /************************
                       Property Iteration
                    ************************/

                    /* For every element, iterate through each property. */
                    for (var property in tweensContainer) {
                        /* Note: In addition to property tween data, tweensContainer contains a reference to its associated element. */
                        if (property !== "element") {
                            var tween = tweensContainer[property],
                                currentValue,
                                /* Easing can either be a pre-genereated function or a string that references a pre-registered easing
                                   on the Velocity.Easings object. In either case, return the appropriate easing *function*. */
                                easing = Type.isString(tween.easing) ? Velocity.Easings[tween.easing] : tween.easing;

                            /******************************
                               Current Value Calculation
                            ******************************/

                            /* If this is the last tick pass (if we've reached 100% completion for this tween),
                               ensure that currentValue is explicitly set to its target endValue so that it's not subjected to any rounding. */
                            if (percentComplete === 1) {
                                currentValue = tween.endValue;
                            /* Otherwise, calculate currentValue based on the current delta from startValue. */
                            } else {
                                currentValue = tween.startValue + ((tween.endValue - tween.startValue) * easing(percentComplete));

                                /* If no value change is occurring, don't proceed with DOM updating. */
                                if (!firstTick && (currentValue === tween.currentValue)) {
                                    continue;
                                }
                            }

                            tween.currentValue = currentValue;

                            /******************
                               Hooks: Part I
                            ******************/

                            /* For hooked properties, the newly-updated rootPropertyValueCache is cached onto the element so that it can be used
                               for subsequent hooks in this call that are associated with the same root property. If we didn't cache the updated
                               rootPropertyValue, each subsequent update to the root property in this tick pass would reset the previous hook's
                               updates to rootPropertyValue prior to injection. A nice performance byproduct of rootPropertyValue caching is that
                               subsequently chained animations using the same hookRoot but a different hook can use this cached rootPropertyValue. */
                            if (CSS.Hooks.registered[property]) {
                                var hookRoot = CSS.Hooks.getRoot(property),
                                    rootPropertyValueCache = Data(element).rootPropertyValueCache[hookRoot];

                                if (rootPropertyValueCache) {
                                    tween.rootPropertyValue = rootPropertyValueCache;
                                }
                            }

                            /*****************
                                DOM Update
                            *****************/

                            /* setPropertyValue() returns an array of the property name and property value post any normalization that may have been performed. */
                            /* Note: To solve an IE<=8 positioning bug, the unit type is dropped when setting a property value of 0. */
                            var adjustedSetData = CSS.setPropertyValue(element, /* SET */
                                                                       property,
                                                                       tween.currentValue + (parseFloat(currentValue) === 0 ? "" : tween.unitType),
                                                                       tween.rootPropertyValue,
                                                                       tween.scrollData);

                            /*******************
                               Hooks: Part II
                            *******************/

                            /* Now that we have the hook's updated rootPropertyValue (the post-processed value provided by adjustedSetData), cache it onto the element. */
                            if (CSS.Hooks.registered[property]) {
                                /* Since adjustedSetData contains normalized data ready for DOM updating, the rootPropertyValue needs to be re-extracted from its normalized form. ?? */
                                if (CSS.Normalizations.registered[hookRoot]) {
                                    Data(element).rootPropertyValueCache[hookRoot] = CSS.Normalizations.registered[hookRoot]("extract", null, adjustedSetData[1]);
                                } else {
                                    Data(element).rootPropertyValueCache[hookRoot] = adjustedSetData[1];
                                }
                            }

                            /***************
                               Transforms
                            ***************/

                            /* Flag whether a transform property is being animated so that flushTransformCache() can be triggered once this tick pass is complete. */
                            if (adjustedSetData[0] === "transform") {
                                transformPropertyExists = true;
                            }
                        }
                    }

                    /****************
                        mobileHA
                    ****************/

                    /* If mobileHA is enabled, set the translate3d transform to null to force hardware acceleration.
                       It's safe to override this property since Velocity doesn't actually support its animation (hooks are used in its place). */
                    if (opts.mobileHA) {
                        /* Don't set the null transform hack if we've already done so. */
                        if (Data(element).transformCache.translate3d === undefined) {
                            /* All entries on the transformCache object are later concatenated into a single transform string via flushTransformCache(). */
                            Data(element).transformCache.translate3d = "(0px, 0px, 0px)";

                            transformPropertyExists = true;
                        }
                    }

                    if (transformPropertyExists) {
                        CSS.flushTransformCache(element);
                    }
                }

                /* The non-"none" display value is only applied to an element once -- when its associated call is first ticked through.
                   Accordingly, it's set to false so that it isn't re-processed by this call in the next tick. */
                if (opts.display !== undefined && opts.display !== "none") {
                    Velocity.State.calls[i][2].display = false;
                }
                if (opts.visibility !== undefined && opts.visibility !== "hidden") {
                    Velocity.State.calls[i][2].visibility = false;
                }


                /* Pass the elements and the timing data (percentComplete, msRemaining, and timeStart) into the progress callback. */
                if (opts.progress) {
                    opts.progress.call(callContainer[1],
                                       callContainer[1],
                                       percentComplete,
                                       Math.max(0, (timeStart + opts.duration) - timeCurrent),
                                       timeStart);
                }

                /* If this call has finished tweening, pass its index to completeCall() to handle call cleanup. */
                if (percentComplete === 1) {
                    completeCall(i);
                }
            }
        }

        /* Note: completeCall() sets the isTicking flag to false when the last call on Velocity.State.calls has completed. */
        if (Velocity.State.isTicking) {
            ticker(tick);
        }
    }

    /**********************
        Call Completion
    **********************/

    /* Note: Unlike tick(), which processes all active calls at once, call completion is handled on a per-call basis. */
    function completeCall (callIndex, isStopped) {
        /* Ensure the call exists. */
        if (!Velocity.State.calls[callIndex]) {
            return false;
        }

        /* Pull the metadata from the call. */
        var call = Velocity.State.calls[callIndex][0],
            elements = Velocity.State.calls[callIndex][1],
            opts = Velocity.State.calls[callIndex][2],
            resolver = Velocity.State.calls[callIndex][4];

        var remainingCallsExist = false;

        /*************************
           Element Finalization
        *************************/

        for (var i = 0, callLength = call.length; i < callLength; i++) {
            var element = call[i].element;

            /* If the user set display to "none" (intending to hide the element), set it now that the animation has completed. */
            /* Note: display:none isn't set when calls are manually stopped (via Velocity("stop"). */
            /* Note: Display gets ignored with "reverse" calls and infinite loops, since this behavior would be undesirable. */
            if (!isStopped && !opts.loop) {
                if (opts.display === "none") {
                    CSS.setPropertyValue(element, "display", opts.display);
                }

                if (opts.visibility === "hidden") {
                    CSS.setPropertyValue(element, "visibility", opts.visibility);
                }
            }

            /* If the element's queue is empty (if only the "inprogress" item is left at position 0) or if its queue is about to run
               a non-Velocity-initiated entry, turn off the isAnimating flag. A non-Velocity-initiatied queue entry's logic might alter
               an element's CSS values and thereby cause Velocity's cached value data to go stale. To detect if a queue entry was initiated by Velocity,
               we check for the existence of our special Velocity.queueEntryFlag declaration, which minifiers won't rename since the flag
               is assigned to jQuery's global $ object and thus exists out of Velocity's own scope. */
            if (opts.loop !== true && ($.queue(element)[1] === undefined || !/\.velocityQueueEntryFlag/i.test($.queue(element)[1]))) {
                /* The element may have been deleted. Ensure that its data cache still exists before acting on it. */
                if (Data(element)) {
                    Data(element).isAnimating = false;
                    /* Clear the element's rootPropertyValueCache, which will become stale. */
                    Data(element).rootPropertyValueCache = {};

                    var transformHAPropertyExists = false;
                    /* If any 3D transform subproperty is at its default value (regardless of unit type), remove it. */
                    $.each(CSS.Lists.transforms3D, function(i, transformName) {
                        var defaultValue = /^scale/.test(transformName) ? 1 : 0,
                            currentValue = Data(element).transformCache[transformName];

                        if (Data(element).transformCache[transformName] !== undefined && new RegExp("^\\(" + defaultValue + "[^.]").test(currentValue)) {
                            transformHAPropertyExists = true;

                            delete Data(element).transformCache[transformName];
                        }
                    });

                    /* Mobile devices have hardware acceleration removed at the end of the animation in order to avoid hogging the GPU's memory. */
                    if (opts.mobileHA) {
                        transformHAPropertyExists = true;
                        delete Data(element).transformCache.translate3d;
                    }

                    /* Flush the subproperty removals to the DOM. */
                    if (transformHAPropertyExists) {
                        CSS.flushTransformCache(element);
                    }

                    /* Remove the "velocity-animating" indicator class. */
                    CSS.Values.removeClass(element, "velocity-animating");
                }
            }

            /*********************
               Option: Complete
            *********************/

            /* Complete is fired once per call (not once per element) and is passed the full raw DOM element set as both its context and its first argument. */
            /* Note: Callbacks aren't fired when calls are manually stopped (via Velocity("stop"). */
            if (!isStopped && opts.complete && !opts.loop && (i === callLength - 1)) {
                /* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */
                try {
                    opts.complete.call(elements, elements);
                } catch (error) {
                    setTimeout(function() { throw error; }, 1);
                }
            }

            /**********************
               Promise Resolving
            **********************/

            /* Note: Infinite loops don't return promises. */
            if (resolver && opts.loop !== true) {
                resolver(elements);
            }

            /****************************
               Option: Loop (Infinite)
            ****************************/

            if (opts.loop === true && !isStopped) {
                /* If a rotateX/Y/Z property is being animated to 360 deg with loop:true, swap tween start/end values to enable
                   continuous iterative rotation looping. (Otherise, the element would just rotate back and forth.) */
                $.each(Data(element).tweensContainer, function(propertyName, tweenContainer) {
                    if (/^rotate/.test(propertyName) && parseFloat(tweenContainer.endValue) === 360) {
                        tweenContainer.endValue = 0;
                        tweenContainer.startValue = 360;
                    }
                });

                Velocity(element, "reverse", { loop: true, delay: opts.delay });
            }

            /***************
               Dequeueing
            ***************/

            /* Fire the next call in the queue so long as this call's queue wasn't set to false (to trigger a parallel animation),
               which would have already caused the next call to fire. Note: Even if the end of the animation queue has been reached,
               $.dequeue() must still be called in order to completely clear jQuery's animation queue. */
            if (opts.queue !== false) {
                $.dequeue(element, opts.queue);
            }
        }

        /************************
           Calls Array Cleanup
        ************************/

        /* Since this call is complete, set it to false so that the rAF tick skips it. This array is later compacted via compactSparseArray().
          (For performance reasons, the call is set to false instead of being deleted from the array: http://www.html5rocks.com/en/tutorials/speed/v8/) */
        Velocity.State.calls[callIndex] = false;

        /* Iterate through the calls array to determine if this was the final in-progress animation.
           If so, set a flag to end ticking and clear the calls array. */
        for (var j = 0, callsLength = Velocity.State.calls.length; j < callsLength; j++) {
            if (Velocity.State.calls[j] !== false) {
                remainingCallsExist = true;

                break;
            }
        }

        if (remainingCallsExist === false) {
            /* tick() will detect this flag upon its next iteration and subsequently turn itself off. */
            Velocity.State.isTicking = false;

            /* Clear the calls array so that its length is reset. */
            delete Velocity.State.calls;
            Velocity.State.calls = [];
        }
    }

    /******************
        Frameworks
    ******************/

    /* Both jQuery and Zepto allow their $.fn object to be extended to allow wrapped elements to be subjected to plugin calls.
       If either framework is loaded, register a "velocity" extension pointing to Velocity's core animate() method.  Velocity
       also registers itself onto a global container (window.jQuery || window.Zepto || window) so that certain features are
       accessible beyond just a per-element scope. This master object contains an .animate() method, which is later assigned to $.fn
       (if jQuery or Zepto are present). Accordingly, Velocity can both act on wrapped DOM elements and stand alone for targeting raw DOM elements. */
    global.Velocity = Velocity;

    if (global !== window) {
        /* Assign the element function to Velocity's core animate() method. */
        global.fn.velocity = animate;
        /* Assign the object function's defaults to Velocity's global defaults object. */
        global.fn.velocity.defaults = Velocity.defaults;
    }

    /***********************
       Packaged Redirects
    ***********************/

    /* slideUp, slideDown */
    $.each([ "Down", "Up" ], function(i, direction) {
        Velocity.Redirects["slide" + direction] = function (element, options, elementsIndex, elementsSize, elements, promiseData) {
            var opts = $.extend({}, options),
                begin = opts.begin,
                complete = opts.complete,
                computedValues = { height: "", marginTop: "", marginBottom: "", paddingTop: "", paddingBottom: "" },
                inlineValues = {};

            if (opts.display === undefined) {
                /* Show the element before slideDown begins and hide the element after slideUp completes. */
                /* Note: Inline elements cannot have dimensions animated, so they're reverted to inline-block. */
                opts.display = (direction === "Down" ? (Velocity.CSS.Values.getDisplayType(element) === "inline" ? "inline-block" : "block") : "none");
            }

            opts.begin = function() {
                /* If the user passed in a begin callback, fire it now. */
                begin && begin.call(elements, elements);

                /* Cache the elements' original vertical dimensional property values so that we can animate back to them. */
                for (var property in computedValues) {
                    /* Cache all inline values, we reset to upon animation completion. */
                    inlineValues[property] = element.style[property];

                    /* For slideDown, use forcefeeding to animate all vertical properties from 0. For slideUp,
                       use forcefeeding to start from computed values and animate down to 0. */
                    var propertyValue = Velocity.CSS.getPropertyValue(element, property);
                    computedValues[property] = (direction === "Down") ? [ propertyValue, 0 ] : [ 0, propertyValue ];
                }

                /* Force vertical overflow content to clip so that sliding works as expected. */
                inlineValues.overflow = element.style.overflow;
                element.style.overflow = "hidden";
            }

            opts.complete = function() {
                /* Reset element to its pre-slide inline values once its slide animation is complete. */
                for (var property in inlineValues) {
                    element.style[property] = inlineValues[property];
                }

                /* If the user passed in a complete callback, fire it now. */
                complete && complete.call(elements, elements);
                promiseData && promiseData.resolver(elements);
            };

            Velocity(element, computedValues, opts);
        };
    });

    /* fadeIn, fadeOut */
    $.each([ "In", "Out" ], function(i, direction) {
        Velocity.Redirects["fade" + direction] = function (element, options, elementsIndex, elementsSize, elements, promiseData) {
            var opts = $.extend({}, options),
                propertiesMap = { opacity: (direction === "In") ? 1 : 0 },
                originalComplete = opts.complete;

            /* Since redirects are triggered individually for each element in the animated set, avoid repeatedly triggering
               callbacks by firing them only when the final element has been reached. */
            if (elementsIndex !== elementsSize - 1) {
                opts.complete = opts.begin = null;
            } else {
                opts.complete = function() {
                    if (originalComplete) {
                        originalComplete.call(elements, elements);
                    }

                    promiseData && promiseData.resolver(elements);
                }
            }

            /* If a display was passed in, use it. Otherwise, default to "none" for fadeOut or the element-specific default for fadeIn. */
            /* Note: We allow users to pass in "null" to skip display setting altogether. */
            if (opts.display === undefined) {
                opts.display = (direction === "In" ? "auto" : "none");
            }

            Velocity(this, propertiesMap, opts);
        };
    });

    return Velocity;
}((window.jQuery || window.Zepto || window), window, document);
}));

/******************
   Known Issues
******************/

/* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent.
Velocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties
will produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(g,l){var e={},d=e.lib={},m=function(){},k=d.Base={extend:function(a){m.prototype=this;var c=new m;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
p=d.WordArray=k.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=l?c:4*a.length},toString:function(a){return(a||n).stringify(this)},concat:function(a){var c=this.words,q=a.words,f=this.sigBytes;a=a.sigBytes;this.clamp();if(f%4)for(var b=0;b<a;b++)c[f+b>>>2]|=(q[b>>>2]>>>24-8*(b%4)&255)<<24-8*((f+b)%4);else if(65535<q.length)for(b=0;b<a;b+=4)c[f+b>>>2]=q[b>>>2];else c.push.apply(c,q);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=g.ceil(c/4)},clone:function(){var a=k.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b<a;b+=4)c.push(4294967296*g.random()|0);return new p.init(c,a)}}),b=e.enc={},n=b.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++){var d=c[f>>>2]>>>24-8*(f%4)&255;b.push((d>>>4).toString(16));b.push((d&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f+=2)b[f>>>3]|=parseInt(a.substr(f,
2),16)<<24-4*(f%8);return new p.init(b,c/2)}},j=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++)b.push(String.fromCharCode(c[f>>>2]>>>24-8*(f%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f++)b[f>>>2]|=(a.charCodeAt(f)&255)<<24-8*(f%4);return new p.init(b,c)}},h=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(j.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return j.parse(unescape(encodeURIComponent(a)))}},
r=d.BufferedBlockAlgorithm=k.extend({reset:function(){this._data=new p.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,b=c.words,f=c.sigBytes,d=this.blockSize,e=f/(4*d),e=a?g.ceil(e):g.max((e|0)-this._minBufferSize,0);a=e*d;f=g.min(4*a,f);if(a){for(var k=0;k<a;k+=d)this._doProcessBlock(b,k);k=b.splice(0,a);c.sigBytes-=f}return new p.init(k,f)},clone:function(){var a=k.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});d.Hasher=r.extend({cfg:k.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){r.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,d){return(new a.init(d)).finalize(b)}},_createHmacHelper:function(a){return function(b,d){return(new s.HMAC.init(a,
d)).finalize(b)}}});var s=e.algo={};return e}(Math);
(function(){var g=CryptoJS,l=g.lib,e=l.WordArray,d=l.Hasher,m=[],l=g.algo.SHA1=d.extend({_doReset:function(){this._hash=new e.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(d,e){for(var b=this._hash.words,n=b[0],j=b[1],h=b[2],g=b[3],l=b[4],a=0;80>a;a++){if(16>a)m[a]=d[e+a]|0;else{var c=m[a-3]^m[a-8]^m[a-14]^m[a-16];m[a]=c<<1|c>>>31}c=(n<<5|n>>>27)+l+m[a];c=20>a?c+((j&h|~j&g)+1518500249):40>a?c+((j^h^g)+1859775393):60>a?c+((j&h|j&g|h&g)-1894007588):c+((j^h^
g)-899497514);l=g;g=h;h=j<<30|j>>>2;j=n;n=c}b[0]=b[0]+n|0;b[1]=b[1]+j|0;b[2]=b[2]+h|0;b[3]=b[3]+g|0;b[4]=b[4]+l|0},_doFinalize:function(){var d=this._data,e=d.words,b=8*this._nDataBytes,g=8*d.sigBytes;e[g>>>5]|=128<<24-g%32;e[(g+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(g+64>>>9<<4)+15]=b;d.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=d.clone.call(this);e._hash=this._hash.clone();return e}});g.SHA1=d._createHelper(l);g.HmacSHA1=d._createHmacHelper(l)})();
(function(){var g=CryptoJS,l=g.enc.Utf8;g.algo.HMAC=g.lib.Base.extend({init:function(e,d){e=this._hasher=new e.init;"string"==typeof d&&(d=l.parse(d));var g=e.blockSize,k=4*g;d.sigBytes>k&&(d=e.finalize(d));d.clamp();for(var p=this._oKey=d.clone(),b=this._iKey=d.clone(),n=p.words,j=b.words,h=0;h<g;h++)n[h]^=1549556828,j[h]^=909522486;p.sigBytes=b.sigBytes=k;this.reset()},reset:function(){var e=this._hasher;e.reset();e.update(this._iKey)},update:function(e){this._hasher.update(e);return this},finalize:function(e){var d=
this._hasher;e=d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e))}})})();

/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
(function () {
    // Shortcuts
    var C = CryptoJS;
    var C_lib = C.lib;
    var WordArray = C_lib.WordArray;
    var C_enc = C.enc;

    /**
     * Base64 encoding strategy.
     */
    var Base64 = C_enc.Base64 = {
        /**
         * Converts a word array to a Base64 string.
         *
         * @param {WordArray} wordArray The word array.
         *
         * @return {string} The Base64 string.
         *
         * @static
         *
         * @example
         *
         *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);
         */
        stringify: function (wordArray) {
            // Shortcuts
            var words = wordArray.words;
            var sigBytes = wordArray.sigBytes;
            var map = this._map;

            // Clamp excess bits
            wordArray.clamp();

            // Convert
            var base64Chars = [];
            for (var i = 0; i < sigBytes; i += 3) {
                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;
                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;

                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;

                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
                }
            }

            // Add padding
            var paddingChar = map.charAt(64);
            if (paddingChar) {
                while (base64Chars.length % 4) {
                    base64Chars.push(paddingChar);
                }
            }

            return base64Chars.join('');
        },

        /**
         * Converts a Base64 string to a word array.
         *
         * @param {string} base64Str The Base64 string.
         *
         * @return {WordArray} The word array.
         *
         * @static
         *
         * @example
         *
         *     var wordArray = CryptoJS.enc.Base64.parse(base64String);
         */
        parse: function (base64Str) {
            // Shortcuts
            var base64StrLength = base64Str.length;
            var map = this._map;

            // Ignore padding
            var paddingChar = map.charAt(64);
            if (paddingChar) {
                var paddingIndex = base64Str.indexOf(paddingChar);
                if (paddingIndex != -1) {
                    base64StrLength = paddingIndex;
                }
            }

            // Convert
            var words = [];
            var nBytes = 0;
            for (var i = 0; i < base64StrLength; i++) {
                if (i % 4) {
                    var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2);
                    var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2);
                    words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);
                    nBytes++;
                }
            }

            return WordArray.create(words, nBytes);
        },

        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
    };
}());

// CodeMirror is the only global var we claim
window.CodeMirror = (function() {
  "use strict";

  // BROWSER SNIFFING

  // Crude, but necessary to handle a number of hard-to-feature-detect
  // bugs and behavior differences.
  var gecko = /gecko\/\d/i.test(navigator.userAgent);
  var ie = /MSIE \d/.test(navigator.userAgent);
  var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
  var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
  var webkit = /WebKit\//.test(navigator.userAgent);
  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
  var chrome = /Chrome\//.test(navigator.userAgent);
  var opera = /Opera\//.test(navigator.userAgent);
  var safari = /Apple Computer/.test(navigator.vendor);
  var khtml = /KHTML\//.test(navigator.userAgent);
  var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
  var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
  var phantom = /PhantomJS/.test(navigator.userAgent);

  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
  // This is woefully incomplete. Suggestions for alternative methods welcome.
  var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
  var mac = ios || /Mac/.test(navigator.platform);
  var windows = /windows/i.test(navigator.platform);

  var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
  if (opera_version) opera_version = Number(opera_version[1]);
  if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
  // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
  var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
  var captureMiddleClick = gecko || (ie && !ie_lt9);

  // Optimize some code when these features are not used
  var sawReadOnlySpans = false, sawCollapsedSpans = false;

  // CONSTRUCTOR

  function CodeMirror(place, options) {
    if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);

    this.options = options = options || {};
    // Determine effective options based on given values and defaults.
    for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
      options[opt] = defaults[opt];
    setGuttersForLineNumbers(options);

    var docStart = typeof options.value == "string" ? 0 : options.value.first;
    var display = this.display = makeDisplay(place, docStart);
    display.wrapper.CodeMirror = this;
    updateGutters(this);
    if (options.autofocus && !mobile) focusInput(this);

    this.state = {keyMaps: [],
                  overlays: [],
                  modeGen: 0,
                  overwrite: false, focused: false,
                  suppressEdits: false, pasteIncoming: false,
                  draggingText: false,
                  highlight: new Delayed()};

    themeChanged(this);
    if (options.lineWrapping)
      this.display.wrapper.className += " CodeMirror-wrap";

    var doc = options.value;
    if (typeof doc == "string") doc = new Doc(options.value, options.mode);
    operation(this, attachDoc)(this, doc);

    // Override magic textarea content restore that IE sometimes does
    // on our hidden textarea on reload
    if (ie) setTimeout(bind(resetInput, this, true), 20);

    registerEventHandlers(this);
    // IE throws unspecified error in certain cases, when
    // trying to access activeElement before onload
    var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
    if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
    else onBlur(this);

    operation(this, function() {
      for (var opt in optionHandlers)
        if (optionHandlers.propertyIsEnumerable(opt))
          optionHandlers[opt](this, options[opt], Init);
      for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
    })();
  }

  // DISPLAY CONSTRUCTOR

  function makeDisplay(place, docStart) {
    var d = {};

    var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
    if (webkit) input.style.width = "1000px";
    else input.setAttribute("wrap", "off");
    // if border: 0; -- iOS fails to open keyboard (issue #1287)
    if (ios) input.style.border = "1px solid black";
    input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");

    // Wraps and hides input textarea
    d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
    // The actual fake scrollbars.
    d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
    d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
    d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
    d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
    // DIVs containing the selection and the actual code
    d.lineDiv = elt("div", null, "CodeMirror-code");
    d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
    // Blinky cursor, and element used to ensure cursor fits at the end of a line
    d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
    // Secondary cursor, shown when on a 'jump' in bi-directional text
    d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
    // Used to measure text size
    d.measure = elt("div", null, "CodeMirror-measure");
    // Wraps everything that needs to exist inside the vertically-padded coordinate system
    d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
                         null, "position: relative; outline: none");
    // Moved around its parent to cover visible view
    d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
    // Set to the height of the text, causes scrolling
    d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
    // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
    d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
    // Will contain the gutters, if any
    d.gutters = elt("div", null, "CodeMirror-gutters");
    d.lineGutter = null;
    // Provides scrolling
    d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
    d.scroller.setAttribute("tabIndex", "-1");
    // The element in which the editor lives.
    d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
                            d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
    // Work around IE7 z-index bug
    if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
    if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);

    // Needed to hide big blue blinking cursor on Mobile Safari
    if (ios) input.style.width = "0px";
    if (!webkit) d.scroller.draggable = true;
    // Needed to handle Tab key in KHTML
    if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
    else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";

    // Current visible range (may be bigger than the view window).
    d.viewOffset = d.lastSizeC = 0;
    d.showingFrom = d.showingTo = docStart;

    // Used to only resize the line number gutter when necessary (when
    // the amount of lines crosses a boundary that makes its width change)
    d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
    // See readInput and resetInput
    d.prevInput = "";
    // Set to true when a non-horizontal-scrolling widget is added. As
    // an optimization, widget aligning is skipped when d is false.
    d.alignWidgets = false;
    // Flag that indicates whether we currently expect input to appear
    // (after some event like 'keypress' or 'input') and are polling
    // intensively.
    d.pollingFast = false;
    // Self-resetting timeout for the poller
    d.poll = new Delayed();

    d.cachedCharWidth = d.cachedTextHeight = null;
    d.measureLineCache = [];
    d.measureLineCachePos = 0;

    // Tracks when resetInput has punted to just putting a short
    // string instead of the (large) selection.
    d.inaccurateSelection = false;

    // Tracks the maximum line length so that the horizontal scrollbar
    // can be kept static when scrolling.
    d.maxLine = null;
    d.maxLineLength = 0;
    d.maxLineChanged = false;

    // Used for measuring wheel scrolling granularity
    d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;

    return d;
  }

  // STATE UPDATES

  // Used to get the editor into a consistent state again when options change.

  function loadMode(cm) {
    cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
    cm.doc.iter(function(line) {
      if (line.stateAfter) line.stateAfter = null;
      if (line.styles) line.styles = null;
    });
    cm.doc.frontier = cm.doc.first;
    startWorker(cm, 100);
    cm.state.modeGen++;
    if (cm.curOp) regChange(cm);
  }

  function wrappingChanged(cm) {
    if (cm.options.lineWrapping) {
      cm.display.wrapper.className += " CodeMirror-wrap";
      cm.display.sizer.style.minWidth = "";
    } else {
      cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
      computeMaxLength(cm);
    }
    estimateLineHeights(cm);
    regChange(cm);
    clearCaches(cm);
    setTimeout(function(){updateScrollbars(cm);}, 100);
  }

  function estimateHeight(cm) {
    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
    return function(line) {
      if (lineIsHidden(cm.doc, line))
        return 0;
      else if (wrapping)
        return (Math.ceil(line.text.length / perLine) || 1) * th;
      else
        return th;
    };
  }

  function estimateLineHeights(cm) {
    var doc = cm.doc, est = estimateHeight(cm);
    doc.iter(function(line) {
      var estHeight = est(line);
      if (estHeight != line.height) updateLineHeight(line, estHeight);
    });
  }

  function keyMapChanged(cm) {
    var map = keyMap[cm.options.keyMap], style = map.style;
    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
      (style ? " cm-keymap-" + style : "");
    cm.state.disableInput = map.disableInput;
  }

  function themeChanged(cm) {
    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
      cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
    clearCaches(cm);
  }

  function guttersChanged(cm) {
    updateGutters(cm);
    regChange(cm);
    setTimeout(function(){alignHorizontally(cm);}, 20);
  }

  function updateGutters(cm) {
    var gutters = cm.display.gutters, specs = cm.options.gutters;
    removeChildren(gutters);
    for (var i = 0; i < specs.length; ++i) {
      var gutterClass = specs[i];
      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
      if (gutterClass == "CodeMirror-linenumbers") {
        cm.display.lineGutter = gElt;
        gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
      }
    }
    gutters.style.display = i ? "" : "none";
  }

  function lineLength(doc, line) {
    if (line.height == 0) return 0;
    var len = line.text.length, merged, cur = line;
    while (merged = collapsedSpanAtStart(cur)) {
      var found = merged.find();
      cur = getLine(doc, found.from.line);
      len += found.from.ch - found.to.ch;
    }
    cur = line;
    while (merged = collapsedSpanAtEnd(cur)) {
      var found = merged.find();
      len -= cur.text.length - found.from.ch;
      cur = getLine(doc, found.to.line);
      len += cur.text.length - found.to.ch;
    }
    return len;
  }

  function computeMaxLength(cm) {
    var d = cm.display, doc = cm.doc;
    d.maxLine = getLine(doc, doc.first);
    d.maxLineLength = lineLength(doc, d.maxLine);
    d.maxLineChanged = true;
    doc.iter(function(line) {
      var len = lineLength(doc, line);
      if (len > d.maxLineLength) {
        d.maxLineLength = len;
        d.maxLine = line;
      }
    });
  }

  // Make sure the gutters options contains the element
  // "CodeMirror-linenumbers" when the lineNumbers option is true.
  function setGuttersForLineNumbers(options) {
    var found = false;
    for (var i = 0; i < options.gutters.length; ++i) {
      if (options.gutters[i] == "CodeMirror-linenumbers") {
        if (options.lineNumbers) found = true;
        else options.gutters.splice(i--, 1);
      }
    }
    if (!found && options.lineNumbers)
      options.gutters.push("CodeMirror-linenumbers");
  }

  // SCROLLBARS

  // Re-synchronize the fake scrollbars with the actual size of the
  // content. Optionally force a scrollTop.
  function updateScrollbars(cm) {
    var d = cm.display, docHeight = cm.doc.height;
    var totalHeight = docHeight + paddingVert(d);
    d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
    d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
    var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
    var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
    var needsV = scrollHeight > (d.scroller.clientHeight + 1);
    if (needsV) {
      d.scrollbarV.style.display = "block";
      d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
      d.scrollbarV.firstChild.style.height =
        (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
    } else d.scrollbarV.style.display = "";
    if (needsH) {
      d.scrollbarH.style.display = "block";
      d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
      d.scrollbarH.firstChild.style.width =
        (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
    } else d.scrollbarH.style.display = "";
    if (needsH && needsV) {
      d.scrollbarFiller.style.display = "block";
      d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
    } else d.scrollbarFiller.style.display = "";
    if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
      d.gutterFiller.style.display = "block";
      d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
      d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
    } else d.gutterFiller.style.display = "";

    if (mac_geLion && scrollbarWidth(d.measure) === 0)
      d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
  }

  function visibleLines(display, doc, viewPort) {
    var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
    if (typeof viewPort == "number") top = viewPort;
    else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
    top = Math.floor(top - paddingTop(display));
    var bottom = Math.ceil(top + height);
    return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
  }

  // LINE NUMBERS

  function alignHorizontally(cm) {
    var display = cm.display;
    if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
    var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
    var gutterW = display.gutters.offsetWidth, l = comp + "px";
    for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
      for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
    }
    if (cm.options.fixedGutter)
      display.gutters.style.left = (comp + gutterW) + "px";
  }

  function maybeUpdateLineNumberWidth(cm) {
    if (!cm.options.lineNumbers) return false;
    var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
    if (last.length != display.lineNumChars) {
      var test = display.measure.appendChild(elt("div", [elt("div", last)],
                                                 "CodeMirror-linenumber CodeMirror-gutter-elt"));
      var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
      display.lineGutter.style.width = "";
      display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
      display.lineNumWidth = display.lineNumInnerWidth + padding;
      display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
      display.lineGutter.style.width = display.lineNumWidth + "px";
      return true;
    }
    return false;
  }

  function lineNumberFor(options, i) {
    return String(options.lineNumberFormatter(i + options.firstLineNumber));
  }
  function compensateForHScroll(display) {
    return getRect(display.scroller).left - getRect(display.sizer).left;
  }

  // DISPLAY DRAWING

  function updateDisplay(cm, changes, viewPort, forced) {
    var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
    var visible = visibleLines(cm.display, cm.doc, viewPort);
    for (;;) {
      if (!updateDisplayInner(cm, changes, visible, forced)) break;
      forced = false;
      updated = true;
      updateSelection(cm);
      updateScrollbars(cm);

      // Clip forced viewport to actual scrollable area
      if (viewPort)
        viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
                            typeof viewPort == "number" ? viewPort : viewPort.top);
      visible = visibleLines(cm.display, cm.doc, viewPort);
      if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
        break;
      changes = [];
    }

    if (updated) {
      signalLater(cm, "update", cm);
      if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
        signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
    }
    return updated;
  }

  // Uses a set of changes plus the current scroll position to
  // determine which DOM updates have to be made, and makes the
  // updates.
  function updateDisplayInner(cm, changes, visible, forced) {
    var display = cm.display, doc = cm.doc;
    if (!display.wrapper.clientWidth) {
      display.showingFrom = display.showingTo = doc.first;
      display.viewOffset = 0;
      return;
    }

    // Bail out if the visible area is already rendered and nothing changed.
    if (!forced && changes.length == 0 &&
        visible.from > display.showingFrom && visible.to < display.showingTo)
      return;

    if (maybeUpdateLineNumberWidth(cm))
      changes = [{from: doc.first, to: doc.first + doc.size}];
    var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
    display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";

    // Used to determine which lines need their line numbers updated
    var positionsChangedFrom = Infinity;
    if (cm.options.lineNumbers)
      for (var i = 0; i < changes.length; ++i)
        if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }

    var end = doc.first + doc.size;
    var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
    var to = Math.min(end, visible.to + cm.options.viewportMargin);
    if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
    if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
    if (sawCollapsedSpans) {
      from = lineNo(visualLine(doc, getLine(doc, from)));
      while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
    }

    // Create a range of theoretically intact lines, and punch holes
    // in that using the change info.
    var intact = [{from: Math.max(display.showingFrom, doc.first),
                   to: Math.min(display.showingTo, end)}];
    if (intact[0].from >= intact[0].to) intact = [];
    else intact = computeIntact(intact, changes);
    // When merged lines are present, we might have to reduce the
    // intact ranges because changes in continued fragments of the
    // intact lines do require the lines to be redrawn.
    if (sawCollapsedSpans)
      for (var i = 0; i < intact.length; ++i) {
        var range = intact[i], merged;
        while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
          var newTo = merged.find().from.line;
          if (newTo > range.from) range.to = newTo;
          else { intact.splice(i--, 1); break; }
        }
      }

    // Clip off the parts that won't be visible
    var intactLines = 0;
    for (var i = 0; i < intact.length; ++i) {
      var range = intact[i];
      if (range.from < from) range.from = from;
      if (range.to > to) range.to = to;
      if (range.from >= range.to) intact.splice(i--, 1);
      else intactLines += range.to - range.from;
    }
    if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
      updateViewOffset(cm);
      return;
    }
    intact.sort(function(a, b) {return a.from - b.from;});

    // Avoid crashing on IE's "unspecified error" when in iframes
    try {
      var focused = document.activeElement;
    } catch(e) {}
    if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
    patchDisplay(cm, from, to, intact, positionsChangedFrom);
    display.lineDiv.style.display = "";
    if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();

    var different = from != display.showingFrom || to != display.showingTo ||
      display.lastSizeC != display.wrapper.clientHeight;
    // This is just a bogus formula that detects when the editor is
    // resized or the font size changes.
    if (different) {
      display.lastSizeC = display.wrapper.clientHeight;
      startWorker(cm, 400);
    }
    display.showingFrom = from; display.showingTo = to;

    updateHeightsInViewport(cm);
    updateViewOffset(cm);

    return true;
  }

  function updateHeightsInViewport(cm) {
    var display = cm.display;
    var prevBottom = display.lineDiv.offsetTop;
    for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
      if (ie_lt8) {
        var bot = node.offsetTop + node.offsetHeight;
        height = bot - prevBottom;
        prevBottom = bot;
      } else {
        var box = getRect(node);
        height = box.bottom - box.top;
      }
      var diff = node.lineObj.height - height;
      if (height < 2) height = textHeight(display);
      if (diff > .001 || diff < -.001) {
        updateLineHeight(node.lineObj, height);
        var widgets = node.lineObj.widgets;
        if (widgets) for (var i = 0; i < widgets.length; ++i)
          widgets[i].height = widgets[i].node.offsetHeight;
      }
    }
  }

  function updateViewOffset(cm) {
    var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
    // Position the mover div to align with the current virtual scroll position
    cm.display.mover.style.top = off + "px";
  }

  function computeIntact(intact, changes) {
    for (var i = 0, l = changes.length || 0; i < l; ++i) {
      var change = changes[i], intact2 = [], diff = change.diff || 0;
      for (var j = 0, l2 = intact.length; j < l2; ++j) {
        var range = intact[j];
        if (change.to <= range.from && change.diff) {
          intact2.push({from: range.from + diff, to: range.to + diff});
        } else if (change.to <= range.from || change.from >= range.to) {
          intact2.push(range);
        } else {
          if (change.from > range.from)
            intact2.push({from: range.from, to: change.from});
          if (change.to < range.to)
            intact2.push({from: change.to + diff, to: range.to + diff});
        }
      }
      intact = intact2;
    }
    return intact;
  }

  function getDimensions(cm) {
    var d = cm.display, left = {}, width = {};
    for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
      left[cm.options.gutters[i]] = n.offsetLeft;
      width[cm.options.gutters[i]] = n.offsetWidth;
    }
    return {fixedPos: compensateForHScroll(d),
            gutterTotalWidth: d.gutters.offsetWidth,
            gutterLeft: left,
            gutterWidth: width,
            wrapperWidth: d.wrapper.clientWidth};
  }

  function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
    var dims = getDimensions(cm);
    var display = cm.display, lineNumbers = cm.options.lineNumbers;
    if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
      removeChildren(display.lineDiv);
    var container = display.lineDiv, cur = container.firstChild;

    function rm(node) {
      var next = node.nextSibling;
      if (webkit && mac && cm.display.currentWheelTarget == node) {
        node.style.display = "none";
        node.lineObj = null;
      } else {
        node.parentNode.removeChild(node);
      }
      return next;
    }

    var nextIntact = intact.shift(), lineN = from;
    cm.doc.iter(from, to, function(line) {
      if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
      if (lineIsHidden(cm.doc, line)) {
        if (line.height != 0) updateLineHeight(line, 0);
        if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
          var w = line.widgets[i];
          if (w.showIfHidden) {
            var prev = cur.previousSibling;
            if (/pre/i.test(prev.nodeName)) {
              var wrap = elt("div", null, null, "position: relative");
              prev.parentNode.replaceChild(wrap, prev);
              wrap.appendChild(prev);
              prev = wrap;
            }
            var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
            if (!w.handleMouseEvents) wnode.ignoreEvents = true;
            positionLineWidget(w, wnode, prev, dims);
          }
        }
      } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
        // This line is intact. Skip to the actual node. Update its
        // line number if needed.
        while (cur.lineObj != line) cur = rm(cur);
        if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
          setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
        cur = cur.nextSibling;
      } else {
        // For lines with widgets, make an attempt to find and reuse
        // the existing element, so that widgets aren't needlessly
        // removed and re-inserted into the dom
        if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
          if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
        // This line needs to be generated.
        var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
        if (lineNode != reuse) {
          container.insertBefore(lineNode, cur);
        } else {
          while (cur != reuse) cur = rm(cur);
          cur = cur.nextSibling;
        }

        lineNode.lineObj = line;
      }
      ++lineN;
    });
    while (cur) cur = rm(cur);
  }

  function buildLineElement(cm, line, lineNo, dims, reuse) {
    var lineElement = lineContent(cm, line);
    var markers = line.gutterMarkers, display = cm.display, wrap;

    if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
      return lineElement;

    // Lines with gutter elements, widgets or a background class need
    // to be wrapped again, and have the extra elements added to the
    // wrapper div

    if (reuse) {
      reuse.alignable = null;
      var isOk = true, widgetsSeen = 0, insertBefore = null;
      for (var n = reuse.firstChild, next; n; n = next) {
        next = n.nextSibling;
        if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
          reuse.removeChild(n);
        } else {
          for (var i = 0; i < line.widgets.length; ++i) {
            var widget = line.widgets[i];
            if (widget.node == n.firstChild) {
              if (!widget.above && !insertBefore) insertBefore = n;
              positionLineWidget(widget, n, reuse, dims);
              ++widgetsSeen;
              break;
            }
          }
          if (i == line.widgets.length) { isOk = false; break; }
        }
      }
      reuse.insertBefore(lineElement, insertBefore);
      if (isOk && widgetsSeen == line.widgets.length) {
        wrap = reuse;
        reuse.className = line.wrapClass || "";
      }
    }
    if (!wrap) {
      wrap = elt("div", null, line.wrapClass, "position: relative");
      wrap.appendChild(lineElement);
    }
    // Kludge to make sure the styled element lies behind the selection (by z-index)
    if (line.bgClass)
      wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
    if (cm.options.lineNumbers || markers) {
      var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
                                             (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
                                         wrap.firstChild);
      if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
      if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
        wrap.lineNumber = gutterWrap.appendChild(
          elt("div", lineNumberFor(cm.options, lineNo),
              "CodeMirror-linenumber CodeMirror-gutter-elt",
              "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
              + display.lineNumInnerWidth + "px"));
      if (markers)
        for (var k = 0; k < cm.options.gutters.length; ++k) {
          var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
          if (found)
            gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
                                       dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
        }
    }
    if (ie_lt8) wrap.style.zIndex = 2;
    if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
      if (!widget.handleMouseEvents) node.ignoreEvents = true;
      positionLineWidget(widget, node, wrap, dims);
      if (widget.above)
        wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
      else
        wrap.appendChild(node);
      signalLater(widget, "redraw");
    }
    return wrap;
  }

  function positionLineWidget(widget, node, wrap, dims) {
    if (widget.noHScroll) {
      (wrap.alignable || (wrap.alignable = [])).push(node);
      var width = dims.wrapperWidth;
      node.style.left = dims.fixedPos + "px";
      if (!widget.coverGutter) {
        width -= dims.gutterTotalWidth;
        node.style.paddingLeft = dims.gutterTotalWidth + "px";
      }
      node.style.width = width + "px";
    }
    if (widget.coverGutter) {
      node.style.zIndex = 5;
      node.style.position = "relative";
      if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
    }
  }

  // SELECTION / CURSOR

  function updateSelection(cm) {
    var display = cm.display;
    var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
    if (collapsed || cm.options.showCursorWhenSelecting)
      updateSelectionCursor(cm);
    else
      display.cursor.style.display = display.otherCursor.style.display = "none";
    if (!collapsed)
      updateSelectionRange(cm);
    else
      display.selectionDiv.style.display = "none";

    // Move the hidden textarea near the cursor to prevent scrolling artifacts
    if (cm.options.moveInputWithCursor) {
      var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
      var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
      display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
                                                        headPos.top + lineOff.top - wrapOff.top)) + "px";
      display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
                                                         headPos.left + lineOff.left - wrapOff.left)) + "px";
    }
  }

  // No selection, plain cursor
  function updateSelectionCursor(cm) {
    var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
    display.cursor.style.left = pos.left + "px";
    display.cursor.style.top = pos.top + "px";
    display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
    display.cursor.style.display = "";

    if (pos.other) {
      display.otherCursor.style.display = "";
      display.otherCursor.style.left = pos.other.left + "px";
      display.otherCursor.style.top = pos.other.top + "px";
      display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
    } else { display.otherCursor.style.display = "none"; }
  }

  // Highlight selection
  function updateSelectionRange(cm) {
    var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
    var fragment = document.createDocumentFragment();
    var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);

    function add(left, top, width, bottom) {
      if (top < 0) top = 0;
      fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
                               "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
                               "px; height: " + (bottom - top) + "px"));
    }

    function drawForLine(line, fromArg, toArg) {
      var lineObj = getLine(doc, line);
      var lineLen = lineObj.text.length;
      var start, end;
      function coords(ch, bias) {
        return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
      }

      iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
        var leftPos = coords(from, "left"), rightPos, left, right;
        if (from == to) {
          rightPos = leftPos;
          left = right = leftPos.left;
        } else {
          rightPos = coords(to - 1, "right");
          if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
          left = leftPos.left;
          right = rightPos.right;
        }
        if (fromArg == null && from == 0) left = pl;
        if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
          add(left, leftPos.top, null, leftPos.bottom);
          left = pl;
          if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
        }
        if (toArg == null && to == lineLen) right = clientWidth;
        if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
          start = leftPos;
        if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
          end = rightPos;
        if (left < pl + 1) left = pl;
        add(left, rightPos.top, right - left, rightPos.bottom);
      });
      return {start: start, end: end};
    }

    if (sel.from.line == sel.to.line) {
      drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
    } else {
      var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
      var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
      var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
      var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
      if (singleVLine) {
        if (leftEnd.top < rightStart.top - 2) {
          add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
          add(pl, rightStart.top, rightStart.left, rightStart.bottom);
        } else {
          add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
        }
      }
      if (leftEnd.bottom < rightStart.top)
        add(pl, leftEnd.bottom, null, rightStart.top);
    }

    removeChildrenAndAdd(display.selectionDiv, fragment);
    display.selectionDiv.style.display = "";
  }

  // Cursor-blinking
  function restartBlink(cm) {
    if (!cm.state.focused) return;
    var display = cm.display;
    clearInterval(display.blinker);
    var on = true;
    display.cursor.style.visibility = display.otherCursor.style.visibility = "";
    display.blinker = setInterval(function() {
      display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
    }, cm.options.cursorBlinkRate);
  }

  // HIGHLIGHT WORKER

  function startWorker(cm, time) {
    if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
      cm.state.highlight.set(time, bind(highlightWorker, cm));
  }

  function highlightWorker(cm) {
    var doc = cm.doc;
    if (doc.frontier < doc.first) doc.frontier = doc.first;
    if (doc.frontier >= cm.display.showingTo) return;
    var end = +new Date + cm.options.workTime;
    var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
    var changed = [], prevChange;
    doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
      if (doc.frontier >= cm.display.showingFrom) { // Visible
        var oldStyles = line.styles;
        line.styles = highlightLine(cm, line, state);
        var ischange = !oldStyles || oldStyles.length != line.styles.length;
        for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
        if (ischange) {
          if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
          else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
        }
        line.stateAfter = copyState(doc.mode, state);
      } else {
        processLine(cm, line, state);
        line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
      }
      ++doc.frontier;
      if (+new Date > end) {
        startWorker(cm, cm.options.workDelay);
        return true;
      }
    });
    if (changed.length)
      operation(cm, function() {
        for (var i = 0; i < changed.length; ++i)
          regChange(this, changed[i].start, changed[i].end);
      })();
  }

  // Finds the line to start with when starting a parse. Tries to
  // find a line with a stateAfter, so that it can start with a
  // valid state. If that fails, it returns the line with the
  // smallest indentation, which tends to need the least context to
  // parse correctly.
  function findStartLine(cm, n, precise) {
    var minindent, minline, doc = cm.doc;
    for (var search = n, lim = n - 100; search > lim; --search) {
      if (search <= doc.first) return doc.first;
      var line = getLine(doc, search - 1);
      if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
      var indented = countColumn(line.text, null, cm.options.tabSize);
      if (minline == null || minindent > indented) {
        minline = search - 1;
        minindent = indented;
      }
    }
    return minline;
  }

  function getStateBefore(cm, n, precise) {
    var doc = cm.doc, display = cm.display;
      if (!doc.mode.startState) return true;
    var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
    if (!state) state = startState(doc.mode);
    else state = copyState(doc.mode, state);
    doc.iter(pos, n, function(line) {
      processLine(cm, line, state);
      var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
      line.stateAfter = save ? copyState(doc.mode, state) : null;
      ++pos;
    });
    return state;
  }

  // POSITION MEASUREMENT

  function paddingTop(display) {return display.lineSpace.offsetTop;}
  function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
  function paddingLeft(display) {
    var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
    return e.offsetLeft;
  }

  function measureChar(cm, line, ch, data, bias) {
    var dir = -1;
    data = data || measureLine(cm, line);

    for (var pos = ch;; pos += dir) {
      var r = data[pos];
      if (r) break;
      if (dir < 0 && pos == 0) dir = 1;
    }
    bias = pos > ch ? "left" : pos < ch ? "right" : bias;
    if (bias == "left" && r.leftSide) r = r.leftSide;
    else if (bias == "right" && r.rightSide) r = r.rightSide;
    return {left: pos < ch ? r.right : r.left,
            right: pos > ch ? r.left : r.right,
            top: r.top,
            bottom: r.bottom};
  }

  function findCachedMeasurement(cm, line) {
    var cache = cm.display.measureLineCache;
    for (var i = 0; i < cache.length; ++i) {
      var memo = cache[i];
      if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
          cm.display.scroller.clientWidth == memo.width &&
          memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
        return memo;
    }
  }

  function clearCachedMeasurement(cm, line) {
    var exists = findCachedMeasurement(cm, line);
    if (exists) exists.text = exists.measure = exists.markedSpans = null;
  }

  function measureLine(cm, line) {
    // First look in the cache
    var cached = findCachedMeasurement(cm, line);
    if (cached) return cached.measure;

    // Failing that, recompute and store result in cache
    var measure = measureLineInner(cm, line);
    var cache = cm.display.measureLineCache;
    var memo = {text: line.text, width: cm.display.scroller.clientWidth,
                markedSpans: line.markedSpans, measure: measure,
                classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
    if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
    else cache.push(memo);
    return measure;
  }

  function measureLineInner(cm, line) {
    var display = cm.display, measure = emptyArray(line.text.length);
    var pre = lineContent(cm, line, measure, true);

    // IE does not cache element positions of inline elements between
    // calls to getBoundingClientRect. This makes the loop below,
    // which gathers the positions of all the characters on the line,
    // do an amount of layout work quadratic to the number of
    // characters. When line wrapping is off, we try to improve things
    // by first subdividing the line into a bunch of inline blocks, so
    // that IE can reuse most of the layout information from caches
    // for those blocks. This does interfere with line wrapping, so it
    // doesn't work when wrapping is on, but in that case the
    // situation is slightly better, since IE does cache line-wrapping
    // information and only recomputes per-line.
    if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
      var fragment = document.createDocumentFragment();
      var chunk = 10, n = pre.childNodes.length;
      for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
        var wrap = elt("div", null, null, "display: inline-block");
        for (var j = 0; j < chunk && n; ++j) {
          wrap.appendChild(pre.firstChild);
          --n;
        }
        fragment.appendChild(wrap);
      }
      pre.appendChild(fragment);
    }

    removeChildrenAndAdd(display.measure, pre);

    var outer = getRect(display.lineDiv);
    var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
    // Work around an IE7/8 bug where it will sometimes have randomly
    // replaced our pre with a clone at this point.
    if (ie_lt9 && display.measure.first != pre)
      removeChildrenAndAdd(display.measure, pre);

    function measureRect(rect) {
      var top = rect.top - outer.top, bot = rect.bottom - outer.top;
      if (bot > maxBot) bot = maxBot;
      if (top < 0) top = 0;
      for (var i = vranges.length - 2; i >= 0; i -= 2) {
        var rtop = vranges[i], rbot = vranges[i+1];
        if (rtop > bot || rbot < top) continue;
        if (rtop <= top && rbot >= bot ||
            top <= rtop && bot >= rbot ||
            Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
          vranges[i] = Math.min(top, rtop);
          vranges[i+1] = Math.max(bot, rbot);
          break;
        }
      }
      if (i < 0) { i = vranges.length; vranges.push(top, bot); }
      return {left: rect.left - outer.left,
              right: rect.right - outer.left,
              top: i, bottom: null};
    }
    function finishRect(rect) {
      rect.bottom = vranges[rect.top+1];
      rect.top = vranges[rect.top];
    }

    for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
      var node = cur, rect = null;
      // A widget might wrap, needs special care
      if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
        if (cur.firstChild.nodeType == 1) node = cur.firstChild;
        var rects = node.getClientRects();
        if (rects.length > 1) {
          rect = data[i] = measureRect(rects[0]);
          rect.rightSide = measureRect(rects[rects.length - 1]);
        }
      }
      if (!rect) rect = data[i] = measureRect(getRect(node));
      if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
      if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
    }
    for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
      finishRect(cur);
      if (cur.leftSide) finishRect(cur.leftSide);
      if (cur.rightSide) finishRect(cur.rightSide);
    }
    return data;
  }

  function measureLineWidth(cm, line) {
    var hasBadSpan = false;
    if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
      var sp = line.markedSpans[i];
      if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
    }
    var cached = !hasBadSpan && findCachedMeasurement(cm, line);
    if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;

    var pre = lineContent(cm, line, null, true);
    var end = pre.appendChild(zeroWidthElement(cm.display.measure));
    removeChildrenAndAdd(cm.display.measure, pre);
    return getRect(end).right - getRect(cm.display.lineDiv).left;
  }

  function clearCaches(cm) {
    cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
    cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
    if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
    cm.display.lineNumChars = null;
  }

  function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
  function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }

  // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
  function intoCoordSystem(cm, lineObj, rect, context) {
    if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
      var size = widgetHeight(lineObj.widgets[i]);
      rect.top += size; rect.bottom += size;
    }
    if (context == "line") return rect;
    if (!context) context = "local";
    var yOff = heightAtLine(cm, lineObj);
    if (context == "local") yOff += paddingTop(cm.display);
    else yOff -= cm.display.viewOffset;
    if (context == "page" || context == "window") {
      var lOff = getRect(cm.display.lineSpace);
      yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
      var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
      rect.left += xOff; rect.right += xOff;
    }
    rect.top += yOff; rect.bottom += yOff;
    return rect;
  }

  // Context may be "window", "page", "div", or "local"/null
  // Result is in "div" coords
  function fromCoordSystem(cm, coords, context) {
    if (context == "div") return coords;
    var left = coords.left, top = coords.top;
    // First move into "page" coordinate system
    if (context == "page") {
      left -= pageScrollX();
      top -= pageScrollY();
    } else if (context == "local" || !context) {
      var localBox = getRect(cm.display.sizer);
      left += localBox.left;
      top += localBox.top;
    }

    var lineSpaceBox = getRect(cm.display.lineSpace);
    return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
  }

  function charCoords(cm, pos, context, lineObj, bias) {
    if (!lineObj) lineObj = getLine(cm.doc, pos.line);
    return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
  }

  function cursorCoords(cm, pos, context, lineObj, measurement) {
    lineObj = lineObj || getLine(cm.doc, pos.line);
    if (!measurement) measurement = measureLine(cm, lineObj);
    function get(ch, right) {
      var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
      if (right) m.left = m.right; else m.right = m.left;
      return intoCoordSystem(cm, lineObj, m, context);
    }
    function getBidi(ch, partPos) {
      var part = order[partPos], right = part.level % 2;
      if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
        part = order[--partPos];
        ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
        right = true;
      } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
        part = order[++partPos];
        ch = bidiLeft(part) - part.level % 2;
        right = false;
      }
      if (right && ch == part.to && ch > part.from) return get(ch - 1);
      return get(ch, right);
    }
    var order = getOrder(lineObj), ch = pos.ch;
    if (!order) return get(ch);
    var partPos = getBidiPartAt(order, ch);
    var val = getBidi(ch, partPos);
    if (bidiOther != null) val.other = getBidi(ch, bidiOther);
    return val;
  }

  function PosWithInfo(line, ch, outside, xRel) {
    var pos = new Pos(line, ch);
    pos.xRel = xRel;
    if (outside) pos.outside = true;
    return pos;
  }

  // Coords must be lineSpace-local
  function coordsChar(cm, x, y) {
    var doc = cm.doc;
    y += cm.display.viewOffset;
    if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
    var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
    if (lineNo > last)
      return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
    if (x < 0) x = 0;

    for (;;) {
      var lineObj = getLine(doc, lineNo);
      var found = coordsCharInner(cm, lineObj, lineNo, x, y);
      var merged = collapsedSpanAtEnd(lineObj);
      var mergedPos = merged && merged.find();
      if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
        lineNo = mergedPos.to.line;
      else
        return found;
    }
  }

  function coordsCharInner(cm, lineObj, lineNo, x, y) {
    var innerOff = y - heightAtLine(cm, lineObj);
    var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
    var measurement = measureLine(cm, lineObj);

    function getX(ch) {
      var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
                            lineObj, measurement);
      wrongLine = true;
      if (innerOff > sp.bottom) return sp.left - adjust;
      else if (innerOff < sp.top) return sp.left + adjust;
      else wrongLine = false;
      return sp.left;
    }

    var bidi = getOrder(lineObj), dist = lineObj.text.length;
    var from = lineLeft(lineObj), to = lineRight(lineObj);
    var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;

    if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
    // Do a binary search between these bounds.
    for (;;) {
      if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
        var ch = x < fromX || x - fromX <= toX - x ? from : to;
        var xDiff = x - (ch == from ? fromX : toX);
        while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
        var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
                              xDiff < 0 ? -1 : xDiff ? 1 : 0);
        return pos;
      }
      var step = Math.ceil(dist / 2), middle = from + step;
      if (bidi) {
        middle = from;
        for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
      }
      var middleX = getX(middle);
      if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
      else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
    }
  }

  var measureText;
  function textHeight(display) {
    if (display.cachedTextHeight != null) return display.cachedTextHeight;
    if (measureText == null) {
      measureText = elt("pre");
      // Measure a bunch of lines, for browsers that compute
      // fractional heights.
      for (var i = 0; i < 49; ++i) {
        measureText.appendChild(document.createTextNode("x"));
        measureText.appendChild(elt("br"));
      }
      measureText.appendChild(document.createTextNode("x"));
    }
    removeChildrenAndAdd(display.measure, measureText);
    var height = measureText.offsetHeight / 50;
    if (height > 3) display.cachedTextHeight = height;
    removeChildren(display.measure);
    return height || 1;
  }

  function charWidth(display) {
    if (display.cachedCharWidth != null) return display.cachedCharWidth;
    var anchor = elt("span", "x");
    var pre = elt("pre", [anchor]);
    removeChildrenAndAdd(display.measure, pre);
    var width = anchor.offsetWidth;
    if (width > 2) display.cachedCharWidth = width;
    return width || 10;
  }

  // OPERATIONS

  // Operations are used to wrap changes in such a way that each
  // change won't have to update the cursor and display (which would
  // be awkward, slow, and error-prone), but instead updates are
  // batched and then all combined and executed at once.

  var nextOpId = 0;
  function startOperation(cm) {
    cm.curOp = {
      // An array of ranges of lines that have to be updated. See
      // updateDisplay.
      changes: [],
      forceUpdate: false,
      updateInput: null,
      userSelChange: null,
      textChanged: null,
      selectionChanged: false,
      cursorActivity: false,
      updateMaxLine: false,
      updateScrollPos: false,
      id: ++nextOpId
    };
    if (!delayedCallbackDepth++) delayedCallbacks = [];
  }

  function endOperation(cm) {
    var op = cm.curOp, doc = cm.doc, display = cm.display;
    cm.curOp = null;

    if (op.updateMaxLine) computeMaxLength(cm);
    if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
      var width = measureLineWidth(cm, display.maxLine);
      display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
      display.maxLineChanged = false;
      var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
      if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
        setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
    }
    var newScrollPos, updated;
    if (op.updateScrollPos) {
      newScrollPos = op.updateScrollPos;
    } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
      var coords = cursorCoords(cm, doc.sel.head);
      newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
    }
    if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
      updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
      if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
    }
    if (!updated && op.selectionChanged) updateSelection(cm);
    if (op.updateScrollPos) {
      display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
      display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
      alignHorizontally(cm);
      if (op.scrollToPos)
        scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
    } else if (newScrollPos) {
      scrollCursorIntoView(cm);
    }
    if (op.selectionChanged) restartBlink(cm);

    if (cm.state.focused && op.updateInput)
      resetInput(cm, op.userSelChange);

    var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
    if (hidden) for (var i = 0; i < hidden.length; ++i)
      if (!hidden[i].lines.length) signal(hidden[i], "hide");
    if (unhidden) for (var i = 0; i < unhidden.length; ++i)
      if (unhidden[i].lines.length) signal(unhidden[i], "unhide");

    var delayed;
    if (!--delayedCallbackDepth) {
      delayed = delayedCallbacks;
      delayedCallbacks = null;
    }
    if (op.textChanged)
      signal(cm, "change", cm, op.textChanged);
    if (op.cursorActivity) signal(cm, "cursorActivity", cm);
    if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
  }

  // Wraps a function in an operation. Returns the wrapped function.
  function operation(cm1, f) {
    return function() {
      var cm = cm1 || this, withOp = !cm.curOp;
      if (withOp) startOperation(cm);
      try { var result = f.apply(cm, arguments); }
      finally { if (withOp) endOperation(cm); }
      return result;
    };
  }
  function docOperation(f) {
    return function() {
      var withOp = this.cm && !this.cm.curOp, result;
      if (withOp) startOperation(this.cm);
      try { result = f.apply(this, arguments); }
      finally { if (withOp) endOperation(this.cm); }
      return result;
    };
  }
  function runInOp(cm, f) {
    var withOp = !cm.curOp, result;
    if (withOp) startOperation(cm);
    try { result = f(); }
    finally { if (withOp) endOperation(cm); }
    return result;
  }

  function regChange(cm, from, to, lendiff) {
    if (from == null) from = cm.doc.first;
    if (to == null) to = cm.doc.first + cm.doc.size;
    cm.curOp.changes.push({from: from, to: to, diff: lendiff});
  }

  // INPUT HANDLING

  function slowPoll(cm) {
    if (cm.display.pollingFast) return;
    cm.display.poll.set(cm.options.pollInterval, function() {
      readInput(cm);
      if (cm.state.focused) slowPoll(cm);
    });
  }

  function fastPoll(cm) {
    var missed = false;
    cm.display.pollingFast = true;
    function p() {
      var changed = readInput(cm);
      if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
      else {cm.display.pollingFast = false; slowPoll(cm);}
    }
    cm.display.poll.set(20, p);
  }

  // prevInput is a hack to work with IME. If we reset the textarea
  // on every change, that breaks IME. So we look for changes
  // compared to the previous content instead. (Modern browsers have
  // events that indicate IME taking place, but these are not widely
  // supported or compatible enough yet to rely on.)
  function readInput(cm) {
    var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
    if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
    var text = input.value;
    if (text == prevInput && posEq(sel.from, sel.to)) return false;
    if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
      resetInput(cm, true);
      return false;
    }

    var withOp = !cm.curOp;
    if (withOp) startOperation(cm);
    sel.shift = false;
    var same = 0, l = Math.min(prevInput.length, text.length);
    while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
    var from = sel.from, to = sel.to;
    if (same < prevInput.length)
      from = Pos(from.line, from.ch - (prevInput.length - same));
    else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
      to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));

    var updateInput = cm.curOp.updateInput;
    var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
                       origin: cm.state.pasteIncoming ? "paste" : "+input"};
    makeChange(cm.doc, changeEvent, "end");
    cm.curOp.updateInput = updateInput;
    signalLater(cm, "inputRead", cm, changeEvent);

    if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
    else cm.display.prevInput = text;
    if (withOp) endOperation(cm);
    cm.state.pasteIncoming = false;
    return true;
  }

  function resetInput(cm, user) {
    var minimal, selected, doc = cm.doc;
    if (!posEq(doc.sel.from, doc.sel.to)) {
      cm.display.prevInput = "";
      minimal = hasCopyEvent &&
        (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
      var content = minimal ? "-" : selected || cm.getSelection();
      cm.display.input.value = content;
      if (cm.state.focused) selectInput(cm.display.input);
      if (ie && !ie_lt9) cm.display.inputHasSelection = content;
    } else if (user) {
      cm.display.prevInput = cm.display.input.value = "";
      if (ie && !ie_lt9) cm.display.inputHasSelection = null;
    }
    cm.display.inaccurateSelection = minimal;
  }

  function focusInput(cm) {
    if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
      cm.display.input.focus();
  }

  function isReadOnly(cm) {
    return cm.options.readOnly || cm.doc.cantEdit;
  }

  // EVENT HANDLERS

  function registerEventHandlers(cm) {
    var d = cm.display;
    on(d.scroller, "mousedown", operation(cm, onMouseDown));
    if (ie)
      on(d.scroller, "dblclick", operation(cm, function(e) {
        if (signalDOMEvent(cm, e)) return;
        var pos = posFromMouse(cm, e);
        if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
        e_preventDefault(e);
        var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
        extendSelection(cm.doc, word.from, word.to);
      }));
    else
      on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
    on(d.lineSpace, "selectstart", function(e) {
      if (!eventInWidget(d, e)) e_preventDefault(e);
    });
    // Gecko browsers fire contextmenu *after* opening the menu, at
    // which point we can't mess with it anymore. Context menu is
    // handled in onMouseDown for Gecko.
    if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});

    on(d.scroller, "scroll", function() {
      if (d.scroller.clientHeight) {
        setScrollTop(cm, d.scroller.scrollTop);
        setScrollLeft(cm, d.scroller.scrollLeft, true);
        signal(cm, "scroll", cm);
      }
    });
    on(d.scrollbarV, "scroll", function() {
      if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
    });
    on(d.scrollbarH, "scroll", function() {
      if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
    });

    on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
    on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});

    function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
    on(d.scrollbarH, "mousedown", reFocus);
    on(d.scrollbarV, "mousedown", reFocus);
    // Prevent wrapper from ever scrolling
    on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });

    var resizeTimer;
    function onResize() {
      if (resizeTimer == null) resizeTimer = setTimeout(function() {
        resizeTimer = null;
        // Might be a text scaling operation, clear size caches.
        d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
        clearCaches(cm);
        runInOp(cm, bind(regChange, cm));
      }, 100);
    }
    on(window, "resize", onResize);
    // Above handler holds on to the editor and its data structures.
    // Here we poll to unregister it when the editor is no longer in
    // the document, so that it can be garbage-collected.
    function unregister() {
      for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
      if (p) setTimeout(unregister, 5000);
      else off(window, "resize", onResize);
    }
    setTimeout(unregister, 5000);

    on(d.input, "keyup", operation(cm, function(e) {
      if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
      if (e.keyCode == 16) cm.doc.sel.shift = false;
    }));
    on(d.input, "input", bind(fastPoll, cm));
    on(d.input, "keydown", operation(cm, onKeyDown));
    on(d.input, "keypress", operation(cm, onKeyPress));
    on(d.input, "focus", bind(onFocus, cm));
    on(d.input, "blur", bind(onBlur, cm));

    function drag_(e) {
      if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
      e_stop(e);
    }
    if (cm.options.dragDrop) {
      on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
      on(d.scroller, "dragenter", drag_);
      on(d.scroller, "dragover", drag_);
      on(d.scroller, "drop", operation(cm, onDrop));
    }
    on(d.scroller, "paste", function(e){
      if (eventInWidget(d, e)) return;
      focusInput(cm);
      fastPoll(cm);
    });
    on(d.input, "paste", function() {
      cm.state.pasteIncoming = true;
      fastPoll(cm);
    });

    function prepareCopy() {
      if (d.inaccurateSelection) {
        d.prevInput = "";
        d.inaccurateSelection = false;
        d.input.value = cm.getSelection();
        selectInput(d.input);
      }
    }
    on(d.input, "cut", prepareCopy);
    on(d.input, "copy", prepareCopy);

    // Needed to handle Tab key in KHTML
    if (khtml) on(d.sizer, "mouseup", function() {
        if (document.activeElement == d.input) d.input.blur();
        focusInput(cm);
    });
  }

  function eventInWidget(display, e) {
    for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
      if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
    }
  }

  function posFromMouse(cm, e, liberal) {
    var display = cm.display;
    if (!liberal) {
      var target = e_target(e);
      if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
          target == display.scrollbarV || target == display.scrollbarV.firstChild ||
          target == display.scrollbarFiller || target == display.gutterFiller) return null;
    }
    var x, y, space = getRect(display.lineSpace);
    // Fails unpredictably on IE[67] when mouse is dragged around quickly.
    try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
    return coordsChar(cm, x - space.left, y - space.top);
  }

  var lastClick, lastDoubleClick;
  function onMouseDown(e) {
    if (signalDOMEvent(this, e)) return;
    var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
    sel.shift = e.shiftKey;

    if (eventInWidget(display, e)) {
      if (!webkit) {
        display.scroller.draggable = false;
        setTimeout(function(){display.scroller.draggable = true;}, 100);
      }
      return;
    }
    if (clickInGutter(cm, e)) return;
    var start = posFromMouse(cm, e);

    switch (e_button(e)) {
    case 3:
      if (captureMiddleClick) onContextMenu.call(cm, cm, e);
      return;
    case 2:
      if (start) extendSelection(cm.doc, start);
      setTimeout(bind(focusInput, cm), 20);
      e_preventDefault(e);
      return;
    }
    // For button 1, if it was clicked inside the editor
    // (posFromMouse returning non-null), we have to adjust the
    // selection.
    if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}

    if (!cm.state.focused) onFocus(cm);

    var now = +new Date, type = "single";
    if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
      type = "triple";
      e_preventDefault(e);
      setTimeout(bind(focusInput, cm), 20);
      selectLine(cm, start.line);
    } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
      type = "double";
      lastDoubleClick = {time: now, pos: start};
      e_preventDefault(e);
      var word = findWordAt(getLine(doc, start.line).text, start);
      extendSelection(cm.doc, word.from, word.to);
    } else { lastClick = {time: now, pos: start}; }

    var last = start;
    if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
        !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
      var dragEnd = operation(cm, function(e2) {
        if (webkit) display.scroller.draggable = false;
        cm.state.draggingText = false;
        off(document, "mouseup", dragEnd);
        off(display.scroller, "drop", dragEnd);
        if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
          e_preventDefault(e2);
          extendSelection(cm.doc, start);
          focusInput(cm);
        }
      });
      // Let the drag handler handle this.
      if (webkit) display.scroller.draggable = true;
      cm.state.draggingText = dragEnd;
      // IE's approach to draggable
      if (display.scroller.dragDrop) display.scroller.dragDrop();
      on(document, "mouseup", dragEnd);
      on(display.scroller, "drop", dragEnd);
      return;
    }
    e_preventDefault(e);
    if (type == "single") extendSelection(cm.doc, clipPos(doc, start));

    var startstart = sel.from, startend = sel.to, lastPos = start;

    function doSelect(cur) {
      if (posEq(lastPos, cur)) return;
      lastPos = cur;

      if (type == "single") {
        extendSelection(cm.doc, clipPos(doc, start), cur);
        return;
      }

      startstart = clipPos(doc, startstart);
      startend = clipPos(doc, startend);
      if (type == "double") {
        var word = findWordAt(getLine(doc, cur.line).text, cur);
        if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
        else extendSelection(cm.doc, startstart, word.to);
      } else if (type == "triple") {
        if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
        else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
      }
    }

    var editorSize = getRect(display.wrapper);
    // Used to ensure timeout re-tries don't fire when another extend
    // happened in the meantime (clearTimeout isn't reliable -- at
    // least on Chrome, the timeouts still happen even when cleared,
    // if the clear happens after their scheduled firing time).
    var counter = 0;

    function extend(e) {
      var curCount = ++counter;
      var cur = posFromMouse(cm, e, true);
      if (!cur) return;
      if (!posEq(cur, last)) {
        if (!cm.state.focused) onFocus(cm);
        last = cur;
        doSelect(cur);
        var visible = visibleLines(display, doc);
        if (cur.line >= visible.to || cur.line < visible.from)
          setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
      } else {
        var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
        if (outside) setTimeout(operation(cm, function() {
          if (counter != curCount) return;
          display.scroller.scrollTop += outside;
          extend(e);
        }), 50);
      }
    }

    function done(e) {
      counter = Infinity;
      e_preventDefault(e);
      focusInput(cm);
      off(document, "mousemove", move);
      off(document, "mouseup", up);
    }

    var move = operation(cm, function(e) {
      if (!ie && !e_button(e)) done(e);
      else extend(e);
    });
    var up = operation(cm, done);
    on(document, "mousemove", move);
    on(document, "mouseup", up);
  }

  function clickInGutter(cm, e) {
    var display = cm.display;
    try { var mX = e.clientX, mY = e.clientY; }
    catch(e) { return false; }

    if (mX >= Math.floor(getRect(display.gutters).right)) return false;
    e_preventDefault(e);
    if (!hasHandler(cm, "gutterClick")) return true;

    var lineBox = getRect(display.lineDiv);
    if (mY > lineBox.bottom) return true;
    mY -= lineBox.top - display.viewOffset;

    for (var i = 0; i < cm.options.gutters.length; ++i) {
      var g = display.gutters.childNodes[i];
      if (g && getRect(g).right >= mX) {
        var line = lineAtHeight(cm.doc, mY);
        var gutter = cm.options.gutters[i];
        signalLater(cm, "gutterClick", cm, line, gutter, e);
        break;
      }
    }
    return true;
  }

  // Kludge to work around strange IE behavior where it'll sometimes
  // re-fire a series of drag-related events right after the drop (#1551)
  var lastDrop = 0;

  function onDrop(e) {
    var cm = this;
    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
      return;
    e_preventDefault(e);
    if (ie) lastDrop = +new Date;
    var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
    if (!pos || isReadOnly(cm)) return;
    if (files && files.length && window.FileReader && window.File) {
      var n = files.length, text = Array(n), read = 0;
      var loadFile = function(file, i) {
        var reader = new FileReader;
        reader.onload = function() {
          text[i] = reader.result;
          if (++read == n) {
            pos = clipPos(cm.doc, pos);
            makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
          }
        };
        reader.readAsText(file);
      };
      for (var i = 0; i < n; ++i) loadFile(files[i], i);
    } else {
      // Don't do a replace if the drop happened inside of the selected text.
      if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
        cm.state.draggingText(e);
        // Ensure the editor is re-focused
        setTimeout(bind(focusInput, cm), 20);
        return;
      }
      try {
        var text = e.dataTransfer.getData("Text");
        if (text) {
          var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
          setSelection(cm.doc, pos, pos);
          if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
          cm.replaceSelection(text, null, "paste");
          focusInput(cm);
          onFocus(cm);
        }
      }
      catch(e){}
    }
  }

  function onDragStart(cm, e) {
    if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;

    var txt = cm.getSelection();
    e.dataTransfer.setData("Text", txt);

    // Use dummy image instead of default browsers image.
    // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
    if (e.dataTransfer.setDragImage && !safari) {
      var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
      if (opera) {
        img.width = img.height = 1;
        cm.display.wrapper.appendChild(img);
        // Force a relayout, or Opera won't use our image for some obscure reason
        img._top = img.offsetTop;
      }
      e.dataTransfer.setDragImage(img, 0, 0);
      if (opera) img.parentNode.removeChild(img);
    }
  }

  function setScrollTop(cm, val) {
    if (Math.abs(cm.doc.scrollTop - val) < 2) return;
    cm.doc.scrollTop = val;
    if (!gecko) updateDisplay(cm, [], val);
    if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
    if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
    if (gecko) updateDisplay(cm, []);
    startWorker(cm, 100);
  }
  function setScrollLeft(cm, val, isScroller) {
    if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
    val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
    cm.doc.scrollLeft = val;
    alignHorizontally(cm);
    if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
    if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
  }

  // Since the delta values reported on mouse wheel events are
  // unstandardized between browsers and even browser versions, and
  // generally horribly unpredictable, this code starts by measuring
  // the scroll effect that the first few mouse wheel events have,
  // and, from that, detects the way it can convert deltas to pixel
  // offsets afterwards.
  //
  // The reason we want to know the amount a wheel event will scroll
  // is that it gives us a chance to update the display before the
  // actual scrolling happens, reducing flickering.

  var wheelSamples = 0, wheelPixelsPerUnit = null;
  // Fill in a browser-detected starting value on browsers where we
  // know one. These don't have to be accurate -- the result of them
  // being wrong would just be a slight flicker on the first wheel
  // scroll (if it is large enough).
  if (ie) wheelPixelsPerUnit = -.53;
  else if (gecko) wheelPixelsPerUnit = 15;
  else if (chrome) wheelPixelsPerUnit = -.7;
  else if (safari) wheelPixelsPerUnit = -1/3;

  function onScrollWheel(cm, e) {
    var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
    if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
    if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
    else if (dy == null) dy = e.wheelDelta;

    var display = cm.display, scroll = display.scroller;
    // Quit if there's nothing to scroll here
    if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
          dy && scroll.scrollHeight > scroll.clientHeight)) return;

    // Webkit browsers on OS X abort momentum scrolls when the target
    // of the scroll event is removed from the scrollable element.
    // This hack (see related code in patchDisplay) makes sure the
    // element is kept around.
    if (dy && mac && webkit) {
      for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
        if (cur.lineObj) {
          cm.display.currentWheelTarget = cur;
          break;
        }
      }
    }

    // On some browsers, horizontal scrolling will cause redraws to
    // happen before the gutter has been realigned, causing it to
    // wriggle around in a most unseemly way. When we have an
    // estimated pixels/delta value, we just handle horizontal
    // scrolling entirely here. It'll be slightly off from native, but
    // better than glitching out.
    if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
      if (dy)
        setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
      setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
      e_preventDefault(e);
      display.wheelStartX = null; // Abort measurement, if in progress
      return;
    }

    if (dy && wheelPixelsPerUnit != null) {
      var pixels = dy * wheelPixelsPerUnit;
      var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
      if (pixels < 0) top = Math.max(0, top + pixels - 50);
      else bot = Math.min(cm.doc.height, bot + pixels + 50);
      updateDisplay(cm, [], {top: top, bottom: bot});
    }

    if (wheelSamples < 20) {
      if (display.wheelStartX == null) {
        display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
        display.wheelDX = dx; display.wheelDY = dy;
        setTimeout(function() {
          if (display.wheelStartX == null) return;
          var movedX = scroll.scrollLeft - display.wheelStartX;
          var movedY = scroll.scrollTop - display.wheelStartY;
          var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
            (movedX && display.wheelDX && movedX / display.wheelDX);
          display.wheelStartX = display.wheelStartY = null;
          if (!sample) return;
          wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
          ++wheelSamples;
        }, 200);
      } else {
        display.wheelDX += dx; display.wheelDY += dy;
      }
    }
  }

  function doHandleBinding(cm, bound, dropShift) {
    if (typeof bound == "string") {
      bound = commands[bound];
      if (!bound) return false;
    }
    // Ensure previous input has been read, so that the handler sees a
    // consistent view of the document
    if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
    var doc = cm.doc, prevShift = doc.sel.shift, done = false;
    try {
      if (isReadOnly(cm)) cm.state.suppressEdits = true;
      if (dropShift) doc.sel.shift = false;
      done = bound(cm) != Pass;
    } finally {
      doc.sel.shift = prevShift;
      cm.state.suppressEdits = false;
    }
    return done;
  }

  function allKeyMaps(cm) {
    var maps = cm.state.keyMaps.slice(0);
    if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
    maps.push(cm.options.keyMap);
    return maps;
  }

  var maybeTransition;
  function handleKeyBinding(cm, e) {
    // Handle auto keymap transitions
    var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
    clearTimeout(maybeTransition);
    if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
      if (getKeyMap(cm.options.keyMap) == startMap) {
        cm.options.keyMap = (next.call ? next.call(null, cm) : next);
        keyMapChanged(cm);
      }
    }, 50);

    var name = keyName(e, true), handled = false;
    if (!name) return false;
    var keymaps = allKeyMaps(cm);

    if (e.shiftKey) {
      // First try to resolve full name (including 'Shift-'). Failing
      // that, see if there is a cursor-motion command (starting with
      // 'go') bound to the keyname without 'Shift-'.
      handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
             || lookupKey(name, keymaps, function(b) {
                  if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
                    return doHandleBinding(cm, b);
                });
    } else {
      handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
    }

    if (handled) {
      e_preventDefault(e);
      restartBlink(cm);
      if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
      signalLater(cm, "keyHandled", cm, name, e);
    }
    return handled;
  }

  function handleCharBinding(cm, e, ch) {
    var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
                            function(b) { return doHandleBinding(cm, b, true); });
    if (handled) {
      e_preventDefault(e);
      restartBlink(cm);
      signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
    }
    return handled;
  }

  var lastStoppedKey = null;
  function onKeyDown(e) {
    var cm = this;
    if (!cm.state.focused) onFocus(cm);
    if (ie && e.keyCode == 27) { e.returnValue = false; }
    if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
    var code = e.keyCode;
    // IE does strange things with escape.
    cm.doc.sel.shift = code == 16 || e.shiftKey;
    // First give onKeyEvent option a chance to handle this.
    var handled = handleKeyBinding(cm, e);
    if (opera) {
      lastStoppedKey = handled ? code : null;
      // Opera has no cut event... we try to at least catch the key combo
      if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
        cm.replaceSelection("");
    }
  }

  function onKeyPress(e) {
    var cm = this;
    if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
    var keyCode = e.keyCode, charCode = e.charCode;
    if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
    if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
    var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
    if (this.options.electricChars && this.doc.mode.electricChars &&
        this.options.smartIndent && !isReadOnly(this) &&
        this.doc.mode.electricChars.indexOf(ch) > -1)
      setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
    if (handleCharBinding(cm, e, ch)) return;
    if (ie && !ie_lt9) cm.display.inputHasSelection = null;
    fastPoll(cm);
  }

  function onFocus(cm) {
    if (cm.options.readOnly == "nocursor") return;
    if (!cm.state.focused) {
      signal(cm, "focus", cm);
      cm.state.focused = true;
      if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
        cm.display.wrapper.className += " CodeMirror-focused";
      resetInput(cm, true);
    }
    slowPoll(cm);
    restartBlink(cm);
  }
  function onBlur(cm) {
    if (cm.state.focused) {
      signal(cm, "blur", cm);
      cm.state.focused = false;
      cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
    }
    clearInterval(cm.display.blinker);
    setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
  }

  var detectingSelectAll;
  function onContextMenu(cm, e) {
    if (signalDOMEvent(cm, e, "contextmenu")) return;
    var display = cm.display, sel = cm.doc.sel;
    if (eventInWidget(display, e)) return;

    var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
    if (!pos || opera) return; // Opera is difficult.
    if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
      operation(cm, setSelection)(cm.doc, pos, pos);

    var oldCSS = display.input.style.cssText;
    display.inputDiv.style.position = "absolute";
    display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
      "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
      "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
    focusInput(cm);
    resetInput(cm, true);
    // Adds "Select all" to context menu in FF
    if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";

    function prepareSelectAllHack() {
      if (display.input.selectionStart != null) {
        var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
        display.prevInput = " ";
        display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
      }
    }
    function rehide() {
      display.inputDiv.style.position = "relative";
      display.input.style.cssText = oldCSS;
      if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
      slowPoll(cm);

      // Try to detect the user choosing select-all
      if (display.input.selectionStart != null) {
        if (!ie || ie_lt9) prepareSelectAllHack();
        clearTimeout(detectingSelectAll);
        var i = 0, poll = function(){
          if (display.prevInput == " " && display.input.selectionStart == 0)
            operation(cm, commands.selectAll)(cm);
          else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
          else resetInput(cm);
        };
        detectingSelectAll = setTimeout(poll, 200);
      }
    }

    if (ie && !ie_lt9) prepareSelectAllHack();
    if (captureMiddleClick) {
      e_stop(e);
      var mouseup = function() {
        off(window, "mouseup", mouseup);
        setTimeout(rehide, 20);
      };
      on(window, "mouseup", mouseup);
    } else {
      setTimeout(rehide, 50);
    }
  }

  // UPDATING

  var changeEnd = CodeMirror.changeEnd = function(change) {
    if (!change.text) return change.to;
    return Pos(change.from.line + change.text.length - 1,
               lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
  };

  // Make sure a position will be valid after the given change.
  function clipPostChange(doc, change, pos) {
    if (!posLess(change.from, pos)) return clipPos(doc, pos);
    var diff = (change.text.length - 1) - (change.to.line - change.from.line);
    if (pos.line > change.to.line + diff) {
      var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
      if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
      return clipToLen(pos, getLine(doc, preLine).text.length);
    }
    if (pos.line == change.to.line + diff)
      return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
                       getLine(doc, change.to.line).text.length - change.to.ch);
    var inside = pos.line - change.from.line;
    return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
  }

  // Hint can be null|"end"|"start"|"around"|{anchor,head}
  function computeSelAfterChange(doc, change, hint) {
    if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
      return {anchor: clipPostChange(doc, change, hint.anchor),
              head: clipPostChange(doc, change, hint.head)};

    if (hint == "start") return {anchor: change.from, head: change.from};

    var end = changeEnd(change);
    if (hint == "around") return {anchor: change.from, head: end};
    if (hint == "end") return {anchor: end, head: end};

    // hint is null, leave the selection alone as much as possible
    var adjustPos = function(pos) {
      if (posLess(pos, change.from)) return pos;
      if (!posLess(change.to, pos)) return end;

      var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
      if (pos.line == change.to.line) ch += end.ch - change.to.ch;
      return Pos(line, ch);
    };
    return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
  }

  function filterChange(doc, change, update) {
    var obj = {
      canceled: false,
      from: change.from,
      to: change.to,
      text: change.text,
      origin: change.origin,
      cancel: function() { this.canceled = true; }
    };
    if (update) obj.update = function(from, to, text, origin) {
      if (from) this.from = clipPos(doc, from);
      if (to) this.to = clipPos(doc, to);
      if (text) this.text = text;
      if (origin !== undefined) this.origin = origin;
    };
    signal(doc, "beforeChange", doc, obj);
    if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);

    if (obj.canceled) return null;
    return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
  }

  // Replace the range from from to to by the strings in replacement.
  // change is a {from, to, text [, origin]} object
  function makeChange(doc, change, selUpdate, ignoreReadOnly) {
    if (doc.cm) {
      if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
      if (doc.cm.state.suppressEdits) return;
    }

    if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
      change = filterChange(doc, change, true);
      if (!change) return;
    }

    // Possibly split or suppress the update based on the presence
    // of read-only spans in its range.
    var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
    if (split) {
      for (var i = split.length - 1; i >= 1; --i)
        makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
      if (split.length)
        makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
    } else {
      makeChangeNoReadonly(doc, change, selUpdate);
    }
  }

  function makeChangeNoReadonly(doc, change, selUpdate) {
    var selAfter = computeSelAfterChange(doc, change, selUpdate);
    addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);

    makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
    var rebased = [];

    linkedDocs(doc, function(doc, sharedHist) {
      if (!sharedHist && indexOf(rebased, doc.history) == -1) {
        rebaseHist(doc.history, change);
        rebased.push(doc.history);
      }
      makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
    });
  }

  function makeChangeFromHistory(doc, type) {
    if (doc.cm && doc.cm.state.suppressEdits) return;

    var hist = doc.history;
    var event = (type == "undo" ? hist.done : hist.undone).pop();
    if (!event) return;

    var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
                anchorAfter: event.anchorBefore, headAfter: event.headBefore,
                generation: hist.generation};
    (type == "undo" ? hist.undone : hist.done).push(anti);
    hist.generation = event.generation || ++hist.maxGeneration;

    var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");

    for (var i = event.changes.length - 1; i >= 0; --i) {
      var change = event.changes[i];
      change.origin = type;
      if (filter && !filterChange(doc, change, false)) {
        (type == "undo" ? hist.done : hist.undone).length = 0;
        return;
      }

      anti.changes.push(historyChangeFromChange(doc, change));

      var after = i ? computeSelAfterChange(doc, change, null)
                    : {anchor: event.anchorBefore, head: event.headBefore};
      makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
      var rebased = [];

      linkedDocs(doc, function(doc, sharedHist) {
        if (!sharedHist && indexOf(rebased, doc.history) == -1) {
          rebaseHist(doc.history, change);
          rebased.push(doc.history);
        }
        makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
      });
    }
  }

  function shiftDoc(doc, distance) {
    function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
    doc.first += distance;
    if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
    doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
    doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
  }

  function makeChangeSingleDoc(doc, change, selAfter, spans) {
    if (doc.cm && !doc.cm.curOp)
      return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);

    if (change.to.line < doc.first) {
      shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
      return;
    }
    if (change.from.line > doc.lastLine()) return;

    // Clip the change to the size of this doc
    if (change.from.line < doc.first) {
      var shift = change.text.length - 1 - (doc.first - change.from.line);
      shiftDoc(doc, shift);
      change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
                text: [lst(change.text)], origin: change.origin};
    }
    var last = doc.lastLine();
    if (change.to.line > last) {
      change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
                text: [change.text[0]], origin: change.origin};
    }

    change.removed = getBetween(doc, change.from, change.to);

    if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
    if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
    else updateDoc(doc, change, spans, selAfter);
  }

  function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
    var doc = cm.doc, display = cm.display, from = change.from, to = change.to;

    var recomputeMaxLength = false, checkWidthStart = from.line;
    if (!cm.options.lineWrapping) {
      checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
      doc.iter(checkWidthStart, to.line + 1, function(line) {
        if (line == display.maxLine) {
          recomputeMaxLength = true;
          return true;
        }
      });
    }

    if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
      cm.curOp.cursorActivity = true;

    updateDoc(doc, change, spans, selAfter, estimateHeight(cm));

    if (!cm.options.lineWrapping) {
      doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
        var len = lineLength(doc, line);
        if (len > display.maxLineLength) {
          display.maxLine = line;
          display.maxLineLength = len;
          display.maxLineChanged = true;
          recomputeMaxLength = false;
        }
      });
      if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
    }

    // Adjust frontier, schedule worker
    doc.frontier = Math.min(doc.frontier, from.line);
    startWorker(cm, 400);

    var lendiff = change.text.length - (to.line - from.line) - 1;
    // Remember that these lines changed, for updating the display
    regChange(cm, from.line, to.line + 1, lendiff);

    if (hasHandler(cm, "change")) {
      var changeObj = {from: from, to: to,
                       text: change.text,
                       removed: change.removed,
                       origin: change.origin};
      if (cm.curOp.textChanged) {
        for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
        cur.next = changeObj;
      } else cm.curOp.textChanged = changeObj;
    }
  }

  function replaceRange(doc, code, from, to, origin) {
    if (!to) to = from;
    if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
    if (typeof code == "string") code = splitLines(code);
    makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
  }

  // POSITION OBJECT

  function Pos(line, ch) {
    if (!(this instanceof Pos)) return new Pos(line, ch);
    this.line = line; this.ch = ch;
  }
  CodeMirror.Pos = Pos;

  function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
  function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
  function copyPos(x) {return Pos(x.line, x.ch);}

  // SELECTION

  function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
  function clipPos(doc, pos) {
    if (pos.line < doc.first) return Pos(doc.first, 0);
    var last = doc.first + doc.size - 1;
    if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
    return clipToLen(pos, getLine(doc, pos.line).text.length);
  }
  function clipToLen(pos, linelen) {
    var ch = pos.ch;
    if (ch == null || ch > linelen) return Pos(pos.line, linelen);
    else if (ch < 0) return Pos(pos.line, 0);
    else return pos;
  }
  function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}

  // If shift is held, this will move the selection anchor. Otherwise,
  // it'll set the whole selection.
  function extendSelection(doc, pos, other, bias) {
    if (doc.sel.shift || doc.sel.extend) {
      var anchor = doc.sel.anchor;
      if (other) {
        var posBefore = posLess(pos, anchor);
        if (posBefore != posLess(other, anchor)) {
          anchor = pos;
          pos = other;
        } else if (posBefore != posLess(pos, other)) {
          pos = other;
        }
      }
      setSelection(doc, anchor, pos, bias);
    } else {
      setSelection(doc, pos, other || pos, bias);
    }
    if (doc.cm) doc.cm.curOp.userSelChange = true;
  }

  function filterSelectionChange(doc, anchor, head) {
    var obj = {anchor: anchor, head: head};
    signal(doc, "beforeSelectionChange", doc, obj);
    if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
    obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
    return obj;
  }

  // Update the selection. Last two args are only used by
  // updateDoc, since they have to be expressed in the line
  // numbers before the update.
  function setSelection(doc, anchor, head, bias, checkAtomic) {
    if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
      var filtered = filterSelectionChange(doc, anchor, head);
      head = filtered.head;
      anchor = filtered.anchor;
    }

    var sel = doc.sel;
    sel.goalColumn = null;
    // Skip over atomic spans.
    if (checkAtomic || !posEq(anchor, sel.anchor))
      anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
    if (checkAtomic || !posEq(head, sel.head))
      head = skipAtomic(doc, head, bias, checkAtomic != "push");

    if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;

    sel.anchor = anchor; sel.head = head;
    var inv = posLess(head, anchor);
    sel.from = inv ? head : anchor;
    sel.to = inv ? anchor : head;

    if (doc.cm)
      doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
        doc.cm.curOp.cursorActivity = true;

    signalLater(doc, "cursorActivity", doc);
  }

  function reCheckSelection(cm) {
    setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
  }

  function skipAtomic(doc, pos, bias, mayClear) {
    var flipped = false, curPos = pos;
    var dir = bias || 1;
    doc.cantEdit = false;
    search: for (;;) {
      var line = getLine(doc, curPos.line);
      if (line.markedSpans) {
        for (var i = 0; i < line.markedSpans.length; ++i) {
          var sp = line.markedSpans[i], m = sp.marker;
          if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
              (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
            if (mayClear) {
              signal(m, "beforeCursorEnter");
              if (m.explicitlyCleared) {
                if (!line.markedSpans) break;
                else {--i; continue;}
              }
            }
            if (!m.atomic) continue;
            var newPos = m.find()[dir < 0 ? "from" : "to"];
            if (posEq(newPos, curPos)) {
              newPos.ch += dir;
              if (newPos.ch < 0) {
                if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
                else newPos = null;
              } else if (newPos.ch > line.text.length) {
                if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
                else newPos = null;
              }
              if (!newPos) {
                if (flipped) {
                  // Driven in a corner -- no valid cursor position found at all
                  // -- try again *with* clearing, if we didn't already
                  if (!mayClear) return skipAtomic(doc, pos, bias, true);
                  // Otherwise, turn off editing until further notice, and return the start of the doc
                  doc.cantEdit = true;
                  return Pos(doc.first, 0);
                }
                flipped = true; newPos = pos; dir = -dir;
              }
            }
            curPos = newPos;
            continue search;
          }
        }
      }
      return curPos;
    }
  }

  // SCROLLING

  function scrollCursorIntoView(cm) {
    var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
    if (!cm.state.focused) return;
    var display = cm.display, box = getRect(display.sizer), doScroll = null;
    if (coords.top + box.top < 0) doScroll = true;
    else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
    if (doScroll != null && !phantom) {
      var hidden = display.cursor.style.display == "none";
      if (hidden) {
        display.cursor.style.display = "";
        display.cursor.style.left = coords.left + "px";
        display.cursor.style.top = (coords.top - display.viewOffset) + "px";
      }
      display.cursor.scrollIntoView(doScroll);
      if (hidden) display.cursor.style.display = "none";
    }
  }

  function scrollPosIntoView(cm, pos, margin) {
    if (margin == null) margin = 0;
    for (;;) {
      var changed = false, coords = cursorCoords(cm, pos);
      var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
      var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
      if (scrollPos.scrollTop != null) {
        setScrollTop(cm, scrollPos.scrollTop);
        if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
      }
      if (scrollPos.scrollLeft != null) {
        setScrollLeft(cm, scrollPos.scrollLeft);
        if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
      }
      if (!changed) return coords;
    }
  }

  function scrollIntoView(cm, x1, y1, x2, y2) {
    var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
    if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
    if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
  }

  function calculateScrollPos(cm, x1, y1, x2, y2) {
    var display = cm.display, snapMargin = textHeight(cm.display);
    if (y1 < 0) y1 = 0;
    var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
    var docBottom = cm.doc.height + paddingVert(display);
    var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
    if (y1 < screentop) {
      result.scrollTop = atTop ? 0 : y1;
    } else if (y2 > screentop + screen) {
      var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
      if (newTop != screentop) result.scrollTop = newTop;
    }

    var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
    x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
    var gutterw = display.gutters.offsetWidth;
    var atLeft = x1 < gutterw + 10;
    if (x1 < screenleft + gutterw || atLeft) {
      if (atLeft) x1 = 0;
      result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
    } else if (x2 > screenw + screenleft - 3) {
      result.scrollLeft = x2 + 10 - screenw;
    }
    return result;
  }

  function updateScrollPos(cm, left, top) {
    cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
                                scrollTop: top == null ? cm.doc.scrollTop : top};
  }

  function addToScrollPos(cm, left, top) {
    var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
    var scroll = cm.display.scroller;
    pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
    pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
  }

  // API UTILITIES

  function indentLine(cm, n, how, aggressive) {
    var doc = cm.doc;
    if (how == null) how = "add";
    if (how == "smart") {
      if (!cm.doc.mode.indent) how = "prev";
      else var state = getStateBefore(cm, n);
    }

    var tabSize = cm.options.tabSize;
    var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
    var curSpaceString = line.text.match(/^\s*/)[0], indentation;
    if (how == "smart") {
      indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
      if (indentation == Pass) {
        if (!aggressive) return;
        how = "prev";
      }
    }
    if (how == "prev") {
      if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
      else indentation = 0;
    } else if (how == "add") {
      indentation = curSpace + cm.options.indentUnit;
    } else if (how == "subtract") {
      indentation = curSpace - cm.options.indentUnit;
    } else if (typeof how == "number") {
      indentation = curSpace + how;
    }
    indentation = Math.max(0, indentation);

    var indentString = "", pos = 0;
    if (cm.options.indentWithTabs)
      for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
    if (pos < indentation) indentString += spaceStr(indentation - pos);

    if (indentString != curSpaceString)
      replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
    line.stateAfter = null;
  }

  function changeLine(cm, handle, op) {
    var no = handle, line = handle, doc = cm.doc;
    if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
    else no = lineNo(handle);
    if (no == null) return null;
    if (op(line, no)) regChange(cm, no, no + 1);
    else return null;
    return line;
  }

  function findPosH(doc, pos, dir, unit, visually) {
    var line = pos.line, ch = pos.ch, origDir = dir;
    var lineObj = getLine(doc, line);
    var possible = true;
    function findNextLine() {
      var l = line + dir;
      if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
      line = l;
      return lineObj = getLine(doc, l);
    }
    function moveOnce(boundToLine) {
      var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
      if (next == null) {
        if (!boundToLine && findNextLine()) {
          if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
          else ch = dir < 0 ? lineObj.text.length : 0;
        } else return (possible = false);
      } else ch = next;
      return true;
    }

    if (unit == "char") moveOnce();
    else if (unit == "column") moveOnce(true);
    else if (unit == "word" || unit == "group") {
      var sawType = null, group = unit == "group";
      for (var first = true;; first = false) {
        if (dir < 0 && !moveOnce(!first)) break;
        var cur = lineObj.text.charAt(ch) || "\n";
        var type = isWordChar(cur) ? "w"
          : !group ? null
          : /\s/.test(cur) ? null
          : "p";
        if (sawType && sawType != type) {
          if (dir < 0) {dir = 1; moveOnce();}
          break;
        }
        if (type) sawType = type;
        if (dir > 0 && !moveOnce(!first)) break;
      }
    }
    var result = skipAtomic(doc, Pos(line, ch), origDir, true);
    if (!possible) result.hitSide = true;
    return result;
  }

  function findPosV(cm, pos, dir, unit) {
    var doc = cm.doc, x = pos.left, y;
    if (unit == "page") {
      var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
      y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
    } else if (unit == "line") {
      y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
    }
    for (;;) {
      var target = coordsChar(cm, x, y);
      if (!target.outside) break;
      if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
      y += dir * 5;
    }
    return target;
  }

  function findWordAt(line, pos) {
    var start = pos.ch, end = pos.ch;
    if (line) {
      if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
      var startChar = line.charAt(start);
      var check = isWordChar(startChar) ? isWordChar
        : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
        : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
      while (start > 0 && check(line.charAt(start - 1))) --start;
      while (end < line.length && check(line.charAt(end))) ++end;
    }
    return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
  }

  function selectLine(cm, line) {
    extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
  }

  // PROTOTYPE

  // The publicly visible API. Note that operation(null, f) means
  // 'wrap f in an operation, performed on its `this` parameter'

  CodeMirror.prototype = {
    constructor: CodeMirror,
    focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},

    setOption: function(option, value) {
      var options = this.options, old = options[option];
      if (options[option] == value && option != "mode") return;
      options[option] = value;
      if (optionHandlers.hasOwnProperty(option))
        operation(this, optionHandlers[option])(this, value, old);
    },

    getOption: function(option) {return this.options[option];},
    getDoc: function() {return this.doc;},

    addKeyMap: function(map, bottom) {
      this.state.keyMaps[bottom ? "push" : "unshift"](map);
    },
    removeKeyMap: function(map) {
      var maps = this.state.keyMaps;
      for (var i = 0; i < maps.length; ++i)
        if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
          maps.splice(i, 1);
          return true;
        }
    },

    addOverlay: operation(null, function(spec, options) {
      var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
      if (mode.startState) throw new Error("Overlays may not be stateful.");
      this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
      this.state.modeGen++;
      regChange(this);
    }),
    removeOverlay: operation(null, function(spec) {
      var overlays = this.state.overlays;
      for (var i = 0; i < overlays.length; ++i) {
        var cur = overlays[i].modeSpec;
        if (cur == spec || typeof spec == "string" && cur.name == spec) {
          overlays.splice(i, 1);
          this.state.modeGen++;
          regChange(this);
          return;
        }
      }
    }),

    indentLine: operation(null, function(n, dir, aggressive) {
      if (typeof dir != "string" && typeof dir != "number") {
        if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
        else dir = dir ? "add" : "subtract";
      }
      if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
    }),
    indentSelection: operation(null, function(how) {
      var sel = this.doc.sel;
      if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
      var e = sel.to.line - (sel.to.ch ? 0 : 1);
      for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
    }),

    // Fetch the parser token for a given character. Useful for hacks
    // that want to inspect the mode state (say, for completion).
    getTokenAt: function(pos, precise) {
      var doc = this.doc;
      pos = clipPos(doc, pos);
      var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
      var line = getLine(doc, pos.line);
      var stream = new StringStream(line.text, this.options.tabSize);
      while (stream.pos < pos.ch && !stream.eol()) {
        stream.start = stream.pos;
        var style = mode.token(stream, state);
      }
      return {start: stream.start,
              end: stream.pos,
              string: stream.current(),
              className: style || null, // Deprecated, use 'type' instead
              type: style || null,
              state: state};
    },

    getTokenTypeAt: function(pos) {
      pos = clipPos(this.doc, pos);
      var styles = getLineStyles(this, getLine(this.doc, pos.line));
      var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
      if (ch == 0) return styles[2];
      for (;;) {
        var mid = (before + after) >> 1;
        if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
        else if (styles[mid * 2 + 1] < ch) before = mid + 1;
        else return styles[mid * 2 + 2];
      }
    },

    getModeAt: function(pos) {
      var mode = this.doc.mode;
      if (!mode.innerMode) return mode;
      return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
    },

    getHelper: function(pos, type) {
      if (!helpers.hasOwnProperty(type)) return;
      var help = helpers[type], mode = this.getModeAt(pos);
      return mode[type] && help[mode[type]] ||
        mode.helperType && help[mode.helperType] ||
        help[mode.name];
    },

    getStateAfter: function(line, precise) {
      var doc = this.doc;
      line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
      return getStateBefore(this, line + 1, precise);
    },

    cursorCoords: function(start, mode) {
      var pos, sel = this.doc.sel;
      if (start == null) pos = sel.head;
      else if (typeof start == "object") pos = clipPos(this.doc, start);
      else pos = start ? sel.from : sel.to;
      return cursorCoords(this, pos, mode || "page");
    },

    charCoords: function(pos, mode) {
      return charCoords(this, clipPos(this.doc, pos), mode || "page");
    },

    coordsChar: function(coords, mode) {
      coords = fromCoordSystem(this, coords, mode || "page");
      return coordsChar(this, coords.left, coords.top);
    },

    lineAtHeight: function(height, mode) {
      height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
      return lineAtHeight(this.doc, height + this.display.viewOffset);
    },
    heightAtLine: function(line, mode) {
      var end = false, last = this.doc.first + this.doc.size - 1;
      if (line < this.doc.first) line = this.doc.first;
      else if (line > last) { line = last; end = true; }
      var lineObj = getLine(this.doc, line);
      return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
        (end ? lineObj.height : 0);
    },

    defaultTextHeight: function() { return textHeight(this.display); },
    defaultCharWidth: function() { return charWidth(this.display); },

    setGutterMarker: operation(null, function(line, gutterID, value) {
      return changeLine(this, line, function(line) {
        var markers = line.gutterMarkers || (line.gutterMarkers = {});
        markers[gutterID] = value;
        if (!value && isEmpty(markers)) line.gutterMarkers = null;
        return true;
      });
    }),

    clearGutter: operation(null, function(gutterID) {
      var cm = this, doc = cm.doc, i = doc.first;
      doc.iter(function(line) {
        if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
          line.gutterMarkers[gutterID] = null;
          regChange(cm, i, i + 1);
          if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
        }
        ++i;
      });
    }),

    addLineClass: operation(null, function(handle, where, cls) {
      return changeLine(this, handle, function(line) {
        var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
        if (!line[prop]) line[prop] = cls;
        else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
        else line[prop] += " " + cls;
        return true;
      });
    }),

    removeLineClass: operation(null, function(handle, where, cls) {
      return changeLine(this, handle, function(line) {
        var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
        var cur = line[prop];
        if (!cur) return false;
        else if (cls == null) line[prop] = null;
        else {
          var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
          if (!found) return false;
          var end = found.index + found[0].length;
          line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
        }
        return true;
      });
    }),

    addLineWidget: operation(null, function(handle, node, options) {
      return addLineWidget(this, handle, node, options);
    }),

    removeLineWidget: function(widget) { widget.clear(); },

    lineInfo: function(line) {
      if (typeof line == "number") {
        if (!isLine(this.doc, line)) return null;
        var n = line;
        line = getLine(this.doc, line);
        if (!line) return null;
      } else {
        var n = lineNo(line);
        if (n == null) return null;
      }
      return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
              textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
              widgets: line.widgets};
    },

    getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},

    addWidget: function(pos, node, scroll, vert, horiz) {
      var display = this.display;
      pos = cursorCoords(this, clipPos(this.doc, pos));
      var top = pos.bottom, left = pos.left;
      node.style.position = "absolute";
      display.sizer.appendChild(node);
      if (vert == "over") {
        top = pos.top;
      } else if (vert == "above" || vert == "near") {
        var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
        hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
        // Default to positioning above (if specified and possible); otherwise default to positioning below
        if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
          top = pos.top - node.offsetHeight;
        else if (pos.bottom + node.offsetHeight <= vspace)
          top = pos.bottom;
        if (left + node.offsetWidth > hspace)
          left = hspace - node.offsetWidth;
      }
      node.style.top = top + "px";
      node.style.left = node.style.right = "";
      if (horiz == "right") {
        left = display.sizer.clientWidth - node.offsetWidth;
        node.style.right = "0px";
      } else {
        if (horiz == "left") left = 0;
        else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
        node.style.left = left + "px";
      }
      if (scroll)
        scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
    },

    triggerOnKeyDown: operation(null, onKeyDown),

    execCommand: function(cmd) {return commands[cmd](this);},

    findPosH: function(from, amount, unit, visually) {
      var dir = 1;
      if (amount < 0) { dir = -1; amount = -amount; }
      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
        cur = findPosH(this.doc, cur, dir, unit, visually);
        if (cur.hitSide) break;
      }
      return cur;
    },

    moveH: operation(null, function(dir, unit) {
      var sel = this.doc.sel, pos;
      if (sel.shift || sel.extend || posEq(sel.from, sel.to))
        pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
      else
        pos = dir < 0 ? sel.from : sel.to;
      extendSelection(this.doc, pos, pos, dir);
    }),

    deleteH: operation(null, function(dir, unit) {
      var sel = this.doc.sel;
      if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
      else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
      this.curOp.userSelChange = true;
    }),

    findPosV: function(from, amount, unit, goalColumn) {
      var dir = 1, x = goalColumn;
      if (amount < 0) { dir = -1; amount = -amount; }
      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
        var coords = cursorCoords(this, cur, "div");
        if (x == null) x = coords.left;
        else coords.left = x;
        cur = findPosV(this, coords, dir, unit);
        if (cur.hitSide) break;
      }
      return cur;
    },

    moveV: operation(null, function(dir, unit) {
      var sel = this.doc.sel;
      var pos = cursorCoords(this, sel.head, "div");
      if (sel.goalColumn != null) pos.left = sel.goalColumn;
      var target = findPosV(this, pos, dir, unit);

      if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
      extendSelection(this.doc, target, target, dir);
      sel.goalColumn = pos.left;
    }),

    toggleOverwrite: function(value) {
      if (value != null && value == this.state.overwrite) return;
      if (this.state.overwrite = !this.state.overwrite)
        this.display.cursor.className += " CodeMirror-overwrite";
      else
        this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
    },
    hasFocus: function() { return this.state.focused; },

    scrollTo: operation(null, function(x, y) {
      updateScrollPos(this, x, y);
    }),
    getScrollInfo: function() {
      var scroller = this.display.scroller, co = scrollerCutOff;
      return {left: scroller.scrollLeft, top: scroller.scrollTop,
              height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
              clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
    },

    scrollIntoView: operation(null, function(pos, margin) {
      if (typeof pos == "number") pos = Pos(pos, 0);
      if (!margin) margin = 0;
      var coords = pos;

      if (!pos || pos.line != null) {
        this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
        this.curOp.scrollToPosMargin = margin;
        coords = cursorCoords(this, this.curOp.scrollToPos);
      }
      var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
      updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
    }),

    setSize: operation(null, function(width, height) {
      function interpret(val) {
        return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
      }
      if (width != null) this.display.wrapper.style.width = interpret(width);
      if (height != null) this.display.wrapper.style.height = interpret(height);
      if (this.options.lineWrapping)
        this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
      this.curOp.forceUpdate = true;
    }),

    operation: function(f){return runInOp(this, f);},

    refresh: operation(null, function() {
      clearCaches(this);
      updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
      regChange(this);
    }),

    swapDoc: operation(null, function(doc) {
      var old = this.doc;
      old.cm = null;
      attachDoc(this, doc);
      clearCaches(this);
      resetInput(this, true);
      updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
      return old;
    }),

    getInputField: function(){return this.display.input;},
    getWrapperElement: function(){return this.display.wrapper;},
    getScrollerElement: function(){return this.display.scroller;},
    getGutterElement: function(){return this.display.gutters;}
  };
  eventMixin(CodeMirror);

  // OPTION DEFAULTS

  var optionHandlers = CodeMirror.optionHandlers = {};

  // The default configuration options.
  var defaults = CodeMirror.defaults = {};

  function option(name, deflt, handle, notOnInit) {
    CodeMirror.defaults[name] = deflt;
    if (handle) optionHandlers[name] =
      notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
  }

  var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};

  // These two are, on init, called from the constructor because they
  // have to be initialized before the editor can start at all.
  option("value", "", function(cm, val) {
    cm.setValue(val);
  }, true);
  option("mode", null, function(cm, val) {
    cm.doc.modeOption = val;
    loadMode(cm);
  }, true);

  option("indentUnit", 2, loadMode, true);
  option("indentWithTabs", false);
  option("smartIndent", true);
  option("tabSize", 4, function(cm) {
    loadMode(cm);
    clearCaches(cm);
    regChange(cm);
  }, true);
  option("electricChars", true);
  option("rtlMoveVisually", !windows);

  option("theme", "default", function(cm) {
    themeChanged(cm);
    guttersChanged(cm);
  }, true);
  option("keyMap", "default", keyMapChanged);
  option("extraKeys", null);

  option("onKeyEvent", null);
  option("onDragEvent", null);

  option("lineWrapping", false, wrappingChanged, true);
  option("gutters", [], function(cm) {
    setGuttersForLineNumbers(cm.options);
    guttersChanged(cm);
  }, true);
  option("fixedGutter", true, function(cm, val) {
    cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
    cm.refresh();
  }, true);
  option("coverGutterNextToScrollbar", false, updateScrollbars, true);
  option("lineNumbers", false, function(cm) {
    setGuttersForLineNumbers(cm.options);
    guttersChanged(cm);
  }, true);
  option("firstLineNumber", 1, guttersChanged, true);
  option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
  option("showCursorWhenSelecting", false, updateSelection, true);

  option("readOnly", false, function(cm, val) {
    if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
    else if (!val) resetInput(cm, true);
  });
  option("dragDrop", true);

  option("cursorBlinkRate", 530);
  option("cursorScrollMargin", 0);
  option("cursorHeight", 1);
  option("workTime", 100);
  option("workDelay", 100);
  option("flattenSpans", true);
  option("pollInterval", 100);
  option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
  option("historyEventDelay", 500);
  option("viewportMargin", 10, function(cm){cm.refresh();}, true);
  option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
  option("moveInputWithCursor", true, function(cm, val) {
    if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
  });

  option("tabindex", null, function(cm, val) {
    cm.display.input.tabIndex = val || "";
  });
  option("autofocus", null);

  // MODE DEFINITION AND QUERYING

  // Known modes, by name and by MIME
  var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};

  CodeMirror.defineMode = function(name, mode) {
    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
    if (arguments.length > 2) {
      mode.dependencies = [];
      for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
    }
    modes[name] = mode;
  };

  CodeMirror.defineMIME = function(mime, spec) {
    mimeModes[mime] = spec;
  };

  CodeMirror.resolveMode = function(spec) {
    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
      spec = mimeModes[spec];
    } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
      var found = mimeModes[spec.name];
      spec = createObj(found, spec);
      spec.name = found.name;
    } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
      return CodeMirror.resolveMode("application/xml");
    }
    if (typeof spec == "string") return {name: spec};
    else return spec || {name: "null"};
  };

  CodeMirror.getMode = function(options, spec) {
    var spec = CodeMirror.resolveMode(spec);
    var mfactory = modes[spec.name];
    if (!mfactory) return CodeMirror.getMode(options, "text/plain");
    var modeObj = mfactory(options, spec);
    if (modeExtensions.hasOwnProperty(spec.name)) {
      var exts = modeExtensions[spec.name];
      for (var prop in exts) {
        if (!exts.hasOwnProperty(prop)) continue;
        if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
        modeObj[prop] = exts[prop];
      }
    }
    modeObj.name = spec.name;

    return modeObj;
  };

  CodeMirror.defineMode("null", function() {
    return {token: function(stream) {stream.skipToEnd();}};
  });
  CodeMirror.defineMIME("text/plain", "null");

  var modeExtensions = CodeMirror.modeExtensions = {};
  CodeMirror.extendMode = function(mode, properties) {
    var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
    copyObj(properties, exts);
  };

  // EXTENSIONS

  CodeMirror.defineExtension = function(name, func) {
    CodeMirror.prototype[name] = func;
  };
  CodeMirror.defineDocExtension = function(name, func) {
    Doc.prototype[name] = func;
  };
  CodeMirror.defineOption = option;

  var initHooks = [];
  CodeMirror.defineInitHook = function(f) {initHooks.push(f);};

  var helpers = CodeMirror.helpers = {};
  CodeMirror.registerHelper = function(type, name, value) {
    if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
    helpers[type][name] = value;
  };

  // UTILITIES

  CodeMirror.isWordChar = isWordChar;

  // MODE STATE HANDLING

  // Utility functions for working with state. Exported because modes
  // sometimes need to do this.
  function copyState(mode, state) {
    if (state === true) return state;
    if (mode.copyState) return mode.copyState(state);
    var nstate = {};
    for (var n in state) {
      var val = state[n];
      if (val instanceof Array) val = val.concat([]);
      nstate[n] = val;
    }
    return nstate;
  }
  CodeMirror.copyState = copyState;

  function startState(mode, a1, a2) {
    return mode.startState ? mode.startState(a1, a2) : true;
  }
  CodeMirror.startState = startState;

  CodeMirror.innerMode = function(mode, state) {
    while (mode.innerMode) {
      var info = mode.innerMode(state);
      if (!info || info.mode == mode) break;
      state = info.state;
      mode = info.mode;
    }
    return info || {mode: mode, state: state};
  };

  // STANDARD COMMANDS

  var commands = CodeMirror.commands = {
    selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
    killLine: function(cm) {
      var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
      if (!sel && cm.getLine(from.line).length == from.ch)
        cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
      else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
    },
    deleteLine: function(cm) {
      var l = cm.getCursor().line;
      cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
    },
    delLineLeft: function(cm) {
      var cur = cm.getCursor();
      cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
    },
    undo: function(cm) {cm.undo();},
    redo: function(cm) {cm.redo();},
    goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
    goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
    goLineStart: function(cm) {
      cm.extendSelection(lineStart(cm, cm.getCursor().line));
    },
    goLineStartSmart: function(cm) {
      var cur = cm.getCursor(), start = lineStart(cm, cur.line);
      var line = cm.getLineHandle(start.line);
      var order = getOrder(line);
      if (!order || order[0].level == 0) {
        var firstNonWS = Math.max(0, line.text.search(/\S/));
        var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
        cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
      } else cm.extendSelection(start);
    },
    goLineEnd: function(cm) {
      cm.extendSelection(lineEnd(cm, cm.getCursor().line));
    },
    goLineRight: function(cm) {
      var top = cm.charCoords(cm.getCursor(), "div").top + 5;
      cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
    },
    goLineLeft: function(cm) {
      var top = cm.charCoords(cm.getCursor(), "div").top + 5;
      cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
    },
    goLineUp: function(cm) {cm.moveV(-1, "line");},
    goLineDown: function(cm) {cm.moveV(1, "line");},
    goPageUp: function(cm) {cm.moveV(-1, "page");},
    goPageDown: function(cm) {cm.moveV(1, "page");},
    goCharLeft: function(cm) {cm.moveH(-1, "char");},
    goCharRight: function(cm) {cm.moveH(1, "char");},
    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
    goColumnRight: function(cm) {cm.moveH(1, "column");},
    goWordLeft: function(cm) {cm.moveH(-1, "word");},
    goGroupRight: function(cm) {cm.moveH(1, "group");},
    goGroupLeft: function(cm) {cm.moveH(-1, "group");},
    goWordRight: function(cm) {cm.moveH(1, "word");},
    delCharBefore: function(cm) {cm.deleteH(-1, "char");},
    delCharAfter: function(cm) {cm.deleteH(1, "char");},
    delWordBefore: function(cm) {cm.deleteH(-1, "word");},
    delWordAfter: function(cm) {cm.deleteH(1, "word");},
    delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
    delGroupAfter: function(cm) {cm.deleteH(1, "group");},
    indentAuto: function(cm) {cm.indentSelection("smart");},
    indentMore: function(cm) {cm.indentSelection("add");},
    indentLess: function(cm) {cm.indentSelection("subtract");},
    insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
    defaultTab: function(cm) {
      if (cm.somethingSelected()) cm.indentSelection("add");
      else cm.replaceSelection("\t", "end", "+input");
    },
    transposeChars: function(cm) {
      var cur = cm.getCursor(), line = cm.getLine(cur.line);
      if (cur.ch > 0 && cur.ch < line.length - 1)
        cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
                        Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
    },
    newlineAndIndent: function(cm) {
      operation(cm, function() {
        cm.replaceSelection("\n", "end", "+input");
        cm.indentLine(cm.getCursor().line, null, true);
      })();
    },
    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
  };

  // STANDARD KEYMAPS

  var keyMap = CodeMirror.keyMap = {};
  keyMap.basic = {
    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
    "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
  };
  // Note that the save and find-related commands aren't defined by
  // default. Unknown commands are simply ignored.
  keyMap.pcDefault = {
    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
    "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
    "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
    "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
    "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
    fallthrough: "basic"
  };
  keyMap.macDefault = {
    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
    "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
    "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
    "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
    "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
    fallthrough: ["basic", "emacsy"]
  };
  keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
  keyMap.emacsy = {
    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
    "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
    "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
  };

  // KEYMAP DISPATCH

  function getKeyMap(val) {
    if (typeof val == "string") return keyMap[val];
    else return val;
  }

  function lookupKey(name, maps, handle) {
    function lookup(map) {
      map = getKeyMap(map);
      var found = map[name];
      if (found === false) return "stop";
      if (found != null && handle(found)) return true;
      if (map.nofallthrough) return "stop";

      var fallthrough = map.fallthrough;
      if (fallthrough == null) return false;
      if (Object.prototype.toString.call(fallthrough) != "[object Array]")
        return lookup(fallthrough);
      for (var i = 0, e = fallthrough.length; i < e; ++i) {
        var done = lookup(fallthrough[i]);
        if (done) return done;
      }
      return false;
    }

    for (var i = 0; i < maps.length; ++i) {
      var done = lookup(maps[i]);
      if (done) return done != "stop";
    }
  }
  function isModifierKey(event) {
    var name = keyNames[event.keyCode];
    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
  }
  function keyName(event, noShift) {
    if (opera && event.keyCode == 34 && event["char"]) return false;
    var name = keyNames[event.keyCode];
    if (name == null || event.altGraphKey) return false;
    if (event.altKey) name = "Alt-" + name;
    if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
    if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
    if (!noShift && event.shiftKey) name = "Shift-" + name;
    return name;
  }
  CodeMirror.lookupKey = lookupKey;
  CodeMirror.isModifierKey = isModifierKey;
  CodeMirror.keyName = keyName;

  // FROMTEXTAREA

  CodeMirror.fromTextArea = function(textarea, options) {
    if (!options) options = {};
    options.value = textarea.value;
    if (!options.tabindex && textarea.tabindex)
      options.tabindex = textarea.tabindex;
    if (!options.placeholder && textarea.placeholder)
      options.placeholder = textarea.placeholder;
    // Set autofocus to true if this textarea is focused, or if it has
    // autofocus and no other element is focused.
    if (options.autofocus == null) {
      var hasFocus = document.body;
      // doc.activeElement occasionally throws on IE
      try { hasFocus = document.activeElement; } catch(e) {}
      options.autofocus = hasFocus == textarea ||
        textarea.getAttribute("autofocus") != null && hasFocus == document.body;
    }

    function save() {textarea.value = cm.getValue();}
    if (textarea.form) {
      on(textarea.form, "submit", save);
      // Deplorable hack to make the submit method do the right thing.
      if (!options.leaveSubmitMethodAlone) {
        var form = textarea.form, realSubmit = form.submit;
        try {
          var wrappedSubmit = form.submit = function() {
            save();
            form.submit = realSubmit;
            form.submit();
            form.submit = wrappedSubmit;
          };
        } catch(e) {}
      }
    }

    textarea.style.display = "none";
    var cm = CodeMirror(function(node) {
      textarea.parentNode.insertBefore(node, textarea.nextSibling);
    }, options);
    cm.save = save;
    cm.getTextArea = function() { return textarea; };
    cm.toTextArea = function() {
      save();
      textarea.parentNode.removeChild(cm.getWrapperElement());
      textarea.style.display = "";
      if (textarea.form) {
        off(textarea.form, "submit", save);
        if (typeof textarea.form.submit == "function")
          textarea.form.submit = realSubmit;
      }
    };
    return cm;
  };

  // STRING STREAM

  // Fed to the mode parsers, provides helper functions to make
  // parsers more succinct.

  // The character stream used by a mode's parser.
  function StringStream(string, tabSize) {
    this.pos = this.start = 0;
    this.string = string;
    this.tabSize = tabSize || 8;
    this.lastColumnPos = this.lastColumnValue = 0;
  }

  StringStream.prototype = {
    eol: function() {return this.pos >= this.string.length;},
    sol: function() {return this.pos == 0;},
    peek: function() {return this.string.charAt(this.pos) || undefined;},
    next: function() {
      if (this.pos < this.string.length)
        return this.string.charAt(this.pos++);
    },
    eat: function(match) {
      var ch = this.string.charAt(this.pos);
      if (typeof match == "string") var ok = ch == match;
      else var ok = ch && (match.test ? match.test(ch) : match(ch));
      if (ok) {++this.pos; return ch;}
    },
    eatWhile: function(match) {
      var start = this.pos;
      while (this.eat(match)){}
      return this.pos > start;
    },
    eatSpace: function() {
      var start = this.pos;
      while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
      return this.pos > start;
    },
    skipToEnd: function() {this.pos = this.string.length;},
    skipTo: function(ch) {
      var found = this.string.indexOf(ch, this.pos);
      if (found > -1) {this.pos = found; return true;}
    },
    backUp: function(n) {this.pos -= n;},
    column: function() {
      if (this.lastColumnPos < this.start) {
        this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
        this.lastColumnPos = this.start;
      }
      return this.lastColumnValue;
    },
    indentation: function() {return countColumn(this.string, null, this.tabSize);},
    match: function(pattern, consume, caseInsensitive) {
      if (typeof pattern == "string") {
        var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
        var substr = this.string.substr(this.pos, pattern.length);
        if (cased(substr) == cased(pattern)) {
          if (consume !== false) this.pos += pattern.length;
          return true;
        }
      } else {
        var match = this.string.slice(this.pos).match(pattern);
        if (match && match.index > 0) return null;
        if (match && consume !== false) this.pos += match[0].length;
        return match;
      }
    },
    current: function(){return this.string.slice(this.start, this.pos);}
  };
  CodeMirror.StringStream = StringStream;

  // TEXTMARKERS

  function TextMarker(doc, type) {
    this.lines = [];
    this.type = type;
    this.doc = doc;
  }
  CodeMirror.TextMarker = TextMarker;
  eventMixin(TextMarker);

  TextMarker.prototype.clear = function() {
    if (this.explicitlyCleared) return;
    var cm = this.doc.cm, withOp = cm && !cm.curOp;
    if (withOp) startOperation(cm);
    if (hasHandler(this, "clear")) {
      var found = this.find();
      if (found) signalLater(this, "clear", found.from, found.to);
    }
    var min = null, max = null;
    for (var i = 0; i < this.lines.length; ++i) {
      var line = this.lines[i];
      var span = getMarkedSpanFor(line.markedSpans, this);
      if (span.to != null) max = lineNo(line);
      line.markedSpans = removeMarkedSpan(line.markedSpans, span);
      if (span.from != null)
        min = lineNo(line);
      else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
        updateLineHeight(line, textHeight(cm.display));
    }
    if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
      var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
      if (len > cm.display.maxLineLength) {
        cm.display.maxLine = visual;
        cm.display.maxLineLength = len;
        cm.display.maxLineChanged = true;
      }
    }

    if (min != null && cm) regChange(cm, min, max + 1);
    this.lines.length = 0;
    this.explicitlyCleared = true;
    if (this.atomic && this.doc.cantEdit) {
      this.doc.cantEdit = false;
      if (cm) reCheckSelection(cm);
    }
    if (withOp) endOperation(cm);
  };

  TextMarker.prototype.find = function() {
    var from, to;
    for (var i = 0; i < this.lines.length; ++i) {
      var line = this.lines[i];
      var span = getMarkedSpanFor(line.markedSpans, this);
      if (span.from != null || span.to != null) {
        var found = lineNo(line);
        if (span.from != null) from = Pos(found, span.from);
        if (span.to != null) to = Pos(found, span.to);
      }
    }
    if (this.type == "bookmark") return from;
    return from && {from: from, to: to};
  };

  TextMarker.prototype.changed = function() {
    var pos = this.find(), cm = this.doc.cm;
    if (!pos || !cm) return;
    var line = getLine(this.doc, pos.from.line);
    clearCachedMeasurement(cm, line);
    if (pos.from.line >= cm.display.showingFrom && pos.from.line < cm.display.showingTo) {
      for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
        if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
        break;
      }
      runInOp(cm, function() {
        cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
      });
    }
  };

  TextMarker.prototype.attachLine = function(line) {
    if (!this.lines.length && this.doc.cm) {
      var op = this.doc.cm.curOp;
      if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
        (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
    }
    this.lines.push(line);
  };
  TextMarker.prototype.detachLine = function(line) {
    this.lines.splice(indexOf(this.lines, line), 1);
    if (!this.lines.length && this.doc.cm) {
      var op = this.doc.cm.curOp;
      (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
    }
  };

  function markText(doc, from, to, options, type) {
    if (options && options.shared) return markTextShared(doc, from, to, options, type);
    if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);

    var marker = new TextMarker(doc, type);
    if (type == "range" && !posLess(from, to)) return marker;
    if (options) copyObj(options, marker);
    if (marker.replacedWith) {
      marker.collapsed = true;
      marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
      if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
    }
    if (marker.collapsed) sawCollapsedSpans = true;

    if (marker.addToHistory)
      addToHistory(doc, {from: from, to: to, origin: "markText"},
                   {head: doc.sel.head, anchor: doc.sel.anchor}, NaN);

    var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
    doc.iter(curLine, to.line + 1, function(line) {
      if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
        updateMaxLine = true;
      var span = {from: null, to: null, marker: marker};
      size += line.text.length;
      if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
      if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
      if (marker.collapsed) {
        if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
        if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
        else updateLineHeight(line, 0);
      }
      addMarkedSpan(line, span);
      ++curLine;
    });
    if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
      if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
    });

    if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });

    if (marker.readOnly) {
      sawReadOnlySpans = true;
      if (doc.history.done.length || doc.history.undone.length)
        doc.clearHistory();
    }
    if (marker.collapsed) {
      if (collapsedAtStart != collapsedAtEnd)
        throw new Error("Inserting collapsed marker overlapping an existing one");
      marker.size = size;
      marker.atomic = true;
    }
    if (cm) {
      if (updateMaxLine) cm.curOp.updateMaxLine = true;
      if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
        regChange(cm, from.line, to.line + 1);
      if (marker.atomic) reCheckSelection(cm);
    }
    return marker;
  }

  // SHARED TEXTMARKERS

  function SharedTextMarker(markers, primary) {
    this.markers = markers;
    this.primary = primary;
    for (var i = 0, me = this; i < markers.length; ++i) {
      markers[i].parent = this;
      on(markers[i], "clear", function(){me.clear();});
    }
  }
  CodeMirror.SharedTextMarker = SharedTextMarker;
  eventMixin(SharedTextMarker);

  SharedTextMarker.prototype.clear = function() {
    if (this.explicitlyCleared) return;
    this.explicitlyCleared = true;
    for (var i = 0; i < this.markers.length; ++i)
      this.markers[i].clear();
    signalLater(this, "clear");
  };
  SharedTextMarker.prototype.find = function() {
    return this.primary.find();
  };

  function markTextShared(doc, from, to, options, type) {
    options = copyObj(options);
    options.shared = false;
    var markers = [markText(doc, from, to, options, type)], primary = markers[0];
    var widget = options.replacedWith;
    linkedDocs(doc, function(doc) {
      if (widget) options.replacedWith = widget.cloneNode(true);
      markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
      for (var i = 0; i < doc.linked.length; ++i)
        if (doc.linked[i].isParent) return;
      primary = lst(markers);
    });
    return new SharedTextMarker(markers, primary);
  }

  // TEXTMARKER SPANS

  function getMarkedSpanFor(spans, marker) {
    if (spans) for (var i = 0; i < spans.length; ++i) {
      var span = spans[i];
      if (span.marker == marker) return span;
    }
  }
  function removeMarkedSpan(spans, span) {
    for (var r, i = 0; i < spans.length; ++i)
      if (spans[i] != span) (r || (r = [])).push(spans[i]);
    return r;
  }
  function addMarkedSpan(line, span) {
    line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
    span.marker.attachLine(line);
  }

  function markedSpansBefore(old, startCh, isInsert) {
    if (old) for (var i = 0, nw; i < old.length; ++i) {
      var span = old[i], marker = span.marker;
      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
      if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
        var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
        (nw || (nw = [])).push({from: span.from,
                                to: endsAfter ? null : span.to,
                                marker: marker});
      }
    }
    return nw;
  }

  function markedSpansAfter(old, endCh, isInsert) {
    if (old) for (var i = 0, nw; i < old.length; ++i) {
      var span = old[i], marker = span.marker;
      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
      if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
        var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
        (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
                                to: span.to == null ? null : span.to - endCh,
                                marker: marker});
      }
    }
    return nw;
  }

  function stretchSpansOverChange(doc, change) {
    var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
    var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
    if (!oldFirst && !oldLast) return null;

    var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
    // Get the spans that 'stick out' on both sides
    var first = markedSpansBefore(oldFirst, startCh, isInsert);
    var last = markedSpansAfter(oldLast, endCh, isInsert);

    // Next, merge those two ends
    var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
    if (first) {
      // Fix up .to properties of first
      for (var i = 0; i < first.length; ++i) {
        var span = first[i];
        if (span.to == null) {
          var found = getMarkedSpanFor(last, span.marker);
          if (!found) span.to = startCh;
          else if (sameLine) span.to = found.to == null ? null : found.to + offset;
        }
      }
    }
    if (last) {
      // Fix up .from in last (or move them into first in case of sameLine)
      for (var i = 0; i < last.length; ++i) {
        var span = last[i];
        if (span.to != null) span.to += offset;
        if (span.from == null) {
          var found = getMarkedSpanFor(first, span.marker);
          if (!found) {
            span.from = offset;
            if (sameLine) (first || (first = [])).push(span);
          }
        } else {
          span.from += offset;
          if (sameLine) (first || (first = [])).push(span);
        }
      }
    }
    if (sameLine && first) {
      // Make sure we didn't create any zero-length spans
      for (var i = 0; i < first.length; ++i)
        if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
          first.splice(i--, 1);
      if (!first.length) first = null;
    }

    var newMarkers = [first];
    if (!sameLine) {
      // Fill gap with whole-line-spans
      var gap = change.text.length - 2, gapMarkers;
      if (gap > 0 && first)
        for (var i = 0; i < first.length; ++i)
          if (first[i].to == null)
            (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
      for (var i = 0; i < gap; ++i)
        newMarkers.push(gapMarkers);
      newMarkers.push(last);
    }
    return newMarkers;
  }

  function mergeOldSpans(doc, change) {
    var old = getOldSpans(doc, change);
    var stretched = stretchSpansOverChange(doc, change);
    if (!old) return stretched;
    if (!stretched) return old;

    for (var i = 0; i < old.length; ++i) {
      var oldCur = old[i], stretchCur = stretched[i];
      if (oldCur && stretchCur) {
        spans: for (var j = 0; j < stretchCur.length; ++j) {
          var span = stretchCur[j];
          for (var k = 0; k < oldCur.length; ++k)
            if (oldCur[k].marker == span.marker) continue spans;
          oldCur.push(span);
        }
      } else if (stretchCur) {
        old[i] = stretchCur;
      }
    }
    return old;
  }

  function removeReadOnlyRanges(doc, from, to) {
    var markers = null;
    doc.iter(from.line, to.line + 1, function(line) {
      if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
        var mark = line.markedSpans[i].marker;
        if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
          (markers || (markers = [])).push(mark);
      }
    });
    if (!markers) return null;
    var parts = [{from: from, to: to}];
    for (var i = 0; i < markers.length; ++i) {
      var mk = markers[i], m = mk.find();
      for (var j = 0; j < parts.length; ++j) {
        var p = parts[j];
        if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
        var newParts = [j, 1];
        if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
          newParts.push({from: p.from, to: m.from});
        if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
          newParts.push({from: m.to, to: p.to});
        parts.splice.apply(parts, newParts);
        j += newParts.length - 1;
      }
    }
    return parts;
  }

  function collapsedSpanAt(line, ch) {
    var sps = sawCollapsedSpans && line.markedSpans, found;
    if (sps) for (var sp, i = 0; i < sps.length; ++i) {
      sp = sps[i];
      if (!sp.marker.collapsed) continue;
      if ((sp.from == null || sp.from < ch) &&
          (sp.to == null || sp.to > ch) &&
          (!found || found.width < sp.marker.width))
        found = sp.marker;
    }
    return found;
  }
  function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
  function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }

  function visualLine(doc, line) {
    var merged;
    while (merged = collapsedSpanAtStart(line))
      line = getLine(doc, merged.find().from.line);
    return line;
  }

  function lineIsHidden(doc, line) {
    var sps = sawCollapsedSpans && line.markedSpans;
    if (sps) for (var sp, i = 0; i < sps.length; ++i) {
      sp = sps[i];
      if (!sp.marker.collapsed) continue;
      if (sp.from == null) return true;
      if (sp.marker.replacedWith) continue;
      if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
        return true;
    }
  }
  function lineIsHiddenInner(doc, line, span) {
    if (span.to == null) {
      var end = span.marker.find().to, endLine = getLine(doc, end.line);
      return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
    }
    if (span.marker.inclusiveRight && span.to == line.text.length)
      return true;
    for (var sp, i = 0; i < line.markedSpans.length; ++i) {
      sp = line.markedSpans[i];
      if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
          (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
          lineIsHiddenInner(doc, line, sp)) return true;
    }
  }

  function detachMarkedSpans(line) {
    var spans = line.markedSpans;
    if (!spans) return;
    for (var i = 0; i < spans.length; ++i)
      spans[i].marker.detachLine(line);
    line.markedSpans = null;
  }

  function attachMarkedSpans(line, spans) {
    if (!spans) return;
    for (var i = 0; i < spans.length; ++i)
      spans[i].marker.attachLine(line);
    line.markedSpans = spans;
  }

  // LINE WIDGETS

  var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
    if (options) for (var opt in options) if (options.hasOwnProperty(opt))
      this[opt] = options[opt];
    this.cm = cm;
    this.node = node;
  };
  eventMixin(LineWidget);
  function widgetOperation(f) {
    return function() {
      var withOp = !this.cm.curOp;
      if (withOp) startOperation(this.cm);
      try {var result = f.apply(this, arguments);}
      finally {if (withOp) endOperation(this.cm);}
      return result;
    };
  }
  LineWidget.prototype.clear = widgetOperation(function() {
    var ws = this.line.widgets, no = lineNo(this.line);
    if (no == null || !ws) return;
    for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
    if (!ws.length) this.line.widgets = null;
    var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
    updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
    if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
    regChange(this.cm, no, no + 1);
  });
  LineWidget.prototype.changed = widgetOperation(function() {
    var oldH = this.height;
    this.height = null;
    var diff = widgetHeight(this) - oldH;
    if (!diff) return;
    updateLineHeight(this.line, this.line.height + diff);
    var no = lineNo(this.line);
    regChange(this.cm, no, no + 1);
  });

  function widgetHeight(widget) {
    if (widget.height != null) return widget.height;
    if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
      removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
    return widget.height = widget.node.offsetHeight;
  }

  function addLineWidget(cm, handle, node, options) {
    var widget = new LineWidget(cm, node, options);
    if (widget.noHScroll) cm.display.alignWidgets = true;
    changeLine(cm, handle, function(line) {
      var widgets = line.widgets || (line.widgets = []);
      if (widget.insertAt == null) widgets.push(widget);
      else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
      widget.line = line;
      if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
        var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
        updateLineHeight(line, line.height + widgetHeight(widget));
        if (aboveVisible) addToScrollPos(cm, 0, widget.height);
      }
      return true;
    });
    return widget;
  }

  // LINE DATA STRUCTURE

  // Line objects. These hold state related to a line, including
  // highlighting info (the styles array).
  var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
    this.text = text;
    attachMarkedSpans(this, markedSpans);
    this.height = estimateHeight ? estimateHeight(this) : 1;
  };
  eventMixin(Line);

  function updateLine(line, text, markedSpans, estimateHeight) {
    line.text = text;
    if (line.stateAfter) line.stateAfter = null;
    if (line.styles) line.styles = null;
    if (line.order != null) line.order = null;
    detachMarkedSpans(line);
    attachMarkedSpans(line, markedSpans);
    var estHeight = estimateHeight ? estimateHeight(line) : 1;
    if (estHeight != line.height) updateLineHeight(line, estHeight);
  }

  function cleanUpLine(line) {
    line.parent = null;
    detachMarkedSpans(line);
  }

  // Run the given mode's parser over a line, update the styles
  // array, which contains alternating fragments of text and CSS
  // classes.
  function runMode(cm, text, mode, state, f) {
    var flattenSpans = mode.flattenSpans;
    if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
    var curStart = 0, curStyle = null;
    var stream = new StringStream(text, cm.options.tabSize), style;
    if (text == "" && mode.blankLine) mode.blankLine(state);
    while (!stream.eol()) {
      if (stream.pos > cm.options.maxHighlightLength) {
        flattenSpans = false;
        // Webkit seems to refuse to render text nodes longer than 57444 characters
        stream.pos = Math.min(text.length, stream.start + 50000);
        style = null;
      } else {
        style = mode.token(stream, state);
      }
      if (!flattenSpans || curStyle != style) {
        if (curStart < stream.start) f(stream.start, curStyle);
        curStart = stream.start; curStyle = style;
      }
      stream.start = stream.pos;
    }
    if (curStart < stream.pos) f(stream.pos, curStyle);
  }

  function highlightLine(cm, line, state) {
    // A styles array always starts with a number identifying the
    // mode/overlays that it is based on (for easy invalidation).
    var st = [cm.state.modeGen];
    // Compute the base array of styles
    runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});

    // Run overlays, adjust style array.
    for (var o = 0; o < cm.state.overlays.length; ++o) {
      var overlay = cm.state.overlays[o], i = 1, at = 0;
      runMode(cm, line.text, overlay.mode, true, function(end, style) {
        var start = i;
        // Ensure there's a token end at the current position, and that i points at it
        while (at < end) {
          var i_end = st[i];
          if (i_end > end)
            st.splice(i, 1, end, st[i+1], i_end);
          i += 2;
          at = Math.min(end, i_end);
        }
        if (!style) return;
        if (overlay.opaque) {
          st.splice(start, i - start, end, style);
          i = start + 2;
        } else {
          for (; start < i; start += 2) {
            var cur = st[start+1];
            st[start+1] = cur ? cur + " " + style : style;
          }
        }
      });
    }

    return st;
  }

  function getLineStyles(cm, line) {
    if (!line.styles || line.styles[0] != cm.state.modeGen)
      line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
    return line.styles;
  }

  // Lightweight form of highlight -- proceed over this line and
  // update state, but don't save a style array.
  function processLine(cm, line, state) {
    var mode = cm.doc.mode;
    var stream = new StringStream(line.text, cm.options.tabSize);
    if (line.text == "" && mode.blankLine) mode.blankLine(state);
    while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
      mode.token(stream, state);
      stream.start = stream.pos;
    }
  }

  var styleToClassCache = {};
  function styleToClass(style) {
    if (!style) return null;
    return styleToClassCache[style] ||
      (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
  }

  function lineContent(cm, realLine, measure, copyWidgets) {
    var merged, line = realLine, empty = true;
    while (merged = collapsedSpanAtStart(line))
      line = getLine(cm.doc, merged.find().from.line);

    var builder = {pre: elt("pre"), col: 0, pos: 0,
                   measure: null, measuredSomething: false, cm: cm,
                   copyWidgets: copyWidgets};
    if (line.textClass) builder.pre.className = line.textClass;

    do {
      if (line.text) empty = false;
      builder.measure = line == realLine && measure;
      builder.pos = 0;
      builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
      if ((ie || webkit) && cm.getOption("lineWrapping"))
        builder.addToken = buildTokenSplitSpaces(builder.addToken);
      var next = insertLineContent(line, builder, getLineStyles(cm, line));
      if (measure && line == realLine && !builder.measuredSomething) {
        measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
        builder.measuredSomething = true;
      }
      if (next) line = getLine(cm.doc, next.to.line);
    } while (next);

    if (measure && !builder.measuredSomething && !measure[0])
      measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
    if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
      builder.pre.appendChild(document.createTextNode("\u00a0"));

    var order;
    // Work around problem with the reported dimensions of single-char
    // direction spans on IE (issue #1129). See also the comment in
    // cursorCoords.
    if (measure && ie && (order = getOrder(line))) {
      var l = order.length - 1;
      if (order[l].from == order[l].to) --l;
      var last = order[l], prev = order[l - 1];
      if (last.from + 1 == last.to && prev && last.level < prev.level) {
        var span = measure[builder.pos - 1];
        if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
                                               span.nextSibling);
      }
    }

    signal(cm, "renderLine", cm, realLine, builder.pre);
    return builder.pre;
  }

  var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
  function buildToken(builder, text, style, startStyle, endStyle, title) {
    if (!text) return;
    if (!tokenSpecialChars.test(text)) {
      builder.col += text.length;
      var content = document.createTextNode(text);
    } else {
      var content = document.createDocumentFragment(), pos = 0;
      while (true) {
        tokenSpecialChars.lastIndex = pos;
        var m = tokenSpecialChars.exec(text);
        var skipped = m ? m.index - pos : text.length - pos;
        if (skipped) {
          content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
          builder.col += skipped;
        }
        if (!m) break;
        pos += skipped + 1;
        if (m[0] == "\t") {
          var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
          content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
          builder.col += tabWidth;
        } else {
          var token = elt("span", "\u2022", "cm-invalidchar");
          token.title = "\\u" + m[0].charCodeAt(0).toString(16);
          content.appendChild(token);
          builder.col += 1;
        }
      }
    }
    if (style || startStyle || endStyle || builder.measure) {
      var fullStyle = style || "";
      if (startStyle) fullStyle += startStyle;
      if (endStyle) fullStyle += endStyle;
      var token = elt("span", [content], fullStyle);
      if (title) token.title = title;
      return builder.pre.appendChild(token);
    }
    builder.pre.appendChild(content);
  }

  function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
    var wrapping = builder.cm.options.lineWrapping;
    for (var i = 0; i < text.length; ++i) {
      var ch = text.charAt(i), start = i == 0;
      if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
        ch = text.slice(i, i + 2);
        ++i;
      } else if (i && wrapping && spanAffectsWrapping(text, i)) {
        builder.pre.appendChild(elt("wbr"));
      }
      var old = builder.measure[builder.pos];
      var span = builder.measure[builder.pos] =
        buildToken(builder, ch, style,
                   start && startStyle, i == text.length - 1 && endStyle);
      if (old) span.leftSide = old.leftSide || old;
      // In IE single-space nodes wrap differently than spaces
      // embedded in larger text nodes, except when set to
      // white-space: normal (issue #1268).
      if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
          i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
        span.style.whiteSpace = "normal";
      builder.pos += ch.length;
    }
    if (text.length) builder.measuredSomething = true;
  }

  function buildTokenSplitSpaces(inner) {
    function split(old) {
      var out = " ";
      for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
      out += " ";
      return out;
    }
    return function(builder, text, style, startStyle, endStyle, title) {
      return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
    };
  }

  function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
    var widget = !ignoreWidget && marker.replacedWith;
    if (widget) {
      if (builder.copyWidgets) widget = widget.cloneNode(true);
      builder.pre.appendChild(widget);
      if (builder.measure) {
        if (size) {
          builder.measure[builder.pos] = widget;
        } else {
          var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure);
          if (marker.type != "bookmark" || marker.insertLeft)
            builder.pre.insertBefore(elt, widget);
          else
            builder.pre.appendChild(elt);
        }
        builder.measuredSomething = true;
      }
    }
    builder.pos += size;
  }

  // Outputs a number of spans to make up a line, taking highlighting
  // and marked text into account.
  function insertLineContent(line, builder, styles) {
    var spans = line.markedSpans, allText = line.text, at = 0;
    if (!spans) {
      for (var i = 1; i < styles.length; i+=2)
        builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
      return;
    }

    var len = allText.length, pos = 0, i = 1, text = "", style;
    var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
    for (;;) {
      if (nextChange == pos) { // Update current marker set
        spanStyle = spanEndStyle = spanStartStyle = title = "";
        collapsed = null; nextChange = Infinity;
        var foundBookmark = null;
        for (var j = 0; j < spans.length; ++j) {
          var sp = spans[j], m = sp.marker;
          if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
            if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
            if (m.className) spanStyle += " " + m.className;
            if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
            if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
            if (m.title && !title) title = m.title;
            if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
              collapsed = sp;
          } else if (sp.from > pos && nextChange > sp.from) {
            nextChange = sp.from;
          }
          if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
        }
        if (collapsed && (collapsed.from || 0) == pos) {
          buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
                             collapsed.marker, collapsed.from == null);
          if (collapsed.to == null) return collapsed.marker.find();
        }
        if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
      }
      if (pos >= len) break;

      var upto = Math.min(len, nextChange);
      while (true) {
        if (text) {
          var end = pos + text.length;
          if (!collapsed) {
            var tokenText = end > upto ? text.slice(0, upto - pos) : text;
            builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
                             spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
          }
          if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
          pos = end;
          spanStartStyle = "";
        }
        text = allText.slice(at, at = styles[i++]);
        style = styleToClass(styles[i++]);
      }
    }
  }

  // DOCUMENT DATA STRUCTURE

  function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
    function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
    function update(line, text, spans) {
      updateLine(line, text, spans, estimateHeight);
      signalLater(line, "change", line, change);
    }

    var from = change.from, to = change.to, text = change.text;
    var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
    var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;

    // First adjust the line structure
    if (from.ch == 0 && to.ch == 0 && lastText == "") {
      // This is a whole-line replace. Treated specially to make
      // sure line objects move the way they are supposed to.
      for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
        added.push(new Line(text[i], spansFor(i), estimateHeight));
      update(lastLine, lastLine.text, lastSpans);
      if (nlines) doc.remove(from.line, nlines);
      if (added.length) doc.insert(from.line, added);
    } else if (firstLine == lastLine) {
      if (text.length == 1) {
        update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
      } else {
        for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
          added.push(new Line(text[i], spansFor(i), estimateHeight));
        added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
        update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
        doc.insert(from.line + 1, added);
      }
    } else if (text.length == 1) {
      update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
      doc.remove(from.line + 1, nlines);
    } else {
      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
      update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
      for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
        added.push(new Line(text[i], spansFor(i), estimateHeight));
      if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
      doc.insert(from.line + 1, added);
    }

    signalLater(doc, "change", doc, change);
    setSelection(doc, selAfter.anchor, selAfter.head, null, true);
  }

  function LeafChunk(lines) {
    this.lines = lines;
    this.parent = null;
    for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
      lines[i].parent = this;
      height += lines[i].height;
    }
    this.height = height;
  }

  LeafChunk.prototype = {
    chunkSize: function() { return this.lines.length; },
    removeInner: function(at, n) {
      for (var i = at, e = at + n; i < e; ++i) {
        var line = this.lines[i];
        this.height -= line.height;
        cleanUpLine(line);
        signalLater(line, "delete");
      }
      this.lines.splice(at, n);
    },
    collapse: function(lines) {
      lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
    },
    insertInner: function(at, lines, height) {
      this.height += height;
      this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
      for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
    },
    iterN: function(at, n, op) {
      for (var e = at + n; at < e; ++at)
        if (op(this.lines[at])) return true;
    }
  };

  function BranchChunk(children) {
    this.children = children;
    var size = 0, height = 0;
    for (var i = 0, e = children.length; i < e; ++i) {
      var ch = children[i];
      size += ch.chunkSize(); height += ch.height;
      ch.parent = this;
    }
    this.size = size;
    this.height = height;
    this.parent = null;
  }

  BranchChunk.prototype = {
    chunkSize: function() { return this.size; },
    removeInner: function(at, n) {
      this.size -= n;
      for (var i = 0; i < this.children.length; ++i) {
        var child = this.children[i], sz = child.chunkSize();
        if (at < sz) {
          var rm = Math.min(n, sz - at), oldHeight = child.height;
          child.removeInner(at, rm);
          this.height -= oldHeight - child.height;
          if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
          if ((n -= rm) == 0) break;
          at = 0;
        } else at -= sz;
      }
      if (this.size - n < 25) {
        var lines = [];
        this.collapse(lines);
        this.children = [new LeafChunk(lines)];
        this.children[0].parent = this;
      }
    },
    collapse: function(lines) {
      for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
    },
    insertInner: function(at, lines, height) {
      this.size += lines.length;
      this.height += height;
      for (var i = 0, e = this.children.length; i < e; ++i) {
        var child = this.children[i], sz = child.chunkSize();
        if (at <= sz) {
          child.insertInner(at, lines, height);
          if (child.lines && child.lines.length > 50) {
            while (child.lines.length > 50) {
              var spilled = child.lines.splice(child.lines.length - 25, 25);
              var newleaf = new LeafChunk(spilled);
              child.height -= newleaf.height;
              this.children.splice(i + 1, 0, newleaf);
              newleaf.parent = this;
            }
            this.maybeSpill();
          }
          break;
        }
        at -= sz;
      }
    },
    maybeSpill: function() {
      if (this.children.length <= 10) return;
      var me = this;
      do {
        var spilled = me.children.splice(me.children.length - 5, 5);
        var sibling = new BranchChunk(spilled);
        if (!me.parent) { // Become the parent node
          var copy = new BranchChunk(me.children);
          copy.parent = me;
          me.children = [copy, sibling];
          me = copy;
        } else {
          me.size -= sibling.size;
          me.height -= sibling.height;
          var myIndex = indexOf(me.parent.children, me);
          me.parent.children.splice(myIndex + 1, 0, sibling);
        }
        sibling.parent = me.parent;
      } while (me.children.length > 10);
      me.parent.maybeSpill();
    },
    iterN: function(at, n, op) {
      for (var i = 0, e = this.children.length; i < e; ++i) {
        var child = this.children[i], sz = child.chunkSize();
        if (at < sz) {
          var used = Math.min(n, sz - at);
          if (child.iterN(at, used, op)) return true;
          if ((n -= used) == 0) break;
          at = 0;
        } else at -= sz;
      }
    }
  };

  var nextDocId = 0;
  var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
    if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
    if (firstLine == null) firstLine = 0;

    BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
    this.first = firstLine;
    this.scrollTop = this.scrollLeft = 0;
    this.cantEdit = false;
    this.history = makeHistory();
    this.cleanGeneration = 1;
    this.frontier = firstLine;
    var start = Pos(firstLine, 0);
    this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
    this.id = ++nextDocId;
    this.modeOption = mode;

    if (typeof text == "string") text = splitLines(text);
    updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
  };

  Doc.prototype = createObj(BranchChunk.prototype, {
    constructor: Doc,
    iter: function(from, to, op) {
      if (op) this.iterN(from - this.first, to - from, op);
      else this.iterN(this.first, this.first + this.size, from);
    },

    insert: function(at, lines) {
      var height = 0;
      for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
      this.insertInner(at - this.first, lines, height);
    },
    remove: function(at, n) { this.removeInner(at - this.first, n); },

    getValue: function(lineSep) {
      var lines = getLines(this, this.first, this.first + this.size);
      if (lineSep === false) return lines;
      return lines.join(lineSep || "\n");
    },
    setValue: function(code) {
      var top = Pos(this.first, 0), last = this.first + this.size - 1;
      makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
                        text: splitLines(code), origin: "setValue"},
                 {head: top, anchor: top}, true);
    },
    replaceRange: function(code, from, to, origin) {
      from = clipPos(this, from);
      to = to ? clipPos(this, to) : from;
      replaceRange(this, code, from, to, origin);
    },
    getRange: function(from, to, lineSep) {
      var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
      if (lineSep === false) return lines;
      return lines.join(lineSep || "\n");
    },

    getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
    setLine: function(line, text) {
      if (isLine(this, line))
        replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
    },
    removeLine: function(line) {
      if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
      else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
    },

    getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
    getLineNumber: function(line) {return lineNo(line);},

    getLineHandleVisualStart: function(line) {
      if (typeof line == "number") line = getLine(this, line);
      return visualLine(this, line);
    },

    lineCount: function() {return this.size;},
    firstLine: function() {return this.first;},
    lastLine: function() {return this.first + this.size - 1;},

    clipPos: function(pos) {return clipPos(this, pos);},

    getCursor: function(start) {
      var sel = this.sel, pos;
      if (start == null || start == "head") pos = sel.head;
      else if (start == "anchor") pos = sel.anchor;
      else if (start == "end" || start === false) pos = sel.to;
      else pos = sel.from;
      return copyPos(pos);
    },
    somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},

    setCursor: docOperation(function(line, ch, extend) {
      var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
      if (extend) extendSelection(this, pos);
      else setSelection(this, pos, pos);
    }),
    setSelection: docOperation(function(anchor, head) {
      setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor));
    }),
    extendSelection: docOperation(function(from, to) {
      extendSelection(this, clipPos(this, from), to && clipPos(this, to));
    }),

    getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
    replaceSelection: function(code, collapse, origin) {
      makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
    },
    undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
    redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),

    setExtending: function(val) {this.sel.extend = val;},

    historySize: function() {
      var hist = this.history;
      return {undo: hist.done.length, redo: hist.undone.length};
    },
    clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},

    markClean: function() {
      this.cleanGeneration = this.changeGeneration();
    },
    changeGeneration: function() {
      this.history.lastOp = this.history.lastOrigin = null;
      return this.history.generation;
    },
    isClean: function (gen) {
      return this.history.generation == (gen || this.cleanGeneration);
    },

    getHistory: function() {
      return {done: copyHistoryArray(this.history.done),
              undone: copyHistoryArray(this.history.undone)};
    },
    setHistory: function(histData) {
      var hist = this.history = makeHistory(this.history.maxGeneration);
      hist.done = histData.done.slice(0);
      hist.undone = histData.undone.slice(0);
    },

    markText: function(from, to, options) {
      return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
    },
    setBookmark: function(pos, options) {
      var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
                      insertLeft: options && options.insertLeft};
      pos = clipPos(this, pos);
      return markText(this, pos, pos, realOpts, "bookmark");
    },
    findMarksAt: function(pos) {
      pos = clipPos(this, pos);
      var markers = [], spans = getLine(this, pos.line).markedSpans;
      if (spans) for (var i = 0; i < spans.length; ++i) {
        var span = spans[i];
        if ((span.from == null || span.from <= pos.ch) &&
            (span.to == null || span.to >= pos.ch))
          markers.push(span.marker.parent || span.marker);
      }
      return markers;
    },
    getAllMarks: function() {
      var markers = [];
      this.iter(function(line) {
        var sps = line.markedSpans;
        if (sps) for (var i = 0; i < sps.length; ++i)
          if (sps[i].from != null) markers.push(sps[i].marker);
      });
      return markers;
    },

    posFromIndex: function(off) {
      var ch, lineNo = this.first;
      this.iter(function(line) {
        var sz = line.text.length + 1;
        if (sz > off) { ch = off; return true; }
        off -= sz;
        ++lineNo;
      });
      return clipPos(this, Pos(lineNo, ch));
    },
    indexFromPos: function (coords) {
      coords = clipPos(this, coords);
      var index = coords.ch;
      if (coords.line < this.first || coords.ch < 0) return 0;
      this.iter(this.first, coords.line, function (line) {
        index += line.text.length + 1;
      });
      return index;
    },

    copy: function(copyHistory) {
      var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
      doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
      doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
                 shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
      if (copyHistory) {
        doc.history.undoDepth = this.history.undoDepth;
        doc.setHistory(this.getHistory());
      }
      return doc;
    },

    linkedDoc: function(options) {
      if (!options) options = {};
      var from = this.first, to = this.first + this.size;
      if (options.from != null && options.from > from) from = options.from;
      if (options.to != null && options.to < to) to = options.to;
      var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
      if (options.sharedHist) copy.history = this.history;
      (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
      copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
      return copy;
    },
    unlinkDoc: function(other) {
      if (other instanceof CodeMirror) other = other.doc;
      if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
        var link = this.linked[i];
        if (link.doc != other) continue;
        this.linked.splice(i, 1);
        other.unlinkDoc(this);
        break;
      }
      // If the histories were shared, split them again
      if (other.history == this.history) {
        var splitIds = [other.id];
        linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
        other.history = makeHistory();
        other.history.done = copyHistoryArray(this.history.done, splitIds);
        other.history.undone = copyHistoryArray(this.history.undone, splitIds);
      }
    },
    iterLinkedDocs: function(f) {linkedDocs(this, f);},

    getMode: function() {return this.mode;},
    getEditor: function() {return this.cm;}
  });

  Doc.prototype.eachLine = Doc.prototype.iter;

  // The Doc methods that should be available on CodeMirror instances
  var dontDelegate = "iter insert remove copy getEditor".split(" ");
  for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
    CodeMirror.prototype[prop] = (function(method) {
      return function() {return method.apply(this.doc, arguments);};
    })(Doc.prototype[prop]);

  eventMixin(Doc);

  function linkedDocs(doc, f, sharedHistOnly) {
    function propagate(doc, skip, sharedHist) {
      if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
        var rel = doc.linked[i];
        if (rel.doc == skip) continue;
        var shared = sharedHist && rel.sharedHist;
        if (sharedHistOnly && !shared) continue;
        f(rel.doc, shared);
        propagate(rel.doc, doc, shared);
      }
    }
    propagate(doc, null, true);
  }

  function attachDoc(cm, doc) {
    if (doc.cm) throw new Error("This document is already in use.");
    cm.doc = doc;
    doc.cm = cm;
    estimateLineHeights(cm);
    loadMode(cm);
    if (!cm.options.lineWrapping) computeMaxLength(cm);
    cm.options.mode = doc.modeOption;
    regChange(cm);
  }

  // LINE UTILITIES

  function getLine(chunk, n) {
    n -= chunk.first;
    while (!chunk.lines) {
      for (var i = 0;; ++i) {
        var child = chunk.children[i], sz = child.chunkSize();
        if (n < sz) { chunk = child; break; }
        n -= sz;
      }
    }
    return chunk.lines[n];
  }

  function getBetween(doc, start, end) {
    var out = [], n = start.line;
    doc.iter(start.line, end.line + 1, function(line) {
      var text = line.text;
      if (n == end.line) text = text.slice(0, end.ch);
      if (n == start.line) text = text.slice(start.ch);
      out.push(text);
      ++n;
    });
    return out;
  }
  function getLines(doc, from, to) {
    var out = [];
    doc.iter(from, to, function(line) { out.push(line.text); });
    return out;
  }

  function updateLineHeight(line, height) {
    var diff = height - line.height;
    for (var n = line; n; n = n.parent) n.height += diff;
  }

  function lineNo(line) {
    if (line.parent == null) return null;
    var cur = line.parent, no = indexOf(cur.lines, line);
    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
      for (var i = 0;; ++i) {
        if (chunk.children[i] == cur) break;
        no += chunk.children[i].chunkSize();
      }
    }
    return no + cur.first;
  }

  function lineAtHeight(chunk, h) {
    var n = chunk.first;
    outer: do {
      for (var i = 0, e = chunk.children.length; i < e; ++i) {
        var child = chunk.children[i], ch = child.height;
        if (h < ch) { chunk = child; continue outer; }
        h -= ch;
        n += child.chunkSize();
      }
      return n;
    } while (!chunk.lines);
    for (var i = 0, e = chunk.lines.length; i < e; ++i) {
      var line = chunk.lines[i], lh = line.height;
      if (h < lh) break;
      h -= lh;
    }
    return n + i;
  }

  function heightAtLine(cm, lineObj) {
    lineObj = visualLine(cm.doc, lineObj);

    var h = 0, chunk = lineObj.parent;
    for (var i = 0; i < chunk.lines.length; ++i) {
      var line = chunk.lines[i];
      if (line == lineObj) break;
      else h += line.height;
    }
    for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
      for (var i = 0; i < p.children.length; ++i) {
        var cur = p.children[i];
        if (cur == chunk) break;
        else h += cur.height;
      }
    }
    return h;
  }

  function getOrder(line) {
    var order = line.order;
    if (order == null) order = line.order = bidiOrdering(line.text);
    return order;
  }

  // HISTORY

  function makeHistory(startGen) {
    return {
      // Arrays of history events. Doing something adds an event to
      // done and clears undo. Undoing moves events from done to
      // undone, redoing moves them in the other direction.
      done: [], undone: [], undoDepth: Infinity,
      // Used to track when changes can be merged into a single undo
      // event
      lastTime: 0, lastOp: null, lastOrigin: null,
      // Used by the isClean() method
      generation: startGen || 1, maxGeneration: startGen || 1
    };
  }

  function attachLocalSpans(doc, change, from, to) {
    var existing = change["spans_" + doc.id], n = 0;
    doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
      if (line.markedSpans)
        (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
      ++n;
    });
  }

  function historyChangeFromChange(doc, change) {
    var from = { line: change.from.line, ch: change.from.ch };
    var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
    attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
    linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
    return histChange;
  }

  function addToHistory(doc, change, selAfter, opId) {
    var hist = doc.history;
    hist.undone.length = 0;
    var time = +new Date, cur = lst(hist.done);

    if (cur &&
        (hist.lastOp == opId ||
         hist.lastOrigin == change.origin && change.origin &&
         ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
          change.origin.charAt(0) == "*"))) {
      // Merge this change into the last event
      var last = lst(cur.changes);
      if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
        // Optimized case for simple insertion -- don't want to add
        // new changesets for every character typed
        last.to = changeEnd(change);
      } else {
        // Add new sub-event
        cur.changes.push(historyChangeFromChange(doc, change));
      }
      cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
    } else {
      // Can not be merged, start a new event.
      cur = {changes: [historyChangeFromChange(doc, change)],
             generation: hist.generation,
             anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
             anchorAfter: selAfter.anchor, headAfter: selAfter.head};
      hist.done.push(cur);
      hist.generation = ++hist.maxGeneration;
      while (hist.done.length > hist.undoDepth)
        hist.done.shift();
    }
    hist.lastTime = time;
    hist.lastOp = opId;
    hist.lastOrigin = change.origin;
  }

  function removeClearedSpans(spans) {
    if (!spans) return null;
    for (var i = 0, out; i < spans.length; ++i) {
      if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
      else if (out) out.push(spans[i]);
    }
    return !out ? spans : out.length ? out : null;
  }

  function getOldSpans(doc, change) {
    var found = change["spans_" + doc.id];
    if (!found) return null;
    for (var i = 0, nw = []; i < change.text.length; ++i)
      nw.push(removeClearedSpans(found[i]));
    return nw;
  }

  // Used both to provide a JSON-safe object in .getHistory, and, when
  // detaching a document, to split the history in two
  function copyHistoryArray(events, newGroup) {
    for (var i = 0, copy = []; i < events.length; ++i) {
      var event = events[i], changes = event.changes, newChanges = [];
      copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
                 anchorAfter: event.anchorAfter, headAfter: event.headAfter});
      for (var j = 0; j < changes.length; ++j) {
        var change = changes[j], m;
        newChanges.push({from: change.from, to: change.to, text: change.text});
        if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
          if (indexOf(newGroup, Number(m[1])) > -1) {
            lst(newChanges)[prop] = change[prop];
            delete change[prop];
          }
        }
      }
    }
    return copy;
  }

  // Rebasing/resetting history to deal with externally-sourced changes

  function rebaseHistSel(pos, from, to, diff) {
    if (to < pos.line) {
      pos.line += diff;
    } else if (from < pos.line) {
      pos.line = from;
      pos.ch = 0;
    }
  }

  // Tries to rebase an array of history events given a change in the
  // document. If the change touches the same lines as the event, the
  // event, and everything 'behind' it, is discarded. If the change is
  // before the event, the event's positions are updated. Uses a
  // copy-on-write scheme for the positions, to avoid having to
  // reallocate them all on every rebase, but also avoid problems with
  // shared position objects being unsafely updated.
  function rebaseHistArray(array, from, to, diff) {
    for (var i = 0; i < array.length; ++i) {
      var sub = array[i], ok = true;
      for (var j = 0; j < sub.changes.length; ++j) {
        var cur = sub.changes[j];
        if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
        if (to < cur.from.line) {
          cur.from.line += diff;
          cur.to.line += diff;
        } else if (from <= cur.to.line) {
          ok = false;
          break;
        }
      }
      if (!sub.copied) {
        sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
        sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
        sub.copied = true;
      }
      if (!ok) {
        array.splice(0, i + 1);
        i = 0;
      } else {
        rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
        rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
      }
    }
  }

  function rebaseHist(hist, change) {
    var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
    rebaseHistArray(hist.done, from, to, diff);
    rebaseHistArray(hist.undone, from, to, diff);
  }

  // EVENT OPERATORS

  function stopMethod() {e_stop(this);}
  // Ensure an event has a stop method.
  function addStop(event) {
    if (!event.stop) event.stop = stopMethod;
    return event;
  }

  function e_preventDefault(e) {
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
  }
  function e_stopPropagation(e) {
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;
  }
  function e_defaultPrevented(e) {
    return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
  }
  function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
  CodeMirror.e_stop = e_stop;
  CodeMirror.e_preventDefault = e_preventDefault;
  CodeMirror.e_stopPropagation = e_stopPropagation;

  function e_target(e) {return e.target || e.srcElement;}
  function e_button(e) {
    var b = e.which;
    if (b == null) {
      if (e.button & 1) b = 1;
      else if (e.button & 2) b = 3;
      else if (e.button & 4) b = 2;
    }
    if (mac && e.ctrlKey && b == 1) b = 3;
    return b;
  }

  // EVENT HANDLING

  function on(emitter, type, f) {
    if (emitter.addEventListener)
      emitter.addEventListener(type, f, false);
    else if (emitter.attachEvent)
      emitter.attachEvent("on" + type, f);
    else {
      var map = emitter._handlers || (emitter._handlers = {});
      var arr = map[type] || (map[type] = []);
      arr.push(f);
    }
  }

  function off(emitter, type, f) {
    if (emitter.removeEventListener)
      emitter.removeEventListener(type, f, false);
    else if (emitter.detachEvent)
      emitter.detachEvent("on" + type, f);
    else {
      var arr = emitter._handlers && emitter._handlers[type];
      if (!arr) return;
      for (var i = 0; i < arr.length; ++i)
        if (arr[i] == f) { arr.splice(i, 1); break; }
    }
  }

  function signal(emitter, type /*, values...*/) {
    var arr = emitter._handlers && emitter._handlers[type];
    if (!arr) return;
    var args = Array.prototype.slice.call(arguments, 2);
    for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
  }

  var delayedCallbacks, delayedCallbackDepth = 0;
  function signalLater(emitter, type /*, values...*/) {
    var arr = emitter._handlers && emitter._handlers[type];
    if (!arr) return;
    var args = Array.prototype.slice.call(arguments, 2);
    if (!delayedCallbacks) {
      ++delayedCallbackDepth;
      delayedCallbacks = [];
      setTimeout(fireDelayed, 0);
    }
    function bnd(f) {return function(){f.apply(null, args);};};
    for (var i = 0; i < arr.length; ++i)
      delayedCallbacks.push(bnd(arr[i]));
  }

  function signalDOMEvent(cm, e, override) {
    signal(cm, override || e.type, cm, e);
    return e_defaultPrevented(e) || e.codemirrorIgnore;
  }

  function fireDelayed() {
    --delayedCallbackDepth;
    var delayed = delayedCallbacks;
    delayedCallbacks = null;
    for (var i = 0; i < delayed.length; ++i) delayed[i]();
  }

  function hasHandler(emitter, type) {
    var arr = emitter._handlers && emitter._handlers[type];
    return arr && arr.length > 0;
  }

  CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;

  function eventMixin(ctor) {
    ctor.prototype.on = function(type, f) {on(this, type, f);};
    ctor.prototype.off = function(type, f) {off(this, type, f);};
  }

  // MISC UTILITIES

  // Number of pixels added to scroller and sizer to hide scrollbar
  var scrollerCutOff = 30;

  // Returned or thrown by various protocols to signal 'I'm not
  // handling this'.
  var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};

  function Delayed() {this.id = null;}
  Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};

  // Counts the column offset in a string, taking tabs into account.
  // Used mostly to find indentation.
  function countColumn(string, end, tabSize, startIndex, startValue) {
    if (end == null) {
      end = string.search(/[^\s\u00a0]/);
      if (end == -1) end = string.length;
    }
    for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
      if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
      else ++n;
    }
    return n;
  }
  CodeMirror.countColumn = countColumn;

  var spaceStrs = [""];
  function spaceStr(n) {
    while (spaceStrs.length <= n)
      spaceStrs.push(lst(spaceStrs) + " ");
    return spaceStrs[n];
  }

  function lst(arr) { return arr[arr.length-1]; }

  function selectInput(node) {
    if (ios) { // Mobile Safari apparently has a bug where select() is broken.
      node.selectionStart = 0;
      node.selectionEnd = node.value.length;
    } else {
      // Suppress mysterious IE10 errors
      try { node.select(); }
      catch(_e) {}
    }
  }

  function indexOf(collection, elt) {
    if (collection.indexOf) return collection.indexOf(elt);
    for (var i = 0, e = collection.length; i < e; ++i)
      if (collection[i] == elt) return i;
    return -1;
  }

  function createObj(base, props) {
    function Obj() {}
    Obj.prototype = base;
    var inst = new Obj();
    if (props) copyObj(props, inst);
    return inst;
  }

  function copyObj(obj, target) {
    if (!target) target = {};
    for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
    return target;
  }

  function emptyArray(size) {
    for (var a = [], i = 0; i < size; ++i) a.push(undefined);
    return a;
  }

  function bind(f) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function(){return f.apply(null, args);};
  }

  var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
  function isWordChar(ch) {
    return /\w/.test(ch) || ch > "\x80" &&
      (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
  }

  function isEmpty(obj) {
    for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
    return true;
  }

  var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;

  // DOM UTILITIES

  function elt(tag, content, className, style) {
    var e = document.createElement(tag);
    if (className) e.className = className;
    if (style) e.style.cssText = style;
    if (typeof content == "string") setTextContent(e, content);
    else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
    return e;
  }

  function removeChildren(e) {
    for (var count = e.childNodes.length; count > 0; --count)
      e.removeChild(e.firstChild);
    return e;
  }

  function removeChildrenAndAdd(parent, e) {
    return removeChildren(parent).appendChild(e);
  }

  function setTextContent(e, str) {
    if (ie_lt9) {
      e.innerHTML = "";
      e.appendChild(document.createTextNode(str));
    } else e.textContent = str;
  }

  function getRect(node) {
    return node.getBoundingClientRect();
  }
  CodeMirror.replaceGetRect = function(f) { getRect = f; };

  // FEATURE DETECTION

  // Detect drag-and-drop
  var dragAndDrop = function() {
    // There is *some* kind of drag-and-drop support in IE6-8, but I
    // couldn't get it to work yet.
    if (ie_lt9) return false;
    var div = elt('div');
    return "draggable" in div || "dragDrop" in div;
  }();

  // For a reason I have yet to figure out, some browsers disallow
  // word wrapping between certain characters *only* if a new inline
  // element is started between them. This makes it hard to reliably
  // measure the position of things, since that requires inserting an
  // extra span. This terribly fragile set of tests matches the
  // character combinations that suffer from this phenomenon on the
  // various browsers.
  function spanAffectsWrapping() { return false; }
  if (gecko) // Only for "$'"
    spanAffectsWrapping = function(str, i) {
      return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
    };
  else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
    spanAffectsWrapping = function(str, i) {
      return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
    };
  else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
    spanAffectsWrapping = function(str, i) {
      if (i > 1 && str.charCodeAt(i - 1) == 45) {
        if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
        if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
      }
      return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
    };

  var knownScrollbarWidth;
  function scrollbarWidth(measure) {
    if (knownScrollbarWidth != null) return knownScrollbarWidth;
    var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
    removeChildrenAndAdd(measure, test);
    if (test.offsetWidth)
      knownScrollbarWidth = test.offsetHeight - test.clientHeight;
    return knownScrollbarWidth || 0;
  }

  var zwspSupported;
  function zeroWidthElement(measure) {
    if (zwspSupported == null) {
      var test = elt("span", "\u200b");
      removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
      if (measure.firstChild.offsetHeight != 0)
        zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
    }
    if (zwspSupported) return elt("span", "\u200b");
    else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
  }

  // See if "".split is the broken IE version, if so, provide an
  // alternative way to split lines.
  var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
    var pos = 0, result = [], l = string.length;
    while (pos <= l) {
      var nl = string.indexOf("\n", pos);
      if (nl == -1) nl = string.length;
      var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
      var rt = line.indexOf("\r");
      if (rt != -1) {
        result.push(line.slice(0, rt));
        pos += rt + 1;
      } else {
        result.push(line);
        pos = nl + 1;
      }
    }
    return result;
  } : function(string){return string.split(/\r\n?|\n/);};
  CodeMirror.splitLines = splitLines;

  var hasSelection = window.getSelection ? function(te) {
    try { return te.selectionStart != te.selectionEnd; }
    catch(e) { return false; }
  } : function(te) {
    try {var range = te.ownerDocument.selection.createRange();}
    catch(e) {}
    if (!range || range.parentElement() != te) return false;
    return range.compareEndPoints("StartToEnd", range) != 0;
  };

  var hasCopyEvent = (function() {
    var e = elt("div");
    if ("oncopy" in e) return true;
    e.setAttribute("oncopy", "return;");
    return typeof e.oncopy == 'function';
  })();

  // KEY NAMING

  var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
                  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
                  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
                  46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
                  186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
                  221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
                  63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
  CodeMirror.keyNames = keyNames;
  (function() {
    // Number keys
    for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
    // Alphabetic keys
    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
    // Function keys
    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
  })();

  // BIDI HELPERS

  function iterateBidiSections(order, from, to, f) {
    if (!order) return f(from, to, "ltr");
    var found = false;
    for (var i = 0; i < order.length; ++i) {
      var part = order[i];
      if (part.from < to && part.to > from || from == to && part.to == from) {
        f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
        found = true;
      }
    }
    if (!found) f(from, to, "ltr");
  }

  function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
  function bidiRight(part) { return part.level % 2 ? part.from : part.to; }

  function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
  function lineRight(line) {
    var order = getOrder(line);
    if (!order) return line.text.length;
    return bidiRight(lst(order));
  }

  function lineStart(cm, lineN) {
    var line = getLine(cm.doc, lineN);
    var visual = visualLine(cm.doc, line);
    if (visual != line) lineN = lineNo(visual);
    var order = getOrder(visual);
    var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
    return Pos(lineN, ch);
  }
  function lineEnd(cm, lineN) {
    var merged, line;
    while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
      lineN = merged.find().to.line;
    var order = getOrder(line);
    var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
    return Pos(lineN, ch);
  }

  function compareBidiLevel(order, a, b) {
    var linedir = order[0].level;
    if (a == linedir) return true;
    if (b == linedir) return false;
    return a < b;
  }
  var bidiOther;
  function getBidiPartAt(order, pos) {
    for (var i = 0, found; i < order.length; ++i) {
      var cur = order[i];
      if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
      if (cur.from == pos || cur.to == pos) {
        if (found == null) {
          found = i;
        } else if (compareBidiLevel(order, cur.level, order[found].level)) {
          bidiOther = found;
          return i;
        } else {
          bidiOther = i;
          return found;
        }
      }
    }
    bidiOther = null;
    return found;
  }

  function moveInLine(line, pos, dir, byUnit) {
    if (!byUnit) return pos + dir;
    do pos += dir;
    while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
    return pos;
  }

  // This is somewhat involved. It is needed in order to move
  // 'visually' through bi-directional text -- i.e., pressing left
  // should make the cursor go left, even when in RTL text. The
  // tricky part is the 'jumps', where RTL and LTR text touch each
  // other. This often requires the cursor offset to move more than
  // one unit, in order to visually move one unit.
  function moveVisually(line, start, dir, byUnit) {
    var bidi = getOrder(line);
    if (!bidi) return moveLogically(line, start, dir, byUnit);
    var pos = getBidiPartAt(bidi, start), part = bidi[pos];
    var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);

    for (;;) {
      if (target > part.from && target < part.to) return target;
      if (target == part.from || target == part.to) {
        if (getBidiPartAt(bidi, target) == pos) return target;
        part = bidi[pos += dir];
        return (dir > 0) == part.level % 2 ? part.to : part.from;
      } else {
        part = bidi[pos += dir];
        if (!part) return null;
        if ((dir > 0) == part.level % 2)
          target = moveInLine(line, part.to, -1, byUnit);
        else
          target = moveInLine(line, part.from, 1, byUnit);
      }
    }
  }

  function moveLogically(line, start, dir, byUnit) {
    var target = start + dir;
    if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
    return target < 0 || target > line.text.length ? null : target;
  }

  // Bidirectional ordering algorithm
  // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
  // that this (partially) implements.

  // One-char codes used for character types:
  // L (L):   Left-to-Right
  // R (R):   Right-to-Left
  // r (AL):  Right-to-Left Arabic
  // 1 (EN):  European Number
  // + (ES):  European Number Separator
  // % (ET):  European Number Terminator
  // n (AN):  Arabic Number
  // , (CS):  Common Number Separator
  // m (NSM): Non-Spacing Mark
  // b (BN):  Boundary Neutral
  // s (B):   Paragraph Separator
  // t (S):   Segment Separator
  // w (WS):  Whitespace
  // N (ON):  Other Neutrals

  // Returns null if characters are ordered as they appear
  // (left-to-right), or an array of sections ({from, to, level}
  // objects) in the order in which they occur visually.
  var bidiOrdering = (function() {
    // Character types for codepoints 0 to 0xff
    var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
    // Character types for codepoints 0x600 to 0x6ff
    var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
    function charType(code) {
      if (code <= 0xff) return lowTypes.charAt(code);
      else if (0x590 <= code && code <= 0x5f4) return "R";
      else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
      else if (0x700 <= code && code <= 0x8ac) return "r";
      else return "L";
    }

    var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
    var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
    // Browsers seem to always treat the boundaries of block elements as being L.
    var outerType = "L";

    return function(str) {
      if (!bidiRE.test(str)) return false;
      var len = str.length, types = [];
      for (var i = 0, type; i < len; ++i)
        types.push(type = charType(str.charCodeAt(i)));

      // W1. Examine each non-spacing mark (NSM) in the level run, and
      // change the type of the NSM to the type of the previous
      // character. If the NSM is at the start of the level run, it will
      // get the type of sor.
      for (var i = 0, prev = outerType; i < len; ++i) {
        var type = types[i];
        if (type == "m") types[i] = prev;
        else prev = type;
      }

      // W2. Search backwards from each instance of a European number
      // until the first strong type (R, L, AL, or sor) is found. If an
      // AL is found, change the type of the European number to Arabic
      // number.
      // W3. Change all ALs to R.
      for (var i = 0, cur = outerType; i < len; ++i) {
        var type = types[i];
        if (type == "1" && cur == "r") types[i] = "n";
        else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
      }

      // W4. A single European separator between two European numbers
      // changes to a European number. A single common separator between
      // two numbers of the same type changes to that type.
      for (var i = 1, prev = types[0]; i < len - 1; ++i) {
        var type = types[i];
        if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
        else if (type == "," && prev == types[i+1] &&
                 (prev == "1" || prev == "n")) types[i] = prev;
        prev = type;
      }

      // W5. A sequence of European terminators adjacent to European
      // numbers changes to all European numbers.
      // W6. Otherwise, separators and terminators change to Other
      // Neutral.
      for (var i = 0; i < len; ++i) {
        var type = types[i];
        if (type == ",") types[i] = "N";
        else if (type == "%") {
          for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
          var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
          for (var j = i; j < end; ++j) types[j] = replace;
          i = end - 1;
        }
      }

      // W7. Search backwards from each instance of a European number
      // until the first strong type (R, L, or sor) is found. If an L is
      // found, then change the type of the European number to L.
      for (var i = 0, cur = outerType; i < len; ++i) {
        var type = types[i];
        if (cur == "L" && type == "1") types[i] = "L";
        else if (isStrong.test(type)) cur = type;
      }

      // N1. A sequence of neutrals takes the direction of the
      // surrounding strong text if the text on both sides has the same
      // direction. European and Arabic numbers act as if they were R in
      // terms of their influence on neutrals. Start-of-level-run (sor)
      // and end-of-level-run (eor) are used at level run boundaries.
      // N2. Any remaining neutrals take the embedding direction.
      for (var i = 0; i < len; ++i) {
        if (isNeutral.test(types[i])) {
          for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
          var before = (i ? types[i-1] : outerType) == "L";
          var after = (end < len - 1 ? types[end] : outerType) == "L";
          var replace = before || after ? "L" : "R";
          for (var j = i; j < end; ++j) types[j] = replace;
          i = end - 1;
        }
      }

      // Here we depart from the documented algorithm, in order to avoid
      // building up an actual levels array. Since there are only three
      // levels (0, 1, 2) in an implementation that doesn't take
      // explicit embedding into account, we can build up the order on
      // the fly, without following the level-based algorithm.
      var order = [], m;
      for (var i = 0; i < len;) {
        if (countsAsLeft.test(types[i])) {
          var start = i;
          for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
          order.push({from: start, to: i, level: 0});
        } else {
          var pos = i, at = order.length;
          for (++i; i < len && types[i] != "L"; ++i) {}
          for (var j = pos; j < i;) {
            if (countsAsNum.test(types[j])) {
              if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
              var nstart = j;
              for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
              order.splice(at, 0, {from: nstart, to: j, level: 2});
              pos = j;
            } else ++j;
          }
          if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
        }
      }
      if (order[0].level == 1 && (m = str.match(/^\s+/))) {
        order[0].from = m[0].length;
        order.unshift({from: 0, to: m[0].length, level: 0});
      }
      if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
        lst(order).to -= m[0].length;
        order.push({from: len - m[0].length, to: len, level: 0});
      }
      if (order[0].level != lst(order).level)
        order.push({from: len, to: len, level: order[0].level});

      return order;
    };
  })();

  // THE END

  CodeMirror.version = "3.15.0";

  return CodeMirror;
})();

// TODO actually recognize syntax of TypeScript constructs

CodeMirror.defineMode("javascript", function(config, parserConfig) {
  var indentUnit = config.indentUnit;
  var statementIndent = parserConfig.statementIndent;
  var jsonMode = parserConfig.json;
  var isTS = parserConfig.typescript;

  // Tokenizer

  var keywords = function(){
    function kw(type) {return {type: type, style: "keyword"};}
    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
    var operator = kw("operator"), atom = {type: "atom", style: "atom"};

    var jsKeywords = {
      "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
      "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
      "var": kw("var"), "const": kw("var"), "let": kw("var"),
      "function": kw("function"), "catch": kw("catch"),
      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
      "in": operator, "typeof": operator, "instanceof": operator,
      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
      "this": kw("this")
    };

    // Extend the 'normal' keywords with the TypeScript language extensions
    if (isTS) {
      var type = {type: "variable", style: "variable-3"};
      var tsKeywords = {
        // object-like things
        "interface": kw("interface"),
        "class": kw("class"),
        "extends": kw("extends"),
        "constructor": kw("constructor"),

        // scope modifiers
        "public": kw("public"),
        "private": kw("private"),
        "protected": kw("protected"),
        "static": kw("static"),

        "super": kw("super"),

        // types
        "string": type, "number": type, "bool": type, "any": type
      };

      for (var attr in tsKeywords) {
        jsKeywords[attr] = tsKeywords[attr];
      }
    }

    return jsKeywords;
  }();

  var isOperatorChar = /[+\-*&%=<>!?|~^]/;

  function chain(stream, state, f) {
    state.tokenize = f;
    return f(stream, state);
  }

  function nextUntilUnescaped(stream, end) {
    var escaped = false, next;
    while ((next = stream.next()) != null) {
      if (next == end && !escaped)
        return false;
      escaped = !escaped && next == "\\";
    }
    return escaped;
  }

  // Used as scratch variables to communicate multiple values without
  // consing up tons of objects.
  var type, content;
  function ret(tp, style, cont) {
    type = tp; content = cont;
    return style;
  }

  function jsTokenBase(stream, state) {
    var ch = stream.next();
    if (ch == '"' || ch == "'")
      return chain(stream, state, jsTokenString(ch));
    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
      return ret(ch);
    else if (ch == "0" && stream.eat(/x/i)) {
      stream.eatWhile(/[\da-f]/i);
      return ret("number", "number");
    }
    else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
      return ret("number", "number");
    }
    else if (ch == "/") {
      if (stream.eat("*")) {
        return chain(stream, state, jsTokenComment);
      }
      else if (stream.eat("/")) {
        stream.skipToEnd();
        return ret("comment", "comment");
      }
      else if (state.lastType == "operator" || state.lastType == "keyword c" ||
               /^[\[{}\(,;:]$/.test(state.lastType)) {
        nextUntilUnescaped(stream, "/");
        stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
        return ret("regexp", "string-2");
      }
      else {
        stream.eatWhile(isOperatorChar);
        return ret("operator", null, stream.current());
      }
    }
    else if (ch == "#") {
      stream.skipToEnd();
      return ret("error", "error");
    }
    else if (isOperatorChar.test(ch)) {
      stream.eatWhile(isOperatorChar);
      return ret("operator", null, stream.current());
    }
    else {
      stream.eatWhile(/[\w\$_]/);
      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
                     ret("variable", "variable", word);
    }
  }

  function jsTokenString(quote) {
    return function(stream, state) {
      if (!nextUntilUnescaped(stream, quote))
        state.tokenize = jsTokenBase;
      return ret("string", "string");
    };
  }

  function jsTokenComment(stream, state) {
    var maybeEnd = false, ch;
    while (ch = stream.next()) {
      if (ch == "/" && maybeEnd) {
        state.tokenize = jsTokenBase;
        break;
      }
      maybeEnd = (ch == "*");
    }
    return ret("comment", "comment");
  }

  // Parser

  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};

  function JSLexical(indented, column, type, align, prev, info) {
    this.indented = indented;
    this.column = column;
    this.type = type;
    this.prev = prev;
    this.info = info;
    if (align != null) this.align = align;
  }

  function inScope(state, varname) {
    for (var v = state.localVars; v; v = v.next)
      if (v.name == varname) return true;
  }

  function parseJS(state, style, type, content, stream) {
    var cc = state.cc;
    // Communicate our context to the combinators.
    // (Less wasteful than consing up a hundred closures on every call.)
    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;

    if (!state.lexical.hasOwnProperty("align"))
      state.lexical.align = true;

    while(true) {
      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
      if (combinator(type, content)) {
        while(cc.length && cc[cc.length - 1].lex)
          cc.pop()();
        if (cx.marked) return cx.marked;
        if (type == "variable" && inScope(state, content)) return "variable-2";
        return style;
      }
    }
  }

  // Combinator utils

  var cx = {state: null, column: null, marked: null, cc: null};
  function pass() {
    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
  }
  function cont() {
    pass.apply(null, arguments);
    return true;
  }
  function register(varname) {
    function inList(list) {
      for (var v = list; v; v = v.next)
        if (v.name == varname) return true;
      return false;
    }
    var state = cx.state;
    if (state.context) {
      cx.marked = "def";
      if (inList(state.localVars)) return;
      state.localVars = {name: varname, next: state.localVars};
    } else {
      if (inList(state.globalVars)) return;
      state.globalVars = {name: varname, next: state.globalVars};
    }
  }

  // Combinators

  var defaultVars = {name: "this", next: {name: "arguments"}};
  function pushcontext() {
    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
    cx.state.localVars = defaultVars;
  }
  function popcontext() {
    cx.state.localVars = cx.state.context.vars;
    cx.state.context = cx.state.context.prev;
  }
  function pushlex(type, info) {
    var result = function() {
      var state = cx.state, indent = state.indented;
      if (state.lexical.type == "stat") indent = state.lexical.indented;
      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
    };
    result.lex = true;
    return result;
  }
  function poplex() {
    var state = cx.state;
    if (state.lexical.prev) {
      if (state.lexical.type == ")")
        state.indented = state.lexical.indented;
      state.lexical = state.lexical.prev;
    }
  }
  poplex.lex = true;

  function expect(wanted) {
    return function(type) {
      if (type == wanted) return cont();
      else if (wanted == ";") return pass();
      else return cont(arguments.callee);
    };
  }

  function statement(type) {
    if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
    if (type == "{") return cont(pushlex("}"), block, poplex);
    if (type == ";") return cont();
    if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
    if (type == "function") return cont(functiondef);
    if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
                                   poplex, statement, poplex);
    if (type == "variable") return cont(pushlex("stat"), maybelabel);
    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
                                      block, poplex, poplex);
    if (type == "case") return cont(expression, expect(":"));
    if (type == "default") return cont(expect(":"));
    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
                                     statement, poplex, popcontext);
    return pass(pushlex("stat"), expression, expect(";"), poplex);
  }
  function expression(type) {
    return expressionInner(type, false);
  }
  function expressionNoComma(type) {
    return expressionInner(type, true);
  }
  function expressionInner(type, noComma) {
    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
    if (type == "function") return cont(functiondef);
    if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
    if (type == "operator") return cont(noComma ? expressionNoComma : expression);
    if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);
    if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop);
    return cont();
  }
  function maybeexpression(type) {
    if (type.match(/[;\}\)\],]/)) return pass();
    return pass(expression);
  }
  function maybeexpressionNoComma(type) {
    if (type.match(/[;\}\)\],]/)) return pass();
    return pass(expressionNoComma);
  }

  function maybeoperatorComma(type, value) {
    if (type == ",") return cont(expression);
    return maybeoperatorNoComma(type, value, false);
  }
  function maybeoperatorNoComma(type, value, noComma) {
    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
    var expr = noComma == false ? expression : expressionNoComma;
    if (type == "operator") {
      if (/\+\+|--/.test(value)) return cont(me);
      if (value == "?") return cont(expression, expect(":"), expr);
      return cont(expr);
    }
    if (type == ";") return;
    if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
    if (type == ".") return cont(property, me);
    if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
  }
  function maybelabel(type) {
    if (type == ":") return cont(poplex, statement);
    return pass(maybeoperatorComma, expect(";"), poplex);
  }
  function property(type) {
    if (type == "variable") {cx.marked = "property"; return cont();}
  }
  function objprop(type, value) {
    if (type == "variable") {
      cx.marked = "property";
      if (value == "get" || value == "set") return cont(getterSetter);
    } else if (type == "number" || type == "string") {
      cx.marked = type + " property";
    }
    if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma);
  }
  function getterSetter(type) {
    if (type == ":") return cont(expression);
    if (type != "variable") return cont(expect(":"), expression);
    cx.marked = "property";
    return cont(functiondef);
  }
  function commasep(what, end) {
    function proceed(type) {
      if (type == ",") {
        var lex = cx.state.lexical;
        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
        return cont(what, proceed);
      }
      if (type == end) return cont();
      return cont(expect(end));
    }
    return function(type) {
      if (type == end) return cont();
      else return pass(what, proceed);
    };
  }
  function block(type) {
    if (type == "}") return cont();
    return pass(statement, block);
  }
  function maybetype(type) {
    if (type == ":") return cont(typedef);
    return pass();
  }
  function typedef(type) {
    if (type == "variable"){cx.marked = "variable-3"; return cont();}
    return pass();
  }
  function vardef1(type, value) {
    if (type == "variable") {
      register(value);
      return isTS ? cont(maybetype, vardef2) : cont(vardef2);
    }
    return pass();
  }
  function vardef2(type, value) {
    if (value == "=") return cont(expressionNoComma, vardef2);
    if (type == ",") return cont(vardef1);
  }
  function maybeelse(type, value) {
    if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
  }
  function forspec1(type) {
    if (type == "var") return cont(vardef1, expect(";"), forspec2);
    if (type == ";") return cont(forspec2);
    if (type == "variable") return cont(formaybein);
    return pass(expression, expect(";"), forspec2);
  }
  function formaybein(_type, value) {
    if (value == "in") return cont(expression);
    return cont(maybeoperatorComma, forspec2);
  }
  function forspec2(type, value) {
    if (type == ";") return cont(forspec3);
    if (value == "in") return cont(expression);
    return pass(expression, expect(";"), forspec3);
  }
  function forspec3(type) {
    if (type != ")") cont(expression);
  }
  function functiondef(type, value) {
    if (type == "variable") {register(value); return cont(functiondef);}
    if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
  }
  function funarg(type, value) {
    if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
  }

  // Interface

  return {
    startState: function(basecolumn) {
      return {
        tokenize: jsTokenBase,
        lastType: null,
        cc: [],
        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
        localVars: parserConfig.localVars,
        globalVars: parserConfig.globalVars,
        context: parserConfig.localVars && {vars: parserConfig.localVars},
        indented: 0
      };
    },

    token: function(stream, state) {
      if (stream.sol()) {
        if (!state.lexical.hasOwnProperty("align"))
          state.lexical.align = false;
        state.indented = stream.indentation();
      }
      if (state.tokenize != jsTokenComment && stream.eatSpace()) return null;
      var style = state.tokenize(stream, state);
      if (type == "comment") return style;
      state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
      return parseJS(state, style, type, content, stream);
    },

    indent: function(state, textAfter) {
      if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
      if (state.tokenize != jsTokenBase) return 0;
      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
      // Kludge to prevent 'maybelse' from blocking lexical scope pops
      for (var i = state.cc.length - 1; i >= 0; --i) {
        var c = state.cc[i];
        if (c == poplex) lexical = lexical.prev;
        else if (c != maybeelse || /^else\b/.test(textAfter)) break;
      }
      if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
      if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
        lexical = lexical.prev;
      var type = lexical.type, closing = firstChar == type;

      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
      else if (type == "form" && firstChar == "{") return lexical.indented;
      else if (type == "form") return lexical.indented + indentUnit;
      else if (type == "stat")
        return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
      else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
      else return lexical.indented + (closing ? 0 : indentUnit);
    },

    electricChars: ":{}",
    blockCommentStart: jsonMode ? null : "/*",
    blockCommentEnd: jsonMode ? null : "*/",
    lineComment: jsonMode ? null : "//",
    fold: "brace",

    helperType: jsonMode ? "json" : "javascript",
    jsonMode: jsonMode
  };
});

CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });

CodeMirror.defineMode("xml", function(config, parserConfig) {
  var indentUnit = config.indentUnit;
  var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
  var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true;

  var Kludges = parserConfig.htmlMode ? {
    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
                      'track': true, 'wbr': true},
    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
                       'th': true, 'tr': true},
    contextGrabbers: {
      'dd': {'dd': true, 'dt': true},
      'dt': {'dd': true, 'dt': true},
      'li': {'li': true},
      'option': {'option': true, 'optgroup': true},
      'optgroup': {'optgroup': true},
      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
      'rp': {'rp': true, 'rt': true},
      'rt': {'rp': true, 'rt': true},
      'tbody': {'tbody': true, 'tfoot': true},
      'td': {'td': true, 'th': true},
      'tfoot': {'tbody': true},
      'th': {'td': true, 'th': true},
      'thead': {'tbody': true, 'tfoot': true},
      'tr': {'tr': true}
    },
    doNotIndent: {"pre": true},
    allowUnquoted: true,
    allowMissing: true
  } : {
    autoSelfClosers: {},
    implicitlyClosed: {},
    contextGrabbers: {},
    doNotIndent: {},
    allowUnquoted: false,
    allowMissing: false
  };
  var alignCDATA = parserConfig.alignCDATA;

  // Return variables for tokenizers
  var tagName, type;

  function inText(stream, state) {
    function chain(parser) {
      state.tokenize = parser;
      return parser(stream, state);
    }

    var ch = stream.next();
    if (ch == "<") {
      if (stream.eat("!")) {
        if (stream.eat("[")) {
          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
          else return null;
        } else if (stream.match("--")) {
          return chain(inBlock("comment", "-->"));
        } else if (stream.match("DOCTYPE", true, true)) {
          stream.eatWhile(/[\w\._\-]/);
          return chain(doctype(1));
        } else {
          return null;
        }
      } else if (stream.eat("?")) {
        stream.eatWhile(/[\w\._\-]/);
        state.tokenize = inBlock("meta", "?>");
        return "meta";
      } else {
        var isClose = stream.eat("/");
        tagName = "";
        var c;
        while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
        if (!tagName) return "error";
        type = isClose ? "closeTag" : "openTag";
        state.tokenize = inTag;
        return "tag";
      }
    } else if (ch == "&") {
      var ok;
      if (stream.eat("#")) {
        if (stream.eat("x")) {
          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
        } else {
          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
        }
      } else {
        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
      }
      return ok ? "atom" : "error";
    } else {
      stream.eatWhile(/[^&<]/);
      return null;
    }
  }

  function inTag(stream, state) {
    var ch = stream.next();
    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
      state.tokenize = inText;
      type = ch == ">" ? "endTag" : "selfcloseTag";
      return "tag";
    } else if (ch == "=") {
      type = "equals";
      return null;
    } else if (ch == "<") {
      return "error";
    } else if (/[\'\"]/.test(ch)) {
      state.tokenize = inAttribute(ch);
      state.stringStartCol = stream.column();
      return state.tokenize(stream, state);
    } else {
      stream.eatWhile(/[^\s\u00a0=<>\"\']/);
      return "word";
    }
  }

  function inAttribute(quote) {
    var closure = function(stream, state) {
      while (!stream.eol()) {
        if (stream.next() == quote) {
          state.tokenize = inTag;
          break;
        }
      }
      return "string";
    };
    closure.isInAttribute = true;
    return closure;
  }

  function inBlock(style, terminator) {
    return function(stream, state) {
      while (!stream.eol()) {
        if (stream.match(terminator)) {
          state.tokenize = inText;
          break;
        }
        stream.next();
      }
      return style;
    };
  }
  function doctype(depth) {
    return function(stream, state) {
      var ch;
      while ((ch = stream.next()) != null) {
        if (ch == "<") {
          state.tokenize = doctype(depth + 1);
          return state.tokenize(stream, state);
        } else if (ch == ">") {
          if (depth == 1) {
            state.tokenize = inText;
            break;
          } else {
            state.tokenize = doctype(depth - 1);
            return state.tokenize(stream, state);
          }
        }
      }
      return "meta";
    };
  }

  var curState, curStream, setStyle;
  function pass() {
    for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
  }
  function cont() {
    pass.apply(null, arguments);
    return true;
  }

  function pushContext(tagName, startOfLine) {
    var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
    curState.context = {
      prev: curState.context,
      tagName: tagName,
      indent: curState.indented,
      startOfLine: startOfLine,
      noIndent: noIndent
    };
  }
  function popContext() {
    if (curState.context) curState.context = curState.context.prev;
  }

  function element(type) {
    if (type == "openTag") {
      curState.tagName = tagName;
      curState.tagStart = curStream.column();
      return cont(attributes, endtag(curState.startOfLine));
    } else if (type == "closeTag") {
      var err = false;
      if (curState.context) {
        if (curState.context.tagName != tagName) {
          if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
            popContext();
          }
          err = !curState.context || curState.context.tagName != tagName;
        }
      } else {
        err = true;
      }
      if (err) setStyle = "error";
      return cont(endclosetag(err));
    }
    return cont();
  }
  function endtag(startOfLine) {
    return function(type) {
      var tagName = curState.tagName;
      curState.tagName = curState.tagStart = null;
      if (type == "selfcloseTag" ||
          (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
        maybePopContext(tagName.toLowerCase());
        return cont();
      }
      if (type == "endTag") {
        maybePopContext(tagName.toLowerCase());
        pushContext(tagName, startOfLine);
        return cont();
      }
      return cont();
    };
  }
  function endclosetag(err) {
    return function(type) {
      if (err) setStyle = "error";
      if (type == "endTag") { popContext(); return cont(); }
      setStyle = "error";
      return cont(arguments.callee);
    };
  }
  function maybePopContext(nextTagName) {
    var parentTagName;
    while (true) {
      if (!curState.context) {
        return;
      }
      parentTagName = curState.context.tagName.toLowerCase();
      if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
          !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
        return;
      }
      popContext();
    }
  }

  function attributes(type) {
    if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
    if (type == "endTag" || type == "selfcloseTag") return pass();
    setStyle = "error";
    return cont(attributes);
  }
  function attribute(type) {
    if (type == "equals") return cont(attvalue, attributes);
    if (!Kludges.allowMissing) setStyle = "error";
    else if (type == "word") setStyle = "attribute";
    return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
  }
  function attvalue(type) {
    if (type == "string") return cont(attvaluemaybe);
    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
    setStyle = "error";
    return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
  }
  function attvaluemaybe(type) {
    if (type == "string") return cont(attvaluemaybe);
    else return pass();
  }

  return {
    startState: function() {
      return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null};
    },

    token: function(stream, state) {
      if (!state.tagName && stream.sol()) {
        state.startOfLine = true;
        state.indented = stream.indentation();
      }
      if (stream.eatSpace()) return null;

      setStyle = type = tagName = null;
      var style = state.tokenize(stream, state);
      state.type = type;
      if ((style || type) && style != "comment") {
        curState = state; curStream = stream;
        while (true) {
          var comb = state.cc.pop() || element;
          if (comb(type || style)) break;
        }
      }
      state.startOfLine = false;
      return setStyle || style;
    },

    indent: function(state, textAfter, fullLine) {
      var context = state.context;
      // Indent multi-line strings (e.g. css).
      if (state.tokenize.isInAttribute) {
        return state.stringStartCol + 1;
      }
      if ((state.tokenize != inTag && state.tokenize != inText) ||
          context && context.noIndent)
        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
      // Indent the starts of attribute names.
      if (state.tagName) {
        if (multilineTagIndentPastTag)
          return state.tagStart + state.tagName.length + 2;
        else
          return state.tagStart + indentUnit * multilineTagIndentFactor;
      }
      if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
      if (context && /^<\//.test(textAfter))
        context = context.prev;
      while (context && !context.startOfLine)
        context = context.prev;
      if (context) return context.indent + indentUnit;
      else return 0;
    },

    electricChars: "/",
    blockCommentStart: "<!--",
    blockCommentEnd: "-->",

    configuration: parserConfig.htmlMode ? "html" : "xml",
    helperType: parserConfig.htmlMode ? "html" : "xml"
  };
});

CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});

CodeMirror.defineMode("yaml", function() {

  var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
  var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');

  return {
    token: function(stream, state) {
      var ch = stream.peek();
      var esc = state.escaped;
      state.escaped = false;
      /* comments */
      if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
        stream.skipToEnd(); return "comment";
      }
      if (state.literal && stream.indentation() > state.keyCol) {
        stream.skipToEnd(); return "string";
      } else if (state.literal) { state.literal = false; }
      if (stream.sol()) {
        state.keyCol = 0;
        state.pair = false;
        state.pairStart = false;
        /* document start */
        if(stream.match(/---/)) { return "def"; }
        /* document end */
        if (stream.match(/\.\.\./)) { return "def"; }
        /* array list item */
        if (stream.match(/\s*-\s+/)) { return 'meta'; }
      }
      /* pairs (associative arrays) -> key */
      if (!state.pair && stream.match(/^\s*([a-z0-9\._-])+(?=\s*:)/i)) {
        state.pair = true;
        state.keyCol = stream.indentation();
        return "atom";
      }
      if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }

      /* inline pairs/lists */
      if (stream.match(/^(\{|\}|\[|\])/)) {
        if (ch == '{')
          state.inlinePairs++;
        else if (ch == '}')
          state.inlinePairs--;
        else if (ch == '[')
          state.inlineList++;
        else
          state.inlineList--;
        return 'meta';
      }

      /* list seperator */
      if (state.inlineList > 0 && !esc && ch == ',') {
        stream.next();
        return 'meta';
      }
      /* pairs seperator */
      if (state.inlinePairs > 0 && !esc && ch == ',') {
        state.keyCol = 0;
        state.pair = false;
        state.pairStart = false;
        stream.next();
        return 'meta';
      }

      /* start of value of a pair */
      if (state.pairStart) {
        /* block literals */
        if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
        /* references */
        if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
        /* numbers */
        if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
        if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
        /* keywords */
        if (stream.match(keywordRegex)) { return 'keyword'; }
      }

      /* nothing found, continue */
      state.pairStart = false;
      state.escaped = (ch == '\\');
      stream.next();
      return null;
    },
    startState: function() {
      return {
        pair: false,
        pairStart: false,
        keyCol: 0,
        inlinePairs: 0,
        inlineList: 0,
        literal: false,
        escaped: false
      };
    }
  };
});

CodeMirror.defineMIME("text/x-yaml", "yaml");

// Open simple dialogs on top of an editor. Relies on dialog.css.

(function() {
  function dialogDiv(cm, template, bottom) {
    var wrap = cm.getWrapperElement();
    var dialog;
    dialog = wrap.appendChild(document.createElement("div"));
    if (bottom) {
      dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
    } else {
      dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
    }
    dialog.innerHTML = template;
    return dialog;
  }

  CodeMirror.defineExtension("openDialog", function(template, callback, options) {
    var dialog = dialogDiv(this, template, options && options.bottom);
    var closed = false, me = this;
    function close() {
      if (closed) return;
      closed = true;
      dialog.parentNode.removeChild(dialog);
    }
    var inp = dialog.getElementsByTagName("input")[0], button;
    if (inp) {
      CodeMirror.on(inp, "keydown", function(e) {
        if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
        if (e.keyCode == 13 || e.keyCode == 27) {
          CodeMirror.e_stop(e);
          close();
          me.focus();
          if (e.keyCode == 13) callback(inp.value);
        }
      });
      if (options && options.onKeyUp) {
        CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
      }
      if (options && options.value) inp.value = options.value;
      inp.focus();
      CodeMirror.on(inp, "blur", close);
    } else if (button = dialog.getElementsByTagName("button")[0]) {
      CodeMirror.on(button, "click", function() {
        close();
        me.focus();
      });
      button.focus();
      CodeMirror.on(button, "blur", close);
    }
    return close;
  });

  CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
    var dialog = dialogDiv(this, template, options && options.bottom);
    var buttons = dialog.getElementsByTagName("button");
    var closed = false, me = this, blurring = 1;
    function close() {
      if (closed) return;
      closed = true;
      dialog.parentNode.removeChild(dialog);
      me.focus();
    }
    buttons[0].focus();
    for (var i = 0; i < buttons.length; ++i) {
      var b = buttons[i];
      (function(callback) {
        CodeMirror.on(b, "click", function(e) {
          CodeMirror.e_preventDefault(e);
          close();
          if (callback) callback(me);
        });
      })(callbacks[i]);
      CodeMirror.on(b, "blur", function() {
        --blurring;
        setTimeout(function() { if (blurring <= 0) close(); }, 200);
      });
      CodeMirror.on(b, "focus", function() { ++blurring; });
    }
  });
})();

// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.

// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.

(function() {
  function searchOverlay(query) {
    if (typeof query == "string") return {token: function(stream) {
      if (stream.match(query)) return "searching";
      stream.next();
      stream.skipTo(query.charAt(0)) || stream.skipToEnd();
    }};
    return {token: function(stream) {
      if (stream.match(query)) return "searching";
      while (!stream.eol()) {
        stream.next();
        if (stream.match(query, false)) break;
      }
    }};
  }

  function SearchState() {
    this.posFrom = this.posTo = this.query = null;
    this.overlay = null;
  }
  function getSearchState(cm) {
    return cm.state.search || (cm.state.search = new SearchState());
  }
  function getSearchCursor(cm, query, pos) {
    // Heuristic: if the query string is all lowercase, do a case insensitive search.
    return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase());
  }
  function dialog(cm, text, shortText, f) {
    if (cm.openDialog) cm.openDialog(text, f);
    else f(prompt(shortText, ""));
  }
  function confirmDialog(cm, text, shortText, fs) {
    if (cm.openConfirm) cm.openConfirm(text, fs);
    else if (confirm(shortText)) fs[0]();
  }
  function parseQuery(query) {
    var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
    return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query;
  }
  var queryDialog =
    'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
  function doSearch(cm, rev) {
    var state = getSearchState(cm);
    if (state.query) return findNext(cm, rev);
    dialog(cm, queryDialog, "Search for:", function(query) {
      cm.operation(function() {
        if (!query || state.query) return;
        state.query = parseQuery(query);
        cm.removeOverlay(state.overlay);
        state.overlay = searchOverlay(state.query);
        cm.addOverlay(state.overlay);
        state.posFrom = state.posTo = cm.getCursor();
        findNext(cm, rev);
      });
    });
  }
  function findNext(cm, rev) {cm.operation(function() {
    var state = getSearchState(cm);
    var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
    if (!cursor.find(rev)) {
      cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
      if (!cursor.find(rev)) return;
    }
    cm.setSelection(cursor.from(), cursor.to());
    state.posFrom = cursor.from(); state.posTo = cursor.to();
  });}
  function clearSearch(cm) {cm.operation(function() {
    var state = getSearchState(cm);
    if (!state.query) return;
    state.query = null;
    cm.removeOverlay(state.overlay);
  });}

  var replaceQueryDialog =
    'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
  var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
  var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
  function replace(cm, all) {
    dialog(cm, replaceQueryDialog, "Replace:", function(query) {
      if (!query) return;
      query = parseQuery(query);
      dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
        if (all) {
          cm.operation(function() {
            for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
              if (typeof query != "string") {
                var match = cm.getRange(cursor.from(), cursor.to()).match(query);
                cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];}));
              } else cursor.replace(text);
            }
          });
        } else {
          clearSearch(cm);
          var cursor = getSearchCursor(cm, query, cm.getCursor());
          var advance = function() {
            var start = cursor.from(), match;
            if (!(match = cursor.findNext())) {
              cursor = getSearchCursor(cm, query);
              if (!(match = cursor.findNext()) ||
                  (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
            }
            cm.setSelection(cursor.from(), cursor.to());
            confirmDialog(cm, doReplaceConfirm, "Replace?",
                          [function() {doReplace(match);}, advance]);
          };
          var doReplace = function(match) {
            cursor.replace(typeof query == "string" ? text :
                           text.replace(/\$(\d)/, function(_, i) {return match[i];}));
            advance();
          };
          advance();
        }
      });
    });
  }

  CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
  CodeMirror.commands.findNext = doSearch;
  CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
  CodeMirror.commands.clearSearch = clearSearch;
  CodeMirror.commands.replace = replace;
  CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
})();

(function(){
  var Pos = CodeMirror.Pos;

  function SearchCursor(doc, query, pos, caseFold) {
    this.atOccurrence = false; this.doc = doc;
    if (caseFold == null && typeof query == "string") caseFold = false;

    pos = pos ? doc.clipPos(pos) : Pos(0, 0);
    this.pos = {from: pos, to: pos};

    // The matches method is filled in based on the type of query.
    // It takes a position and a direction, and returns an object
    // describing the next occurrence of the query, or null if no
    // more matches were found.
    if (typeof query != "string") { // Regexp match
      if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
      this.matches = function(reverse, pos) {
        if (reverse) {
          query.lastIndex = 0;
          var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
          for (;;) {
            query.lastIndex = cutOff;
            var newMatch = query.exec(line);
            if (!newMatch) break;
            match = newMatch;
            start = match.index;
            cutOff = match.index + (match[0].length || 1);
            if (cutOff == line.length) break;
          }
          var matchLen = (match && match[0].length) || 0;
          if (!matchLen) {
            if (start == 0 && line.length == 0) {match = undefined;}
            else if (start != doc.getLine(pos.line).length) {
              matchLen++;
            }
          }
        } else {
          query.lastIndex = pos.ch;
          var line = doc.getLine(pos.line), match = query.exec(line);
          var matchLen = (match && match[0].length) || 0;
          var start = match && match.index;
          if (start + matchLen != line.length && !matchLen) matchLen = 1;
        }
        if (match && matchLen)
          return {from: Pos(pos.line, start),
                  to: Pos(pos.line, start + matchLen),
                  match: match};
      };
    } else { // String query
      if (caseFold) query = query.toLowerCase();
      var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
      var target = query.split("\n");
      // Different methods for single-line and multi-line queries
      if (target.length == 1) {
        if (!query.length) {
          // Empty string would match anything and never progress, so
          // we define it to match nothing instead.
          this.matches = function() {};
        } else {
          this.matches = function(reverse, pos) {
            var line = fold(doc.getLine(pos.line)), len = query.length, match;
            if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
                        : (match = line.indexOf(query, pos.ch)) != -1)
              return {from: Pos(pos.line, match),
                      to: Pos(pos.line, match + len)};
          };
        }
      } else {
        this.matches = function(reverse, pos) {
          var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln));
          var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
          if (reverse ? offsetA >= pos.ch || offsetA != match.length
              : offsetA <= pos.ch || offsetA != line.length - match.length)
            return;
          for (;;) {
            if (reverse ? !ln : ln == doc.lineCount() - 1) return;
            line = fold(doc.getLine(ln += reverse ? -1 : 1));
            match = target[reverse ? --idx : ++idx];
            if (idx > 0 && idx < target.length - 1) {
              if (line != match) return;
              else continue;
            }
            var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
            if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
              return;
            var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB);
            return {from: reverse ? end : start, to: reverse ? start : end};
          }
        };
      }
    }
  }

  SearchCursor.prototype = {
    findNext: function() {return this.find(false);},
    findPrevious: function() {return this.find(true);},

    find: function(reverse) {
      var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
      function savePosAndFail(line) {
        var pos = Pos(line, 0);
        self.pos = {from: pos, to: pos};
        self.atOccurrence = false;
        return false;
      }

      for (;;) {
        if (this.pos = this.matches(reverse, pos)) {
          if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); }
          this.atOccurrence = true;
          return this.pos.match || true;
        }
        if (reverse) {
          if (!pos.line) return savePosAndFail(0);
          pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);
        }
        else {
          var maxLine = this.doc.lineCount();
          if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
          pos = Pos(pos.line + 1, 0);
        }
      }
    },

    from: function() {if (this.atOccurrence) return this.pos.from;},
    to: function() {if (this.atOccurrence) return this.pos.to;},

    replace: function(newText) {
      if (!this.atOccurrence) return;
      var lines = CodeMirror.splitLines(newText);
      this.doc.replaceRange(lines, this.pos.from, this.pos.to);
      this.pos.to = Pos(this.pos.from.line + lines.length - 1,
                        lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
    }
  };

  CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
    return new SearchCursor(this.doc, query, pos, caseFold);
  });
  CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
    return new SearchCursor(this, query, pos, caseFold);
  });
})();

(function() {
  "use strict";
  var GUTTER_ID = "CodeMirror-lint-markers";
  var SEVERITIES = /^(?:error|warning)$/;

  function showTooltip(e, content) {
    var tt = document.createElement("div");
    tt.className = "CodeMirror-lint-tooltip";
    tt.appendChild(content.cloneNode(true));
    document.body.appendChild(tt);

    function position(e) {
      if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
      tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
      tt.style.left = (e.clientX + 5) + "px";
    }
    CodeMirror.on(document, "mousemove", position);
    position(e);
    if (tt.style.opacity != null) tt.style.opacity = 1;
    return tt;
  }
  function rm(elt) {
    if (elt.parentNode) elt.parentNode.removeChild(elt);
  }
  function hideTooltip(tt) {
    if (!tt.parentNode) return;
    if (tt.style.opacity == null) rm(tt);
    tt.style.opacity = 0;
    setTimeout(function() { rm(tt); }, 600);
  }

  function showTooltipFor(e, content, node) {
    var tooltip = showTooltip(e, content);
    function hide() {
      CodeMirror.off(node, "mouseout", hide);
      if (tooltip) { hideTooltip(tooltip); tooltip = null; }
    }
    var poll = setInterval(function() {
      if (tooltip) for (var n = node;; n = n.parentNode) {
        if (n == document.body) return;
        if (!n) { hide(); break; }
      }
      if (!tooltip) return clearInterval(poll);
    }, 400);
    CodeMirror.on(node, "mouseout", hide);
  }

  function LintState(cm, options, hasGutter) {
    this.marked = [];
    this.options = options;
    this.timeout = null;
    this.hasGutter = hasGutter;
    this.onMouseOver = function(e) { onMouseOver(cm, e); };
  }

  function parseOptions(cm, options) {
    if (options instanceof Function) return {getAnnotations: options};
    if (!options || options === true) options = {};
    if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
    if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
    return options;
  }

  function clearMarks(cm) {
    var state = cm.state.lint;
    if (state.hasGutter) cm.clearGutter(GUTTER_ID);
    for (var i = 0; i < state.marked.length; ++i)
      state.marked[i].clear();
    state.marked.length = 0;
  }

  function makeMarker(labels, severity, multiple, tooltips) {
    var marker = document.createElement("div"), inner = marker;
    marker.className = "CodeMirror-lint-marker-" + severity;
    if (multiple) {
      inner = marker.appendChild(document.createElement("div"));
      inner.className = "CodeMirror-lint-marker-multiple";
    }

    if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
      showTooltipFor(e, labels, inner);
    });

    return marker;
  }

  function getMaxSeverity(a, b) {
    if (a == "error") return a;
    else return b;
  }

  function groupByLine(annotations) {
    var lines = [];
    for (var i = 0; i < annotations.length; ++i) {
      var ann = annotations[i], line = ann.from.line;
      (lines[line] || (lines[line] = [])).push(ann);
    }
    return lines;
  }

  function annotationTooltip(ann) {
    var severity = ann.severity;
    if (!SEVERITIES.test(severity)) severity = "error";
    var tip = document.createElement("div");
    tip.className = "CodeMirror-lint-message-" + severity;
    tip.appendChild(document.createTextNode(ann.message));
    return tip;
  }

  function startLinting(cm) {
    var state = cm.state.lint, options = state.options;
    if (options.async)
      options.getAnnotations(cm, updateLinting, options);
    else
      updateLinting(cm, options.getAnnotations(cm.getValue()));
  }

  function updateLinting(cm, annotationsNotSorted) {
    clearMarks(cm);
    var state = cm.state.lint, options = state.options;

    var annotations = groupByLine(annotationsNotSorted);

    for (var line = 0; line < annotations.length; ++line) {
      var anns = annotations[line];
      if (!anns) continue;

      var maxSeverity = null;
      var tipLabel = state.hasGutter && document.createDocumentFragment();

      for (var i = 0; i < anns.length; ++i) {
        var ann = anns[i];
        var severity = ann.severity;
        if (!SEVERITIES.test(severity)) severity = "error";
        maxSeverity = getMaxSeverity(maxSeverity, severity);

        if (options.formatAnnotation) ann = options.formatAnnotation(ann);
        if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));

        if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
          className: "CodeMirror-lint-mark-" + severity,
          __annotation: ann
        }));
      }

      if (state.hasGutter)
        cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
                                                       state.options.tooltips));
    }
    if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
  }

  function onChange(cm) {
    var state = cm.state.lint;
    clearTimeout(state.timeout);
    state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
  }

  function popupSpanTooltip(ann, e) {
    var target = e.target || e.srcElement;
    showTooltipFor(e, annotationTooltip(ann), target);
  }

  // When the mouseover fires, the cursor might not actually be over
  // the character itself yet. These pairs of x,y offsets are used to
  // probe a few nearby points when no suitable marked range is found.
  var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];

  function onMouseOver(cm, e) {
    if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;
    for (var i = 0; i < nearby.length; i += 2) {
      var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],
                                                top: e.clientY + nearby[i + 1]}));
      for (var j = 0; j < spans.length; ++j) {
        var span = spans[j], ann = span.__annotation;
        if (ann) return popupSpanTooltip(ann, e);
      }
    }
  }

  function optionHandler(cm, val, old) {
    if (old && old != CodeMirror.Init) {
      clearMarks(cm);
      cm.off("change", onChange);
      CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
      delete cm.state.lint;
    }

    if (val) {
      var gutters = cm.getOption("gutters"), hasLintGutter = false;
      for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
      var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
      cm.on("change", onChange);
      if (state.options.tooltips != false)
        CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);

      startLinting(cm);
    }
  }

  CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated
  CodeMirror.defineOption("lint", false, optionHandler); // deprecated
})();

/**
 * @license AngularJS v1.3.20
 * (c) 2010-2014 Google, Inc. http://angularjs.org
 * License: MIT
 */
(function(window, document, undefined) {'use strict';

/**
 * @description
 *
 * This object provides a utility for producing rich Error messages within
 * Angular. It can be called as follows:
 *
 * var exampleMinErr = minErr('example');
 * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
 *
 * The above creates an instance of minErr in the example namespace. The
 * resulting error will have a namespaced error code of example.one.  The
 * resulting error will replace {0} with the value of foo, and {1} with the
 * value of bar. The object is not restricted in the number of arguments it can
 * take.
 *
 * If fewer arguments are specified than necessary for interpolation, the extra
 * interpolation markers will be preserved in the final string.
 *
 * Since data will be parsed statically during a build step, some restrictions
 * are applied with respect to how minErr instances are created and called.
 * Instances should have names of the form namespaceMinErr for a minErr created
 * using minErr('namespace') . Error codes, namespaces and template strings
 * should all be static strings, not variables or general expressions.
 *
 * @param {string} module The namespace to use for the new minErr instance.
 * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
 *   error from returned function, for cases when a particular type of error is useful.
 * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
 */

function minErr(module, ErrorConstructor) {
  ErrorConstructor = ErrorConstructor || Error;
  return function() {
    var code = arguments[0],
      prefix = '[' + (module ? module + ':' : '') + code + '] ',
      template = arguments[1],
      templateArgs = arguments,

      message, i;

    message = prefix + template.replace(/\{\d+\}/g, function(match) {
      var index = +match.slice(1, -1), arg;

      if (index + 2 < templateArgs.length) {
        return toDebugString(templateArgs[index + 2]);
      }
      return match;
    });

    message = message + '\nhttp://errors.angularjs.org/1.3.20/' +
      (module ? module + '/' : '') + code;
    for (i = 2; i < arguments.length; i++) {
      message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
        encodeURIComponent(toDebugString(arguments[i]));
    }
    return new ErrorConstructor(message);
  };
}

/* We need to tell jshint what variables are being exported */
/* global angular: true,
  msie: true,
  jqLite: true,
  jQuery: true,
  slice: true,
  splice: true,
  push: true,
  toString: true,
  ngMinErr: true,
  angularModule: true,
  uid: true,
  REGEX_STRING_REGEXP: true,
  VALIDITY_STATE_PROPERTY: true,

  lowercase: true,
  uppercase: true,
  manualLowercase: true,
  manualUppercase: true,
  nodeName_: true,
  isArrayLike: true,
  forEach: true,
  sortedKeys: true,
  forEachSorted: true,
  reverseParams: true,
  nextUid: true,
  setHashKey: true,
  extend: true,
  int: true,
  inherit: true,
  noop: true,
  identity: true,
  valueFn: true,
  isUndefined: true,
  isDefined: true,
  isObject: true,
  isString: true,
  isNumber: true,
  isDate: true,
  isArray: true,
  isFunction: true,
  isRegExp: true,
  isWindow: true,
  isScope: true,
  isFile: true,
  isFormData: true,
  isBlob: true,
  isBoolean: true,
  isPromiseLike: true,
  trim: true,
  escapeForRegexp: true,
  isElement: true,
  makeMap: true,
  includes: true,
  arrayRemove: true,
  copy: true,
  shallowCopy: true,
  equals: true,
  csp: true,
  concat: true,
  sliceArgs: true,
  bind: true,
  toJsonReplacer: true,
  toJson: true,
  fromJson: true,
  startingTag: true,
  tryDecodeURIComponent: true,
  parseKeyValue: true,
  toKeyValue: true,
  encodeUriSegment: true,
  encodeUriQuery: true,
  angularInit: true,
  bootstrap: true,
  getTestability: true,
  snake_case: true,
  bindJQuery: true,
  assertArg: true,
  assertArgFn: true,
  assertNotHasOwnProperty: true,
  getter: true,
  getBlockNodes: true,
  hasOwnProperty: true,
  createMap: true,

  NODE_TYPE_ELEMENT: true,
  NODE_TYPE_ATTRIBUTE: true,
  NODE_TYPE_TEXT: true,
  NODE_TYPE_COMMENT: true,
  NODE_TYPE_DOCUMENT: true,
  NODE_TYPE_DOCUMENT_FRAGMENT: true,
*/

////////////////////////////////////

/**
 * @ngdoc module
 * @name ng
 * @module ng
 * @description
 *
 * # ng (core module)
 * The ng module is loaded by default when an AngularJS application is started. The module itself
 * contains the essential components for an AngularJS application to function. The table below
 * lists a high level breakdown of each of the services/factories, filters, directives and testing
 * components available within this core module.
 *
 * <div doc-module-components="ng"></div>
 */

var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;

// The name of a form control's ValidityState property.
// This is used so that it's possible for internal tests to create mock ValidityStates.
var VALIDITY_STATE_PROPERTY = 'validity';

/**
 * @ngdoc function
 * @name angular.lowercase
 * @module ng
 * @kind function
 *
 * @description Converts the specified string to lowercase.
 * @param {string} string String to be converted to lowercase.
 * @returns {string} Lowercased string.
 */
var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
var hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * @ngdoc function
 * @name angular.uppercase
 * @module ng
 * @kind function
 *
 * @description Converts the specified string to uppercase.
 * @param {string} string String to be converted to uppercase.
 * @returns {string} Uppercased string.
 */
var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};


var manualLowercase = function(s) {
  /* jshint bitwise: false */
  return isString(s)
      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
      : s;
};
var manualUppercase = function(s) {
  /* jshint bitwise: false */
  return isString(s)
      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
      : s;
};


// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
// with correct but slower alternatives.
if ('i' !== 'I'.toLowerCase()) {
  lowercase = manualLowercase;
  uppercase = manualUppercase;
}


var
    msie,             // holds major version number for IE, or NaN if UA is not IE.
    jqLite,           // delay binding since jQuery could be loaded after us.
    jQuery,           // delay binding
    slice             = [].slice,
    splice            = [].splice,
    push              = [].push,
    toString          = Object.prototype.toString,
    ngMinErr          = minErr('ng'),

    /** @name angular */
    angular           = window.angular || (window.angular = {}),
    angularModule,
    uid               = 0;

/**
 * documentMode is an IE-only property
 * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
 */
msie = document.documentMode;


/**
 * @private
 * @param {*} obj
 * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
 *                   String ...)
 */
function isArrayLike(obj) {
  if (obj == null || isWindow(obj)) {
    return false;
  }

  // Support: iOS 8.2 (not reproducible in simulator)
  // "length" in obj used to prevent JIT error (gh-11508)
  var length = "length" in Object(obj) && obj.length;

  if (obj.nodeType === NODE_TYPE_ELEMENT && length) {
    return true;
  }

  return isString(obj) || isArray(obj) || length === 0 ||
         typeof length === 'number' && length > 0 && (length - 1) in obj;
}

/**
 * @ngdoc function
 * @name angular.forEach
 * @module ng
 * @kind function
 *
 * @description
 * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
 * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
 * is the value of an object property or an array element, `key` is the object property key or
 * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
 *
 * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
 * using the `hasOwnProperty` method.
 *
 * Unlike ES262's
 * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
 * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
 * return the value provided.
 *
   ```js
     var values = {name: 'misko', gender: 'male'};
     var log = [];
     angular.forEach(values, function(value, key) {
       this.push(key + ': ' + value);
     }, log);
     expect(log).toEqual(['name: misko', 'gender: male']);
   ```
 *
 * @param {Object|Array} obj Object to iterate over.
 * @param {Function} iterator Iterator function.
 * @param {Object=} context Object to become context (`this`) for the iterator function.
 * @returns {Object|Array} Reference to `obj`.
 */

function forEach(obj, iterator, context) {
  var key, length;
  if (obj) {
    if (isFunction(obj)) {
      for (key in obj) {
        // Need to check if hasOwnProperty exists,
        // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
        if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
          iterator.call(context, obj[key], key, obj);
        }
      }
    } else if (isArray(obj) || isArrayLike(obj)) {
      var isPrimitive = typeof obj !== 'object';
      for (key = 0, length = obj.length; key < length; key++) {
        if (isPrimitive || key in obj) {
          iterator.call(context, obj[key], key, obj);
        }
      }
    } else if (obj.forEach && obj.forEach !== forEach) {
        obj.forEach(iterator, context, obj);
    } else {
      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key, obj);
        }
      }
    }
  }
  return obj;
}

function sortedKeys(obj) {
  return Object.keys(obj).sort();
}

function forEachSorted(obj, iterator, context) {
  var keys = sortedKeys(obj);
  for (var i = 0; i < keys.length; i++) {
    iterator.call(context, obj[keys[i]], keys[i]);
  }
  return keys;
}


/**
 * when using forEach the params are value, key, but it is often useful to have key, value.
 * @param {function(string, *)} iteratorFn
 * @returns {function(*, string)}
 */
function reverseParams(iteratorFn) {
  return function(value, key) { iteratorFn(key, value); };
}

/**
 * A consistent way of creating unique IDs in angular.
 *
 * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
 * we hit number precision issues in JavaScript.
 *
 * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
 *
 * @returns {number} an unique alpha-numeric string
 */
function nextUid() {
  return ++uid;
}


/**
 * Set or clear the hashkey for an object.
 * @param obj object
 * @param h the hashkey (!truthy to delete the hashkey)
 */
function setHashKey(obj, h) {
  if (h) {
    obj.$$hashKey = h;
  } else {
    delete obj.$$hashKey;
  }
}

/**
 * @ngdoc function
 * @name angular.extend
 * @module ng
 * @kind function
 *
 * @description
 * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
 * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
 * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
 * Note: Keep in mind that `angular.extend` does not support recursive merge (deep copy).
 *
 * @param {Object} dst Destination object.
 * @param {...Object} src Source object(s).
 * @returns {Object} Reference to `dst`.
 */
function extend(dst) {
  var h = dst.$$hashKey;

  for (var i = 1, ii = arguments.length; i < ii; i++) {
    var obj = arguments[i];
    if (obj) {
      var keys = Object.keys(obj);
      for (var j = 0, jj = keys.length; j < jj; j++) {
        var key = keys[j];
        dst[key] = obj[key];
      }
    }
  }

  setHashKey(dst, h);
  return dst;
}

function int(str) {
  return parseInt(str, 10);
}


function inherit(parent, extra) {
  return extend(Object.create(parent), extra);
}

/**
 * @ngdoc function
 * @name angular.noop
 * @module ng
 * @kind function
 *
 * @description
 * A function that performs no operations. This function can be useful when writing code in the
 * functional style.
   ```js
     function foo(callback) {
       var result = calculateResult();
       (callback || angular.noop)(result);
     }
   ```
 */
function noop() {}
noop.$inject = [];


/**
 * @ngdoc function
 * @name angular.identity
 * @module ng
 * @kind function
 *
 * @description
 * A function that returns its first argument. This function is useful when writing code in the
 * functional style.
 *
   ```js
     function transformer(transformationFn, value) {
       return (transformationFn || angular.identity)(value);
     };
   ```
  * @param {*} value to be returned.
  * @returns {*} the value passed in.
 */
function identity($) {return $;}
identity.$inject = [];


function valueFn(value) {return function() {return value;};}

/**
 * @ngdoc function
 * @name angular.isUndefined
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is undefined.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is undefined.
 */
function isUndefined(value) {return typeof value === 'undefined';}


/**
 * @ngdoc function
 * @name angular.isDefined
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is defined.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is defined.
 */
function isDefined(value) {return typeof value !== 'undefined';}


/**
 * @ngdoc function
 * @name angular.isObject
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
 * considered to be objects. Note that JavaScript arrays are objects.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is an `Object` but not `null`.
 */
function isObject(value) {
  // http://jsperf.com/isobject4
  return value !== null && typeof value === 'object';
}


/**
 * @ngdoc function
 * @name angular.isString
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is a `String`.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is a `String`.
 */
function isString(value) {return typeof value === 'string';}


/**
 * @ngdoc function
 * @name angular.isNumber
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is a `Number`.
 *
 * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
 *
 * If you wish to exclude these then you can use the native
 * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
 * method.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is a `Number`.
 */
function isNumber(value) {return typeof value === 'number';}


/**
 * @ngdoc function
 * @name angular.isDate
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a value is a date.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is a `Date`.
 */
function isDate(value) {
  return toString.call(value) === '[object Date]';
}


/**
 * @ngdoc function
 * @name angular.isArray
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is an `Array`.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is an `Array`.
 */
var isArray = Array.isArray;

/**
 * @ngdoc function
 * @name angular.isFunction
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is a `Function`.
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is a `Function`.
 */
function isFunction(value) {return typeof value === 'function';}


/**
 * Determines if a value is a regular expression object.
 *
 * @private
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is a `RegExp`.
 */
function isRegExp(value) {
  return toString.call(value) === '[object RegExp]';
}


/**
 * Checks if `obj` is a window object.
 *
 * @private
 * @param {*} obj Object to check
 * @returns {boolean} True if `obj` is a window obj.
 */
function isWindow(obj) {
  return obj && obj.window === obj;
}


function isScope(obj) {
  return obj && obj.$evalAsync && obj.$watch;
}


function isFile(obj) {
  return toString.call(obj) === '[object File]';
}


function isFormData(obj) {
  return toString.call(obj) === '[object FormData]';
}


function isBlob(obj) {
  return toString.call(obj) === '[object Blob]';
}


function isBoolean(value) {
  return typeof value === 'boolean';
}


function isPromiseLike(obj) {
  return obj && isFunction(obj.then);
}


var trim = function(value) {
  return isString(value) ? value.trim() : value;
};

// Copied from:
// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
// Prereq: s is a string.
var escapeForRegexp = function(s) {
  return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
           replace(/\x08/g, '\\x08');
};


/**
 * @ngdoc function
 * @name angular.isElement
 * @module ng
 * @kind function
 *
 * @description
 * Determines if a reference is a DOM element (or wrapped jQuery element).
 *
 * @param {*} value Reference to check.
 * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
 */
function isElement(node) {
  return !!(node &&
    (node.nodeName  // we are a direct element
    || (node.prop && node.attr && node.find)));  // we have an on and find method part of jQuery API
}

/**
 * @param str 'key1,key2,...'
 * @returns {object} in the form of {key1:true, key2:true, ...}
 */
function makeMap(str) {
  var obj = {}, items = str.split(","), i;
  for (i = 0; i < items.length; i++)
    obj[items[i]] = true;
  return obj;
}


function nodeName_(element) {
  return lowercase(element.nodeName || (element[0] && element[0].nodeName));
}

function includes(array, obj) {
  return Array.prototype.indexOf.call(array, obj) != -1;
}

function arrayRemove(array, value) {
  var index = array.indexOf(value);
  if (index >= 0)
    array.splice(index, 1);
  return value;
}

/**
 * @ngdoc function
 * @name angular.copy
 * @module ng
 * @kind function
 *
 * @description
 * Creates a deep copy of `source`, which should be an object or an array.
 *
 * * If no destination is supplied, a copy of the object or array is created.
 * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
 *   are deleted and then all elements/properties from the source are copied to it.
 * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
 * * If `source` is identical to 'destination' an exception will be thrown.
 *
 * @param {*} source The source that will be used to make a copy.
 *                   Can be any type, including primitives, `null`, and `undefined`.
 * @param {(Object|Array)=} destination Destination into which the source is copied. If
 *     provided, must be of the same type as `source`.
 * @returns {*} The copy or updated `destination`, if `destination` was specified.
 *
 * @example
 <example module="copyExample">
 <file name="index.html">
 <div ng-controller="ExampleController">
 <form novalidate class="simple-form">
 Name: <input type="text" ng-model="user.name" /><br />
 E-mail: <input type="email" ng-model="user.email" /><br />
 Gender: <input type="radio" ng-model="user.gender" value="male" />male
 <input type="radio" ng-model="user.gender" value="female" />female<br />
 <button ng-click="reset()">RESET</button>
 <button ng-click="update(user)">SAVE</button>
 </form>
 <pre>form = {{user | json}}</pre>
 <pre>master = {{master | json}}</pre>
 </div>

 <script>
  angular.module('copyExample', [])
    .controller('ExampleController', ['$scope', function($scope) {
      $scope.master= {};

      $scope.update = function(user) {
        // Example with 1 argument
        $scope.master= angular.copy(user);
      };

      $scope.reset = function() {
        // Example with 2 arguments
        angular.copy($scope.master, $scope.user);
      };

      $scope.reset();
    }]);
 </script>
 </file>
 </example>
 */
function copy(source, destination, stackSource, stackDest) {
  if (isWindow(source) || isScope(source)) {
    throw ngMinErr('cpws',
      "Can't copy! Making copies of Window or Scope instances is not supported.");
  }

  if (!destination) {
    destination = source;
    if (source) {
      if (isArray(source)) {
        destination = copy(source, [], stackSource, stackDest);
      } else if (isDate(source)) {
        destination = new Date(source.getTime());
      } else if (isRegExp(source)) {
        destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
        destination.lastIndex = source.lastIndex;
      } else if (isObject(source)) {
        var emptyObject = Object.create(Object.getPrototypeOf(source));
        destination = copy(source, emptyObject, stackSource, stackDest);
      }
    }
  } else {
    if (source === destination) throw ngMinErr('cpi',
      "Can't copy! Source and destination are identical.");

    stackSource = stackSource || [];
    stackDest = stackDest || [];

    if (isObject(source)) {
      var index = stackSource.indexOf(source);
      if (index !== -1) return stackDest[index];

      stackSource.push(source);
      stackDest.push(destination);
    }

    var result;
    if (isArray(source)) {
      destination.length = 0;
      for (var i = 0; i < source.length; i++) {
        result = copy(source[i], null, stackSource, stackDest);
        if (isObject(source[i])) {
          stackSource.push(source[i]);
          stackDest.push(result);
        }
        destination.push(result);
      }
    } else {
      var h = destination.$$hashKey;
      if (isArray(destination)) {
        destination.length = 0;
      } else {
        forEach(destination, function(value, key) {
          delete destination[key];
        });
      }
      for (var key in source) {
        if (source.hasOwnProperty(key)) {
          result = copy(source[key], null, stackSource, stackDest);
          if (isObject(source[key])) {
            stackSource.push(source[key]);
            stackDest.push(result);
          }
          destination[key] = result;
        }
      }
      setHashKey(destination,h);
    }

  }
  return destination;
}

/**
 * Creates a shallow copy of an object, an array or a primitive.
 *
 * Assumes that there are no proto properties for objects.
 */
function shallowCopy(src, dst) {
  if (isArray(src)) {
    dst = dst || [];

    for (var i = 0, ii = src.length; i < ii; i++) {
      dst[i] = src[i];
    }
  } else if (isObject(src)) {
    dst = dst || {};

    for (var key in src) {
      if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
        dst[key] = src[key];
      }
    }
  }

  return dst || src;
}


/**
 * @ngdoc function
 * @name angular.equals
 * @module ng
 * @kind function
 *
 * @description
 * Determines if two objects or two values are equivalent. Supports value types, regular
 * expressions, arrays and objects.
 *
 * Two objects or values are considered equivalent if at least one of the following is true:
 *
 * * Both objects or values pass `===` comparison.
 * * Both objects or values are of the same type and all of their properties are equal by
 *   comparing them with `angular.equals`.
 * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
 * * Both values represent the same regular expression (In JavaScript,
 *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
 *   representation matches).
 *
 * During a property comparison, properties of `function` type and properties with names
 * that begin with `$` are ignored.
 *
 * Scope and DOMWindow objects are being compared only by identify (`===`).
 *
 * @param {*} o1 Object or value to compare.
 * @param {*} o2 Object or value to compare.
 * @returns {boolean} True if arguments are equal.
 */
function equals(o1, o2) {
  if (o1 === o2) return true;
  if (o1 === null || o2 === null) return false;
  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
  if (t1 == t2) {
    if (t1 == 'object') {
      if (isArray(o1)) {
        if (!isArray(o2)) return false;
        if ((length = o1.length) == o2.length) {
          for (key = 0; key < length; key++) {
            if (!equals(o1[key], o2[key])) return false;
          }
          return true;
        }
      } else if (isDate(o1)) {
        if (!isDate(o2)) return false;
        return equals(o1.getTime(), o2.getTime());
      } else if (isRegExp(o1)) {
        return isRegExp(o2) ? o1.toString() == o2.toString() : false;
      } else {
        if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
          isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
        keySet = {};
        for (key in o1) {
          if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
          if (!equals(o1[key], o2[key])) return false;
          keySet[key] = true;
        }
        for (key in o2) {
          if (!keySet.hasOwnProperty(key) &&
              key.charAt(0) !== '$' &&
              o2[key] !== undefined &&
              !isFunction(o2[key])) return false;
        }
        return true;
      }
    }
  }
  return false;
}

var csp = function() {
  if (isDefined(csp.isActive_)) return csp.isActive_;

  var active = !!(document.querySelector('[ng-csp]') ||
                  document.querySelector('[data-ng-csp]'));

  if (!active) {
    try {
      /* jshint -W031, -W054 */
      new Function('');
      /* jshint +W031, +W054 */
    } catch (e) {
      active = true;
    }
  }

  return (csp.isActive_ = active);
};



function concat(array1, array2, index) {
  return array1.concat(slice.call(array2, index));
}

function sliceArgs(args, startIndex) {
  return slice.call(args, startIndex || 0);
}


/* jshint -W101 */
/**
 * @ngdoc function
 * @name angular.bind
 * @module ng
 * @kind function
 *
 * @description
 * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
 * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
 * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
 * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
 *
 * @param {Object} self Context which `fn` should be evaluated in.
 * @param {function()} fn Function to be bound.
 * @param {...*} args Optional arguments to be prebound to the `fn` function call.
 * @returns {function()} Function that wraps the `fn` with all the specified bindings.
 */
/* jshint +W101 */
function bind(self, fn) {
  var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
  if (isFunction(fn) && !(fn instanceof RegExp)) {
    return curryArgs.length
      ? function() {
          return arguments.length
            ? fn.apply(self, concat(curryArgs, arguments, 0))
            : fn.apply(self, curryArgs);
        }
      : function() {
          return arguments.length
            ? fn.apply(self, arguments)
            : fn.call(self);
        };
  } else {
    // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
    return fn;
  }
}


function toJsonReplacer(key, value) {
  var val = value;

  if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
    val = undefined;
  } else if (isWindow(value)) {
    val = '$WINDOW';
  } else if (value &&  document === value) {
    val = '$DOCUMENT';
  } else if (isScope(value)) {
    val = '$SCOPE';
  }

  return val;
}


/**
 * @ngdoc function
 * @name angular.toJson
 * @module ng
 * @kind function
 *
 * @description
 * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
 * stripped since angular uses this notation internally.
 *
 * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
 * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
 *    If set to an integer, the JSON output will contain that many spaces per indentation.
 * @returns {string|undefined} JSON-ified string representing `obj`.
 */
function toJson(obj, pretty) {
  if (typeof obj === 'undefined') return undefined;
  if (!isNumber(pretty)) {
    pretty = pretty ? 2 : null;
  }
  return JSON.stringify(obj, toJsonReplacer, pretty);
}


/**
 * @ngdoc function
 * @name angular.fromJson
 * @module ng
 * @kind function
 *
 * @description
 * Deserializes a JSON string.
 *
 * @param {string} json JSON string to deserialize.
 * @returns {Object|Array|string|number} Deserialized JSON string.
 */
function fromJson(json) {
  return isString(json)
      ? JSON.parse(json)
      : json;
}


/**
 * @returns {string} Returns the string representation of the element.
 */
function startingTag(element) {
  element = jqLite(element).clone();
  try {
    // turns out IE does not let you set .html() on elements which
    // are not allowed to have children. So we just ignore it.
    element.empty();
  } catch (e) {}
  var elemHtml = jqLite('<div>').append(element).html();
  try {
    return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
        elemHtml.
          match(/^(<[^>]+>)/)[1].
          replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
  } catch (e) {
    return lowercase(elemHtml);
  }

}


/////////////////////////////////////////////////

/**
 * Tries to decode the URI component without throwing an exception.
 *
 * @private
 * @param str value potential URI component to check.
 * @returns {boolean} True if `value` can be decoded
 * with the decodeURIComponent function.
 */
function tryDecodeURIComponent(value) {
  try {
    return decodeURIComponent(value);
  } catch (e) {
    // Ignore any invalid uri component
  }
}


/**
 * Parses an escaped url query string into key-value pairs.
 * @returns {Object.<string,boolean|Array>}
 */
function parseKeyValue(/**string*/keyValue) {
  var obj = {}, key_value, key;
  forEach((keyValue || "").split('&'), function(keyValue) {
    if (keyValue) {
      key_value = keyValue.replace(/\+/g,'%20').split('=');
      key = tryDecodeURIComponent(key_value[0]);
      if (isDefined(key)) {
        var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
        if (!hasOwnProperty.call(obj, key)) {
          obj[key] = val;
        } else if (isArray(obj[key])) {
          obj[key].push(val);
        } else {
          obj[key] = [obj[key],val];
        }
      }
    }
  });
  return obj;
}

function toKeyValue(obj) {
  var parts = [];
  forEach(obj, function(value, key) {
    if (isArray(value)) {
      forEach(value, function(arrayValue) {
        parts.push(encodeUriQuery(key, true) +
                   (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
      });
    } else {
    parts.push(encodeUriQuery(key, true) +
               (value === true ? '' : '=' + encodeUriQuery(value, true)));
    }
  });
  return parts.length ? parts.join('&') : '';
}


/**
 * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
 * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
 * segments:
 *    segment       = *pchar
 *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
 *    pct-encoded   = "%" HEXDIG HEXDIG
 *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
 *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
 *                     / "*" / "+" / "," / ";" / "="
 */
function encodeUriSegment(val) {
  return encodeUriQuery(val, true).
             replace(/%26/gi, '&').
             replace(/%3D/gi, '=').
             replace(/%2B/gi, '+');
}


/**
 * This method is intended for encoding *key* or *value* parts of query component. We need a custom
 * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
 * encoded per http://tools.ietf.org/html/rfc3986:
 *    query       = *( pchar / "/" / "?" )
 *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
 *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
 *    pct-encoded   = "%" HEXDIG HEXDIG
 *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
 *                     / "*" / "+" / "," / ";" / "="
 */
function encodeUriQuery(val, pctEncodeSpaces) {
  return encodeURIComponent(val).
             replace(/%40/gi, '@').
             replace(/%3A/gi, ':').
             replace(/%24/g, '$').
             replace(/%2C/gi, ',').
             replace(/%3B/gi, ';').
             replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
}

var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];

function getNgAttribute(element, ngAttr) {
  var attr, i, ii = ngAttrPrefixes.length;
  element = jqLite(element);
  for (i = 0; i < ii; ++i) {
    attr = ngAttrPrefixes[i] + ngAttr;
    if (isString(attr = element.attr(attr))) {
      return attr;
    }
  }
  return null;
}

/**
 * @ngdoc directive
 * @name ngApp
 * @module ng
 *
 * @element ANY
 * @param {angular.Module} ngApp an optional application
 *   {@link angular.module module} name to load.
 * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
 *   created in "strict-di" mode. This means that the application will fail to invoke functions which
 *   do not use explicit function annotation (and are thus unsuitable for minification), as described
 *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
 *   tracking down the root of these bugs.
 *
 * @description
 *
 * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
 * designates the **root element** of the application and is typically placed near the root element
 * of the page - e.g. on the `<body>` or `<html>` tags.
 *
 * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
 * found in the document will be used to define the root element to auto-bootstrap as an
 * application. To run multiple applications in an HTML document you must manually bootstrap them using
 * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
 *
 * You can specify an **AngularJS module** to be used as the root module for the application.  This
 * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
 * should contain the application code needed or have dependencies on other modules that will
 * contain the code. See {@link angular.module} for more information.
 *
 * In the example below if the `ngApp` directive were not placed on the `html` element then the
 * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
 * would not be resolved to `3`.
 *
 * `ngApp` is the easiest, and most common way to bootstrap an application.
 *
 <example module="ngAppDemo">
   <file name="index.html">
   <div ng-controller="ngAppDemoController">
     I can add: {{a}} + {{b}} =  {{ a+b }}
   </div>
   </file>
   <file name="script.js">
   angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
     $scope.a = 1;
     $scope.b = 2;
   });
   </file>
 </example>
 *
 * Using `ngStrictDi`, you would see something like this:
 *
 <example ng-app-included="true">
   <file name="index.html">
   <div ng-app="ngAppStrictDemo" ng-strict-di>
       <div ng-controller="GoodController1">
           I can add: {{a}} + {{b}} =  {{ a+b }}

           <p>This renders because the controller does not fail to
              instantiate, by using explicit annotation style (see
              script.js for details)
           </p>
       </div>

       <div ng-controller="GoodController2">
           Name: <input ng-model="name"><br />
           Hello, {{name}}!

           <p>This renders because the controller does not fail to
              instantiate, by using explicit annotation style
              (see script.js for details)
           </p>
       </div>

       <div ng-controller="BadController">
           I can add: {{a}} + {{b}} =  {{ a+b }}

           <p>The controller could not be instantiated, due to relying
              on automatic function annotations (which are disabled in
              strict mode). As such, the content of this section is not
              interpolated, and there should be an error in your web console.
           </p>
       </div>
   </div>
   </file>
   <file name="script.js">
   angular.module('ngAppStrictDemo', [])
     // BadController will fail to instantiate, due to relying on automatic function annotation,
     // rather than an explicit annotation
     .controller('BadController', function($scope) {
       $scope.a = 1;
       $scope.b = 2;
     })
     // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
     // due to using explicit annotations using the array style and $inject property, respectively.
     .controller('GoodController1', ['$scope', function($scope) {
       $scope.a = 1;
       $scope.b = 2;
     }])
     .controller('GoodController2', GoodController2);
     function GoodController2($scope) {
       $scope.name = "World";
     }
     GoodController2.$inject = ['$scope'];
   </file>
   <file name="style.css">
   div[ng-controller] {
       margin-bottom: 1em;
       -webkit-border-radius: 4px;
       border-radius: 4px;
       border: 1px solid;
       padding: .5em;
   }
   div[ng-controller^=Good] {
       border-color: #d6e9c6;
       background-color: #dff0d8;
       color: #3c763d;
   }
   div[ng-controller^=Bad] {
       border-color: #ebccd1;
       background-color: #f2dede;
       color: #a94442;
       margin-bottom: 0;
   }
   </file>
 </example>
 */
function angularInit(element, bootstrap) {
  var appElement,
      module,
      config = {};

  // The element `element` has priority over any other element
  forEach(ngAttrPrefixes, function(prefix) {
    var name = prefix + 'app';

    if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
      appElement = element;
      module = element.getAttribute(name);
    }
  });
  forEach(ngAttrPrefixes, function(prefix) {
    var name = prefix + 'app';
    var candidate;

    if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
      appElement = candidate;
      module = candidate.getAttribute(name);
    }
  });
  if (appElement) {
    config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
    bootstrap(appElement, module ? [module] : [], config);
  }
}

/**
 * @ngdoc function
 * @name angular.bootstrap
 * @module ng
 * @description
 * Use this function to manually start up angular application.
 *
 * See: {@link guide/bootstrap Bootstrap}
 *
 * Note that Protractor based end-to-end tests cannot use this function to bootstrap manually.
 * They must use {@link ng.directive:ngApp ngApp}.
 *
 * Angular will detect if it has been loaded into the browser more than once and only allow the
 * first loaded script to be bootstrapped and will report a warning to the browser console for
 * each of the subsequent scripts. This prevents strange results in applications, where otherwise
 * multiple instances of Angular try to work on the DOM.
 *
 * ```html
 * <!doctype html>
 * <html>
 * <body>
 * <div ng-controller="WelcomeController">
 *   {{greeting}}
 * </div>
 *
 * <script src="angular.js"></script>
 * <script>
 *   var app = angular.module('demo', [])
 *   .controller('WelcomeController', function($scope) {
 *       $scope.greeting = 'Welcome!';
 *   });
 *   angular.bootstrap(document, ['demo']);
 * </script>
 * </body>
 * </html>
 * ```
 *
 * @param {DOMElement} element DOM element which is the root of angular application.
 * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
 *     Each item in the array should be the name of a predefined module or a (DI annotated)
 *     function that will be invoked by the injector as a `config` block.
 *     See: {@link angular.module modules}
 * @param {Object=} config an object for defining configuration options for the application. The
 *     following keys are supported:
 *
 * * `strictDi` - disable automatic function annotation for the application. This is meant to
 *   assist in finding bugs which break minified code. Defaults to `false`.
 *
 * @returns {auto.$injector} Returns the newly created injector for this app.
 */
function bootstrap(element, modules, config) {
  if (!isObject(config)) config = {};
  var defaultConfig = {
    strictDi: false
  };
  config = extend(defaultConfig, config);
  var doBootstrap = function() {
    element = jqLite(element);

    if (element.injector()) {
      var tag = (element[0] === document) ? 'document' : startingTag(element);
      //Encode angle brackets to prevent input from being sanitized to empty string #8683
      throw ngMinErr(
          'btstrpd',
          "App Already Bootstrapped with this Element '{0}'",
          tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
    }

    modules = modules || [];
    modules.unshift(['$provide', function($provide) {
      $provide.value('$rootElement', element);
    }]);

    if (config.debugInfoEnabled) {
      // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
      modules.push(['$compileProvider', function($compileProvider) {
        $compileProvider.debugInfoEnabled(true);
      }]);
    }

    modules.unshift('ng');
    var injector = createInjector(modules, config.strictDi);
    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
       function bootstrapApply(scope, element, compile, injector) {
        scope.$apply(function() {
          element.data('$injector', injector);
          compile(element)(scope);
        });
      }]
    );
    return injector;
  };

  var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;

  if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
    config.debugInfoEnabled = true;
    window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
  }

  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
    return doBootstrap();
  }

  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
  angular.resumeBootstrap = function(extraModules) {
    forEach(extraModules, function(module) {
      modules.push(module);
    });
    return doBootstrap();
  };

  if (isFunction(angular.resumeDeferredBootstrap)) {
    angular.resumeDeferredBootstrap();
  }
}

/**
 * @ngdoc function
 * @name angular.reloadWithDebugInfo
 * @module ng
 * @description
 * Use this function to reload the current application with debug information turned on.
 * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
 *
 * See {@link ng.$compileProvider#debugInfoEnabled} for more.
 */
function reloadWithDebugInfo() {
  window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
  window.location.reload();
}

/**
 * @name angular.getTestability
 * @module ng
 * @description
 * Get the testability service for the instance of Angular on the given
 * element.
 * @param {DOMElement} element DOM element which is the root of angular application.
 */
function getTestability(rootElement) {
  var injector = angular.element(rootElement).injector();
  if (!injector) {
    throw ngMinErr('test',
      'no injector found for element argument to getTestability');
  }
  return injector.get('$$testability');
}

var SNAKE_CASE_REGEXP = /[A-Z]/g;
function snake_case(name, separator) {
  separator = separator || '_';
  return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
    return (pos ? separator : '') + letter.toLowerCase();
  });
}

var bindJQueryFired = false;
var skipDestroyOnNextJQueryCleanData;
function bindJQuery() {
  var originalCleanData;

  if (bindJQueryFired) {
    return;
  }

  // bind to jQuery if present;
  jQuery = window.jQuery;
  // Use jQuery if it exists with proper functionality, otherwise default to us.
  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
  // versions. It will not work for sure with jQuery <1.7, though.
  if (jQuery && jQuery.fn.on) {
    jqLite = jQuery;
    extend(jQuery.fn, {
      scope: JQLitePrototype.scope,
      isolateScope: JQLitePrototype.isolateScope,
      controller: JQLitePrototype.controller,
      injector: JQLitePrototype.injector,
      inheritedData: JQLitePrototype.inheritedData
    });

    // All nodes removed from the DOM via various jQuery APIs like .remove()
    // are passed through jQuery.cleanData. Monkey-patch this method to fire
    // the $destroy event on all removed nodes.
    originalCleanData = jQuery.cleanData;
    jQuery.cleanData = function(elems) {
      var events;
      if (!skipDestroyOnNextJQueryCleanData) {
        for (var i = 0, elem; (elem = elems[i]) != null; i++) {
          events = jQuery._data(elem, "events");
          if (events && events.$destroy) {
            jQuery(elem).triggerHandler('$destroy');
          }
        }
      } else {
        skipDestroyOnNextJQueryCleanData = false;
      }
      originalCleanData(elems);
    };
  } else {
    jqLite = JQLite;
  }

  angular.element = jqLite;

  // Prevent double-proxying.
  bindJQueryFired = true;
}

/**
 * throw error if the argument is falsy.
 */
function assertArg(arg, name, reason) {
  if (!arg) {
    throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
  }
  return arg;
}

function assertArgFn(arg, name, acceptArrayAnnotation) {
  if (acceptArrayAnnotation && isArray(arg)) {
      arg = arg[arg.length - 1];
  }

  assertArg(isFunction(arg), name, 'not a function, got ' +
      (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
  return arg;
}

/**
 * throw error if the name given is hasOwnProperty
 * @param  {String} name    the name to test
 * @param  {String} context the context in which the name is used, such as module or directive
 */
function assertNotHasOwnProperty(name, context) {
  if (name === 'hasOwnProperty') {
    throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context);
  }
}

/**
 * Return the value accessible from the object by path. Any undefined traversals are ignored
 * @param {Object} obj starting object
 * @param {String} path path to traverse
 * @param {boolean} [bindFnToScope=true]
 * @returns {Object} value as accessible by path
 */
//TODO(misko): this function needs to be removed
function getter(obj, path, bindFnToScope) {
  if (!path) return obj;
  var keys = path.split('.');
  var key;
  var lastInstance = obj;
  var len = keys.length;

  for (var i = 0; i < len; i++) {
    key = keys[i];
    if (obj) {
      obj = (lastInstance = obj)[key];
    }
  }
  if (!bindFnToScope && isFunction(obj)) {
    return bind(lastInstance, obj);
  }
  return obj;
}

/**
 * Return the DOM siblings between the first and last node in the given array.
 * @param {Array} array like object
 * @returns {jqLite} jqLite collection containing the nodes
 */
function getBlockNodes(nodes) {
  // TODO(perf): just check if all items in `nodes` are siblings and if they are return the original
  //             collection, otherwise update the original collection.
  var node = nodes[0];
  var endNode = nodes[nodes.length - 1];
  var blockNodes = [node];

  do {
    node = node.nextSibling;
    if (!node) break;
    blockNodes.push(node);
  } while (node !== endNode);

  return jqLite(blockNodes);
}


/**
 * Creates a new object without a prototype. This object is useful for lookup without having to
 * guard against prototypically inherited properties via hasOwnProperty.
 *
 * Related micro-benchmarks:
 * - http://jsperf.com/object-create2
 * - http://jsperf.com/proto-map-lookup/2
 * - http://jsperf.com/for-in-vs-object-keys2
 *
 * @returns {Object}
 */
function createMap() {
  return Object.create(null);
}

var NODE_TYPE_ELEMENT = 1;
var NODE_TYPE_ATTRIBUTE = 2;
var NODE_TYPE_TEXT = 3;
var NODE_TYPE_COMMENT = 8;
var NODE_TYPE_DOCUMENT = 9;
var NODE_TYPE_DOCUMENT_FRAGMENT = 11;

/**
 * @ngdoc type
 * @name angular.Module
 * @module ng
 * @description
 *
 * Interface for configuring angular {@link angular.module modules}.
 */

function setupModuleLoader(window) {

  var $injectorMinErr = minErr('$injector');
  var ngMinErr = minErr('ng');

  function ensure(obj, name, factory) {
    return obj[name] || (obj[name] = factory());
  }

  var angular = ensure(window, 'angular', Object);

  // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
  angular.$$minErr = angular.$$minErr || minErr;

  return ensure(angular, 'module', function() {
    /** @type {Object.<string, angular.Module>} */
    var modules = {};

    /**
     * @ngdoc function
     * @name angular.module
     * @module ng
     * @description
     *
     * The `angular.module` is a global place for creating, registering and retrieving Angular
     * modules.
     * All modules (angular core or 3rd party) that should be available to an application must be
     * registered using this mechanism.
     *
     * When passed two or more arguments, a new module is created.  If passed only one argument, an
     * existing module (the name passed as the first argument to `module`) is retrieved.
     *
     *
     * # Module
     *
     * A module is a collection of services, directives, controllers, filters, and configuration information.
     * `angular.module` is used to configure the {@link auto.$injector $injector}.
     *
     * ```js
     * // Create a new module
     * var myModule = angular.module('myModule', []);
     *
     * // register a new service
     * myModule.value('appName', 'MyCoolApp');
     *
     * // configure existing services inside initialization blocks.
     * myModule.config(['$locationProvider', function($locationProvider) {
     *   // Configure existing providers
     *   $locationProvider.hashPrefix('!');
     * }]);
     * ```
     *
     * Then you can create an injector and load your modules like this:
     *
     * ```js
     * var injector = angular.injector(['ng', 'myModule'])
     * ```
     *
     * However it's more likely that you'll just use
     * {@link ng.directive:ngApp ngApp} or
     * {@link angular.bootstrap} to simplify this process for you.
     *
     * @param {!string} name The name of the module to create or retrieve.
     * @param {!Array.<string>=} requires If specified then new module is being created. If
     *        unspecified then the module is being retrieved for further configuration.
     * @param {Function=} configFn Optional configuration function for the module. Same as
     *        {@link angular.Module#config Module#config()}.
     * @returns {module} new module with the {@link angular.Module} api.
     */
    return function module(name, requires, configFn) {
      var assertNotHasOwnProperty = function(name, context) {
        if (name === 'hasOwnProperty') {
          throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
        }
      };

      assertNotHasOwnProperty(name, 'module');
      if (requires && modules.hasOwnProperty(name)) {
        modules[name] = null;
      }
      return ensure(modules, name, function() {
        if (!requires) {
          throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
             "the module name or forgot to load it. If registering a module ensure that you " +
             "specify the dependencies as the second argument.", name);
        }

        /** @type {!Array.<Array.<*>>} */
        var invokeQueue = [];

        /** @type {!Array.<Function>} */
        var configBlocks = [];

        /** @type {!Array.<Function>} */
        var runBlocks = [];

        var config = invokeLater('$injector', 'invoke', 'push', configBlocks);

        /** @type {angular.Module} */
        var moduleInstance = {
          // Private state
          _invokeQueue: invokeQueue,
          _configBlocks: configBlocks,
          _runBlocks: runBlocks,

          /**
           * @ngdoc property
           * @name angular.Module#requires
           * @module ng
           *
           * @description
           * Holds the list of modules which the injector will load before the current module is
           * loaded.
           */
          requires: requires,

          /**
           * @ngdoc property
           * @name angular.Module#name
           * @module ng
           *
           * @description
           * Name of the module.
           */
          name: name,


          /**
           * @ngdoc method
           * @name angular.Module#provider
           * @module ng
           * @param {string} name service name
           * @param {Function} providerType Construction function for creating new instance of the
           *                                service.
           * @description
           * See {@link auto.$provide#provider $provide.provider()}.
           */
          provider: invokeLater('$provide', 'provider'),

          /**
           * @ngdoc method
           * @name angular.Module#factory
           * @module ng
           * @param {string} name service name
           * @param {Function} providerFunction Function for creating new instance of the service.
           * @description
           * See {@link auto.$provide#factory $provide.factory()}.
           */
          factory: invokeLater('$provide', 'factory'),

          /**
           * @ngdoc method
           * @name angular.Module#service
           * @module ng
           * @param {string} name service name
           * @param {Function} constructor A constructor function that will be instantiated.
           * @description
           * See {@link auto.$provide#service $provide.service()}.
           */
          service: invokeLater('$provide', 'service'),

          /**
           * @ngdoc method
           * @name angular.Module#value
           * @module ng
           * @param {string} name service name
           * @param {*} object Service instance object.
           * @description
           * See {@link auto.$provide#value $provide.value()}.
           */
          value: invokeLater('$provide', 'value'),

          /**
           * @ngdoc method
           * @name angular.Module#constant
           * @module ng
           * @param {string} name constant name
           * @param {*} object Constant value.
           * @description
           * Because the constant are fixed, they get applied before other provide methods.
           * See {@link auto.$provide#constant $provide.constant()}.
           */
          constant: invokeLater('$provide', 'constant', 'unshift'),

          /**
           * @ngdoc method
           * @name angular.Module#animation
           * @module ng
           * @param {string} name animation name
           * @param {Function} animationFactory Factory function for creating new instance of an
           *                                    animation.
           * @description
           *
           * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
           *
           *
           * Defines an animation hook that can be later used with
           * {@link ngAnimate.$animate $animate} service and directives that use this service.
           *
           * ```js
           * module.animation('.animation-name', function($inject1, $inject2) {
           *   return {
           *     eventName : function(element, done) {
           *       //code to run the animation
           *       //once complete, then run done()
           *       return function cancellationFunction(element) {
           *         //code to cancel the animation
           *       }
           *     }
           *   }
           * })
           * ```
           *
           * See {@link ng.$animateProvider#register $animateProvider.register()} and
           * {@link ngAnimate ngAnimate module} for more information.
           */
          animation: invokeLater('$animateProvider', 'register'),

          /**
           * @ngdoc method
           * @name angular.Module#filter
           * @module ng
           * @param {string} name Filter name - this must be a valid angular expression identifier
           * @param {Function} filterFactory Factory function for creating new instance of filter.
           * @description
           * See {@link ng.$filterProvider#register $filterProvider.register()}.
           *
           * <div class="alert alert-warning">
           * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
           * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
           * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
           * (`myapp_subsection_filterx`).
           * </div>
           */
          filter: invokeLater('$filterProvider', 'register'),

          /**
           * @ngdoc method
           * @name angular.Module#controller
           * @module ng
           * @param {string|Object} name Controller name, or an object map of controllers where the
           *    keys are the names and the values are the constructors.
           * @param {Function} constructor Controller constructor function.
           * @description
           * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
           */
          controller: invokeLater('$controllerProvider', 'register'),

          /**
           * @ngdoc method
           * @name angular.Module#directive
           * @module ng
           * @param {string|Object} name Directive name, or an object map of directives where the
           *    keys are the names and the values are the factories.
           * @param {Function} directiveFactory Factory function for creating new instance of
           * directives.
           * @description
           * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
           */
          directive: invokeLater('$compileProvider', 'directive'),

          /**
           * @ngdoc method
           * @name angular.Module#config
           * @module ng
           * @param {Function} configFn Execute this function on module load. Useful for service
           *    configuration.
           * @description
           * Use this method to register work which needs to be performed on module loading.
           * For more about how to configure services, see
           * {@link providers#provider-recipe Provider Recipe}.
           */
          config: config,

          /**
           * @ngdoc method
           * @name angular.Module#run
           * @module ng
           * @param {Function} initializationFn Execute this function after injector creation.
           *    Useful for application initialization.
           * @description
           * Use this method to register work which should be performed when the injector is done
           * loading all modules.
           */
          run: function(block) {
            runBlocks.push(block);
            return this;
          }
        };

        if (configFn) {
          config(configFn);
        }

        return moduleInstance;

        /**
         * @param {string} provider
         * @param {string} method
         * @param {String=} insertMethod
         * @returns {angular.Module}
         */
        function invokeLater(provider, method, insertMethod, queue) {
          if (!queue) queue = invokeQueue;
          return function() {
            queue[insertMethod || 'push']([provider, method, arguments]);
            return moduleInstance;
          };
        }
      });
    };
  });

}

/* global: toDebugString: true */

function serializeObject(obj) {
  var seen = [];

  return JSON.stringify(obj, function(key, val) {
    val = toJsonReplacer(key, val);
    if (isObject(val)) {

      if (seen.indexOf(val) >= 0) return '<<already seen>>';

      seen.push(val);
    }
    return val;
  });
}

function toDebugString(obj) {
  if (typeof obj === 'function') {
    return obj.toString().replace(/ \{[\s\S]*$/, '');
  } else if (typeof obj === 'undefined') {
    return 'undefined';
  } else if (typeof obj !== 'string') {
    return serializeObject(obj);
  }
  return obj;
}

/* global angularModule: true,
  version: true,

  $LocaleProvider,
  $CompileProvider,

  htmlAnchorDirective,
  inputDirective,
  inputDirective,
  formDirective,
  scriptDirective,
  selectDirective,
  styleDirective,
  optionDirective,
  ngBindDirective,
  ngBindHtmlDirective,
  ngBindTemplateDirective,
  ngClassDirective,
  ngClassEvenDirective,
  ngClassOddDirective,
  ngCspDirective,
  ngCloakDirective,
  ngControllerDirective,
  ngFormDirective,
  ngHideDirective,
  ngIfDirective,
  ngIncludeDirective,
  ngIncludeFillContentDirective,
  ngInitDirective,
  ngNonBindableDirective,
  ngPluralizeDirective,
  ngRepeatDirective,
  ngShowDirective,
  ngStyleDirective,
  ngSwitchDirective,
  ngSwitchWhenDirective,
  ngSwitchDefaultDirective,
  ngOptionsDirective,
  ngTranscludeDirective,
  ngModelDirective,
  ngListDirective,
  ngChangeDirective,
  patternDirective,
  patternDirective,
  requiredDirective,
  requiredDirective,
  minlengthDirective,
  minlengthDirective,
  maxlengthDirective,
  maxlengthDirective,
  ngValueDirective,
  ngModelOptionsDirective,
  ngAttributeAliasDirectives,
  ngEventDirectives,

  $AnchorScrollProvider,
  $AnimateProvider,
  $BrowserProvider,
  $CacheFactoryProvider,
  $ControllerProvider,
  $DocumentProvider,
  $ExceptionHandlerProvider,
  $FilterProvider,
  $InterpolateProvider,
  $IntervalProvider,
  $HttpProvider,
  $HttpBackendProvider,
  $LocationProvider,
  $LogProvider,
  $ParseProvider,
  $RootScopeProvider,
  $QProvider,
  $$QProvider,
  $$SanitizeUriProvider,
  $SceProvider,
  $SceDelegateProvider,
  $SnifferProvider,
  $TemplateCacheProvider,
  $TemplateRequestProvider,
  $$TestabilityProvider,
  $TimeoutProvider,
  $$RAFProvider,
  $$AsyncCallbackProvider,
  $WindowProvider,
  $$jqLiteProvider
*/


/**
 * @ngdoc object
 * @name angular.version
 * @module ng
 * @description
 * An object that contains information about the current AngularJS version. This object has the
 * following properties:
 *
 * - `full` – `{string}` – Full version string, such as "0.9.18".
 * - `major` – `{number}` – Major version number, such as "0".
 * - `minor` – `{number}` – Minor version number, such as "9".
 * - `dot` – `{number}` – Dot version number, such as "18".
 * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
 */
var version = {
  full: '1.3.20',    // all of these placeholder strings will be replaced by grunt's
  major: 1,    // package task
  minor: 3,
  dot: 20,
  codeName: 'shallow-translucence'
};


function publishExternalAPI(angular) {
  extend(angular, {
    'bootstrap': bootstrap,
    'copy': copy,
    'extend': extend,
    'equals': equals,
    'element': jqLite,
    'forEach': forEach,
    'injector': createInjector,
    'noop': noop,
    'bind': bind,
    'toJson': toJson,
    'fromJson': fromJson,
    'identity': identity,
    'isUndefined': isUndefined,
    'isDefined': isDefined,
    'isString': isString,
    'isFunction': isFunction,
    'isObject': isObject,
    'isNumber': isNumber,
    'isElement': isElement,
    'isArray': isArray,
    'version': version,
    'isDate': isDate,
    'lowercase': lowercase,
    'uppercase': uppercase,
    'callbacks': {counter: 0},
    'getTestability': getTestability,
    '$$minErr': minErr,
    '$$csp': csp,
    'reloadWithDebugInfo': reloadWithDebugInfo
  });

  angularModule = setupModuleLoader(window);
  try {
    angularModule('ngLocale');
  } catch (e) {
    angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
  }

  angularModule('ng', ['ngLocale'], ['$provide',
    function ngModule($provide) {
      // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
      $provide.provider({
        $$sanitizeUri: $$SanitizeUriProvider
      });
      $provide.provider('$compile', $CompileProvider).
        directive({
            a: htmlAnchorDirective,
            input: inputDirective,
            textarea: inputDirective,
            form: formDirective,
            script: scriptDirective,
            select: selectDirective,
            style: styleDirective,
            option: optionDirective,
            ngBind: ngBindDirective,
            ngBindHtml: ngBindHtmlDirective,
            ngBindTemplate: ngBindTemplateDirective,
            ngClass: ngClassDirective,
            ngClassEven: ngClassEvenDirective,
            ngClassOdd: ngClassOddDirective,
            ngCloak: ngCloakDirective,
            ngController: ngControllerDirective,
            ngForm: ngFormDirective,
            ngHide: ngHideDirective,
            ngIf: ngIfDirective,
            ngInclude: ngIncludeDirective,
            ngInit: ngInitDirective,
            ngNonBindable: ngNonBindableDirective,
            ngPluralize: ngPluralizeDirective,
            ngRepeat: ngRepeatDirective,
            ngShow: ngShowDirective,
            ngStyle: ngStyleDirective,
            ngSwitch: ngSwitchDirective,
            ngSwitchWhen: ngSwitchWhenDirective,
            ngSwitchDefault: ngSwitchDefaultDirective,
            ngOptions: ngOptionsDirective,
            ngTransclude: ngTranscludeDirective,
            ngModel: ngModelDirective,
            ngList: ngListDirective,
            ngChange: ngChangeDirective,
            pattern: patternDirective,
            ngPattern: patternDirective,
            required: requiredDirective,
            ngRequired: requiredDirective,
            minlength: minlengthDirective,
            ngMinlength: minlengthDirective,
            maxlength: maxlengthDirective,
            ngMaxlength: maxlengthDirective,
            ngValue: ngValueDirective,
            ngModelOptions: ngModelOptionsDirective
        }).
        directive({
          ngInclude: ngIncludeFillContentDirective
        }).
        directive(ngAttributeAliasDirectives).
        directive(ngEventDirectives);
      $provide.provider({
        $anchorScroll: $AnchorScrollProvider,
        $animate: $AnimateProvider,
        $browser: $BrowserProvider,
        $cacheFactory: $CacheFactoryProvider,
        $controller: $ControllerProvider,
        $document: $DocumentProvider,
        $exceptionHandler: $ExceptionHandlerProvider,
        $filter: $FilterProvider,
        $interpolate: $InterpolateProvider,
        $interval: $IntervalProvider,
        $http: $HttpProvider,
        $httpBackend: $HttpBackendProvider,
        $location: $LocationProvider,
        $log: $LogProvider,
        $parse: $ParseProvider,
        $rootScope: $RootScopeProvider,
        $q: $QProvider,
        $$q: $$QProvider,
        $sce: $SceProvider,
        $sceDelegate: $SceDelegateProvider,
        $sniffer: $SnifferProvider,
        $templateCache: $TemplateCacheProvider,
        $templateRequest: $TemplateRequestProvider,
        $$testability: $$TestabilityProvider,
        $timeout: $TimeoutProvider,
        $window: $WindowProvider,
        $$rAF: $$RAFProvider,
        $$asyncCallback: $$AsyncCallbackProvider,
        $$jqLite: $$jqLiteProvider
      });
    }
  ]);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *     Any commits to this file should be reviewed with security in mind.  *
 *   Changes to this file can potentially create security vulnerabilities. *
 *          An approval from 2 Core members with history of modifying      *
 *                         this file is required.                          *
 *                                                                         *
 *  Does the change somehow allow for arbitrary javascript to be executed? *
 *    Or allows for someone to change the prototype of built-in objects?   *
 *     Or gives undesired access to variables likes document or window?    *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* global JQLitePrototype: true,
  addEventListenerFn: true,
  removeEventListenerFn: true,
  BOOLEAN_ATTR: true,
  ALIASED_ATTR: true,
*/

//////////////////////////////////
//JQLite
//////////////////////////////////

/**
 * @ngdoc function
 * @name angular.element
 * @module ng
 * @kind function
 *
 * @description
 * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
 *
 * If jQuery is available, `angular.element` is an alias for the
 * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`
 * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite."
 *
 * <div class="alert alert-success">jqLite is a tiny, API-compatible subset of jQuery that allows
 * Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most
 * commonly needed functionality with the goal of having a very small footprint.</div>
 *
 * To use `jQuery`, simply ensure it is loaded before the `angular.js` file.
 *
 * <div class="alert">**Note:** all element references in Angular are always wrapped with jQuery or
 * jqLite; they are never raw DOM references.</div>
 *
 * ## Angular's jqLite
 * jqLite provides only the following jQuery methods:
 *
 * - [`addClass()`](http://api.jquery.com/addClass/)
 * - [`after()`](http://api.jquery.com/after/)
 * - [`append()`](http://api.jquery.com/append/)
 * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
 * - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
 * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
 * - [`clone()`](http://api.jquery.com/clone/)
 * - [`contents()`](http://api.jquery.com/contents/)
 * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. As a setter, does not convert numbers to strings or append 'px'.
 * - [`data()`](http://api.jquery.com/data/)
 * - [`detach()`](http://api.jquery.com/detach/)
 * - [`empty()`](http://api.jquery.com/empty/)
 * - [`eq()`](http://api.jquery.com/eq/)
 * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name
 * - [`hasClass()`](http://api.jquery.com/hasClass/)
 * - [`html()`](http://api.jquery.com/html/)
 * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
 * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
 * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
 * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
 * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
 * - [`prepend()`](http://api.jquery.com/prepend/)
 * - [`prop()`](http://api.jquery.com/prop/)
 * - [`ready()`](http://api.jquery.com/ready/)
 * - [`remove()`](http://api.jquery.com/remove/)
 * - [`removeAttr()`](http://api.jquery.com/removeAttr/)
 * - [`removeClass()`](http://api.jquery.com/removeClass/)
 * - [`removeData()`](http://api.jquery.com/removeData/)
 * - [`replaceWith()`](http://api.jquery.com/replaceWith/)
 * - [`text()`](http://api.jquery.com/text/)
 * - [`toggleClass()`](http://api.jquery.com/toggleClass/)
 * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
 * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
 * - [`val()`](http://api.jquery.com/val/)
 * - [`wrap()`](http://api.jquery.com/wrap/)
 *
 * ## jQuery/jqLite Extras
 * Angular also provides the following additional methods and events to both jQuery and jqLite:
 *
 * ### Events
 * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
 *    on all DOM nodes being removed.  This can be used to clean up any 3rd party bindings to the DOM
 *    element before it is removed.
 *
 * ### Methods
 * - `controller(name)` - retrieves the controller of the current element or its parent. By default
 *   retrieves controller associated with the `ngController` directive. If `name` is provided as
 *   camelCase directive name, then the controller for this directive will be retrieved (e.g.
 *   `'ngModel'`).
 * - `injector()` - retrieves the injector of the current element or its parent.
 * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
 *   element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
 *   be enabled.
 * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
 *   current element. This getter should be used only on elements that contain a directive which starts a new isolate
 *   scope. Calling `scope()` on this element always returns the original non-isolate scope.
 *   Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
 * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
 *   parent element is reached.
 *
 * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
 * @returns {Object} jQuery object.
 */

JQLite.expando = 'ng339';

var jqCache = JQLite.cache = {},
    jqId = 1,
    addEventListenerFn = function(element, type, fn) {
      element.addEventListener(type, fn, false);
    },
    removeEventListenerFn = function(element, type, fn) {
      element.removeEventListener(type, fn, false);
    };

/*
 * !!! This is an undocumented "private" function !!!
 */
JQLite._data = function(node) {
  //jQuery always returns an object on cache miss
  return this.cache[node[this.expando]] || {};
};

function jqNextId() { return ++jqId; }


var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;
var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"};
var jqLiteMinErr = minErr('jqLite');

/**
 * Converts snake_case to camelCase.
 * Also there is special case for Moz prefix starting with upper case letter.
 * @param name Name to normalize
 */
function camelCase(name) {
  return name.
    replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    }).
    replace(MOZ_HACK_REGEXP, 'Moz$1');
}

var SINGLE_TAG_REGEXP = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;
var HTML_REGEXP = /<|&#?\w+;/;
var TAG_NAME_REGEXP = /<([\w:]+)/;
var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi;

var wrapMap = {
  'option': [1, '<select multiple="multiple">', '</select>'],

  'thead': [1, '<table>', '</table>'],
  'col': [2, '<table><colgroup>', '</colgroup></table>'],
  'tr': [2, '<table><tbody>', '</tbody></table>'],
  'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
  '_default': [0, "", ""]
};

wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;


function jqLiteIsTextNode(html) {
  return !HTML_REGEXP.test(html);
}

function jqLiteAcceptsData(node) {
  // The window object can accept data but has no nodeType
  // Otherwise we are only interested in elements (1) and documents (9)
  var nodeType = node.nodeType;
  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
}

function jqLiteBuildFragment(html, context) {
  var tmp, tag, wrap,
      fragment = context.createDocumentFragment(),
      nodes = [], i;

  if (jqLiteIsTextNode(html)) {
    // Convert non-html into a text node
    nodes.push(context.createTextNode(html));
  } else {
    // Convert html into DOM nodes
    tmp = tmp || fragment.appendChild(context.createElement("div"));
    tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
    wrap = wrapMap[tag] || wrapMap._default;
    tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1></$2>") + wrap[2];

    // Descend through wrappers to the right content
    i = wrap[0];
    while (i--) {
      tmp = tmp.lastChild;
    }

    nodes = concat(nodes, tmp.childNodes);

    tmp = fragment.firstChild;
    tmp.textContent = "";
  }

  // Remove wrapper from fragment
  fragment.textContent = "";
  fragment.innerHTML = ""; // Clear inner HTML
  forEach(nodes, function(node) {
    fragment.appendChild(node);
  });

  return fragment;
}

function jqLiteParseHTML(html, context) {
  context = context || document;
  var parsed;

  if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
    return [context.createElement(parsed[1])];
  }

  if ((parsed = jqLiteBuildFragment(html, context))) {
    return parsed.childNodes;
  }

  return [];
}

/////////////////////////////////////////////
function JQLite(element) {
  if (element instanceof JQLite) {
    return element;
  }

  var argIsString;

  if (isString(element)) {
    element = trim(element);
    argIsString = true;
  }
  if (!(this instanceof JQLite)) {
    if (argIsString && element.charAt(0) != '<') {
      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
    }
    return new JQLite(element);
  }

  if (argIsString) {
    jqLiteAddNodes(this, jqLiteParseHTML(element));
  } else {
    jqLiteAddNodes(this, element);
  }
}

function jqLiteClone(element) {
  return element.cloneNode(true);
}

function jqLiteDealoc(element, onlyDescendants) {
  if (!onlyDescendants) jqLiteRemoveData(element);

  if (element.querySelectorAll) {
    var descendants = element.querySelectorAll('*');
    for (var i = 0, l = descendants.length; i < l; i++) {
      jqLiteRemoveData(descendants[i]);
    }
  }
}

function jqLiteOff(element, type, fn, unsupported) {
  if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');

  var expandoStore = jqLiteExpandoStore(element);
  var events = expandoStore && expandoStore.events;
  var handle = expandoStore && expandoStore.handle;

  if (!handle) return; //no listeners registered

  if (!type) {
    for (type in events) {
      if (type !== '$destroy') {
        removeEventListenerFn(element, type, handle);
      }
      delete events[type];
    }
  } else {
    forEach(type.split(' '), function(type) {
      if (isDefined(fn)) {
        var listenerFns = events[type];
        arrayRemove(listenerFns || [], fn);
        if (listenerFns && listenerFns.length > 0) {
          return;
        }
      }

      removeEventListenerFn(element, type, handle);
      delete events[type];
    });
  }
}

function jqLiteRemoveData(element, name) {
  var expandoId = element.ng339;
  var expandoStore = expandoId && jqCache[expandoId];

  if (expandoStore) {
    if (name) {
      delete expandoStore.data[name];
      return;
    }

    if (expandoStore.handle) {
      if (expandoStore.events.$destroy) {
        expandoStore.handle({}, '$destroy');
      }
      jqLiteOff(element);
    }
    delete jqCache[expandoId];
    element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
  }
}


function jqLiteExpandoStore(element, createIfNecessary) {
  var expandoId = element.ng339,
      expandoStore = expandoId && jqCache[expandoId];

  if (createIfNecessary && !expandoStore) {
    element.ng339 = expandoId = jqNextId();
    expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};
  }

  return expandoStore;
}


function jqLiteData(element, key, value) {
  if (jqLiteAcceptsData(element)) {

    var isSimpleSetter = isDefined(value);
    var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
    var massGetter = !key;
    var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
    var data = expandoStore && expandoStore.data;

    if (isSimpleSetter) { // data('key', value)
      data[key] = value;
    } else {
      if (massGetter) {  // data()
        return data;
      } else {
        if (isSimpleGetter) { // data('key')
          // don't force creation of expandoStore if it doesn't exist yet
          return data && data[key];
        } else { // mass-setter: data({key1: val1, key2: val2})
          extend(data, key);
        }
      }
    }
  }
}

function jqLiteHasClass(element, selector) {
  if (!element.getAttribute) return false;
  return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
      indexOf(" " + selector + " ") > -1);
}

function jqLiteRemoveClass(element, cssClasses) {
  if (cssClasses && element.setAttribute) {
    forEach(cssClasses.split(' '), function(cssClass) {
      element.setAttribute('class', trim(
          (" " + (element.getAttribute('class') || '') + " ")
          .replace(/[\n\t]/g, " ")
          .replace(" " + trim(cssClass) + " ", " "))
      );
    });
  }
}

function jqLiteAddClass(element, cssClasses) {
  if (cssClasses && element.setAttribute) {
    var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
                            .replace(/[\n\t]/g, " ");

    forEach(cssClasses.split(' '), function(cssClass) {
      cssClass = trim(cssClass);
      if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
        existingClasses += cssClass + ' ';
      }
    });

    element.setAttribute('class', trim(existingClasses));
  }
}


function jqLiteAddNodes(root, elements) {
  // THIS CODE IS VERY HOT. Don't make changes without benchmarking.

  if (elements) {

    // if a Node (the most common case)
    if (elements.nodeType) {
      root[root.length++] = elements;
    } else {
      var length = elements.length;

      // if an Array or NodeList and not a Window
      if (typeof length === 'number' && elements.window !== elements) {
        if (length) {
          for (var i = 0; i < length; i++) {
            root[root.length++] = elements[i];
          }
        }
      } else {
        root[root.length++] = elements;
      }
    }
  }
}


function jqLiteController(element, name) {
  return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
}

function jqLiteInheritedData(element, name, value) {
  // if element is the document object work with the html element instead
  // this makes $(document).scope() possible
  if (element.nodeType == NODE_TYPE_DOCUMENT) {
    element = element.documentElement;
  }
  var names = isArray(name) ? name : [name];

  while (element) {
    for (var i = 0, ii = names.length; i < ii; i++) {
      if ((value = jqLite.data(element, names[i])) !== undefined) return value;
    }

    // If dealing with a document fragment node with a host element, and no parent, use the host
    // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
    // to lookup parent controllers.
    element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
  }
}

function jqLiteEmpty(element) {
  jqLiteDealoc(element, true);
  while (element.firstChild) {
    element.removeChild(element.firstChild);
  }
}

function jqLiteRemove(element, keepData) {
  if (!keepData) jqLiteDealoc(element);
  var parent = element.parentNode;
  if (parent) parent.removeChild(element);
}


function jqLiteDocumentLoaded(action, win) {
  win = win || window;
  if (win.document.readyState === 'complete') {
    // Force the action to be run async for consistent behaviour
    // from the action's point of view
    // i.e. it will definitely not be in a $apply
    win.setTimeout(action);
  } else {
    // No need to unbind this handler as load is only ever called once
    jqLite(win).on('load', action);
  }
}

//////////////////////////////////////////
// Functions which are declared directly.
//////////////////////////////////////////
var JQLitePrototype = JQLite.prototype = {
  ready: function(fn) {
    var fired = false;

    function trigger() {
      if (fired) return;
      fired = true;
      fn();
    }

    // check if document is already loaded
    if (document.readyState === 'complete') {
      setTimeout(trigger);
    } else {
      this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
      // we can not use jqLite since we are not done loading and jQuery could be loaded later.
      // jshint -W064
      JQLite(window).on('load', trigger); // fallback to window.onload for others
      // jshint +W064
    }
  },
  toString: function() {
    var value = [];
    forEach(this, function(e) { value.push('' + e);});
    return '[' + value.join(', ') + ']';
  },

  eq: function(index) {
      return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
  },

  length: 0,
  push: push,
  sort: [].sort,
  splice: [].splice
};

//////////////////////////////////////////
// Functions iterating getter/setters.
// these functions return self on setter and
// value on get.
//////////////////////////////////////////
var BOOLEAN_ATTR = {};
forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
  BOOLEAN_ATTR[lowercase(value)] = value;
});
var BOOLEAN_ELEMENTS = {};
forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
  BOOLEAN_ELEMENTS[value] = true;
});
var ALIASED_ATTR = {
  'ngMinlength': 'minlength',
  'ngMaxlength': 'maxlength',
  'ngMin': 'min',
  'ngMax': 'max',
  'ngPattern': 'pattern'
};

function getBooleanAttrName(element, name) {
  // check dom last since we will most likely fail on name
  var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];

  // booleanAttr is here twice to minimize DOM access
  return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
}

function getAliasedAttrName(element, name) {
  var nodeName = element.nodeName;
  return (nodeName === 'INPUT' || nodeName === 'TEXTAREA') && ALIASED_ATTR[name];
}

forEach({
  data: jqLiteData,
  removeData: jqLiteRemoveData
}, function(fn, name) {
  JQLite[name] = fn;
});

forEach({
  data: jqLiteData,
  inheritedData: jqLiteInheritedData,

  scope: function(element) {
    // Can't use jqLiteData here directly so we stay compatible with jQuery!
    return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
  },

  isolateScope: function(element) {
    // Can't use jqLiteData here directly so we stay compatible with jQuery!
    return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
  },

  controller: jqLiteController,

  injector: function(element) {
    return jqLiteInheritedData(element, '$injector');
  },

  removeAttr: function(element, name) {
    element.removeAttribute(name);
  },

  hasClass: jqLiteHasClass,

  css: function(element, name, value) {
    name = camelCase(name);

    if (isDefined(value)) {
      element.style[name] = value;
    } else {
      return element.style[name];
    }
  },

  attr: function(element, name, value) {
    var nodeType = element.nodeType;
    if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) {
      return;
    }
    var lowercasedName = lowercase(name);
    if (BOOLEAN_ATTR[lowercasedName]) {
      if (isDefined(value)) {
        if (!!value) {
          element[name] = true;
          element.setAttribute(name, lowercasedName);
        } else {
          element[name] = false;
          element.removeAttribute(lowercasedName);
        }
      } else {
        return (element[name] ||
                 (element.attributes.getNamedItem(name) || noop).specified)
               ? lowercasedName
               : undefined;
      }
    } else if (isDefined(value)) {
      element.setAttribute(name, value);
    } else if (element.getAttribute) {
      // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code
      // some elements (e.g. Document) don't have get attribute, so return undefined
      var ret = element.getAttribute(name, 2);
      // normalize non-existing attributes to undefined (as jQuery)
      return ret === null ? undefined : ret;
    }
  },

  prop: function(element, name, value) {
    if (isDefined(value)) {
      element[name] = value;
    } else {
      return element[name];
    }
  },

  text: (function() {
    getText.$dv = '';
    return getText;

    function getText(element, value) {
      if (isUndefined(value)) {
        var nodeType = element.nodeType;
        return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
      }
      element.textContent = value;
    }
  })(),

  val: function(element, value) {
    if (isUndefined(value)) {
      if (element.multiple && nodeName_(element) === 'select') {
        var result = [];
        forEach(element.options, function(option) {
          if (option.selected) {
            result.push(option.value || option.text);
          }
        });
        return result.length === 0 ? null : result;
      }
      return element.value;
    }
    element.value = value;
  },

  html: function(element, value) {
    if (isUndefined(value)) {
      return element.innerHTML;
    }
    jqLiteDealoc(element, true);
    element.innerHTML = value;
  },

  empty: jqLiteEmpty
}, function(fn, name) {
  /**
   * Properties: writes return selection, reads return first value
   */
  JQLite.prototype[name] = function(arg1, arg2) {
    var i, key;
    var nodeCount = this.length;

    // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
    // in a way that survives minification.
    // jqLiteEmpty takes no arguments but is a setter.
    if (fn !== jqLiteEmpty &&
        (((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2) === undefined)) {
      if (isObject(arg1)) {

        // we are a write, but the object properties are the key/values
        for (i = 0; i < nodeCount; i++) {
          if (fn === jqLiteData) {
            // data() takes the whole object in jQuery
            fn(this[i], arg1);
          } else {
            for (key in arg1) {
              fn(this[i], key, arg1[key]);
            }
          }
        }
        // return self for chaining
        return this;
      } else {
        // we are a read, so read the first child.
        // TODO: do we still need this?
        var value = fn.$dv;
        // Only if we have $dv do we iterate over all, otherwise it is just the first element.
        var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount;
        for (var j = 0; j < jj; j++) {
          var nodeValue = fn(this[j], arg1, arg2);
          value = value ? value + nodeValue : nodeValue;
        }
        return value;
      }
    } else {
      // we are a write, so apply to all children
      for (i = 0; i < nodeCount; i++) {
        fn(this[i], arg1, arg2);
      }
      // return self for chaining
      return this;
    }
  };
});

function createEventHandler(element, events) {
  var eventHandler = function(event, type) {
    // jQuery specific api
    event.isDefaultPrevented = function() {
      return event.defaultPrevented;
    };

    var eventFns = events[type || event.type];
    var eventFnsLength = eventFns ? eventFns.length : 0;

    if (!eventFnsLength) return;

    if (isUndefined(event.immediatePropagationStopped)) {
      var originalStopImmediatePropagation = event.stopImmediatePropagation;
      event.stopImmediatePropagation = function() {
        event.immediatePropagationStopped = true;

        if (event.stopPropagation) {
          event.stopPropagation();
        }

        if (originalStopImmediatePropagation) {
          originalStopImmediatePropagation.call(event);
        }
      };
    }

    event.isImmediatePropagationStopped = function() {
      return event.immediatePropagationStopped === true;
    };

    // Copy event handlers in case event handlers array is modified during execution.
    if ((eventFnsLength > 1)) {
      eventFns = shallowCopy(eventFns);
    }

    for (var i = 0; i < eventFnsLength; i++) {
      if (!event.isImmediatePropagationStopped()) {
        eventFns[i].call(element, event);
      }
    }
  };

  // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
  //       events on `element`
  eventHandler.elem = element;
  return eventHandler;
}

//////////////////////////////////////////
// Functions iterating traversal.
// These functions chain results into a single
// selector.
//////////////////////////////////////////
forEach({
  removeData: jqLiteRemoveData,

  on: function jqLiteOn(element, type, fn, unsupported) {
    if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');

    // Do not add event handlers to non-elements because they will not be cleaned up.
    if (!jqLiteAcceptsData(element)) {
      return;
    }

    var expandoStore = jqLiteExpandoStore(element, true);
    var events = expandoStore.events;
    var handle = expandoStore.handle;

    if (!handle) {
      handle = expandoStore.handle = createEventHandler(element, events);
    }

    // http://jsperf.com/string-indexof-vs-split
    var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];
    var i = types.length;

    while (i--) {
      type = types[i];
      var eventFns = events[type];

      if (!eventFns) {
        events[type] = [];

        if (type === 'mouseenter' || type === 'mouseleave') {
          // Refer to jQuery's implementation of mouseenter & mouseleave
          // Read about mouseenter and mouseleave:
          // http://www.quirksmode.org/js/events_mouse.html#link8

          jqLiteOn(element, MOUSE_EVENT_MAP[type], function(event) {
            var target = this, related = event.relatedTarget;
            // For mousenter/leave call the handler if related is outside the target.
            // NB: No relatedTarget if the mouse left/entered the browser window
            if (!related || (related !== target && !target.contains(related))) {
              handle(event, type);
            }
          });

        } else {
          if (type !== '$destroy') {
            addEventListenerFn(element, type, handle);
          }
        }
        eventFns = events[type];
      }
      eventFns.push(fn);
    }
  },

  off: jqLiteOff,

  one: function(element, type, fn) {
    element = jqLite(element);

    //add the listener twice so that when it is called
    //you can remove the original function and still be
    //able to call element.off(ev, fn) normally
    element.on(type, function onFn() {
      element.off(type, fn);
      element.off(type, onFn);
    });
    element.on(type, fn);
  },

  replaceWith: function(element, replaceNode) {
    var index, parent = element.parentNode;
    jqLiteDealoc(element);
    forEach(new JQLite(replaceNode), function(node) {
      if (index) {
        parent.insertBefore(node, index.nextSibling);
      } else {
        parent.replaceChild(node, element);
      }
      index = node;
    });
  },

  children: function(element) {
    var children = [];
    forEach(element.childNodes, function(element) {
      if (element.nodeType === NODE_TYPE_ELEMENT)
        children.push(element);
    });
    return children;
  },

  contents: function(element) {
    return element.contentDocument || element.childNodes || [];
  },

  append: function(element, node) {
    var nodeType = element.nodeType;
    if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;

    node = new JQLite(node);

    for (var i = 0, ii = node.length; i < ii; i++) {
      var child = node[i];
      element.appendChild(child);
    }
  },

  prepend: function(element, node) {
    if (element.nodeType === NODE_TYPE_ELEMENT) {
      var index = element.firstChild;
      forEach(new JQLite(node), function(child) {
        element.insertBefore(child, index);
      });
    }
  },

  wrap: function(element, wrapNode) {
    wrapNode = jqLite(wrapNode).eq(0).clone()[0];
    var parent = element.parentNode;
    if (parent) {
      parent.replaceChild(wrapNode, element);
    }
    wrapNode.appendChild(element);
  },

  remove: jqLiteRemove,

  detach: function(element) {
    jqLiteRemove(element, true);
  },

  after: function(element, newElement) {
    var index = element, parent = element.parentNode;
    newElement = new JQLite(newElement);

    for (var i = 0, ii = newElement.length; i < ii; i++) {
      var node = newElement[i];
      parent.insertBefore(node, index.nextSibling);
      index = node;
    }
  },

  addClass: jqLiteAddClass,
  removeClass: jqLiteRemoveClass,

  toggleClass: function(element, selector, condition) {
    if (selector) {
      forEach(selector.split(' '), function(className) {
        var classCondition = condition;
        if (isUndefined(classCondition)) {
          classCondition = !jqLiteHasClass(element, className);
        }
        (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);
      });
    }
  },

  parent: function(element) {
    var parent = element.parentNode;
    return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;
  },

  next: function(element) {
    return element.nextElementSibling;
  },

  find: function(element, selector) {
    if (element.getElementsByTagName) {
      return element.getElementsByTagName(selector);
    } else {
      return [];
    }
  },

  clone: jqLiteClone,

  triggerHandler: function(element, event, extraParameters) {

    var dummyEvent, eventFnsCopy, handlerArgs;
    var eventName = event.type || event;
    var expandoStore = jqLiteExpandoStore(element);
    var events = expandoStore && expandoStore.events;
    var eventFns = events && events[eventName];

    if (eventFns) {
      // Create a dummy event to pass to the handlers
      dummyEvent = {
        preventDefault: function() { this.defaultPrevented = true; },
        isDefaultPrevented: function() { return this.defaultPrevented === true; },
        stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },
        isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },
        stopPropagation: noop,
        type: eventName,
        target: element
      };

      // If a custom event was provided then extend our dummy event with it
      if (event.type) {
        dummyEvent = extend(dummyEvent, event);
      }

      // Copy event handlers in case event handlers array is modified during execution.
      eventFnsCopy = shallowCopy(eventFns);
      handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];

      forEach(eventFnsCopy, function(fn) {
        if (!dummyEvent.isImmediatePropagationStopped()) {
          fn.apply(element, handlerArgs);
        }
      });
    }
  }
}, function(fn, name) {
  /**
   * chaining functions
   */
  JQLite.prototype[name] = function(arg1, arg2, arg3) {
    var value;

    for (var i = 0, ii = this.length; i < ii; i++) {
      if (isUndefined(value)) {
        value = fn(this[i], arg1, arg2, arg3);
        if (isDefined(value)) {
          // any function which returns a value needs to be wrapped
          value = jqLite(value);
        }
      } else {
        jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
      }
    }
    return isDefined(value) ? value : this;
  };

  // bind legacy bind/unbind to on/off
  JQLite.prototype.bind = JQLite.prototype.on;
  JQLite.prototype.unbind = JQLite.prototype.off;
});


// Provider for private $$jqLite service
function $$jqLiteProvider() {
  this.$get = function $$jqLite() {
    return extend(JQLite, {
      hasClass: function(node, classes) {
        if (node.attr) node = node[0];
        return jqLiteHasClass(node, classes);
      },
      addClass: function(node, classes) {
        if (node.attr) node = node[0];
        return jqLiteAddClass(node, classes);
      },
      removeClass: function(node, classes) {
        if (node.attr) node = node[0];
        return jqLiteRemoveClass(node, classes);
      }
    });
  };
}

/**
 * Computes a hash of an 'obj'.
 * Hash of a:
 *  string is string
 *  number is number as string
 *  object is either result of calling $$hashKey function on the object or uniquely generated id,
 *         that is also assigned to the $$hashKey property of the object.
 *
 * @param obj
 * @returns {string} hash string such that the same input will have the same hash string.
 *         The resulting string key is in 'type:hashKey' format.
 */
function hashKey(obj, nextUidFn) {
  var key = obj && obj.$$hashKey;

  if (key) {
    if (typeof key === 'function') {
      key = obj.$$hashKey();
    }
    return key;
  }

  var objType = typeof obj;
  if (objType == 'function' || (objType == 'object' && obj !== null)) {
    key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();
  } else {
    key = objType + ':' + obj;
  }

  return key;
}

/**
 * HashMap which can use objects as keys
 */
function HashMap(array, isolatedUid) {
  if (isolatedUid) {
    var uid = 0;
    this.nextUid = function() {
      return ++uid;
    };
  }
  forEach(array, this.put, this);
}
HashMap.prototype = {
  /**
   * Store key value pair
   * @param key key to store can be any type
   * @param value value to store can be any type
   */
  put: function(key, value) {
    this[hashKey(key, this.nextUid)] = value;
  },

  /**
   * @param key
   * @returns {Object} the value for the key
   */
  get: function(key) {
    return this[hashKey(key, this.nextUid)];
  },

  /**
   * Remove the key/value pair
   * @param key
   */
  remove: function(key) {
    var value = this[key = hashKey(key, this.nextUid)];
    delete this[key];
    return value;
  }
};

/**
 * @ngdoc function
 * @module ng
 * @name angular.injector
 * @kind function
 *
 * @description
 * Creates an injector object that can be used for retrieving services as well as for
 * dependency injection (see {@link guide/di dependency injection}).
 *
 * @param {Array.<string|Function>} modules A list of module functions or their aliases. See
 *     {@link angular.module}. The `ng` module must be explicitly added.
 * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
 *     disallows argument name annotation inference.
 * @returns {injector} Injector object. See {@link auto.$injector $injector}.
 *
 * @example
 * Typical usage
 * ```js
 *   // create an injector
 *   var $injector = angular.injector(['ng']);
 *
 *   // use the injector to kick off your application
 *   // use the type inference to auto inject arguments, or use implicit injection
 *   $injector.invoke(function($rootScope, $compile, $document) {
 *     $compile($document)($rootScope);
 *     $rootScope.$digest();
 *   });
 * ```
 *
 * Sometimes you want to get access to the injector of a currently running Angular app
 * from outside Angular. Perhaps, you want to inject and compile some markup after the
 * application has been bootstrapped. You can do this using the extra `injector()` added
 * to JQuery/jqLite elements. See {@link angular.element}.
 *
 * *This is fairly rare but could be the case if a third party library is injecting the
 * markup.*
 *
 * In the following example a new block of HTML containing a `ng-controller`
 * directive is added to the end of the document body by JQuery. We then compile and link
 * it into the current AngularJS scope.
 *
 * ```js
 * var $div = $('<div ng-controller="MyCtrl">{{content.label}}</div>');
 * $(document.body).append($div);
 *
 * angular.element(document).injector().invoke(function($compile) {
 *   var scope = angular.element($div).scope();
 *   $compile($div)(scope);
 * });
 * ```
 */


/**
 * @ngdoc module
 * @name auto
 * @description
 *
 * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
 */

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var $injectorMinErr = minErr('$injector');

function anonFn(fn) {
  // For anonymous functions, showing at the very least the function signature can help in
  // debugging.
  var fnText = fn.toString().replace(STRIP_COMMENTS, ''),
      args = fnText.match(FN_ARGS);
  if (args) {
    return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
  }
  return 'fn';
}

function annotate(fn, strictDi, name) {
  var $inject,
      fnText,
      argDecl,
      last;

  if (typeof fn === 'function') {
    if (!($inject = fn.$inject)) {
      $inject = [];
      if (fn.length) {
        if (strictDi) {
          if (!isString(name) || !name) {
            name = fn.name || anonFn(fn);
          }
          throw $injectorMinErr('strictdi',
            '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
        }
        fnText = fn.toString().replace(STRIP_COMMENTS, '');
        argDecl = fnText.match(FN_ARGS);
        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
          arg.replace(FN_ARG, function(all, underscore, name) {
            $inject.push(name);
          });
        });
      }
      fn.$inject = $inject;
    }
  } else if (isArray(fn)) {
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn');
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);
  }
  return $inject;
}

///////////////////////////////////////

/**
 * @ngdoc service
 * @name $injector
 *
 * @description
 *
 * `$injector` is used to retrieve object instances as defined by
 * {@link auto.$provide provider}, instantiate types, invoke methods,
 * and load modules.
 *
 * The following always holds true:
 *
 * ```js
 *   var $injector = angular.injector();
 *   expect($injector.get('$injector')).toBe($injector);
 *   expect($injector.invoke(function($injector) {
 *     return $injector;
 *   })).toBe($injector);
 * ```
 *
 * # Injection Function Annotation
 *
 * JavaScript does not have annotations, and annotations are needed for dependency injection. The
 * following are all valid ways of annotating function with injection arguments and are equivalent.
 *
 * ```js
 *   // inferred (only works if code not minified/obfuscated)
 *   $injector.invoke(function(serviceA){});
 *
 *   // annotated
 *   function explicit(serviceA) {};
 *   explicit.$inject = ['serviceA'];
 *   $injector.invoke(explicit);
 *
 *   // inline
 *   $injector.invoke(['serviceA', function(serviceA){}]);
 * ```
 *
 * ## Inference
 *
 * In JavaScript calling `toString()` on a function returns the function definition. The definition
 * can then be parsed and the function arguments can be extracted. This method of discovering
 * annotations is disallowed when the injector is in strict mode.
 * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
 * argument names.
 *
 * ## `$inject` Annotation
 * By adding an `$inject` property onto a function the injection parameters can be specified.
 *
 * ## Inline
 * As an array of injection names, where the last item in the array is the function to call.
 */

/**
 * @ngdoc method
 * @name $injector#get
 *
 * @description
 * Return an instance of the service.
 *
 * @param {string} name The name of the instance to retrieve.
 * @param {string=} caller An optional string to provide the origin of the function call for error messages.
 * @return {*} The instance.
 */

/**
 * @ngdoc method
 * @name $injector#invoke
 *
 * @description
 * Invoke the method and supply the method arguments from the `$injector`.
 *
 * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are
 *   injected according to the {@link guide/di $inject Annotation} rules.
 * @param {Object=} self The `this` for the invoked method.
 * @param {Object=} locals Optional object. If preset then any argument names are read from this
 *                         object first, before the `$injector` is consulted.
 * @returns {*} the value returned by the invoked `fn` function.
 */

/**
 * @ngdoc method
 * @name $injector#has
 *
 * @description
 * Allows the user to query if the particular service exists.
 *
 * @param {string} name Name of the service to query.
 * @returns {boolean} `true` if injector has given service.
 */

/**
 * @ngdoc method
 * @name $injector#instantiate
 * @description
 * Create a new instance of JS type. The method takes a constructor function, invokes the new
 * operator, and supplies all of the arguments to the constructor function as specified by the
 * constructor annotation.
 *
 * @param {Function} Type Annotated constructor function.
 * @param {Object=} locals Optional object. If preset then any argument names are read from this
 * object first, before the `$injector` is consulted.
 * @returns {Object} new instance of `Type`.
 */

/**
 * @ngdoc method
 * @name $injector#annotate
 *
 * @description
 * Returns an array of service names which the function is requesting for injection. This API is
 * used by the injector to determine which services need to be injected into the function when the
 * function is invoked. There are three ways in which the function can be annotated with the needed
 * dependencies.
 *
 * # Argument names
 *
 * The simplest form is to extract the dependencies from the arguments of the function. This is done
 * by converting the function into a string using `toString()` method and extracting the argument
 * names.
 * ```js
 *   // Given
 *   function MyController($scope, $route) {
 *     // ...
 *   }
 *
 *   // Then
 *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
 * ```
 *
 * You can disallow this method by using strict injection mode.
 *
 * This method does not work with code minification / obfuscation. For this reason the following
 * annotation strategies are supported.
 *
 * # The `$inject` property
 *
 * If a function has an `$inject` property and its value is an array of strings, then the strings
 * represent names of services to be injected into the function.
 * ```js
 *   // Given
 *   var MyController = function(obfuscatedScope, obfuscatedRoute) {
 *     // ...
 *   }
 *   // Define function dependencies
 *   MyController['$inject'] = ['$scope', '$route'];
 *
 *   // Then
 *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
 * ```
 *
 * # The array notation
 *
 * It is often desirable to inline Injected functions and that's when setting the `$inject` property
 * is very inconvenient. In these situations using the array notation to specify the dependencies in
 * a way that survives minification is a better choice:
 *
 * ```js
 *   // We wish to write this (not minification / obfuscation safe)
 *   injector.invoke(function($compile, $rootScope) {
 *     // ...
 *   });
 *
 *   // We are forced to write break inlining
 *   var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {
 *     // ...
 *   };
 *   tmpFn.$inject = ['$compile', '$rootScope'];
 *   injector.invoke(tmpFn);
 *
 *   // To better support inline function the inline annotation is supported
 *   injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
 *     // ...
 *   }]);
 *
 *   // Therefore
 *   expect(injector.annotate(
 *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
 *    ).toEqual(['$compile', '$rootScope']);
 * ```
 *
 * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to
 * be retrieved as described above.
 *
 * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
 *
 * @returns {Array.<string>} The names of the services which the function requires.
 */




/**
 * @ngdoc service
 * @name $provide
 *
 * @description
 *
 * The {@link auto.$provide $provide} service has a number of methods for registering components
 * with the {@link auto.$injector $injector}. Many of these functions are also exposed on
 * {@link angular.Module}.
 *
 * An Angular **service** is a singleton object created by a **service factory**.  These **service
 * factories** are functions which, in turn, are created by a **service provider**.
 * The **service providers** are constructor functions. When instantiated they must contain a
 * property called `$get`, which holds the **service factory** function.
 *
 * When you request a service, the {@link auto.$injector $injector} is responsible for finding the
 * correct **service provider**, instantiating it and then calling its `$get` **service factory**
 * function to get the instance of the **service**.
 *
 * Often services have no configuration options and there is no need to add methods to the service
 * provider.  The provider will be no more than a constructor function with a `$get` property. For
 * these cases the {@link auto.$provide $provide} service has additional helper methods to register
 * services without specifying a provider.
 *
 * * {@link auto.$provide#provider provider(provider)} - registers a **service provider** with the
 *     {@link auto.$injector $injector}
 * * {@link auto.$provide#constant constant(obj)} - registers a value/object that can be accessed by
 *     providers and services.
 * * {@link auto.$provide#value value(obj)} - registers a value/object that can only be accessed by
 *     services, not providers.
 * * {@link auto.$provide#factory factory(fn)} - registers a service **factory function**, `fn`,
 *     that will be wrapped in a **service provider** object, whose `$get` property will contain the
 *     given factory function.
 * * {@link auto.$provide#service service(class)} - registers a **constructor function**, `class`
 *     that will be wrapped in a **service provider** object, whose `$get` property will instantiate
 *      a new object using the given constructor function.
 *
 * See the individual methods for more information and examples.
 */

/**
 * @ngdoc method
 * @name $provide#provider
 * @description
 *
 * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions
 * are constructor functions, whose instances are responsible for "providing" a factory for a
 * service.
 *
 * Service provider names start with the name of the service they provide followed by `Provider`.
 * For example, the {@link ng.$log $log} service has a provider called
 * {@link ng.$logProvider $logProvider}.
 *
 * Service provider objects can have additional methods which allow configuration of the provider
 * and its service. Importantly, you can configure what kind of service is created by the `$get`
 * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a
 * method {@link ng.$logProvider#debugEnabled debugEnabled}
 * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the
 * console or not.
 *
 * @param {string} name The name of the instance. NOTE: the provider will be available under `name +
                        'Provider'` key.
 * @param {(Object|function())} provider If the provider is:
 *
 *   - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
 *     {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.
 *   - `Constructor`: a new instance of the provider will be created using
 *     {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.
 *
 * @returns {Object} registered provider instance

 * @example
 *
 * The following example shows how to create a simple event tracking service and register it using
 * {@link auto.$provide#provider $provide.provider()}.
 *
 * ```js
 *  // Define the eventTracker provider
 *  function EventTrackerProvider() {
 *    var trackingUrl = '/track';
 *
 *    // A provider method for configuring where the tracked events should been saved
 *    this.setTrackingUrl = function(url) {
 *      trackingUrl = url;
 *    };
 *
 *    // The service factory function
 *    this.$get = ['$http', function($http) {
 *      var trackedEvents = {};
 *      return {
 *        // Call this to track an event
 *        event: function(event) {
 *          var count = trackedEvents[event] || 0;
 *          count += 1;
 *          trackedEvents[event] = count;
 *          return count;
 *        },
 *        // Call this to save the tracked events to the trackingUrl
 *        save: function() {
 *          $http.post(trackingUrl, trackedEvents);
 *        }
 *      };
 *    }];
 *  }
 *
 *  describe('eventTracker', function() {
 *    var postSpy;
 *
 *    beforeEach(module(function($provide) {
 *      // Register the eventTracker provider
 *      $provide.provider('eventTracker', EventTrackerProvider);
 *    }));
 *
 *    beforeEach(module(function(eventTrackerProvider) {
 *      // Configure eventTracker provider
 *      eventTrackerProvider.setTrackingUrl('/custom-track');
 *    }));
 *
 *    it('tracks events', inject(function(eventTracker) {
 *      expect(eventTracker.event('login')).toEqual(1);
 *      expect(eventTracker.event('login')).toEqual(2);
 *    }));
 *
 *    it('saves to the tracking url', inject(function(eventTracker, $http) {
 *      postSpy = spyOn($http, 'post');
 *      eventTracker.event('login');
 *      eventTracker.save();
 *      expect(postSpy).toHaveBeenCalled();
 *      expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
 *      expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
 *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
 *    }));
 *  });
 * ```
 */

/**
 * @ngdoc method
 * @name $provide#factory
 * @description
 *
 * Register a **service factory**, which will be called to return the service instance.
 * This is short for registering a service where its provider consists of only a `$get` property,
 * which is the given service factory function.
 * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to
 * configure your service in a provider.
 *
 * @param {string} name The name of the instance.
 * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.
 *                      Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.
 * @returns {Object} registered provider instance
 *
 * @example
 * Here is an example of registering a service
 * ```js
 *   $provide.factory('ping', ['$http', function($http) {
 *     return function ping() {
 *       return $http.send('/ping');
 *     };
 *   }]);
 * ```
 * You would then inject and use this service like this:
 * ```js
 *   someModule.controller('Ctrl', ['ping', function(ping) {
 *     ping();
 *   }]);
 * ```
 */


/**
 * @ngdoc method
 * @name $provide#service
 * @description
 *
 * Register a **service constructor**, which will be invoked with `new` to create the service
 * instance.
 * This is short for registering a service where its provider's `$get` property is the service
 * constructor function that will be used to instantiate the service instance.
 *
 * You should use {@link auto.$provide#service $provide.service(class)} if you define your service
 * as a type/class.
 *
 * @param {string} name The name of the instance.
 * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)
 *     that will be instantiated.
 * @returns {Object} registered provider instance
 *
 * @example
 * Here is an example of registering a service using
 * {@link auto.$provide#service $provide.service(class)}.
 * ```js
 *   var Ping = function($http) {
 *     this.$http = $http;
 *   };
 *
 *   Ping.$inject = ['$http'];
 *
 *   Ping.prototype.send = function() {
 *     return this.$http.get('/ping');
 *   };
 *   $provide.service('ping', Ping);
 * ```
 * You would then inject and use this service like this:
 * ```js
 *   someModule.controller('Ctrl', ['ping', function(ping) {
 *     ping.send();
 *   }]);
 * ```
 */


/**
 * @ngdoc method
 * @name $provide#value
 * @description
 *
 * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
 * number, an array, an object or a function.  This is short for registering a service where its
 * provider's `$get` property is a factory function that takes no arguments and returns the **value
 * service**.
 *
 * Value services are similar to constant services, except that they cannot be injected into a
 * module configuration function (see {@link angular.Module#config}) but they can be overridden by
 * an Angular
 * {@link auto.$provide#decorator decorator}.
 *
 * @param {string} name The name of the instance.
 * @param {*} value The value.
 * @returns {Object} registered provider instance
 *
 * @example
 * Here are some examples of creating value services.
 * ```js
 *   $provide.value('ADMIN_USER', 'admin');
 *
 *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
 *
 *   $provide.value('halfOf', function(value) {
 *     return value / 2;
 *   });
 * ```
 */


/**
 * @ngdoc method
 * @name $provide#constant
 * @description
 *
 * Register a **constant service**, such as a string, a number, an array, an object or a function,
 * with the {@link auto.$injector $injector}. Unlike {@link auto.$provide#value value} it can be
 * injected into a module configuration function (see {@link angular.Module#config}) and it cannot
 * be overridden by an Angular {@link auto.$provide#decorator decorator}.
 *
 * @param {string} name The name of the constant.
 * @param {*} value The constant value.
 * @returns {Object} registered instance
 *
 * @example
 * Here a some examples of creating constants:
 * ```js
 *   $provide.constant('SHARD_HEIGHT', 306);
 *
 *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
 *
 *   $provide.constant('double', function(value) {
 *     return value * 2;
 *   });
 * ```
 */


/**
 * @ngdoc method
 * @name $provide#decorator
 * @description
 *
 * Register a **service decorator** with the {@link auto.$injector $injector}. A service decorator
 * intercepts the creation of a service, allowing it to override or modify the behaviour of the
 * service. The object returned by the decorator may be the original service, or a new service
 * object which replaces or wraps and delegates to the original service.
 *
 * @param {string} name The name of the service to decorate.
 * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be
 *    instantiated and should return the decorated service instance. The function is called using
 *    the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
 *    Local injection arguments:
 *
 *    * `$delegate` - The original service instance, which can be monkey patched, configured,
 *      decorated or delegated to.
 *
 * @example
 * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
 * calls to {@link ng.$log#error $log.warn()}.
 * ```js
 *   $provide.decorator('$log', ['$delegate', function($delegate) {
 *     $delegate.warn = $delegate.error;
 *     return $delegate;
 *   }]);
 * ```
 */


function createInjector(modulesToLoad, strictDi) {
  strictDi = (strictDi === true);
  var INSTANTIATING = {},
      providerSuffix = 'Provider',
      path = [],
      loadedModules = new HashMap([], true),
      providerCache = {
        $provide: {
            provider: supportObject(provider),
            factory: supportObject(factory),
            service: supportObject(service),
            value: supportObject(value),
            constant: supportObject(constant),
            decorator: decorator
          }
      },
      providerInjector = (providerCache.$injector =
          createInternalInjector(providerCache, function(serviceName, caller) {
            if (angular.isString(caller)) {
              path.push(caller);
            }
            throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
          })),
      instanceCache = {},
      instanceInjector = (instanceCache.$injector =
          createInternalInjector(instanceCache, function(serviceName, caller) {
            var provider = providerInjector.get(serviceName + providerSuffix, caller);
            return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
          }));


  forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); });

  return instanceInjector;

  ////////////////////////////////////
  // $provider
  ////////////////////////////////////

  function supportObject(delegate) {
    return function(key, value) {
      if (isObject(key)) {
        forEach(key, reverseParams(delegate));
      } else {
        return delegate(key, value);
      }
    };
  }

  function provider(name, provider_) {
    assertNotHasOwnProperty(name, 'service');
    if (isFunction(provider_) || isArray(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function enforceReturnValue(name, factory) {
    return function enforcedReturnValue() {
      var result = instanceInjector.invoke(factory, this);
      if (isUndefined(result)) {
        throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
      }
      return result;
    };
  }

  function factory(name, factoryFn, enforce) {
    return provider(name, {
      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
    });
  }

  function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

  function value(name, val) { return factory(name, valueFn(val), false); }

  function constant(name, value) {
    assertNotHasOwnProperty(name, 'constant');
    providerCache[name] = value;
    instanceCache[name] = value;
  }

  function decorator(serviceName, decorFn) {
    var origProvider = providerInjector.get(serviceName + providerSuffix),
        orig$get = origProvider.$get;

    origProvider.$get = function() {
      var origInstance = instanceInjector.invoke(orig$get, origProvider);
      return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
    };
  }

  ////////////////////////////////////
  // Module Loading
  ////////////////////////////////////
  function loadModules(modulesToLoad) {
    var runBlocks = [], moduleFn;
    forEach(modulesToLoad, function(module) {
      if (loadedModules.get(module)) return;
      loadedModules.put(module, true);

      function runInvokeQueue(queue) {
        var i, ii;
        for (i = 0, ii = queue.length; i < ii; i++) {
          var invokeArgs = queue[i],
              provider = providerInjector.get(invokeArgs[0]);

          provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
        }
      }

      try {
        if (isString(module)) {
          moduleFn = angularModule(module);
          runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
          runInvokeQueue(moduleFn._invokeQueue);
          runInvokeQueue(moduleFn._configBlocks);
        } else if (isFunction(module)) {
            runBlocks.push(providerInjector.invoke(module));
        } else if (isArray(module)) {
            runBlocks.push(providerInjector.invoke(module));
        } else {
          assertArgFn(module, 'module');
        }
      } catch (e) {
        if (isArray(module)) {
          module = module[module.length - 1];
        }
        if (e.message && e.stack && e.stack.indexOf(e.message) == -1) {
          // Safari & FF's stack traces don't contain error.message content
          // unlike those of Chrome and IE
          // So if stack doesn't contain message, we create a new string that contains both.
          // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
          /* jshint -W022 */
          e = e.message + '\n' + e.stack;
        }
        throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}",
                  module, e.stack || e.message || e);
      }
    });
    return runBlocks;
  }

  ////////////////////////////////////
  // internal Injector
  ////////////////////////////////////

  function createInternalInjector(cache, factory) {

    function getService(serviceName, caller) {
      if (cache.hasOwnProperty(serviceName)) {
        if (cache[serviceName] === INSTANTIATING) {
          throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
                    serviceName + ' <- ' + path.join(' <- '));
        }
        return cache[serviceName];
      } else {
        try {
          path.unshift(serviceName);
          cache[serviceName] = INSTANTIATING;
          return cache[serviceName] = factory(serviceName, caller);
        } catch (err) {
          if (cache[serviceName] === INSTANTIATING) {
            delete cache[serviceName];
          }
          throw err;
        } finally {
          path.shift();
        }
      }
    }

    function invoke(fn, self, locals, serviceName) {
      if (typeof locals === 'string') {
        serviceName = locals;
        locals = null;
      }

      var args = [],
          $inject = createInjector.$$annotate(fn, strictDi, serviceName),
          length, i,
          key;

      for (i = 0, length = $inject.length; i < length; i++) {
        key = $inject[i];
        if (typeof key !== 'string') {
          throw $injectorMinErr('itkn',
                  'Incorrect injection token! Expected service name as string, got {0}', key);
        }
        args.push(
          locals && locals.hasOwnProperty(key)
          ? locals[key]
          : getService(key, serviceName)
        );
      }
      if (isArray(fn)) {
        fn = fn[length];
      }

      // http://jsperf.com/angularjs-invoke-apply-vs-switch
      // #5388
      return fn.apply(self, args);
    }

    function instantiate(Type, locals, serviceName) {
      // Check if Type is annotated and use just the given function at n-1 as parameter
      // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
      // Object creation: http://jsperf.com/create-constructor/2
      var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
      var returnedValue = invoke(Type, instance, locals, serviceName);

      return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
    }

    return {
      invoke: invoke,
      instantiate: instantiate,
      get: getService,
      annotate: createInjector.$$annotate,
      has: function(name) {
        return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
      }
    };
  }
}

createInjector.$$annotate = annotate;

/**
 * @ngdoc provider
 * @name $anchorScrollProvider
 *
 * @description
 * Use `$anchorScrollProvider` to disable automatic scrolling whenever
 * {@link ng.$location#hash $location.hash()} changes.
 */
function $AnchorScrollProvider() {

  var autoScrollingEnabled = true;

  /**
   * @ngdoc method
   * @name $anchorScrollProvider#disableAutoScrolling
   *
   * @description
   * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
   * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
   * Use this method to disable automatic scrolling.
   *
   * If automatic scrolling is disabled, one must explicitly call
   * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the
   * current hash.
   */
  this.disableAutoScrolling = function() {
    autoScrollingEnabled = false;
  };

  /**
   * @ngdoc service
   * @name $anchorScroll
   * @kind function
   * @requires $window
   * @requires $location
   * @requires $rootScope
   *
   * @description
   * When called, it checks the current value of {@link ng.$location#hash $location.hash()} and
   * scrolls to the related element, according to the rules specified in the
   * [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
   *
   * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
   * match any anchor whenever it changes. This can be disabled by calling
   * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.
   *
   * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
   * vertical scroll-offset (either fixed or dynamic).
   *
   * @property {(number|function|jqLite)} yOffset
   * If set, specifies a vertical scroll-offset. This is often useful when there are fixed
   * positioned elements at the top of the page, such as navbars, headers etc.
   *
   * `yOffset` can be specified in various ways:
   * - **number**: A fixed number of pixels to be used as offset.<br /><br />
   * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return
   *   a number representing the offset (in pixels).<br /><br />
   * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from
   *   the top of the page to the element's bottom will be used as offset.<br />
   *   **Note**: The element will be taken into account only as long as its `position` is set to
   *   `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust
   *   their height and/or positioning according to the viewport's size.
   *
   * <br />
   * <div class="alert alert-warning">
   * In order for `yOffset` to work properly, scrolling should take place on the document's root and
   * not some child element.
   * </div>
   *
   * @example
     <example module="anchorScrollExample">
       <file name="index.html">
         <div id="scrollArea" ng-controller="ScrollController">
           <a ng-click="gotoBottom()">Go to bottom</a>
           <a id="bottom"></a> You're at the bottom!
         </div>
       </file>
       <file name="script.js">
         angular.module('anchorScrollExample', [])
           .controller('ScrollController', ['$scope', '$location', '$anchorScroll',
             function ($scope, $location, $anchorScroll) {
               $scope.gotoBottom = function() {
                 // set the location.hash to the id of
                 // the element you wish to scroll to.
                 $location.hash('bottom');

                 // call $anchorScroll()
                 $anchorScroll();
               };
             }]);
       </file>
       <file name="style.css">
         #scrollArea {
           height: 280px;
           overflow: auto;
         }

         #bottom {
           display: block;
           margin-top: 2000px;
         }
       </file>
     </example>
   *
   * <hr />
   * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).
   * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.
   *
   * @example
     <example module="anchorScrollOffsetExample">
       <file name="index.html">
         <div class="fixed-header" ng-controller="headerCtrl">
           <a href="" ng-click="gotoAnchor(x)" ng-repeat="x in [1,2,3,4,5]">
             Go to anchor {{x}}
           </a>
         </div>
         <div id="anchor{{x}}" class="anchor" ng-repeat="x in [1,2,3,4,5]">
           Anchor {{x}} of 5
         </div>
       </file>
       <file name="script.js">
         angular.module('anchorScrollOffsetExample', [])
           .run(['$anchorScroll', function($anchorScroll) {
             $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels
           }])
           .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',
             function ($anchorScroll, $location, $scope) {
               $scope.gotoAnchor = function(x) {
                 var newHash = 'anchor' + x;
                 if ($location.hash() !== newHash) {
                   // set the $location.hash to `newHash` and
                   // $anchorScroll will automatically scroll to it
                   $location.hash('anchor' + x);
                 } else {
                   // call $anchorScroll() explicitly,
                   // since $location.hash hasn't changed
                   $anchorScroll();
                 }
               };
             }
           ]);
       </file>
       <file name="style.css">
         body {
           padding-top: 50px;
         }

         .anchor {
           border: 2px dashed DarkOrchid;
           padding: 10px 10px 200px 10px;
         }

         .fixed-header {
           background-color: rgba(0, 0, 0, 0.2);
           height: 50px;
           position: fixed;
           top: 0; left: 0; right: 0;
         }

         .fixed-header > a {
           display: inline-block;
           margin: 5px 15px;
         }
       </file>
     </example>
   */
  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
    var document = $window.document;

    // Helper function to get first anchor from a NodeList
    // (using `Array#some()` instead of `angular#forEach()` since it's more performant
    //  and working in all supported browsers.)
    function getFirstAnchor(list) {
      var result = null;
      Array.prototype.some.call(list, function(element) {
        if (nodeName_(element) === 'a') {
          result = element;
          return true;
        }
      });
      return result;
    }

    function getYOffset() {

      var offset = scroll.yOffset;

      if (isFunction(offset)) {
        offset = offset();
      } else if (isElement(offset)) {
        var elem = offset[0];
        var style = $window.getComputedStyle(elem);
        if (style.position !== 'fixed') {
          offset = 0;
        } else {
          offset = elem.getBoundingClientRect().bottom;
        }
      } else if (!isNumber(offset)) {
        offset = 0;
      }

      return offset;
    }

    function scrollTo(elem) {
      if (elem) {
        elem.scrollIntoView();

        var offset = getYOffset();

        if (offset) {
          // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.
          // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the
          // top of the viewport.
          //
          // IF the number of pixels from the top of `elem` to the end of the page's content is less
          // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some
          // way down the page.
          //
          // This is often the case for elements near the bottom of the page.
          //
          // In such cases we do not need to scroll the whole `offset` up, just the difference between
          // the top of the element and the offset, which is enough to align the top of `elem` at the
          // desired position.
          var elemTop = elem.getBoundingClientRect().top;
          $window.scrollBy(0, elemTop - offset);
        }
      } else {
        $window.scrollTo(0, 0);
      }
    }

    function scroll() {
      var hash = $location.hash(), elm;

      // empty hash, scroll to the top of the page
      if (!hash) scrollTo(null);

      // element with given id
      else if ((elm = document.getElementById(hash))) scrollTo(elm);

      // first anchor with given name :-D
      else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);

      // no element and hash == 'top', scroll to the top of the page
      else if (hash === 'top') scrollTo(null);
    }

    // does not scroll when user clicks on anchor link that is currently on
    // (no url change, no $location.hash() change), browser native does scroll
    if (autoScrollingEnabled) {
      $rootScope.$watch(function autoScrollWatch() {return $location.hash();},
        function autoScrollWatchAction(newVal, oldVal) {
          // skip the initial scroll if $location.hash is empty
          if (newVal === oldVal && newVal === '') return;

          jqLiteDocumentLoaded(function() {
            $rootScope.$evalAsync(scroll);
          });
        });
    }

    return scroll;
  }];
}

var $animateMinErr = minErr('$animate');

/**
 * @ngdoc provider
 * @name $animateProvider
 *
 * @description
 * Default implementation of $animate that doesn't perform any animations, instead just
 * synchronously performs DOM
 * updates and calls done() callbacks.
 *
 * In order to enable animations the ngAnimate module has to be loaded.
 *
 * To see the functional implementation check out src/ngAnimate/animate.js
 */
var $AnimateProvider = ['$provide', function($provide) {


  this.$$selectors = {};


  /**
   * @ngdoc method
   * @name $animateProvider#register
   *
   * @description
   * Registers a new injectable animation factory function. The factory function produces the
   * animation object which contains callback functions for each event that is expected to be
   * animated.
   *
   *   * `eventFn`: `function(Element, doneFunction)` The element to animate, the `doneFunction`
   *   must be called once the element animation is complete. If a function is returned then the
   *   animation service will use this function to cancel the animation whenever a cancel event is
   *   triggered.
   *
   *
   * ```js
   *   return {
     *     eventFn : function(element, done) {
     *       //code to run the animation
     *       //once complete, then run done()
     *       return function cancellationFunction() {
     *         //code to cancel the animation
     *       }
     *     }
     *   }
   * ```
   *
   * @param {string} name The name of the animation.
   * @param {Function} factory The factory function that will be executed to return the animation
   *                           object.
   */
  this.register = function(name, factory) {
    var key = name + '-animation';
    if (name && name.charAt(0) != '.') throw $animateMinErr('notcsel',
        "Expecting class selector starting with '.' got '{0}'.", name);
    this.$$selectors[name.substr(1)] = key;
    $provide.factory(key, factory);
  };

  /**
   * @ngdoc method
   * @name $animateProvider#classNameFilter
   *
   * @description
   * Sets and/or returns the CSS class regular expression that is checked when performing
   * an animation. Upon bootstrap the classNameFilter value is not set at all and will
   * therefore enable $animate to attempt to perform an animation on any element.
   * When setting the classNameFilter value, animations will only be performed on elements
   * that successfully match the filter expression. This in turn can boost performance
   * for low-powered devices as well as applications containing a lot of structural operations.
   * @param {RegExp=} expression The className expression which will be checked against all animations
   * @return {RegExp} The current CSS className expression value. If null then there is no expression value
   */
  this.classNameFilter = function(expression) {
    if (arguments.length === 1) {
      this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
    }
    return this.$$classNameFilter;
  };

  this.$get = ['$$q', '$$asyncCallback', '$rootScope', function($$q, $$asyncCallback, $rootScope) {

    var currentDefer;

    function runAnimationPostDigest(fn) {
      var cancelFn, defer = $$q.defer();
      defer.promise.$$cancelFn = function ngAnimateMaybeCancel() {
        cancelFn && cancelFn();
      };

      $rootScope.$$postDigest(function ngAnimatePostDigest() {
        cancelFn = fn(function ngAnimateNotifyComplete() {
          defer.resolve();
        });
      });

      return defer.promise;
    }

    function resolveElementClasses(element, classes) {
      var toAdd = [], toRemove = [];

      var hasClasses = createMap();
      forEach((element.attr('class') || '').split(/\s+/), function(className) {
        hasClasses[className] = true;
      });

      forEach(classes, function(status, className) {
        var hasClass = hasClasses[className];

        // If the most recent class manipulation (via $animate) was to remove the class, and the
        // element currently has the class, the class is scheduled for removal. Otherwise, if
        // the most recent class manipulation (via $animate) was to add the class, and the
        // element does not currently have the class, the class is scheduled to be added.
        if (status === false && hasClass) {
          toRemove.push(className);
        } else if (status === true && !hasClass) {
          toAdd.push(className);
        }
      });

      return (toAdd.length + toRemove.length) > 0 &&
        [toAdd.length ? toAdd : null, toRemove.length ? toRemove : null];
    }

    function cachedClassManipulation(cache, classes, op) {
      for (var i=0, ii = classes.length; i < ii; ++i) {
        var className = classes[i];
        cache[className] = op;
      }
    }

    function asyncPromise() {
      // only serve one instance of a promise in order to save CPU cycles
      if (!currentDefer) {
        currentDefer = $$q.defer();
        $$asyncCallback(function() {
          currentDefer.resolve();
          currentDefer = null;
        });
      }
      return currentDefer.promise;
    }

    function applyStyles(element, options) {
      if (angular.isObject(options)) {
        var styles = extend(options.from || {}, options.to || {});
        element.css(styles);
      }
    }

    /**
     *
     * @ngdoc service
     * @name $animate
     * @description The $animate service provides rudimentary DOM manipulation functions to
     * insert, remove and move elements within the DOM, as well as adding and removing classes.
     * This service is the core service used by the ngAnimate $animator service which provides
     * high-level animation hooks for CSS and JavaScript.
     *
     * $animate is available in the AngularJS core, however, the ngAnimate module must be included
     * to enable full out animation support. Otherwise, $animate will only perform simple DOM
     * manipulation operations.
     *
     * To learn more about enabling animation support, click here to visit the {@link ngAnimate
     * ngAnimate module page} as well as the {@link ngAnimate.$animate ngAnimate $animate service
     * page}.
     */
    return {
      animate: function(element, from, to) {
        applyStyles(element, { from: from, to: to });
        return asyncPromise();
      },

      /**
       *
       * @ngdoc method
       * @name $animate#enter
       * @kind function
       * @description Inserts the element into the DOM either after the `after` element or
       * as the first child within the `parent` element. When the function is called a promise
       * is returned that will be resolved at a later time.
       * @param {DOMElement} element the element which will be inserted into the DOM
       * @param {DOMElement} parent the parent element which will append the element as
       *   a child (if the after element is not present)
       * @param {DOMElement} after the sibling element which will append the element
       *   after itself
       * @param {object=} options an optional collection of styles that will be applied to the element.
       * @return {Promise} the animation callback promise
       */
      enter: function(element, parent, after, options) {
        applyStyles(element, options);
        after ? after.after(element)
              : parent.prepend(element);
        return asyncPromise();
      },

      /**
       *
       * @ngdoc method
       * @name $animate#leave
       * @kind function
       * @description Removes the element from the DOM. When the function is called a promise
       * is returned that will be resolved at a later time.
       * @param {DOMElement} element the element which will be removed from the DOM
       * @param {object=} options an optional collection of options that will be applied to the element.
       * @return {Promise} the animation callback promise
       */
      leave: function(element, options) {
        applyStyles(element, options);
        element.remove();
        return asyncPromise();
      },

      /**
       *
       * @ngdoc method
       * @name $animate#move
       * @kind function
       * @description Moves the position of the provided element within the DOM to be placed
       * either after the `after` element or inside of the `parent` element. When the function
       * is called a promise is returned that will be resolved at a later time.
       *
       * @param {DOMElement} element the element which will be moved around within the
       *   DOM
       * @param {DOMElement} parent the parent element where the element will be
       *   inserted into (if the after element is not present)
       * @param {DOMElement} after the sibling element where the element will be
       *   positioned next to
       * @param {object=} options an optional collection of options that will be applied to the element.
       * @return {Promise} the animation callback promise
       */
      move: function(element, parent, after, options) {
        // Do not remove element before insert. Removing will cause data associated with the
        // element to be dropped. Insert will implicitly do the remove.
        return this.enter(element, parent, after, options);
      },

      /**
       *
       * @ngdoc method
       * @name $animate#addClass
       * @kind function
       * @description Adds the provided className CSS class value to the provided element.
       * When the function is called a promise is returned that will be resolved at a later time.
       * @param {DOMElement} element the element which will have the className value
       *   added to it
       * @param {string} className the CSS class which will be added to the element
       * @param {object=} options an optional collection of options that will be applied to the element.
       * @return {Promise} the animation callback promise
       */
      addClass: function(element, className, options) {
        return this.setClass(element, className, [], options);
      },

      $$addClassImmediately: function(element, className, options) {
        element = jqLite(element);
        className = !isString(className)
                        ? (isArray(className) ? className.join(' ') : '')
                        : className;
        forEach(element, function(element) {
          jqLiteAddClass(element, className);
        });
        applyStyles(element, options);
        return asyncPromise();
      },

      /**
       *
       * @ngdoc method
       * @name $animate#removeClass
       * @kind function
       * @description Removes the provided className CSS class value from the provided element.
       * When the function is called a promise is returned that will be resolved at a later time.
       * @param {DOMElement} element the element which will have the className value
       *   removed from it
       * @param {string} className the CSS class which will be removed from the element
       * @param {object=} options an optional collection of options that will be applied to the element.
       * @return {Promise} the animation callback promise
       */
      removeClass: function(element, className, options) {
        return this.setClass(element, [], className, options);
      },

      $$removeClassImmediately: function(element, className, options) {
        element = jqLite(element);
        className = !isString(className)
                        ? (isArray(className) ? className.join(' ') : '')
                        : className;
        forEach(element, function(element) {
          jqLiteRemoveClass(element, className);
        });
        applyStyles(element, options);
        return asyncPromise();
      },

      /**
       *
       * @ngdoc method
       * @name $animate#setClass
       * @kind function
       * @description Adds and/or removes the given CSS classes to and from the element.
       * When the function is called a promise is returned that will be resolved at a later time.
       * @param {DOMElement} element the element which will have its CSS classes changed
       *   removed from it
       * @param {string} add the CSS classes which will be added to the element
       * @param {string} remove the CSS class which will be removed from the element
       * @param {object=} options an optional collection of options that will be applied to the element.
       * @return {Promise} the animation callback promise
       */
      setClass: function(element, add, remove, options) {
        var self = this;
        var STORAGE_KEY = '$$animateClasses';
        var createdCache = false;
        element = jqLite(element);

        var cache = element.data(STORAGE_KEY);
        if (!cache) {
          cache = {
            classes: {},
            options: options
          };
          createdCache = true;
        } else if (options && cache.options) {
          cache.options = angular.extend(cache.options || {}, options);
        }

        var classes = cache.classes;

        add = isArray(add) ? add : add.split(' ');
        remove = isArray(remove) ? remove : remove.split(' ');
        cachedClassManipulation(classes, add, true);
        cachedClassManipulation(classes, remove, false);

        if (createdCache) {
          cache.promise = runAnimationPostDigest(function(done) {
            var cache = element.data(STORAGE_KEY);
            element.removeData(STORAGE_KEY);

            // in the event that the element is removed before postDigest
            // is run then the cache will be undefined and there will be
            // no need anymore to add or remove and of the element classes
            if (cache) {
              var classes = resolveElementClasses(element, cache.classes);
              if (classes) {
                self.$$setClassImmediately(element, classes[0], classes[1], cache.options);
              }
            }

            done();
          });
          element.data(STORAGE_KEY, cache);
        }

        return cache.promise;
      },

      $$setClassImmediately: function(element, add, remove, options) {
        add && this.$$addClassImmediately(element, add);
        remove && this.$$removeClassImmediately(element, remove);
        applyStyles(element, options);
        return asyncPromise();
      },

      enabled: noop,
      cancel: noop
    };
  }];
}];

function $$AsyncCallbackProvider() {
  this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) {
    return $$rAF.supported
      ? function(fn) { return $$rAF(fn); }
      : function(fn) {
        return $timeout(fn, 0, false);
      };
  }];
}

/* global stripHash: true */

/**
 * ! This is a private undocumented service !
 *
 * @name $browser
 * @requires $log
 * @description
 * This object has two goals:
 *
 * - hide all the global state in the browser caused by the window object
 * - abstract away all the browser specific features and inconsistencies
 *
 * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser`
 * service, which can be used for convenient testing of the application without the interaction with
 * the real browser apis.
 */
/**
 * @param {object} window The global window object.
 * @param {object} document jQuery wrapped document.
 * @param {object} $log window.console or an object with the same interface.
 * @param {object} $sniffer $sniffer service
 */
function Browser(window, document, $log, $sniffer) {
  var self = this,
      rawDocument = document[0],
      location = window.location,
      history = window.history,
      setTimeout = window.setTimeout,
      clearTimeout = window.clearTimeout,
      pendingDeferIds = {};

  self.isMock = false;

  var outstandingRequestCount = 0;
  var outstandingRequestCallbacks = [];

  // TODO(vojta): remove this temporary api
  self.$$completeOutstandingRequest = completeOutstandingRequest;
  self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; };

  /**
   * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks`
   * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.
   */
  function completeOutstandingRequest(fn) {
    try {
      fn.apply(null, sliceArgs(arguments, 1));
    } finally {
      outstandingRequestCount--;
      if (outstandingRequestCount === 0) {
        while (outstandingRequestCallbacks.length) {
          try {
            outstandingRequestCallbacks.pop()();
          } catch (e) {
            $log.error(e);
          }
        }
      }
    }
  }

  function getHash(url) {
    var index = url.indexOf('#');
    return index === -1 ? '' : url.substr(index);
  }

  /**
   * @private
   * Note: this method is used only by scenario runner
   * TODO(vojta): prefix this method with $$ ?
   * @param {function()} callback Function that will be called when no outstanding request
   */
  self.notifyWhenNoOutstandingRequests = function(callback) {
    // force browser to execute all pollFns - this is needed so that cookies and other pollers fire
    // at some deterministic time in respect to the test runner's actions. Leaving things up to the
    // regular poller would result in flaky tests.
    forEach(pollFns, function(pollFn) { pollFn(); });

    if (outstandingRequestCount === 0) {
      callback();
    } else {
      outstandingRequestCallbacks.push(callback);
    }
  };

  //////////////////////////////////////////////////////////////
  // Poll Watcher API
  //////////////////////////////////////////////////////////////
  var pollFns = [],
      pollTimeout;

  /**
   * @name $browser#addPollFn
   *
   * @param {function()} fn Poll function to add
   *
   * @description
   * Adds a function to the list of functions that poller periodically executes,
   * and starts polling if not started yet.
   *
   * @returns {function()} the added function
   */
  self.addPollFn = function(fn) {
    if (isUndefined(pollTimeout)) startPoller(100, setTimeout);
    pollFns.push(fn);
    return fn;
  };

  /**
   * @param {number} interval How often should browser call poll functions (ms)
   * @param {function()} setTimeout Reference to a real or fake `setTimeout` function.
   *
   * @description
   * Configures the poller to run in the specified intervals, using the specified
   * setTimeout fn and kicks it off.
   */
  function startPoller(interval, setTimeout) {
    (function check() {
      forEach(pollFns, function(pollFn) { pollFn(); });
      pollTimeout = setTimeout(check, interval);
    })();
  }

  //////////////////////////////////////////////////////////////
  // URL API
  //////////////////////////////////////////////////////////////

  var cachedState, lastHistoryState,
      lastBrowserUrl = location.href,
      baseElement = document.find('base'),
      reloadLocation = null;

  cacheState();
  lastHistoryState = cachedState;

  /**
   * @name $browser#url
   *
   * @description
   * GETTER:
   * Without any argument, this method just returns current value of location.href.
   *
   * SETTER:
   * With at least one argument, this method sets url to new value.
   * If html5 history api supported, pushState/replaceState is used, otherwise
   * location.href/location.replace is used.
   * Returns its own instance to allow chaining
   *
   * NOTE: this api is intended for use only by the $location service. Please use the
   * {@link ng.$location $location service} to change url.
   *
   * @param {string} url New url (when used as setter)
   * @param {boolean=} replace Should new url replace current history record?
   * @param {object=} state object to use with pushState/replaceState
   */
  self.url = function(url, replace, state) {
    // In modern browsers `history.state` is `null` by default; treating it separately
    // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
    // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
    if (isUndefined(state)) {
      state = null;
    }

    // Android Browser BFCache causes location, history reference to become stale.
    if (location !== window.location) location = window.location;
    if (history !== window.history) history = window.history;

    // setter
    if (url) {
      var sameState = lastHistoryState === state;

      // Don't change anything if previous and current URLs and states match. This also prevents
      // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
      // See https://github.com/angular/angular.js/commit/ffb2701
      if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
        return self;
      }
      var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
      lastBrowserUrl = url;
      lastHistoryState = state;
      // Don't use history API if only the hash changed
      // due to a bug in IE10/IE11 which leads
      // to not firing a `hashchange` nor `popstate` event
      // in some cases (see #9143).
      if ($sniffer.history && (!sameBase || !sameState)) {
        history[replace ? 'replaceState' : 'pushState'](state, '', url);
        cacheState();
        // Do the assignment again so that those two variables are referentially identical.
        lastHistoryState = cachedState;
      } else {
        if (!sameBase || reloadLocation) {
          reloadLocation = url;
        }
        if (replace) {
          location.replace(url);
        } else if (!sameBase) {
          location.href = url;
        } else {
          location.hash = getHash(url);
        }
      }
      return self;
    // getter
    } else {
      // - reloadLocation is needed as browsers don't allow to read out
      //   the new location.href if a reload happened.
      // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
      return reloadLocation || location.href.replace(/%27/g,"'");
    }
  };

  /**
   * @name $browser#state
   *
   * @description
   * This method is a getter.
   *
   * Return history.state or null if history.state is undefined.
   *
   * @returns {object} state
   */
  self.state = function() {
    return cachedState;
  };

  var urlChangeListeners = [],
      urlChangeInit = false;

  function cacheStateAndFireUrlChange() {
    cacheState();
    fireUrlChange();
  }

  function getCurrentState() {
    try {
      return history.state;
    } catch (e) {
      // MSIE can reportedly throw when there is no state (UNCONFIRMED).
    }
  }

  // This variable should be used *only* inside the cacheState function.
  var lastCachedState = null;
  function cacheState() {
    // This should be the only place in $browser where `history.state` is read.
    cachedState = getCurrentState();
    cachedState = isUndefined(cachedState) ? null : cachedState;

    // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
    if (equals(cachedState, lastCachedState)) {
      cachedState = lastCachedState;
    }
    lastCachedState = cachedState;
  }

  function fireUrlChange() {
    if (lastBrowserUrl === self.url() && lastHistoryState === cachedState) {
      return;
    }

    lastBrowserUrl = self.url();
    lastHistoryState = cachedState;
    forEach(urlChangeListeners, function(listener) {
      listener(self.url(), cachedState);
    });
  }

  /**
   * @name $browser#onUrlChange
   *
   * @description
   * Register callback function that will be called, when url changes.
   *
   * It's only called when the url is changed from outside of angular:
   * - user types different url into address bar
   * - user clicks on history (forward/back) button
   * - user clicks on a link
   *
   * It's not called when url is changed by $browser.url() method
   *
   * The listener gets called with new url as parameter.
   *
   * NOTE: this api is intended for use only by the $location service. Please use the
   * {@link ng.$location $location service} to monitor url changes in angular apps.
   *
   * @param {function(string)} listener Listener function to be called when url changes.
   * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous.
   */
  self.onUrlChange = function(callback) {
    // TODO(vojta): refactor to use node's syntax for events
    if (!urlChangeInit) {
      // We listen on both (hashchange/popstate) when available, as some browsers (e.g. Opera)
      // don't fire popstate when user change the address bar and don't fire hashchange when url
      // changed by push/replaceState

      // html5 history api - popstate event
      if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
      // hashchange event
      jqLite(window).on('hashchange', cacheStateAndFireUrlChange);

      urlChangeInit = true;
    }

    urlChangeListeners.push(callback);
    return callback;
  };

  /**
   * Checks whether the url has changed outside of Angular.
   * Needs to be exported to be able to check for changes that have been done in sync,
   * as hashchange/popstate events fire in async.
   */
  self.$$checkUrlChange = fireUrlChange;

  //////////////////////////////////////////////////////////////
  // Misc API
  //////////////////////////////////////////////////////////////

  /**
   * @name $browser#baseHref
   *
   * @description
   * Returns current <base href>
   * (always relative - without domain)
   *
   * @returns {string} The current base href
   */
  self.baseHref = function() {
    var href = baseElement.attr('href');
    return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
  };

  //////////////////////////////////////////////////////////////
  // Cookies API
  //////////////////////////////////////////////////////////////
  var lastCookies = {};
  var lastCookieString = '';
  var cookiePath = self.baseHref();

  function safeDecodeURIComponent(str) {
    try {
      return decodeURIComponent(str);
    } catch (e) {
      return str;
    }
  }

  /**
   * @name $browser#cookies
   *
   * @param {string=} name Cookie name
   * @param {string=} value Cookie value
   *
   * @description
   * The cookies method provides a 'private' low level access to browser cookies.
   * It is not meant to be used directly, use the $cookie service instead.
   *
   * The return values vary depending on the arguments that the method was called with as follows:
   *
   * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
   *   it
   * - cookies(name, value) -> set name to value, if value is undefined delete the cookie
   * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
   *   way)
   *
   * @returns {Object} Hash of all cookies (if called without any parameter)
   */
  self.cookies = function(name, value) {
    var cookieLength, cookieArray, cookie, i, index;

    if (name) {
      if (value === undefined) {
        rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
                                ";expires=Thu, 01 Jan 1970 00:00:00 GMT";
      } else {
        if (isString(value)) {
          cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
                                ';path=' + cookiePath).length + 1;

          // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
          // - 300 cookies
          // - 20 cookies per unique domain
          // - 4096 bytes per cookie
          if (cookieLength > 4096) {
            $log.warn("Cookie '" + name +
              "' possibly not set or overflowed because it was too large (" +
              cookieLength + " > 4096 bytes)!");
          }
        }
      }
    } else {
      if (rawDocument.cookie !== lastCookieString) {
        lastCookieString = rawDocument.cookie;
        cookieArray = lastCookieString.split("; ");
        lastCookies = {};

        for (i = 0; i < cookieArray.length; i++) {
          cookie = cookieArray[i];
          index = cookie.indexOf('=');
          if (index > 0) { //ignore nameless cookies
            name = safeDecodeURIComponent(cookie.substring(0, index));
            // the first value that is seen for a cookie is the most
            // specific one.  values for the same cookie name that
            // follow are for less specific paths.
            if (lastCookies[name] === undefined) {
              lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
            }
          }
        }
      }
      return lastCookies;
    }
  };


  /**
   * @name $browser#defer
   * @param {function()} fn A function, who's execution should be deferred.
   * @param {number=} [delay=0] of milliseconds to defer the function execution.
   * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.
   *
   * @description
   * Executes a fn asynchronously via `setTimeout(fn, delay)`.
   *
   * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using
   * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed
   * via `$browser.defer.flush()`.
   *
   */
  self.defer = function(fn, delay) {
    var timeoutId;
    outstandingRequestCount++;
    timeoutId = setTimeout(function() {
      delete pendingDeferIds[timeoutId];
      completeOutstandingRequest(fn);
    }, delay || 0);
    pendingDeferIds[timeoutId] = true;
    return timeoutId;
  };


  /**
   * @name $browser#defer.cancel
   *
   * @description
   * Cancels a deferred task identified with `deferId`.
   *
   * @param {*} deferId Token returned by the `$browser.defer` function.
   * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
   *                    canceled.
   */
  self.defer.cancel = function(deferId) {
    if (pendingDeferIds[deferId]) {
      delete pendingDeferIds[deferId];
      clearTimeout(deferId);
      completeOutstandingRequest(noop);
      return true;
    }
    return false;
  };

}

function $BrowserProvider() {
  this.$get = ['$window', '$log', '$sniffer', '$document',
      function($window, $log, $sniffer, $document) {
        return new Browser($window, $document, $log, $sniffer);
      }];
}

/**
 * @ngdoc service
 * @name $cacheFactory
 *
 * @description
 * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to
 * them.
 *
 * ```js
 *
 *  var cache = $cacheFactory('cacheId');
 *  expect($cacheFactory.get('cacheId')).toBe(cache);
 *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
 *
 *  cache.put("key", "value");
 *  cache.put("another key", "another value");
 *
 *  // We've specified no options on creation
 *  expect(cache.info()).toEqual({id: 'cacheId', size: 2});
 *
 * ```
 *
 *
 * @param {string} cacheId Name or id of the newly created cache.
 * @param {object=} options Options object that specifies the cache behavior. Properties:
 *
 *   - `{number=}` `capacity` — turns the cache into LRU cache.
 *
 * @returns {object} Newly created cache object with the following set of methods:
 *
 * - `{object}` `info()` — Returns id, size, and options of cache.
 * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns
 *   it.
 * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
 * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
 * - `{void}` `removeAll()` — Removes all cached values.
 * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
 *
 * @example
   <example module="cacheExampleApp">
     <file name="index.html">
       <div ng-controller="CacheController">
         <input ng-model="newCacheKey" placeholder="Key">
         <input ng-model="newCacheValue" placeholder="Value">
         <button ng-click="put(newCacheKey, newCacheValue)">Cache</button>

         <p ng-if="keys.length">Cached Values</p>
         <div ng-repeat="key in keys">
           <span ng-bind="key"></span>
           <span>: </span>
           <b ng-bind="cache.get(key)"></b>
         </div>

         <p>Cache Info</p>
         <div ng-repeat="(key, value) in cache.info()">
           <span ng-bind="key"></span>
           <span>: </span>
           <b ng-bind="value"></b>
         </div>
       </div>
     </file>
     <file name="script.js">
       angular.module('cacheExampleApp', []).
         controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) {
           $scope.keys = [];
           $scope.cache = $cacheFactory('cacheId');
           $scope.put = function(key, value) {
             if ($scope.cache.get(key) === undefined) {
               $scope.keys.push(key);
             }
             $scope.cache.put(key, value === undefined ? null : value);
           };
         }]);
     </file>
     <file name="style.css">
       p {
         margin: 10px 0 3px;
       }
     </file>
   </example>
 */
function $CacheFactoryProvider() {

  this.$get = function() {
    var caches = {};

    function cacheFactory(cacheId, options) {
      if (cacheId in caches) {
        throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId);
      }

      var size = 0,
          stats = extend({}, options, {id: cacheId}),
          data = {},
          capacity = (options && options.capacity) || Number.MAX_VALUE,
          lruHash = {},
          freshEnd = null,
          staleEnd = null;

      /**
       * @ngdoc type
       * @name $cacheFactory.Cache
       *
       * @description
       * A cache object used to store and retrieve data, primarily used by
       * {@link $http $http} and the {@link ng.directive:script script} directive to cache
       * templates and other data.
       *
       * ```js
       *  angular.module('superCache')
       *    .factory('superCache', ['$cacheFactory', function($cacheFactory) {
       *      return $cacheFactory('super-cache');
       *    }]);
       * ```
       *
       * Example test:
       *
       * ```js
       *  it('should behave like a cache', inject(function(superCache) {
       *    superCache.put('key', 'value');
       *    superCache.put('another key', 'another value');
       *
       *    expect(superCache.info()).toEqual({
       *      id: 'super-cache',
       *      size: 2
       *    });
       *
       *    superCache.remove('another key');
       *    expect(superCache.get('another key')).toBeUndefined();
       *
       *    superCache.removeAll();
       *    expect(superCache.info()).toEqual({
       *      id: 'super-cache',
       *      size: 0
       *    });
       *  }));
       * ```
       */
      return caches[cacheId] = {

        /**
         * @ngdoc method
         * @name $cacheFactory.Cache#put
         * @kind function
         *
         * @description
         * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be
         * retrieved later, and incrementing the size of the cache if the key was not already
         * present in the cache. If behaving like an LRU cache, it will also remove stale
         * entries from the set.
         *
         * It will not insert undefined values into the cache.
         *
         * @param {string} key the key under which the cached data is stored.
         * @param {*} value the value to store alongside the key. If it is undefined, the key
         *    will not be stored.
         * @returns {*} the value stored.
         */
        put: function(key, value) {
          if (capacity < Number.MAX_VALUE) {
            var lruEntry = lruHash[key] || (lruHash[key] = {key: key});

            refresh(lruEntry);
          }

          if (isUndefined(value)) return;
          if (!(key in data)) size++;
          data[key] = value;

          if (size > capacity) {
            this.remove(staleEnd.key);
          }

          return value;
        },

        /**
         * @ngdoc method
         * @name $cacheFactory.Cache#get
         * @kind function
         *
         * @description
         * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.
         *
         * @param {string} key the key of the data to be retrieved
         * @returns {*} the value stored.
         */
        get: function(key) {
          if (capacity < Number.MAX_VALUE) {
            var lruEntry = lruHash[key];

            if (!lruEntry) return;

            refresh(lruEntry);
          }

          return data[key];
        },


        /**
         * @ngdoc method
         * @name $cacheFactory.Cache#remove
         * @kind function
         *
         * @description
         * Removes an entry from the {@link $cacheFactory.Cache Cache} object.
         *
         * @param {string} key the key of the entry to be removed
         */
        remove: function(key) {
          if (capacity < Number.MAX_VALUE) {
            var lruEntry = lruHash[key];

            if (!lruEntry) return;

            if (lruEntry == freshEnd) freshEnd = lruEntry.p;
            if (lruEntry == staleEnd) staleEnd = lruEntry.n;
            link(lruEntry.n,lruEntry.p);

            delete lruHash[key];
          }

          delete data[key];
          size--;
        },


        /**
         * @ngdoc method
         * @name $cacheFactory.Cache#removeAll
         * @kind function
         *
         * @description
         * Clears the cache object of any entries.
         */
        removeAll: function() {
          data = {};
          size = 0;
          lruHash = {};
          freshEnd = staleEnd = null;
        },


        /**
         * @ngdoc method
         * @name $cacheFactory.Cache#destroy
         * @kind function
         *
         * @description
         * Destroys the {@link $cacheFactory.Cache Cache} object entirely,
         * removing it from the {@link $cacheFactory $cacheFactory} set.
         */
        destroy: function() {
          data = null;
          stats = null;
          lruHash = null;
          delete caches[cacheId];
        },


        /**
         * @ngdoc method
         * @name $cacheFactory.Cache#info
         * @kind function
         *
         * @description
         * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.
         *
         * @returns {object} an object with the following properties:
         *   <ul>
         *     <li>**id**: the id of the cache instance</li>
         *     <li>**size**: the number of entries kept in the cache instance</li>
         *     <li>**...**: any additional properties from the options object when creating the
         *       cache.</li>
         *   </ul>
         */
        info: function() {
          return extend({}, stats, {size: size});
        }
      };


      /**
       * makes the `entry` the freshEnd of the LRU linked list
       */
      function refresh(entry) {
        if (entry != freshEnd) {
          if (!staleEnd) {
            staleEnd = entry;
          } else if (staleEnd == entry) {
            staleEnd = entry.n;
          }

          link(entry.n, entry.p);
          link(entry, freshEnd);
          freshEnd = entry;
          freshEnd.n = null;
        }
      }


      /**
       * bidirectionally links two entries of the LRU linked list
       */
      function link(nextEntry, prevEntry) {
        if (nextEntry != prevEntry) {
          if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify
          if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify
        }
      }
    }


  /**
   * @ngdoc method
   * @name $cacheFactory#info
   *
   * @description
   * Get information about all the caches that have been created
   *
   * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
   */
    cacheFactory.info = function() {
      var info = {};
      forEach(caches, function(cache, cacheId) {
        info[cacheId] = cache.info();
      });
      return info;
    };


  /**
   * @ngdoc method
   * @name $cacheFactory#get
   *
   * @description
   * Get access to a cache object by the `cacheId` used when it was created.
   *
   * @param {string} cacheId Name or id of a cache to access.
   * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
   */
    cacheFactory.get = function(cacheId) {
      return caches[cacheId];
    };


    return cacheFactory;
  };
}

/**
 * @ngdoc service
 * @name $templateCache
 *
 * @description
 * The first time a template is used, it is loaded in the template cache for quick retrieval. You
 * can load templates directly into the cache in a `script` tag, or by consuming the
 * `$templateCache` service directly.
 *
 * Adding via the `script` tag:
 *
 * ```html
 *   <script type="text/ng-template" id="templateId.html">
 *     <p>This is the content of the template</p>
 *   </script>
 * ```
 *
 * **Note:** the `script` tag containing the template does not need to be included in the `head` of
 * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
 * element with ng-app attribute), otherwise the template will be ignored.
 *
 * Adding via the `$templateCache` service:
 *
 * ```js
 * var myApp = angular.module('myApp', []);
 * myApp.run(function($templateCache) {
 *   $templateCache.put('templateId.html', 'This is the content of the template');
 * });
 * ```
 *
 * To retrieve the template later, simply use it in your HTML:
 * ```html
 * <div ng-include=" 'templateId.html' "></div>
 * ```
 *
 * or get it via Javascript:
 * ```js
 * $templateCache.get('templateId.html')
 * ```
 *
 * See {@link ng.$cacheFactory $cacheFactory}.
 *
 */
function $TemplateCacheProvider() {
  this.$get = ['$cacheFactory', function($cacheFactory) {
    return $cacheFactory('templates');
  }];
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *     Any commits to this file should be reviewed with security in mind.  *
 *   Changes to this file can potentially create security vulnerabilities. *
 *          An approval from 2 Core members with history of modifying      *
 *                         this file is required.                          *
 *                                                                         *
 *  Does the change somehow allow for arbitrary javascript to be executed? *
 *    Or allows for someone to change the prototype of built-in objects?   *
 *     Or gives undesired access to variables likes document or window?    *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!
 *
 * DOM-related variables:
 *
 * - "node" - DOM Node
 * - "element" - DOM Element or Node
 * - "$node" or "$element" - jqLite-wrapped node or element
 *
 *
 * Compiler related stuff:
 *
 * - "linkFn" - linking fn of a single directive
 * - "nodeLinkFn" - function that aggregates all linking fns for a particular node
 * - "childLinkFn" -  function that aggregates all linking fns for child nodes of a particular node
 * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList)
 */


/**
 * @ngdoc service
 * @name $compile
 * @kind function
 *
 * @description
 * Compiles an HTML string or DOM into a template and produces a template function, which
 * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.
 *
 * The compilation is a process of walking the DOM tree and matching DOM elements to
 * {@link ng.$compileProvider#directive directives}.
 *
 * <div class="alert alert-warning">
 * **Note:** This document is an in-depth reference of all directive options.
 * For a gentle introduction to directives with examples of common use cases,
 * see the {@link guide/directive directive guide}.
 * </div>
 *
 * ## Comprehensive Directive API
 *
 * There are many different options for a directive.
 *
 * The difference resides in the return value of the factory function.
 * You can either return a "Directive Definition Object" (see below) that defines the directive properties,
 * or just the `postLink` function (all other properties will have the default values).
 *
 * <div class="alert alert-success">
 * **Best Practice:** It's recommended to use the "directive definition object" form.
 * </div>
 *
 * Here's an example directive declared with a Directive Definition Object:
 *
 * ```js
 *   var myModule = angular.module(...);
 *
 *   myModule.directive('directiveName', function factory(injectables) {
 *     var directiveDefinitionObject = {
 *       priority: 0,
 *       template: '<div></div>', // or // function(tElement, tAttrs) { ... },
 *       // or
 *       // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
 *       transclude: false,
 *       restrict: 'A',
 *       templateNamespace: 'html',
 *       scope: false,
 *       controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
 *       controllerAs: 'stringIdentifier',
 *       bindToController: false,
 *       require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
 *       compile: function compile(tElement, tAttrs, transclude) {
 *         return {
 *           pre: function preLink(scope, iElement, iAttrs, controller) { ... },
 *           post: function postLink(scope, iElement, iAttrs, controller) { ... }
 *         }
 *         // or
 *         // return function postLink( ... ) { ... }
 *       },
 *       // or
 *       // link: {
 *       //  pre: function preLink(scope, iElement, iAttrs, controller) { ... },
 *       //  post: function postLink(scope, iElement, iAttrs, controller) { ... }
 *       // }
 *       // or
 *       // link: function postLink( ... ) { ... }
 *     };
 *     return directiveDefinitionObject;
 *   });
 * ```
 *
 * <div class="alert alert-warning">
 * **Note:** Any unspecified options will use the default value. You can see the default values below.
 * </div>
 *
 * Therefore the above can be simplified as:
 *
 * ```js
 *   var myModule = angular.module(...);
 *
 *   myModule.directive('directiveName', function factory(injectables) {
 *     var directiveDefinitionObject = {
 *       link: function postLink(scope, iElement, iAttrs) { ... }
 *     };
 *     return directiveDefinitionObject;
 *     // or
 *     // return function postLink(scope, iElement, iAttrs) { ... }
 *   });
 * ```
 *
 *
 *
 * ### Directive Definition Object
 *
 * The directive definition object provides instructions to the {@link ng.$compile
 * compiler}. The attributes are:
 *
 * #### `multiElement`
 * When this property is set to true, the HTML compiler will collect DOM nodes between
 * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
 * together as the directive elements. It is recommended that this feature be used on directives
 * which are not strictly behavioural (such as {@link ngClick}), and which
 * do not manipulate or replace child nodes (such as {@link ngInclude}).
 *
 * #### `priority`
 * When there are multiple directives defined on a single DOM element, sometimes it
 * is necessary to specify the order in which the directives are applied. The `priority` is used
 * to sort the directives before their `compile` functions get called. Priority is defined as a
 * number. Directives with greater numerical `priority` are compiled first. Pre-link functions
 * are also run in priority order, but post-link functions are run in reverse order. The order
 * of directives with the same priority is undefined. The default priority is `0`.
 *
 * #### `terminal`
 * If set to true then the current `priority` will be the last set of directives
 * which will execute (any directives at the current priority will still execute
 * as the order of execution on same `priority` is undefined). Note that expressions
 * and other directives used in the directive's template will also be excluded from execution.
 *
 * #### `scope`
 * **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the
 * same element request a new scope, only one new scope is created. The new scope rule does not
 * apply for the root of the template since the root of the template always gets a new scope.
 *
 * **If set to `{}` (object hash),** then a new "isolate" scope is created. The 'isolate' scope differs from
 * normal scope in that it does not prototypically inherit from the parent scope. This is useful
 * when creating reusable components, which should not accidentally read or modify data in the
 * parent scope.
 *
 * The 'isolate' scope takes an object hash which defines a set of local scope properties
 * derived from the parent scope. These local properties are useful for aliasing values for
 * templates. Locals definition is a hash of local scope property to its source:
 *
 * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
 *   always a string since DOM attributes are strings. If no `attr` name is specified  then the
 *   attribute name is assumed to be the same as the local name.
 *   Given `<widget my-attr="hello {{name}}">` and widget definition
 *   of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect
 *   the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the
 *   `localName` property on the widget scope. The `name` is read from the parent scope (not
 *   component scope).
 *
 * * `=` or `=attr` - set up bi-directional binding between a local scope property and the
 *   parent scope property of name defined via the value of the `attr` attribute. If no `attr`
 *   name is specified then the attribute name is assumed to be the same as the local name.
 *   Given `<widget my-attr="parentModel">` and widget definition of
 *   `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the
 *   value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
 *   in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent
 *   scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You
 *   can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. If
 *   you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use
 *   `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional).
 *
 * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
 *   If no `attr` name is specified then the attribute name is assumed to be the same as the
 *   local name. Given `<widget my-attr="count = count + value">` and widget definition of
 *   `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to
 *   a function wrapper for the `count = count + value` expression. Often it's desirable to
 *   pass data from the isolated scope via an expression to the parent scope, this can be
 *   done by passing a map of local variable names and values into the expression wrapper fn.
 *   For example, if the expression is `increment(amount)` then we can specify the amount value
 *   by calling the `localFn` as `localFn({amount: 22})`.
 *
 *
 * #### `bindToController`
 * When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController: true` will
 * allow a component to have its properties bound to the controller, rather than to scope. When the controller
 * is instantiated, the initial values of the isolate scope bindings are already available.
 *
 * #### `controller`
 * Controller constructor function. The controller is instantiated before the
 * pre-linking phase and it is shared with other directives (see
 * `require` attribute). This allows the directives to communicate with each other and augment
 * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
 *
 * * `$scope` - Current scope associated with the element
 * * `$element` - Current element
 * * `$attrs` - Current attributes object for the element
 * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
 *   `function([scope], cloneLinkingFn, futureParentElement)`.
 *    * `scope`: optional argument to override the scope.
 *    * `cloneLinkingFn`: optional argument to create clones of the original transcluded content.
 *    * `futureParentElement`:
 *        * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
 *        * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
 *        * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
 *          and when the `cloneLinkinFn` is passed,
 *          as those elements need to created and cloned in a special way when they are defined outside their
 *          usual containers (e.g. like `<svg>`).
 *        * See also the `directive.templateNamespace` property.
 *
 *
 * #### `require`
 * Require another directive and inject its controller as the fourth argument to the linking function. The
 * `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
 * injected argument will be an array in corresponding order. If no such directive can be
 * found, or if the directive does not have a controller, then an error is raised (unless no link function
 * is specified, in which case error checking is skipped). The name can be prefixed with:
 *
 * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
 * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
 * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.
 * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found.
 * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass
 *   `null` to the `link` fn if not found.
 * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass
 *   `null` to the `link` fn if not found.
 *
 *
 * #### `controllerAs`
 * Controller alias at the directive scope. An alias for the controller so it
 * can be referenced at the directive template. The directive needs to define a scope for this
 * configuration to be used. Useful in the case when directive is used as component.
 *
 *
 * #### `restrict`
 * String of subset of `EACM` which restricts the directive to a specific directive
 * declaration style. If omitted, the defaults (elements and attributes) are used.
 *
 * * `E` - Element name (default): `<my-directive></my-directive>`
 * * `A` - Attribute (default): `<div my-directive="exp"></div>`
 * * `C` - Class: `<div class="my-directive: exp;"></div>`
 * * `M` - Comment: `<!-- directive: my-directive exp -->`
 *
 *
 * #### `templateNamespace`
 * String representing the document type used by the markup in the template.
 * AngularJS needs this information as those elements need to be created and cloned
 * in a special way when they are defined outside their usual containers like `<svg>` and `<math>`.
 *
 * * `html` - All root nodes in the template are HTML. Root nodes may also be
 *   top-level elements such as `<svg>` or `<math>`.
 * * `svg` - The root nodes in the template are SVG elements (excluding `<math>`).
 * * `math` - The root nodes in the template are MathML elements (excluding `<svg>`).
 *
 * If no `templateNamespace` is specified, then the namespace is considered to be `html`.
 *
 * #### `template`
 * HTML markup that may:
 * * Replace the contents of the directive's element (default).
 * * Replace the directive's element itself (if `replace` is true - DEPRECATED).
 * * Wrap the contents of the directive's element (if `transclude` is true).
 *
 * Value may be:
 *
 * * A string. For example `<div red-on-hover>{{delete_str}}</div>`.
 * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`
 *   function api below) and returns a string value.
 *
 *
 * #### `templateUrl`
 * This is similar to `template` but the template is loaded from the specified URL, asynchronously.
 *
 * Because template loading is asynchronous the compiler will suspend compilation of directives on that element
 * for later when the template has been resolved.  In the meantime it will continue to compile and link
 * sibling and parent elements as though this element had not contained any directives.
 *
 * The compiler does not suspend the entire compilation to wait for templates to be loaded because this
 * would result in the whole app "stalling" until all templates are loaded asynchronously - even in the
 * case when only one deeply nested directive has `templateUrl`.
 *
 * Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache}
 *
 * You can specify `templateUrl` as a string representing the URL or as a function which takes two
 * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns
 * a string value representing the url.  In either case, the template URL is passed through {@link
 * $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.
 *
 *
 * #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0)
 * specify what the template should replace. Defaults to `false`.
 *
 * * `true` - the template will replace the directive's element.
 * * `false` - the template will replace the contents of the directive's element.
 *
 * The replacement process migrates all of the attributes / classes from the old element to the new
 * one. See the {@link guide/directive#template-expanding-directive
 * Directives Guide} for an example.
 *
 * There are very few scenarios where element replacement is required for the application function,
 * the main one being reusable custom components that are used within SVG contexts
 * (because SVG doesn't work with custom elements in the DOM tree).
 *
 * #### `transclude`
 * Extract the contents of the element where the directive appears and make it available to the directive.
 * The contents are compiled and provided to the directive as a **transclusion function**. See the
 * {@link $compile#transclusion Transclusion} section below.
 *
 * There are two kinds of transclusion depending upon whether you want to transclude just the contents of the
 * directive's element or the entire element:
 *
 * * `true` - transclude the content (i.e. the child nodes) of the directive's element.
 * * `'element'` - transclude the whole of the directive's element including any directives on this
 *   element that defined at a lower priority than this directive. When used, the `template`
 *   property is ignored.
 *
 *
 * #### `compile`
 *
 * ```js
 *   function compile(tElement, tAttrs, transclude) { ... }
 * ```
 *
 * The compile function deals with transforming the template DOM. Since most directives do not do
 * template transformation, it is not used often. The compile function takes the following arguments:
 *
 *   * `tElement` - template element - The element where the directive has been declared. It is
 *     safe to do template transformation on the element and child elements only.
 *
 *   * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
 *     between all directive compile functions.
 *
 *   * `transclude` -  [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
 *
 * <div class="alert alert-warning">
 * **Note:** The template instance and the link instance may be different objects if the template has
 * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that
 * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration
 * should be done in a linking function rather than in a compile function.
 * </div>

 * <div class="alert alert-warning">
 * **Note:** The compile function cannot handle directives that recursively use themselves in their
 * own templates or compile functions. Compiling these directives results in an infinite loop and a
 * stack overflow errors.
 *
 * This can be avoided by manually using $compile in the postLink function to imperatively compile
 * a directive's template instead of relying on automatic template compilation via `template` or
 * `templateUrl` declaration or manual compilation inside the compile function.
 * </div>
 *
 * <div class="alert alert-error">
 * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it
 *   e.g. does not know about the right outer scope. Please use the transclude function that is passed
 *   to the link function instead.
 * </div>

 * A compile function can have a return value which can be either a function or an object.
 *
 * * returning a (post-link) function - is equivalent to registering the linking function via the
 *   `link` property of the config object when the compile function is empty.
 *
 * * returning an object with function(s) registered via `pre` and `post` properties - allows you to
 *   control when a linking function should be called during the linking phase. See info about
 *   pre-linking and post-linking functions below.
 *
 *
 * #### `link`
 * This property is used only if the `compile` property is not defined.
 *
 * ```js
 *   function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
 * ```
 *
 * The link function is responsible for registering DOM listeners as well as updating the DOM. It is
 * executed after the template has been cloned. This is where most of the directive logic will be
 * put.
 *
 *   * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the
 *     directive for registering {@link ng.$rootScope.Scope#$watch watches}.
 *
 *   * `iElement` - instance element - The element where the directive is to be used. It is safe to
 *     manipulate the children of the element only in `postLink` function since the children have
 *     already been linked.
 *
 *   * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared
 *     between all directive linking functions.
 *
 *   * `controller` - the directive's required controller instance(s) - Instances are shared
 *     among all directives, which allows the directives to use the controllers as a communication
 *     channel. The exact value depends on the directive's `require` property:
 *       * `string`: the controller instance
 *       * `array`: array of controller instances
 *       * no controller(s) required: `undefined`
 *
 *     If a required controller cannot be found, and it is optional, the instance is `null`,
 *     otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.
 *
 *   * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
 *     This is the same as the `$transclude`
 *     parameter of directive controllers, see there for details.
 *     `function([scope], cloneLinkingFn, futureParentElement)`.
 *
 * #### Pre-linking function
 *
 * Executed before the child elements are linked. Not safe to do DOM transformation since the
 * compiler linking function will fail to locate the correct elements for linking.
 *
 * #### Post-linking function
 *
 * Executed after the child elements are linked.
 *
 * Note that child elements that contain `templateUrl` directives will not have been compiled
 * and linked since they are waiting for their template to load asynchronously and their own
 * compilation and linking has been suspended until that occurs.
 *
 * It is safe to do DOM transformation in the post-linking function on elements that are not waiting
 * for their async templates to be resolved.
 *
 *
 * ### Transclusion
 *
 * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and
 * copying them to another part of the DOM, while maintaining their connection to the original AngularJS
 * scope from where they were taken.
 *
 * Transclusion is used (often with {@link ngTransclude}) to insert the
 * original contents of a directive's element into a specified place in the template of the directive.
 * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded
 * content has access to the properties on the scope from which it was taken, even if the directive
 * has isolated scope.
 * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.
 *
 * This makes it possible for the widget to have private state for its template, while the transcluded
 * content has access to its originating scope.
 *
 * <div class="alert alert-warning">
 * **Note:** When testing an element transclude directive you must not place the directive at the root of the
 * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives
 * Testing Transclusion Directives}.
 * </div>
 *
 * #### Transclusion Functions
 *
 * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion
 * function** to the directive's `link` function and `controller`. This transclusion function is a special
 * **linking function** that will return the compiled contents linked to a new transclusion scope.
 *
 * <div class="alert alert-info">
 * If you are just using {@link ngTransclude} then you don't need to worry about this function, since
 * ngTransclude will deal with it for us.
 * </div>
 *
 * If you want to manually control the insertion and removal of the transcluded content in your directive
 * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery
 * object that contains the compiled DOM, which is linked to the correct transclusion scope.
 *
 * When you call a transclusion function you can pass in a **clone attach function**. This function accepts
 * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded
 * content and the `scope` is the newly created transclusion scope, to which the clone is bound.
 *
 * <div class="alert alert-info">
 * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a translude function
 * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.
 * </div>
 *
 * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone
 * attach function**:
 *
 * ```js
 * var transcludedContent, transclusionScope;
 *
 * $transclude(function(clone, scope) {
 *   element.append(clone);
 *   transcludedContent = clone;
 *   transclusionScope = scope;
 * });
 * ```
 *
 * Later, if you want to remove the transcluded content from your DOM then you should also destroy the
 * associated transclusion scope:
 *
 * ```js
 * transcludedContent.remove();
 * transclusionScope.$destroy();
 * ```
 *
 * <div class="alert alert-info">
 * **Best Practice**: if you intend to add and remove transcluded content manually in your directive
 * (by calling the transclude function to get the DOM and and calling `element.remove()` to remove it),
 * then you are also responsible for calling `$destroy` on the transclusion scope.
 * </div>
 *
 * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}
 * automatically destroy their transluded clones as necessary so you do not need to worry about this if
 * you are simply using {@link ngTransclude} to inject the transclusion into your directive.
 *
 *
 * #### Transclusion Scopes
 *
 * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion
 * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed
 * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it
 * was taken.
 *
 * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look
 * like this:
 *
 * ```html
 * <div ng-app>
 *   <div isolate>
 *     <div transclusion>
 *     </div>
 *   </div>
 * </div>
 * ```
 *
 * The `$parent` scope hierarchy will look like this:
 *
 * ```
 * - $rootScope
 *   - isolate
 *     - transclusion
 * ```
 *
 * but the scopes will inherit prototypically from different scopes to their `$parent`.
 *
 * ```
 * - $rootScope
 *   - transclusion
 * - isolate
 * ```
 *
 *
 * ### Attributes
 *
 * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the
 * `link()` or `compile()` functions. It has a variety of uses.
 *
 * accessing *Normalized attribute names:*
 * Directives like 'ngBind' can be expressed in many ways: 'ng:bind', `data-ng-bind`, or 'x-ng-bind'.
 * the attributes object allows for normalized access to
 *   the attributes.
 *
 * * *Directive inter-communication:* All directives share the same instance of the attributes
 *   object which allows the directives to use the attributes object as inter directive
 *   communication.
 *
 * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object
 *   allowing other directives to read the interpolated value.
 *
 * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes
 *   that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also
 *   the only way to easily get the actual value because during the linking phase the interpolation
 *   hasn't been evaluated yet and so the value is at this time set to `undefined`.
 *
 * ```js
 * function linkingFn(scope, elm, attrs, ctrl) {
 *   // get the attribute value
 *   console.log(attrs.ngModel);
 *
 *   // change the attribute
 *   attrs.$set('ngModel', 'new value');
 *
 *   // observe changes to interpolated attribute
 *   attrs.$observe('ngModel', function(value) {
 *     console.log('ngModel has changed value to ' + value);
 *   });
 * }
 * ```
 *
 * ## Example
 *
 * <div class="alert alert-warning">
 * **Note**: Typically directives are registered with `module.directive`. The example below is
 * to illustrate how `$compile` works.
 * </div>
 *
 <example module="compileExample">
   <file name="index.html">
    <script>
      angular.module('compileExample', [], function($compileProvider) {
        // configure new 'compile' directive by passing a directive
        // factory function. The factory function injects the '$compile'
        $compileProvider.directive('compile', function($compile) {
          // directive factory creates a link function
          return function(scope, element, attrs) {
            scope.$watch(
              function(scope) {
                 // watch the 'compile' expression for changes
                return scope.$eval(attrs.compile);
              },
              function(value) {
                // when the 'compile' expression changes
                // assign it into the current DOM
                element.html(value);

                // compile the new DOM and link it to the current
                // scope.
                // NOTE: we only compile .childNodes so that
                // we don't get into infinite loop compiling ourselves
                $compile(element.contents())(scope);
              }
            );
          };
        });
      })
      .controller('GreeterController', ['$scope', function($scope) {
        $scope.name = 'Angular';
        $scope.html = 'Hello {{name}}';
      }]);
    </script>
    <div ng-controller="GreeterController">
      <input ng-model="name"> <br>
      <textarea ng-model="html"></textarea> <br>
      <div compile="html"></div>
    </div>
   </file>
   <file name="protractor.js" type="protractor">
     it('should auto compile', function() {
       var textarea = $('textarea');
       var output = $('div[compile]');
       // The initial state reads 'Hello Angular'.
       expect(output.getText()).toBe('Hello Angular');
       textarea.clear();
       textarea.sendKeys('{{name}}!');
       expect(output.getText()).toBe('Angular!');
     });
   </file>
 </example>

 *
 *
 * @param {string|DOMElement} element Element or HTML string to compile into a template function.
 * @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED.
 *
 * <div class="alert alert-error">
 * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it
 *   e.g. will not use the right outer scope. Please pass the transclude function as a
 *   `parentBoundTranscludeFn` to the link function instead.
 * </div>
 *
 * @param {number} maxPriority only apply directives lower than given priority (Only effects the
 *                 root element(s), not their children)
 * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template
 * (a DOM element/tree) to a scope. Where:
 *
 *  * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.
 *  * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
 *  `template` and call the `cloneAttachFn` function allowing the caller to attach the
 *  cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is
 *  called as: <br> `cloneAttachFn(clonedElement, scope)` where:
 *
 *      * `clonedElement` - is a clone of the original `element` passed into the compiler.
 *      * `scope` - is the current scope with which the linking function is working with.
 *
 *  * `options` - An optional object hash with linking options. If `options` is provided, then the following
 *  keys may be used to control linking behavior:
 *
 *      * `parentBoundTranscludeFn` - the transclude function made available to
 *        directives; if given, it will be passed through to the link functions of
 *        directives found in `element` during compilation.
 *      * `transcludeControllers` - an object hash with keys that map controller names
 *        to controller instances; if given, it will make the controllers
 *        available to directives.
 *      * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add
 *        the cloned elements; only needed for transcludes that are allowed to contain non html
 *        elements (e.g. SVG elements). See also the directive.controller property.
 *
 * Calling the linking function returns the element of the template. It is either the original
 * element passed in, or the clone of the element if the `cloneAttachFn` is provided.
 *
 * After linking the view is not updated until after a call to $digest which typically is done by
 * Angular automatically.
 *
 * If you need access to the bound view, there are two ways to do it:
 *
 * - If you are not asking the linking function to clone the template, create the DOM element(s)
 *   before you send them to the compiler and keep this reference around.
 *   ```js
 *     var element = $compile('<p>{{total}}</p>')(scope);
 *   ```
 *
 * - if on the other hand, you need the element to be cloned, the view reference from the original
 *   example would not point to the clone, but rather to the original template that was cloned. In
 *   this case, you can access the clone via the cloneAttachFn:
 *   ```js
 *     var templateElement = angular.element('<p>{{total}}</p>'),
 *         scope = ....;
 *
 *     var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
 *       //attach the clone to DOM document at the right place
 *     });
 *
 *     //now we have reference to the cloned DOM via `clonedElement`
 *   ```
 *
 *
 * For information on how the compiler works, see the
 * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.
 */

var $compileMinErr = minErr('$compile');

/**
 * @ngdoc provider
 * @name $compileProvider
 *
 * @description
 */
$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
function $CompileProvider($provide, $$sanitizeUriProvider) {
  var hasDirectives = {},
      Suffix = 'Directive',
      COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\w\-]+)\s+(.*)$/,
      CLASS_DIRECTIVE_REGEXP = /(([\w\-]+)(?:\:([^;]+))?;?)/,
      ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
      REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;

  // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
  // The assumption is that future DOM event attribute names will begin with
  // 'on' and be composed of only English letters.
  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;

  function parseIsolateBindings(scope, directiveName) {
    var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/;

    var bindings = {};

    forEach(scope, function(definition, scopeName) {
      var match = definition.match(LOCAL_REGEXP);

      if (!match) {
        throw $compileMinErr('iscp',
            "Invalid isolate scope definition for directive '{0}'." +
            " Definition: {... {1}: '{2}' ...}",
            directiveName, scopeName, definition);
      }

      bindings[scopeName] = {
        mode: match[1][0],
        collection: match[2] === '*',
        optional: match[3] === '?',
        attrName: match[4] || scopeName
      };
    });

    return bindings;
  }

  /**
   * @ngdoc method
   * @name $compileProvider#directive
   * @kind function
   *
   * @description
   * Register a new directive with the compiler.
   *
   * @param {string|Object} name Name of the directive in camel-case (i.e. <code>ngBind</code> which
   *    will match as <code>ng-bind</code>), or an object map of directives where the keys are the
   *    names and the values are the factories.
   * @param {Function|Array} directiveFactory An injectable directive factory function. See
   *    {@link guide/directive} for more info.
   * @returns {ng.$compileProvider} Self for chaining.
   */
   this.directive = function registerDirective(name, directiveFactory) {
    assertNotHasOwnProperty(name, 'directive');
    if (isString(name)) {
      assertArg(directiveFactory, 'directiveFactory');
      if (!hasDirectives.hasOwnProperty(name)) {
        hasDirectives[name] = [];
        $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
          function($injector, $exceptionHandler) {
            var directives = [];
            forEach(hasDirectives[name], function(directiveFactory, index) {
              try {
                var directive = $injector.invoke(directiveFactory);
                if (isFunction(directive)) {
                  directive = { compile: valueFn(directive) };
                } else if (!directive.compile && directive.link) {
                  directive.compile = valueFn(directive.link);
                }
                directive.priority = directive.priority || 0;
                directive.index = index;
                directive.name = directive.name || name;
                directive.require = directive.require || (directive.controller && directive.name);
                directive.restrict = directive.restrict || 'EA';
                if (isObject(directive.scope)) {
                  directive.$$isolateBindings = parseIsolateBindings(directive.scope, directive.name);
                }
                directives.push(directive);
              } catch (e) {
                $exceptionHandler(e);
              }
            });
            return directives;
          }]);
      }
      hasDirectives[name].push(directiveFactory);
    } else {
      forEach(name, reverseParams(registerDirective));
    }
    return this;
  };


  /**
   * @ngdoc method
   * @name $compileProvider#aHrefSanitizationWhitelist
   * @kind function
   *
   * @description
   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
   * urls during a[href] sanitization.
   *
   * The sanitization is a security measure aimed at preventing XSS attacks via html links.
   *
   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
   *
   * @param {RegExp=} regexp New regexp to whitelist urls with.
   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
   *    chaining otherwise.
   */
  this.aHrefSanitizationWhitelist = function(regexp) {
    if (isDefined(regexp)) {
      $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
      return this;
    } else {
      return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
    }
  };


  /**
   * @ngdoc method
   * @name $compileProvider#imgSrcSanitizationWhitelist
   * @kind function
   *
   * @description
   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
   * urls during img[src] sanitization.
   *
   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
   *
   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
   *
   * @param {RegExp=} regexp New regexp to whitelist urls with.
   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
   *    chaining otherwise.
   */
  this.imgSrcSanitizationWhitelist = function(regexp) {
    if (isDefined(regexp)) {
      $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
      return this;
    } else {
      return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
    }
  };

  /**
   * @ngdoc method
   * @name  $compileProvider#debugInfoEnabled
   *
   * @param {boolean=} enabled update the debugInfoEnabled state if provided, otherwise just return the
   * current debugInfoEnabled state
   * @returns {*} current value if used as getter or itself (chaining) if used as setter
   *
   * @kind function
   *
   * @description
   * Call this method to enable/disable various debug runtime information in the compiler such as adding
   * binding information and a reference to the current scope on to DOM elements.
   * If enabled, the compiler will add the following to DOM elements that have been bound to the scope
   * * `ng-binding` CSS class
   * * `$binding` data property containing an array of the binding expressions
   *
   * You may want to disable this in production for a significant performance boost. See
   * {@link guide/production#disabling-debug-data Disabling Debug Data} for more.
   *
   * The default value is true.
   */
  var debugInfoEnabled = true;
  this.debugInfoEnabled = function(enabled) {
    if (isDefined(enabled)) {
      debugInfoEnabled = enabled;
      return this;
    }
    return debugInfoEnabled;
  };

  this.$get = [
            '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
            '$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri',
    function($injector,   $interpolate,   $exceptionHandler,   $templateRequest,   $parse,
             $controller,   $rootScope,   $document,   $sce,   $animate,   $$sanitizeUri) {

    var Attributes = function(element, attributesToCopy) {
      if (attributesToCopy) {
        var keys = Object.keys(attributesToCopy);
        var i, l, key;

        for (i = 0, l = keys.length; i < l; i++) {
          key = keys[i];
          this[key] = attributesToCopy[key];
        }
      } else {
        this.$attr = {};
      }

      this.$$element = element;
    };

    Attributes.prototype = {
      /**
       * @ngdoc method
       * @name $compile.directive.Attributes#$normalize
       * @kind function
       *
       * @description
       * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or
       * `data-`) to its normalized, camelCase form.
       *
       * Also there is special case for Moz prefix starting with upper case letter.
       *
       * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
       *
       * @param {string} name Name to normalize
       */
      $normalize: directiveNormalize,


      /**
       * @ngdoc method
       * @name $compile.directive.Attributes#$addClass
       * @kind function
       *
       * @description
       * Adds the CSS class value specified by the classVal parameter to the element. If animations
       * are enabled then an animation will be triggered for the class addition.
       *
       * @param {string} classVal The className value that will be added to the element
       */
      $addClass: function(classVal) {
        if (classVal && classVal.length > 0) {
          $animate.addClass(this.$$element, classVal);
        }
      },

      /**
       * @ngdoc method
       * @name $compile.directive.Attributes#$removeClass
       * @kind function
       *
       * @description
       * Removes the CSS class value specified by the classVal parameter from the element. If
       * animations are enabled then an animation will be triggered for the class removal.
       *
       * @param {string} classVal The className value that will be removed from the element
       */
      $removeClass: function(classVal) {
        if (classVal && classVal.length > 0) {
          $animate.removeClass(this.$$element, classVal);
        }
      },

      /**
       * @ngdoc method
       * @name $compile.directive.Attributes#$updateClass
       * @kind function
       *
       * @description
       * Adds and removes the appropriate CSS class values to the element based on the difference
       * between the new and old CSS class values (specified as newClasses and oldClasses).
       *
       * @param {string} newClasses The current CSS className value
       * @param {string} oldClasses The former CSS className value
       */
      $updateClass: function(newClasses, oldClasses) {
        var toAdd = tokenDifference(newClasses, oldClasses);
        if (toAdd && toAdd.length) {
          $animate.addClass(this.$$element, toAdd);
        }

        var toRemove = tokenDifference(oldClasses, newClasses);
        if (toRemove && toRemove.length) {
          $animate.removeClass(this.$$element, toRemove);
        }
      },

      /**
       * Set a normalized attribute on the element in a way such that all directives
       * can share the attribute. This function properly handles boolean attributes.
       * @param {string} key Normalized key. (ie ngAttribute)
       * @param {string|boolean} value The value to set. If `null` attribute will be deleted.
       * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.
       *     Defaults to true.
       * @param {string=} attrName Optional none normalized name. Defaults to key.
       */
      $set: function(key, value, writeAttr, attrName) {
        // TODO: decide whether or not to throw an error if "class"
        //is set through this function since it may cause $updateClass to
        //become unstable.

        var node = this.$$element[0],
            booleanKey = getBooleanAttrName(node, key),
            aliasedKey = getAliasedAttrName(node, key),
            observer = key,
            nodeName;

        if (booleanKey) {
          this.$$element.prop(key, value);
          attrName = booleanKey;
        } else if (aliasedKey) {
          this[aliasedKey] = value;
          observer = aliasedKey;
        }

        this[key] = value;

        // translate normalized key to actual key
        if (attrName) {
          this.$attr[key] = attrName;
        } else {
          attrName = this.$attr[key];
          if (!attrName) {
            this.$attr[key] = attrName = snake_case(key, '-');
          }
        }

        nodeName = nodeName_(this.$$element);

        if ((nodeName === 'a' && key === 'href') ||
            (nodeName === 'img' && key === 'src')) {
          // sanitize a[href] and img[src] values
          this[key] = value = $$sanitizeUri(value, key === 'src');
        } else if (nodeName === 'img' && key === 'srcset') {
          // sanitize img[srcset] values
          var result = "";

          // first check if there are spaces because it's not the same pattern
          var trimmedSrcset = trim(value);
          //                (   999x   ,|   999w   ,|   ,|,   )
          var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
          var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;

          // split srcset into tuple of uri and descriptor except for the last item
          var rawUris = trimmedSrcset.split(pattern);

          // for each tuples
          var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
          for (var i = 0; i < nbrUrisWith2parts; i++) {
            var innerIdx = i * 2;
            // sanitize the uri
            result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
            // add the descriptor
            result += (" " + trim(rawUris[innerIdx + 1]));
          }

          // split the last item into uri and descriptor
          var lastTuple = trim(rawUris[i * 2]).split(/\s/);

          // sanitize the last uri
          result += $$sanitizeUri(trim(lastTuple[0]), true);

          // and add the last descriptor if any
          if (lastTuple.length === 2) {
            result += (" " + trim(lastTuple[1]));
          }
          this[key] = value = result;
        }

        if (writeAttr !== false) {
          if (value === null || value === undefined) {
            this.$$element.removeAttr(attrName);
          } else {
            this.$$element.attr(attrName, value);
          }
        }

        // fire observers
        var $$observers = this.$$observers;
        $$observers && forEach($$observers[observer], function(fn) {
          try {
            fn(value);
          } catch (e) {
            $exceptionHandler(e);
          }
        });
      },


      /**
       * @ngdoc method
       * @name $compile.directive.Attributes#$observe
       * @kind function
       *
       * @description
       * Observes an interpolated attribute.
       *
       * The observer function will be invoked once during the next `$digest` following
       * compilation. The observer is then invoked whenever the interpolated value
       * changes.
       *
       * @param {string} key Normalized key. (ie ngAttribute) .
       * @param {function(interpolatedValue)} fn Function that will be called whenever
                the interpolated value of the attribute changes.
       *        See the {@link guide/directive#text-and-attribute-bindings Directives} guide for more info.
       * @returns {function()} Returns a deregistration function for this observer.
       */
      $observe: function(key, fn) {
        var attrs = this,
            $$observers = (attrs.$$observers || (attrs.$$observers = createMap())),
            listeners = ($$observers[key] || ($$observers[key] = []));

        listeners.push(fn);
        $rootScope.$evalAsync(function() {
          if (!listeners.$$inter && attrs.hasOwnProperty(key)) {
            // no one registered attribute interpolation function, so lets call it manually
            fn(attrs[key]);
          }
        });

        return function() {
          arrayRemove(listeners, fn);
        };
      }
    };


    function safeAddClass($element, className) {
      try {
        $element.addClass(className);
      } catch (e) {
        // ignore, since it means that we are trying to set class on
        // SVG element, where class name is read-only.
      }
    }


    var startSymbol = $interpolate.startSymbol(),
        endSymbol = $interpolate.endSymbol(),
        denormalizeTemplate = (startSymbol == '{{' || endSymbol  == '}}')
            ? identity
            : function denormalizeTemplate(template) {
              return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
        },
        NG_ATTR_BINDING = /^ngAttr[A-Z]/;

    compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) {
      var bindings = $element.data('$binding') || [];

      if (isArray(binding)) {
        bindings = bindings.concat(binding);
      } else {
        bindings.push(binding);
      }

      $element.data('$binding', bindings);
    } : noop;

    compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) {
      safeAddClass($element, 'ng-binding');
    } : noop;

    compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) {
      var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope';
      $element.data(dataName, scope);
    } : noop;

    compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) {
      safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');
    } : noop;

    return compile;

    //================================

    function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,
                        previousCompileContext) {
      if (!($compileNodes instanceof jqLite)) {
        // jquery always rewraps, whereas we need to preserve the original selector so that we can
        // modify it.
        $compileNodes = jqLite($compileNodes);
      }
      // We can not compile top level text elements since text nodes can be merged and we will
      // not be able to attach scope data to them, so we will wrap them in <span>
      forEach($compileNodes, function(node, index) {
        if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */ ) {
          $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
        }
      });
      var compositeLinkFn =
              compileNodes($compileNodes, transcludeFn, $compileNodes,
                           maxPriority, ignoreDirective, previousCompileContext);
      compile.$$addScopeClass($compileNodes);
      var namespace = null;
      return function publicLinkFn(scope, cloneConnectFn, options) {
        assertArg(scope, 'scope');

        options = options || {};
        var parentBoundTranscludeFn = options.parentBoundTranscludeFn,
          transcludeControllers = options.transcludeControllers,
          futureParentElement = options.futureParentElement;

        // When `parentBoundTranscludeFn` is passed, it is a
        // `controllersBoundTransclude` function (it was previously passed
        // as `transclude` to directive.link) so we must unwrap it to get
        // its `boundTranscludeFn`
        if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {
          parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;
        }

        if (!namespace) {
          namespace = detectNamespaceForChildElements(futureParentElement);
        }
        var $linkNode;
        if (namespace !== 'html') {
          // When using a directive with replace:true and templateUrl the $compileNodes
          // (or a child element inside of them)
          // might change, so we need to recreate the namespace adapted compileNodes
          // for call to the link function.
          // Note: This will already clone the nodes...
          $linkNode = jqLite(
            wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
          );
        } else if (cloneConnectFn) {
          // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
          // and sometimes changes the structure of the DOM.
          $linkNode = JQLitePrototype.clone.call($compileNodes);
        } else {
          $linkNode = $compileNodes;
        }

        if (transcludeControllers) {
          for (var controllerName in transcludeControllers) {
            $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);
          }
        }

        compile.$$addScopeInfo($linkNode, scope);

        if (cloneConnectFn) cloneConnectFn($linkNode, scope);
        if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
        return $linkNode;
      };
    }

    function detectNamespaceForChildElements(parentElement) {
      // TODO: Make this detect MathML as well...
      var node = parentElement && parentElement[0];
      if (!node) {
        return 'html';
      } else {
        return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg' : 'html';
      }
    }

    /**
     * Compile function matches each node in nodeList against the directives. Once all directives
     * for a particular node are collected their compile functions are executed. The compile
     * functions return values - the linking functions - are combined into a composite linking
     * function, which is the a linking function for the node.
     *
     * @param {NodeList} nodeList an array of nodes or NodeList to compile
     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the
     *        scope argument is auto-generated to the new child of the transcluded parent scope.
     * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then
     *        the rootElement must be set the jqLite collection of the compile root. This is
     *        needed so that the jqLite collection items can be replaced with widgets.
     * @param {number=} maxPriority Max directive priority.
     * @returns {Function} A composite linking function of all of the matched directives or null.
     */
    function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
                            previousCompileContext) {
      var linkFns = [],
          attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;

      for (var i = 0; i < nodeList.length; i++) {
        attrs = new Attributes();

        // we must always refer to nodeList[i] since the nodes can be replaced underneath us.
        directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,
                                        ignoreDirective);

        nodeLinkFn = (directives.length)
            ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,
                                      null, [], [], previousCompileContext)
            : null;

        if (nodeLinkFn && nodeLinkFn.scope) {
          compile.$$addScopeClass(attrs.$$element);
        }

        childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
                      !(childNodes = nodeList[i].childNodes) ||
                      !childNodes.length)
            ? null
            : compileNodes(childNodes,
                 nodeLinkFn ? (
                  (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)
                     && nodeLinkFn.transclude) : transcludeFn);

        if (nodeLinkFn || childLinkFn) {
          linkFns.push(i, nodeLinkFn, childLinkFn);
          linkFnFound = true;
          nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;
        }

        //use the previous context only for the first element in the virtual group
        previousCompileContext = null;
      }

      // return a linking function if we have found anything, null otherwise
      return linkFnFound ? compositeLinkFn : null;

      function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
        var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;
        var stableNodeList;


        if (nodeLinkFnFound) {
          // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our
          // offsets don't get screwed up
          var nodeListLength = nodeList.length;
          stableNodeList = new Array(nodeListLength);

          // create a sparse array by only copying the elements which have a linkFn
          for (i = 0; i < linkFns.length; i+=3) {
            idx = linkFns[i];
            stableNodeList[idx] = nodeList[idx];
          }
        } else {
          stableNodeList = nodeList;
        }

        for (i = 0, ii = linkFns.length; i < ii;) {
          node = stableNodeList[linkFns[i++]];
          nodeLinkFn = linkFns[i++];
          childLinkFn = linkFns[i++];

          if (nodeLinkFn) {
            if (nodeLinkFn.scope) {
              childScope = scope.$new();
              compile.$$addScopeInfo(jqLite(node), childScope);
            } else {
              childScope = scope;
            }

            if (nodeLinkFn.transcludeOnThisElement) {
              childBoundTranscludeFn = createBoundTranscludeFn(
                  scope, nodeLinkFn.transclude, parentBoundTranscludeFn,
                  nodeLinkFn.elementTranscludeOnThisElement);

            } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
              childBoundTranscludeFn = parentBoundTranscludeFn;

            } else if (!parentBoundTranscludeFn && transcludeFn) {
              childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);

            } else {
              childBoundTranscludeFn = null;
            }

            nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);

          } else if (childLinkFn) {
            childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);
          }
        }
      }
    }

    function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn, elementTransclusion) {

      var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {

        if (!transcludedScope) {
          transcludedScope = scope.$new(false, containingScope);
          transcludedScope.$$transcluded = true;
        }

        return transcludeFn(transcludedScope, cloneFn, {
          parentBoundTranscludeFn: previousBoundTranscludeFn,
          transcludeControllers: controllers,
          futureParentElement: futureParentElement
        });
      };

      return boundTranscludeFn;
    }

    /**
     * Looks for directives on the given node and adds them to the directive collection which is
     * sorted.
     *
     * @param node Node to search.
     * @param directives An array to which the directives are added to. This array is sorted before
     *        the function returns.
     * @param attrs The shared attrs object which is used to populate the normalized attributes.
     * @param {number=} maxPriority Max directive priority.
     */
    function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
      var nodeType = node.nodeType,
          attrsMap = attrs.$attr,
          match,
          className;

      switch (nodeType) {
        case NODE_TYPE_ELEMENT: /* Element */
          // use the node name: <directive>
          addDirective(directives,
              directiveNormalize(nodeName_(node)), 'E', maxPriority, ignoreDirective);

          // iterate over the attributes
          for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
                   j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
            var attrStartName = false;
            var attrEndName = false;

            attr = nAttrs[j];
            name = attr.name;
            value = trim(attr.value);

            // support ngAttr attribute binding
            ngAttrName = directiveNormalize(name);
            if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) {
              name = name.replace(PREFIX_REGEXP, '')
                .substr(8).replace(/_(.)/g, function(match, letter) {
                  return letter.toUpperCase();
                });
            }

            var directiveNName = ngAttrName.replace(/(Start|End)$/, '');
            if (directiveIsMultiElement(directiveNName)) {
              if (ngAttrName === directiveNName + 'Start') {
                attrStartName = name;
                attrEndName = name.substr(0, name.length - 5) + 'end';
                name = name.substr(0, name.length - 6);
              }
            }

            nName = directiveNormalize(name.toLowerCase());
            attrsMap[nName] = name;
            if (isNgAttr || !attrs.hasOwnProperty(nName)) {
                attrs[nName] = value;
                if (getBooleanAttrName(node, nName)) {
                  attrs[nName] = true; // presence means true
                }
            }
            addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);
            addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,
                          attrEndName);
          }

          // use class as directive
          className = node.className;
          if (isObject(className)) {
              // Maybe SVGAnimatedString
              className = className.animVal;
          }
          if (isString(className) && className !== '') {
            while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) {
              nName = directiveNormalize(match[2]);
              if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {
                attrs[nName] = trim(match[3]);
              }
              className = className.substr(match.index + match[0].length);
            }
          }
          break;
        case NODE_TYPE_TEXT: /* Text Node */
          addTextInterpolateDirective(directives, node.nodeValue);
          break;
        case NODE_TYPE_COMMENT: /* Comment */
          try {
            match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);
            if (match) {
              nName = directiveNormalize(match[1]);
              if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {
                attrs[nName] = trim(match[2]);
              }
            }
          } catch (e) {
            // turns out that under some circumstances IE9 throws errors when one attempts to read
            // comment's node value.
            // Just ignore it and continue. (Can't seem to reproduce in test case.)
          }
          break;
      }

      directives.sort(byPriority);
      return directives;
    }

    /**
     * Given a node with an directive-start it collects all of the siblings until it finds
     * directive-end.
     * @param node
     * @param attrStart
     * @param attrEnd
     * @returns {*}
     */
    function groupScan(node, attrStart, attrEnd) {
      var nodes = [];
      var depth = 0;
      if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
        do {
          if (!node) {
            throw $compileMinErr('uterdir',
                      "Unterminated attribute, found '{0}' but no matching '{1}' found.",
                      attrStart, attrEnd);
          }
          if (node.nodeType == NODE_TYPE_ELEMENT) {
            if (node.hasAttribute(attrStart)) depth++;
            if (node.hasAttribute(attrEnd)) depth--;
          }
          nodes.push(node);
          node = node.nextSibling;
        } while (depth > 0);
      } else {
        nodes.push(node);
      }

      return jqLite(nodes);
    }

    /**
     * Wrapper for linking function which converts normal linking function into a grouped
     * linking function.
     * @param linkFn
     * @param attrStart
     * @param attrEnd
     * @returns {Function}
     */
    function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
      return function(scope, element, attrs, controllers, transcludeFn) {
        element = groupScan(element[0], attrStart, attrEnd);
        return linkFn(scope, element, attrs, controllers, transcludeFn);
      };
    }

    /**
     * Once the directives have been collected, their compile functions are executed. This method
     * is responsible for inlining directive templates as well as terminating the application
     * of the directives if the terminal directive has been reached.
     *
     * @param {Array} directives Array of collected directives to execute their compile function.
     *        this needs to be pre-sorted by priority order.
     * @param {Node} compileNode The raw DOM node to apply the compile functions to
     * @param {Object} templateAttrs The shared attribute function
     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the
     *                                                  scope argument is auto-generated to the new
     *                                                  child of the transcluded parent scope.
     * @param {JQLite} jqCollection If we are working on the root of the compile tree then this
     *                              argument has the root jqLite array so that we can replace nodes
     *                              on it.
     * @param {Object=} originalReplaceDirective An optional directive that will be ignored when
     *                                           compiling the transclusion.
     * @param {Array.<Function>} preLinkFns
     * @param {Array.<Function>} postLinkFns
     * @param {Object} previousCompileContext Context used for previous compilation of the current
     *                                        node
     * @returns {Function} linkFn
     */
    function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,
                                   jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,
                                   previousCompileContext) {
      previousCompileContext = previousCompileContext || {};

      var terminalPriority = -Number.MAX_VALUE,
          newScopeDirective,
          controllerDirectives = previousCompileContext.controllerDirectives,
          controllers,
          newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
          templateDirective = previousCompileContext.templateDirective,
          nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
          hasTranscludeDirective = false,
          hasTemplate = false,
          hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
          $compileNode = templateAttrs.$$element = jqLite(compileNode),
          directive,
          directiveName,
          $template,
          replaceDirective = originalReplaceDirective,
          childTranscludeFn = transcludeFn,
          linkFn,
          directiveValue;

      // executes all directives on the current element
      for (var i = 0, ii = directives.length; i < ii; i++) {
        directive = directives[i];
        var attrStart = directive.$$start;
        var attrEnd = directive.$$end;

        // collect multiblock sections
        if (attrStart) {
          $compileNode = groupScan(compileNode, attrStart, attrEnd);
        }
        $template = undefined;

        if (terminalPriority > directive.priority) {
          break; // prevent further processing of directives
        }

        if (directiveValue = directive.scope) {

          // skip the check for directives with async templates, we'll check the derived sync
          // directive when the template arrives
          if (!directive.templateUrl) {
            if (isObject(directiveValue)) {
              // This directive is trying to add an isolated scope.
              // Check that there is no scope of any kind already
              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,
                                directive, $compileNode);
              newIsolateScopeDirective = directive;
            } else {
              // This directive is trying to add a child scope.
              // Check that there is no isolated scope already
              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,
                                $compileNode);
            }
          }

          newScopeDirective = newScopeDirective || directive;
        }

        directiveName = directive.name;

        if (!directive.templateUrl && directive.controller) {
          directiveValue = directive.controller;
          controllerDirectives = controllerDirectives || {};
          assertNoDuplicate("'" + directiveName + "' controller",
              controllerDirectives[directiveName], directive, $compileNode);
          controllerDirectives[directiveName] = directive;
        }

        if (directiveValue = directive.transclude) {
          hasTranscludeDirective = true;

          // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
          // This option should only be used by directives that know how to safely handle element transclusion,
          // where the transcluded nodes are added or replaced after linking.
          if (!directive.$$tlb) {
            assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
            nonTlbTranscludeDirective = directive;
          }

          if (directiveValue == 'element') {
            hasElementTranscludeDirective = true;
            terminalPriority = directive.priority;
            $template = $compileNode;
            $compileNode = templateAttrs.$$element =
                jqLite(document.createComment(' ' + directiveName + ': ' +
                                              templateAttrs[directiveName] + ' '));
            compileNode = $compileNode[0];
            replaceWith(jqCollection, sliceArgs($template), compileNode);

            childTranscludeFn = compile($template, transcludeFn, terminalPriority,
                                        replaceDirective && replaceDirective.name, {
                                          // Don't pass in:
                                          // - controllerDirectives - otherwise we'll create duplicates controllers
                                          // - newIsolateScopeDirective or templateDirective - combining templates with
                                          //   element transclusion doesn't make sense.
                                          //
                                          // We need only nonTlbTranscludeDirective so that we prevent putting transclusion
                                          // on the same element more than once.
                                          nonTlbTranscludeDirective: nonTlbTranscludeDirective
                                        });
          } else {
            $template = jqLite(jqLiteClone(compileNode)).contents();
            $compileNode.empty(); // clear contents
            childTranscludeFn = compile($template, transcludeFn);
          }
        }

        if (directive.template) {
          hasTemplate = true;
          assertNoDuplicate('template', templateDirective, directive, $compileNode);
          templateDirective = directive;

          directiveValue = (isFunction(directive.template))
              ? directive.template($compileNode, templateAttrs)
              : directive.template;

          directiveValue = denormalizeTemplate(directiveValue);

          if (directive.replace) {
            replaceDirective = directive;
            if (jqLiteIsTextNode(directiveValue)) {
              $template = [];
            } else {
              $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));
            }
            compileNode = $template[0];

            if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
              throw $compileMinErr('tplrt',
                  "Template for directive '{0}' must have exactly one root element. {1}",
                  directiveName, '');
            }

            replaceWith(jqCollection, $compileNode, compileNode);

            var newTemplateAttrs = {$attr: {}};

            // combine directives from the original node and from the template:
            // - take the array of directives for this element
            // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)
            // - collect directives from the template and sort them by priority
            // - combine directives as: processed + template + unprocessed
            var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);
            var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));

            if (newIsolateScopeDirective) {
              markDirectivesAsIsolate(templateDirectives);
            }
            directives = directives.concat(templateDirectives).concat(unprocessedDirectives);
            mergeTemplateAttributes(templateAttrs, newTemplateAttrs);

            ii = directives.length;
          } else {
            $compileNode.html(directiveValue);
          }
        }

        if (directive.templateUrl) {
          hasTemplate = true;
          assertNoDuplicate('template', templateDirective, directive, $compileNode);
          templateDirective = directive;

          if (directive.replace) {
            replaceDirective = directive;
          }

          nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
              templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {
                controllerDirectives: controllerDirectives,
                newIsolateScopeDirective: newIsolateScopeDirective,
                templateDirective: templateDirective,
                nonTlbTranscludeDirective: nonTlbTranscludeDirective
              });
          ii = directives.length;
        } else if (directive.compile) {
          try {
            linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);
            if (isFunction(linkFn)) {
              addLinkFns(null, linkFn, attrStart, attrEnd);
            } else if (linkFn) {
              addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd);
            }
          } catch (e) {
            $exceptionHandler(e, startingTag($compileNode));
          }
        }

        if (directive.terminal) {
          nodeLinkFn.terminal = true;
          terminalPriority = Math.max(terminalPriority, directive.priority);
        }

      }

      nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
      nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
      nodeLinkFn.elementTranscludeOnThisElement = hasElementTranscludeDirective;
      nodeLinkFn.templateOnThisElement = hasTemplate;
      nodeLinkFn.transclude = childTranscludeFn;

      previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;

      // might be normal or delayed nodeLinkFn depending on if templateUrl is present
      return nodeLinkFn;

      ////////////////////

      function addLinkFns(pre, post, attrStart, attrEnd) {
        if (pre) {
          if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
          pre.require = directive.require;
          pre.directiveName = directiveName;
          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
            pre = cloneAndAnnotateFn(pre, {isolateScope: true});
          }
          preLinkFns.push(pre);
        }
        if (post) {
          if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
          post.require = directive.require;
          post.directiveName = directiveName;
          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
            post = cloneAndAnnotateFn(post, {isolateScope: true});
          }
          postLinkFns.push(post);
        }
      }


      function getControllers(directiveName, require, $element, elementControllers) {
        var value, retrievalMethod = 'data', optional = false;
        var $searchElement = $element;
        var match;
        if (isString(require)) {
          match = require.match(REQUIRE_PREFIX_REGEXP);
          require = require.substring(match[0].length);

          if (match[3]) {
            if (match[1]) match[3] = null;
            else match[1] = match[3];
          }
          if (match[1] === '^') {
            retrievalMethod = 'inheritedData';
          } else if (match[1] === '^^') {
            retrievalMethod = 'inheritedData';
            $searchElement = $element.parent();
          }
          if (match[2] === '?') {
            optional = true;
          }

          value = null;

          if (elementControllers && retrievalMethod === 'data') {
            if (value = elementControllers[require]) {
              value = value.instance;
            }
          }
          value = value || $searchElement[retrievalMethod]('$' + require + 'Controller');

          if (!value && !optional) {
            throw $compileMinErr('ctreq',
                "Controller '{0}', required by directive '{1}', can't be found!",
                require, directiveName);
          }
          return value || null;
        } else if (isArray(require)) {
          value = [];
          forEach(require, function(require) {
            value.push(getControllers(directiveName, require, $element, elementControllers));
          });
        }
        return value;
      }


      function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
        var i, ii, linkFn, controller, isolateScope, elementControllers, transcludeFn, $element,
            attrs;

        if (compileNode === linkNode) {
          attrs = templateAttrs;
          $element = templateAttrs.$$element;
        } else {
          $element = jqLite(linkNode);
          attrs = new Attributes($element, templateAttrs);
        }

        if (newIsolateScopeDirective) {
          isolateScope = scope.$new(true);
        }

        if (boundTranscludeFn) {
          // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
          // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
          transcludeFn = controllersBoundTransclude;
          transcludeFn.$$boundTransclude = boundTranscludeFn;
        }

        if (controllerDirectives) {
          // TODO: merge `controllers` and `elementControllers` into single object.
          controllers = {};
          elementControllers = {};
          forEach(controllerDirectives, function(directive) {
            var locals = {
              $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
              $element: $element,
              $attrs: attrs,
              $transclude: transcludeFn
            }, controllerInstance;

            controller = directive.controller;
            if (controller == '@') {
              controller = attrs[directive.name];
            }

            controllerInstance = $controller(controller, locals, true, directive.controllerAs);

            // For directives with element transclusion the element is a comment,
            // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
            // clean up (http://bugs.jquery.com/ticket/8335).
            // Instead, we save the controllers for the element in a local hash and attach to .data
            // later, once we have the actual element.
            elementControllers[directive.name] = controllerInstance;
            if (!hasElementTranscludeDirective) {
              $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
            }

            controllers[directive.name] = controllerInstance;
          });
        }

        if (newIsolateScopeDirective) {
          compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||
              templateDirective === newIsolateScopeDirective.$$originalDirective)));
          compile.$$addScopeClass($element, true);

          var isolateScopeController = controllers && controllers[newIsolateScopeDirective.name];
          var isolateBindingContext = isolateScope;
          if (isolateScopeController && isolateScopeController.identifier &&
              newIsolateScopeDirective.bindToController === true) {
            isolateBindingContext = isolateScopeController.instance;
          }

          forEach(isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, function(definition, scopeName) {
            var attrName = definition.attrName,
                optional = definition.optional,
                mode = definition.mode, // @, =, or &
                lastValue,
                parentGet, parentSet, compare;

            switch (mode) {

              case '@':
                attrs.$observe(attrName, function(value) {
                  isolateBindingContext[scopeName] = value;
                });
                attrs.$$observers[attrName].$$scope = scope;
                if (attrs[attrName]) {
                  // If the attribute has been provided then we trigger an interpolation to ensure
                  // the value is there for use in the link fn
                  isolateBindingContext[scopeName] = $interpolate(attrs[attrName])(scope);
                }
                break;

              case '=':
                if (optional && !attrs[attrName]) {
                  return;
                }
                parentGet = $parse(attrs[attrName]);
                if (parentGet.literal) {
                  compare = equals;
                } else {
                  compare = function(a, b) { return a === b || (a !== a && b !== b); };
                }
                parentSet = parentGet.assign || function() {
                  // reset the change, or we will throw this exception on every $digest
                  lastValue = isolateBindingContext[scopeName] = parentGet(scope);
                  throw $compileMinErr('nonassign',
                      "Expression '{0}' used with directive '{1}' is non-assignable!",
                      attrs[attrName], newIsolateScopeDirective.name);
                };
                lastValue = isolateBindingContext[scopeName] = parentGet(scope);
                var parentValueWatch = function parentValueWatch(parentValue) {
                  if (!compare(parentValue, isolateBindingContext[scopeName])) {
                    // we are out of sync and need to copy
                    if (!compare(parentValue, lastValue)) {
                      // parent changed and it has precedence
                      isolateBindingContext[scopeName] = parentValue;
                    } else {
                      // if the parent can be assigned then do so
                      parentSet(scope, parentValue = isolateBindingContext[scopeName]);
                    }
                  }
                  return lastValue = parentValue;
                };
                parentValueWatch.$stateful = true;
                var unwatch;
                if (definition.collection) {
                  unwatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
                } else {
                  unwatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
                }
                isolateScope.$on('$destroy', unwatch);
                break;

              case '&':
                parentGet = $parse(attrs[attrName]);
                isolateBindingContext[scopeName] = function(locals) {
                  return parentGet(scope, locals);
                };
                break;
            }
          });
        }
        if (controllers) {
          forEach(controllers, function(controller) {
            controller();
          });
          controllers = null;
        }

        // PRELINKING
        for (i = 0, ii = preLinkFns.length; i < ii; i++) {
          linkFn = preLinkFns[i];
          invokeLinkFn(linkFn,
              linkFn.isolateScope ? isolateScope : scope,
              $element,
              attrs,
              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
              transcludeFn
          );
        }

        // RECURSION
        // We only pass the isolate scope, if the isolate directive has a template,
        // otherwise the child elements do not belong to the isolate directive.
        var scopeToChild = scope;
        if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {
          scopeToChild = isolateScope;
        }
        childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);

        // POSTLINKING
        for (i = postLinkFns.length - 1; i >= 0; i--) {
          linkFn = postLinkFns[i];
          invokeLinkFn(linkFn,
              linkFn.isolateScope ? isolateScope : scope,
              $element,
              attrs,
              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
              transcludeFn
          );
        }

        // This is the function that is injected as `$transclude`.
        // Note: all arguments are optional!
        function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement) {
          var transcludeControllers;

          // No scope passed in:
          if (!isScope(scope)) {
            futureParentElement = cloneAttachFn;
            cloneAttachFn = scope;
            scope = undefined;
          }

          if (hasElementTranscludeDirective) {
            transcludeControllers = elementControllers;
          }
          if (!futureParentElement) {
            futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
          }
          return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
        }
      }
    }

    function markDirectivesAsIsolate(directives) {
      // mark all directives as needing isolate scope.
      for (var j = 0, jj = directives.length; j < jj; j++) {
        directives[j] = inherit(directives[j], {$$isolateScope: true});
      }
    }

    /**
     * looks up the directive and decorates it with exception handling and proper parameters. We
     * call this the boundDirective.
     *
     * @param {string} name name of the directive to look up.
     * @param {string} location The directive must be found in specific format.
     *   String containing any of theses characters:
     *
     *   * `E`: element name
     *   * `A': attribute
     *   * `C`: class
     *   * `M`: comment
     * @returns {boolean} true if directive was added.
     */
    function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,
                          endAttrName) {
      if (name === ignoreDirective) return null;
      var match = null;
      if (hasDirectives.hasOwnProperty(name)) {
        for (var directive, directives = $injector.get(name + Suffix),
            i = 0, ii = directives.length; i < ii; i++) {
          try {
            directive = directives[i];
            if ((maxPriority === undefined || maxPriority > directive.priority) &&
                 directive.restrict.indexOf(location) != -1) {
              if (startAttrName) {
                directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
              }
              tDirectives.push(directive);
              match = directive;
            }
          } catch (e) { $exceptionHandler(e); }
        }
      }
      return match;
    }


    /**
     * looks up the directive and returns true if it is a multi-element directive,
     * and therefore requires DOM nodes between -start and -end markers to be grouped
     * together.
     *
     * @param {string} name name of the directive to look up.
     * @returns true if directive was registered as multi-element.
     */
    function directiveIsMultiElement(name) {
      if (hasDirectives.hasOwnProperty(name)) {
        for (var directive, directives = $injector.get(name + Suffix),
            i = 0, ii = directives.length; i < ii; i++) {
          directive = directives[i];
          if (directive.multiElement) {
            return true;
          }
        }
      }
      return false;
    }

    /**
     * When the element is replaced with HTML template then the new attributes
     * on the template need to be merged with the existing attributes in the DOM.
     * The desired effect is to have both of the attributes present.
     *
     * @param {object} dst destination attributes (original DOM)
     * @param {object} src source attributes (from the directive template)
     */
    function mergeTemplateAttributes(dst, src) {
      var srcAttr = src.$attr,
          dstAttr = dst.$attr,
          $element = dst.$$element;

      // reapply the old attributes to the new element
      forEach(dst, function(value, key) {
        if (key.charAt(0) != '$') {
          if (src[key] && src[key] !== value) {
            value += (key === 'style' ? ';' : ' ') + src[key];
          }
          dst.$set(key, value, true, srcAttr[key]);
        }
      });

      // copy the new attributes on the old attrs object
      forEach(src, function(value, key) {
        if (key == 'class') {
          safeAddClass($element, value);
          dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
        } else if (key == 'style') {
          $element.attr('style', $element.attr('style') + ';' + value);
          dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
          // `dst` will never contain hasOwnProperty as DOM parser won't let it.
          // You will get an "InvalidCharacterError: DOM Exception 5" error if you
          // have an attribute like "has-own-property" or "data-has-own-property", etc.
        } else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) {
          dst[key] = value;
          dstAttr[key] = srcAttr[key];
        }
      });
    }


    function compileTemplateUrl(directives, $compileNode, tAttrs,
        $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
      var linkQueue = [],
          afterTemplateNodeLinkFn,
          afterTemplateChildLinkFn,
          beforeTemplateCompileNode = $compileNode[0],
          origAsyncDirective = directives.shift(),
          derivedSyncDirective = inherit(origAsyncDirective, {
            templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective
          }),
          templateUrl = (isFunction(origAsyncDirective.templateUrl))
              ? origAsyncDirective.templateUrl($compileNode, tAttrs)
              : origAsyncDirective.templateUrl,
          templateNamespace = origAsyncDirective.templateNamespace;

      $compileNode.empty();

      $templateRequest(templateUrl)
        .then(function(content) {
          var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;

          content = denormalizeTemplate(content);

          if (origAsyncDirective.replace) {
            if (jqLiteIsTextNode(content)) {
              $template = [];
            } else {
              $template = removeComments(wrapTemplate(templateNamespace, trim(content)));
            }
            compileNode = $template[0];

            if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
              throw $compileMinErr('tplrt',
                  "Template for directive '{0}' must have exactly one root element. {1}",
                  origAsyncDirective.name, templateUrl);
            }

            tempTemplateAttrs = {$attr: {}};
            replaceWith($rootElement, $compileNode, compileNode);
            var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);

            if (isObject(origAsyncDirective.scope)) {
              markDirectivesAsIsolate(templateDirectives);
            }
            directives = templateDirectives.concat(directives);
            mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
          } else {
            compileNode = beforeTemplateCompileNode;
            $compileNode.html(content);
          }

          directives.unshift(derivedSyncDirective);

          afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,
              childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,
              previousCompileContext);
          forEach($rootElement, function(node, i) {
            if (node == compileNode) {
              $rootElement[i] = $compileNode[0];
            }
          });
          afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);

          while (linkQueue.length) {
            var scope = linkQueue.shift(),
                beforeTemplateLinkNode = linkQueue.shift(),
                linkRootElement = linkQueue.shift(),
                boundTranscludeFn = linkQueue.shift(),
                linkNode = $compileNode[0];

            if (scope.$$destroyed) continue;

            if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
              var oldClasses = beforeTemplateLinkNode.className;

              if (!(previousCompileContext.hasElementTranscludeDirective &&
                  origAsyncDirective.replace)) {
                // it was cloned therefore we have to clone as well.
                linkNode = jqLiteClone(compileNode);
              }
              replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);

              // Copy in CSS classes from original node
              safeAddClass(jqLite(linkNode), oldClasses);
            }
            if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
              childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
            } else {
              childBoundTranscludeFn = boundTranscludeFn;
            }
            afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
              childBoundTranscludeFn);
          }
          linkQueue = null;
        });

      return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
        var childBoundTranscludeFn = boundTranscludeFn;
        if (scope.$$destroyed) return;
        if (linkQueue) {
          linkQueue.push(scope,
                         node,
                         rootElement,
                         childBoundTranscludeFn);
        } else {
          if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
            childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
          }
          afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);
        }
      };
    }


    /**
     * Sorting function for bound directives.
     */
    function byPriority(a, b) {
      var diff = b.priority - a.priority;
      if (diff !== 0) return diff;
      if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;
      return a.index - b.index;
    }


    function assertNoDuplicate(what, previousDirective, directive, element) {
      if (previousDirective) {
        throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}',
            previousDirective.name, directive.name, what, startingTag(element));
      }
    }


    function addTextInterpolateDirective(directives, text) {
      var interpolateFn = $interpolate(text, true);
      if (interpolateFn) {
        directives.push({
          priority: 0,
          compile: function textInterpolateCompileFn(templateNode) {
            var templateNodeParent = templateNode.parent(),
                hasCompileParent = !!templateNodeParent.length;

            // When transcluding a template that has bindings in the root
            // we don't have a parent and thus need to add the class during linking fn.
            if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);

            return function textInterpolateLinkFn(scope, node) {
              var parent = node.parent();
              if (!hasCompileParent) compile.$$addBindingClass(parent);
              compile.$$addBindingInfo(parent, interpolateFn.expressions);
              scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {
                node[0].nodeValue = value;
              });
            };
          }
        });
      }
    }


    function wrapTemplate(type, template) {
      type = lowercase(type || 'html');
      switch (type) {
      case 'svg':
      case 'math':
        var wrapper = document.createElement('div');
        wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
        return wrapper.childNodes[0].childNodes;
      default:
        return template;
      }
    }


    function getTrustedContext(node, attrNormalizedName) {
      if (attrNormalizedName == "srcdoc") {
        return $sce.HTML;
      }
      var tag = nodeName_(node);
      // maction[xlink:href] can source SVG.  It's not limited to <maction>.
      if (attrNormalizedName == "xlinkHref" ||
          (tag == "form" && attrNormalizedName == "action") ||
          (tag != "img" && (attrNormalizedName == "src" ||
                            attrNormalizedName == "ngSrc"))) {
        return $sce.RESOURCE_URL;
      }
    }


    function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) {
      var trustedContext = getTrustedContext(node, name);
      allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing;

      var interpolateFn = $interpolate(value, true, trustedContext, allOrNothing);

      // no interpolation found -> ignore
      if (!interpolateFn) return;


      if (name === "multiple" && nodeName_(node) === "select") {
        throw $compileMinErr("selmulti",
            "Binding to the 'multiple' attribute is not supported. Element: {0}",
            startingTag(node));
      }

      directives.push({
        priority: 100,
        compile: function() {
            return {
              pre: function attrInterpolatePreLinkFn(scope, element, attr) {
                var $$observers = (attr.$$observers || (attr.$$observers = {}));

                if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
                  throw $compileMinErr('nodomevents',
                      "Interpolations for HTML DOM event attributes are disallowed.  Please use the " +
                          "ng- versions (such as ng-click instead of onclick) instead.");
                }

                // If the attribute has changed since last $interpolate()ed
                var newValue = attr[name];
                if (newValue !== value) {
                  // we need to interpolate again since the attribute value has been updated
                  // (e.g. by another directive's compile function)
                  // ensure unset/empty values make interpolateFn falsy
                  interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);
                  value = newValue;
                }

                // if attribute was updated so that there is no interpolation going on we don't want to
                // register any observers
                if (!interpolateFn) return;

                // initialize attr object so that it's ready in case we need the value for isolate
                // scope initialization, otherwise the value would not be available from isolate
                // directive's linking fn during linking phase
                attr[name] = interpolateFn(scope);

                ($$observers[name] || ($$observers[name] = [])).$$inter = true;
                (attr.$$observers && attr.$$observers[name].$$scope || scope).
                  $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
                    //special case for class attribute addition + removal
                    //so that class changes can tap into the animation
                    //hooks provided by the $animate service. Be sure to
                    //skip animations when the first digest occurs (when
                    //both the new and the old values are the same) since
                    //the CSS classes are the non-interpolated values
                    if (name === 'class' && newValue != oldValue) {
                      attr.$updateClass(newValue, oldValue);
                    } else {
                      attr.$set(name, newValue);
                    }
                  });
              }
            };
          }
      });
    }


    /**
     * This is a special jqLite.replaceWith, which can replace items which
     * have no parents, provided that the containing jqLite collection is provided.
     *
     * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes
     *                               in the root of the tree.
     * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep
     *                                  the shell, but replace its DOM node reference.
     * @param {Node} newNode The new DOM node.
     */
    function replaceWith($rootElement, elementsToRemove, newNode) {
      var firstElementToRemove = elementsToRemove[0],
          removeCount = elementsToRemove.length,
          parent = firstElementToRemove.parentNode,
          i, ii;

      if ($rootElement) {
        for (i = 0, ii = $rootElement.length; i < ii; i++) {
          if ($rootElement[i] == firstElementToRemove) {
            $rootElement[i++] = newNode;
            for (var j = i, j2 = j + removeCount - 1,
                     jj = $rootElement.length;
                 j < jj; j++, j2++) {
              if (j2 < jj) {
                $rootElement[j] = $rootElement[j2];
              } else {
                delete $rootElement[j];
              }
            }
            $rootElement.length -= removeCount - 1;

            // If the replaced element is also the jQuery .context then replace it
            // .context is a deprecated jQuery api, so we should set it only when jQuery set it
            // http://api.jquery.com/context/
            if ($rootElement.context === firstElementToRemove) {
              $rootElement.context = newNode;
            }
            break;
          }
        }
      }

      if (parent) {
        parent.replaceChild(newNode, firstElementToRemove);
      }

      // TODO(perf): what's this document fragment for? is it needed? can we at least reuse it?
      var fragment = document.createDocumentFragment();
      fragment.appendChild(firstElementToRemove);

      // Copy over user data (that includes Angular's $scope etc.). Don't copy private
      // data here because there's no public interface in jQuery to do that and copying over
      // event listeners (which is the main use of private data) wouldn't work anyway.
      jqLite(newNode).data(jqLite(firstElementToRemove).data());

      // Remove data of the replaced element. We cannot just call .remove()
      // on the element it since that would deallocate scope that is needed
      // for the new node. Instead, remove the data "manually".
      if (!jQuery) {
        delete jqLite.cache[firstElementToRemove[jqLite.expando]];
      } else {
        // jQuery 2.x doesn't expose the data storage. Use jQuery.cleanData to clean up after
        // the replaced element. The cleanData version monkey-patched by Angular would cause
        // the scope to be trashed and we do need the very same scope to work with the new
        // element. However, we cannot just cache the non-patched version and use it here as
        // that would break if another library patches the method after Angular does (one
        // example is jQuery UI). Instead, set a flag indicating scope destroying should be
        // skipped this one time.
        skipDestroyOnNextJQueryCleanData = true;
        jQuery.cleanData([firstElementToRemove]);
      }

      for (var k = 1, kk = elementsToRemove.length; k < kk; k++) {
        var element = elementsToRemove[k];
        jqLite(element).remove(); // must do this way to clean up expando
        fragment.appendChild(element);
        delete elementsToRemove[k];
      }

      elementsToRemove[0] = newNode;
      elementsToRemove.length = 1;
    }


    function cloneAndAnnotateFn(fn, annotation) {
      return extend(function() { return fn.apply(null, arguments); }, fn, annotation);
    }


    function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {
      try {
        linkFn(scope, $element, attrs, controllers, transcludeFn);
      } catch (e) {
        $exceptionHandler(e, startingTag($element));
      }
    }
  }];
}

var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
/**
 * Converts all accepted directives format into proper directive name.
 * @param name Name to normalize
 */
function directiveNormalize(name) {
  return camelCase(name.replace(PREFIX_REGEXP, ''));
}

/**
 * @ngdoc type
 * @name $compile.directive.Attributes
 *
 * @description
 * A shared object between directive compile / linking functions which contains normalized DOM
 * element attributes. The values reflect current binding state `{{ }}`. The normalization is
 * needed since all of these are treated as equivalent in Angular:
 *
 * ```
 *    <span ng:bind="a" ng-bind="a" data-ng-bind="a" x-ng-bind="a">
 * ```
 */

/**
 * @ngdoc property
 * @name $compile.directive.Attributes#$attr
 *
 * @description
 * A map of DOM element attribute names to the normalized name. This is
 * needed to do reverse lookup from normalized name back to actual name.
 */


/**
 * @ngdoc method
 * @name $compile.directive.Attributes#$set
 * @kind function
 *
 * @description
 * Set DOM element attribute value.
 *
 *
 * @param {string} name Normalized element attribute name of the property to modify. The name is
 *          reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr}
 *          property to the original name.
 * @param {string} value Value to set the attribute to. The value can be an interpolated string.
 */



/**
 * Closure compiler type information
 */

function nodesetLinkingFn(
  /* angular.Scope */ scope,
  /* NodeList */ nodeList,
  /* Element */ rootElement,
  /* function(Function) */ boundTranscludeFn
) {}

function directiveLinkingFn(
  /* nodesetLinkingFn */ nodesetLinkingFn,
  /* angular.Scope */ scope,
  /* Node */ node,
  /* Element */ rootElement,
  /* function(Function) */ boundTranscludeFn
) {}

function tokenDifference(str1, str2) {
  var values = '',
      tokens1 = str1.split(/\s+/),
      tokens2 = str2.split(/\s+/);

  outer:
  for (var i = 0; i < tokens1.length; i++) {
    var token = tokens1[i];
    for (var j = 0; j < tokens2.length; j++) {
      if (token == tokens2[j]) continue outer;
    }
    values += (values.length > 0 ? ' ' : '') + token;
  }
  return values;
}

function removeComments(jqNodes) {
  jqNodes = jqLite(jqNodes);
  var i = jqNodes.length;

  if (i <= 1) {
    return jqNodes;
  }

  while (i--) {
    var node = jqNodes[i];
    if (node.nodeType === NODE_TYPE_COMMENT) {
      splice.call(jqNodes, i, 1);
    }
  }
  return jqNodes;
}

var $controllerMinErr = minErr('$controller');

/**
 * @ngdoc provider
 * @name $controllerProvider
 * @description
 * The {@link ng.$controller $controller service} is used by Angular to create new
 * controllers.
 *
 * This provider allows controller registration via the
 * {@link ng.$controllerProvider#register register} method.
 */
function $ControllerProvider() {
  var controllers = {},
      globals = false,
      CNTRL_REG = /^(\S+)(\s+as\s+(\w+))?$/;


  /**
   * @ngdoc method
   * @name $controllerProvider#register
   * @param {string|Object} name Controller name, or an object map of controllers where the keys are
   *    the names and the values are the constructors.
   * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI
   *    annotations in the array notation).
   */
  this.register = function(name, constructor) {
    assertNotHasOwnProperty(name, 'controller');
    if (isObject(name)) {
      extend(controllers, name);
    } else {
      controllers[name] = constructor;
    }
  };

  /**
   * @ngdoc method
   * @name $controllerProvider#allowGlobals
   * @description If called, allows `$controller` to find controller constructors on `window`
   */
  this.allowGlobals = function() {
    globals = true;
  };


  this.$get = ['$injector', '$window', function($injector, $window) {

    /**
     * @ngdoc service
     * @name $controller
     * @requires $injector
     *
     * @param {Function|string} constructor If called with a function then it's considered to be the
     *    controller constructor function. Otherwise it's considered to be a string which is used
     *    to retrieve the controller constructor using the following steps:
     *
     *    * check if a controller with given name is registered via `$controllerProvider`
     *    * check if evaluating the string on the current scope returns a constructor
     *    * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
     *      `window` object (not recommended)
     *
     *    The string can use the `controller as property` syntax, where the controller instance is published
     *    as the specified property on the `scope`; the `scope` must be injected into `locals` param for this
     *    to work correctly.
     *
     * @param {Object} locals Injection locals for Controller.
     * @return {Object} Instance of given controller.
     *
     * @description
     * `$controller` service is responsible for instantiating controllers.
     *
     * It's just a simple call to {@link auto.$injector $injector}, but extracted into
     * a service, so that one can override this service with [BC version](https://gist.github.com/1649788).
     */
    return function(expression, locals, later, ident) {
      // PRIVATE API:
      //   param `later` --- indicates that the controller's constructor is invoked at a later time.
      //                     If true, $controller will allocate the object with the correct
      //                     prototype chain, but will not invoke the controller until a returned
      //                     callback is invoked.
      //   param `ident` --- An optional label which overrides the label parsed from the controller
      //                     expression, if any.
      var instance, match, constructor, identifier;
      later = later === true;
      if (ident && isString(ident)) {
        identifier = ident;
      }

      if (isString(expression)) {
        match = expression.match(CNTRL_REG);
        if (!match) {
          throw $controllerMinErr('ctrlfmt',
            "Badly formed controller string '{0}'. " +
            "Must match `__name__ as __id__` or `__name__`.", expression);
        }
        constructor = match[1],
        identifier = identifier || match[3];
        expression = controllers.hasOwnProperty(constructor)
            ? controllers[constructor]
            : getter(locals.$scope, constructor, true) ||
                (globals ? getter($window, constructor, true) : undefined);

        assertArgFn(expression, constructor, true);
      }

      if (later) {
        // Instantiate controller later:
        // This machinery is used to create an instance of the object before calling the
        // controller's constructor itself.
        //
        // This allows properties to be added to the controller before the constructor is
        // invoked. Primarily, this is used for isolate scope bindings in $compile.
        //
        // This feature is not intended for use by applications, and is thus not documented
        // publicly.
        // Object creation: http://jsperf.com/create-constructor/2
        var controllerPrototype = (isArray(expression) ?
          expression[expression.length - 1] : expression).prototype;
        instance = Object.create(controllerPrototype || null);

        if (identifier) {
          addIdentifier(locals, identifier, instance, constructor || expression.name);
        }

        return extend(function() {
          $injector.invoke(expression, instance, locals, constructor);
          return instance;
        }, {
          instance: instance,
          identifier: identifier
        });
      }

      instance = $injector.instantiate(expression, locals, constructor);

      if (identifier) {
        addIdentifier(locals, identifier, instance, constructor || expression.name);
      }

      return instance;
    };

    function addIdentifier(locals, identifier, instance, name) {
      if (!(locals && isObject(locals.$scope))) {
        throw minErr('$controller')('noscp',
          "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.",
          name, identifier);
      }

      locals.$scope[identifier] = instance;
    }
  }];
}

/**
 * @ngdoc service
 * @name $document
 * @requires $window
 *
 * @description
 * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.
 *
 * @example
   <example module="documentExample">
     <file name="index.html">
       <div ng-controller="ExampleController">
         <p>$document title: <b ng-bind="title"></b></p>
         <p>window.document title: <b ng-bind="windowTitle"></b></p>
       </div>
     </file>
     <file name="script.js">
       angular.module('documentExample', [])
         .controller('ExampleController', ['$scope', '$document', function($scope, $document) {
           $scope.title = $document[0].title;
           $scope.windowTitle = angular.element(window.document)[0].title;
         }]);
     </file>
   </example>
 */
function $DocumentProvider() {
  this.$get = ['$window', function(window) {
    return jqLite(window.document);
  }];
}

/**
 * @ngdoc service
 * @name $exceptionHandler
 * @requires ng.$log
 *
 * @description
 * Any uncaught exception in angular expressions is delegated to this service.
 * The default implementation simply delegates to `$log.error` which logs it into
 * the browser console.
 *
 * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by
 * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.
 *
 * ## Example:
 *
 * ```js
 *   angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
 *     return function(exception, cause) {
 *       exception.message += ' (caused by "' + cause + '")';
 *       throw exception;
 *     };
 *   });
 * ```
 *
 * This example will override the normal action of `$exceptionHandler`, to make angular
 * exceptions fail hard when they happen, instead of just logging to the console.
 *
 * <hr />
 * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`
 * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}
 * (unless executed during a digest).
 *
 * If you wish, you can manually delegate exceptions, e.g.
 * `try { ... } catch(e) { $exceptionHandler(e); }`
 *
 * @param {Error} exception Exception associated with the error.
 * @param {string=} cause optional information about the context in which
 *       the error was thrown.
 *
 */
function $ExceptionHandlerProvider() {
  this.$get = ['$log', function($log) {
    return function(exception, cause) {
      $log.error.apply($log, arguments);
    };
  }];
}

var APPLICATION_JSON = 'application/json';
var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
var JSON_START = /^\[|^\{(?!\{)/;
var JSON_ENDS = {
  '[': /]$/,
  '{': /}$/
};
var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;

function defaultHttpResponseTransform(data, headers) {
  if (isString(data)) {
    // Strip json vulnerability protection prefix and trim whitespace
    var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();

    if (tempData) {
      var contentType = headers('Content-Type');
      if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
        data = fromJson(tempData);
      }
    }
  }

  return data;
}

function isJsonLike(str) {
    var jsonStart = str.match(JSON_START);
    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
}

/**
 * Parse headers into key value object
 *
 * @param {string} headers Raw headers as a string
 * @returns {Object} Parsed headers as key value object
 */
function parseHeaders(headers) {
  var parsed = createMap(), key, val, i;

  if (!headers) return parsed;

  forEach(headers.split('\n'), function(line) {
    i = line.indexOf(':');
    key = lowercase(trim(line.substr(0, i)));
    val = trim(line.substr(i + 1));

    if (key) {
      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
    }
  });

  return parsed;
}


/**
 * Returns a function that provides access to parsed headers.
 *
 * Headers are lazy parsed when first requested.
 * @see parseHeaders
 *
 * @param {(string|Object)} headers Headers to provide access to.
 * @returns {function(string=)} Returns a getter function which if called with:
 *
 *   - if called with single an argument returns a single header value or null
 *   - if called with no arguments returns an object containing all headers.
 */
function headersGetter(headers) {
  var headersObj = isObject(headers) ? headers : undefined;

  return function(name) {
    if (!headersObj) headersObj =  parseHeaders(headers);

    if (name) {
      var value = headersObj[lowercase(name)];
      if (value === void 0) {
        value = null;
      }
      return value;
    }

    return headersObj;
  };
}


/**
 * Chain all given functions
 *
 * This function is used for both request and response transforming
 *
 * @param {*} data Data to transform.
 * @param {function(string=)} headers HTTP headers getter fn.
 * @param {number} status HTTP status code of the response.
 * @param {(Function|Array.<Function>)} fns Function or an array of functions.
 * @returns {*} Transformed data.
 */
function transformData(data, headers, status, fns) {
  if (isFunction(fns))
    return fns(data, headers, status);

  forEach(fns, function(fn) {
    data = fn(data, headers, status);
  });

  return data;
}


function isSuccess(status) {
  return 200 <= status && status < 300;
}


/**
 * @ngdoc provider
 * @name $httpProvider
 * @description
 * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
 * */
function $HttpProvider() {
  /**
   * @ngdoc property
   * @name $httpProvider#defaults
   * @description
   *
   * Object containing default values for all {@link ng.$http $http} requests.
   *
   * - **`defaults.cache`** - {Object} - an object built with {@link ng.$cacheFactory `$cacheFactory`}
   * that will provide the cache for all requests who set their `cache` property to `true`.
   * If you set the `default.cache = false` then only requests that specify their own custom
   * cache object will be cached. See {@link $http#caching $http Caching} for more information.
   *
   * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
   * Defaults value is `'XSRF-TOKEN'`.
   *
   * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the
   * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.
   *
   * - **`defaults.headers`** - {Object} - Default headers for all $http requests.
   * Refer to {@link ng.$http#setting-http-headers $http} for documentation on
   * setting default headers.
   *     - **`defaults.headers.common`**
   *     - **`defaults.headers.post`**
   *     - **`defaults.headers.put`**
   *     - **`defaults.headers.patch`**
   *
   **/
  var defaults = this.defaults = {
    // transform incoming response data
    transformResponse: [defaultHttpResponseTransform],

    // transform outgoing request data
    transformRequest: [function(d) {
      return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;
    }],

    // default headers
    headers: {
      common: {
        'Accept': 'application/json, text/plain, */*'
      },
      post:   shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
      put:    shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
      patch:  shallowCopy(CONTENT_TYPE_APPLICATION_JSON)
    },

    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN'
  };

  var useApplyAsync = false;
  /**
   * @ngdoc method
   * @name $httpProvider#useApplyAsync
   * @description
   *
   * Configure $http service to combine processing of multiple http responses received at around
   * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in
   * significant performance improvement for bigger applications that make many HTTP requests
   * concurrently (common during application bootstrap).
   *
   * Defaults to false. If no value is specifed, returns the current configured value.
   *
   * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred
   *    "apply" on the next tick, giving time for subsequent requests in a roughly ~10ms window
   *    to load and share the same digest cycle.
   *
   * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.
   *    otherwise, returns the current configured value.
   **/
  this.useApplyAsync = function(value) {
    if (isDefined(value)) {
      useApplyAsync = !!value;
      return this;
    }
    return useApplyAsync;
  };

  /**
   * @ngdoc property
   * @name $httpProvider#interceptors
   * @description
   *
   * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}
   * pre-processing of request or postprocessing of responses.
   *
   * These service factories are ordered by request, i.e. they are applied in the same order as the
   * array, on request, but reverse order, on response.
   *
   * {@link ng.$http#interceptors Interceptors detailed info}
   **/
  var interceptorFactories = this.interceptors = [];

  this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
      function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) {

    var defaultCache = $cacheFactory('$http');

    /**
     * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
     * The reversal is needed so that we can build up the interception chain around the
     * server request.
     */
    var reversedInterceptors = [];

    forEach(interceptorFactories, function(interceptorFactory) {
      reversedInterceptors.unshift(isString(interceptorFactory)
          ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
    });

    /**
     * @ngdoc service
     * @kind function
     * @name $http
     * @requires ng.$httpBackend
     * @requires $cacheFactory
     * @requires $rootScope
     * @requires $q
     * @requires $injector
     *
     * @description
     * The `$http` service is a core Angular service that facilitates communication with the remote
     * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest)
     * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP).
     *
     * For unit testing applications that use `$http` service, see
     * {@link ngMock.$httpBackend $httpBackend mock}.
     *
     * For a higher level of abstraction, please check out the {@link ngResource.$resource
     * $resource} service.
     *
     * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
     * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
     * it is important to familiarize yourself with these APIs and the guarantees they provide.
     *
     *
     * ## General usage
     * The `$http` service is a function which takes a single argument — a configuration object —
     * that is used to generate an HTTP request and returns  a {@link ng.$q promise}
     * with two $http specific methods: `success` and `error`.
     *
     * ```js
     *   // Simple GET request example :
     *   $http.get('/someUrl').
     *     success(function(data, status, headers, config) {
     *       // this callback will be called asynchronously
     *       // when the response is available
     *     }).
     *     error(function(data, status, headers, config) {
     *       // called asynchronously if an error occurs
     *       // or server returns response with an error status.
     *     });
     * ```
     *
     * ```js
     *   // Simple POST request example (passing data) :
     *   $http.post('/someUrl', {msg:'hello word!'}).
     *     success(function(data, status, headers, config) {
     *       // this callback will be called asynchronously
     *       // when the response is available
     *     }).
     *     error(function(data, status, headers, config) {
     *       // called asynchronously if an error occurs
     *       // or server returns response with an error status.
     *     });
     * ```
     *
     *
     * Since the returned value of calling the $http function is a `promise`, you can also use
     * the `then` method to register callbacks, and these callbacks will receive a single argument –
     * an object representing the response. See the API signature and type info below for more
     * details.
     *
     * A response status code between 200 and 299 is considered a success status and
     * will result in the success callback being called. Note that if the response is a redirect,
     * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
     * called for such responses.
     *
     * ## Writing Unit Tests that use $http
     * When unit testing (using {@link ngMock ngMock}), it is necessary to call
     * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending
     * request using trained responses.
     *
     * ```
     * $httpBackend.expectGET(...);
     * $http.get(...);
     * $httpBackend.flush();
     * ```
     *
     * ## Shortcut methods
     *
     * Shortcut methods are also available. All shortcut methods require passing in the URL, and
     * request data must be passed in for POST/PUT requests.
     *
     * ```js
     *   $http.get('/someUrl').success(successCallback);
     *   $http.post('/someUrl', data).success(successCallback);
     * ```
     *
     * Complete list of shortcut methods:
     *
     * - {@link ng.$http#get $http.get}
     * - {@link ng.$http#head $http.head}
     * - {@link ng.$http#post $http.post}
     * - {@link ng.$http#put $http.put}
     * - {@link ng.$http#delete $http.delete}
     * - {@link ng.$http#jsonp $http.jsonp}
     * - {@link ng.$http#patch $http.patch}
     *
     *
     * ## Setting HTTP Headers
     *
     * The $http service will automatically add certain HTTP headers to all requests. These defaults
     * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
     * object, which currently contains this default configuration:
     *
     * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
     *   - `Accept: application/json, text/plain, * / *`
     * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
     *   - `Content-Type: application/json`
     * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
     *   - `Content-Type: application/json`
     *
     * To add or overwrite these defaults, simply add or remove a property from these configuration
     * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
     * with the lowercased HTTP method name as the key, e.g.
     * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }.
     *
     * The defaults can also be set at runtime via the `$http.defaults` object in the same
     * fashion. For example:
     *
     * ```
     * module.run(function($http) {
     *   $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'
     * });
     * ```
     *
     * In addition, you can supply a `headers` property in the config object passed when
     * calling `$http(config)`, which overrides the defaults without changing them globally.
     *
     * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,
     * Use the `headers` property, setting the desired header to `undefined`. For example:
     *
     * ```js
     * var req = {
     *  method: 'POST',
     *  url: 'http://example.com',
     *  headers: {
     *    'Content-Type': undefined
     *  },
     *  data: { test: 'test' }
     * }
     *
     * $http(req).success(function(){...}).error(function(){...});
     * ```
     *
     * ## Transforming Requests and Responses
     *
     * Both requests and responses can be transformed using transformation functions: `transformRequest`
     * and `transformResponse`. These properties can be a single function that returns
     * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,
     * which allows you to `push` or `unshift` a new transformation function into the transformation chain.
     *
     * ### Default Transformations
     *
     * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and
     * `defaults.transformResponse` properties. If a request does not provide its own transformations
     * then these will be applied.
     *
     * You can augment or replace the default transformations by modifying these properties by adding to or
     * replacing the array.
     *
     * Angular provides the following default transformations:
     *
     * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`):
     *
     * - If the `data` property of the request configuration object contains an object, serialize it
     *   into JSON format.
     *
     * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`):
     *
     *  - If XSRF prefix is detected, strip it (see Security Considerations section below).
     *  - If JSON response is detected, deserialize it using a JSON parser.
     *
     *
     * ### Overriding the Default Transformations Per Request
     *
     * If you wish override the request/response transformations only for a single request then provide
     * `transformRequest` and/or `transformResponse` properties on the configuration object passed
     * into `$http`.
     *
     * Note that if you provide these properties on the config object the default transformations will be
     * overwritten. If you wish to augment the default transformations then you must include them in your
     * local transformation array.
     *
     * The following code demonstrates adding a new response transformation to be run after the default response
     * transformations have been run.
     *
     * ```js
     * function appendTransform(defaults, transform) {
     *
     *   // We can't guarantee that the default transformation is an array
     *   defaults = angular.isArray(defaults) ? defaults : [defaults];
     *
     *   // Append the new transformation to the defaults
     *   return defaults.concat(transform);
     * }
     *
     * $http({
     *   url: '...',
     *   method: 'GET',
     *   transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
     *     return doTransform(value);
     *   })
     * });
     * ```
     *
     *
     * ## Caching
     *
     * To enable caching, set the request configuration `cache` property to `true` (to use default
     * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).
     * When the cache is enabled, `$http` stores the response from the server in the specified
     * cache. The next time the same request is made, the response is served from the cache without
     * sending a request to the server.
     *
     * Note that even if the response is served from cache, delivery of the data is asynchronous in
     * the same way that real requests are.
     *
     * If there are multiple GET requests for the same URL that should be cached using the same
     * cache, but the cache is not populated yet, only one request to the server will be made and
     * the remaining requests will be fulfilled using the response from the first request.
     *
     * You can change the default cache to a new object (built with
     * {@link ng.$cacheFactory `$cacheFactory`}) by updating the
     * {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set
     * their `cache` property to `true` will now use this cache object.
     *
     * If you set the default cache to `false` then only requests that specify their own custom
     * cache object will be cached.
     *
     * ## Interceptors
     *
     * Before you start creating interceptors, be sure to understand the
     * {@link ng.$q $q and deferred/promise APIs}.
     *
     * For purposes of global error handling, authentication, or any kind of synchronous or
     * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
     * able to intercept requests before they are handed to the server and
     * responses before they are handed over to the application code that
     * initiated these requests. The interceptors leverage the {@link ng.$q
     * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.
     *
     * The interceptors are service factories that are registered with the `$httpProvider` by
     * adding them to the `$httpProvider.interceptors` array. The factory is called and
     * injected with dependencies (if specified) and returns the interceptor.
     *
     * There are two kinds of interceptors (and two kinds of rejection interceptors):
     *
     *   * `request`: interceptors get called with a http `config` object. The function is free to
     *     modify the `config` object or create a new one. The function needs to return the `config`
     *     object directly, or a promise containing the `config` or a new `config` object.
     *   * `requestError`: interceptor gets called when a previous interceptor threw an error or
     *     resolved with a rejection.
     *   * `response`: interceptors get called with http `response` object. The function is free to
     *     modify the `response` object or create a new one. The function needs to return the `response`
     *     object directly, or as a promise containing the `response` or a new `response` object.
     *   * `responseError`: interceptor gets called when a previous interceptor threw an error or
     *     resolved with a rejection.
     *
     *
     * ```js
     *   // register the interceptor as a service
     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
     *     return {
     *       // optional method
     *       'request': function(config) {
     *         // do something on success
     *         return config;
     *       },
     *
     *       // optional method
     *      'requestError': function(rejection) {
     *         // do something on error
     *         if (canRecover(rejection)) {
     *           return responseOrNewPromise
     *         }
     *         return $q.reject(rejection);
     *       },
     *
     *
     *
     *       // optional method
     *       'response': function(response) {
     *         // do something on success
     *         return response;
     *       },
     *
     *       // optional method
     *      'responseError': function(rejection) {
     *         // do something on error
     *         if (canRecover(rejection)) {
     *           return responseOrNewPromise
     *         }
     *         return $q.reject(rejection);
     *       }
     *     };
     *   });
     *
     *   $httpProvider.interceptors.push('myHttpInterceptor');
     *
     *
     *   // alternatively, register the interceptor via an anonymous factory
     *   $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
     *     return {
     *      'request': function(config) {
     *          // same as above
     *       },
     *
     *       'response': function(response) {
     *          // same as above
     *       }
     *     };
     *   });
     * ```
     *
     * ## Security Considerations
     *
     * When designing web applications, consider security threats from:
     *
     * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
     * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)
     *
     * Both server and the client must cooperate in order to eliminate these threats. Angular comes
     * pre-configured with strategies that address these issues, but for this to work backend server
     * cooperation is required.
     *
     * ### JSON Vulnerability Protection
     *
     * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
     * allows third party website to turn your JSON resource URL into
     * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To
     * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
     * Angular will automatically strip the prefix before processing it as JSON.
     *
     * For example if your server needs to return:
     * ```js
     * ['one','two']
     * ```
     *
     * which is vulnerable to attack, your server can return:
     * ```js
     * )]}',
     * ['one','two']
     * ```
     *
     * Angular will strip the prefix, before processing the JSON.
     *
     *
     * ### Cross Site Request Forgery (XSRF) Protection
     *
     * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is a technique by which
     * an unauthorized site can gain your user's private data. Angular provides a mechanism
     * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
     * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
     * JavaScript that runs on your domain could read the cookie, your server can be assured that
     * the XHR came from JavaScript running on your domain. The header will not be set for
     * cross-domain requests.
     *
     * To take advantage of this, your server needs to set a token in a JavaScript readable session
     * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
     * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
     * that only JavaScript running on your domain could have sent the request. The token must be
     * unique for each user and must be verifiable by the server (to prevent the JavaScript from
     * making up its own tokens). We recommend that the token is a digest of your site's
     * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography&#41;)
     * for added security.
     *
     * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
     * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time,
     * or the per-request config object.
     *
     *
     * @param {object} config Object describing the request to be made and how it should be
     *    processed. The object has following properties:
     *
     *    - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
     *    - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.
     *    - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned
     *      to `?key1=value1&key2=value2` after the url. If the value is not a string, it will be
     *      JSONified.
     *    - **data** – `{string|Object}` – Data to be sent as the request message data.
     *    - **headers** – `{Object}` – Map of strings or functions which return strings representing
     *      HTTP headers to send to the server. If the return value of a function is null, the
     *      header will not be sent.
     *    - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
     *    - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
     *    - **transformRequest** –
     *      `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
     *      transform function or an array of such functions. The transform function takes the http
     *      request body and headers and returns its transformed (typically serialized) version.
     *      See {@link ng.$http#overriding-the-default-transformations-per-request
     *      Overriding the Default Transformations}
     *    - **transformResponse** –
     *      `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
     *      transform function or an array of such functions. The transform function takes the http
     *      response body, headers and status and returns its transformed (typically deserialized) version.
     *      See {@link ng.$http#overriding-the-default-transformations-per-request
     *      Overriding the Default Transformations}
     *    - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
     *      GET request, otherwise if a cache instance built with
     *      {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
     *      caching.
     *    - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
     *      that should abort the request when resolved.
     *    - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
     *      XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)
     *      for more information.
     *    - **responseType** - `{string}` - see
     *      [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
     *
     * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
     *   standard `then` method and two http specific methods: `success` and `error`. The `then`
     *   method takes two arguments a success and an error callback which will be called with a
     *   response object. The `success` and `error` methods take a single argument - a function that
     *   will be called when the request succeeds or fails respectively. The arguments passed into
     *   these functions are destructured representation of the response object passed into the
     *   `then` method. The response object has these properties:
     *
     *   - **data** – `{string|Object}` – The response body transformed with the transform
     *     functions.
     *   - **status** – `{number}` – HTTP status code of the response.
     *   - **headers** – `{function([headerName])}` – Header getter function.
     *   - **config** – `{Object}` – The configuration object that was used to generate the request.
     *   - **statusText** – `{string}` – HTTP status text of the response.
     *
     * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
     *   requests. This is primarily meant to be used for debugging purposes.
     *
     *
     * @example
<example module="httpExample">
<file name="index.html">
  <div ng-controller="FetchController">
    <select ng-model="method">
      <option>GET</option>
      <option>JSONP</option>
    </select>
    <input type="text" ng-model="url" size="80"/>
    <button id="fetchbtn" ng-click="fetch()">fetch</button><br>
    <button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
    <button id="samplejsonpbtn"
      ng-click="updateModel('JSONP',
                    'https://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
      Sample JSONP
    </button>
    <button id="invalidjsonpbtn"
      ng-click="updateModel('JSONP', 'https://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
        Invalid JSONP
      </button>
    <pre>http status code: {{status}}</pre>
    <pre>http response data: {{data}}</pre>
  </div>
</file>
<file name="script.js">
  angular.module('httpExample', [])
    .controller('FetchController', ['$scope', '$http', '$templateCache',
      function($scope, $http, $templateCache) {
        $scope.method = 'GET';
        $scope.url = 'http-hello.html';

        $scope.fetch = function() {
          $scope.code = null;
          $scope.response = null;

          $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
            success(function(data, status) {
              $scope.status = status;
              $scope.data = data;
            }).
            error(function(data, status) {
              $scope.data = data || "Request failed";
              $scope.status = status;
          });
        };

        $scope.updateModel = function(method, url) {
          $scope.method = method;
          $scope.url = url;
        };
      }]);
</file>
<file name="http-hello.html">
  Hello, $http!
</file>
<file name="protractor.js" type="protractor">
  var status = element(by.binding('status'));
  var data = element(by.binding('data'));
  var fetchBtn = element(by.id('fetchbtn'));
  var sampleGetBtn = element(by.id('samplegetbtn'));
  var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
  var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));

  it('should make an xhr GET request', function() {
    sampleGetBtn.click();
    fetchBtn.click();
    expect(status.getText()).toMatch('200');
    expect(data.getText()).toMatch(/Hello, \$http!/);
  });

// Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185
// it('should make a JSONP request to angularjs.org', function() {
//   sampleJsonpBtn.click();
//   fetchBtn.click();
//   expect(status.getText()).toMatch('200');
//   expect(data.getText()).toMatch(/Super Hero!/);
// });

  it('should make JSONP request to invalid URL and invoke the error handler',
      function() {
    invalidJsonpBtn.click();
    fetchBtn.click();
    expect(status.getText()).toMatch('0');
    expect(data.getText()).toMatch('Request failed');
  });
</file>
</example>
     */
    function $http(requestConfig) {

      if (!angular.isObject(requestConfig)) {
        throw minErr('$http')('badreq', 'Http request configuration must be an object.  Received: {0}', requestConfig);
      }

      var config = extend({
        method: 'get',
        transformRequest: defaults.transformRequest,
        transformResponse: defaults.transformResponse
      }, requestConfig);

      config.headers = mergeHeaders(requestConfig);
      config.method = uppercase(config.method);

      var serverRequest = function(config) {
        var headers = config.headers;
        var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);

        // strip content-type if data is undefined
        if (isUndefined(reqData)) {
          forEach(headers, function(value, header) {
            if (lowercase(header) === 'content-type') {
                delete headers[header];
            }
          });
        }

        if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
          config.withCredentials = defaults.withCredentials;
        }

        // send request
        return sendReq(config, reqData).then(transformResponse, transformResponse);
      };

      var chain = [serverRequest, undefined];
      var promise = $q.when(config);

      // apply interceptors
      forEach(reversedInterceptors, function(interceptor) {
        if (interceptor.request || interceptor.requestError) {
          chain.unshift(interceptor.request, interceptor.requestError);
        }
        if (interceptor.response || interceptor.responseError) {
          chain.push(interceptor.response, interceptor.responseError);
        }
      });

      while (chain.length) {
        var thenFn = chain.shift();
        var rejectFn = chain.shift();

        promise = promise.then(thenFn, rejectFn);
      }

      promise.success = function(fn) {
        assertArgFn(fn, 'fn');

        promise.then(function(response) {
          fn(response.data, response.status, response.headers, config);
        });
        return promise;
      };

      promise.error = function(fn) {
        assertArgFn(fn, 'fn');

        promise.then(null, function(response) {
          fn(response.data, response.status, response.headers, config);
        });
        return promise;
      };

      return promise;

      function transformResponse(response) {
        // make a copy since the response must be cacheable
        var resp = extend({}, response);
        if (!response.data) {
          resp.data = response.data;
        } else {
          resp.data = transformData(response.data, response.headers, response.status, config.transformResponse);
        }
        return (isSuccess(response.status))
          ? resp
          : $q.reject(resp);
      }

      function executeHeaderFns(headers) {
        var headerContent, processedHeaders = {};

        forEach(headers, function(headerFn, header) {
          if (isFunction(headerFn)) {
            headerContent = headerFn();
            if (headerContent != null) {
              processedHeaders[header] = headerContent;
            }
          } else {
            processedHeaders[header] = headerFn;
          }
        });

        return processedHeaders;
      }

      function mergeHeaders(config) {
        var defHeaders = defaults.headers,
            reqHeaders = extend({}, config.headers),
            defHeaderName, lowercaseDefHeaderName, reqHeaderName;

        defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);

        // using for-in instead of forEach to avoid unecessary iteration after header has been found
        defaultHeadersIteration:
        for (defHeaderName in defHeaders) {
          lowercaseDefHeaderName = lowercase(defHeaderName);

          for (reqHeaderName in reqHeaders) {
            if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
              continue defaultHeadersIteration;
            }
          }

          reqHeaders[defHeaderName] = defHeaders[defHeaderName];
        }

        // execute if header value is a function for merged headers
        return executeHeaderFns(reqHeaders);
      }
    }

    $http.pendingRequests = [];

    /**
     * @ngdoc method
     * @name $http#get
     *
     * @description
     * Shortcut method to perform `GET` request.
     *
     * @param {string} url Relative or absolute URL specifying the destination of the request
     * @param {Object=} config Optional configuration object
     * @returns {HttpPromise} Future object
     */

    /**
     * @ngdoc method
     * @name $http#delete
     *
     * @description
     * Shortcut method to perform `DELETE` request.
     *
     * @param {string} url Relative or absolute URL specifying the destination of the request
     * @param {Object=} config Optional configuration object
     * @returns {HttpPromise} Future object
     */

    /**
     * @ngdoc method
     * @name $http#head
     *
     * @description
     * Shortcut method to perform `HEAD` request.
     *
     * @param {string} url Relative or absolute URL specifying the destination of the request
     * @param {Object=} config Optional configuration object
     * @returns {HttpPromise} Future object
     */

    /**
     * @ngdoc method
     * @name $http#jsonp
     *
     * @description
     * Shortcut method to perform `JSONP` request.
     *
     * @param {string} url Relative or absolute URL specifying the destination of the request.
     *                     The name of the callback should be the string `JSON_CALLBACK`.
     * @param {Object=} config Optional configuration object
     * @returns {HttpPromise} Future object
     */
    createShortMethods('get', 'delete', 'head', 'jsonp');

    /**
     * @ngdoc method
     * @name $http#post
     *
     * @description
     * Shortcut method to perform `POST` request.
     *
     * @param {string} url Relative or absolute URL specifying the destination of the request
     * @param {*} data Request content
     * @param {Object=} config Optional configuration object
     * @returns {HttpPromise} Future object
     */

    /**
     * @ngdoc method
     * @name $http#put
     *
     * @description
     * Shortcut method to perform `PUT` request.
     *
     * @param {string} url Relative or absolute URL specifying the destination of the request
     * @param {*} data Request content
     * @param {Object=} config Optional configuration object
     * @returns {HttpPromise} Future object
     */

     /**
      * @ngdoc method
      * @name $http#patch
      *
      * @description
      * Shortcut method to perform `PATCH` request.
      *
      * @param {string} url Relative or absolute URL specifying the destination of the request
      * @param {*} data Request content
      * @param {Object=} config Optional configuration object
      * @returns {HttpPromise} Future object
      */
    createShortMethodsWithData('post', 'put', 'patch');

        /**
         * @ngdoc property
         * @name $http#defaults
         *
         * @description
         * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
         * default headers, withCredentials as well as request and response transformations.
         *
         * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
         */
    $http.defaults = defaults;


    return $http;


    function createShortMethods(names) {
      forEach(arguments, function(name) {
        $http[name] = function(url, config) {
          return $http(extend(config || {}, {
            method: name,
            url: url
          }));
        };
      });
    }


    function createShortMethodsWithData(name) {
      forEach(arguments, function(name) {
        $http[name] = function(url, data, config) {
          return $http(extend(config || {}, {
            method: name,
            url: url,
            data: data
          }));
        };
      });
    }


    /**
     * Makes the request.
     *
     * !!! ACCESSES CLOSURE VARS:
     * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
     */
    function sendReq(config, reqData) {
      var deferred = $q.defer(),
          promise = deferred.promise,
          cache,
          cachedResp,
          reqHeaders = config.headers,
          url = buildUrl(config.url, config.params);

      $http.pendingRequests.push(config);
      promise.then(removePendingReq, removePendingReq);


      if ((config.cache || defaults.cache) && config.cache !== false &&
          (config.method === 'GET' || config.method === 'JSONP')) {
        cache = isObject(config.cache) ? config.cache
              : isObject(defaults.cache) ? defaults.cache
              : defaultCache;
      }

      if (cache) {
        cachedResp = cache.get(url);
        if (isDefined(cachedResp)) {
          if (isPromiseLike(cachedResp)) {
            // cached request has already been sent, but there is no response yet
            cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);
          } else {
            // serving from cache
            if (isArray(cachedResp)) {
              resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);
            } else {
              resolvePromise(cachedResp, 200, {}, 'OK');
            }
          }
        } else {
          // put the promise for the non-transformed response into cache as a placeholder
          cache.put(url, promise);
        }
      }


      // if we won't have the response in cache, set the xsrf headers and
      // send the request to the backend
      if (isUndefined(cachedResp)) {
        var xsrfValue = urlIsSameOrigin(config.url)
            ? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
            : undefined;
        if (xsrfValue) {
          reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
        }

        $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
            config.withCredentials, config.responseType);
      }

      return promise;


      /**
       * Callback registered to $httpBackend():
       *  - caches the response if desired
       *  - resolves the raw $http promise
       *  - calls $apply
       */
      function done(status, response, headersString, statusText) {
        if (cache) {
          if (isSuccess(status)) {
            cache.put(url, [status, response, parseHeaders(headersString), statusText]);
          } else {
            // remove promise from the cache
            cache.remove(url);
          }
        }

        function resolveHttpPromise() {
          resolvePromise(response, status, headersString, statusText);
        }

        if (useApplyAsync) {
          $rootScope.$applyAsync(resolveHttpPromise);
        } else {
          resolveHttpPromise();
          if (!$rootScope.$$phase) $rootScope.$apply();
        }
      }


      /**
       * Resolves the raw $http promise.
       */
      function resolvePromise(response, status, headers, statusText) {
        //status: HTTP response status code, 0, -1 (aborted by timeout / promise)
        status = status >= -1 ? status : 0;

        (isSuccess(status) ? deferred.resolve : deferred.reject)({
          data: response,
          status: status,
          headers: headersGetter(headers),
          config: config,
          statusText: statusText
        });
      }

      function resolvePromiseWithResult(result) {
        resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);
      }

      function removePendingReq() {
        var idx = $http.pendingRequests.indexOf(config);
        if (idx !== -1) $http.pendingRequests.splice(idx, 1);
      }
    }


    function buildUrl(url, params) {
      if (!params) return url;
      var parts = [];
      forEachSorted(params, function(value, key) {
        if (value === null || isUndefined(value)) return;
        if (!isArray(value)) value = [value];

        forEach(value, function(v) {
          if (isObject(v)) {
            if (isDate(v)) {
              v = v.toISOString();
            } else {
              v = toJson(v);
            }
          }
          parts.push(encodeUriQuery(key) + '=' +
                     encodeUriQuery(v));
        });
      });
      if (parts.length > 0) {
        url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
      }
      return url;
    }
  }];
}

function createXhr() {
    return new window.XMLHttpRequest();
}

/**
 * @ngdoc service
 * @name $httpBackend
 * @requires $window
 * @requires $document
 *
 * @description
 * HTTP backend used by the {@link ng.$http service} that delegates to
 * XMLHttpRequest object or JSONP and deals with browser incompatibilities.
 *
 * You should never need to use this service directly, instead use the higher-level abstractions:
 * {@link ng.$http $http} or {@link ngResource.$resource $resource}.
 *
 * During testing this implementation is swapped with {@link ngMock.$httpBackend mock
 * $httpBackend} which can be trained with responses.
 */
function $HttpBackendProvider() {
  this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
    return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]);
  }];
}

function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
  // TODO(vojta): fix the signature
  return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
    $browser.$$incOutstandingRequestCount();
    url = url || $browser.url();

    if (lowercase(method) == 'jsonp') {
      var callbackId = '_' + (callbacks.counter++).toString(36);
      callbacks[callbackId] = function(data) {
        callbacks[callbackId].data = data;
        callbacks[callbackId].called = true;
      };

      var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId),
          callbackId, function(status, text) {
        completeRequest(callback, status, callbacks[callbackId].data, "", text);
        callbacks[callbackId] = noop;
      });
    } else {

      var xhr = createXhr();

      xhr.open(method, url, true);
      forEach(headers, function(value, key) {
        if (isDefined(value)) {
            xhr.setRequestHeader(key, value);
        }
      });

      xhr.onload = function requestLoaded() {
        var statusText = xhr.statusText || '';

        // responseText is the old-school way of retrieving response (supported by IE9)
        // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
        var response = ('response' in xhr) ? xhr.response : xhr.responseText;

        // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
        var status = xhr.status === 1223 ? 204 : xhr.status;

        // fix status code when it is 0 (0 status is undocumented).
        // Occurs when accessing file resources or on Android 4.1 stock browser
        // while retrieving files from application cache.
        if (status === 0) {
          status = response ? 200 : urlResolve(url).protocol == 'file' ? 404 : 0;
        }

        completeRequest(callback,
            status,
            response,
            xhr.getAllResponseHeaders(),
            statusText);
      };

      var requestError = function() {
        // The response is always empty
        // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
        completeRequest(callback, -1, null, null, '');
      };

      xhr.onerror = requestError;
      xhr.onabort = requestError;

      if (withCredentials) {
        xhr.withCredentials = true;
      }

      if (responseType) {
        try {
          xhr.responseType = responseType;
        } catch (e) {
          // WebKit added support for the json responseType value on 09/03/2013
          // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
          // known to throw when setting the value "json" as the response type. Other older
          // browsers implementing the responseType
          //
          // The json response type can be ignored if not supported, because JSON payloads are
          // parsed on the client-side regardless.
          if (responseType !== 'json') {
            throw e;
          }
        }
      }

      xhr.send(post || null);
    }

    if (timeout > 0) {
      var timeoutId = $browserDefer(timeoutRequest, timeout);
    } else if (isPromiseLike(timeout)) {
      timeout.then(timeoutRequest);
    }


    function timeoutRequest() {
      jsonpDone && jsonpDone();
      xhr && xhr.abort();
    }

    function completeRequest(callback, status, response, headersString, statusText) {
      // cancel timeout and subsequent timeout promise resolution
      if (timeoutId !== undefined) {
        $browserDefer.cancel(timeoutId);
      }
      jsonpDone = xhr = null;

      callback(status, response, headersString, statusText);
      $browser.$$completeOutstandingRequest(noop);
    }
  };

  function jsonpReq(url, callbackId, done) {
    // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.:
    // - fetches local scripts via XHR and evals them
    // - adds and immediately removes script elements from the document
    var script = rawDocument.createElement('script'), callback = null;
    script.type = "text/javascript";
    script.src = url;
    script.async = true;

    callback = function(event) {
      removeEventListenerFn(script, "load", callback);
      removeEventListenerFn(script, "error", callback);
      rawDocument.body.removeChild(script);
      script = null;
      var status = -1;
      var text = "unknown";

      if (event) {
        if (event.type === "load" && !callbacks[callbackId].called) {
          event = { type: "error" };
        }
        text = event.type;
        status = event.type === "error" ? 404 : 200;
      }

      if (done) {
        done(status, text);
      }
    };

    addEventListenerFn(script, "load", callback);
    addEventListenerFn(script, "error", callback);
    rawDocument.body.appendChild(script);
    return callback;
  }
}

var $interpolateMinErr = minErr('$interpolate');

/**
 * @ngdoc provider
 * @name $interpolateProvider
 *
 * @description
 *
 * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
 *
 * @example
<example module="customInterpolationApp">
<file name="index.html">
<script>
  var customInterpolationApp = angular.module('customInterpolationApp', []);

  customInterpolationApp.config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('//');
    $interpolateProvider.endSymbol('//');
  });


  customInterpolationApp.controller('DemoController', function() {
      this.label = "This binding is brought you by // interpolation symbols.";
  });
</script>
<div ng-app="App" ng-controller="DemoController as demo">
    //demo.label//
</div>
</file>
<file name="protractor.js" type="protractor">
  it('should interpolate binding with custom symbols', function() {
    expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
  });
</file>
</example>
 */
function $InterpolateProvider() {
  var startSymbol = '{{';
  var endSymbol = '}}';

  /**
   * @ngdoc method
   * @name $interpolateProvider#startSymbol
   * @description
   * Symbol to denote start of expression in the interpolated string. Defaults to `{{`.
   *
   * @param {string=} value new value to set the starting symbol to.
   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
   */
  this.startSymbol = function(value) {
    if (value) {
      startSymbol = value;
      return this;
    } else {
      return startSymbol;
    }
  };

  /**
   * @ngdoc method
   * @name $interpolateProvider#endSymbol
   * @description
   * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
   *
   * @param {string=} value new value to set the ending symbol to.
   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
   */
  this.endSymbol = function(value) {
    if (value) {
      endSymbol = value;
      return this;
    } else {
      return endSymbol;
    }
  };


  this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {
    var startSymbolLength = startSymbol.length,
        endSymbolLength = endSymbol.length,
        escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'),
        escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g');

    function escape(ch) {
      return '\\\\\\' + ch;
    }

    /**
     * @ngdoc service
     * @name $interpolate
     * @kind function
     *
     * @requires $parse
     * @requires $sce
     *
     * @description
     *
     * Compiles a string with markup into an interpolation function. This service is used by the
     * HTML {@link ng.$compile $compile} service for data binding. See
     * {@link ng.$interpolateProvider $interpolateProvider} for configuring the
     * interpolation markup.
     *
     *
     * ```js
     *   var $interpolate = ...; // injected
     *   var exp = $interpolate('Hello {{name | uppercase}}!');
     *   expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
     * ```
     *
     * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is
     * `true`, the interpolation function will return `undefined` unless all embedded expressions
     * evaluate to a value other than `undefined`.
     *
     * ```js
     *   var $interpolate = ...; // injected
     *   var context = {greeting: 'Hello', name: undefined };
     *
     *   // default "forgiving" mode
     *   var exp = $interpolate('{{greeting}} {{name}}!');
     *   expect(exp(context)).toEqual('Hello !');
     *
     *   // "allOrNothing" mode
     *   exp = $interpolate('{{greeting}} {{name}}!', false, null, true);
     *   expect(exp(context)).toBeUndefined();
     *   context.name = 'Angular';
     *   expect(exp(context)).toEqual('Hello Angular!');
     * ```
     *
     * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.
     *
     * ####Escaped Interpolation
     * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers
     * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash).
     * It will be rendered as a regular start/end marker, and will not be interpreted as an expression
     * or binding.
     *
     * This enables web-servers to prevent script injection attacks and defacing attacks, to some
     * degree, while also enabling code examples to work without relying on the
     * {@link ng.directive:ngNonBindable ngNonBindable} directive.
     *
     * **For security purposes, it is strongly encouraged that web servers escape user-supplied data,
     * replacing angle brackets (&lt;, &gt;) with &amp;lt; and &amp;gt; respectively, and replacing all
     * interpolation start/end markers with their escaped counterparts.**
     *
     * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered
     * output when the $interpolate service processes the text. So, for HTML elements interpolated
     * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter
     * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such,
     * this is typically useful only when user-data is used in rendering a template from the server, or
     * when otherwise untrusted data is used by a directive.
     *
     * <example>
     *  <file name="index.html">
     *    <div ng-init="username='A user'">
     *      <p ng-init="apptitle='Escaping demo'">{{apptitle}}: \{\{ username = "defaced value"; \}\}
     *        </p>
     *      <p><strong>{{username}}</strong> attempts to inject code which will deface the
     *        application, but fails to accomplish their task, because the server has correctly
     *        escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash)
     *        characters.</p>
     *      <p>Instead, the result of the attempted script injection is visible, and can be removed
     *        from the database by an administrator.</p>
     *    </div>
     *  </file>
     * </example>
     *
     * @param {string} text The text with markup to interpolate.
     * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have
     *    embedded expression in order to return an interpolation function. Strings with no
     *    embedded expression will return null for the interpolation function.
     * @param {string=} trustedContext when provided, the returned function passes the interpolated
     *    result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,
     *    trustedContext)} before returning it.  Refer to the {@link ng.$sce $sce} service that
     *    provides Strict Contextual Escaping for details.
     * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined
     *    unless all embedded expressions evaluate to a value other than `undefined`.
     * @returns {function(context)} an interpolation function which is used to compute the
     *    interpolated string. The function has these parameters:
     *
     * - `context`: evaluation context for all expressions embedded in the interpolated text
     */
    function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
      allOrNothing = !!allOrNothing;
      var startIndex,
          endIndex,
          index = 0,
          expressions = [],
          parseFns = [],
          textLength = text.length,
          exp,
          concat = [],
          expressionPositions = [];

      while (index < textLength) {
        if (((startIndex = text.indexOf(startSymbol, index)) != -1) &&
             ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1)) {
          if (index !== startIndex) {
            concat.push(unescapeText(text.substring(index, startIndex)));
          }
          exp = text.substring(startIndex + startSymbolLength, endIndex);
          expressions.push(exp);
          parseFns.push($parse(exp, parseStringifyInterceptor));
          index = endIndex + endSymbolLength;
          expressionPositions.push(concat.length);
          concat.push('');
        } else {
          // we did not find an interpolation, so we have to add the remainder to the separators array
          if (index !== textLength) {
            concat.push(unescapeText(text.substring(index)));
          }
          break;
        }
      }

      // Concatenating expressions makes it hard to reason about whether some combination of
      // concatenated values are unsafe to use and could easily lead to XSS.  By requiring that a
      // single expression be used for iframe[src], object[src], etc., we ensure that the value
      // that's used is assigned or constructed by some JS code somewhere that is more testable or
      // make it obvious that you bound the value to some user controlled value.  This helps reduce
      // the load when auditing for XSS issues.
      if (trustedContext && concat.length > 1) {
          throw $interpolateMinErr('noconcat',
              "Error while interpolating: {0}\nStrict Contextual Escaping disallows " +
              "interpolations that concatenate multiple expressions when a trusted value is " +
              "required.  See http://docs.angularjs.org/api/ng.$sce", text);
      }

      if (!mustHaveExpression || expressions.length) {
        var compute = function(values) {
          for (var i = 0, ii = expressions.length; i < ii; i++) {
            if (allOrNothing && isUndefined(values[i])) return;
            concat[expressionPositions[i]] = values[i];
          }
          return concat.join('');
        };

        var getValue = function(value) {
          return trustedContext ?
            $sce.getTrusted(trustedContext, value) :
            $sce.valueOf(value);
        };

        var stringify = function(value) {
          if (value == null) { // null || undefined
            return '';
          }
          switch (typeof value) {
            case 'string':
              break;
            case 'number':
              value = '' + value;
              break;
            default:
              value = toJson(value);
          }

          return value;
        };

        return extend(function interpolationFn(context) {
            var i = 0;
            var ii = expressions.length;
            var values = new Array(ii);

            try {
              for (; i < ii; i++) {
                values[i] = parseFns[i](context);
              }

              return compute(values);
            } catch (err) {
              var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
                  err.toString());
              $exceptionHandler(newErr);
            }

          }, {
          // all of these properties are undocumented for now
          exp: text, //just for compatibility with regular watchers created via $watch
          expressions: expressions,
          $$watchDelegate: function(scope, listener, objectEquality) {
            var lastValue;
            return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
              var currValue = compute(values);
              if (isFunction(listener)) {
                listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
              }
              lastValue = currValue;
            }, objectEquality);
          }
        });
      }

      function unescapeText(text) {
        return text.replace(escapedStartRegexp, startSymbol).
          replace(escapedEndRegexp, endSymbol);
      }

      function parseStringifyInterceptor(value) {
        try {
          value = getValue(value);
          return allOrNothing && !isDefined(value) ? value : stringify(value);
        } catch (err) {
          var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
            err.toString());
          $exceptionHandler(newErr);
        }
      }
    }


    /**
     * @ngdoc method
     * @name $interpolate#startSymbol
     * @description
     * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.
     *
     * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change
     * the symbol.
     *
     * @returns {string} start symbol.
     */
    $interpolate.startSymbol = function() {
      return startSymbol;
    };


    /**
     * @ngdoc method
     * @name $interpolate#endSymbol
     * @description
     * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
     *
     * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change
     * the symbol.
     *
     * @returns {string} end symbol.
     */
    $interpolate.endSymbol = function() {
      return endSymbol;
    };

    return $interpolate;
  }];
}

function $IntervalProvider() {
  this.$get = ['$rootScope', '$window', '$q', '$$q',
       function($rootScope,   $window,   $q,   $$q) {
    var intervals = {};


     /**
      * @ngdoc service
      * @name $interval
      *
      * @description
      * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`
      * milliseconds.
      *
      * The return value of registering an interval function is a promise. This promise will be
      * notified upon each tick of the interval, and will be resolved after `count` iterations, or
      * run indefinitely if `count` is not defined. The value of the notification will be the
      * number of iterations that have run.
      * To cancel an interval, call `$interval.cancel(promise)`.
      *
      * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
      * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
      * time.
      *
      * <div class="alert alert-warning">
      * **Note**: Intervals created by this service must be explicitly destroyed when you are finished
      * with them.  In particular they are not automatically destroyed when a controller's scope or a
      * directive's element are destroyed.
      * You should take this into consideration and make sure to always cancel the interval at the
      * appropriate moment.  See the example below for more details on how and when to do this.
      * </div>
      *
      * @param {function()} fn A function that should be called repeatedly.
      * @param {number} delay Number of milliseconds between each function call.
      * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
      *   indefinitely.
      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
      * @returns {promise} A promise which will be notified on each iteration.
      *
      * @example
      * <example module="intervalExample">
      * <file name="index.html">
      *   <script>
      *     angular.module('intervalExample', [])
      *       .controller('ExampleController', ['$scope', '$interval',
      *         function($scope, $interval) {
      *           $scope.format = 'M/d/yy h:mm:ss a';
      *           $scope.blood_1 = 100;
      *           $scope.blood_2 = 120;
      *
      *           var stop;
      *           $scope.fight = function() {
      *             // Don't start a new fight if we are already fighting
      *             if ( angular.isDefined(stop) ) return;
      *
      *             stop = $interval(function() {
      *               if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
      *                 $scope.blood_1 = $scope.blood_1 - 3;
      *                 $scope.blood_2 = $scope.blood_2 - 4;
      *               } else {
      *                 $scope.stopFight();
      *               }
      *             }, 100);
      *           };
      *
      *           $scope.stopFight = function() {
      *             if (angular.isDefined(stop)) {
      *               $interval.cancel(stop);
      *               stop = undefined;
      *             }
      *           };
      *
      *           $scope.resetFight = function() {
      *             $scope.blood_1 = 100;
      *             $scope.blood_2 = 120;
      *           };
      *
      *           $scope.$on('$destroy', function() {
      *             // Make sure that the interval is destroyed too
      *             $scope.stopFight();
      *           });
      *         }])
      *       // Register the 'myCurrentTime' directive factory method.
      *       // We inject $interval and dateFilter service since the factory method is DI.
      *       .directive('myCurrentTime', ['$interval', 'dateFilter',
      *         function($interval, dateFilter) {
      *           // return the directive link function. (compile function not needed)
      *           return function(scope, element, attrs) {
      *             var format,  // date format
      *                 stopTime; // so that we can cancel the time updates
      *
      *             // used to update the UI
      *             function updateTime() {
      *               element.text(dateFilter(new Date(), format));
      *             }
      *
      *             // watch the expression, and update the UI on change.
      *             scope.$watch(attrs.myCurrentTime, function(value) {
      *               format = value;
      *               updateTime();
      *             });
      *
      *             stopTime = $interval(updateTime, 1000);
      *
      *             // listen on DOM destroy (removal) event, and cancel the next UI update
      *             // to prevent updating time after the DOM element was removed.
      *             element.on('$destroy', function() {
      *               $interval.cancel(stopTime);
      *             });
      *           }
      *         }]);
      *   </script>
      *
      *   <div>
      *     <div ng-controller="ExampleController">
      *       Date format: <input ng-model="format"> <hr/>
      *       Current time is: <span my-current-time="format"></span>
      *       <hr/>
      *       Blood 1 : <font color='red'>{{blood_1}}</font>
      *       Blood 2 : <font color='red'>{{blood_2}}</font>
      *       <button type="button" data-ng-click="fight()">Fight</button>
      *       <button type="button" data-ng-click="stopFight()">StopFight</button>
      *       <button type="button" data-ng-click="resetFight()">resetFight</button>
      *     </div>
      *   </div>
      *
      * </file>
      * </example>
      */
    function interval(fn, delay, count, invokeApply) {
      var setInterval = $window.setInterval,
          clearInterval = $window.clearInterval,
          iteration = 0,
          skipApply = (isDefined(invokeApply) && !invokeApply),
          deferred = (skipApply ? $$q : $q).defer(),
          promise = deferred.promise;

      count = isDefined(count) ? count : 0;

      promise.then(null, null, fn);

      promise.$$intervalId = setInterval(function tick() {
        deferred.notify(iteration++);

        if (count > 0 && iteration >= count) {
          deferred.resolve(iteration);
          clearInterval(promise.$$intervalId);
          delete intervals[promise.$$intervalId];
        }

        if (!skipApply) $rootScope.$apply();

      }, delay);

      intervals[promise.$$intervalId] = deferred;

      return promise;
    }


     /**
      * @ngdoc method
      * @name $interval#cancel
      *
      * @description
      * Cancels a task associated with the `promise`.
      *
      * @param {promise} promise returned by the `$interval` function.
      * @returns {boolean} Returns `true` if the task was successfully canceled.
      */
    interval.cancel = function(promise) {
      if (promise && promise.$$intervalId in intervals) {
        intervals[promise.$$intervalId].reject('canceled');
        $window.clearInterval(promise.$$intervalId);
        delete intervals[promise.$$intervalId];
        return true;
      }
      return false;
    };

    return interval;
  }];
}

/**
 * @ngdoc service
 * @name $locale
 *
 * @description
 * $locale service provides localization rules for various Angular components. As of right now the
 * only public api is:
 *
 * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
 */
function $LocaleProvider() {
  this.$get = function() {
    return {
      id: 'en-us',

      NUMBER_FORMATS: {
        DECIMAL_SEP: '.',
        GROUP_SEP: ',',
        PATTERNS: [
          { // Decimal Pattern
            minInt: 1,
            minFrac: 0,
            maxFrac: 3,
            posPre: '',
            posSuf: '',
            negPre: '-',
            negSuf: '',
            gSize: 3,
            lgSize: 3
          },{ //Currency Pattern
            minInt: 1,
            minFrac: 2,
            maxFrac: 2,
            posPre: '\u00A4',
            posSuf: '',
            negPre: '(\u00A4',
            negSuf: ')',
            gSize: 3,
            lgSize: 3
          }
        ],
        CURRENCY_SYM: '$'
      },

      DATETIME_FORMATS: {
        MONTH:
            'January,February,March,April,May,June,July,August,September,October,November,December'
            .split(','),
        SHORTMONTH:  'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','),
        DAY: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','),
        SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','),
        AMPMS: ['AM','PM'],
        medium: 'MMM d, y h:mm:ss a',
        'short': 'M/d/yy h:mm a',
        fullDate: 'EEEE, MMMM d, y',
        longDate: 'MMMM d, y',
        mediumDate: 'MMM d, y',
        shortDate: 'M/d/yy',
        mediumTime: 'h:mm:ss a',
        shortTime: 'h:mm a',
        ERANAMES: [
          "Before Christ",
          "Anno Domini"
        ],
        ERAS: [
          "BC",
          "AD"
        ]
      },

      pluralCat: function(num) {
        if (num === 1) {
          return 'one';
        }
        return 'other';
      }
    };
  };
}

var PATH_MATCH = /^([^\?#]*)(\?([^#]*))?(#(.*))?$/,
    DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
var $locationMinErr = minErr('$location');


/**
 * Encode path using encodeUriSegment, ignoring forward slashes
 *
 * @param {string} path Path to encode
 * @returns {string}
 */
function encodePath(path) {
  var segments = path.split('/'),
      i = segments.length;

  while (i--) {
    segments[i] = encodeUriSegment(segments[i]);
  }

  return segments.join('/');
}

function parseAbsoluteUrl(absoluteUrl, locationObj) {
  var parsedUrl = urlResolve(absoluteUrl);

  locationObj.$$protocol = parsedUrl.protocol;
  locationObj.$$host = parsedUrl.hostname;
  locationObj.$$port = int(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
}


function parseAppUrl(relativeUrl, locationObj) {
  var prefixed = (relativeUrl.charAt(0) !== '/');
  if (prefixed) {
    relativeUrl = '/' + relativeUrl;
  }
  var match = urlResolve(relativeUrl);
  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
      match.pathname.substring(1) : match.pathname);
  locationObj.$$search = parseKeyValue(match.search);
  locationObj.$$hash = decodeURIComponent(match.hash);

  // make sure path starts with '/';
  if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') {
    locationObj.$$path = '/' + locationObj.$$path;
  }
}


/**
 *
 * @param {string} begin
 * @param {string} whole
 * @returns {string} returns text from whole after begin or undefined if it does not begin with
 *                   expected string.
 */
function beginsWith(begin, whole) {
  if (whole.indexOf(begin) === 0) {
    return whole.substr(begin.length);
  }
}


function stripHash(url) {
  var index = url.indexOf('#');
  return index == -1 ? url : url.substr(0, index);
}

function trimEmptyHash(url) {
  return url.replace(/(#.+)|#$/, '$1');
}


function stripFile(url) {
  return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
}

/* return the server only (scheme://host:port) */
function serverBase(url) {
  return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));
}


/**
 * LocationHtml5Url represents an url
 * This object is exposed as $location service when HTML5 mode is enabled and supported
 *
 * @constructor
 * @param {string} appBase application base URL
 * @param {string} appBaseNoFile application base URL stripped of any filename
 * @param {string} basePrefix url path prefix
 */
function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
  this.$$html5 = true;
  basePrefix = basePrefix || '';
  parseAbsoluteUrl(appBase, this);


  /**
   * Parse given html5 (regular) url string into properties
   * @param {string} url HTML5 url
   * @private
   */
  this.$$parse = function(url) {
    var pathUrl = beginsWith(appBaseNoFile, url);
    if (!isString(pathUrl)) {
      throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url,
          appBaseNoFile);
    }

    parseAppUrl(pathUrl, this);

    if (!this.$$path) {
      this.$$path = '/';
    }

    this.$$compose();
  };

  /**
   * Compose url and update `absUrl` property
   * @private
   */
  this.$$compose = function() {
    var search = toKeyValue(this.$$search),
        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';

    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
    this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/'
  };

  this.$$parseLinkUrl = function(url, relHref) {
    if (relHref && relHref[0] === '#') {
      // special case for links to hash fragments:
      // keep the old url and only replace the hash fragment
      this.hash(relHref.slice(1));
      return true;
    }
    var appUrl, prevAppUrl;
    var rewrittenUrl;

    if ((appUrl = beginsWith(appBase, url)) !== undefined) {
      prevAppUrl = appUrl;
      if ((appUrl = beginsWith(basePrefix, appUrl)) !== undefined) {
        rewrittenUrl = appBaseNoFile + (beginsWith('/', appUrl) || appUrl);
      } else {
        rewrittenUrl = appBase + prevAppUrl;
      }
    } else if ((appUrl = beginsWith(appBaseNoFile, url)) !== undefined) {
      rewrittenUrl = appBaseNoFile + appUrl;
    } else if (appBaseNoFile == url + '/') {
      rewrittenUrl = appBaseNoFile;
    }
    if (rewrittenUrl) {
      this.$$parse(rewrittenUrl);
    }
    return !!rewrittenUrl;
  };
}


/**
 * LocationHashbangUrl represents url
 * This object is exposed as $location service when developer doesn't opt into html5 mode.
 * It also serves as the base class for html5 mode fallback on legacy browsers.
 *
 * @constructor
 * @param {string} appBase application base URL
 * @param {string} appBaseNoFile application base URL stripped of any filename
 * @param {string} hashPrefix hashbang prefix
 */
function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {

  parseAbsoluteUrl(appBase, this);


  /**
   * Parse given hashbang url into properties
   * @param {string} url Hashbang url
   * @private
   */
  this.$$parse = function(url) {
    var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url);
    var withoutHashUrl;

    if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') {

      // The rest of the url starts with a hash so we have
      // got either a hashbang path or a plain hash fragment
      withoutHashUrl = beginsWith(hashPrefix, withoutBaseUrl);
      if (isUndefined(withoutHashUrl)) {
        // There was no hashbang prefix so we just have a hash fragment
        withoutHashUrl = withoutBaseUrl;
      }

    } else {
      // There was no hashbang path nor hash fragment:
      // If we are in HTML5 mode we use what is left as the path;
      // Otherwise we ignore what is left
      if (this.$$html5) {
        withoutHashUrl = withoutBaseUrl;
      } else {
        withoutHashUrl = '';
        if (isUndefined(withoutBaseUrl)) {
          appBase = url;
          this.replace();
        }
      }
    }

    parseAppUrl(withoutHashUrl, this);

    this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);

    this.$$compose();

    /*
     * In Windows, on an anchor node on documents loaded from
     * the filesystem, the browser will return a pathname
     * prefixed with the drive name ('/C:/path') when a
     * pathname without a drive is set:
     *  * a.setAttribute('href', '/foo')
     *   * a.pathname === '/C:/foo' //true
     *
     * Inside of Angular, we're always using pathnames that
     * do not include drive names for routing.
     */
    function removeWindowsDriveName(path, url, base) {
      /*
      Matches paths for file protocol on windows,
      such as /C:/foo/bar, and captures only /foo/bar.
      */
      var windowsFilePathExp = /^\/[A-Z]:(\/.*)/;

      var firstPathSegmentMatch;

      //Get the relative path from the input URL.
      if (url.indexOf(base) === 0) {
        url = url.replace(base, '');
      }

      // The input URL intentionally contains a first path segment that ends with a colon.
      if (windowsFilePathExp.exec(url)) {
        return path;
      }

      firstPathSegmentMatch = windowsFilePathExp.exec(path);
      return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
    }
  };

  /**
   * Compose hashbang url and update `absUrl` property
   * @private
   */
  this.$$compose = function() {
    var search = toKeyValue(this.$$search),
        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';

    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
    this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : '');
  };

  this.$$parseLinkUrl = function(url, relHref) {
    if (stripHash(appBase) == stripHash(url)) {
      this.$$parse(url);
      return true;
    }
    return false;
  };
}


/**
 * LocationHashbangUrl represents url
 * This object is exposed as $location service when html5 history api is enabled but the browser
 * does not support it.
 *
 * @constructor
 * @param {string} appBase application base URL
 * @param {string} appBaseNoFile application base URL stripped of any filename
 * @param {string} hashPrefix hashbang prefix
 */
function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {
  this.$$html5 = true;
  LocationHashbangUrl.apply(this, arguments);

  this.$$parseLinkUrl = function(url, relHref) {
    if (relHref && relHref[0] === '#') {
      // special case for links to hash fragments:
      // keep the old url and only replace the hash fragment
      this.hash(relHref.slice(1));
      return true;
    }

    var rewrittenUrl;
    var appUrl;

    if (appBase == stripHash(url)) {
      rewrittenUrl = url;
    } else if ((appUrl = beginsWith(appBaseNoFile, url))) {
      rewrittenUrl = appBase + hashPrefix + appUrl;
    } else if (appBaseNoFile === url + '/') {
      rewrittenUrl = appBaseNoFile;
    }
    if (rewrittenUrl) {
      this.$$parse(rewrittenUrl);
    }
    return !!rewrittenUrl;
  };

  this.$$compose = function() {
    var search = toKeyValue(this.$$search),
        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';

    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
    // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#'
    this.$$absUrl = appBase + hashPrefix + this.$$url;
  };

}


var locationPrototype = {

  /**
   * Are we in html5 mode?
   * @private
   */
  $$html5: false,

  /**
   * Has any change been replacing?
   * @private
   */
  $$replace: false,

  /**
   * @ngdoc method
   * @name $location#absUrl
   *
   * @description
   * This method is getter only.
   *
   * Return full url representation with all segments encoded according to rules specified in
   * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var absUrl = $location.absUrl();
   * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
   * ```
   *
   * @return {string} full url
   */
  absUrl: locationGetter('$$absUrl'),

  /**
   * @ngdoc method
   * @name $location#url
   *
   * @description
   * This method is getter / setter.
   *
   * Return url (e.g. `/path?a=b#hash`) when called without any parameter.
   *
   * Change path, search and hash, when called with parameter and return `$location`.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var url = $location.url();
   * // => "/some/path?foo=bar&baz=xoxo"
   * ```
   *
   * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`)
   * @return {string} url
   */
  url: function(url) {
    if (isUndefined(url))
      return this.$$url;

    var match = PATH_MATCH.exec(url);
    if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
    if (match[2] || match[1] || url === '') this.search(match[3] || '');
    this.hash(match[5] || '');

    return this;
  },

  /**
   * @ngdoc method
   * @name $location#protocol
   *
   * @description
   * This method is getter only.
   *
   * Return protocol of current url.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var protocol = $location.protocol();
   * // => "http"
   * ```
   *
   * @return {string} protocol of current url
   */
  protocol: locationGetter('$$protocol'),

  /**
   * @ngdoc method
   * @name $location#host
   *
   * @description
   * This method is getter only.
   *
   * Return host of current url.
   *
   * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var host = $location.host();
   * // => "example.com"
   *
   * // given url http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
   * host = $location.host();
   * // => "example.com"
   * host = location.host;
   * // => "example.com:8080"
   * ```
   *
   * @return {string} host of current url.
   */
  host: locationGetter('$$host'),

  /**
   * @ngdoc method
   * @name $location#port
   *
   * @description
   * This method is getter only.
   *
   * Return port of current url.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var port = $location.port();
   * // => 80
   * ```
   *
   * @return {Number} port
   */
  port: locationGetter('$$port'),

  /**
   * @ngdoc method
   * @name $location#path
   *
   * @description
   * This method is getter / setter.
   *
   * Return path of current url when called without any parameter.
   *
   * Change path when called with parameter and return `$location`.
   *
   * Note: Path should always begin with forward slash (/), this method will add the forward slash
   * if it is missing.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var path = $location.path();
   * // => "/some/path"
   * ```
   *
   * @param {(string|number)=} path New path
   * @return {string} path
   */
  path: locationGetterSetter('$$path', function(path) {
    path = path !== null ? path.toString() : '';
    return path.charAt(0) == '/' ? path : '/' + path;
  }),

  /**
   * @ngdoc method
   * @name $location#search
   *
   * @description
   * This method is getter / setter.
   *
   * Return search part (as object) of current url when called without any parameter.
   *
   * Change search part when called with parameter and return `$location`.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
   * var searchObject = $location.search();
   * // => {foo: 'bar', baz: 'xoxo'}
   *
   * // set foo to 'yipee'
   * $location.search('foo', 'yipee');
   * // $location.search() => {foo: 'yipee', baz: 'xoxo'}
   * ```
   *
   * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or
   * hash object.
   *
   * When called with a single argument the method acts as a setter, setting the `search` component
   * of `$location` to the specified value.
   *
   * If the argument is a hash object containing an array of values, these values will be encoded
   * as duplicate search parameters in the url.
   *
   * @param {(string|Number|Array<string>|boolean)=} paramValue If `search` is a string or number, then `paramValue`
   * will override only a single search property.
   *
   * If `paramValue` is an array, it will override the property of the `search` component of
   * `$location` specified via the first argument.
   *
   * If `paramValue` is `null`, the property specified via the first argument will be deleted.
   *
   * If `paramValue` is `true`, the property specified via the first argument will be added with no
   * value nor trailing equal sign.
   *
   * @return {Object} If called with no arguments returns the parsed `search` object. If called with
   * one or more arguments returns `$location` object itself.
   */
  search: function(search, paramValue) {
    switch (arguments.length) {
      case 0:
        return this.$$search;
      case 1:
        if (isString(search) || isNumber(search)) {
          search = search.toString();
          this.$$search = parseKeyValue(search);
        } else if (isObject(search)) {
          search = copy(search, {});
          // remove object undefined or null properties
          forEach(search, function(value, key) {
            if (value == null) delete search[key];
          });

          this.$$search = search;
        } else {
          throw $locationMinErr('isrcharg',
              'The first argument of the `$location#search()` call must be a string or an object.');
        }
        break;
      default:
        if (isUndefined(paramValue) || paramValue === null) {
          delete this.$$search[search];
        } else {
          this.$$search[search] = paramValue;
        }
    }

    this.$$compose();
    return this;
  },

  /**
   * @ngdoc method
   * @name $location#hash
   *
   * @description
   * This method is getter / setter.
   *
   * Return hash fragment when called without any parameter.
   *
   * Change hash fragment when called with parameter and return `$location`.
   *
   *
   * ```js
   * // given url http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
   * var hash = $location.hash();
   * // => "hashValue"
   * ```
   *
   * @param {(string|number)=} hash New hash fragment
   * @return {string} hash
   */
  hash: locationGetterSetter('$$hash', function(hash) {
    return hash !== null ? hash.toString() : '';
  }),

  /**
   * @ngdoc method
   * @name $location#replace
   *
   * @description
   * If called, all changes to $location during current `$digest` will be replacing current history
   * record, instead of adding new one.
   */
  replace: function() {
    this.$$replace = true;
    return this;
  }
};

forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {
  Location.prototype = Object.create(locationPrototype);

  /**
   * @ngdoc method
   * @name $location#state
   *
   * @description
   * This method is getter / setter.
   *
   * Return the history state object when called without any parameter.
   *
   * Change the history state object when called with one parameter and return `$location`.
   * The state object is later passed to `pushState` or `replaceState`.
   *
   * NOTE: This method is supported only in HTML5 mode and only in browsers supporting
   * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support
   * older browsers (like IE9 or Android < 4.0), don't use this method.
   *
   * @param {object=} state State object for pushState or replaceState
   * @return {object} state
   */
  Location.prototype.state = function(state) {
    if (!arguments.length)
      return this.$$state;

    if (Location !== LocationHtml5Url || !this.$$html5) {
      throw $locationMinErr('nostate', 'History API state support is available only ' +
        'in HTML5 mode and only in browsers supporting HTML5 History API');
    }
    // The user might modify `stateObject` after invoking `$location.state(stateObject)`
    // but we're changing the $$state reference to $browser.state() during the $digest
    // so the modification window is narrow.
    this.$$state = isUndefined(state) ? null : state;

    return this;
  };
});


function locationGetter(property) {
  return function() {
    return this[property];
  };
}


function locationGetterSetter(property, preprocess) {
  return function(value) {
    if (isUndefined(value))
      return this[property];

    this[property] = preprocess(value);
    this.$$compose();

    return this;
  };
}


/**
 * @ngdoc service
 * @name $location
 *
 * @requires $rootElement
 *
 * @description
 * The $location service parses the URL in the browser address bar (based on the
 * [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL
 * available to your application. Changes to the URL in the address bar are reflected into
 * $location service and changes to $location are reflected into the browser address bar.
 *
 * **The $location service:**
 *
 * - Exposes the current URL in the browser address bar, so you can
 *   - Watch and observe the URL.
 *   - Change the URL.
 * - Synchronizes the URL with the browser when the user
 *   - Changes the address bar.
 *   - Clicks the back or forward button (or clicks a History link).
 *   - Clicks on a link.
 * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
 *
 * For more information see {@link guide/$location Developer Guide: Using $location}
 */

/**
 * @ngdoc provider
 * @name $locationProvider
 * @description
 * Use the `$locationProvider` to configure how the application deep linking paths are stored.
 */
function $LocationProvider() {
  var hashPrefix = '',
      html5Mode = {
        enabled: false,
        requireBase: true,
        rewriteLinks: true
      };

  /**
   * @ngdoc method
   * @name $locationProvider#hashPrefix
   * @description
   * @param {string=} prefix Prefix for hash part (containing path and search)
   * @returns {*} current value if used as getter or itself (chaining) if used as setter
   */
  this.hashPrefix = function(prefix) {
    if (isDefined(prefix)) {
      hashPrefix = prefix;
      return this;
    } else {
      return hashPrefix;
    }
  };

  /**
   * @ngdoc method
   * @name $locationProvider#html5Mode
   * @description
   * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.
   *   If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported
   *   properties:
   *   - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to
   *     change urls where supported. Will fall back to hash-prefixed paths in browsers that do not
   *     support `pushState`.
   *   - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies
   *     whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are
   *     true, and a base tag is not present, an error will be thrown when `$location` is injected.
   *     See the {@link guide/$location $location guide for more information}
   *   - **rewriteLinks** - `{boolean}` - (default: `true`) When html5Mode is enabled,
   *     enables/disables url rewriting for relative links.
   *
   * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
   */
  this.html5Mode = function(mode) {
    if (isBoolean(mode)) {
      html5Mode.enabled = mode;
      return this;
    } else if (isObject(mode)) {

      if (isBoolean(mode.enabled)) {
        html5Mode.enabled = mode.enabled;
      }

      if (isBoolean(mode.requireBase)) {
        html5Mode.requireBase = mode.requireBase;
      }

      if (isBoolean(mode.rewriteLinks)) {
        html5Mode.rewriteLinks = mode.rewriteLinks;
      }

      return this;
    } else {
      return html5Mode;
    }
  };

  /**
   * @ngdoc event
   * @name $location#$locationChangeStart
   * @eventType broadcast on root scope
   * @description
   * Broadcasted before a URL will change.
   *
   * This change can be prevented by calling
   * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more
   * details about event object. Upon successful change
   * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired.
   *
   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
   * the browser supports the HTML5 History API.
   *
   * @param {Object} angularEvent Synthetic event object.
   * @param {string} newUrl New URL
   * @param {string=} oldUrl URL that was before it was changed.
   * @param {string=} newState New history state object
   * @param {string=} oldState History state object that was before it was changed.
   */

  /**
   * @ngdoc event
   * @name $location#$locationChangeSuccess
   * @eventType broadcast on root scope
   * @description
   * Broadcasted after a URL was changed.
   *
   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
   * the browser supports the HTML5 History API.
   *
   * @param {Object} angularEvent Synthetic event object.
   * @param {string} newUrl New URL
   * @param {string=} oldUrl URL that was before it was changed.
   * @param {string=} newState New history state object
   * @param {string=} oldState History state object that was before it was changed.
   */

  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window',
      function($rootScope, $browser, $sniffer, $rootElement, $window) {
    var $location,
        LocationMode,
        baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
        initialUrl = $browser.url(),
        appBase;

    if (html5Mode.enabled) {
      if (!baseHref && html5Mode.requireBase) {
        throw $locationMinErr('nobase',
          "$location in HTML5 mode requires a <base> tag to be present!");
      }
      appBase = serverBase(initialUrl) + (baseHref || '/');
      LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;
    } else {
      appBase = stripHash(initialUrl);
      LocationMode = LocationHashbangUrl;
    }
    var appBaseNoFile = stripFile(appBase);

    $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix);
    $location.$$parseLinkUrl(initialUrl, initialUrl);

    $location.$$state = $browser.state();

    var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;

    function setBrowserUrlWithFallback(url, replace, state) {
      var oldUrl = $location.url();
      var oldState = $location.$$state;
      try {
        $browser.url(url, replace, state);

        // Make sure $location.state() returns referentially identical (not just deeply equal)
        // state object; this makes possible quick checking if the state changed in the digest
        // loop. Checking deep equality would be too expensive.
        $location.$$state = $browser.state();
      } catch (e) {
        // Restore old values if pushState fails
        $location.url(oldUrl);
        $location.$$state = oldState;

        throw e;
      }
    }

    $rootElement.on('click', function(event) {
      // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
      // currently we open nice url link and redirect then

      if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which == 2 || event.button == 2) return;

      var elm = jqLite(event.target);

      // traverse the DOM up to find first A tag
      while (nodeName_(elm[0]) !== 'a') {
        // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
        if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;
      }

      var absHref = elm.prop('href');
      // get the actual href attribute - see
      // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx
      var relHref = elm.attr('href') || elm.attr('xlink:href');

      if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
        // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
        // an animation.
        absHref = urlResolve(absHref.animVal).href;
      }

      // Ignore when url is started with javascript: or mailto:
      if (IGNORE_URI_REGEXP.test(absHref)) return;

      if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) {
        if ($location.$$parseLinkUrl(absHref, relHref)) {
          // We do a preventDefault for all urls that are part of the angular application,
          // in html5mode and also without, so that we are able to abort navigation without
          // getting double entries in the location history.
          event.preventDefault();
          // update location manually
          if ($location.absUrl() != $browser.url()) {
            $rootScope.$apply();
            // hack to work around FF6 bug 684208 when scenario runner clicks on links
            $window.angular['ff-684208-preventDefault'] = true;
          }
        }
      }
    });


    // rewrite hashbang url <> html5 url
    if (trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl)) {
      $browser.url($location.absUrl(), true);
    }

    var initializing = true;

    // update $location when $browser url changes
    $browser.onUrlChange(function(newUrl, newState) {

      if (isUndefined(beginsWith(appBaseNoFile, newUrl))) {
        // If we are navigating outside of the app then force a reload
        $window.location.href = newUrl;
        return;
      }

      $rootScope.$evalAsync(function() {
        var oldUrl = $location.absUrl();
        var oldState = $location.$$state;
        var defaultPrevented;

        $location.$$parse(newUrl);
        $location.$$state = newState;

        defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
            newState, oldState).defaultPrevented;

        // if the location was changed by a `$locationChangeStart` handler then stop
        // processing this location change
        if ($location.absUrl() !== newUrl) return;

        if (defaultPrevented) {
          $location.$$parse(oldUrl);
          $location.$$state = oldState;
          setBrowserUrlWithFallback(oldUrl, false, oldState);
        } else {
          initializing = false;
          afterLocationChange(oldUrl, oldState);
        }
      });
      if (!$rootScope.$$phase) $rootScope.$digest();
    });

    // update browser
    $rootScope.$watch(function $locationWatch() {
      var oldUrl = trimEmptyHash($browser.url());
      var newUrl = trimEmptyHash($location.absUrl());
      var oldState = $browser.state();
      var currentReplace = $location.$$replace;
      var urlOrStateChanged = oldUrl !== newUrl ||
        ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);

      if (initializing || urlOrStateChanged) {
        initializing = false;

        $rootScope.$evalAsync(function() {
          var newUrl = $location.absUrl();
          var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
              $location.$$state, oldState).defaultPrevented;

          // if the location was changed by a `$locationChangeStart` handler then stop
          // processing this location change
          if ($location.absUrl() !== newUrl) return;

          if (defaultPrevented) {
            $location.$$parse(oldUrl);
            $location.$$state = oldState;
          } else {
            if (urlOrStateChanged) {
              setBrowserUrlWithFallback(newUrl, currentReplace,
                                        oldState === $location.$$state ? null : $location.$$state);
            }
            afterLocationChange(oldUrl, oldState);
          }
        });
      }

      $location.$$replace = false;

      // we don't need to return anything because $evalAsync will make the digest loop dirty when
      // there is a change
    });

    return $location;

    function afterLocationChange(oldUrl, oldState) {
      $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl,
        $location.$$state, oldState);
    }
}];
}

/**
 * @ngdoc service
 * @name $log
 * @requires $window
 *
 * @description
 * Simple service for logging. Default implementation safely writes the message
 * into the browser's console (if present).
 *
 * The main purpose of this service is to simplify debugging and troubleshooting.
 *
 * The default is to log `debug` messages. You can use
 * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
 *
 * @example
   <example module="logExample">
     <file name="script.js">
       angular.module('logExample', [])
         .controller('LogController', ['$scope', '$log', function($scope, $log) {
           $scope.$log = $log;
           $scope.message = 'Hello World!';
         }]);
     </file>
     <file name="index.html">
       <div ng-controller="LogController">
         <p>Reload this page with open console, enter text and hit the log button...</p>
         Message:
         <input type="text" ng-model="message"/>
         <button ng-click="$log.log(message)">log</button>
         <button ng-click="$log.warn(message)">warn</button>
         <button ng-click="$log.info(message)">info</button>
         <button ng-click="$log.error(message)">error</button>
         <button ng-click="$log.debug(message)">debug</button>
       </div>
     </file>
   </example>
 */

/**
 * @ngdoc provider
 * @name $logProvider
 * @description
 * Use the `$logProvider` to configure how the application logs messages
 */
function $LogProvider() {
  var debug = true,
      self = this;

  /**
   * @ngdoc method
   * @name $logProvider#debugEnabled
   * @description
   * @param {boolean=} flag enable or disable debug level messages
   * @returns {*} current value if used as getter or itself (chaining) if used as setter
   */
  this.debugEnabled = function(flag) {
    if (isDefined(flag)) {
      debug = flag;
    return this;
    } else {
      return debug;
    }
  };

  this.$get = ['$window', function($window) {
    return {
      /**
       * @ngdoc method
       * @name $log#log
       *
       * @description
       * Write a log message
       */
      log: consoleLog('log'),

      /**
       * @ngdoc method
       * @name $log#info
       *
       * @description
       * Write an information message
       */
      info: consoleLog('info'),

      /**
       * @ngdoc method
       * @name $log#warn
       *
       * @description
       * Write a warning message
       */
      warn: consoleLog('warn'),

      /**
       * @ngdoc method
       * @name $log#error
       *
       * @description
       * Write an error message
       */
      error: consoleLog('error'),

      /**
       * @ngdoc method
       * @name $log#debug
       *
       * @description
       * Write a debug message
       */
      debug: (function() {
        var fn = consoleLog('debug');

        return function() {
          if (debug) {
            fn.apply(self, arguments);
          }
        };
      }())
    };

    function formatError(arg) {
      if (arg instanceof Error) {
        if (arg.stack) {
          arg = (arg.message && arg.stack.indexOf(arg.message) === -1)
              ? 'Error: ' + arg.message + '\n' + arg.stack
              : arg.stack;
        } else if (arg.sourceURL) {
          arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
        }
      }
      return arg;
    }

    function consoleLog(type) {
      var console = $window.console || {},
          logFn = console[type] || console.log || noop,
          hasApply = false;

      // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
      // The reason behind this is that console.log has type "object" in IE8...
      try {
        hasApply = !!logFn.apply;
      } catch (e) {}

      if (hasApply) {
        return function() {
          var args = [];
          forEach(arguments, function(arg) {
            args.push(formatError(arg));
          });
          return logFn.apply(console, args);
        };
      }

      // we are IE which either doesn't have window.console => this is noop and we do nothing,
      // or we are IE where console.log doesn't have apply so we log at least first 2 args
      return function(arg1, arg2) {
        logFn(arg1, arg2 == null ? '' : arg2);
      };
    }
  }];
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *     Any commits to this file should be reviewed with security in mind.  *
 *   Changes to this file can potentially create security vulnerabilities. *
 *          An approval from 2 Core members with history of modifying      *
 *                         this file is required.                          *
 *                                                                         *
 *  Does the change somehow allow for arbitrary javascript to be executed? *
 *    Or allows for someone to change the prototype of built-in objects?   *
 *     Or gives undesired access to variables likes document or window?    *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var $parseMinErr = minErr('$parse');

// Sandboxing Angular Expressions
// ------------------------------
// Angular expressions are generally considered safe because these expressions only have direct
// access to `$scope` and locals. However, one can obtain the ability to execute arbitrary JS code by
// obtaining a reference to native JS functions such as the Function constructor.
//
// As an example, consider the following Angular expression:
//
//   {}.toString.constructor('alert("evil JS code")')
//
// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
// against the expression language, but not to prevent exploits that were enabled by exposing
// sensitive JavaScript or browser APIs on Scope. Exposing such objects on a Scope is never a good
// practice and therefore we are not even trying to protect against interaction with an object
// explicitly exposed in this way.
//
// In general, it is not possible to access a Window object from an angular expression unless a
// window or some DOM object that has a reference to window is published onto a Scope.
// Similarly we prevent invocations of function known to be dangerous, as well as assignments to
// native objects.
//
// See https://docs.angularjs.org/guide/security


function ensureSafeMemberName(name, fullExpression) {
  if (name === "__defineGetter__" || name === "__defineSetter__"
      || name === "__lookupGetter__" || name === "__lookupSetter__"
      || name === "__proto__") {
    throw $parseMinErr('isecfld',
        'Attempting to access a disallowed field in Angular expressions! '
        + 'Expression: {0}', fullExpression);
  }
  return name;
}

function getStringValue(name, fullExpression) {
  // From the JavaScript docs:
  // Property names must be strings. This means that non-string objects cannot be used
  // as keys in an object. Any non-string object, including a number, is typecasted
  // into a string via the toString method.
  //
  // So, to ensure that we are checking the same `name` that JavaScript would use,
  // we cast it to a string, if possible.
  // Doing `name + ''` can cause a repl error if the result to `toString` is not a string,
  // this is, this will handle objects that misbehave.
  name = name + '';
  if (!isString(name)) {
    throw $parseMinErr('iseccst',
        'Cannot convert object to primitive value! '
        + 'Expression: {0}', fullExpression);
  }
  return name;
}

function ensureSafeObject(obj, fullExpression) {
  // nifty check if obj is Function that is fast and works across iframes and other contexts
  if (obj) {
    if (obj.constructor === obj) {
      throw $parseMinErr('isecfn',
          'Referencing Function in Angular expressions is disallowed! Expression: {0}',
          fullExpression);
    } else if (// isWindow(obj)
        obj.window === obj) {
      throw $parseMinErr('isecwindow',
          'Referencing the Window in Angular expressions is disallowed! Expression: {0}',
          fullExpression);
    } else if (// isElement(obj)
        obj.children && (obj.nodeName || (obj.prop && obj.attr && obj.find))) {
      throw $parseMinErr('isecdom',
          'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}',
          fullExpression);
    } else if (// block Object so that we can't get hold of dangerous Object.* methods
        obj === Object) {
      throw $parseMinErr('isecobj',
          'Referencing Object in Angular expressions is disallowed! Expression: {0}',
          fullExpression);
    }
  }
  return obj;
}

var CALL = Function.prototype.call;
var APPLY = Function.prototype.apply;
var BIND = Function.prototype.bind;

function ensureSafeFunction(obj, fullExpression) {
  if (obj) {
    if (obj.constructor === obj) {
      throw $parseMinErr('isecfn',
        'Referencing Function in Angular expressions is disallowed! Expression: {0}',
        fullExpression);
    } else if (obj === CALL || obj === APPLY || obj === BIND) {
      throw $parseMinErr('isecff',
        'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}',
        fullExpression);
    }
  }
}

//Keyword constants
var CONSTANTS = createMap();
forEach({
  'null': function() { return null; },
  'true': function() { return true; },
  'false': function() { return false; },
  'undefined': function() {}
}, function(constantGetter, name) {
  constantGetter.constant = constantGetter.literal = constantGetter.sharedGetter = true;
  CONSTANTS[name] = constantGetter;
});

//Not quite a constant, but can be lex/parsed the same
CONSTANTS['this'] = function(self) { return self; };
CONSTANTS['this'].sharedGetter = true;


//Operators - will be wrapped by binaryFn/unaryFn/assignment/filter
var OPERATORS = extend(createMap(), {
    '+':function(self, locals, a, b) {
      a=a(self, locals); b=b(self, locals);
      if (isDefined(a)) {
        if (isDefined(b)) {
          return a + b;
        }
        return a;
      }
      return isDefined(b) ? b : undefined;},
    '-':function(self, locals, a, b) {
          a=a(self, locals); b=b(self, locals);
          return (isDefined(a) ? a : 0) - (isDefined(b) ? b : 0);
        },
    '*':function(self, locals, a, b) {return a(self, locals) * b(self, locals);},
    '/':function(self, locals, a, b) {return a(self, locals) / b(self, locals);},
    '%':function(self, locals, a, b) {return a(self, locals) % b(self, locals);},
    '===':function(self, locals, a, b) {return a(self, locals) === b(self, locals);},
    '!==':function(self, locals, a, b) {return a(self, locals) !== b(self, locals);},
    '==':function(self, locals, a, b) {return a(self, locals) == b(self, locals);},
    '!=':function(self, locals, a, b) {return a(self, locals) != b(self, locals);},
    '<':function(self, locals, a, b) {return a(self, locals) < b(self, locals);},
    '>':function(self, locals, a, b) {return a(self, locals) > b(self, locals);},
    '<=':function(self, locals, a, b) {return a(self, locals) <= b(self, locals);},
    '>=':function(self, locals, a, b) {return a(self, locals) >= b(self, locals);},
    '&&':function(self, locals, a, b) {return a(self, locals) && b(self, locals);},
    '||':function(self, locals, a, b) {return a(self, locals) || b(self, locals);},
    '!':function(self, locals, a) {return !a(self, locals);},

    //Tokenized as operators but parsed as assignment/filters
    '=':true,
    '|':true
});
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};


/////////////////////////////////////////


/**
 * @constructor
 */
var Lexer = function(options) {
  this.options = options;
};

Lexer.prototype = {
  constructor: Lexer,

  lex: function(text) {
    this.text = text;
    this.index = 0;
    this.tokens = [];

    while (this.index < this.text.length) {
      var ch = this.text.charAt(this.index);
      if (ch === '"' || ch === "'") {
        this.readString(ch);
      } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
        this.readNumber();
      } else if (this.isIdent(ch)) {
        this.readIdent();
      } else if (this.is(ch, '(){}[].,;:?')) {
        this.tokens.push({index: this.index, text: ch});
        this.index++;
      } else if (this.isWhitespace(ch)) {
        this.index++;
      } else {
        var ch2 = ch + this.peek();
        var ch3 = ch2 + this.peek(2);
        var op1 = OPERATORS[ch];
        var op2 = OPERATORS[ch2];
        var op3 = OPERATORS[ch3];
        if (op1 || op2 || op3) {
          var token = op3 ? ch3 : (op2 ? ch2 : ch);
          this.tokens.push({index: this.index, text: token, operator: true});
          this.index += token.length;
        } else {
          this.throwError('Unexpected next character ', this.index, this.index + 1);
        }
      }
    }
    return this.tokens;
  },

  is: function(ch, chars) {
    return chars.indexOf(ch) !== -1;
  },

  peek: function(i) {
    var num = i || 1;
    return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false;
  },

  isNumber: function(ch) {
    return ('0' <= ch && ch <= '9') && typeof ch === "string";
  },

  isWhitespace: function(ch) {
    // IE treats non-breaking space as \u00A0
    return (ch === ' ' || ch === '\r' || ch === '\t' ||
            ch === '\n' || ch === '\v' || ch === '\u00A0');
  },

  isIdent: function(ch) {
    return ('a' <= ch && ch <= 'z' ||
            'A' <= ch && ch <= 'Z' ||
            '_' === ch || ch === '$');
  },

  isExpOperator: function(ch) {
    return (ch === '-' || ch === '+' || this.isNumber(ch));
  },

  throwError: function(error, start, end) {
    end = end || this.index;
    var colStr = (isDefined(start)
            ? 's ' + start +  '-' + this.index + ' [' + this.text.substring(start, end) + ']'
            : ' ' + end);
    throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].',
        error, colStr, this.text);
  },

  readNumber: function() {
    var number = '';
    var start = this.index;
    while (this.index < this.text.length) {
      var ch = lowercase(this.text.charAt(this.index));
      if (ch == '.' || this.isNumber(ch)) {
        number += ch;
      } else {
        var peekCh = this.peek();
        if (ch == 'e' && this.isExpOperator(peekCh)) {
          number += ch;
        } else if (this.isExpOperator(ch) &&
            peekCh && this.isNumber(peekCh) &&
            number.charAt(number.length - 1) == 'e') {
          number += ch;
        } else if (this.isExpOperator(ch) &&
            (!peekCh || !this.isNumber(peekCh)) &&
            number.charAt(number.length - 1) == 'e') {
          this.throwError('Invalid exponent');
        } else {
          break;
        }
      }
      this.index++;
    }
    this.tokens.push({
      index: start,
      text: number,
      constant: true,
      value: Number(number)
    });
  },

  readIdent: function() {
    var start = this.index;
    while (this.index < this.text.length) {
      var ch = this.text.charAt(this.index);
      if (!(this.isIdent(ch) || this.isNumber(ch))) {
        break;
      }
      this.index++;
    }
    this.tokens.push({
      index: start,
      text: this.text.slice(start, this.index),
      identifier: true
    });
  },

  readString: function(quote) {
    var start = this.index;
    this.index++;
    var string = '';
    var rawString = quote;
    var escape = false;
    while (this.index < this.text.length) {
      var ch = this.text.charAt(this.index);
      rawString += ch;
      if (escape) {
        if (ch === 'u') {
          var hex = this.text.substring(this.index + 1, this.index + 5);
          if (!hex.match(/[\da-f]{4}/i))
            this.throwError('Invalid unicode escape [\\u' + hex + ']');
          this.index += 4;
          string += String.fromCharCode(parseInt(hex, 16));
        } else {
          var rep = ESCAPE[ch];
          string = string + (rep || ch);
        }
        escape = false;
      } else if (ch === '\\') {
        escape = true;
      } else if (ch === quote) {
        this.index++;
        this.tokens.push({
          index: start,
          text: rawString,
          constant: true,
          value: string
        });
        return;
      } else {
        string += ch;
      }
      this.index++;
    }
    this.throwError('Unterminated quote', start);
  }
};


function isConstant(exp) {
  return exp.constant;
}

/**
 * @constructor
 */
var Parser = function(lexer, $filter, options) {
  this.lexer = lexer;
  this.$filter = $filter;
  this.options = options;
};

Parser.ZERO = extend(function() {
  return 0;
}, {
  sharedGetter: true,
  constant: true
});

Parser.prototype = {
  constructor: Parser,

  parse: function(text) {
    this.text = text;
    this.tokens = this.lexer.lex(text);

    var value = this.statements();

    if (this.tokens.length !== 0) {
      this.throwError('is an unexpected token', this.tokens[0]);
    }

    value.literal = !!value.literal;
    value.constant = !!value.constant;

    return value;
  },

  primary: function() {
    var primary;
    if (this.expect('(')) {
      primary = this.filterChain();
      this.consume(')');
    } else if (this.expect('[')) {
      primary = this.arrayDeclaration();
    } else if (this.expect('{')) {
      primary = this.object();
    } else if (this.peek().identifier && this.peek().text in CONSTANTS) {
      primary = CONSTANTS[this.consume().text];
    } else if (this.peek().identifier) {
      primary = this.identifier();
    } else if (this.peek().constant) {
      primary = this.constant();
    } else {
      this.throwError('not a primary expression', this.peek());
    }

    var next, context;
    while ((next = this.expect('(', '[', '.'))) {
      if (next.text === '(') {
        primary = this.functionCall(primary, context);
        context = null;
      } else if (next.text === '[') {
        context = primary;
        primary = this.objectIndex(primary);
      } else if (next.text === '.') {
        context = primary;
        primary = this.fieldAccess(primary);
      } else {
        this.throwError('IMPOSSIBLE');
      }
    }
    return primary;
  },

  throwError: function(msg, token) {
    throw $parseMinErr('syntax',
        'Syntax Error: Token \'{0}\' {1} at column {2} of the expression [{3}] starting at [{4}].',
          token.text, msg, (token.index + 1), this.text, this.text.substring(token.index));
  },

  peekToken: function() {
    if (this.tokens.length === 0)
      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
    return this.tokens[0];
  },

  peek: function(e1, e2, e3, e4) {
    return this.peekAhead(0, e1, e2, e3, e4);
  },
  peekAhead: function(i, e1, e2, e3, e4) {
    if (this.tokens.length > i) {
      var token = this.tokens[i];
      var t = token.text;
      if (t === e1 || t === e2 || t === e3 || t === e4 ||
          (!e1 && !e2 && !e3 && !e4)) {
        return token;
      }
    }
    return false;
  },

  expect: function(e1, e2, e3, e4) {
    var token = this.peek(e1, e2, e3, e4);
    if (token) {
      this.tokens.shift();
      return token;
    }
    return false;
  },

  consume: function(e1) {
    if (this.tokens.length === 0) {
      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
    }

    var token = this.expect(e1);
    if (!token) {
      this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
    }
    return token;
  },

  unaryFn: function(op, right) {
    var fn = OPERATORS[op];
    return extend(function $parseUnaryFn(self, locals) {
      return fn(self, locals, right);
    }, {
      constant:right.constant,
      inputs: [right]
    });
  },

  binaryFn: function(left, op, right, isBranching) {
    var fn = OPERATORS[op];
    return extend(function $parseBinaryFn(self, locals) {
      return fn(self, locals, left, right);
    }, {
      constant: left.constant && right.constant,
      inputs: !isBranching && [left, right]
    });
  },

  identifier: function() {
    var id = this.consume().text;

    //Continue reading each `.identifier` unless it is a method invocation
    while (this.peek('.') && this.peekAhead(1).identifier && !this.peekAhead(2, '(')) {
      id += this.consume().text + this.consume().text;
    }

    return getterFn(id, this.options, this.text);
  },

  constant: function() {
    var value = this.consume().value;

    return extend(function $parseConstant() {
      return value;
    }, {
      constant: true,
      literal: true
    });
  },

  statements: function() {
    var statements = [];
    while (true) {
      if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
        statements.push(this.filterChain());
      if (!this.expect(';')) {
        // optimize for the common case where there is only one statement.
        // TODO(size): maybe we should not support multiple statements?
        return (statements.length === 1)
            ? statements[0]
            : function $parseStatements(self, locals) {
                var value;
                for (var i = 0, ii = statements.length; i < ii; i++) {
                  value = statements[i](self, locals);
                }
                return value;
              };
      }
    }
  },

  filterChain: function() {
    var left = this.expression();
    var token;
    while ((token = this.expect('|'))) {
      left = this.filter(left);
    }
    return left;
  },

  filter: function(inputFn) {
    var fn = this.$filter(this.consume().text);
    var argsFn;
    var args;

    if (this.peek(':')) {
      argsFn = [];
      args = []; // we can safely reuse the array
      while (this.expect(':')) {
        argsFn.push(this.expression());
      }
    }

    var inputs = [inputFn].concat(argsFn || []);

    return extend(function $parseFilter(self, locals) {
      var input = inputFn(self, locals);
      if (args) {
        args[0] = input;

        var i = argsFn.length;
        while (i--) {
          args[i + 1] = argsFn[i](self, locals);
        }

        return fn.apply(undefined, args);
      }

      return fn(input);
    }, {
      constant: !fn.$stateful && inputs.every(isConstant),
      inputs: !fn.$stateful && inputs
    });
  },

  expression: function() {
    return this.assignment();
  },

  assignment: function() {
    var left = this.ternary();
    var right;
    var token;
    if ((token = this.expect('='))) {
      if (!left.assign) {
        this.throwError('implies assignment but [' +
            this.text.substring(0, token.index) + '] can not be assigned to', token);
      }
      right = this.ternary();
      return extend(function $parseAssignment(scope, locals) {
        return left.assign(scope, right(scope, locals), locals);
      }, {
        inputs: [left, right]
      });
    }
    return left;
  },

  ternary: function() {
    var left = this.logicalOR();
    var middle;
    var token;
    if ((token = this.expect('?'))) {
      middle = this.assignment();
      if (this.consume(':')) {
        var right = this.assignment();

        return extend(function $parseTernary(self, locals) {
          return left(self, locals) ? middle(self, locals) : right(self, locals);
        }, {
          constant: left.constant && middle.constant && right.constant
        });
      }
    }

    return left;
  },

  logicalOR: function() {
    var left = this.logicalAND();
    var token;
    while ((token = this.expect('||'))) {
      left = this.binaryFn(left, token.text, this.logicalAND(), true);
    }
    return left;
  },

  logicalAND: function() {
    var left = this.equality();
    var token;
    while ((token = this.expect('&&'))) {
      left = this.binaryFn(left, token.text, this.equality(), true);
    }
    return left;
  },

  equality: function() {
    var left = this.relational();
    var token;
    while ((token = this.expect('==','!=','===','!=='))) {
      left = this.binaryFn(left, token.text, this.relational());
    }
    return left;
  },

  relational: function() {
    var left = this.additive();
    var token;
    while ((token = this.expect('<', '>', '<=', '>='))) {
      left = this.binaryFn(left, token.text, this.additive());
    }
    return left;
  },

  additive: function() {
    var left = this.multiplicative();
    var token;
    while ((token = this.expect('+','-'))) {
      left = this.binaryFn(left, token.text, this.multiplicative());
    }
    return left;
  },

  multiplicative: function() {
    var left = this.unary();
    var token;
    while ((token = this.expect('*','/','%'))) {
      left = this.binaryFn(left, token.text, this.unary());
    }
    return left;
  },

  unary: function() {
    var token;
    if (this.expect('+')) {
      return this.primary();
    } else if ((token = this.expect('-'))) {
      return this.binaryFn(Parser.ZERO, token.text, this.unary());
    } else if ((token = this.expect('!'))) {
      return this.unaryFn(token.text, this.unary());
    } else {
      return this.primary();
    }
  },

  fieldAccess: function(object) {
    var getter = this.identifier();

    return extend(function $parseFieldAccess(scope, locals, self) {
      var o = self || object(scope, locals);
      return (o == null) ? undefined : getter(o);
    }, {
      assign: function(scope, value, locals) {
        var o = object(scope, locals);
        if (!o) object.assign(scope, o = {}, locals);
        return getter.assign(o, value);
      }
    });
  },

  objectIndex: function(obj) {
    var expression = this.text;

    var indexFn = this.expression();
    this.consume(']');

    return extend(function $parseObjectIndex(self, locals) {
      var o = obj(self, locals),
          i = getStringValue(indexFn(self, locals), expression),
          v;

      ensureSafeMemberName(i, expression);
      if (!o) return undefined;
      v = ensureSafeObject(o[i], expression);
      return v;
    }, {
      assign: function(self, value, locals) {
        var key = ensureSafeMemberName(getStringValue(indexFn(self, locals), expression), expression);
        // prevent overwriting of Function.constructor which would break ensureSafeObject check
        var o = ensureSafeObject(obj(self, locals), expression);
        if (!o) obj.assign(self, o = {}, locals);
        return o[key] = value;
      }
    });
  },

  functionCall: function(fnGetter, contextGetter) {
    var argsFn = [];
    if (this.peekToken().text !== ')') {
      do {
        argsFn.push(this.expression());
      } while (this.expect(','));
    }
    this.consume(')');

    var expressionText = this.text;
    // we can safely reuse the array across invocations
    var args = argsFn.length ? [] : null;

    return function $parseFunctionCall(scope, locals) {
      var context = contextGetter ? contextGetter(scope, locals) : isDefined(contextGetter) ? undefined : scope;
      var fn = fnGetter(scope, locals, context) || noop;

      if (args) {
        var i = argsFn.length;
        while (i--) {
          args[i] = ensureSafeObject(argsFn[i](scope, locals), expressionText);
        }
      }

      ensureSafeObject(context, expressionText);
      ensureSafeFunction(fn, expressionText);

      // IE doesn't have apply for some native functions
      var v = fn.apply
            ? fn.apply(context, args)
            : fn(args[0], args[1], args[2], args[3], args[4]);

      if (args) {
        // Free-up the memory (arguments of the last function call).
        args.length = 0;
      }

      return ensureSafeObject(v, expressionText);
      };
  },

  // This is used with json array declaration
  arrayDeclaration: function() {
    var elementFns = [];
    if (this.peekToken().text !== ']') {
      do {
        if (this.peek(']')) {
          // Support trailing commas per ES5.1.
          break;
        }
        elementFns.push(this.expression());
      } while (this.expect(','));
    }
    this.consume(']');

    return extend(function $parseArrayLiteral(self, locals) {
      var array = [];
      for (var i = 0, ii = elementFns.length; i < ii; i++) {
        array.push(elementFns[i](self, locals));
      }
      return array;
    }, {
      literal: true,
      constant: elementFns.every(isConstant),
      inputs: elementFns
    });
  },

  object: function() {
    var keys = [], valueFns = [];
    if (this.peekToken().text !== '}') {
      do {
        if (this.peek('}')) {
          // Support trailing commas per ES5.1.
          break;
        }
        var token = this.consume();
        if (token.constant) {
          keys.push(token.value);
        } else if (token.identifier) {
          keys.push(token.text);
        } else {
          this.throwError("invalid key", token);
        }
        this.consume(':');
        valueFns.push(this.expression());
      } while (this.expect(','));
    }
    this.consume('}');

    return extend(function $parseObjectLiteral(self, locals) {
      var object = {};
      for (var i = 0, ii = valueFns.length; i < ii; i++) {
        object[keys[i]] = valueFns[i](self, locals);
      }
      return object;
    }, {
      literal: true,
      constant: valueFns.every(isConstant),
      inputs: valueFns
    });
  }
};


//////////////////////////////////////////////////
// Parser helper functions
//////////////////////////////////////////////////

function setter(obj, locals, path, setValue, fullExp) {
  ensureSafeObject(obj, fullExp);
  ensureSafeObject(locals, fullExp);

  var element = path.split('.'), key;
  for (var i = 0; element.length > 1; i++) {
    key = ensureSafeMemberName(element.shift(), fullExp);
    var propertyObj = (i === 0 && locals && locals[key]) || obj[key];
    if (!propertyObj) {
      propertyObj = {};
      obj[key] = propertyObj;
    }
    obj = ensureSafeObject(propertyObj, fullExp);
  }
  key = ensureSafeMemberName(element.shift(), fullExp);
  ensureSafeObject(obj[key], fullExp);
  obj[key] = setValue;
  return setValue;
}

var getterFnCacheDefault = createMap();
var getterFnCacheExpensive = createMap();

function isPossiblyDangerousMemberName(name) {
  return name == 'constructor';
}

/**
 * Implementation of the "Black Hole" variant from:
 * - http://jsperf.com/angularjs-parse-getter/4
 * - http://jsperf.com/path-evaluation-simplified/7
 */
function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, expensiveChecks) {
  ensureSafeMemberName(key0, fullExp);
  ensureSafeMemberName(key1, fullExp);
  ensureSafeMemberName(key2, fullExp);
  ensureSafeMemberName(key3, fullExp);
  ensureSafeMemberName(key4, fullExp);
  var eso = function(o) {
    return ensureSafeObject(o, fullExp);
  };
  var eso0 = (expensiveChecks || isPossiblyDangerousMemberName(key0)) ? eso : identity;
  var eso1 = (expensiveChecks || isPossiblyDangerousMemberName(key1)) ? eso : identity;
  var eso2 = (expensiveChecks || isPossiblyDangerousMemberName(key2)) ? eso : identity;
  var eso3 = (expensiveChecks || isPossiblyDangerousMemberName(key3)) ? eso : identity;
  var eso4 = (expensiveChecks || isPossiblyDangerousMemberName(key4)) ? eso : identity;

  return function cspSafeGetter(scope, locals) {
    var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope;

    if (pathVal == null) return pathVal;
    pathVal = eso0(pathVal[key0]);

    if (!key1) return pathVal;
    if (pathVal == null) return undefined;
    pathVal = eso1(pathVal[key1]);

    if (!key2) return pathVal;
    if (pathVal == null) return undefined;
    pathVal = eso2(pathVal[key2]);

    if (!key3) return pathVal;
    if (pathVal == null) return undefined;
    pathVal = eso3(pathVal[key3]);

    if (!key4) return pathVal;
    if (pathVal == null) return undefined;
    pathVal = eso4(pathVal[key4]);

    return pathVal;
  };
}

function getterFnWithEnsureSafeObject(fn, fullExpression) {
  return function(s, l) {
    return fn(s, l, ensureSafeObject, fullExpression);
  };
}

function getterFn(path, options, fullExp) {
  var expensiveChecks = options.expensiveChecks;
  var getterFnCache = (expensiveChecks ? getterFnCacheExpensive : getterFnCacheDefault);
  var fn = getterFnCache[path];
  if (fn) return fn;


  var pathKeys = path.split('.'),
      pathKeysLength = pathKeys.length;

  // http://jsperf.com/angularjs-parse-getter/6
  if (options.csp) {
    if (pathKeysLength < 6) {
      fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, expensiveChecks);
    } else {
      fn = function cspSafeGetter(scope, locals) {
        var i = 0, val;
        do {
          val = cspSafeGetterFn(pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++],
                                pathKeys[i++], fullExp, expensiveChecks)(scope, locals);

          locals = undefined; // clear after first iteration
          scope = val;
        } while (i < pathKeysLength);
        return val;
      };
    }
  } else {
    var code = '';
    if (expensiveChecks) {
      code += 's = eso(s, fe);\nl = eso(l, fe);\n';
    }
    var needsEnsureSafeObject = expensiveChecks;
    forEach(pathKeys, function(key, index) {
      ensureSafeMemberName(key, fullExp);
      var lookupJs = (index
                      // we simply dereference 's' on any .dot notation
                      ? 's'
                      // but if we are first then we check locals first, and if so read it first
                      : '((l&&l.hasOwnProperty("' + key + '"))?l:s)') + '.' + key;
      if (expensiveChecks || isPossiblyDangerousMemberName(key)) {
        lookupJs = 'eso(' + lookupJs + ', fe)';
        needsEnsureSafeObject = true;
      }
      code += 'if(s == null) return undefined;\n' +
              's=' + lookupJs + ';\n';
    });
    code += 'return s;';

    /* jshint -W054 */
    var evaledFnGetter = new Function('s', 'l', 'eso', 'fe', code); // s=scope, l=locals, eso=ensureSafeObject
    /* jshint +W054 */
    evaledFnGetter.toString = valueFn(code);
    if (needsEnsureSafeObject) {
      evaledFnGetter = getterFnWithEnsureSafeObject(evaledFnGetter, fullExp);
    }
    fn = evaledFnGetter;
  }

  fn.sharedGetter = true;
  fn.assign = function(self, value, locals) {
    return setter(self, locals, path, value, path);
  };
  getterFnCache[path] = fn;
  return fn;
}

var objectValueOf = Object.prototype.valueOf;

function getValueOf(value) {
  return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
}

///////////////////////////////////

/**
 * @ngdoc service
 * @name $parse
 * @kind function
 *
 * @description
 *
 * Converts Angular {@link guide/expression expression} into a function.
 *
 * ```js
 *   var getter = $parse('user.name');
 *   var setter = getter.assign;
 *   var context = {user:{name:'angular'}};
 *   var locals = {user:{name:'local'}};
 *
 *   expect(getter(context)).toEqual('angular');
 *   setter(context, 'newValue');
 *   expect(context.user.name).toEqual('newValue');
 *   expect(getter(context, locals)).toEqual('local');
 * ```
 *
 *
 * @param {string} expression String expression to compile.
 * @returns {function(context, locals)} a function which represents the compiled expression:
 *
 *    * `context` – `{object}` – an object against which any expressions embedded in the strings
 *      are evaluated against (typically a scope object).
 *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
 *      `context`.
 *
 *    The returned function also has the following properties:
 *      * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
 *        literal.
 *      * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
 *        constant literals.
 *      * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
 *        set to a function to change its value on the given context.
 *
 */


/**
 * @ngdoc provider
 * @name $parseProvider
 *
 * @description
 * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}
 *  service.
 */
function $ParseProvider() {
  var cacheDefault = createMap();
  var cacheExpensive = createMap();



  this.$get = ['$filter', '$sniffer', function($filter, $sniffer) {
    var $parseOptions = {
          csp: $sniffer.csp,
          expensiveChecks: false
        },
        $parseOptionsExpensive = {
          csp: $sniffer.csp,
          expensiveChecks: true
        };

    function wrapSharedExpression(exp) {
      var wrapped = exp;

      if (exp.sharedGetter) {
        wrapped = function $parseWrapper(self, locals) {
          return exp(self, locals);
        };
        wrapped.literal = exp.literal;
        wrapped.constant = exp.constant;
        wrapped.assign = exp.assign;
      }

      return wrapped;
    }

    return function $parse(exp, interceptorFn, expensiveChecks) {
      var parsedExpression, oneTime, cacheKey;

      switch (typeof exp) {
        case 'string':
          cacheKey = exp = exp.trim();

          var cache = (expensiveChecks ? cacheExpensive : cacheDefault);
          parsedExpression = cache[cacheKey];

          if (!parsedExpression) {
            if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
              oneTime = true;
              exp = exp.substring(2);
            }

            var parseOptions = expensiveChecks ? $parseOptionsExpensive : $parseOptions;
            var lexer = new Lexer(parseOptions);
            var parser = new Parser(lexer, $filter, parseOptions);
            parsedExpression = parser.parse(exp);

            if (parsedExpression.constant) {
              parsedExpression.$$watchDelegate = constantWatchDelegate;
            } else if (oneTime) {
              //oneTime is not part of the exp passed to the Parser so we may have to
              //wrap the parsedExpression before adding a $$watchDelegate
              parsedExpression = wrapSharedExpression(parsedExpression);
              parsedExpression.$$watchDelegate = parsedExpression.literal ?
                oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
            } else if (parsedExpression.inputs) {
              parsedExpression.$$watchDelegate = inputsWatchDelegate;
            }

            cache[cacheKey] = parsedExpression;
          }
          return addInterceptor(parsedExpression, interceptorFn);

        case 'function':
          return addInterceptor(exp, interceptorFn);

        default:
          return addInterceptor(noop, interceptorFn);
      }
    };

    function collectExpressionInputs(inputs, list) {
      for (var i = 0, ii = inputs.length; i < ii; i++) {
        var input = inputs[i];
        if (!input.constant) {
          if (input.inputs) {
            collectExpressionInputs(input.inputs, list);
          } else if (list.indexOf(input) === -1) { // TODO(perf) can we do better?
            list.push(input);
          }
        }
      }

      return list;
    }

    function expressionInputDirtyCheck(newValue, oldValueOfValue) {

      if (newValue == null || oldValueOfValue == null) { // null/undefined
        return newValue === oldValueOfValue;
      }

      if (typeof newValue === 'object') {

        // attempt to convert the value to a primitive type
        // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
        //             be cheaply dirty-checked
        newValue = getValueOf(newValue);

        if (typeof newValue === 'object') {
          // objects/arrays are not supported - deep-watching them would be too expensive
          return false;
        }

        // fall-through to the primitive equality check
      }

      //Primitive or NaN
      return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);
    }

    function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression) {
      var inputExpressions = parsedExpression.$$inputs ||
                    (parsedExpression.$$inputs = collectExpressionInputs(parsedExpression.inputs, []));

      var lastResult;

      if (inputExpressions.length === 1) {
        var oldInputValue = expressionInputDirtyCheck; // init to something unique so that equals check fails
        inputExpressions = inputExpressions[0];
        return scope.$watch(function expressionInputWatch(scope) {
          var newInputValue = inputExpressions(scope);
          if (!expressionInputDirtyCheck(newInputValue, oldInputValue)) {
            lastResult = parsedExpression(scope);
            oldInputValue = newInputValue && getValueOf(newInputValue);
          }
          return lastResult;
        }, listener, objectEquality);
      }

      var oldInputValueOfValues = [];
      for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
        oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails
      }

      return scope.$watch(function expressionInputsWatch(scope) {
        var changed = false;

        for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
          var newInputValue = inputExpressions[i](scope);
          if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) {
            oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
          }
        }

        if (changed) {
          lastResult = parsedExpression(scope);
        }

        return lastResult;
      }, listener, objectEquality);
    }

    function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression) {
      var unwatch, lastValue;
      return unwatch = scope.$watch(function oneTimeWatch(scope) {
        return parsedExpression(scope);
      }, function oneTimeListener(value, old, scope) {
        lastValue = value;
        if (isFunction(listener)) {
          listener.apply(this, arguments);
        }
        if (isDefined(value)) {
          scope.$$postDigest(function() {
            if (isDefined(lastValue)) {
              unwatch();
            }
          });
        }
      }, objectEquality);
    }

    function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {
      var unwatch, lastValue;
      return unwatch = scope.$watch(function oneTimeWatch(scope) {
        return parsedExpression(scope);
      }, function oneTimeListener(value, old, scope) {
        lastValue = value;
        if (isFunction(listener)) {
          listener.call(this, value, old, scope);
        }
        if (isAllDefined(value)) {
          scope.$$postDigest(function() {
            if (isAllDefined(lastValue)) unwatch();
          });
        }
      }, objectEquality);

      function isAllDefined(value) {
        var allDefined = true;
        forEach(value, function(val) {
          if (!isDefined(val)) allDefined = false;
        });
        return allDefined;
      }
    }

    function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {
      var unwatch;
      return unwatch = scope.$watch(function constantWatch(scope) {
        return parsedExpression(scope);
      }, function constantListener(value, old, scope) {
        if (isFunction(listener)) {
          listener.apply(this, arguments);
        }
        unwatch();
      }, objectEquality);
    }

    function addInterceptor(parsedExpression, interceptorFn) {
      if (!interceptorFn) return parsedExpression;
      var watchDelegate = parsedExpression.$$watchDelegate;

      var regularWatch =
          watchDelegate !== oneTimeLiteralWatchDelegate &&
          watchDelegate !== oneTimeWatchDelegate;

      var fn = regularWatch ? function regularInterceptedExpression(scope, locals) {
        var value = parsedExpression(scope, locals);
        return interceptorFn(value, scope, locals);
      } : function oneTimeInterceptedExpression(scope, locals) {
        var value = parsedExpression(scope, locals);
        var result = interceptorFn(value, scope, locals);
        // we only return the interceptor's result if the
        // initial value is defined (for bind-once)
        return isDefined(value) ? result : value;
      };

      // Propagate $$watchDelegates other then inputsWatchDelegate
      if (parsedExpression.$$watchDelegate &&
          parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
        fn.$$watchDelegate = parsedExpression.$$watchDelegate;
      } else if (!interceptorFn.$stateful) {
        // If there is an interceptor, but no watchDelegate then treat the interceptor like
        // we treat filters - it is assumed to be a pure function unless flagged with $stateful
        fn.$$watchDelegate = inputsWatchDelegate;
        fn.inputs = [parsedExpression];
      }

      return fn;
    }
  }];
}

/**
 * @ngdoc service
 * @name $q
 * @requires $rootScope
 *
 * @description
 * A service that helps you run functions asynchronously, and use their return values (or exceptions)
 * when they are done processing.
 *
 * This is an implementation of promises/deferred objects inspired by
 * [Kris Kowal's Q](https://github.com/kriskowal/q).
 *
 * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
 * implementations, and the other which resembles ES6 promises to some degree.
 *
 * # $q constructor
 *
 * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
 * function as the first argument. This is similar to the native Promise implementation from ES6 Harmony,
 * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
 *
 * While the constructor-style use is supported, not all of the supporting methods from ES6 Harmony promises are
 * available yet.
 *
 * It can be used like so:
 *
 * ```js
 *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`
 *   // are available in the current lexical scope (they could have been injected or passed in).
 *
 *   function asyncGreet(name) {
 *     // perform some asynchronous operation, resolve or reject the promise when appropriate.
 *     return $q(function(resolve, reject) {
 *       setTimeout(function() {
 *         if (okToGreet(name)) {
 *           resolve('Hello, ' + name + '!');
 *         } else {
 *           reject('Greeting ' + name + ' is not allowed.');
 *         }
 *       }, 1000);
 *     });
 *   }
 *
 *   var promise = asyncGreet('Robin Hood');
 *   promise.then(function(greeting) {
 *     alert('Success: ' + greeting);
 *   }, function(reason) {
 *     alert('Failed: ' + reason);
 *   });
 * ```
 *
 * Note: progress/notify callbacks are not currently supported via the ES6-style interface.
 *
 * However, the more traditional CommonJS-style usage is still available, and documented below.
 *
 * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an
 * interface for interacting with an object that represents the result of an action that is
 * performed asynchronously, and may or may not be finished at any given point in time.
 *
 * From the perspective of dealing with error handling, deferred and promise APIs are to
 * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
 *
 * ```js
 *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`
 *   // are available in the current lexical scope (they could have been injected or passed in).
 *
 *   function asyncGreet(name) {
 *     var deferred = $q.defer();
 *
 *     setTimeout(function() {
 *       deferred.notify('About to greet ' + name + '.');
 *
 *       if (okToGreet(name)) {
 *         deferred.resolve('Hello, ' + name + '!');
 *       } else {
 *         deferred.reject('Greeting ' + name + ' is not allowed.');
 *       }
 *     }, 1000);
 *
 *     return deferred.promise;
 *   }
 *
 *   var promise = asyncGreet('Robin Hood');
 *   promise.then(function(greeting) {
 *     alert('Success: ' + greeting);
 *   }, function(reason) {
 *     alert('Failed: ' + reason);
 *   }, function(update) {
 *     alert('Got notification: ' + update);
 *   });
 * ```
 *
 * At first it might not be obvious why this extra complexity is worth the trouble. The payoff
 * comes in the way of guarantees that promise and deferred APIs make, see
 * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.
 *
 * Additionally the promise api allows for composition that is very hard to do with the
 * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
 * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the
 * section on serial or parallel joining of promises.
 *
 * # The Deferred API
 *
 * A new instance of deferred is constructed by calling `$q.defer()`.
 *
 * The purpose of the deferred object is to expose the associated Promise instance as well as APIs
 * that can be used for signaling the successful or unsuccessful completion, as well as the status
 * of the task.
 *
 * **Methods**
 *
 * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
 *   constructed via `$q.reject`, the promise will be rejected instead.
 * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
 *   resolving it with a rejection constructed via `$q.reject`.
 * - `notify(value)` - provides updates on the status of the promise's execution. This may be called
 *   multiple times before the promise is either resolved or rejected.
 *
 * **Properties**
 *
 * - promise – `{Promise}` – promise object associated with this deferred.
 *
 *
 * # The Promise API
 *
 * A new promise instance is created when a deferred instance is created and can be retrieved by
 * calling `deferred.promise`.
 *
 * The purpose of the promise object is to allow for interested parties to get access to the result
 * of the deferred task when it completes.
 *
 * **Methods**
 *
 * - `then(successCallback, errorCallback, notifyCallback)` – regardless of when the promise was or
 *   will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously
 *   as soon as the result is available. The callbacks are called with a single argument: the result
 *   or rejection reason. Additionally, the notify callback may be called zero or more times to
 *   provide a progress indication, before the promise is resolved or rejected.
 *
 *   This method *returns a new promise* which is resolved or rejected via the return value of the
 *   `successCallback`, `errorCallback`. It also notifies via the return value of the
 *   `notifyCallback` method. The promise cannot be resolved or rejected from the notifyCallback
 *   method.
 *
 * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
 *
 * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,
 *   but to do so without modifying the final value. This is useful to release resources or do some
 *   clean-up that needs to be done whether the promise was rejected or resolved. See the [full
 *   specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for
 *   more information.
 *
 * # Chaining promises
 *
 * Because calling the `then` method of a promise returns a new derived promise, it is easily
 * possible to create a chain of promises:
 *
 * ```js
 *   promiseB = promiseA.then(function(result) {
 *     return result + 1;
 *   });
 *
 *   // promiseB will be resolved immediately after promiseA is resolved and its value
 *   // will be the result of promiseA incremented by 1
 * ```
 *
 * It is possible to create chains of any length and since a promise can be resolved with another
 * promise (which will defer its resolution further), it is possible to pause/defer resolution of
 * the promises at any point in the chain. This makes it possible to implement powerful APIs like
 * $http's response interceptors.
 *
 *
 * # Differences between Kris Kowal's Q and $q
 *
 *  There are two main differences:
 *
 * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation
 *   mechanism in angular, which means faster propagation of resolution or rejection into your
 *   models and avoiding unnecessary browser repaints, which would result in flickering UI.
 * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
 *   all the important functionality needed for common async tasks.
 *
 *  # Testing
 *
 *  ```js
 *    it('should simulate promise', inject(function($q, $rootScope) {
 *      var deferred = $q.defer();
 *      var promise = deferred.promise;
 *      var resolvedValue;
 *
 *      promise.then(function(value) { resolvedValue = value; });
 *      expect(resolvedValue).toBeUndefined();
 *
 *      // Simulate resolving of promise
 *      deferred.resolve(123);
 *      // Note that the 'then' function does not get called synchronously.
 *      // This is because we want the promise API to always be async, whether or not
 *      // it got called synchronously or asynchronously.
 *      expect(resolvedValue).toBeUndefined();
 *
 *      // Propagate promise resolution to 'then' functions using $apply().
 *      $rootScope.$apply();
 *      expect(resolvedValue).toEqual(123);
 *    }));
 *  ```
 *
 * @param {function(function, function)} resolver Function which is responsible for resolving or
 *   rejecting the newly created promise. The first parameter is a function which resolves the
 *   promise, the second parameter is a function which rejects the promise.
 *
 * @returns {Promise} The newly created promise.
 */
function $QProvider() {

  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
    return qFactory(function(callback) {
      $rootScope.$evalAsync(callback);
    }, $exceptionHandler);
  }];
}

function $$QProvider() {
  this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) {
    return qFactory(function(callback) {
      $browser.defer(callback);
    }, $exceptionHandler);
  }];
}

/**
 * Constructs a promise manager.
 *
 * @param {function(function)} nextTick Function for executing functions in the next turn.
 * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for
 *     debugging purposes.
 * @returns {object} Promise manager.
 */
function qFactory(nextTick, exceptionHandler) {
  var $qMinErr = minErr('$q', TypeError);
  function callOnce(self, resolveFn, rejectFn) {
    var called = false;
    function wrap(fn) {
      return function(value) {
        if (called) return;
        called = true;
        fn.call(self, value);
      };
    }

    return [wrap(resolveFn), wrap(rejectFn)];
  }

  /**
   * @ngdoc method
   * @name ng.$q#defer
   * @kind function
   *
   * @description
   * Creates a `Deferred` object which represents a task which will finish in the future.
   *
   * @returns {Deferred} Returns a new instance of deferred.
   */
  var defer = function() {
    return new Deferred();
  };

  function Promise() {
    this.$$state = { status: 0 };
  }

  Promise.prototype = {
    then: function(onFulfilled, onRejected, progressBack) {
      var result = new Deferred();

      this.$$state.pending = this.$$state.pending || [];
      this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
      if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);

      return result.promise;
    },

    "catch": function(callback) {
      return this.then(null, callback);
    },

    "finally": function(callback, progressBack) {
      return this.then(function(value) {
        return handleCallback(value, true, callback);
      }, function(error) {
        return handleCallback(error, false, callback);
      }, progressBack);
    }
  };

  //Faster, more basic than angular.bind http://jsperf.com/angular-bind-vs-custom-vs-native
  function simpleBind(context, fn) {
    return function(value) {
      fn.call(context, value);
    };
  }

  function processQueue(state) {
    var fn, promise, pending;

    pending = state.pending;
    state.processScheduled = false;
    state.pending = undefined;
    for (var i = 0, ii = pending.length; i < ii; ++i) {
      promise = pending[i][0];
      fn = pending[i][state.status];
      try {
        if (isFunction(fn)) {
          promise.resolve(fn(state.value));
        } else if (state.status === 1) {
          promise.resolve(state.value);
        } else {
          promise.reject(state.value);
        }
      } catch (e) {
        promise.reject(e);
        exceptionHandler(e);
      }
    }
  }

  function scheduleProcessQueue(state) {
    if (state.processScheduled || !state.pending) return;
    state.processScheduled = true;
    nextTick(function() { processQueue(state); });
  }

  function Deferred() {
    this.promise = new Promise();
    //Necessary to support unbound execution :/
    this.resolve = simpleBind(this, this.resolve);
    this.reject = simpleBind(this, this.reject);
    this.notify = simpleBind(this, this.notify);
  }

  Deferred.prototype = {
    resolve: function(val) {
      if (this.promise.$$state.status) return;
      if (val === this.promise) {
        this.$$reject($qMinErr(
          'qcycle',
          "Expected promise to be resolved with value other than itself '{0}'",
          val));
      } else {
        this.$$resolve(val);
      }

    },

    $$resolve: function(val) {
      var then, fns;

      fns = callOnce(this, this.$$resolve, this.$$reject);
      try {
        if ((isObject(val) || isFunction(val))) then = val && val.then;
        if (isFunction(then)) {
          this.promise.$$state.status = -1;
          then.call(val, fns[0], fns[1], this.notify);
        } else {
          this.promise.$$state.value = val;
          this.promise.$$state.status = 1;
          scheduleProcessQueue(this.promise.$$state);
        }
      } catch (e) {
        fns[1](e);
        exceptionHandler(e);
      }
    },

    reject: function(reason) {
      if (this.promise.$$state.status) return;
      this.$$reject(reason);
    },

    $$reject: function(reason) {
      this.promise.$$state.value = reason;
      this.promise.$$state.status = 2;
      scheduleProcessQueue(this.promise.$$state);
    },

    notify: function(progress) {
      var callbacks = this.promise.$$state.pending;

      if ((this.promise.$$state.status <= 0) && callbacks && callbacks.length) {
        nextTick(function() {
          var callback, result;
          for (var i = 0, ii = callbacks.length; i < ii; i++) {
            result = callbacks[i][0];
            callback = callbacks[i][3];
            try {
              result.notify(isFunction(callback) ? callback(progress) : progress);
            } catch (e) {
              exceptionHandler(e);
            }
          }
        });
      }
    }
  };

  /**
   * @ngdoc method
   * @name $q#reject
   * @kind function
   *
   * @description
   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
   * used to forward rejection in a chain of promises. If you are dealing with the last promise in
   * a promise chain, you don't need to worry about it.
   *
   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
   * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
   * a promise error callback and you want to forward the error to the promise derived from the
   * current promise, you have to "rethrow" the error by returning a rejection constructed via
   * `reject`.
   *
   * ```js
   *   promiseB = promiseA.then(function(result) {
   *     // success: do something and resolve promiseB
   *     //          with the old or a new result
   *     return result;
   *   }, function(reason) {
   *     // error: handle the error if possible and
   *     //        resolve promiseB with newPromiseOrValue,
   *     //        otherwise forward the rejection to promiseB
   *     if (canHandle(reason)) {
   *      // handle the error and recover
   *      return newPromiseOrValue;
   *     }
   *     return $q.reject(reason);
   *   });
   * ```
   *
   * @param {*} reason Constant, message, exception or an object representing the rejection reason.
   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
   */
  var reject = function(reason) {
    var result = new Deferred();
    result.reject(reason);
    return result.promise;
  };

  var makePromise = function makePromise(value, resolved) {
    var result = new Deferred();
    if (resolved) {
      result.resolve(value);
    } else {
      result.reject(value);
    }
    return result.promise;
  };

  var handleCallback = function handleCallback(value, isResolved, callback) {
    var callbackOutput = null;
    try {
      if (isFunction(callback)) callbackOutput = callback();
    } catch (e) {
      return makePromise(e, false);
    }
    if (isPromiseLike(callbackOutput)) {
      return callbackOutput.then(function() {
        return makePromise(value, isResolved);
      }, function(error) {
        return makePromise(error, false);
      });
    } else {
      return makePromise(value, isResolved);
    }
  };

  /**
   * @ngdoc method
   * @name $q#when
   * @kind function
   *
   * @description
   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
   * This is useful when you are dealing with an object that might or might not be a promise, or if
   * the promise comes from a source that can't be trusted.
   *
   * @param {*} value Value or a promise
   * @returns {Promise} Returns a promise of the passed value or promise
   */


  var when = function(value, callback, errback, progressBack) {
    var result = new Deferred();
    result.resolve(value);
    return result.promise.then(callback, errback, progressBack);
  };

  /**
   * @ngdoc method
   * @name $q#all
   * @kind function
   *
   * @description
   * Combines multiple promises into a single promise that is resolved when all of the input
   * promises are resolved.
   *
   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
   * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,
   *   each value corresponding to the promise at the same index/key in the `promises` array/hash.
   *   If any of the promises is resolved with a rejection, this resulting promise will be rejected
   *   with the same rejection value.
   */

  function all(promises) {
    var deferred = new Deferred(),
        counter = 0,
        results = isArray(promises) ? [] : {};

    forEach(promises, function(promise, key) {
      counter++;
      when(promise).then(function(value) {
        if (results.hasOwnProperty(key)) return;
        results[key] = value;
        if (!(--counter)) deferred.resolve(results);
      }, function(reason) {
        if (results.hasOwnProperty(key)) return;
        deferred.reject(reason);
      });
    });

    if (counter === 0) {
      deferred.resolve(results);
    }

    return deferred.promise;
  }

  var $Q = function Q(resolver) {
    if (!isFunction(resolver)) {
      throw $qMinErr('norslvr', "Expected resolverFn, got '{0}'", resolver);
    }

    if (!(this instanceof Q)) {
      // More useful when $Q is the Promise itself.
      return new Q(resolver);
    }

    var deferred = new Deferred();

    function resolveFn(value) {
      deferred.resolve(value);
    }

    function rejectFn(reason) {
      deferred.reject(reason);
    }

    resolver(resolveFn, rejectFn);

    return deferred.promise;
  };

  $Q.defer = defer;
  $Q.reject = reject;
  $Q.when = when;
  $Q.all = all;

  return $Q;
}

function $$RAFProvider() { //rAF
  this.$get = ['$window', '$timeout', function($window, $timeout) {
    var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame;

    var cancelAnimationFrame = $window.cancelAnimationFrame ||
                               $window.webkitCancelAnimationFrame ||
                               $window.webkitCancelRequestAnimationFrame;

    var rafSupported = !!requestAnimationFrame;
    var rafFn = rafSupported
      ? function(fn) {
          var id = requestAnimationFrame(fn);
          return function() {
            cancelAnimationFrame(id);
          };
        }
      : function(fn) {
          var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666
          return function() {
            $timeout.cancel(timer);
          };
        };

    queueFn.supported = rafSupported;

    var cancelLastRAF;
    var taskCount = 0;
    var taskQueue = [];
    return queueFn;

    function flush() {
      for (var i = 0; i < taskQueue.length; i++) {
        var task = taskQueue[i];
        if (task) {
          taskQueue[i] = null;
          task();
        }
      }
      taskCount = taskQueue.length = 0;
    }

    function queueFn(asyncFn) {
      var index = taskQueue.length;

      taskCount++;
      taskQueue.push(asyncFn);

      if (index === 0) {
        cancelLastRAF = rafFn(flush);
      }

      return function cancelQueueFn() {
        if (index >= 0) {
          taskQueue[index] = null;
          index = null;

          if (--taskCount === 0 && cancelLastRAF) {
            cancelLastRAF();
            cancelLastRAF = null;
            taskQueue.length = 0;
          }
        }
      };
    }
  }];
}

/**
 * DESIGN NOTES
 *
 * The design decisions behind the scope are heavily favored for speed and memory consumption.
 *
 * The typical use of scope is to watch the expressions, which most of the time return the same
 * value as last time so we optimize the operation.
 *
 * Closures construction is expensive in terms of speed as well as memory:
 *   - No closures, instead use prototypical inheritance for API
 *   - Internal state needs to be stored on scope directly, which means that private state is
 *     exposed as $$____ properties
 *
 * Loop operations are optimized by using while(count--) { ... }
 *   - this means that in order to keep the same order of execution as addition we have to add
 *     items to the array at the beginning (unshift) instead of at the end (push)
 *
 * Child scopes are created and removed often
 *   - Using an array would be slow since inserts in middle are expensive so we use linked list
 *
 * There are few watches then a lot of observers. This is why you don't want the observer to be
 * implemented in the same way as watch. Watch requires return of initialization function which
 * are expensive to construct.
 */


/**
 * @ngdoc provider
 * @name $rootScopeProvider
 * @description
 *
 * Provider for the $rootScope service.
 */

/**
 * @ngdoc method
 * @name $rootScopeProvider#digestTtl
 * @description
 *
 * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and
 * assuming that the model is unstable.
 *
 * The current default is 10 iterations.
 *
 * In complex applications it's possible that the dependencies between `$watch`s will result in
 * several digest iterations. However if an application needs more than the default 10 digest
 * iterations for its model to stabilize then you should investigate what is causing the model to
 * continuously change during the digest.
 *
 * Increasing the TTL could have performance implications, so you should not change it without
 * proper justification.
 *
 * @param {number} limit The number of digest iterations.
 */


/**
 * @ngdoc service
 * @name $rootScope
 * @description
 *
 * Every application has a single root {@link ng.$rootScope.Scope scope}.
 * All other scopes are descendant scopes of the root scope. Scopes provide separation
 * between the model and the view, via a mechanism for watching the model for changes.
 * They also provide an event emission/broadcast and subscription facility. See the
 * {@link guide/scope developer guide on scopes}.
 */
function $RootScopeProvider() {
  var TTL = 10;
  var $rootScopeMinErr = minErr('$rootScope');
  var lastDirtyWatch = null;
  var applyAsyncId = null;

  this.digestTtl = function(value) {
    if (arguments.length) {
      TTL = value;
    }
    return TTL;
  };

  function createChildScopeClass(parent) {
    function ChildScope() {
      this.$$watchers = this.$$nextSibling =
          this.$$childHead = this.$$childTail = null;
      this.$$listeners = {};
      this.$$listenerCount = {};
      this.$id = nextUid();
      this.$$ChildScope = null;
    }
    ChildScope.prototype = parent;
    return ChildScope;
  }

  this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
      function($injector, $exceptionHandler, $parse, $browser) {

    function destroyChildScope($event) {
        $event.currentScope.$$destroyed = true;
    }

    /**
     * @ngdoc type
     * @name $rootScope.Scope
     *
     * @description
     * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the
     * {@link auto.$injector $injector}. Child scopes are created using the
     * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when
     * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for
     * an in-depth introduction and usage examples.
     *
     *
     * # Inheritance
     * A scope can inherit from a parent scope, as in this example:
     * ```js
         var parent = $rootScope;
         var child = parent.$new();

         parent.salutation = "Hello";
         expect(child.salutation).toEqual('Hello');

         child.salutation = "Welcome";
         expect(child.salutation).toEqual('Welcome');
         expect(parent.salutation).toEqual('Hello');
     * ```
     *
     * When interacting with `Scope` in tests, additional helper methods are available on the
     * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional
     * details.
     *
     *
     * @param {Object.<string, function()>=} providers Map of service factory which need to be
     *                                       provided for the current scope. Defaults to {@link ng}.
     * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should
     *                              append/override services provided by `providers`. This is handy
     *                              when unit-testing and having the need to override a default
     *                              service.
     * @returns {Object} Newly created scope.
     *
     */
    function Scope() {
      this.$id = nextUid();
      this.$$phase = this.$parent = this.$$watchers =
                     this.$$nextSibling = this.$$prevSibling =
                     this.$$childHead = this.$$childTail = null;
      this.$root = this;
      this.$$destroyed = false;
      this.$$listeners = {};
      this.$$listenerCount = {};
      this.$$isolateBindings = null;
    }

    /**
     * @ngdoc property
     * @name $rootScope.Scope#$id
     *
     * @description
     * Unique scope ID (monotonically increasing) useful for debugging.
     */

     /**
      * @ngdoc property
      * @name $rootScope.Scope#$parent
      *
      * @description
      * Reference to the parent scope.
      */

      /**
       * @ngdoc property
       * @name $rootScope.Scope#$root
       *
       * @description
       * Reference to the root scope.
       */

    Scope.prototype = {
      constructor: Scope,
      /**
       * @ngdoc method
       * @name $rootScope.Scope#$new
       * @kind function
       *
       * @description
       * Creates a new child {@link ng.$rootScope.Scope scope}.
       *
       * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event.
       * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}.
       *
       * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is
       * desired for the scope and its child scopes to be permanently detached from the parent and
       * thus stop participating in model change detection and listener notification by invoking.
       *
       * @param {boolean} isolate If true, then the scope does not prototypically inherit from the
       *         parent scope. The scope is isolated, as it can not see parent scope properties.
       *         When creating widgets, it is useful for the widget to not accidentally read parent
       *         state.
       *
       * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent`
       *                              of the newly created scope. Defaults to `this` scope if not provided.
       *                              This is used when creating a transclude scope to correctly place it
       *                              in the scope hierarchy while maintaining the correct prototypical
       *                              inheritance.
       *
       * @returns {Object} The newly created child scope.
       *
       */
      $new: function(isolate, parent) {
        var child;

        parent = parent || this;

        if (isolate) {
          child = new Scope();
          child.$root = this.$root;
        } else {
          // Only create a child scope class if somebody asks for one,
          // but cache it to allow the VM to optimize lookups.
          if (!this.$$ChildScope) {
            this.$$ChildScope = createChildScopeClass(this);
          }
          child = new this.$$ChildScope();
        }
        child.$parent = parent;
        child.$$prevSibling = parent.$$childTail;
        if (parent.$$childHead) {
          parent.$$childTail.$$nextSibling = child;
          parent.$$childTail = child;
        } else {
          parent.$$childHead = parent.$$childTail = child;
        }

        // When the new scope is not isolated or we inherit from `this`, and
        // the parent scope is destroyed, the property `$$destroyed` is inherited
        // prototypically. In all other cases, this property needs to be set
        // when the parent scope is destroyed.
        // The listener needs to be added after the parent is set
        if (isolate || parent != this) child.$on('$destroy', destroyChildScope);

        return child;
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$watch
       * @kind function
       *
       * @description
       * Registers a `listener` callback to be executed whenever the `watchExpression` changes.
       *
       * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest
       *   $digest()} and should return the value that will be watched. (Since
       *   {@link ng.$rootScope.Scope#$digest $digest()} reruns when it detects changes the
       *   `watchExpression` can execute multiple times per
       *   {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.)
       * - The `listener` is called only when the value from the current `watchExpression` and the
       *   previous call to `watchExpression` are not equal (with the exception of the initial run,
       *   see below). Inequality is determined according to reference inequality,
       *   [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)
       *    via the `!==` Javascript operator, unless `objectEquality == true`
       *   (see next point)
       * - When `objectEquality == true`, inequality of the `watchExpression` is determined
       *   according to the {@link angular.equals} function. To save the value of the object for
       *   later comparison, the {@link angular.copy} function is used. This therefore means that
       *   watching complex objects will have adverse memory and performance implications.
       * - The watch `listener` may change the model, which may trigger other `listener`s to fire.
       *   This is achieved by rerunning the watchers until no changes are detected. The rerun
       *   iteration limit is 10 to prevent an infinite loop deadlock.
       *
       *
       * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called,
       * you can register a `watchExpression` function with no `listener`. (Be prepared for
       * multiple calls to your `watchExpression` because it will execute multiple times in a
       * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.)
       *
       * After a watcher is registered with the scope, the `listener` fn is called asynchronously
       * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the
       * watcher. In rare cases, this is undesirable because the listener is called when the result
       * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you
       * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the
       * listener was called due to initialization.
       *
       *
       *
       * # Example
       * ```js
           // let's assume that scope was dependency injected as the $rootScope
           var scope = $rootScope;
           scope.name = 'misko';
           scope.counter = 0;

           expect(scope.counter).toEqual(0);
           scope.$watch('name', function(newValue, oldValue) {
             scope.counter = scope.counter + 1;
           });
           expect(scope.counter).toEqual(0);

           scope.$digest();
           // the listener is always called during the first $digest loop after it was registered
           expect(scope.counter).toEqual(1);

           scope.$digest();
           // but now it will not be called unless the value changes
           expect(scope.counter).toEqual(1);

           scope.name = 'adam';
           scope.$digest();
           expect(scope.counter).toEqual(2);



           // Using a function as a watchExpression
           var food;
           scope.foodCounter = 0;
           expect(scope.foodCounter).toEqual(0);
           scope.$watch(
             // This function returns the value being watched. It is called for each turn of the $digest loop
             function() { return food; },
             // This is the change listener, called when the value returned from the above function changes
             function(newValue, oldValue) {
               if ( newValue !== oldValue ) {
                 // Only increment the counter if the value changed
                 scope.foodCounter = scope.foodCounter + 1;
               }
             }
           );
           // No digest has been run so the counter will be zero
           expect(scope.foodCounter).toEqual(0);

           // Run the digest but since food has not changed count will still be zero
           scope.$digest();
           expect(scope.foodCounter).toEqual(0);

           // Update food and run digest.  Now the counter will increment
           food = 'cheeseburger';
           scope.$digest();
           expect(scope.foodCounter).toEqual(1);

       * ```
       *
       *
       *
       * @param {(function()|string)} watchExpression Expression that is evaluated on each
       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers
       *    a call to the `listener`.
       *
       *    - `string`: Evaluated as {@link guide/expression expression}
       *    - `function(scope)`: called with current `scope` as a parameter.
       * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value
       *    of `watchExpression` changes.
       *
       *    - `newVal` contains the current value of the `watchExpression`
       *    - `oldVal` contains the previous value of the `watchExpression`
       *    - `scope` refers to the current scope
       * @param {boolean=} objectEquality Compare for object equality using {@link angular.equals} instead of
       *     comparing for reference equality.
       * @returns {function()} Returns a deregistration function for this listener.
       */
      $watch: function(watchExp, listener, objectEquality) {
        var get = $parse(watchExp);

        if (get.$$watchDelegate) {
          return get.$$watchDelegate(this, listener, objectEquality, get);
        }
        var scope = this,
            array = scope.$$watchers,
            watcher = {
              fn: listener,
              last: initWatchVal,
              get: get,
              exp: watchExp,
              eq: !!objectEquality
            };

        lastDirtyWatch = null;

        if (!isFunction(listener)) {
          watcher.fn = noop;
        }

        if (!array) {
          array = scope.$$watchers = [];
        }
        // we use unshift since we use a while loop in $digest for speed.
        // the while loop reads in reverse order.
        array.unshift(watcher);

        return function deregisterWatch() {
          arrayRemove(array, watcher);
          lastDirtyWatch = null;
        };
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$watchGroup
       * @kind function
       *
       * @description
       * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`.
       * If any one expression in the collection changes the `listener` is executed.
       *
       * - The items in the `watchExpressions` array are observed via standard $watch operation and are examined on every
       *   call to $digest() to see if any items changes.
       * - The `listener` is called whenever any expression in the `watchExpressions` array changes.
       *
       * @param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually
       * watched using {@link ng.$rootScope.Scope#$watch $watch()}
       *
       * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any
       *    expression in `watchExpressions` changes
       *    The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching
       *    those of `watchExpression`
       *    and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching
       *    those of `watchExpression`
       *    The `scope` refers to the current scope.
       * @returns {function()} Returns a de-registration function for all listeners.
       */
      $watchGroup: function(watchExpressions, listener) {
        var oldValues = new Array(watchExpressions.length);
        var newValues = new Array(watchExpressions.length);
        var deregisterFns = [];
        var self = this;
        var changeReactionScheduled = false;
        var firstRun = true;

        if (!watchExpressions.length) {
          // No expressions means we call the listener ASAP
          var shouldCall = true;
          self.$evalAsync(function() {
            if (shouldCall) listener(newValues, newValues, self);
          });
          return function deregisterWatchGroup() {
            shouldCall = false;
          };
        }

        if (watchExpressions.length === 1) {
          // Special case size of one
          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
            newValues[0] = value;
            oldValues[0] = oldValue;
            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);
          });
        }

        forEach(watchExpressions, function(expr, i) {
          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
            newValues[i] = value;
            oldValues[i] = oldValue;
            if (!changeReactionScheduled) {
              changeReactionScheduled = true;
              self.$evalAsync(watchGroupAction);
            }
          });
          deregisterFns.push(unwatchFn);
        });

        function watchGroupAction() {
          changeReactionScheduled = false;

          if (firstRun) {
            firstRun = false;
            listener(newValues, newValues, self);
          } else {
            listener(newValues, oldValues, self);
          }
        }

        return function deregisterWatchGroup() {
          while (deregisterFns.length) {
            deregisterFns.shift()();
          }
        };
      },


      /**
       * @ngdoc method
       * @name $rootScope.Scope#$watchCollection
       * @kind function
       *
       * @description
       * Shallow watches the properties of an object and fires whenever any of the properties change
       * (for arrays, this implies watching the array items; for object maps, this implies watching
       * the properties). If a change is detected, the `listener` callback is fired.
       *
       * - The `obj` collection is observed via standard $watch operation and is examined on every
       *   call to $digest() to see if any items have been added, removed, or moved.
       * - The `listener` is called whenever anything within the `obj` has changed. Examples include
       *   adding, removing, and moving items belonging to an object or array.
       *
       *
       * # Example
       * ```js
          $scope.names = ['igor', 'matias', 'misko', 'james'];
          $scope.dataCount = 4;

          $scope.$watchCollection('names', function(newNames, oldNames) {
            $scope.dataCount = newNames.length;
          });

          expect($scope.dataCount).toEqual(4);
          $scope.$digest();

          //still at 4 ... no changes
          expect($scope.dataCount).toEqual(4);

          $scope.names.pop();
          $scope.$digest();

          //now there's been a change
          expect($scope.dataCount).toEqual(3);
       * ```
       *
       *
       * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The
       *    expression value should evaluate to an object or an array which is observed on each
       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the
       *    collection will trigger a call to the `listener`.
       *
       * @param {function(newCollection, oldCollection, scope)} listener a callback function called
       *    when a change is detected.
       *    - The `newCollection` object is the newly modified data obtained from the `obj` expression
       *    - The `oldCollection` object is a copy of the former collection data.
       *      Due to performance considerations, the`oldCollection` value is computed only if the
       *      `listener` function declares two or more arguments.
       *    - The `scope` argument refers to the current scope.
       *
       * @returns {function()} Returns a de-registration function for this listener. When the
       *    de-registration function is executed, the internal watch operation is terminated.
       */
      $watchCollection: function(obj, listener) {
        $watchCollectionInterceptor.$stateful = true;

        var self = this;
        // the current value, updated on each dirty-check run
        var newValue;
        // a shallow copy of the newValue from the last dirty-check run,
        // updated to match newValue during dirty-check run
        var oldValue;
        // a shallow copy of the newValue from when the last change happened
        var veryOldValue;
        // only track veryOldValue if the listener is asking for it
        var trackVeryOldValue = (listener.length > 1);
        var changeDetected = 0;
        var changeDetector = $parse(obj, $watchCollectionInterceptor);
        var internalArray = [];
        var internalObject = {};
        var initRun = true;
        var oldLength = 0;

        function $watchCollectionInterceptor(_value) {
          newValue = _value;
          var newLength, key, bothNaN, newItem, oldItem;

          // If the new value is undefined, then return undefined as the watch may be a one-time watch
          if (isUndefined(newValue)) return;

          if (!isObject(newValue)) { // if primitive
            if (oldValue !== newValue) {
              oldValue = newValue;
              changeDetected++;
            }
          } else if (isArrayLike(newValue)) {
            if (oldValue !== internalArray) {
              // we are transitioning from something which was not an array into array.
              oldValue = internalArray;
              oldLength = oldValue.length = 0;
              changeDetected++;
            }

            newLength = newValue.length;

            if (oldLength !== newLength) {
              // if lengths do not match we need to trigger change notification
              changeDetected++;
              oldValue.length = oldLength = newLength;
            }
            // copy the items to oldValue and look for changes.
            for (var i = 0; i < newLength; i++) {
              oldItem = oldValue[i];
              newItem = newValue[i];

              bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
              if (!bothNaN && (oldItem !== newItem)) {
                changeDetected++;
                oldValue[i] = newItem;
              }
            }
          } else {
            if (oldValue !== internalObject) {
              // we are transitioning from something which was not an object into object.
              oldValue = internalObject = {};
              oldLength = 0;
              changeDetected++;
            }
            // copy the items to oldValue and look for changes.
            newLength = 0;
            for (key in newValue) {
              if (newValue.hasOwnProperty(key)) {
                newLength++;
                newItem = newValue[key];
                oldItem = oldValue[key];

                if (key in oldValue) {
                  bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
                  if (!bothNaN && (oldItem !== newItem)) {
                    changeDetected++;
                    oldValue[key] = newItem;
                  }
                } else {
                  oldLength++;
                  oldValue[key] = newItem;
                  changeDetected++;
                }
              }
            }
            if (oldLength > newLength) {
              // we used to have more keys, need to find them and destroy them.
              changeDetected++;
              for (key in oldValue) {
                if (!newValue.hasOwnProperty(key)) {
                  oldLength--;
                  delete oldValue[key];
                }
              }
            }
          }
          return changeDetected;
        }

        function $watchCollectionAction() {
          if (initRun) {
            initRun = false;
            listener(newValue, newValue, self);
          } else {
            listener(newValue, veryOldValue, self);
          }

          // make a copy for the next time a collection is changed
          if (trackVeryOldValue) {
            if (!isObject(newValue)) {
              //primitive
              veryOldValue = newValue;
            } else if (isArrayLike(newValue)) {
              veryOldValue = new Array(newValue.length);
              for (var i = 0; i < newValue.length; i++) {
                veryOldValue[i] = newValue[i];
              }
            } else { // if object
              veryOldValue = {};
              for (var key in newValue) {
                if (hasOwnProperty.call(newValue, key)) {
                  veryOldValue[key] = newValue[key];
                }
              }
            }
          }
        }

        return this.$watch(changeDetector, $watchCollectionAction);
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$digest
       * @kind function
       *
       * @description
       * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and
       * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change
       * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers}
       * until no more listeners are firing. This means that it is possible to get into an infinite
       * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of
       * iterations exceeds 10.
       *
       * Usually, you don't call `$digest()` directly in
       * {@link ng.directive:ngController controllers} or in
       * {@link ng.$compileProvider#directive directives}.
       * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within
       * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`.
       *
       * If you want to be notified whenever `$digest()` is called,
       * you can register a `watchExpression` function with
       * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`.
       *
       * In unit tests, you may need to call `$digest()` to simulate the scope life cycle.
       *
       * # Example
       * ```js
           var scope = ...;
           scope.name = 'misko';
           scope.counter = 0;

           expect(scope.counter).toEqual(0);
           scope.$watch('name', function(newValue, oldValue) {
             scope.counter = scope.counter + 1;
           });
           expect(scope.counter).toEqual(0);

           scope.$digest();
           // the listener is always called during the first $digest loop after it was registered
           expect(scope.counter).toEqual(1);

           scope.$digest();
           // but now it will not be called unless the value changes
           expect(scope.counter).toEqual(1);

           scope.name = 'adam';
           scope.$digest();
           expect(scope.counter).toEqual(2);
       * ```
       *
       */
      $digest: function() {
        var watch, value, last,
            watchers,
            length,
            dirty, ttl = TTL,
            next, current, target = this,
            watchLog = [],
            logIdx, logMsg, asyncTask;

        beginPhase('$digest');
        // Check for changes to browser url that happened in sync before the call to $digest
        $browser.$$checkUrlChange();

        if (this === $rootScope && applyAsyncId !== null) {
          // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then
          // cancel the scheduled $apply and flush the queue of expressions to be evaluated.
          $browser.defer.cancel(applyAsyncId);
          flushApplyAsync();
        }

        lastDirtyWatch = null;

        do { // "while dirty" loop
          dirty = false;
          current = target;

          while (asyncQueue.length) {
            try {
              asyncTask = asyncQueue.shift();
              asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals);
            } catch (e) {
              $exceptionHandler(e);
            }
            lastDirtyWatch = null;
          }

          traverseScopesLoop:
          do { // "traverse the scopes" loop
            if ((watchers = current.$$watchers)) {
              // process our watches
              length = watchers.length;
              while (length--) {
                try {
                  watch = watchers[length];
                  // Most common watches are on primitives, in which case we can short
                  // circuit it with === operator, only when === fails do we use .equals
                  if (watch) {
                    if ((value = watch.get(current)) !== (last = watch.last) &&
                        !(watch.eq
                            ? equals(value, last)
                            : (typeof value === 'number' && typeof last === 'number'
                               && isNaN(value) && isNaN(last)))) {
                      dirty = true;
                      lastDirtyWatch = watch;
                      watch.last = watch.eq ? copy(value, null) : value;
                      watch.fn(value, ((last === initWatchVal) ? value : last), current);
                      if (ttl < 5) {
                        logIdx = 4 - ttl;
                        if (!watchLog[logIdx]) watchLog[logIdx] = [];
                        watchLog[logIdx].push({
                          msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
                          newVal: value,
                          oldVal: last
                        });
                      }
                    } else if (watch === lastDirtyWatch) {
                      // If the most recently dirty watcher is now clean, short circuit since the remaining watchers
                      // have already been tested.
                      dirty = false;
                      break traverseScopesLoop;
                    }
                  }
                } catch (e) {
                  $exceptionHandler(e);
                }
              }
            }

            // Insanity Warning: scope depth-first traversal
            // yes, this code is a bit crazy, but it works and we have tests to prove it!
            // this piece should be kept in sync with the traversal in $broadcast
            if (!(next = (current.$$childHead ||
                (current !== target && current.$$nextSibling)))) {
              while (current !== target && !(next = current.$$nextSibling)) {
                current = current.$parent;
              }
            }
          } while ((current = next));

          // `break traverseScopesLoop;` takes us to here

          if ((dirty || asyncQueue.length) && !(ttl--)) {
            clearPhase();
            throw $rootScopeMinErr('infdig',
                '{0} $digest() iterations reached. Aborting!\n' +
                'Watchers fired in the last 5 iterations: {1}',
                TTL, watchLog);
          }

        } while (dirty || asyncQueue.length);

        clearPhase();

        while (postDigestQueue.length) {
          try {
            postDigestQueue.shift()();
          } catch (e) {
            $exceptionHandler(e);
          }
        }
      },


      /**
       * @ngdoc event
       * @name $rootScope.Scope#$destroy
       * @eventType broadcast on scope being destroyed
       *
       * @description
       * Broadcasted when a scope and its children are being destroyed.
       *
       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
       * clean up DOM bindings before an element is removed from the DOM.
       */

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$destroy
       * @kind function
       *
       * @description
       * Removes the current scope (and all of its children) from the parent scope. Removal implies
       * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer
       * propagate to the current scope and its children. Removal also implies that the current
       * scope is eligible for garbage collection.
       *
       * The `$destroy()` is usually used by directives such as
       * {@link ng.directive:ngRepeat ngRepeat} for managing the
       * unrolling of the loop.
       *
       * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope.
       * Application code can register a `$destroy` event handler that will give it a chance to
       * perform any necessary cleanup.
       *
       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
       * clean up DOM bindings before an element is removed from the DOM.
       */
      $destroy: function() {
        // we can't destroy the root scope or a scope that has been already destroyed
        if (this.$$destroyed) return;
        var parent = this.$parent;

        this.$broadcast('$destroy');
        this.$$destroyed = true;
        if (this === $rootScope) return;

        for (var eventName in this.$$listenerCount) {
          decrementListenerCount(this, this.$$listenerCount[eventName], eventName);
        }

        // sever all the references to parent scopes (after this cleanup, the current scope should
        // not be retained by any of our references and should be eligible for garbage collection)
        if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
        if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
        if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
        if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;

        // Disable listeners, watchers and apply/digest methods
        this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;
        this.$on = this.$watch = this.$watchGroup = function() { return noop; };
        this.$$listeners = {};

        // All of the code below is bogus code that works around V8's memory leak via optimized code
        // and inline caches.
        //
        // see:
        // - https://code.google.com/p/v8/issues/detail?id=2073#c26
        // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909
        // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451

        this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead =
            this.$$childTail = this.$root = this.$$watchers = null;
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$eval
       * @kind function
       *
       * @description
       * Executes the `expression` on the current scope and returns the result. Any exceptions in
       * the expression are propagated (uncaught). This is useful when evaluating Angular
       * expressions.
       *
       * # Example
       * ```js
           var scope = ng.$rootScope.Scope();
           scope.a = 1;
           scope.b = 2;

           expect(scope.$eval('a+b')).toEqual(3);
           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
       * ```
       *
       * @param {(string|function())=} expression An angular expression to be executed.
       *
       *    - `string`: execute using the rules as defined in  {@link guide/expression expression}.
       *    - `function(scope)`: execute the function with the current `scope` parameter.
       *
       * @param {(object)=} locals Local variables object, useful for overriding values in scope.
       * @returns {*} The result of evaluating the expression.
       */
      $eval: function(expr, locals) {
        return $parse(expr)(this, locals);
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$evalAsync
       * @kind function
       *
       * @description
       * Executes the expression on the current scope at a later point in time.
       *
       * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only
       * that:
       *
       *   - it will execute after the function that scheduled the evaluation (preferably before DOM
       *     rendering).
       *   - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after
       *     `expression` execution.
       *
       * Any exceptions from the execution of the expression are forwarded to the
       * {@link ng.$exceptionHandler $exceptionHandler} service.
       *
       * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle
       * will be scheduled. However, it is encouraged to always call code that changes the model
       * from within an `$apply` call. That includes code evaluated via `$evalAsync`.
       *
       * @param {(string|function())=} expression An angular expression to be executed.
       *
       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
       *    - `function(scope)`: execute the function with the current `scope` parameter.
       *
       * @param {(object)=} locals Local variables object, useful for overriding values in scope.
       */
      $evalAsync: function(expr, locals) {
        // if we are outside of an $digest loop and this is the first time we are scheduling async
        // task also schedule async auto-flush
        if (!$rootScope.$$phase && !asyncQueue.length) {
          $browser.defer(function() {
            if (asyncQueue.length) {
              $rootScope.$digest();
            }
          });
        }

        asyncQueue.push({scope: this, expression: expr, locals: locals});
      },

      $$postDigest: function(fn) {
        postDigestQueue.push(fn);
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$apply
       * @kind function
       *
       * @description
       * `$apply()` is used to execute an expression in angular from outside of the angular
       * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).
       * Because we are calling into the angular framework we need to perform proper scope life
       * cycle of {@link ng.$exceptionHandler exception handling},
       * {@link ng.$rootScope.Scope#$digest executing watches}.
       *
       * ## Life cycle
       *
       * # Pseudo-Code of `$apply()`
       * ```js
           function $apply(expr) {
             try {
               return $eval(expr);
             } catch (e) {
               $exceptionHandler(e);
             } finally {
               $root.$digest();
             }
           }
       * ```
       *
       *
       * Scope's `$apply()` method transitions through the following stages:
       *
       * 1. The {@link guide/expression expression} is executed using the
       *    {@link ng.$rootScope.Scope#$eval $eval()} method.
       * 2. Any exceptions from the execution of the expression are forwarded to the
       *    {@link ng.$exceptionHandler $exceptionHandler} service.
       * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the
       *    expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method.
       *
       *
       * @param {(string|function())=} exp An angular expression to be executed.
       *
       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
       *    - `function(scope)`: execute the function with current `scope` parameter.
       *
       * @returns {*} The result of evaluating the expression.
       */
      $apply: function(expr) {
        try {
          beginPhase('$apply');
          return this.$eval(expr);
        } catch (e) {
          $exceptionHandler(e);
        } finally {
          clearPhase();
          try {
            $rootScope.$digest();
          } catch (e) {
            $exceptionHandler(e);
            throw e;
          }
        }
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$applyAsync
       * @kind function
       *
       * @description
       * Schedule the invocation of $apply to occur at a later time. The actual time difference
       * varies across browsers, but is typically around ~10 milliseconds.
       *
       * This can be used to queue up multiple expressions which need to be evaluated in the same
       * digest.
       *
       * @param {(string|function())=} exp An angular expression to be executed.
       *
       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
       *    - `function(scope)`: execute the function with current `scope` parameter.
       */
      $applyAsync: function(expr) {
        var scope = this;
        expr && applyAsyncQueue.push($applyAsyncExpression);
        scheduleApplyAsync();

        function $applyAsyncExpression() {
          scope.$eval(expr);
        }
      },

      /**
       * @ngdoc method
       * @name $rootScope.Scope#$on
       * @kind function
       *
       * @description
       * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for
       * discussion of event life cycle.
       *
       * The event listener function format is: `function(event, args...)`. The `event` object
       * passed into the listener has the following attributes:
       *
       *   - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or
       *     `$broadcast`-ed.
       *   - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the
       *     event propagates through the scope hierarchy, this property is set to null.
       *   - `name` - `{string}`: name of the event.
       *   - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel
       *     further event propagation (available only for events that were `$emit`-ed).
       *   - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag
       *     to true.
       *   - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
       *
       * @param {string} name Event name to listen on.
       * @param {function(event, ...args)} listener Function to call when the event is emitted.
       * @returns {function()} Returns a deregistration function for this listener.
       */
      $on: function(name, listener) {
        var namedListeners = this.$$listeners[name];
        if (!namedListeners) {
          this.$$listeners[name] = namedListeners = [];
        }
        namedListeners.push(listener);

        var current = this;
        do {
          if (!current.$$listenerCount[name]) {
            current.$$listenerCount[name] = 0;
          }
          current.$$listenerCount[name]++;
        } while ((current = current.$parent));

        var self = this;
        return function() {
          var indexOfListener = namedListeners.indexOf(listener);
          if (indexOfListener !== -1) {
            namedListeners[indexOfListener] = null;
            decrementListenerCount(self, 1, name);
          }
        };
      },


      /**
       * @ngdoc method
       * @name $rootScope.Scope#$emit
       * @kind function
       *
       * @description
       * Dispatches an event `name` upwards through the scope hierarchy notifying the
       * registered {@link ng.$rootScope.Scope#$on} listeners.
       *
       * The event life cycle starts at the scope on which `$emit` was called. All
       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
       * notified. Afterwards, the event traverses upwards toward the root scope and calls all
       * registered listeners along the way. The event will stop propagating if one of the listeners
       * cancels it.
       *
       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
       *
       * @param {string} name Event name to emit.
       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
       * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}).
       */
      $emit: function(name, args) {
        var empty = [],
            namedListeners,
            scope = this,
            stopPropagation = false,
            event = {
              name: name,
              targetScope: scope,
              stopPropagation: function() {stopPropagation = true;},
              preventDefault: function() {
                event.defaultPrevented = true;
              },
              defaultPrevented: false
            },
            listenerArgs = concat([event], arguments, 1),
            i, length;

        do {
          namedListeners = scope.$$listeners[name] || empty;
          event.currentScope = scope;
          for (i = 0, length = namedListeners.length; i < length; i++) {

            // if listeners were deregistered, defragment the array
            if (!namedListeners[i]) {
              namedListeners.splice(i, 1);
              i--;
              length--;
              continue;
            }
            try {
              //allow all listeners attached to the current scope to run
              namedListeners[i].apply(null, listenerArgs);
            } catch (e) {
              $exceptionHandler(e);
            }
          }
          //if any listener on the current scope stops propagation, prevent bubbling
          if (stopPropagation) {
            event.currentScope = null;
            return event;
          }
          //traverse upwards
          scope = scope.$parent;
        } while (scope);

        event.currentScope = null;

        return event;
      },


      /**
       * @ngdoc method
       * @name $rootScope.Scope#$broadcast
       * @kind function
       *
       * @description
       * Dispatches an event `name` downwards to all child scopes (and their children) notifying the
       * registered {@link ng.$rootScope.Scope#$on} listeners.
       *
       * The event life cycle starts at the scope on which `$broadcast` was called. All
       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
       * notified. Afterwards, the event propagates to all direct and indirect scopes of the current
       * scope and calls all registered listeners along the way. The event cannot be canceled.
       *
       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
       *
       * @param {string} name Event name to broadcast.
       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
       * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
       */
      $broadcast: function(name, args) {
        var target = this,
            current = target,
            next = target,
            event = {
              name: name,
              targetScope: target,
              preventDefault: function() {
                event.defaultPrevented = true;
              },
              defaultPrevented: false
            };

        if (!target.$$listenerCount[name]) return event;

        var listenerArgs = concat([event], arguments, 1),
            listeners, i, length;

        //down while you can, then up and next sibling or up and next sibling until back at root
        while ((current = next)) {
          event.currentScope = current;
          listeners = current.$$listeners[name] || [];
          for (i = 0, length = listeners.length; i < length; i++) {
            // if listeners were deregistered, defragment the array
            if (!listeners[i]) {
              listeners.splice(i, 1);
              i--;
              length--;
              continue;
            }

            try {
              listeners[i].apply(null, listenerArgs);
            } catch (e) {
              $exceptionHandler(e);
            }
          }

          // Insanity Warning: scope depth-first traversal
          // yes, this code is a bit crazy, but it works and we have tests to prove it!
          // this piece should be kept in sync with the traversal in $digest
          // (though it differs due to having the extra check for $$listenerCount)
          if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
              (current !== target && current.$$nextSibling)))) {
            while (current !== target && !(next = current.$$nextSibling)) {
              current = current.$parent;
            }
          }
        }

        event.currentScope = null;
        return event;
      }
    };

    var $rootScope = new Scope();

    //The internal queues. Expose them on the $rootScope for debugging/testing purposes.
    var asyncQueue = $rootScope.$$asyncQueue = [];
    var postDigestQueue = $rootScope.$$postDigestQueue = [];
    var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];

    return $rootScope;


    function beginPhase(phase) {
      if ($rootScope.$$phase) {
        throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);
      }

      $rootScope.$$phase = phase;
    }

    function clearPhase() {
      $rootScope.$$phase = null;
    }


    function decrementListenerCount(current, count, name) {
      do {
        current.$$listenerCount[name] -= count;

        if (current.$$listenerCount[name] === 0) {
          delete current.$$listenerCount[name];
        }
      } while ((current = current.$parent));
    }

    /**
     * function used as an initial value for watchers.
     * because it's unique we can easily tell it apart from other values
     */
    function initWatchVal() {}

    function flushApplyAsync() {
      while (applyAsyncQueue.length) {
        try {
          applyAsyncQueue.shift()();
        } catch (e) {
          $exceptionHandler(e);
        }
      }
      applyAsyncId = null;
    }

    function scheduleApplyAsync() {
      if (applyAsyncId === null) {
        applyAsyncId = $browser.defer(function() {
          $rootScope.$apply(flushApplyAsync);
        });
      }
    }
  }];
}

/**
 * @description
 * Private service to sanitize uris for links and images. Used by $compile and $sanitize.
 */
function $$SanitizeUriProvider() {
  var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
    imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/;

  /**
   * @description
   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
   * urls during a[href] sanitization.
   *
   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
   *
   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
   *
   * @param {RegExp=} regexp New regexp to whitelist urls with.
   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
   *    chaining otherwise.
   */
  this.aHrefSanitizationWhitelist = function(regexp) {
    if (isDefined(regexp)) {
      aHrefSanitizationWhitelist = regexp;
      return this;
    }
    return aHrefSanitizationWhitelist;
  };


  /**
   * @description
   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
   * urls during img[src] sanitization.
   *
   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
   *
   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
   *
   * @param {RegExp=} regexp New regexp to whitelist urls with.
   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
   *    chaining otherwise.
   */
  this.imgSrcSanitizationWhitelist = function(regexp) {
    if (isDefined(regexp)) {
      imgSrcSanitizationWhitelist = regexp;
      return this;
    }
    return imgSrcSanitizationWhitelist;
  };

  this.$get = function() {
    return function sanitizeUri(uri, isImage) {
      var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
      var normalizedVal;
      normalizedVal = urlResolve(uri).href;
      if (normalizedVal !== '' && !normalizedVal.match(regex)) {
        return 'unsafe:' + normalizedVal;
      }
      return uri;
    };
  };
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *     Any commits to this file should be reviewed with security in mind.  *
 *   Changes to this file can potentially create security vulnerabilities. *
 *          An approval from 2 Core members with history of modifying      *
 *                         this file is required.                          *
 *                                                                         *
 *  Does the change somehow allow for arbitrary javascript to be executed? *
 *    Or allows for someone to change the prototype of built-in objects?   *
 *     Or gives undesired access to variables likes document or window?    *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var $sceMinErr = minErr('$sce');

var SCE_CONTEXTS = {
  HTML: 'html',
  CSS: 'css',
  URL: 'url',
  // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a
  // url.  (e.g. ng-include, script src, templateUrl)
  RESOURCE_URL: 'resourceUrl',
  JS: 'js'
};

// Helper functions follow.

function adjustMatcher(matcher) {
  if (matcher === 'self') {
    return matcher;
  } else if (isString(matcher)) {
    // Strings match exactly except for 2 wildcards - '*' and '**'.
    // '*' matches any character except those from the set ':/.?&'.
    // '**' matches any character (like .* in a RegExp).
    // More than 2 *'s raises an error as it's ill defined.
    if (matcher.indexOf('***') > -1) {
      throw $sceMinErr('iwcard',
          'Illegal sequence *** in string matcher.  String: {0}', matcher);
    }
    matcher = escapeForRegexp(matcher).
                  replace('\\*\\*', '.*').
                  replace('\\*', '[^:/.?&;]*');
    return new RegExp('^' + matcher + '$');
  } else if (isRegExp(matcher)) {
    // The only other type of matcher allowed is a Regexp.
    // Match entire URL / disallow partial matches.
    // Flags are reset (i.e. no global, ignoreCase or multiline)
    return new RegExp('^' + matcher.source + '$');
  } else {
    throw $sceMinErr('imatcher',
        'Matchers may only be "self", string patterns or RegExp objects');
  }
}


function adjustMatchers(matchers) {
  var adjustedMatchers = [];
  if (isDefined(matchers)) {
    forEach(matchers, function(matcher) {
      adjustedMatchers.push(adjustMatcher(matcher));
    });
  }
  return adjustedMatchers;
}


/**
 * @ngdoc service
 * @name $sceDelegate
 * @kind function
 *
 * @description
 *
 * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
 * Contextual Escaping (SCE)} services to AngularJS.
 *
 * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of
 * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS.  This is
 * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to
 * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things
 * work because `$sce` delegates to `$sceDelegate` for these operations.
 *
 * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.
 *
 * The default instance of `$sceDelegate` should work out of the box with little pain.  While you
 * can override it completely to change the behavior of `$sce`, the common case would
 * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
 * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as
 * templates.  Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist
 * $sceDelegateProvider.resourceUrlWhitelist} and {@link
 * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
 */

/**
 * @ngdoc provider
 * @name $sceDelegateProvider
 * @description
 *
 * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
 * $sceDelegate} service.  This allows one to get/set the whitelists and blacklists used to ensure
 * that the URLs used for sourcing Angular templates are safe.  Refer {@link
 * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and
 * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
 *
 * For the general details about this service in Angular, read the main page for {@link ng.$sce
 * Strict Contextual Escaping (SCE)}.
 *
 * **Example**:  Consider the following case. <a name="example"></a>
 *
 * - your app is hosted at url `http://myapp.example.com/`
 * - but some of your templates are hosted on other domains you control such as
 *   `http://srv01.assets.example.com/`,  `http://srv02.assets.example.com/`, etc.
 * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.
 *
 * Here is what a secure configuration for this scenario might look like:
 *
 * ```
 *  angular.module('myApp', []).config(function($sceDelegateProvider) {
 *    $sceDelegateProvider.resourceUrlWhitelist([
 *      // Allow same origin resource loads.
 *      'self',
 *      // Allow loading from our assets domain.  Notice the difference between * and **.
 *      'http://srv*.assets.example.com/**'
 *    ]);
 *
 *    // The blacklist overrides the whitelist so the open redirect here is blocked.
 *    $sceDelegateProvider.resourceUrlBlacklist([
 *      'http://myapp.example.com/clickThru**'
 *    ]);
 *  });
 * ```
 */

function $SceDelegateProvider() {
  this.SCE_CONTEXTS = SCE_CONTEXTS;

  // Resource URLs can also be trusted by policy.
  var resourceUrlWhitelist = ['self'],
      resourceUrlBlacklist = [];

  /**
   * @ngdoc method
   * @name $sceDelegateProvider#resourceUrlWhitelist
   * @kind function
   *
   * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
   *     provided.  This must be an array or null.  A snapshot of this array is used so further
   *     changes to the array are ignored.
   *
   *     Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
   *     allowed in this array.
   *
   *     Note: **an empty whitelist array will block all URLs**!
   *
   * @return {Array} the currently set whitelist array.
   *
   * The **default value** when no whitelist has been explicitly set is `['self']` allowing only
   * same origin resource requests.
   *
   * @description
   * Sets/Gets the whitelist of trusted resource URLs.
   */
  this.resourceUrlWhitelist = function(value) {
    if (arguments.length) {
      resourceUrlWhitelist = adjustMatchers(value);
    }
    return resourceUrlWhitelist;
  };

  /**
   * @ngdoc method
   * @name $sceDelegateProvider#resourceUrlBlacklist
   * @kind function
   *
   * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
   *     provided.  This must be an array or null.  A snapshot of this array is used so further
   *     changes to the array are ignored.
   *
   *     Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
   *     allowed in this array.
   *
   *     The typical usage for the blacklist is to **block
   *     [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
   *     these would otherwise be trusted but actually return content from the redirected domain.
   *
   *     Finally, **the blacklist overrides the whitelist** and has the final say.
   *
   * @return {Array} the currently set blacklist array.
   *
   * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there
   * is no blacklist.)
   *
   * @description
   * Sets/Gets the blacklist of trusted resource URLs.
   */

  this.resourceUrlBlacklist = function(value) {
    if (arguments.length) {
      resourceUrlBlacklist = adjustMatchers(value);
    }
    return resourceUrlBlacklist;
  };

  this.$get = ['$injector', function($injector) {

    var htmlSanitizer = function htmlSanitizer(html) {
      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
    };

    if ($injector.has('$sanitize')) {
      htmlSanitizer = $injector.get('$sanitize');
    }


    function matchUrl(matcher, parsedUrl) {
      if (matcher === 'self') {
        return urlIsSameOrigin(parsedUrl);
      } else {
        // definitely a regex.  See adjustMatchers()
        return !!matcher.exec(parsedUrl.href);
      }
    }

    function isResourceUrlAllowedByPolicy(url) {
      var parsedUrl = urlResolve(url.toString());
      var i, n, allowed = false;
      // Ensure that at least one item from the whitelist allows this url.
      for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
        if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
          allowed = true;
          break;
        }
      }
      if (allowed) {
        // Ensure that no item from the blacklist blocked this url.
        for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
          if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
            allowed = false;
            break;
          }
        }
      }
      return allowed;
    }

    function generateHolderType(Base) {
      var holderType = function TrustedValueHolderType(trustedValue) {
        this.$$unwrapTrustedValue = function() {
          return trustedValue;
        };
      };
      if (Base) {
        holderType.prototype = new Base();
      }
      holderType.prototype.valueOf = function sceValueOf() {
        return this.$$unwrapTrustedValue();
      };
      holderType.prototype.toString = function sceToString() {
        return this.$$unwrapTrustedValue().toString();
      };
      return holderType;
    }

    var trustedValueHolderBase = generateHolderType(),
        byType = {};

    byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);
    byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);
    byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);
    byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);
    byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);

    /**
     * @ngdoc method
     * @name $sceDelegate#trustAs
     *
     * @description
     * Returns an object that is trusted by angular for use in specified strict
     * contextual escaping contexts (such as ng-bind-html, ng-include, any src
     * attribute interpolation, any dom event binding attribute interpolation
     * such as for onclick,  etc.) that uses the provided value.
     * See {@link ng.$sce $sce} for enabling strict contextual escaping.
     *
     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,
     *   resourceUrl, html, js and css.
     * @param {*} value The value that that should be considered trusted/safe.
     * @returns {*} A value that can be used to stand in for the provided `value` in places
     * where Angular expects a $sce.trustAs() return value.
     */
    function trustAs(type, trustedValue) {
      var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
      if (!Constructor) {
        throw $sceMinErr('icontext',
            'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',
            type, trustedValue);
      }
      if (trustedValue === null || trustedValue === undefined || trustedValue === '') {
        return trustedValue;
      }
      // All the current contexts in SCE_CONTEXTS happen to be strings.  In order to avoid trusting
      // mutable objects, we ensure here that the value passed in is actually a string.
      if (typeof trustedValue !== 'string') {
        throw $sceMinErr('itype',
            'Attempted to trust a non-string value in a content requiring a string: Context: {0}',
            type);
      }
      return new Constructor(trustedValue);
    }

    /**
     * @ngdoc method
     * @name $sceDelegate#valueOf
     *
     * @description
     * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs
     * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link
     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.
     *
     * If the passed parameter is not a value that had been returned by {@link
     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is.
     *
     * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}
     *      call or anything else.
     * @returns {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs
     *     `$sceDelegate.trustAs`} if `value` is the result of such a call.  Otherwise, returns
     *     `value` unchanged.
     */
    function valueOf(maybeTrusted) {
      if (maybeTrusted instanceof trustedValueHolderBase) {
        return maybeTrusted.$$unwrapTrustedValue();
      } else {
        return maybeTrusted;
      }
    }

    /**
     * @ngdoc method
     * @name $sceDelegate#getTrusted
     *
     * @description
     * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and
     * returns the originally supplied value if the queried context type is a supertype of the
     * created type.  If this condition isn't satisfied, throws an exception.
     *
     * @param {string} type The kind of context in which this value is to be used.
     * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs
     *     `$sceDelegate.trustAs`} call.
     * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs
     *     `$sceDelegate.trustAs`} if valid in this context.  Otherwise, throws an exception.
     */
    function getTrusted(type, maybeTrusted) {
      if (maybeTrusted === null || maybeTrusted === undefined || maybeTrusted === '') {
        return maybeTrusted;
      }
      var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
      if (constructor && maybeTrusted instanceof constructor) {
        return maybeTrusted.$$unwrapTrustedValue();
      }
      // If we get here, then we may only take one of two actions.
      // 1. sanitize the value for the requested type, or
      // 2. throw an exception.
      if (type === SCE_CONTEXTS.RESOURCE_URL) {
        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
          return maybeTrusted;
        } else {
          throw $sceMinErr('insecurl',
              'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',
              maybeTrusted.toString());
        }
      } else if (type === SCE_CONTEXTS.HTML) {
        return htmlSanitizer(maybeTrusted);
      }
      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
    }

    return { trustAs: trustAs,
             getTrusted: getTrusted,
             valueOf: valueOf };
  }];
}


/**
 * @ngdoc provider
 * @name $sceProvider
 * @description
 *
 * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.
 * -   enable/disable Strict Contextual Escaping (SCE) in a module
 * -   override the default implementation with a custom delegate
 *
 * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.
 */

/* jshint maxlen: false*/

/**
 * @ngdoc service
 * @name $sce
 * @kind function
 *
 * @description
 *
 * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.
 *
 * # Strict Contextual Escaping
 *
 * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain
 * contexts to result in a value that is marked as safe to use for that context.  One example of
 * such a context is binding arbitrary html controlled by the user via `ng-bind-html`.  We refer
 * to these contexts as privileged or SCE contexts.
 *
 * As of version 1.2, Angular ships with SCE enabled by default.
 *
 * Note:  When enabled (the default), IE<11 in quirks mode is not supported.  In this mode, IE<11 allow
 * one to execute arbitrary javascript by the use of the expression() syntax.  Refer
 * <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.
 * You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`
 * to the top of your HTML document.
 *
 * SCE assists in writing code in way that (a) is secure by default and (b) makes auditing for
 * security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
 *
 * Here's an example of a binding in a privileged context:
 *
 * ```
 * <input ng-model="userHtml">
 * <div ng-bind-html="userHtml"></div>
 * ```
 *
 * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user.  With SCE
 * disabled, this application allows the user to render arbitrary HTML into the DIV.
 * In a more realistic example, one may be rendering user comments, blog articles, etc. via
 * bindings.  (HTML is just one example of a context where rendering user controlled input creates
 * security vulnerabilities.)
 *
 * For the case of HTML, you might use a library, either on the client side, or on the server side,
 * to sanitize unsafe HTML before binding to the value and rendering it in the document.
 *
 * How would you ensure that every place that used these types of bindings was bound to a value that
 * was sanitized by your library (or returned as safe for rendering by your server?)  How can you
 * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some
 * properties/fields and forgot to update the binding to the sanitized value?
 *
 * To be secure by default, you want to ensure that any such bindings are disallowed unless you can
 * determine that something explicitly says it's safe to use a value for binding in that
 * context.  You can then audit your code (a simple grep would do) to ensure that this is only done
 * for those values that you can easily tell are safe - because they were received from your server,
 * sanitized by your library, etc.  You can organize your codebase to help with this - perhaps
 * allowing only the files in a specific directory to do this.  Ensuring that the internal API
 * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.
 *
 * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs}
 * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to
 * obtain values that will be accepted by SCE / privileged contexts.
 *
 *
 * ## How does it work?
 *
 * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted
 * $sce.getTrusted(context, value)} rather than to the value directly.  Directives use {@link
 * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the
 * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
 *
 * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
 * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}.  Here's the actual code (slightly
 * simplified):
 *
 * ```
 * var ngBindHtmlDirective = ['$sce', function($sce) {
 *   return function(scope, element, attr) {
 *     scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
 *       element.html(value || '');
 *     });
 *   };
 * }];
 * ```
 *
 * ## Impact on loading templates
 *
 * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as
 * `templateUrl`'s specified by {@link guide/directive directives}.
 *
 * By default, Angular only loads templates from the same domain and protocol as the application
 * document.  This is done by calling {@link ng.$sce#getTrustedResourceUrl
 * $sce.getTrustedResourceUrl} on the template URL.  To load templates from other domains and/or
 * protocols, you may either either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist
 * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.
 *
 * *Please note*:
 * The browser's
 * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
 * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)
 * policy apply in addition to this and may further restrict whether the template is successfully
 * loaded.  This means that without the right CORS policy, loading templates from a different domain
 * won't work on all browsers.  Also, loading templates from `file://` URL does not work on some
 * browsers.
 *
 * ## This feels like too much overhead
 *
 * It's important to remember that SCE only applies to interpolation expressions.
 *
 * If your expressions are constant literals, they're automatically trusted and you don't need to
 * call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.
 * `<div ng-bind-html="'<b>implicitly trusted</b>'"></div>`) just works.
 *
 * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
 * through {@link ng.$sce#getTrusted $sce.getTrusted}.  SCE doesn't play a role here.
 *
 * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load
 * templates in `ng-include` from your application's domain without having to even know about SCE.
 * It blocks loading templates from other domains or loading templates over http from an https
 * served document.  You can change these by setting your own custom {@link
 * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link
 * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.
 *
 * This significantly reduces the overhead.  It is far easier to pay the small overhead and have an
 * application that's secure and can be audited to verify that with much more ease than bolting
 * security onto an application later.
 *
 * <a name="contexts"></a>
 * ## What trusted context types are supported?
 *
 * | Context             | Notes          |
 * |---------------------|----------------|
 * | `$sce.HTML`         | For HTML that's safe to source into the application.  The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |
 * | `$sce.CSS`          | For CSS that's safe to source into the application.  Currently unused.  Feel free to use it in your own directives. |
 * | `$sce.URL`          | For URLs that are safe to follow as links.  Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |
 * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application.  Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.)  <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
 * | `$sce.JS`           | For JavaScript that is safe to execute in your application's context.  Currently unused.  Feel free to use it in your own directives. |
 *
 * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a>
 *
 *  Each element in these arrays must be one of the following:
 *
 *  - **'self'**
 *    - The special **string**, `'self'`, can be used to match against all URLs of the **same
 *      domain** as the application document using the **same protocol**.
 *  - **String** (except the special value `'self'`)
 *    - The string is matched against the full *normalized / absolute URL* of the resource
 *      being tested (substring matches are not good enough.)
 *    - There are exactly **two wildcard sequences** - `*` and `**`.  All other characters
 *      match themselves.
 *    - `*`: matches zero or more occurrences of any character other than one of the following 6
 *      characters: '`:`', '`/`', '`.`', '`?`', '`&`' and ';'.  It's a useful wildcard for use
 *      in a whitelist.
 *    - `**`: matches zero or more occurrences of *any* character.  As such, it's not
 *      appropriate for use in a scheme, domain, etc. as it would match too much.  (e.g.
 *      http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might
 *      not have been the intention.)  Its usage at the very end of the path is ok.  (e.g.
 *      http://foo.example.com/templates/**).
 *  - **RegExp** (*see caveat below*)
 *    - *Caveat*:  While regular expressions are powerful and offer great flexibility,  their syntax
 *      (and all the inevitable escaping) makes them *harder to maintain*.  It's easy to
 *      accidentally introduce a bug when one updates a complex expression (imho, all regexes should
 *      have good test coverage).  For instance, the use of `.` in the regex is correct only in a
 *      small number of cases.  A `.` character in the regex used when matching the scheme or a
 *      subdomain could be matched against a `:` or literal `.` that was likely not intended.   It
 *      is highly recommended to use the string patterns and only fall back to regular expressions
 *      as a last resort.
 *    - The regular expression must be an instance of RegExp (i.e. not a string.)  It is
 *      matched against the **entire** *normalized / absolute URL* of the resource being tested
 *      (even when the RegExp did not have the `^` and `$` codes.)  In addition, any flags
 *      present on the RegExp (such as multiline, global, ignoreCase) are ignored.
 *    - If you are generating your JavaScript from some other templating engine (not
 *      recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),
 *      remember to escape your regular expression (and be aware that you might need more than
 *      one level of escaping depending on your templating engine and the way you interpolated
 *      the value.)  Do make use of your platform's escaping mechanism as it might be good
 *      enough before coding your own.  E.g. Ruby has
 *      [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape)
 *      and Python has [re.escape](http://docs.python.org/library/re.html#re.escape).
 *      Javascript lacks a similar built in function for escaping.  Take a look at Google
 *      Closure library's [goog.string.regExpEscape(s)](
 *      http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962).
 *
 * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example.
 *
 * ## Show me an example using SCE.
 *
 * <example module="mySceApp" deps="angular-sanitize.js">
 * <file name="index.html">
 *   <div ng-controller="AppController as myCtrl">
 *     <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
 *     <b>User comments</b><br>
 *     By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
 *     $sanitize is available.  If $sanitize isn't available, this results in an error instead of an
 *     exploit.
 *     <div class="well">
 *       <div ng-repeat="userComment in myCtrl.userComments">
 *         <b>{{userComment.name}}</b>:
 *         <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
 *         <br>
 *       </div>
 *     </div>
 *   </div>
 * </file>
 *
 * <file name="script.js">
 *   angular.module('mySceApp', ['ngSanitize'])
 *     .controller('AppController', ['$http', '$templateCache', '$sce',
 *       function($http, $templateCache, $sce) {
 *         var self = this;
 *         $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
 *           self.userComments = userComments;
 *         });
 *         self.explicitlyTrustedHtml = $sce.trustAsHtml(
 *             '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
 *             'sanitization.&quot;">Hover over this text.</span>');
 *       }]);
 * </file>
 *
 * <file name="test_data.json">
 * [
 *   { "name": "Alice",
 *     "htmlComment":
 *         "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
 *   },
 *   { "name": "Bob",
 *     "htmlComment": "<i>Yes!</i>  Am I the only other one?"
 *   }
 * ]
 * </file>
 *
 * <file name="protractor.js" type="protractor">
 *   describe('SCE doc demo', function() {
 *     it('should sanitize untrusted values', function() {
 *       expect(element.all(by.css('.htmlComment')).first().getInnerHtml())
 *           .toBe('<span>Is <i>anyone</i> reading this?</span>');
 *     });
 *
 *     it('should NOT sanitize explicitly trusted values', function() {
 *       expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
 *           '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
 *           'sanitization.&quot;">Hover over this text.</span>');
 *     });
 *   });
 * </file>
 * </example>
 *
 *
 *
 * ## Can I disable SCE completely?
 *
 * Yes, you can.  However, this is strongly discouraged.  SCE gives you a lot of security benefits
 * for little coding overhead.  It will be much harder to take an SCE disabled application and
 * either secure it on your own or enable SCE at a later stage.  It might make sense to disable SCE
 * for cases where you have a lot of existing code that was written before SCE was introduced and
 * you're migrating them a module at a time.
 *
 * That said, here's how you can completely disable SCE:
 *
 * ```
 * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
 *   // Completely disable SCE.  For demonstration purposes only!
 *   // Do not use in new projects.
 *   $sceProvider.enabled(false);
 * });
 * ```
 *
 */
/* jshint maxlen: 100 */

function $SceProvider() {
  var enabled = true;

  /**
   * @ngdoc method
   * @name $sceProvider#enabled
   * @kind function
   *
   * @param {boolean=} value If provided, then enables/disables SCE.
   * @return {boolean} true if SCE is enabled, false otherwise.
   *
   * @description
   * Enables/disables SCE and returns the current value.
   */
  this.enabled = function(value) {
    if (arguments.length) {
      enabled = !!value;
    }
    return enabled;
  };


  /* Design notes on the default implementation for SCE.
   *
   * The API contract for the SCE delegate
   * -------------------------------------
   * The SCE delegate object must provide the following 3 methods:
   *
   * - trustAs(contextEnum, value)
   *     This method is used to tell the SCE service that the provided value is OK to use in the
   *     contexts specified by contextEnum.  It must return an object that will be accepted by
   *     getTrusted() for a compatible contextEnum and return this value.
   *
   * - valueOf(value)
   *     For values that were not produced by trustAs(), return them as is.  For values that were
   *     produced by trustAs(), return the corresponding input value to trustAs.  Basically, if
   *     trustAs is wrapping the given values into some type, this operation unwraps it when given
   *     such a value.
   *
   * - getTrusted(contextEnum, value)
   *     This function should return the a value that is safe to use in the context specified by
   *     contextEnum or throw and exception otherwise.
   *
   * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be
   * opaque or wrapped in some holder object.  That happens to be an implementation detail.  For
   * instance, an implementation could maintain a registry of all trusted objects by context.  In
   * such a case, trustAs() would return the same object that was passed in.  getTrusted() would
   * return the same object passed in if it was found in the registry under a compatible context or
   * throw an exception otherwise.  An implementation might only wrap values some of the time based
   * on some criteria.  getTrusted() might return a value and not throw an exception for special
   * constants or objects even if not wrapped.  All such implementations fulfill this contract.
   *
   *
   * A note on the inheritance model for SCE contexts
   * ------------------------------------------------
   * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types.  This
   * is purely an implementation details.
   *
   * The contract is simply this:
   *
   *     getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value)
   *     will also succeed.
   *
   * Inheritance happens to capture this in a natural way.  In some future, we
   * may not use inheritance anymore.  That is OK because no code outside of
   * sce.js and sceSpecs.js would need to be aware of this detail.
   */

  this.$get = ['$parse', '$sceDelegate', function(
                $parse,   $sceDelegate) {
    // Prereq: Ensure that we're not running in IE<11 quirks mode.  In that mode, IE < 11 allow
    // the "expression(javascript expression)" syntax which is insecure.
    if (enabled && msie < 8) {
      throw $sceMinErr('iequirks',
        'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
        'mode.  You can fix this by adding the text <!doctype html> to the top of your HTML ' +
        'document.  See http://docs.angularjs.org/api/ng.$sce for more information.');
    }

    var sce = shallowCopy(SCE_CONTEXTS);

    /**
     * @ngdoc method
     * @name $sce#isEnabled
     * @kind function
     *
     * @return {Boolean} true if SCE is enabled, false otherwise.  If you want to set the value, you
     * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.
     *
     * @description
     * Returns a boolean indicating if SCE is enabled.
     */
    sce.isEnabled = function() {
      return enabled;
    };
    sce.trustAs = $sceDelegate.trustAs;
    sce.getTrusted = $sceDelegate.getTrusted;
    sce.valueOf = $sceDelegate.valueOf;

    if (!enabled) {
      sce.trustAs = sce.getTrusted = function(type, value) { return value; };
      sce.valueOf = identity;
    }

    /**
     * @ngdoc method
     * @name $sce#parseAs
     *
     * @description
     * Converts Angular {@link guide/expression expression} into a function.  This is like {@link
     * ng.$parse $parse} and is identical when the expression is a literal constant.  Otherwise, it
     * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,
     * *result*)}
     *
     * @param {string} type The kind of SCE context in which this result will be used.
     * @param {string} expression String expression to compile.
     * @returns {function(context, locals)} a function which represents the compiled expression:
     *
     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
     *      are evaluated against (typically a scope object).
     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
     *      `context`.
     */
    sce.parseAs = function sceParseAs(type, expr) {
      var parsed = $parse(expr);
      if (parsed.literal && parsed.constant) {
        return parsed;
      } else {
        return $parse(expr, function(value) {
          return sce.getTrusted(type, value);
        });
      }
    };

    /**
     * @ngdoc method
     * @name $sce#trustAs
     *
     * @description
     * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.  As such,
     * returns an object that is trusted by angular for use in specified strict contextual
     * escaping contexts (such as ng-bind-html, ng-include, any src attribute
     * interpolation, any dom event binding attribute interpolation such as for onclick,  etc.)
     * that uses the provided value.  See * {@link ng.$sce $sce} for enabling strict contextual
     * escaping.
     *
     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,
     *   resource_url, html, js and css.
     * @param {*} value The value that that should be considered trusted/safe.
     * @returns {*} A value that can be used to stand in for the provided `value` in places
     * where Angular expects a $sce.trustAs() return value.
     */

    /**
     * @ngdoc method
     * @name $sce#trustAsHtml
     *
     * @description
     * Shorthand method.  `$sce.trustAsHtml(value)` →
     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}
     *
     * @param {*} value The value to trustAs.
     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml
     *     $sce.getTrustedHtml(value)} to obtain the original value.  (privileged directives
     *     only accept expressions that are either literal constants or are the
     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
     */

    /**
     * @ngdoc method
     * @name $sce#trustAsUrl
     *
     * @description
     * Shorthand method.  `$sce.trustAsUrl(value)` →
     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}
     *
     * @param {*} value The value to trustAs.
     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl
     *     $sce.getTrustedUrl(value)} to obtain the original value.  (privileged directives
     *     only accept expressions that are either literal constants or are the
     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
     */

    /**
     * @ngdoc method
     * @name $sce#trustAsResourceUrl
     *
     * @description
     * Shorthand method.  `$sce.trustAsResourceUrl(value)` →
     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}
     *
     * @param {*} value The value to trustAs.
     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl
     *     $sce.getTrustedResourceUrl(value)} to obtain the original value.  (privileged directives
     *     only accept expressions that are either literal constants or are the return
     *     value of {@link ng.$sce#trustAs $sce.trustAs}.)
     */

    /**
     * @ngdoc method
     * @name $sce#trustAsJs
     *
     * @description
     * Shorthand method.  `$sce.trustAsJs(value)` →
     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}
     *
     * @param {*} value The value to trustAs.
     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs
     *     $sce.getTrustedJs(value)} to obtain the original value.  (privileged directives
     *     only accept expressions that are either literal constants or are the
     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
     */

    /**
     * @ngdoc method
     * @name $sce#getTrusted
     *
     * @description
     * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}.  As such,
     * takes the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the
     * originally supplied value if the queried context type is a supertype of the created type.
     * If this condition isn't satisfied, throws an exception.
     *
     * @param {string} type The kind of context in which this value is to be used.
     * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`}
     *                         call.
     * @returns {*} The value the was originally provided to
     *              {@link ng.$sce#trustAs `$sce.trustAs`} if valid in this context.
     *              Otherwise, throws an exception.
     */

    /**
     * @ngdoc method
     * @name $sce#getTrustedHtml
     *
     * @description
     * Shorthand method.  `$sce.getTrustedHtml(value)` →
     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}
     *
     * @param {*} value The value to pass to `$sce.getTrusted`.
     * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)`
     */

    /**
     * @ngdoc method
     * @name $sce#getTrustedCss
     *
     * @description
     * Shorthand method.  `$sce.getTrustedCss(value)` →
     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}
     *
     * @param {*} value The value to pass to `$sce.getTrusted`.
     * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)`
     */

    /**
     * @ngdoc method
     * @name $sce#getTrustedUrl
     *
     * @description
     * Shorthand method.  `$sce.getTrustedUrl(value)` →
     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}
     *
     * @param {*} value The value to pass to `$sce.getTrusted`.
     * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)`
     */

    /**
     * @ngdoc method
     * @name $sce#getTrustedResourceUrl
     *
     * @description
     * Shorthand method.  `$sce.getTrustedResourceUrl(value)` →
     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}
     *
     * @param {*} value The value to pass to `$sceDelegate.getTrusted`.
     * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`
     */

    /**
     * @ngdoc method
     * @name $sce#getTrustedJs
     *
     * @description
     * Shorthand method.  `$sce.getTrustedJs(value)` →
     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}
     *
     * @param {*} value The value to pass to `$sce.getTrusted`.
     * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)`
     */

    /**
     * @ngdoc method
     * @name $sce#parseAsHtml
     *
     * @description
     * Shorthand method.  `$sce.parseAsHtml(expression string)` →
     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}
     *
     * @param {string} expression String expression to compile.
     * @returns {function(context, locals)} a function which represents the compiled expression:
     *
     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
     *      are evaluated against (typically a scope object).
     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
     *      `context`.
     */

    /**
     * @ngdoc method
     * @name $sce#parseAsCss
     *
     * @description
     * Shorthand method.  `$sce.parseAsCss(value)` →
     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}
     *
     * @param {string} expression String expression to compile.
     * @returns {function(context, locals)} a function which represents the compiled expression:
     *
     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
     *      are evaluated against (typically a scope object).
     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
     *      `context`.
     */

    /**
     * @ngdoc method
     * @name $sce#parseAsUrl
     *
     * @description
     * Shorthand method.  `$sce.parseAsUrl(value)` →
     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}
     *
     * @param {string} expression String expression to compile.
     * @returns {function(context, locals)} a function which represents the compiled expression:
     *
     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
     *      are evaluated against (typically a scope object).
     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
     *      `context`.
     */

    /**
     * @ngdoc method
     * @name $sce#parseAsResourceUrl
     *
     * @description
     * Shorthand method.  `$sce.parseAsResourceUrl(value)` →
     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
     *
     * @param {string} expression String expression to compile.
     * @returns {function(context, locals)} a function which represents the compiled expression:
     *
     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
     *      are evaluated against (typically a scope object).
     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
     *      `context`.
     */

    /**
     * @ngdoc method
     * @name $sce#parseAsJs
     *
     * @description
     * Shorthand method.  `$sce.parseAsJs(value)` →
     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}
     *
     * @param {string} expression String expression to compile.
     * @returns {function(context, locals)} a function which represents the compiled expression:
     *
     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
     *      are evaluated against (typically a scope object).
     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
     *      `context`.
     */

    // Shorthand delegations.
    var parse = sce.parseAs,
        getTrusted = sce.getTrusted,
        trustAs = sce.trustAs;

    forEach(SCE_CONTEXTS, function(enumValue, name) {
      var lName = lowercase(name);
      sce[camelCase("parse_as_" + lName)] = function(expr) {
        return parse(enumValue, expr);
      };
      sce[camelCase("get_trusted_" + lName)] = function(value) {
        return getTrusted(enumValue, value);
      };
      sce[camelCase("trust_as_" + lName)] = function(value) {
        return trustAs(enumValue, value);
      };
    });

    return sce;
  }];
}

/**
 * !!! This is an undocumented "private" service !!!
 *
 * @name $sniffer
 * @requires $window
 * @requires $document
 *
 * @property {boolean} history Does the browser support html5 history api ?
 * @property {boolean} transitions Does the browser support CSS transition events ?
 * @property {boolean} animations Does the browser support CSS animation events ?
 *
 * @description
 * This is very simple implementation of testing browser's features.
 */
function $SnifferProvider() {
  this.$get = ['$window', '$document', function($window, $document) {
    var eventSupport = {},
        android =
          int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
        boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
        document = $document[0] || {},
        vendorPrefix,
        vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/,
        bodyStyle = document.body && document.body.style,
        transitions = false,
        animations = false,
        match;

    if (bodyStyle) {
      for (var prop in bodyStyle) {
        if (match = vendorRegex.exec(prop)) {
          vendorPrefix = match[0];
          vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
          break;
        }
      }

      if (!vendorPrefix) {
        vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit';
      }

      transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
      animations  = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));

      if (android && (!transitions ||  !animations)) {
        transitions = isString(document.body.style.webkitTransition);
        animations = isString(document.body.style.webkitAnimation);
      }
    }


    return {
      // Android has history.pushState, but it does not update location correctly
      // so let's not use the history API at all.
      // http://code.google.com/p/android/issues/detail?id=17471
      // https://github.com/angular/angular.js/issues/904

      // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
      // so let's not use the history API also
      // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
      // jshint -W018
      history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee),
      // jshint +W018
      hasEvent: function(event) {
        // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
        // it. In particular the event is not fired when backspace or delete key are pressed or
        // when cut operation is performed.
        // IE10+ implements 'input' event but it erroneously fires under various situations,
        // e.g. when placeholder changes, or a form is focused.
        if (event === 'input' && msie <= 11) return false;

        if (isUndefined(eventSupport[event])) {
          var divElm = document.createElement('div');
          eventSupport[event] = 'on' + event in divElm;
        }

        return eventSupport[event];
      },
      csp: csp(),
      vendorPrefix: vendorPrefix,
      transitions: transitions,
      animations: animations,
      android: android
    };
  }];
}

var $compileMinErr = minErr('$compile');

/**
 * @ngdoc service
 * @name $templateRequest
 *
 * @description
 * The `$templateRequest` service runs security checks then downloads the provided template using
 * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request
 * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the
 * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the
 * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted
 * when `tpl` is of type string and `$templateCache` has the matching entry.
 *
 * @param {string|TrustedResourceUrl} tpl The HTTP request template URL
 * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty
 *
 * @return {Promise} the HTTP Promise for the given.
 *
 * @property {number} totalPendingRequests total amount of pending template requests being downloaded.
 */
function $TemplateRequestProvider() {
  this.$get = ['$templateCache', '$http', '$q', '$sce', function($templateCache, $http, $q, $sce) {
    function handleRequestFn(tpl, ignoreRequestError) {
      handleRequestFn.totalPendingRequests++;

      // We consider the template cache holds only trusted templates, so
      // there's no need to go through whitelisting again for keys that already
      // are included in there. This also makes Angular accept any script
      // directive, no matter its name. However, we still need to unwrap trusted
      // types.
      if (!isString(tpl) || !$templateCache.get(tpl)) {
        tpl = $sce.getTrustedResourceUrl(tpl);
      }

      var transformResponse = $http.defaults && $http.defaults.transformResponse;

      if (isArray(transformResponse)) {
        transformResponse = transformResponse.filter(function(transformer) {
          return transformer !== defaultHttpResponseTransform;
        });
      } else if (transformResponse === defaultHttpResponseTransform) {
        transformResponse = null;
      }

      var httpOptions = {
        cache: $templateCache,
        transformResponse: transformResponse
      };

      return $http.get(tpl, httpOptions)
        ['finally'](function() {
          handleRequestFn.totalPendingRequests--;
        })
        .then(function(response) {
          return response.data;
        }, handleError);

      function handleError(resp) {
        if (!ignoreRequestError) {
          throw $compileMinErr('tpload', 'Failed to load template: {0}', tpl);
        }
        return $q.reject(resp);
      }
    }

    handleRequestFn.totalPendingRequests = 0;

    return handleRequestFn;
  }];
}

function $$TestabilityProvider() {
  this.$get = ['$rootScope', '$browser', '$location',
       function($rootScope,   $browser,   $location) {

    /**
     * @name $testability
     *
     * @description
     * The private $$testability service provides a collection of methods for use when debugging
     * or by automated test and debugging tools.
     */
    var testability = {};

    /**
     * @name $$testability#findBindings
     *
     * @description
     * Returns an array of elements that are bound (via ng-bind or {{}})
     * to expressions matching the input.
     *
     * @param {Element} element The element root to search from.
     * @param {string} expression The binding expression to match.
     * @param {boolean} opt_exactMatch If true, only returns exact matches
     *     for the expression. Filters and whitespace are ignored.
     */
    testability.findBindings = function(element, expression, opt_exactMatch) {
      var bindings = element.getElementsByClassName('ng-binding');
      var matches = [];
      forEach(bindings, function(binding) {
        var dataBinding = angular.element(binding).data('$binding');
        if (dataBinding) {
          forEach(dataBinding, function(bindingName) {
            if (opt_exactMatch) {
              var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)');
              if (matcher.test(bindingName)) {
                matches.push(binding);
              }
            } else {
              if (bindingName.indexOf(expression) != -1) {
                matches.push(binding);
              }
            }
          });
        }
      });
      return matches;
    };

    /**
     * @name $$testability#findModels
     *
     * @description
     * Returns an array of elements that are two-way found via ng-model to
     * expressions matching the input.
     *
     * @param {Element} element The element root to search from.
     * @param {string} expression The model expression to match.
     * @param {boolean} opt_exactMatch If true, only returns exact matches
     *     for the expression.
     */
    testability.findModels = function(element, expression, opt_exactMatch) {
      var prefixes = ['ng-', 'data-ng-', 'ng\\:'];
      for (var p = 0; p < prefixes.length; ++p) {
        var attributeEquals = opt_exactMatch ? '=' : '*=';
        var selector = '[' + prefixes[p] + 'model' + attributeEquals + '"' + expression + '"]';
        var elements = element.querySelectorAll(selector);
        if (elements.length) {
          return elements;
        }
      }
    };

    /**
     * @name $$testability#getLocation
     *
     * @description
     * Shortcut for getting the location in a browser agnostic way. Returns
     *     the path, search, and hash. (e.g. /path?a=b#hash)
     */
    testability.getLocation = function() {
      return $location.url();
    };

    /**
     * @name $$testability#setLocation
     *
     * @description
     * Shortcut for navigating to a location without doing a full page reload.
     *
     * @param {string} url The location url (path, search and hash,
     *     e.g. /path?a=b#hash) to go to.
     */
    testability.setLocation = function(url) {
      if (url !== $location.url()) {
        $location.url(url);
        $rootScope.$digest();
      }
    };

    /**
     * @name $$testability#whenStable
     *
     * @description
     * Calls the callback when $timeout and $http requests are completed.
     *
     * @param {function} callback
     */
    testability.whenStable = function(callback) {
      $browser.notifyWhenNoOutstandingRequests(callback);
    };

    return testability;
  }];
}

function $TimeoutProvider() {
  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
       function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {
    var deferreds = {};


     /**
      * @ngdoc service
      * @name $timeout
      *
      * @description
      * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
      * block and delegates any exceptions to
      * {@link ng.$exceptionHandler $exceptionHandler} service.
      *
      * The return value of registering a timeout function is a promise, which will be resolved when
      * the timeout is reached and the timeout function is executed.
      *
      * To cancel a timeout request, call `$timeout.cancel(promise)`.
      *
      * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
      * synchronously flush the queue of deferred functions.
      *
      * @param {function()} fn A function, whose execution should be delayed.
      * @param {number=} [delay=0] Delay in milliseconds.
      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
      * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
      *   promise will be resolved with is the return value of the `fn` function.
      *
      */
    function timeout(fn, delay, invokeApply) {
      var skipApply = (isDefined(invokeApply) && !invokeApply),
          deferred = (skipApply ? $$q : $q).defer(),
          promise = deferred.promise,
          timeoutId;

      timeoutId = $browser.defer(function() {
        try {
          deferred.resolve(fn());
        } catch (e) {
          deferred.reject(e);
          $exceptionHandler(e);
        }
        finally {
          delete deferreds[promise.$$timeoutId];
        }

        if (!skipApply) $rootScope.$apply();
      }, delay);

      promise.$$timeoutId = timeoutId;
      deferreds[timeoutId] = deferred;

      return promise;
    }


     /**
      * @ngdoc method
      * @name $timeout#cancel
      *
      * @description
      * Cancels a task associated with the `promise`. As a result of this, the promise will be
      * resolved with a rejection.
      *
      * @param {Promise=} promise Promise returned by the `$timeout` function.
      * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
      *   canceled.
      */
    timeout.cancel = function(promise) {
      if (promise && promise.$$timeoutId in deferreds) {
        deferreds[promise.$$timeoutId].reject('canceled');
        delete deferreds[promise.$$timeoutId];
        return $browser.defer.cancel(promise.$$timeoutId);
      }
      return false;
    };

    return timeout;
  }];
}

// NOTE:  The usage of window and document instead of $window and $document here is
// deliberate.  This service depends on the specific behavior of anchor nodes created by the
// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and
// cause us to break tests.  In addition, when the browser resolves a URL for XHR, it
// doesn't know about mocked locations and resolves URLs to the real document - which is
// exactly the behavior needed here.  There is little value is mocking these out for this
// service.
var urlParsingNode = document.createElement("a");
var originUrl = urlResolve(window.location.href);


/**
 *
 * Implementation Notes for non-IE browsers
 * ----------------------------------------
 * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,
 * results both in the normalizing and parsing of the URL.  Normalizing means that a relative
 * URL will be resolved into an absolute URL in the context of the application document.
 * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related
 * properties are all populated to reflect the normalized URL.  This approach has wide
 * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc.  See
 * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
 *
 * Implementation Notes for IE
 * ---------------------------
 * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other
 * browsers.  However, the parsed components will not be set if the URL assigned did not specify
 * them.  (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.)  We
 * work around that by performing the parsing in a 2nd step by taking a previously normalized
 * URL (e.g. by assigning to a.href) and assigning it a.href again.  This correctly populates the
 * properties such as protocol, hostname, port, etc.
 *
 * References:
 *   http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement
 *   http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
 *   http://url.spec.whatwg.org/#urlutils
 *   https://github.com/angular/angular.js/pull/2902
 *   http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
 *
 * @kind function
 * @param {string} url The URL to be parsed.
 * @description Normalizes and parses a URL.
 * @returns {object} Returns the normalized URL as a dictionary.
 *
 *   | member name   | Description    |
 *   |---------------|----------------|
 *   | href          | A normalized version of the provided URL if it was not an absolute URL |
 *   | protocol      | The protocol including the trailing colon                              |
 *   | host          | The host and port (if the port is non-default) of the normalizedUrl    |
 *   | search        | The search params, minus the question mark                             |
 *   | hash          | The hash string, minus the hash symbol
 *   | hostname      | The hostname
 *   | port          | The port, without ":"
 *   | pathname      | The pathname, beginning with "/"
 *
 */
function urlResolve(url) {
  var href = url;

  if (msie) {
    // Normalize before parse.  Refer Implementation Notes on why this is
    // done in two steps on IE.
    urlParsingNode.setAttribute("href", href);
    href = urlParsingNode.href;
  }

  urlParsingNode.setAttribute('href', href);

  // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
  return {
    href: urlParsingNode.href,
    protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
    host: urlParsingNode.host,
    search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
    hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
    hostname: urlParsingNode.hostname,
    port: urlParsingNode.port,
    pathname: (urlParsingNode.pathname.charAt(0) === '/')
      ? urlParsingNode.pathname
      : '/' + urlParsingNode.pathname
  };
}

/**
 * Parse a request URL and determine whether this is a same-origin request as the application document.
 *
 * @param {string|object} requestUrl The url of the request as a string that will be resolved
 * or a parsed URL object.
 * @returns {boolean} Whether the request is for the same origin as the application document.
 */
function urlIsSameOrigin(requestUrl) {
  var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;
  return (parsed.protocol === originUrl.protocol &&
          parsed.host === originUrl.host);
}

/**
 * @ngdoc service
 * @name $window
 *
 * @description
 * A reference to the browser's `window` object. While `window`
 * is globally available in JavaScript, it causes testability problems, because
 * it is a global variable. In angular we always refer to it through the
 * `$window` service, so it may be overridden, removed or mocked for testing.
 *
 * Expressions, like the one defined for the `ngClick` directive in the example
 * below, are evaluated with respect to the current scope.  Therefore, there is
 * no risk of inadvertently coding in a dependency on a global value in such an
 * expression.
 *
 * @example
   <example module="windowExample">
     <file name="index.html">
       <script>
         angular.module('windowExample', [])
           .controller('ExampleController', ['$scope', '$window', function($scope, $window) {
             $scope.greeting = 'Hello, World!';
             $scope.doGreeting = function(greeting) {
               $window.alert(greeting);
             };
           }]);
       </script>
       <div ng-controller="ExampleController">
         <input type="text" ng-model="greeting" />
         <button ng-click="doGreeting(greeting)">ALERT</button>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
      it('should display the greeting in the input box', function() {
       element(by.model('greeting')).sendKeys('Hello, E2E Tests');
       // If we click the button it will block the test runner
       // element(':button').click();
      });
     </file>
   </example>
 */
function $WindowProvider() {
  this.$get = valueFn(window);
}

/* global currencyFilter: true,
 dateFilter: true,
 filterFilter: true,
 jsonFilter: true,
 limitToFilter: true,
 lowercaseFilter: true,
 numberFilter: true,
 orderByFilter: true,
 uppercaseFilter: true,
 */

/**
 * @ngdoc provider
 * @name $filterProvider
 * @description
 *
 * Filters are just functions which transform input to an output. However filters need to be
 * Dependency Injected. To achieve this a filter definition consists of a factory function which is
 * annotated with dependencies and is responsible for creating a filter function.
 *
 * <div class="alert alert-warning">
 * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
 * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
 * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
 * (`myapp_subsection_filterx`).
 * </div>
 *
 * ```js
 *   // Filter registration
 *   function MyModule($provide, $filterProvider) {
 *     // create a service to demonstrate injection (not always needed)
 *     $provide.value('greet', function(name){
 *       return 'Hello ' + name + '!';
 *     });
 *
 *     // register a filter factory which uses the
 *     // greet service to demonstrate DI.
 *     $filterProvider.register('greet', function(greet){
 *       // return the filter function which uses the greet service
 *       // to generate salutation
 *       return function(text) {
 *         // filters need to be forgiving so check input validity
 *         return text && greet(text) || text;
 *       };
 *     });
 *   }
 * ```
 *
 * The filter function is registered with the `$injector` under the filter name suffix with
 * `Filter`.
 *
 * ```js
 *   it('should be the same instance', inject(
 *     function($filterProvider) {
 *       $filterProvider.register('reverse', function(){
 *         return ...;
 *       });
 *     },
 *     function($filter, reverseFilter) {
 *       expect($filter('reverse')).toBe(reverseFilter);
 *     });
 * ```
 *
 *
 * For more information about how angular filters work, and how to create your own filters, see
 * {@link guide/filter Filters} in the Angular Developer Guide.
 */

/**
 * @ngdoc service
 * @name $filter
 * @kind function
 * @description
 * Filters are used for formatting data displayed to the user.
 *
 * The general syntax in templates is as follows:
 *
 *         {{ expression [| filter_name[:parameter_value] ... ] }}
 *
 * @param {String} name Name of the filter function to retrieve
 * @return {Function} the filter function
 * @example
   <example name="$filter" module="filterExample">
     <file name="index.html">
       <div ng-controller="MainCtrl">
        <h3>{{ originalText }}</h3>
        <h3>{{ filteredText }}</h3>
       </div>
     </file>

     <file name="script.js">
      angular.module('filterExample', [])
      .controller('MainCtrl', function($scope, $filter) {
        $scope.originalText = 'hello';
        $scope.filteredText = $filter('uppercase')($scope.originalText);
      });
     </file>
   </example>
  */
$FilterProvider.$inject = ['$provide'];
function $FilterProvider($provide) {
  var suffix = 'Filter';

  /**
   * @ngdoc method
   * @name $filterProvider#register
   * @param {string|Object} name Name of the filter function, or an object map of filters where
   *    the keys are the filter names and the values are the filter factories.
   *
   *    <div class="alert alert-warning">
   *    **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
   *    Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
   *    your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
   *    (`myapp_subsection_filterx`).
   *    </div>
   * @returns {Object} Registered filter instance, or if a map of filters was provided then a map
   *    of the registered filter instances.
   */
  function register(name, factory) {
    if (isObject(name)) {
      var filters = {};
      forEach(name, function(filter, key) {
        filters[key] = register(key, filter);
      });
      return filters;
    } else {
      return $provide.factory(name + suffix, factory);
    }
  }
  this.register = register;

  this.$get = ['$injector', function($injector) {
    return function(name) {
      return $injector.get(name + suffix);
    };
  }];

  ////////////////////////////////////////

  /* global
    currencyFilter: false,
    dateFilter: false,
    filterFilter: false,
    jsonFilter: false,
    limitToFilter: false,
    lowercaseFilter: false,
    numberFilter: false,
    orderByFilter: false,
    uppercaseFilter: false,
  */

  register('currency', currencyFilter);
  register('date', dateFilter);
  register('filter', filterFilter);
  register('json', jsonFilter);
  register('limitTo', limitToFilter);
  register('lowercase', lowercaseFilter);
  register('number', numberFilter);
  register('orderBy', orderByFilter);
  register('uppercase', uppercaseFilter);
}

/**
 * @ngdoc filter
 * @name filter
 * @kind function
 *
 * @description
 * Selects a subset of items from `array` and returns it as a new array.
 *
 * @param {Array} array The source array.
 * @param {string|Object|function()} expression The predicate to be used for selecting items from
 *   `array`.
 *
 *   Can be one of:
 *
 *   - `string`: The string is used for matching against the contents of the `array`. All strings or
 *     objects with string properties in `array` that match this string will be returned. This also
 *     applies to nested object properties.
 *     The predicate can be negated by prefixing the string with `!`.
 *
 *   - `Object`: A pattern object can be used to filter specific properties on objects contained
 *     by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
 *     which have property `name` containing "M" and property `phone` containing "1". A special
 *     property name `$` can be used (as in `{$:"text"}`) to accept a match against any
 *     property of the object or its nested object properties. That's equivalent to the simple
 *     substring match with a `string` as described above. The predicate can be negated by prefixing
 *     the string with `!`.
 *     For example `{name: "!M"}` predicate will return an array of items which have property `name`
 *     not containing "M".
 *
 *     Note that a named property will match properties on the same level only, while the special
 *     `$` property will match properties on the same level or deeper. E.g. an array item like
 *     `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but
 *     **will** be matched by `{$: 'John'}`.
 *
 *   - `function(value, index)`: A predicate function can be used to write arbitrary filters. The
 *     function is called for each element of `array`. The final result is an array of those
 *     elements that the predicate returned true for.
 *
 * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
 *     determining if the expected value (from the filter expression) and actual value (from
 *     the object in the array) should be considered a match.
 *
 *   Can be one of:
 *
 *   - `function(actual, expected)`:
 *     The function will be given the object value and the predicate value to compare and
 *     should return true if both values should be considered equal.
 *
 *   - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`.
 *     This is essentially strict comparison of expected and actual.
 *
 *   - `false|undefined`: A short hand for a function which will look for a substring match in case
 *     insensitive way.
 *
 * @example
   <example>
     <file name="index.html">
       <div ng-init="friends = [{name:'John', phone:'555-1276'},
                                {name:'Mary', phone:'800-BIG-MARY'},
                                {name:'Mike', phone:'555-4321'},
                                {name:'Adam', phone:'555-5678'},
                                {name:'Julie', phone:'555-8765'},
                                {name:'Juliette', phone:'555-5678'}]"></div>

       Search: <input ng-model="searchText">
       <table id="searchTextResults">
         <tr><th>Name</th><th>Phone</th></tr>
         <tr ng-repeat="friend in friends | filter:searchText">
           <td>{{friend.name}}</td>
           <td>{{friend.phone}}</td>
         </tr>
       </table>
       <hr>
       Any: <input ng-model="search.$"> <br>
       Name only <input ng-model="search.name"><br>
       Phone only <input ng-model="search.phone"><br>
       Equality <input type="checkbox" ng-model="strict"><br>
       <table id="searchObjResults">
         <tr><th>Name</th><th>Phone</th></tr>
         <tr ng-repeat="friendObj in friends | filter:search:strict">
           <td>{{friendObj.name}}</td>
           <td>{{friendObj.phone}}</td>
         </tr>
       </table>
     </file>
     <file name="protractor.js" type="protractor">
       var expectFriendNames = function(expectedNames, key) {
         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
           arr.forEach(function(wd, i) {
             expect(wd.getText()).toMatch(expectedNames[i]);
           });
         });
       };

       it('should search across all fields when filtering with a string', function() {
         var searchText = element(by.model('searchText'));
         searchText.clear();
         searchText.sendKeys('m');
         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');

         searchText.clear();
         searchText.sendKeys('76');
         expectFriendNames(['John', 'Julie'], 'friend');
       });

       it('should search in specific fields when filtering with a predicate object', function() {
         var searchAny = element(by.model('search.$'));
         searchAny.clear();
         searchAny.sendKeys('i');
         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
       });
       it('should use a equal comparison when comparator is true', function() {
         var searchName = element(by.model('search.name'));
         var strict = element(by.model('strict'));
         searchName.clear();
         searchName.sendKeys('Julie');
         strict.click();
         expectFriendNames(['Julie'], 'friendObj');
       });
     </file>
   </example>
 */
function filterFilter() {
  return function(array, expression, comparator) {
    if (!isArray(array)) return array;

    var expressionType = (expression !== null) ? typeof expression : 'null';
    var predicateFn;
    var matchAgainstAnyProp;

    switch (expressionType) {
      case 'function':
        predicateFn = expression;
        break;
      case 'boolean':
      case 'null':
      case 'number':
      case 'string':
        matchAgainstAnyProp = true;
        //jshint -W086
      case 'object':
        //jshint +W086
        predicateFn = createPredicateFn(expression, comparator, matchAgainstAnyProp);
        break;
      default:
        return array;
    }

    return array.filter(predicateFn);
  };
}

// Helper functions for `filterFilter`
function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
  var shouldMatchPrimitives = isObject(expression) && ('$' in expression);
  var predicateFn;

  if (comparator === true) {
    comparator = equals;
  } else if (!isFunction(comparator)) {
    comparator = function(actual, expected) {
      if (isUndefined(actual)) {
        // No substring matching against `undefined`
        return false;
      }
      if ((actual === null) || (expected === null)) {
        // No substring matching against `null`; only match against `null`
        return actual === expected;
      }
      if (isObject(actual) || isObject(expected)) {
        // Prevent an object to be considered equal to a string like `'[object'`
        return false;
      }

      actual = lowercase('' + actual);
      expected = lowercase('' + expected);
      return actual.indexOf(expected) !== -1;
    };
  }

  predicateFn = function(item) {
    if (shouldMatchPrimitives && !isObject(item)) {
      return deepCompare(item, expression.$, comparator, false);
    }
    return deepCompare(item, expression, comparator, matchAgainstAnyProp);
  };

  return predicateFn;
}

function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) {
  var actualType = (actual !== null) ? typeof actual : 'null';
  var expectedType = (expected !== null) ? typeof expected : 'null';

  if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
    return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp);
  } else if (isArray(actual)) {
    // In case `actual` is an array, consider it a match
    // if ANY of it's items matches `expected`
    return actual.some(function(item) {
      return deepCompare(item, expected, comparator, matchAgainstAnyProp);
    });
  }

  switch (actualType) {
    case 'object':
      var key;
      if (matchAgainstAnyProp) {
        for (key in actual) {
          if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, true)) {
            return true;
          }
        }
        return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, false);
      } else if (expectedType === 'object') {
        for (key in expected) {
          var expectedVal = expected[key];
          if (isFunction(expectedVal) || isUndefined(expectedVal)) {
            continue;
          }

          var matchAnyProperty = key === '$';
          var actualVal = matchAnyProperty ? actual : actual[key];
          if (!deepCompare(actualVal, expectedVal, comparator, matchAnyProperty, matchAnyProperty)) {
            return false;
          }
        }
        return true;
      } else {
        return comparator(actual, expected);
      }
      break;
    case 'function':
      return false;
    default:
      return comparator(actual, expected);
  }
}

/**
 * @ngdoc filter
 * @name currency
 * @kind function
 *
 * @description
 * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default
 * symbol for current locale is used.
 *
 * @param {number} amount Input to filter.
 * @param {string=} symbol Currency symbol or identifier to be displayed.
 * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale
 * @returns {string} Formatted number.
 *
 *
 * @example
   <example module="currencyExample">
     <file name="index.html">
       <script>
         angular.module('currencyExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.amount = 1234.56;
           }]);
       </script>
       <div ng-controller="ExampleController">
         <input type="number" ng-model="amount"> <br>
         default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
         custom currency identifier (USD$): <span id="currency-custom">{{amount | currency:"USD$"}}</span>
         no fractions (0): <span id="currency-no-fractions">{{amount | currency:"USD$":0}}</span>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
       it('should init with 1234.56', function() {
         expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
         expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56');
         expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235');
       });
       it('should update', function() {
         if (browser.params.browser == 'safari') {
           // Safari does not understand the minus key. See
           // https://github.com/angular/protractor/issues/481
           return;
         }
         element(by.model('amount')).clear();
         element(by.model('amount')).sendKeys('-1234');
         expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
         expect(element(by.id('currency-custom')).getText()).toBe('(USD$1,234.00)');
         expect(element(by.id('currency-no-fractions')).getText()).toBe('(USD$1,234)');
       });
     </file>
   </example>
 */
currencyFilter.$inject = ['$locale'];
function currencyFilter($locale) {
  var formats = $locale.NUMBER_FORMATS;
  return function(amount, currencySymbol, fractionSize) {
    if (isUndefined(currencySymbol)) {
      currencySymbol = formats.CURRENCY_SYM;
    }

    if (isUndefined(fractionSize)) {
      fractionSize = formats.PATTERNS[1].maxFrac;
    }

    // if null or undefined pass it through
    return (amount == null)
        ? amount
        : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).
            replace(/\u00A4/g, currencySymbol);
  };
}

/**
 * @ngdoc filter
 * @name number
 * @kind function
 *
 * @description
 * Formats a number as text.
 *
 * If the input is null or undefined, it will just be returned.
 * If the input is infinite (Infinity/-Infinity) the Infinity symbol '∞' is returned.
 * If the input is not a number an empty string is returned.
 *
 * @param {number|string} number Number to format.
 * @param {(number|string)=} fractionSize Number of decimal places to round the number to.
 * If this is not provided then the fraction size is computed from the current locale's number
 * formatting pattern. In the case of the default locale, it will be 3.
 * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
 *
 * @example
   <example module="numberFilterExample">
     <file name="index.html">
       <script>
         angular.module('numberFilterExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.val = 1234.56789;
           }]);
       </script>
       <div ng-controller="ExampleController">
         Enter number: <input ng-model='val'><br>
         Default formatting: <span id='number-default'>{{val | number}}</span><br>
         No fractions: <span>{{val | number:0}}</span><br>
         Negative number: <span>{{-val | number:4}}</span>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
       it('should format numbers', function() {
         expect(element(by.id('number-default')).getText()).toBe('1,234.568');
         expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
         expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
       });

       it('should update', function() {
         element(by.model('val')).clear();
         element(by.model('val')).sendKeys('3374.333');
         expect(element(by.id('number-default')).getText()).toBe('3,374.333');
         expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
         expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
      });
     </file>
   </example>
 */


numberFilter.$inject = ['$locale'];
function numberFilter($locale) {
  var formats = $locale.NUMBER_FORMATS;
  return function(number, fractionSize) {

    // if null or undefined pass it through
    return (number == null)
        ? number
        : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP,
                       fractionSize);
  };
}

var DECIMAL_SEP = '.';
function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
  if (!isFinite(number) || isObject(number)) return '';

  var isNegative = number < 0;
  number = Math.abs(number);
  var numStr = number + '',
      formatedText = '',
      parts = [];

  var hasExponent = false;
  if (numStr.indexOf('e') !== -1) {
    var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
    if (match && match[2] == '-' && match[3] > fractionSize + 1) {
      number = 0;
    } else {
      formatedText = numStr;
      hasExponent = true;
    }
  }

  if (!hasExponent) {
    var fractionLen = (numStr.split(DECIMAL_SEP)[1] || '').length;

    // determine fractionSize if it is not specified
    if (isUndefined(fractionSize)) {
      fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac);
    }

    // safely round numbers in JS without hitting imprecisions of floating-point arithmetics
    // inspired by:
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
    number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);

    var fraction = ('' + number).split(DECIMAL_SEP);
    var whole = fraction[0];
    fraction = fraction[1] || '';

    var i, pos = 0,
        lgroup = pattern.lgSize,
        group = pattern.gSize;

    if (whole.length >= (lgroup + group)) {
      pos = whole.length - lgroup;
      for (i = 0; i < pos; i++) {
        if ((pos - i) % group === 0 && i !== 0) {
          formatedText += groupSep;
        }
        formatedText += whole.charAt(i);
      }
    }

    for (i = pos; i < whole.length; i++) {
      if ((whole.length - i) % lgroup === 0 && i !== 0) {
        formatedText += groupSep;
      }
      formatedText += whole.charAt(i);
    }

    // format fraction part.
    while (fraction.length < fractionSize) {
      fraction += '0';
    }

    if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
  } else {
    if (fractionSize > 0 && number < 1) {
      formatedText = number.toFixed(fractionSize);
      number = parseFloat(formatedText);
    }
  }

  if (number === 0) {
    isNegative = false;
  }

  parts.push(isNegative ? pattern.negPre : pattern.posPre,
             formatedText,
             isNegative ? pattern.negSuf : pattern.posSuf);
  return parts.join('');
}

function padNumber(num, digits, trim) {
  var neg = '';
  if (num < 0) {
    neg =  '-';
    num = -num;
  }
  num = '' + num;
  while (num.length < digits) num = '0' + num;
  if (trim)
    num = num.substr(num.length - digits);
  return neg + num;
}


function dateGetter(name, size, offset, trim) {
  offset = offset || 0;
  return function(date) {
    var value = date['get' + name]();
    if (offset > 0 || value > -offset)
      value += offset;
    if (value === 0 && offset == -12) value = 12;
    return padNumber(value, size, trim);
  };
}

function dateStrGetter(name, shortForm) {
  return function(date, formats) {
    var value = date['get' + name]();
    var get = uppercase(shortForm ? ('SHORT' + name) : name);

    return formats[get][value];
  };
}

function timeZoneGetter(date) {
  var zone = -1 * date.getTimezoneOffset();
  var paddedZone = (zone >= 0) ? "+" : "";

  paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
                padNumber(Math.abs(zone % 60), 2);

  return paddedZone;
}

function getFirstThursdayOfYear(year) {
    // 0 = index of January
    var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();
    // 4 = index of Thursday (+1 to account for 1st = 5)
    // 11 = index of *next* Thursday (+1 account for 1st = 12)
    return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);
}

function getThursdayThisWeek(datetime) {
    return new Date(datetime.getFullYear(), datetime.getMonth(),
      // 4 = index of Thursday
      datetime.getDate() + (4 - datetime.getDay()));
}

function weekGetter(size) {
   return function(date) {
      var firstThurs = getFirstThursdayOfYear(date.getFullYear()),
         thisThurs = getThursdayThisWeek(date);

      var diff = +thisThurs - +firstThurs,
         result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week

      return padNumber(result, size);
   };
}

function ampmGetter(date, formats) {
  return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
}

function eraGetter(date, formats) {
  return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];
}

function longEraGetter(date, formats) {
  return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];
}

var DATE_FORMATS = {
  yyyy: dateGetter('FullYear', 4),
    yy: dateGetter('FullYear', 2, 0, true),
     y: dateGetter('FullYear', 1),
  MMMM: dateStrGetter('Month'),
   MMM: dateStrGetter('Month', true),
    MM: dateGetter('Month', 2, 1),
     M: dateGetter('Month', 1, 1),
    dd: dateGetter('Date', 2),
     d: dateGetter('Date', 1),
    HH: dateGetter('Hours', 2),
     H: dateGetter('Hours', 1),
    hh: dateGetter('Hours', 2, -12),
     h: dateGetter('Hours', 1, -12),
    mm: dateGetter('Minutes', 2),
     m: dateGetter('Minutes', 1),
    ss: dateGetter('Seconds', 2),
     s: dateGetter('Seconds', 1),
     // while ISO 8601 requires fractions to be prefixed with `.` or `,`
     // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
   sss: dateGetter('Milliseconds', 3),
  EEEE: dateStrGetter('Day'),
   EEE: dateStrGetter('Day', true),
     a: ampmGetter,
     Z: timeZoneGetter,
    ww: weekGetter(2),
     w: weekGetter(1),
     G: eraGetter,
     GG: eraGetter,
     GGG: eraGetter,
     GGGG: longEraGetter
};

var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
    NUMBER_STRING = /^\-?\d+$/;

/**
 * @ngdoc filter
 * @name date
 * @kind function
 *
 * @description
 *   Formats `date` to a string based on the requested `format`.
 *
 *   `format` string can be composed of the following elements:
 *
 *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)
 *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
 *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)
 *   * `'MMMM'`: Month in year (January-December)
 *   * `'MMM'`: Month in year (Jan-Dec)
 *   * `'MM'`: Month in year, padded (01-12)
 *   * `'M'`: Month in year (1-12)
 *   * `'dd'`: Day in month, padded (01-31)
 *   * `'d'`: Day in month (1-31)
 *   * `'EEEE'`: Day in Week,(Sunday-Saturday)
 *   * `'EEE'`: Day in Week, (Sun-Sat)
 *   * `'HH'`: Hour in day, padded (00-23)
 *   * `'H'`: Hour in day (0-23)
 *   * `'hh'`: Hour in AM/PM, padded (01-12)
 *   * `'h'`: Hour in AM/PM, (1-12)
 *   * `'mm'`: Minute in hour, padded (00-59)
 *   * `'m'`: Minute in hour (0-59)
 *   * `'ss'`: Second in minute, padded (00-59)
 *   * `'s'`: Second in minute (0-59)
 *   * `'sss'`: Millisecond in second, padded (000-999)
 *   * `'a'`: AM/PM marker
 *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
 *   * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year
 *   * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year
 *   * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')
 *   * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')
 *
 *   `format` string can also be one of the following predefined
 *   {@link guide/i18n localizable formats}:
 *
 *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale
 *     (e.g. Sep 3, 2010 12:05:08 PM)
 *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 PM)
 *   * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US  locale
 *     (e.g. Friday, September 3, 2010)
 *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010)
 *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010)
 *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
 *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM)
 *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM)
 *
 *   `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g.
 *   `"h 'in the morning'"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence
 *   (e.g. `"h 'o''clock'"`).
 *
 * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
 *    number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its
 *    shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
 *    specified in the string input, the time is considered to be in the local timezone.
 * @param {string=} format Formatting rules (see Description). If not specified,
 *    `mediumDate` is used.
 * @param {string=} timezone Timezone to be used for formatting. Right now, only `'UTC'` is supported.
 *    If not specified, the timezone of the browser will be used.
 * @returns {string} Formatted string or the input if input is not recognized as date/millis.
 *
 * @example
   <example>
     <file name="index.html">
       <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
           <span>{{1288323623006 | date:'medium'}}</span><br>
       <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
          <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
       <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
          <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
       <span ng-non-bindable>{{1288323623006 | date:"MM/dd/yyyy 'at' h:mma"}}</span>:
          <span>{{'1288323623006' | date:"MM/dd/yyyy 'at' h:mma"}}</span><br>
     </file>
     <file name="protractor.js" type="protractor">
       it('should format date', function() {
         expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
            toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
         expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
            toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
         expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
            toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
         expect(element(by.binding("'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"")).getText()).
            toMatch(/10\/2\d\/2010 at \d{1,2}:\d{2}(AM|PM)/);
       });
     </file>
   </example>
 */
dateFilter.$inject = ['$locale'];
function dateFilter($locale) {


  var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
                     // 1        2       3         4          5          6          7          8  9     10      11
  function jsonStringToDate(string) {
    var match;
    if (match = string.match(R_ISO8601_STR)) {
      var date = new Date(0),
          tzHour = 0,
          tzMin  = 0,
          dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
          timeSetter = match[8] ? date.setUTCHours : date.setHours;

      if (match[9]) {
        tzHour = int(match[9] + match[10]);
        tzMin = int(match[9] + match[11]);
      }
      dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
      var h = int(match[4] || 0) - tzHour;
      var m = int(match[5] || 0) - tzMin;
      var s = int(match[6] || 0);
      var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
      timeSetter.call(date, h, m, s, ms);
      return date;
    }
    return string;
  }


  return function(date, format, timezone) {
    var text = '',
        parts = [],
        fn, match;

    format = format || 'mediumDate';
    format = $locale.DATETIME_FORMATS[format] || format;
    if (isString(date)) {
      date = NUMBER_STRING.test(date) ? int(date) : jsonStringToDate(date);
    }

    if (isNumber(date)) {
      date = new Date(date);
    }

    if (!isDate(date)) {
      return date;
    }

    while (format) {
      match = DATE_FORMATS_SPLIT.exec(format);
      if (match) {
        parts = concat(parts, match, 1);
        format = parts.pop();
      } else {
        parts.push(format);
        format = null;
      }
    }

    if (timezone && timezone === 'UTC') {
      date = new Date(date.getTime());
      date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
    }
    forEach(parts, function(value) {
      fn = DATE_FORMATS[value];
      text += fn ? fn(date, $locale.DATETIME_FORMATS)
                 : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
    });

    return text;
  };
}


/**
 * @ngdoc filter
 * @name json
 * @kind function
 *
 * @description
 *   Allows you to convert a JavaScript object into JSON string.
 *
 *   This filter is mostly useful for debugging. When using the double curly {{value}} notation
 *   the binding is automatically converted to JSON.
 *
 * @param {*} object Any JavaScript object (including arrays and primitive types) to filter.
 * @param {number=} spacing The number of spaces to use per indentation, defaults to 2.
 * @returns {string} JSON string.
 *
 *
 * @example
   <example>
     <file name="index.html">
       <pre id="default-spacing">{{ {'name':'value'} | json }}</pre>
       <pre id="custom-spacing">{{ {'name':'value'} | json:4 }}</pre>
     </file>
     <file name="protractor.js" type="protractor">
       it('should jsonify filtered objects', function() {
         expect(element(by.id('default-spacing')).getText()).toMatch(/\{\n  "name": ?"value"\n}/);
         expect(element(by.id('custom-spacing')).getText()).toMatch(/\{\n    "name": ?"value"\n}/);
       });
     </file>
   </example>
 *
 */
function jsonFilter() {
  return function(object, spacing) {
    if (isUndefined(spacing)) {
        spacing = 2;
    }
    return toJson(object, spacing);
  };
}


/**
 * @ngdoc filter
 * @name lowercase
 * @kind function
 * @description
 * Converts string to lowercase.
 * @see angular.lowercase
 */
var lowercaseFilter = valueFn(lowercase);


/**
 * @ngdoc filter
 * @name uppercase
 * @kind function
 * @description
 * Converts string to uppercase.
 * @see angular.uppercase
 */
var uppercaseFilter = valueFn(uppercase);

/**
 * @ngdoc filter
 * @name limitTo
 * @kind function
 *
 * @description
 * Creates a new array or string containing only a specified number of elements. The elements
 * are taken from either the beginning or the end of the source array, string or number, as specified by
 * the value and sign (positive or negative) of `limit`. If a number is used as input, it is
 * converted to a string.
 *
 * @param {Array|string|number} input Source array, string or number to be limited.
 * @param {string|number} limit The length of the returned array or string. If the `limit` number
 *     is positive, `limit` number of items from the beginning of the source array/string are copied.
 *     If the number is negative, `limit` number  of items from the end of the source array/string
 *     are copied. The `limit` will be trimmed if it exceeds `array.length`
 * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
 *     had less than `limit` elements.
 *
 * @example
   <example module="limitToExample">
     <file name="index.html">
       <script>
         angular.module('limitToExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.numbers = [1,2,3,4,5,6,7,8,9];
             $scope.letters = "abcdefghi";
             $scope.longNumber = 2345432342;
             $scope.numLimit = 3;
             $scope.letterLimit = 3;
             $scope.longNumberLimit = 3;
           }]);
       </script>
       <div ng-controller="ExampleController">
         Limit {{numbers}} to: <input type="number" step="1" ng-model="numLimit">
         <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
         Limit {{letters}} to: <input type="number" step="1" ng-model="letterLimit">
         <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
         Limit {{longNumber}} to: <input type="number" step="1" ng-model="longNumberLimit">
         <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
       var numLimitInput = element(by.model('numLimit'));
       var letterLimitInput = element(by.model('letterLimit'));
       var longNumberLimitInput = element(by.model('longNumberLimit'));
       var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
       var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
       var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));

       it('should limit the number array to first three items', function() {
         expect(numLimitInput.getAttribute('value')).toBe('3');
         expect(letterLimitInput.getAttribute('value')).toBe('3');
         expect(longNumberLimitInput.getAttribute('value')).toBe('3');
         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
         expect(limitedLetters.getText()).toEqual('Output letters: abc');
         expect(limitedLongNumber.getText()).toEqual('Output long number: 234');
       });

       // There is a bug in safari and protractor that doesn't like the minus key
       // it('should update the output when -3 is entered', function() {
       //   numLimitInput.clear();
       //   numLimitInput.sendKeys('-3');
       //   letterLimitInput.clear();
       //   letterLimitInput.sendKeys('-3');
       //   longNumberLimitInput.clear();
       //   longNumberLimitInput.sendKeys('-3');
       //   expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
       //   expect(limitedLetters.getText()).toEqual('Output letters: ghi');
       //   expect(limitedLongNumber.getText()).toEqual('Output long number: 342');
       // });

       it('should not exceed the maximum size of input array', function() {
         numLimitInput.clear();
         numLimitInput.sendKeys('100');
         letterLimitInput.clear();
         letterLimitInput.sendKeys('100');
         longNumberLimitInput.clear();
         longNumberLimitInput.sendKeys('100');
         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
         expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
         expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');
       });
     </file>
   </example>
*/
function limitToFilter() {
  return function(input, limit) {
    if (isNumber(input)) input = input.toString();
    if (!isArray(input) && !isString(input)) return input;

    if (Math.abs(Number(limit)) === Infinity) {
      limit = Number(limit);
    } else {
      limit = int(limit);
    }

    //NaN check on limit
    if (limit) {
      return limit > 0 ? input.slice(0, limit) : input.slice(limit);
    } else {
      return isString(input) ? "" : [];
    }
  };
}

/**
 * @ngdoc filter
 * @name orderBy
 * @kind function
 *
 * @description
 * Orders a specified `array` by the `expression` predicate. It is ordered alphabetically
 * for strings and numerically for numbers. Note: if you notice numbers are not being sorted
 * correctly, make sure they are actually being saved as numbers and not strings.
 *
 * @param {Array} array The array to sort.
 * @param {function(*)|string|Array.<(function(*)|string)>=} expression A predicate to be
 *    used by the comparator to determine the order of elements.
 *
 *    Can be one of:
 *
 *    - `function`: Getter function. The result of this function will be sorted using the
 *      `<`, `===`, `>` operator.
 *    - `string`: An Angular expression. The result of this expression is used to compare elements
 *      (for example `name` to sort by a property called `name` or `name.substr(0, 3)` to sort by
 *      3 first characters of a property called `name`). The result of a constant expression
 *      is interpreted as a property name to be used in comparisons (for example `"special name"`
 *      to sort object by the value of their `special name` property). An expression can be
 *      optionally prefixed with `+` or `-` to control ascending or descending sort order
 *      (for example, `+name` or `-name`). If no property is provided, (e.g. `'+'`) then the array
 *      element itself is used to compare where sorting.
 *    - `Array`: An array of function or string predicates. The first predicate in the array
 *      is used for sorting, but when two items are equivalent, the next predicate is used.
 *
 *    If the predicate is missing or empty then it defaults to `'+'`.
 *
 * @param {boolean=} reverse Reverse the order of the array.
 * @returns {Array} Sorted copy of the source array.
 *
 *
 * @example
 * The example below demonstrates a simple ngRepeat, where the data is sorted
 * by age in descending order (predicate is set to `'-age'`).
 * `reverse` is not set, which means it defaults to `false`.
   <example module="orderByExample">
     <file name="index.html">
       <script>
         angular.module('orderByExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.friends =
                 [{name:'John', phone:'555-1212', age:10},
                  {name:'Mary', phone:'555-9876', age:19},
                  {name:'Mike', phone:'555-4321', age:21},
                  {name:'Adam', phone:'555-5678', age:35},
                  {name:'Julie', phone:'555-8765', age:29}];
           }]);
       </script>
       <div ng-controller="ExampleController">
         <table class="friend">
           <tr>
             <th>Name</th>
             <th>Phone Number</th>
             <th>Age</th>
           </tr>
           <tr ng-repeat="friend in friends | orderBy:'-age'">
             <td>{{friend.name}}</td>
             <td>{{friend.phone}}</td>
             <td>{{friend.age}}</td>
           </tr>
         </table>
       </div>
     </file>
   </example>
 *
 * The predicate and reverse parameters can be controlled dynamically through scope properties,
 * as shown in the next example.
 * @example
   <example module="orderByExample">
     <file name="index.html">
       <script>
         angular.module('orderByExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.friends =
                 [{name:'John', phone:'555-1212', age:10},
                  {name:'Mary', phone:'555-9876', age:19},
                  {name:'Mike', phone:'555-4321', age:21},
                  {name:'Adam', phone:'555-5678', age:35},
                  {name:'Julie', phone:'555-8765', age:29}];
             $scope.predicate = '-age';
           }]);
       </script>
       <div ng-controller="ExampleController">
         <pre>Sorting predicate = {{predicate}}; reverse = {{reverse}}</pre>
         <hr/>
         [ <a href="" ng-click="predicate=''">unsorted</a> ]
         <table class="friend">
           <tr>
             <th><a href="" ng-click="predicate = 'name'; reverse=false">Name</a>
                 (<a href="" ng-click="predicate = '-name'; reverse=false">^</a>)</th>
             <th><a href="" ng-click="predicate = 'phone'; reverse=!reverse">Phone Number</a></th>
             <th><a href="" ng-click="predicate = 'age'; reverse=!reverse">Age</a></th>
           </tr>
           <tr ng-repeat="friend in friends | orderBy:predicate:reverse">
             <td>{{friend.name}}</td>
             <td>{{friend.phone}}</td>
             <td>{{friend.age}}</td>
           </tr>
         </table>
       </div>
     </file>
   </example>
 *
 * It's also possible to call the orderBy filter manually, by injecting `$filter`, retrieving the
 * filter routine with `$filter('orderBy')`, and calling the returned filter routine with the
 * desired parameters.
 *
 * Example:
 *
 * @example
  <example module="orderByExample">
    <file name="index.html">
      <div ng-controller="ExampleController">
        <table class="friend">
          <tr>
            <th><a href="" ng-click="reverse=false;order('name', false)">Name</a>
              (<a href="" ng-click="order('-name',false)">^</a>)</th>
            <th><a href="" ng-click="reverse=!reverse;order('phone', reverse)">Phone Number</a></th>
            <th><a href="" ng-click="reverse=!reverse;order('age',reverse)">Age</a></th>
          </tr>
          <tr ng-repeat="friend in friends">
            <td>{{friend.name}}</td>
            <td>{{friend.phone}}</td>
            <td>{{friend.age}}</td>
          </tr>
        </table>
      </div>
    </file>

    <file name="script.js">
      angular.module('orderByExample', [])
        .controller('ExampleController', ['$scope', '$filter', function($scope, $filter) {
          var orderBy = $filter('orderBy');
          $scope.friends = [
            { name: 'John',    phone: '555-1212',    age: 10 },
            { name: 'Mary',    phone: '555-9876',    age: 19 },
            { name: 'Mike',    phone: '555-4321',    age: 21 },
            { name: 'Adam',    phone: '555-5678',    age: 35 },
            { name: 'Julie',   phone: '555-8765',    age: 29 }
          ];
          $scope.order = function(predicate, reverse) {
            $scope.friends = orderBy($scope.friends, predicate, reverse);
          };
          $scope.order('-age',false);
        }]);
    </file>
</example>
 */
orderByFilter.$inject = ['$parse'];
function orderByFilter($parse) {
  return function(array, sortPredicate, reverseOrder) {
    if (!(isArrayLike(array))) return array;
    sortPredicate = isArray(sortPredicate) ? sortPredicate : [sortPredicate];
    if (sortPredicate.length === 0) { sortPredicate = ['+']; }
    sortPredicate = sortPredicate.map(function(predicate) {
      var descending = false, get = predicate || identity;
      if (isString(predicate)) {
        if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) {
          descending = predicate.charAt(0) == '-';
          predicate = predicate.substring(1);
        }
        if (predicate === '') {
          // Effectively no predicate was passed so we compare identity
          return reverseComparator(compare, descending);
        }
        get = $parse(predicate);
        if (get.constant) {
          var key = get();
          return reverseComparator(function(a, b) {
            return compare(a[key], b[key]);
          }, descending);
        }
      }
      return reverseComparator(function(a, b) {
        return compare(get(a),get(b));
      }, descending);
    });
    return slice.call(array).sort(reverseComparator(comparator, reverseOrder));

    function comparator(o1, o2) {
      for (var i = 0; i < sortPredicate.length; i++) {
        var comp = sortPredicate[i](o1, o2);
        if (comp !== 0) return comp;
      }
      return 0;
    }
    function reverseComparator(comp, descending) {
      return descending
          ? function(a, b) {return comp(b,a);}
          : comp;
    }

    function isPrimitive(value) {
      switch (typeof value) {
        case 'number': /* falls through */
        case 'boolean': /* falls through */
        case 'string':
          return true;
        default:
          return false;
      }
    }

    function objectToString(value) {
      if (value === null) return 'null';
      if (typeof value.valueOf === 'function') {
        value = value.valueOf();
        if (isPrimitive(value)) return value;
      }
      if (typeof value.toString === 'function') {
        value = value.toString();
        if (isPrimitive(value)) return value;
      }
      return '';
    }

    function compare(v1, v2) {
      var t1 = typeof v1;
      var t2 = typeof v2;
      if (t1 === t2 && t1 === "object") {
        v1 = objectToString(v1);
        v2 = objectToString(v2);
      }
      if (t1 === t2) {
        if (t1 === "string") {
           v1 = v1.toLowerCase();
           v2 = v2.toLowerCase();
        }
        if (v1 === v2) return 0;
        return v1 < v2 ? -1 : 1;
      } else {
        return t1 < t2 ? -1 : 1;
      }
    }
  };
}

function ngDirective(directive) {
  if (isFunction(directive)) {
    directive = {
      link: directive
    };
  }
  directive.restrict = directive.restrict || 'AC';
  return valueFn(directive);
}

/**
 * @ngdoc directive
 * @name a
 * @restrict E
 *
 * @description
 * Modifies the default behavior of the html A tag so that the default action is prevented when
 * the href attribute is empty.
 *
 * This change permits the easy creation of action links with the `ngClick` directive
 * without changing the location or causing page reloads, e.g.:
 * `<a href="" ng-click="list.addItem()">Add Item</a>`
 */
var htmlAnchorDirective = valueFn({
  restrict: 'E',
  compile: function(element, attr) {
    if (!attr.href && !attr.xlinkHref && !attr.name) {
      return function(scope, element) {
        // If the linked element is not an anchor tag anymore, do nothing
        if (element[0].nodeName.toLowerCase() !== 'a') return;

        // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
                   'xlink:href' : 'href';
        element.on('click', function(event) {
          // if we have no href url, then don't navigate anywhere.
          if (!element.attr(href)) {
            event.preventDefault();
          }
        });
      };
    }
  }
});

/**
 * @ngdoc directive
 * @name ngHref
 * @restrict A
 * @priority 99
 *
 * @description
 * Using Angular markup like `{{hash}}` in an href attribute will
 * make the link go to the wrong URL if the user clicks it before
 * Angular has a chance to replace the `{{hash}}` markup with its
 * value. Until Angular replaces the markup the link will be broken
 * and will most likely return a 404 error. The `ngHref` directive
 * solves this problem.
 *
 * The wrong way to write it:
 * ```html
 * <a href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
 * ```
 *
 * The correct way to write it:
 * ```html
 * <a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
 * ```
 *
 * @element A
 * @param {template} ngHref any string which can contain `{{}}` markup.
 *
 * @example
 * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes
 * in links and their different behaviors:
    <example>
      <file name="index.html">
        <input ng-model="value" /><br />
        <a id="link-1" href ng-click="value = 1">link 1</a> (link, don't reload)<br />
        <a id="link-2" href="" ng-click="value = 2">link 2</a> (link, don't reload)<br />
        <a id="link-3" ng-href="/{{'123'}}">link 3</a> (link, reload!)<br />
        <a id="link-4" href="" name="xx" ng-click="value = 4">anchor</a> (link, don't reload)<br />
        <a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
        <a id="link-6" ng-href="{{value}}">link</a> (link, change location)
      </file>
      <file name="protractor.js" type="protractor">
        it('should execute ng-click but not reload when href without value', function() {
          element(by.id('link-1')).click();
          expect(element(by.model('value')).getAttribute('value')).toEqual('1');
          expect(element(by.id('link-1')).getAttribute('href')).toBe('');
        });

        it('should execute ng-click but not reload when href empty string', function() {
          element(by.id('link-2')).click();
          expect(element(by.model('value')).getAttribute('value')).toEqual('2');
          expect(element(by.id('link-2')).getAttribute('href')).toBe('');
        });

        it('should execute ng-click and change url when ng-href specified', function() {
          expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);

          element(by.id('link-3')).click();

          // At this point, we navigate away from an Angular page, so we need
          // to use browser.driver to get the base webdriver.

          browser.wait(function() {
            return browser.driver.getCurrentUrl().then(function(url) {
              return url.match(/\/123$/);
            });
          }, 5000, 'page should navigate to /123');
        });

        xit('should execute ng-click but not reload when href empty string and name specified', function() {
          element(by.id('link-4')).click();
          expect(element(by.model('value')).getAttribute('value')).toEqual('4');
          expect(element(by.id('link-4')).getAttribute('href')).toBe('');
        });

        it('should execute ng-click but not reload when no href but name specified', function() {
          element(by.id('link-5')).click();
          expect(element(by.model('value')).getAttribute('value')).toEqual('5');
          expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
        });

        it('should only change url when only ng-href', function() {
          element(by.model('value')).clear();
          element(by.model('value')).sendKeys('6');
          expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);

          element(by.id('link-6')).click();

          // At this point, we navigate away from an Angular page, so we need
          // to use browser.driver to get the base webdriver.
          browser.wait(function() {
            return browser.driver.getCurrentUrl().then(function(url) {
              return url.match(/\/6$/);
            });
          }, 5000, 'page should navigate to /6');
        });
      </file>
    </example>
 */

/**
 * @ngdoc directive
 * @name ngSrc
 * @restrict A
 * @priority 99
 *
 * @description
 * Using Angular markup like `{{hash}}` in a `src` attribute doesn't
 * work right: The browser will fetch from the URL with the literal
 * text `{{hash}}` until Angular replaces the expression inside
 * `{{hash}}`. The `ngSrc` directive solves this problem.
 *
 * The buggy way to write it:
 * ```html
 * <img src="http://www.gravatar.com/avatar/{{hash}}"/>
 * ```
 *
 * The correct way to write it:
 * ```html
 * <img ng-src="http://www.gravatar.com/avatar/{{hash}}"/>
 * ```
 *
 * @element IMG
 * @param {template} ngSrc any string which can contain `{{}}` markup.
 */

/**
 * @ngdoc directive
 * @name ngSrcset
 * @restrict A
 * @priority 99
 *
 * @description
 * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't
 * work right: The browser will fetch from the URL with the literal
 * text `{{hash}}` until Angular replaces the expression inside
 * `{{hash}}`. The `ngSrcset` directive solves this problem.
 *
 * The buggy way to write it:
 * ```html
 * <img srcset="http://www.gravatar.com/avatar/{{hash}} 2x"/>
 * ```
 *
 * The correct way to write it:
 * ```html
 * <img ng-srcset="http://www.gravatar.com/avatar/{{hash}} 2x"/>
 * ```
 *
 * @element IMG
 * @param {template} ngSrcset any string which can contain `{{}}` markup.
 */

/**
 * @ngdoc directive
 * @name ngDisabled
 * @restrict A
 * @priority 100
 *
 * @description
 *
 * This directive sets the `disabled` attribute on the element if the
 * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
 *
 * A special directive is necessary because we cannot use interpolation inside the `disabled`
 * attribute.  The following example would make the button enabled on Chrome/Firefox
 * but not on older IEs:
 *
 * ```html
 * <!-- See below for an example of ng-disabled being used correctly -->
 * <div ng-init="isDisabled = false">
 *  <button disabled="{{isDisabled}}">Disabled</button>
 * </div>
 * ```
 *
 * This is because the HTML specification does not require browsers to preserve the values of
 * boolean attributes such as `disabled` (Their presence means true and their absence means false.)
 * If we put an Angular interpolation expression into such an attribute then the
 * binding information would be lost when the browser removes the attribute.
 *
 * @example
    <example>
      <file name="index.html">
        Click me to toggle: <input type="checkbox" ng-model="checked"><br/>
        <button ng-model="button" ng-disabled="checked">Button</button>
      </file>
      <file name="protractor.js" type="protractor">
        it('should toggle button', function() {
          expect(element(by.css('button')).getAttribute('disabled')).toBeFalsy();
          element(by.model('checked')).click();
          expect(element(by.css('button')).getAttribute('disabled')).toBeTruthy();
        });
      </file>
    </example>
 *
 * @element INPUT
 * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
 *     then the `disabled` attribute will be set on the element
 */


/**
 * @ngdoc directive
 * @name ngChecked
 * @restrict A
 * @priority 100
 *
 * @description
 * The HTML specification does not require browsers to preserve the values of boolean attributes
 * such as checked. (Their presence means true and their absence means false.)
 * If we put an Angular interpolation expression into such an attribute then the
 * binding information would be lost when the browser removes the attribute.
 * The `ngChecked` directive solves this problem for the `checked` attribute.
 * This complementary directive is not removed by the browser and so provides
 * a permanent reliable place to store the binding information.
 * @example
    <example>
      <file name="index.html">
        Check me to check both: <input type="checkbox" ng-model="master"><br/>
        <input id="checkSlave" type="checkbox" ng-checked="master">
      </file>
      <file name="protractor.js" type="protractor">
        it('should check both checkBoxes', function() {
          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
          element(by.model('master')).click();
          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
        });
      </file>
    </example>
 *
 * @element INPUT
 * @param {expression} ngChecked If the {@link guide/expression expression} is truthy,
 *     then special attribute "checked" will be set on the element
 */


/**
 * @ngdoc directive
 * @name ngReadonly
 * @restrict A
 * @priority 100
 *
 * @description
 * The HTML specification does not require browsers to preserve the values of boolean attributes
 * such as readonly. (Their presence means true and their absence means false.)
 * If we put an Angular interpolation expression into such an attribute then the
 * binding information would be lost when the browser removes the attribute.
 * The `ngReadonly` directive solves this problem for the `readonly` attribute.
 * This complementary directive is not removed by the browser and so provides
 * a permanent reliable place to store the binding information.
 * @example
    <example>
      <file name="index.html">
        Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/>
        <input type="text" ng-readonly="checked" value="I'm Angular"/>
      </file>
      <file name="protractor.js" type="protractor">
        it('should toggle readonly attr', function() {
          expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeFalsy();
          element(by.model('checked')).click();
          expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeTruthy();
        });
      </file>
    </example>
 *
 * @element INPUT
 * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy,
 *     then special attribute "readonly" will be set on the element
 */


/**
 * @ngdoc directive
 * @name ngSelected
 * @restrict A
 * @priority 100
 *
 * @description
 * The HTML specification does not require browsers to preserve the values of boolean attributes
 * such as selected. (Their presence means true and their absence means false.)
 * If we put an Angular interpolation expression into such an attribute then the
 * binding information would be lost when the browser removes the attribute.
 * The `ngSelected` directive solves this problem for the `selected` attribute.
 * This complementary directive is not removed by the browser and so provides
 * a permanent reliable place to store the binding information.
 *
 * @example
    <example>
      <file name="index.html">
        Check me to select: <input type="checkbox" ng-model="selected"><br/>
        <select>
          <option>Hello!</option>
          <option id="greet" ng-selected="selected">Greetings!</option>
        </select>
      </file>
      <file name="protractor.js" type="protractor">
        it('should select Greetings!', function() {
          expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
          element(by.model('selected')).click();
          expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
        });
      </file>
    </example>
 *
 * @element OPTION
 * @param {expression} ngSelected If the {@link guide/expression expression} is truthy,
 *     then special attribute "selected" will be set on the element
 */

/**
 * @ngdoc directive
 * @name ngOpen
 * @restrict A
 * @priority 100
 *
 * @description
 * The HTML specification does not require browsers to preserve the values of boolean attributes
 * such as open. (Their presence means true and their absence means false.)
 * If we put an Angular interpolation expression into such an attribute then the
 * binding information would be lost when the browser removes the attribute.
 * The `ngOpen` directive solves this problem for the `open` attribute.
 * This complementary directive is not removed by the browser and so provides
 * a permanent reliable place to store the binding information.
 * @example
     <example>
       <file name="index.html">
         Check me check multiple: <input type="checkbox" ng-model="open"><br/>
         <details id="details" ng-open="open">
            <summary>Show/Hide me</summary>
         </details>
       </file>
       <file name="protractor.js" type="protractor">
         it('should toggle open', function() {
           expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
           element(by.model('open')).click();
           expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
         });
       </file>
     </example>
 *
 * @element DETAILS
 * @param {expression} ngOpen If the {@link guide/expression expression} is truthy,
 *     then special attribute "open" will be set on the element
 */

var ngAttributeAliasDirectives = {};


// boolean attrs are evaluated
forEach(BOOLEAN_ATTR, function(propName, attrName) {
  // binding to multiple is not supported
  if (propName == "multiple") return;

  var normalized = directiveNormalize('ng-' + attrName);
  ngAttributeAliasDirectives[normalized] = function() {
    return {
      restrict: 'A',
      priority: 100,
      link: function(scope, element, attr) {
        scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
          attr.$set(attrName, !!value);
        });
      }
    };
  };
});

// aliased input attrs are evaluated
forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {
  ngAttributeAliasDirectives[ngAttr] = function() {
    return {
      priority: 100,
      link: function(scope, element, attr) {
        //special case ngPattern when a literal regular expression value
        //is used as the expression (this way we don't have to watch anything).
        if (ngAttr === "ngPattern" && attr.ngPattern.charAt(0) == "/") {
          var match = attr.ngPattern.match(REGEX_STRING_REGEXP);
          if (match) {
            attr.$set("ngPattern", new RegExp(match[1], match[2]));
            return;
          }
        }

        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
          attr.$set(ngAttr, value);
        });
      }
    };
  };
});

// ng-src, ng-srcset, ng-href are interpolated
forEach(['src', 'srcset', 'href'], function(attrName) {
  var normalized = directiveNormalize('ng-' + attrName);
  ngAttributeAliasDirectives[normalized] = function() {
    return {
      priority: 99, // it needs to run after the attributes are interpolated
      link: function(scope, element, attr) {
        var propName = attrName,
            name = attrName;

        if (attrName === 'href' &&
            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {
          name = 'xlinkHref';
          attr.$attr[name] = 'xlink:href';
          propName = null;
        }

        attr.$observe(normalized, function(value) {
          if (!value) {
            if (attrName === 'href') {
              attr.$set(name, null);
            }
            return;
          }

          attr.$set(name, value);

          // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
          // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
          // to set the property as well to achieve the desired effect.
          // we use attr[attrName] value since $set can sanitize the url.
          if (msie && propName) element.prop(propName, attr[name]);
        });
      }
    };
  };
});

/* global -nullFormCtrl, -SUBMITTED_CLASS, addSetValidityMethod: true
 */
var nullFormCtrl = {
  $addControl: noop,
  $$renameControl: nullFormRenameControl,
  $removeControl: noop,
  $setValidity: noop,
  $setDirty: noop,
  $setPristine: noop,
  $setSubmitted: noop
},
SUBMITTED_CLASS = 'ng-submitted';

function nullFormRenameControl(control, name) {
  control.$name = name;
}

/**
 * @ngdoc type
 * @name form.FormController
 *
 * @property {boolean} $pristine True if user has not interacted with the form yet.
 * @property {boolean} $dirty True if user has already interacted with the form.
 * @property {boolean} $valid True if all of the containing forms and controls are valid.
 * @property {boolean} $invalid True if at least one containing control or form is invalid.
 * @property {boolean} $submitted True if user has submitted the form even if its invalid.
 *
 * @property {Object} $error Is an object hash, containing references to controls or
 *  forms with failing validators, where:
 *
 *  - keys are validation tokens (error names),
 *  - values are arrays of controls or forms that have a failing validator for given error name.
 *
 *  Built-in validation tokens:
 *
 *  - `email`
 *  - `max`
 *  - `maxlength`
 *  - `min`
 *  - `minlength`
 *  - `number`
 *  - `pattern`
 *  - `required`
 *  - `url`
 *  - `date`
 *  - `datetimelocal`
 *  - `time`
 *  - `week`
 *  - `month`
 *
 * @description
 * `FormController` keeps track of all its controls and nested forms as well as the state of them,
 * such as being valid/invalid or dirty/pristine.
 *
 * Each {@link ng.directive:form form} directive creates an instance
 * of `FormController`.
 *
 */
//asks for $scope to fool the BC controller module
FormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate'];
function FormController(element, attrs, $scope, $animate, $interpolate) {
  var form = this,
      controls = [];

  var parentForm = form.$$parentForm = element.parent().controller('form') || nullFormCtrl;

  // init state
  form.$error = {};
  form.$$success = {};
  form.$pending = undefined;
  form.$name = $interpolate(attrs.name || attrs.ngForm || '')($scope);
  form.$dirty = false;
  form.$pristine = true;
  form.$valid = true;
  form.$invalid = false;
  form.$submitted = false;

  parentForm.$addControl(form);

  /**
   * @ngdoc method
   * @name form.FormController#$rollbackViewValue
   *
   * @description
   * Rollback all form controls pending updates to the `$modelValue`.
   *
   * Updates may be pending by a debounced event or because the input is waiting for a some future
   * event defined in `ng-model-options`. This method is typically needed by the reset button of
   * a form that uses `ng-model-options` to pend updates.
   */
  form.$rollbackViewValue = function() {
    forEach(controls, function(control) {
      control.$rollbackViewValue();
    });
  };

  /**
   * @ngdoc method
   * @name form.FormController#$commitViewValue
   *
   * @description
   * Commit all form controls pending updates to the `$modelValue`.
   *
   * Updates may be pending by a debounced event or because the input is waiting for a some future
   * event defined in `ng-model-options`. This method is rarely needed as `NgModelController`
   * usually handles calling this in response to input events.
   */
  form.$commitViewValue = function() {
    forEach(controls, function(control) {
      control.$commitViewValue();
    });
  };

  /**
   * @ngdoc method
   * @name form.FormController#$addControl
   *
   * @description
   * Register a control with the form.
   *
   * Input elements using ngModelController do this automatically when they are linked.
   */
  form.$addControl = function(control) {
    // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
    // and not added to the scope.  Now we throw an error.
    assertNotHasOwnProperty(control.$name, 'input');
    controls.push(control);

    if (control.$name) {
      form[control.$name] = control;
    }
  };

  // Private API: rename a form control
  form.$$renameControl = function(control, newName) {
    var oldName = control.$name;

    if (form[oldName] === control) {
      delete form[oldName];
    }
    form[newName] = control;
    control.$name = newName;
  };

  /**
   * @ngdoc method
   * @name form.FormController#$removeControl
   *
   * @description
   * Deregister a control from the form.
   *
   * Input elements using ngModelController do this automatically when they are destroyed.
   */
  form.$removeControl = function(control) {
    if (control.$name && form[control.$name] === control) {
      delete form[control.$name];
    }
    forEach(form.$pending, function(value, name) {
      form.$setValidity(name, null, control);
    });
    forEach(form.$error, function(value, name) {
      form.$setValidity(name, null, control);
    });
    forEach(form.$$success, function(value, name) {
      form.$setValidity(name, null, control);
    });

    arrayRemove(controls, control);
  };


  /**
   * @ngdoc method
   * @name form.FormController#$setValidity
   *
   * @description
   * Sets the validity of a form control.
   *
   * This method will also propagate to parent forms.
   */
  addSetValidityMethod({
    ctrl: this,
    $element: element,
    set: function(object, property, controller) {
      var list = object[property];
      if (!list) {
        object[property] = [controller];
      } else {
        var index = list.indexOf(controller);
        if (index === -1) {
          list.push(controller);
        }
      }
    },
    unset: function(object, property, controller) {
      var list = object[property];
      if (!list) {
        return;
      }
      arrayRemove(list, controller);
      if (list.length === 0) {
        delete object[property];
      }
    },
    parentForm: parentForm,
    $animate: $animate
  });

  /**
   * @ngdoc method
   * @name form.FormController#$setDirty
   *
   * @description
   * Sets the form to a dirty state.
   *
   * This method can be called to add the 'ng-dirty' class and set the form to a dirty
   * state (ng-dirty class). This method will also propagate to parent forms.
   */
  form.$setDirty = function() {
    $animate.removeClass(element, PRISTINE_CLASS);
    $animate.addClass(element, DIRTY_CLASS);
    form.$dirty = true;
    form.$pristine = false;
    parentForm.$setDirty();
  };

  /**
   * @ngdoc method
   * @name form.FormController#$setPristine
   *
   * @description
   * Sets the form to its pristine state.
   *
   * This method can be called to remove the 'ng-dirty' class and set the form to its pristine
   * state (ng-pristine class). This method will also propagate to all the controls contained
   * in this form.
   *
   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
   * saving or resetting it.
   */
  form.$setPristine = function() {
    $animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
    form.$dirty = false;
    form.$pristine = true;
    form.$submitted = false;
    forEach(controls, function(control) {
      control.$setPristine();
    });
  };

  /**
   * @ngdoc method
   * @name form.FormController#$setUntouched
   *
   * @description
   * Sets the form to its untouched state.
   *
   * This method can be called to remove the 'ng-touched' class and set the form controls to their
   * untouched state (ng-untouched class).
   *
   * Setting a form controls back to their untouched state is often useful when setting the form
   * back to its pristine state.
   */
  form.$setUntouched = function() {
    forEach(controls, function(control) {
      control.$setUntouched();
    });
  };

  /**
   * @ngdoc method
   * @name form.FormController#$setSubmitted
   *
   * @description
   * Sets the form to its submitted state.
   */
  form.$setSubmitted = function() {
    $animate.addClass(element, SUBMITTED_CLASS);
    form.$submitted = true;
    parentForm.$setSubmitted();
  };
}

/**
 * @ngdoc directive
 * @name ngForm
 * @restrict EAC
 *
 * @description
 * Nestable alias of {@link ng.directive:form `form`} directive. HTML
 * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
 * sub-group of controls needs to be determined.
 *
 * Note: the purpose of `ngForm` is to group controls,
 * but not to be a replacement for the `<form>` tag with all of its capabilities
 * (e.g. posting to the server, ...).
 *
 * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into
 *                       related scope, under this name.
 *
 */

 /**
 * @ngdoc directive
 * @name form
 * @restrict E
 *
 * @description
 * Directive that instantiates
 * {@link form.FormController FormController}.
 *
 * If the `name` attribute is specified, the form controller is published onto the current scope under
 * this name.
 *
 * # Alias: {@link ng.directive:ngForm `ngForm`}
 *
 * In Angular, forms can be nested. This means that the outer form is valid when all of the child
 * forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so
 * Angular provides the {@link ng.directive:ngForm `ngForm`} directive which behaves identically to
 * `<form>` but can be nested.  This allows you to have nested forms, which is very useful when
 * using Angular validation directives in forms that are dynamically generated using the
 * {@link ng.directive:ngRepeat `ngRepeat`} directive. Since you cannot dynamically generate the `name`
 * attribute of input elements using interpolation, you have to wrap each set of repeated inputs in an
 * `ngForm` directive and nest these in an outer `form` element.
 *
 *
 * # CSS classes
 *  - `ng-valid` is set if the form is valid.
 *  - `ng-invalid` is set if the form is invalid.
 *  - `ng-pristine` is set if the form is pristine.
 *  - `ng-dirty` is set if the form is dirty.
 *  - `ng-submitted` is set if the form was submitted.
 *
 * Keep in mind that ngAnimate can detect each of these classes when added and removed.
 *
 *
 * # Submitting a form and preventing the default action
 *
 * Since the role of forms in client-side Angular applications is different than in classical
 * roundtrip apps, it is desirable for the browser not to translate the form submission into a full
 * page reload that sends the data to the server. Instead some javascript logic should be triggered
 * to handle the form submission in an application-specific way.
 *
 * For this reason, Angular prevents the default action (form submission to the server) unless the
 * `<form>` element has an `action` attribute specified.
 *
 * You can use one of the following two ways to specify what javascript method should be called when
 * a form is submitted:
 *
 * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element
 * - {@link ng.directive:ngClick ngClick} directive on the first
  *  button or input field of type submit (input[type=submit])
 *
 * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit}
 * or {@link ng.directive:ngClick ngClick} directives.
 * This is because of the following form submission rules in the HTML specification:
 *
 * - If a form has only one input field then hitting enter in this field triggers form submit
 * (`ngSubmit`)
 * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter
 * doesn't trigger submit
 * - if a form has one or more input fields and one or more buttons or input[type=submit] then
 * hitting enter in any of the input fields will trigger the click handler on the *first* button or
 * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)
 *
 * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is
 * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
 * to have access to the updated model.
 *
 * ## Animation Hooks
 *
 * Animations in ngForm are triggered when any of the associated CSS classes are added and removed.
 * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any
 * other validations that are performed within the form. Animations in ngForm are similar to how
 * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well
 * as JS animations.
 *
 * The following example shows a simple way to utilize CSS transitions to style a form element
 * that has been rendered as invalid after it has been validated:
 *
 * <pre>
 * //be sure to include ngAnimate as a module to hook into more
 * //advanced animations
 * .my-form {
 *   transition:0.5s linear all;
 *   background: white;
 * }
 * .my-form.ng-invalid {
 *   background: red;
 *   color:white;
 * }
 * </pre>
 *
 * @example
    <example deps="angular-animate.js" animations="true" fixBase="true" module="formExample">
      <file name="index.html">
       <script>
         angular.module('formExample', [])
           .controller('FormController', ['$scope', function($scope) {
             $scope.userType = 'guest';
           }]);
       </script>
       <style>
        .my-form {
          -webkit-transition:all linear 0.5s;
          transition:all linear 0.5s;
          background: transparent;
        }
        .my-form.ng-invalid {
          background: red;
        }
       </style>
       <form name="myForm" ng-controller="FormController" class="my-form">
         userType: <input name="input" ng-model="userType" required>
         <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
         <code>userType = {{userType}}</code><br>
         <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>
         <code>myForm.input.$error = {{myForm.input.$error}}</code><br>
         <code>myForm.$valid = {{myForm.$valid}}</code><br>
         <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>
        </form>
      </file>
      <file name="protractor.js" type="protractor">
        it('should initialize to model', function() {
          var userType = element(by.binding('userType'));
          var valid = element(by.binding('myForm.input.$valid'));

          expect(userType.getText()).toContain('guest');
          expect(valid.getText()).toContain('true');
        });

        it('should be invalid if empty', function() {
          var userType = element(by.binding('userType'));
          var valid = element(by.binding('myForm.input.$valid'));
          var userInput = element(by.model('userType'));

          userInput.clear();
          userInput.sendKeys('');

          expect(userType.getText()).toEqual('userType =');
          expect(valid.getText()).toContain('false');
        });
      </file>
    </example>
 *
 * @param {string=} name Name of the form. If specified, the form controller will be published into
 *                       related scope, under this name.
 */
var formDirectiveFactory = function(isNgForm) {
  return ['$timeout', function($timeout) {
    var formDirective = {
      name: 'form',
      restrict: isNgForm ? 'EAC' : 'E',
      controller: FormController,
      compile: function ngFormCompile(formElement, attr) {
        // Setup initial state of the control
        formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);

        var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);

        return {
          pre: function ngFormPreLink(scope, formElement, attr, controller) {
            // if `action` attr is not present on the form, prevent the default action (submission)
            if (!('action' in attr)) {
              // we can't use jq events because if a form is destroyed during submission the default
              // action is not prevented. see #1238
              //
              // IE 9 is not affected because it doesn't fire a submit event and try to do a full
              // page reload if the form was destroyed by submission of the form via a click handler
              // on a button in the form. Looks like an IE9 specific bug.
              var handleFormSubmission = function(event) {
                scope.$apply(function() {
                  controller.$commitViewValue();
                  controller.$setSubmitted();
                });

                event.preventDefault();
              };

              addEventListenerFn(formElement[0], 'submit', handleFormSubmission);

              // unregister the preventDefault listener so that we don't not leak memory but in a
              // way that will achieve the prevention of the default action.
              formElement.on('$destroy', function() {
                $timeout(function() {
                  removeEventListenerFn(formElement[0], 'submit', handleFormSubmission);
                }, 0, false);
              });
            }

            var parentFormCtrl = controller.$$parentForm;

            if (nameAttr) {
              setter(scope, null, controller.$name, controller, controller.$name);
              attr.$observe(nameAttr, function(newValue) {
                if (controller.$name === newValue) return;
                setter(scope, null, controller.$name, undefined, controller.$name);
                parentFormCtrl.$$renameControl(controller, newValue);
                setter(scope, null, controller.$name, controller, controller.$name);
              });
            }
            formElement.on('$destroy', function() {
              parentFormCtrl.$removeControl(controller);
              if (nameAttr) {
                setter(scope, null, attr[nameAttr], undefined, controller.$name);
              }
              extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
            });
          }
        };
      }
    };

    return formDirective;
  }];
};

var formDirective = formDirectiveFactory();
var ngFormDirective = formDirectiveFactory(true);

/* global VALID_CLASS: false,
  INVALID_CLASS: false,
  PRISTINE_CLASS: false,
  DIRTY_CLASS: false,
  UNTOUCHED_CLASS: false,
  TOUCHED_CLASS: false,
  ngModelMinErr: false,
*/

// Regex code is obtained from SO: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/;
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;

var inputType = {

  /**
   * @ngdoc input
   * @name input[text]
   *
   * @description
   * Standard HTML text input with angular data binding, inherited by most of the `input` elements.
   *
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} required Adds `required` validation error key if the value is not entered.
   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   *    `required` when you want to data-bind to the `required` attribute.
   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
   *    minlength.
   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
   *    any length.
   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
   *    that contains the regular expression body that will be converted to a regular expression
   *    as in the ngPattern directive.
   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
   *    a RegExp found by evaluating the Angular expression given in the attribute value.
   *    If the expression evaluates to a RegExp object then this is used directly.
   *    If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
   *    characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
   *    This parameter is ignored for input[type=password] controls, which will never trim the
   *    input.
   *
   * @example
      <example name="text-input-directive" module="textInputExample">
        <file name="index.html">
         <script>
           angular.module('textInputExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.example = {
                 text: 'guest',
                 word: /^\s*\w*\s*$/
               };
             }]);
         </script>
         <form name="myForm" ng-controller="ExampleController">
           Single word: <input type="text" name="input" ng-model="example.text"
                               ng-pattern="example.word" required ng-trim="false">
           <span class="error" ng-show="myForm.input.$error.required">
             Required!</span>
           <span class="error" ng-show="myForm.input.$error.pattern">
             Single word only!</span>

           <tt>text = {{example.text}}</tt><br/>
           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
          </form>
        </file>
        <file name="protractor.js" type="protractor">
          var text = element(by.binding('example.text'));
          var valid = element(by.binding('myForm.input.$valid'));
          var input = element(by.model('example.text'));

          it('should initialize to model', function() {
            expect(text.getText()).toContain('guest');
            expect(valid.getText()).toContain('true');
          });

          it('should be invalid if empty', function() {
            input.clear();
            input.sendKeys('');

            expect(text.getText()).toEqual('text =');
            expect(valid.getText()).toContain('false');
          });

          it('should be invalid if multi word', function() {
            input.clear();
            input.sendKeys('hello world');

            expect(valid.getText()).toContain('false');
          });
        </file>
      </example>
   */
  'text': textInputType,

    /**
     * @ngdoc input
     * @name input[date]
     *
     * @description
     * Input with date validation and transformation. In browsers that do not yet support
     * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601
     * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many
     * modern browsers do not yet support this input type, it is important to provide cues to users on the
     * expected input format via a placeholder or label.
     *
     * The model must always be a Date object, otherwise Angular will throw an error.
     * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
     *
     * The timezone to be used to read/write the `Date` instance in the model can be defined using
     * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
     *
     * @param {string} ngModel Assignable angular expression to data-bind to.
     * @param {string=} name Property name of the form under which the control is published.
     * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
     * valid ISO date string (yyyy-MM-dd).
     * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be
     * a valid ISO date string (yyyy-MM-dd).
     * @param {string=} required Sets `required` validation error key if the value is not entered.
     * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
     *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
     *    `required` when you want to data-bind to the `required` attribute.
     * @param {string=} ngChange Angular expression to be executed when input changes due to user
     *    interaction with the input element.
     *
     * @example
     <example name="date-input-directive" module="dateInputExample">
     <file name="index.html">
       <script>
          angular.module('dateInputExample', [])
            .controller('DateController', ['$scope', function($scope) {
              $scope.example = {
                value: new Date(2013, 9, 22)
              };
            }]);
       </script>
       <form name="myForm" ng-controller="DateController as dateCtrl">
          Pick a date in 2013:
          <input type="date" id="exampleInput" name="input" ng-model="example.value"
              placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
          <span class="error" ng-show="myForm.input.$error.required">
              Required!</span>
          <span class="error" ng-show="myForm.input.$error.date">
              Not a valid date!</span>
           <tt>value = {{example.value | date: "yyyy-MM-dd"}}</tt><br/>
           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
       </form>
     </file>
     <file name="protractor.js" type="protractor">
        var value = element(by.binding('example.value | date: "yyyy-MM-dd"'));
        var valid = element(by.binding('myForm.input.$valid'));
        var input = element(by.model('example.value'));

        // currently protractor/webdriver does not support
        // sending keys to all known HTML5 input controls
        // for various browsers (see https://github.com/angular/protractor/issues/562).
        function setInput(val) {
          // set the value of the element and force validation.
          var scr = "var ipt = document.getElementById('exampleInput'); " +
          "ipt.value = '" + val + "';" +
          "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
          browser.executeScript(scr);
        }

        it('should initialize to model', function() {
          expect(value.getText()).toContain('2013-10-22');
          expect(valid.getText()).toContain('myForm.input.$valid = true');
        });

        it('should be invalid if empty', function() {
          setInput('');
          expect(value.getText()).toEqual('value =');
          expect(valid.getText()).toContain('myForm.input.$valid = false');
        });

        it('should be invalid if over max', function() {
          setInput('2015-01-01');
          expect(value.getText()).toContain('');
          expect(valid.getText()).toContain('myForm.input.$valid = false');
        });
     </file>
     </example>
     */
  'date': createDateInputType('date', DATE_REGEXP,
         createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']),
         'yyyy-MM-dd'),

   /**
    * @ngdoc input
    * @name input[datetime-local]
    *
    * @description
    * Input with datetime validation and transformation. In browsers that do not yet support
    * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
    * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.
    *
    * The model must always be a Date object, otherwise Angular will throw an error.
    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
    *
    * The timezone to be used to read/write the `Date` instance in the model can be defined using
    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
    *
    * @param {string} ngModel Assignable angular expression to data-bind to.
    * @param {string=} name Property name of the form under which the control is published.
    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
    * valid ISO datetime format (yyyy-MM-ddTHH:mm:ss).
    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be
    * a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss).
    * @param {string=} required Sets `required` validation error key if the value is not entered.
    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
    *    `required` when you want to data-bind to the `required` attribute.
    * @param {string=} ngChange Angular expression to be executed when input changes due to user
    *    interaction with the input element.
    *
    * @example
    <example name="datetimelocal-input-directive" module="dateExample">
    <file name="index.html">
      <script>
        angular.module('dateExample', [])
          .controller('DateController', ['$scope', function($scope) {
            $scope.example = {
              value: new Date(2010, 11, 28, 14, 57)
            };
          }]);
      </script>
      <form name="myForm" ng-controller="DateController as dateCtrl">
        Pick a date between in 2013:
        <input type="datetime-local" id="exampleInput" name="input" ng-model="example.value"
            placeholder="yyyy-MM-ddTHH:mm:ss" min="2001-01-01T00:00:00" max="2013-12-31T00:00:00" required />
        <span class="error" ng-show="myForm.input.$error.required">
            Required!</span>
        <span class="error" ng-show="myForm.input.$error.datetimelocal">
            Not a valid date!</span>
        <tt>value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/>
        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
      </form>
    </file>
    <file name="protractor.js" type="protractor">
      var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"'));
      var valid = element(by.binding('myForm.input.$valid'));
      var input = element(by.model('example.value'));

      // currently protractor/webdriver does not support
      // sending keys to all known HTML5 input controls
      // for various browsers (https://github.com/angular/protractor/issues/562).
      function setInput(val) {
        // set the value of the element and force validation.
        var scr = "var ipt = document.getElementById('exampleInput'); " +
        "ipt.value = '" + val + "';" +
        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
        browser.executeScript(scr);
      }

      it('should initialize to model', function() {
        expect(value.getText()).toContain('2010-12-28T14:57:00');
        expect(valid.getText()).toContain('myForm.input.$valid = true');
      });

      it('should be invalid if empty', function() {
        setInput('');
        expect(value.getText()).toEqual('value =');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });

      it('should be invalid if over max', function() {
        setInput('2015-01-01T23:59:00');
        expect(value.getText()).toContain('');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });
    </file>
    </example>
    */
  'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,
      createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),
      'yyyy-MM-ddTHH:mm:ss.sss'),

  /**
   * @ngdoc input
   * @name input[time]
   *
   * @description
   * Input with time validation and transformation. In browsers that do not yet support
   * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
   * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a
   * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.
   *
   * The model must always be a Date object, otherwise Angular will throw an error.
   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
   *
   * The timezone to be used to read/write the `Date` instance in the model can be defined using
   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
   * valid ISO time format (HH:mm:ss).
   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be a
   * valid ISO time format (HH:mm:ss).
   * @param {string=} required Sets `required` validation error key if the value is not entered.
   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   *    `required` when you want to data-bind to the `required` attribute.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   *
   * @example
   <example name="time-input-directive" module="timeExample">
   <file name="index.html">
     <script>
      angular.module('timeExample', [])
        .controller('DateController', ['$scope', function($scope) {
          $scope.example = {
            value: new Date(1970, 0, 1, 14, 57, 0)
          };
        }]);
     </script>
     <form name="myForm" ng-controller="DateController as dateCtrl">
        Pick a between 8am and 5pm:
        <input type="time" id="exampleInput" name="input" ng-model="example.value"
            placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required />
        <span class="error" ng-show="myForm.input.$error.required">
            Required!</span>
        <span class="error" ng-show="myForm.input.$error.time">
            Not a valid date!</span>
        <tt>value = {{example.value | date: "HH:mm:ss"}}</tt><br/>
        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
     </form>
   </file>
   <file name="protractor.js" type="protractor">
      var value = element(by.binding('example.value | date: "HH:mm:ss"'));
      var valid = element(by.binding('myForm.input.$valid'));
      var input = element(by.model('example.value'));

      // currently protractor/webdriver does not support
      // sending keys to all known HTML5 input controls
      // for various browsers (https://github.com/angular/protractor/issues/562).
      function setInput(val) {
        // set the value of the element and force validation.
        var scr = "var ipt = document.getElementById('exampleInput'); " +
        "ipt.value = '" + val + "';" +
        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
        browser.executeScript(scr);
      }

      it('should initialize to model', function() {
        expect(value.getText()).toContain('14:57:00');
        expect(valid.getText()).toContain('myForm.input.$valid = true');
      });

      it('should be invalid if empty', function() {
        setInput('');
        expect(value.getText()).toEqual('value =');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });

      it('should be invalid if over max', function() {
        setInput('23:59:00');
        expect(value.getText()).toContain('');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });
   </file>
   </example>
   */
  'time': createDateInputType('time', TIME_REGEXP,
      createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),
     'HH:mm:ss.sss'),

   /**
    * @ngdoc input
    * @name input[week]
    *
    * @description
    * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support
    * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
    * week format (yyyy-W##), for example: `2013-W02`.
    *
    * The model must always be a Date object, otherwise Angular will throw an error.
    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
    *
    * The timezone to be used to read/write the `Date` instance in the model can be defined using
    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
    *
    * @param {string} ngModel Assignable angular expression to data-bind to.
    * @param {string=} name Property name of the form under which the control is published.
    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
    * valid ISO week format (yyyy-W##).
    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be
    * a valid ISO week format (yyyy-W##).
    * @param {string=} required Sets `required` validation error key if the value is not entered.
    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
    *    `required` when you want to data-bind to the `required` attribute.
    * @param {string=} ngChange Angular expression to be executed when input changes due to user
    *    interaction with the input element.
    *
    * @example
    <example name="week-input-directive" module="weekExample">
    <file name="index.html">
      <script>
      angular.module('weekExample', [])
        .controller('DateController', ['$scope', function($scope) {
          $scope.example = {
            value: new Date(2013, 0, 3)
          };
        }]);
      </script>
      <form name="myForm" ng-controller="DateController as dateCtrl">
        Pick a date between in 2013:
        <input id="exampleInput" type="week" name="input" ng-model="example.value"
            placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
        <span class="error" ng-show="myForm.input.$error.required">
            Required!</span>
        <span class="error" ng-show="myForm.input.$error.week">
            Not a valid date!</span>
        <tt>value = {{example.value | date: "yyyy-Www"}}</tt><br/>
        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
      </form>
    </file>
    <file name="protractor.js" type="protractor">
      var value = element(by.binding('example.value | date: "yyyy-Www"'));
      var valid = element(by.binding('myForm.input.$valid'));
      var input = element(by.model('example.value'));

      // currently protractor/webdriver does not support
      // sending keys to all known HTML5 input controls
      // for various browsers (https://github.com/angular/protractor/issues/562).
      function setInput(val) {
        // set the value of the element and force validation.
        var scr = "var ipt = document.getElementById('exampleInput'); " +
        "ipt.value = '" + val + "';" +
        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
        browser.executeScript(scr);
      }

      it('should initialize to model', function() {
        expect(value.getText()).toContain('2013-W01');
        expect(valid.getText()).toContain('myForm.input.$valid = true');
      });

      it('should be invalid if empty', function() {
        setInput('');
        expect(value.getText()).toEqual('value =');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });

      it('should be invalid if over max', function() {
        setInput('2015-W01');
        expect(value.getText()).toContain('');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });
    </file>
    </example>
    */
  'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'),

  /**
   * @ngdoc input
   * @name input[month]
   *
   * @description
   * Input with month validation and transformation. In browsers that do not yet support
   * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
   * month format (yyyy-MM), for example: `2009-01`.
   *
   * The model must always be a Date object, otherwise Angular will throw an error.
   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
   * If the model is not set to the first of the month, the next view to model update will set it
   * to the first of the month.
   *
   * The timezone to be used to read/write the `Date` instance in the model can be defined using
   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be
   * a valid ISO month format (yyyy-MM).
   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must
   * be a valid ISO month format (yyyy-MM).
   * @param {string=} required Sets `required` validation error key if the value is not entered.
   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   *    `required` when you want to data-bind to the `required` attribute.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   *
   * @example
   <example name="month-input-directive" module="monthExample">
   <file name="index.html">
     <script>
      angular.module('monthExample', [])
        .controller('DateController', ['$scope', function($scope) {
          $scope.example = {
            value: new Date(2013, 9, 1)
          };
        }]);
     </script>
     <form name="myForm" ng-controller="DateController as dateCtrl">
       Pick a month in 2013:
       <input id="exampleInput" type="month" name="input" ng-model="example.value"
          placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
       <span class="error" ng-show="myForm.input.$error.required">
          Required!</span>
       <span class="error" ng-show="myForm.input.$error.month">
          Not a valid month!</span>
       <tt>value = {{example.value | date: "yyyy-MM"}}</tt><br/>
       <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
       <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
       <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
       <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
     </form>
   </file>
   <file name="protractor.js" type="protractor">
      var value = element(by.binding('example.value | date: "yyyy-MM"'));
      var valid = element(by.binding('myForm.input.$valid'));
      var input = element(by.model('example.value'));

      // currently protractor/webdriver does not support
      // sending keys to all known HTML5 input controls
      // for various browsers (https://github.com/angular/protractor/issues/562).
      function setInput(val) {
        // set the value of the element and force validation.
        var scr = "var ipt = document.getElementById('exampleInput'); " +
        "ipt.value = '" + val + "';" +
        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
        browser.executeScript(scr);
      }

      it('should initialize to model', function() {
        expect(value.getText()).toContain('2013-10');
        expect(valid.getText()).toContain('myForm.input.$valid = true');
      });

      it('should be invalid if empty', function() {
        setInput('');
        expect(value.getText()).toEqual('value =');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });

      it('should be invalid if over max', function() {
        setInput('2015-01');
        expect(value.getText()).toContain('');
        expect(valid.getText()).toContain('myForm.input.$valid = false');
      });
   </file>
   </example>
   */
  'month': createDateInputType('month', MONTH_REGEXP,
     createDateParser(MONTH_REGEXP, ['yyyy', 'MM']),
     'yyyy-MM'),

  /**
   * @ngdoc input
   * @name input[number]
   *
   * @description
   * Text input with number validation and transformation. Sets the `number` validation
   * error if not a valid number.
   *
   * <div class="alert alert-warning">
   * The model must always be of type `number` otherwise Angular will throw an error.
   * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt}
   * error docs for more information and an example of how to convert your model if necessary.
   * </div>
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
   * @param {string=} required Sets `required` validation error key if the value is not entered.
   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   *    `required` when you want to data-bind to the `required` attribute.
   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
   *    minlength.
   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
   *    any length.
   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
   *    that contains the regular expression body that will be converted to a regular expression
   *    as in the ngPattern directive.
   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
   *    a RegExp found by evaluating the Angular expression given in the attribute value.
   *    If the expression evaluates to a RegExp object then this is used directly.
   *    If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
   *    characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   *
   * @example
      <example name="number-input-directive" module="numberExample">
        <file name="index.html">
         <script>
           angular.module('numberExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.example = {
                 value: 12
               };
             }]);
         </script>
         <form name="myForm" ng-controller="ExampleController">
           Number: <input type="number" name="input" ng-model="example.value"
                          min="0" max="99" required>
           <span class="error" ng-show="myForm.input.$error.required">
             Required!</span>
           <span class="error" ng-show="myForm.input.$error.number">
             Not valid number!</span>
           <tt>value = {{example.value}}</tt><br/>
           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
          </form>
        </file>
        <file name="protractor.js" type="protractor">
          var value = element(by.binding('example.value'));
          var valid = element(by.binding('myForm.input.$valid'));
          var input = element(by.model('example.value'));

          it('should initialize to model', function() {
            expect(value.getText()).toContain('12');
            expect(valid.getText()).toContain('true');
          });

          it('should be invalid if empty', function() {
            input.clear();
            input.sendKeys('');
            expect(value.getText()).toEqual('value =');
            expect(valid.getText()).toContain('false');
          });

          it('should be invalid if over max', function() {
            input.clear();
            input.sendKeys('123');
            expect(value.getText()).toEqual('value =');
            expect(valid.getText()).toContain('false');
          });
        </file>
      </example>
   */
  'number': numberInputType,


  /**
   * @ngdoc input
   * @name input[url]
   *
   * @description
   * Text input with URL validation. Sets the `url` validation error key if the content is not a
   * valid URL.
   *
   * <div class="alert alert-warning">
   * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex
   * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify
   * the built-in validators (see the {@link guide/forms Forms guide})
   * </div>
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} required Sets `required` validation error key if the value is not entered.
   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   *    `required` when you want to data-bind to the `required` attribute.
   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
   *    minlength.
   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
   *    any length.
   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
   *    that contains the regular expression body that will be converted to a regular expression
   *    as in the ngPattern directive.
   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
   *    a RegExp found by evaluating the Angular expression given in the attribute value.
   *    If the expression evaluates to a RegExp object then this is used directly.
   *    If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
   *    characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   *
   * @example
      <example name="url-input-directive" module="urlExample">
        <file name="index.html">
         <script>
           angular.module('urlExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.url = {
                 text: 'http://google.com'
               };
             }]);
         </script>
         <form name="myForm" ng-controller="ExampleController">
           URL: <input type="url" name="input" ng-model="url.text" required>
           <span class="error" ng-show="myForm.input.$error.required">
             Required!</span>
           <span class="error" ng-show="myForm.input.$error.url">
             Not valid url!</span>
           <tt>text = {{url.text}}</tt><br/>
           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
           <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
          </form>
        </file>
        <file name="protractor.js" type="protractor">
          var text = element(by.binding('url.text'));
          var valid = element(by.binding('myForm.input.$valid'));
          var input = element(by.model('url.text'));

          it('should initialize to model', function() {
            expect(text.getText()).toContain('http://google.com');
            expect(valid.getText()).toContain('true');
          });

          it('should be invalid if empty', function() {
            input.clear();
            input.sendKeys('');

            expect(text.getText()).toEqual('text =');
            expect(valid.getText()).toContain('false');
          });

          it('should be invalid if not url', function() {
            input.clear();
            input.sendKeys('box');

            expect(valid.getText()).toContain('false');
          });
        </file>
      </example>
   */
  'url': urlInputType,


  /**
   * @ngdoc input
   * @name input[email]
   *
   * @description
   * Text input with email validation. Sets the `email` validation error key if not a valid email
   * address.
   *
   * <div class="alert alert-warning">
   * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex
   * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can
   * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})
   * </div>
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} required Sets `required` validation error key if the value is not entered.
   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   *    `required` when you want to data-bind to the `required` attribute.
   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
   *    minlength.
   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
   *    any length.
   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
   *    that contains the regular expression body that will be converted to a regular expression
   *    as in the ngPattern directive.
   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
   *    a RegExp found by evaluating the Angular expression given in the attribute value.
   *    If the expression evaluates to a RegExp object then this is used directly.
   *    If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
   *    characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   *
   * @example
      <example name="email-input-directive" module="emailExample">
        <file name="index.html">
         <script>
           angular.module('emailExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.email = {
                 text: 'me@example.com'
               };
             }]);
         </script>
           <form name="myForm" ng-controller="ExampleController">
             Email: <input type="email" name="input" ng-model="email.text" required>
             <span class="error" ng-show="myForm.input.$error.required">
               Required!</span>
             <span class="error" ng-show="myForm.input.$error.email">
               Not valid email!</span>
             <tt>text = {{email.text}}</tt><br/>
             <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
             <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
             <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
             <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
             <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
           </form>
         </file>
        <file name="protractor.js" type="protractor">
          var text = element(by.binding('email.text'));
          var valid = element(by.binding('myForm.input.$valid'));
          var input = element(by.model('email.text'));

          it('should initialize to model', function() {
            expect(text.getText()).toContain('me@example.com');
            expect(valid.getText()).toContain('true');
          });

          it('should be invalid if empty', function() {
            input.clear();
            input.sendKeys('');
            expect(text.getText()).toEqual('text =');
            expect(valid.getText()).toContain('false');
          });

          it('should be invalid if not email', function() {
            input.clear();
            input.sendKeys('xxx');

            expect(valid.getText()).toContain('false');
          });
        </file>
      </example>
   */
  'email': emailInputType,


  /**
   * @ngdoc input
   * @name input[radio]
   *
   * @description
   * HTML radio button.
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string} value The value to which the expression should be set when selected.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   * @param {string} ngValue Angular expression which sets the value to which the expression should
   *    be set when selected.
   *
   * @example
      <example name="radio-input-directive" module="radioExample">
        <file name="index.html">
         <script>
           angular.module('radioExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.color = {
                 name: 'blue'
               };
               $scope.specialValue = {
                 "id": "12345",
                 "value": "green"
               };
             }]);
         </script>
         <form name="myForm" ng-controller="ExampleController">
           <input type="radio" ng-model="color.name" value="red">  Red <br/>
           <input type="radio" ng-model="color.name" ng-value="specialValue"> Green <br/>
           <input type="radio" ng-model="color.name" value="blue"> Blue <br/>
           <tt>color = {{color.name | json}}</tt><br/>
          </form>
          Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
        </file>
        <file name="protractor.js" type="protractor">
          it('should change state', function() {
            var color = element(by.binding('color.name'));

            expect(color.getText()).toContain('blue');

            element.all(by.model('color.name')).get(0).click();

            expect(color.getText()).toContain('red');
          });
        </file>
      </example>
   */
  'radio': radioInputType,


  /**
   * @ngdoc input
   * @name input[checkbox]
   *
   * @description
   * HTML checkbox.
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string=} name Property name of the form under which the control is published.
   * @param {expression=} ngTrueValue The value to which the expression should be set when selected.
   * @param {expression=} ngFalseValue The value to which the expression should be set when not selected.
   * @param {string=} ngChange Angular expression to be executed when input changes due to user
   *    interaction with the input element.
   *
   * @example
      <example name="checkbox-input-directive" module="checkboxExample">
        <file name="index.html">
         <script>
           angular.module('checkboxExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.checkboxModel = {
                value1 : true,
                value2 : 'YES'
              };
             }]);
         </script>
         <form name="myForm" ng-controller="ExampleController">
           Value1: <input type="checkbox" ng-model="checkboxModel.value1"> <br/>
           Value2: <input type="checkbox" ng-model="checkboxModel.value2"
                          ng-true-value="'YES'" ng-false-value="'NO'"> <br/>
           <tt>value1 = {{checkboxModel.value1}}</tt><br/>
           <tt>value2 = {{checkboxModel.value2}}</tt><br/>
          </form>
        </file>
        <file name="protractor.js" type="protractor">
          it('should change state', function() {
            var value1 = element(by.binding('checkboxModel.value1'));
            var value2 = element(by.binding('checkboxModel.value2'));

            expect(value1.getText()).toContain('true');
            expect(value2.getText()).toContain('YES');

            element(by.model('checkboxModel.value1')).click();
            element(by.model('checkboxModel.value2')).click();

            expect(value1.getText()).toContain('false');
            expect(value2.getText()).toContain('NO');
          });
        </file>
      </example>
   */
  'checkbox': checkboxInputType,

  'hidden': noop,
  'button': noop,
  'submit': noop,
  'reset': noop,
  'file': noop
};

function stringBasedInputType(ctrl) {
  ctrl.$formatters.push(function(value) {
    return ctrl.$isEmpty(value) ? value : value.toString();
  });
}

function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
  stringBasedInputType(ctrl);
}

function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  var type = lowercase(element[0].type);

  // In composition mode, users are still inputing intermediate text buffer,
  // hold the listener until composition is done.
  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
  if (!$sniffer.android) {
    var composing = false;

    element.on('compositionstart', function(data) {
      composing = true;
    });

    element.on('compositionend', function() {
      composing = false;
      listener();
    });
  }

  var listener = function(ev) {
    if (timeout) {
      $browser.defer.cancel(timeout);
      timeout = null;
    }
    if (composing) return;
    var value = element.val(),
        event = ev && ev.type;

    // By default we will trim the value
    // If the attribute ng-trim exists we will avoid trimming
    // If input type is 'password', the value is never trimmed
    if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) {
      value = trim(value);
    }

    // If a control is suffering from bad input (due to native validators), browsers discard its
    // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the
    // control's value is the same empty value twice in a row.
    if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
      ctrl.$setViewValue(value, event);
    }
  };

  // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
  // input event on backspace, delete or cut
  if ($sniffer.hasEvent('input')) {
    element.on('input', listener);
  } else {
    var timeout;

    var deferListener = function(ev, input, origValue) {
      if (!timeout) {
        timeout = $browser.defer(function() {
          timeout = null;
          if (!input || input.value !== origValue) {
            listener(ev);
          }
        });
      }
    };

    element.on('keydown', function(event) {
      var key = event.keyCode;

      // ignore
      //    command            modifiers                   arrows
      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;

      deferListener(event, this, this.value);
    });

    // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
    if ($sniffer.hasEvent('paste')) {
      element.on('paste cut', deferListener);
    }
  }

  // if user paste into input using mouse on older browser
  // or form autocomplete on newer browser, we need "change" event to catch it
  element.on('change', listener);

  ctrl.$render = function() {
    element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
  };
}

function weekParser(isoWeek, existingDate) {
  if (isDate(isoWeek)) {
    return isoWeek;
  }

  if (isString(isoWeek)) {
    WEEK_REGEXP.lastIndex = 0;
    var parts = WEEK_REGEXP.exec(isoWeek);
    if (parts) {
      var year = +parts[1],
          week = +parts[2],
          hours = 0,
          minutes = 0,
          seconds = 0,
          milliseconds = 0,
          firstThurs = getFirstThursdayOfYear(year),
          addDays = (week - 1) * 7;

      if (existingDate) {
        hours = existingDate.getHours();
        minutes = existingDate.getMinutes();
        seconds = existingDate.getSeconds();
        milliseconds = existingDate.getMilliseconds();
      }

      return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);
    }
  }

  return NaN;
}

function createDateParser(regexp, mapping) {
  return function(iso, date) {
    var parts, map;

    if (isDate(iso)) {
      return iso;
    }

    if (isString(iso)) {
      // When a date is JSON'ified to wraps itself inside of an extra
      // set of double quotes. This makes the date parsing code unable
      // to match the date string and parse it as a date.
      if (iso.charAt(0) == '"' && iso.charAt(iso.length - 1) == '"') {
        iso = iso.substring(1, iso.length - 1);
      }
      if (ISO_DATE_REGEXP.test(iso)) {
        return new Date(iso);
      }
      regexp.lastIndex = 0;
      parts = regexp.exec(iso);

      if (parts) {
        parts.shift();
        if (date) {
          map = {
            yyyy: date.getFullYear(),
            MM: date.getMonth() + 1,
            dd: date.getDate(),
            HH: date.getHours(),
            mm: date.getMinutes(),
            ss: date.getSeconds(),
            sss: date.getMilliseconds() / 1000
          };
        } else {
          map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };
        }

        forEach(parts, function(part, index) {
          if (index < mapping.length) {
            map[mapping[index]] = +part;
          }
        });
        return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);
      }
    }

    return NaN;
  };
}

function createDateInputType(type, regexp, parseDate, format) {
  return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
    badInputChecker(scope, element, attr, ctrl);
    baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
    var timezone = ctrl && ctrl.$options && ctrl.$options.timezone;
    var previousDate;

    ctrl.$$parserName = type;
    ctrl.$parsers.push(function(value) {
      if (ctrl.$isEmpty(value)) return null;
      if (regexp.test(value)) {
        // Note: We cannot read ctrl.$modelValue, as there might be a different
        // parser/formatter in the processing chain so that the model
        // contains some different data format!
        var parsedDate = parseDate(value, previousDate);
        if (timezone === 'UTC') {
          parsedDate.setMinutes(parsedDate.getMinutes() - parsedDate.getTimezoneOffset());
        }
        return parsedDate;
      }
      return undefined;
    });

    ctrl.$formatters.push(function(value) {
      if (value && !isDate(value)) {
        throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
      }
      if (isValidDate(value)) {
        previousDate = value;
        if (previousDate && timezone === 'UTC') {
          var timezoneOffset = 60000 * previousDate.getTimezoneOffset();
          previousDate = new Date(previousDate.getTime() + timezoneOffset);
        }
        return $filter('date')(value, format, timezone);
      } else {
        previousDate = null;
        return '';
      }
    });

    if (isDefined(attr.min) || attr.ngMin) {
      var minVal;
      ctrl.$validators.min = function(value) {
        return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;
      };
      attr.$observe('min', function(val) {
        minVal = parseObservedDateValue(val);
        ctrl.$validate();
      });
    }

    if (isDefined(attr.max) || attr.ngMax) {
      var maxVal;
      ctrl.$validators.max = function(value) {
        return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
      };
      attr.$observe('max', function(val) {
        maxVal = parseObservedDateValue(val);
        ctrl.$validate();
      });
    }

    function isValidDate(value) {
      // Invalid Date: getTime() returns NaN
      return value && !(value.getTime && value.getTime() !== value.getTime());
    }

    function parseObservedDateValue(val) {
      return isDefined(val) ? (isDate(val) ? val : parseDate(val)) : undefined;
    }
  };
}

function badInputChecker(scope, element, attr, ctrl) {
  var node = element[0];
  var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity);
  if (nativeValidation) {
    ctrl.$parsers.push(function(value) {
      var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};
      // Detect bug in FF35 for input[email] (https://bugzilla.mozilla.org/show_bug.cgi?id=1064430):
      // - also sets validity.badInput (should only be validity.typeMismatch).
      // - see http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#e-mail-state-(type=email)
      // - can ignore this case as we can still read out the erroneous email...
      return validity.badInput && !validity.typeMismatch ? undefined : value;
    });
  }
}

function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  badInputChecker(scope, element, attr, ctrl);
  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);

  ctrl.$$parserName = 'number';
  ctrl.$parsers.push(function(value) {
    if (ctrl.$isEmpty(value))      return null;
    if (NUMBER_REGEXP.test(value)) return parseFloat(value);
    return undefined;
  });

  ctrl.$formatters.push(function(value) {
    if (!ctrl.$isEmpty(value)) {
      if (!isNumber(value)) {
        throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value);
      }
      value = value.toString();
    }
    return value;
  });

  if (isDefined(attr.min) || attr.ngMin) {
    var minVal;
    ctrl.$validators.min = function(value) {
      return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
    };

    attr.$observe('min', function(val) {
      if (isDefined(val) && !isNumber(val)) {
        val = parseFloat(val, 10);
      }
      minVal = isNumber(val) && !isNaN(val) ? val : undefined;
      // TODO(matsko): implement validateLater to reduce number of validations
      ctrl.$validate();
    });
  }

  if (isDefined(attr.max) || attr.ngMax) {
    var maxVal;
    ctrl.$validators.max = function(value) {
      return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
    };

    attr.$observe('max', function(val) {
      if (isDefined(val) && !isNumber(val)) {
        val = parseFloat(val, 10);
      }
      maxVal = isNumber(val) && !isNaN(val) ? val : undefined;
      // TODO(matsko): implement validateLater to reduce number of validations
      ctrl.$validate();
    });
  }
}

function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  // Note: no badInputChecker here by purpose as `url` is only a validation
  // in browsers, i.e. we can always read out input.value even if it is not valid!
  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
  stringBasedInputType(ctrl);

  ctrl.$$parserName = 'url';
  ctrl.$validators.url = function(modelValue, viewValue) {
    var value = modelValue || viewValue;
    return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
  };
}

function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
  // Note: no badInputChecker here by purpose as `url` is only a validation
  // in browsers, i.e. we can always read out input.value even if it is not valid!
  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
  stringBasedInputType(ctrl);

  ctrl.$$parserName = 'email';
  ctrl.$validators.email = function(modelValue, viewValue) {
    var value = modelValue || viewValue;
    return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
  };
}

function radioInputType(scope, element, attr, ctrl) {
  // make the name unique, if not defined
  if (isUndefined(attr.name)) {
    element.attr('name', nextUid());
  }

  var listener = function(ev) {
    if (element[0].checked) {
      ctrl.$setViewValue(attr.value, ev && ev.type);
    }
  };

  element.on('click', listener);

  ctrl.$render = function() {
    var value = attr.value;
    element[0].checked = (value == ctrl.$viewValue);
  };

  attr.$observe('value', ctrl.$render);
}

function parseConstantExpr($parse, context, name, expression, fallback) {
  var parseFn;
  if (isDefined(expression)) {
    parseFn = $parse(expression);
    if (!parseFn.constant) {
      throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' +
                                   '`{1}`.', name, expression);
    }
    return parseFn(context);
  }
  return fallback;
}

function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
  var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);
  var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);

  var listener = function(ev) {
    ctrl.$setViewValue(element[0].checked, ev && ev.type);
  };

  element.on('click', listener);

  ctrl.$render = function() {
    element[0].checked = ctrl.$viewValue;
  };

  // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`
  // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert
  // it to a boolean.
  ctrl.$isEmpty = function(value) {
    return value === false;
  };

  ctrl.$formatters.push(function(value) {
    return equals(value, trueValue);
  });

  ctrl.$parsers.push(function(value) {
    return value ? trueValue : falseValue;
  });
}


/**
 * @ngdoc directive
 * @name textarea
 * @restrict E
 *
 * @description
 * HTML textarea element control with angular data-binding. The data-binding and validation
 * properties of this element are exactly the same as those of the
 * {@link ng.directive:input input element}.
 *
 * @param {string} ngModel Assignable angular expression to data-bind to.
 * @param {string=} name Property name of the form under which the control is published.
 * @param {string=} required Sets `required` validation error key if the value is not entered.
 * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
 *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
 *    `required` when you want to data-bind to the `required` attribute.
 * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
 *    minlength.
 * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
 *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
 *    length.
 * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
 *    RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
 *    patterns defined as scope expressions.
 * @param {string=} ngChange Angular expression to be executed when input changes due to user
 *    interaction with the input element.
 * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
 */


/**
 * @ngdoc directive
 * @name input
 * @restrict E
 *
 * @description
 * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,
 * input state control, and validation.
 * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.
 *
 * <div class="alert alert-warning">
 * **Note:** Not every feature offered is available for all input types.
 * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.
 * </div>
 *
 * @param {string} ngModel Assignable angular expression to data-bind to.
 * @param {string=} name Property name of the form under which the control is published.
 * @param {string=} required Sets `required` validation error key if the value is not entered.
 * @param {boolean=} ngRequired Sets `required` attribute if set to true
 * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
 *    minlength.
 * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
 *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
 *    length.
 * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
 *    RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
 *    patterns defined as scope expressions.
 * @param {string=} ngChange Angular expression to be executed when input changes due to user
 *    interaction with the input element.
 * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
 *    This parameter is ignored for input[type=password] controls, which will never trim the
 *    input.
 *
 * @example
    <example name="input-directive" module="inputExample">
      <file name="index.html">
       <script>
          angular.module('inputExample', [])
            .controller('ExampleController', ['$scope', function($scope) {
              $scope.user = {name: 'guest', last: 'visitor'};
            }]);
       </script>
       <div ng-controller="ExampleController">
         <form name="myForm">
           User name: <input type="text" name="userName" ng-model="user.name" required>
           <span class="error" ng-show="myForm.userName.$error.required">
             Required!</span><br>
           Last name: <input type="text" name="lastName" ng-model="user.last"
             ng-minlength="3" ng-maxlength="10">
           <span class="error" ng-show="myForm.lastName.$error.minlength">
             Too short!</span>
           <span class="error" ng-show="myForm.lastName.$error.maxlength">
             Too long!</span><br>
         </form>
         <hr>
         <tt>user = {{user}}</tt><br/>
         <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
         <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
         <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
         <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br>
         <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
         <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br>
         <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br>
       </div>
      </file>
      <file name="protractor.js" type="protractor">
        var user = element(by.exactBinding('user'));
        var userNameValid = element(by.binding('myForm.userName.$valid'));
        var lastNameValid = element(by.binding('myForm.lastName.$valid'));
        var lastNameError = element(by.binding('myForm.lastName.$error'));
        var formValid = element(by.binding('myForm.$valid'));
        var userNameInput = element(by.model('user.name'));
        var userLastInput = element(by.model('user.last'));

        it('should initialize to model', function() {
          expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
          expect(userNameValid.getText()).toContain('true');
          expect(formValid.getText()).toContain('true');
        });

        it('should be invalid if empty when required', function() {
          userNameInput.clear();
          userNameInput.sendKeys('');

          expect(user.getText()).toContain('{"last":"visitor"}');
          expect(userNameValid.getText()).toContain('false');
          expect(formValid.getText()).toContain('false');
        });

        it('should be valid if empty when min length is set', function() {
          userLastInput.clear();
          userLastInput.sendKeys('');

          expect(user.getText()).toContain('{"name":"guest","last":""}');
          expect(lastNameValid.getText()).toContain('true');
          expect(formValid.getText()).toContain('true');
        });

        it('should be invalid if less than required min length', function() {
          userLastInput.clear();
          userLastInput.sendKeys('xx');

          expect(user.getText()).toContain('{"name":"guest"}');
          expect(lastNameValid.getText()).toContain('false');
          expect(lastNameError.getText()).toContain('minlength');
          expect(formValid.getText()).toContain('false');
        });

        it('should be invalid if longer than max length', function() {
          userLastInput.clear();
          userLastInput.sendKeys('some ridiculously long name');

          expect(user.getText()).toContain('{"name":"guest"}');
          expect(lastNameValid.getText()).toContain('false');
          expect(lastNameError.getText()).toContain('maxlength');
          expect(formValid.getText()).toContain('false');
        });
      </file>
    </example>
 */
var inputDirective = ['$browser', '$sniffer', '$filter', '$parse',
    function($browser, $sniffer, $filter, $parse) {
  return {
    restrict: 'E',
    require: ['?ngModel'],
    link: {
      pre: function(scope, element, attr, ctrls) {
        if (ctrls[0]) {
          (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,
                                                              $browser, $filter, $parse);
        }
      }
    }
  };
}];



var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
/**
 * @ngdoc directive
 * @name ngValue
 *
 * @description
 * Binds the given expression to the value of `<option>` or {@link input[radio] `input[radio]`},
 * so that when the element is selected, the {@link ngModel `ngModel`} of that element is set to
 * the bound value.
 *
 * `ngValue` is useful when dynamically generating lists of radio buttons using
 * {@link ngRepeat `ngRepeat`}, as shown below.
 *
 * Likewise, `ngValue` can be used to generate `<option>` elements for
 * the {@link select `select`} element. In that case however, only strings are supported
 * for the `value `attribute, so the resulting `ngModel` will always be a string.
 * Support for `select` models with non-string values is available via `ngOptions`.
 *
 * @element input
 * @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute
 *   of the `input` element
 *
 * @example
    <example name="ngValue-directive" module="valueExample">
      <file name="index.html">
       <script>
          angular.module('valueExample', [])
            .controller('ExampleController', ['$scope', function($scope) {
              $scope.names = ['pizza', 'unicorns', 'robots'];
              $scope.my = { favorite: 'unicorns' };
            }]);
       </script>
        <form ng-controller="ExampleController">
          <h2>Which is your favorite?</h2>
            <label ng-repeat="name in names" for="{{name}}">
              {{name}}
              <input type="radio"
                     ng-model="my.favorite"
                     ng-value="name"
                     id="{{name}}"
                     name="favorite">
            </label>
          <div>You chose {{my.favorite}}</div>
        </form>
      </file>
      <file name="protractor.js" type="protractor">
        var favorite = element(by.binding('my.favorite'));

        it('should initialize to model', function() {
          expect(favorite.getText()).toContain('unicorns');
        });
        it('should bind the values to the inputs', function() {
          element.all(by.model('my.favorite')).get(0).click();
          expect(favorite.getText()).toContain('pizza');
        });
      </file>
    </example>
 */
var ngValueDirective = function() {
  return {
    restrict: 'A',
    priority: 100,
    compile: function(tpl, tplAttr) {
      if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
        return function ngValueConstantLink(scope, elm, attr) {
          attr.$set('value', scope.$eval(attr.ngValue));
        };
      } else {
        return function ngValueLink(scope, elm, attr) {
          scope.$watch(attr.ngValue, function valueWatchAction(value) {
            attr.$set('value', value);
          });
        };
      }
    }
  };
};

/**
 * @ngdoc directive
 * @name ngBind
 * @restrict AC
 *
 * @description
 * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element
 * with the value of a given expression, and to update the text content when the value of that
 * expression changes.
 *
 * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
 * `{{ expression }}` which is similar but less verbose.
 *
 * It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily
 * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
 * element attribute, it makes the bindings invisible to the user while the page is loading.
 *
 * An alternative solution to this problem would be using the
 * {@link ng.directive:ngCloak ngCloak} directive.
 *
 *
 * @element ANY
 * @param {expression} ngBind {@link guide/expression Expression} to evaluate.
 *
 * @example
 * Enter a name in the Live Preview text box; the greeting below the text box changes instantly.
   <example module="bindExample">
     <file name="index.html">
       <script>
         angular.module('bindExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.name = 'Whirled';
           }]);
       </script>
       <div ng-controller="ExampleController">
         Enter name: <input type="text" ng-model="name"><br>
         Hello <span ng-bind="name"></span>!
       </div>
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-bind', function() {
         var nameInput = element(by.model('name'));

         expect(element(by.binding('name')).getText()).toBe('Whirled');
         nameInput.clear();
         nameInput.sendKeys('world');
         expect(element(by.binding('name')).getText()).toBe('world');
       });
     </file>
   </example>
 */
var ngBindDirective = ['$compile', function($compile) {
  return {
    restrict: 'AC',
    compile: function ngBindCompile(templateElement) {
      $compile.$$addBindingClass(templateElement);
      return function ngBindLink(scope, element, attr) {
        $compile.$$addBindingInfo(element, attr.ngBind);
        element = element[0];
        scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
          element.textContent = value === undefined ? '' : value;
        });
      };
    }
  };
}];


/**
 * @ngdoc directive
 * @name ngBindTemplate
 *
 * @description
 * The `ngBindTemplate` directive specifies that the element
 * text content should be replaced with the interpolation of the template
 * in the `ngBindTemplate` attribute.
 * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
 * expressions. This directive is needed since some HTML elements
 * (such as TITLE and OPTION) cannot contain SPAN elements.
 *
 * @element ANY
 * @param {string} ngBindTemplate template of form
 *   <tt>{{</tt> <tt>expression</tt> <tt>}}</tt> to eval.
 *
 * @example
 * Try it here: enter text in text box and watch the greeting change.
   <example module="bindExample">
     <file name="index.html">
       <script>
         angular.module('bindExample', [])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.salutation = 'Hello';
             $scope.name = 'World';
           }]);
       </script>
       <div ng-controller="ExampleController">
        Salutation: <input type="text" ng-model="salutation"><br>
        Name: <input type="text" ng-model="name"><br>
        <pre ng-bind-template="{{salutation}} {{name}}!"></pre>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-bind', function() {
         var salutationElem = element(by.binding('salutation'));
         var salutationInput = element(by.model('salutation'));
         var nameInput = element(by.model('name'));

         expect(salutationElem.getText()).toBe('Hello World!');

         salutationInput.clear();
         salutationInput.sendKeys('Greetings');
         nameInput.clear();
         nameInput.sendKeys('user');

         expect(salutationElem.getText()).toBe('Greetings user!');
       });
     </file>
   </example>
 */
var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) {
  return {
    compile: function ngBindTemplateCompile(templateElement) {
      $compile.$$addBindingClass(templateElement);
      return function ngBindTemplateLink(scope, element, attr) {
        var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));
        $compile.$$addBindingInfo(element, interpolateFn.expressions);
        element = element[0];
        attr.$observe('ngBindTemplate', function(value) {
          element.textContent = value === undefined ? '' : value;
        });
      };
    }
  };
}];


/**
 * @ngdoc directive
 * @name ngBindHtml
 *
 * @description
 * Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,
 * the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.
 * To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link
 * ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}
 * in your module's dependencies, you need to include "angular-sanitize.js" in your application.
 *
 * You may also bypass sanitization for values you know are safe. To do so, bind to
 * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}.  See the example
 * under {@link ng.$sce#show-me-an-example-using-sce- Strict Contextual Escaping (SCE)}.
 *
 * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you
 * will have an exception (instead of an exploit.)
 *
 * @element ANY
 * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
 *
 * @example

   <example module="bindHtmlExample" deps="angular-sanitize.js">
     <file name="index.html">
       <div ng-controller="ExampleController">
        <p ng-bind-html="myHTML"></p>
       </div>
     </file>

     <file name="script.js">
       angular.module('bindHtmlExample', ['ngSanitize'])
         .controller('ExampleController', ['$scope', function($scope) {
           $scope.myHTML =
              'I am an <code>HTML</code>string with ' +
              '<a href="#">links!</a> and other <em>stuff</em>';
         }]);
     </file>

     <file name="protractor.js" type="protractor">
       it('should check ng-bind-html', function() {
         expect(element(by.binding('myHTML')).getText()).toBe(
             'I am an HTMLstring with links! and other stuff');
       });
     </file>
   </example>
 */
var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {
  return {
    restrict: 'A',
    compile: function ngBindHtmlCompile(tElement, tAttrs) {
      var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);
      var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function getStringValue(value) {
        return (value || '').toString();
      });
      $compile.$$addBindingClass(tElement);

      return function ngBindHtmlLink(scope, element, attr) {
        $compile.$$addBindingInfo(element, attr.ngBindHtml);

        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
          // we re-evaluate the expr because we want a TrustedValueHolderType
          // for $sce, not a string
          element.html($sce.getTrustedHtml(ngBindHtmlGetter(scope)) || '');
        });
      };
    }
  };
}];

/**
 * @ngdoc directive
 * @name ngChange
 *
 * @description
 * Evaluate the given expression when the user changes the input.
 * The expression is evaluated immediately, unlike the JavaScript onchange event
 * which only triggers at the end of a change (usually, when the user leaves the
 * form element or presses the return key).
 *
 * The `ngChange` expression is only evaluated when a change in the input value causes
 * a new value to be committed to the model.
 *
 * It will not be evaluated:
 * * if the value returned from the `$parsers` transformation pipeline has not changed
 * * if the input has continued to be invalid since the model will stay `null`
 * * if the model is changed programmatically and not by a change to the input value
 *
 *
 * Note, this directive requires `ngModel` to be present.
 *
 * @element input
 * @param {expression} ngChange {@link guide/expression Expression} to evaluate upon change
 * in input value.
 *
 * @example
 * <example name="ngChange-directive" module="changeExample">
 *   <file name="index.html">
 *     <script>
 *       angular.module('changeExample', [])
 *         .controller('ExampleController', ['$scope', function($scope) {
 *           $scope.counter = 0;
 *           $scope.change = function() {
 *             $scope.counter++;
 *           };
 *         }]);
 *     </script>
 *     <div ng-controller="ExampleController">
 *       <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
 *       <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
 *       <label for="ng-change-example2">Confirmed</label><br />
 *       <tt>debug = {{confirmed}}</tt><br/>
 *       <tt>counter = {{counter}}</tt><br/>
 *     </div>
 *   </file>
 *   <file name="protractor.js" type="protractor">
 *     var counter = element(by.binding('counter'));
 *     var debug = element(by.binding('confirmed'));
 *
 *     it('should evaluate the expression if changing from view', function() {
 *       expect(counter.getText()).toContain('0');
 *
 *       element(by.id('ng-change-example1')).click();
 *
 *       expect(counter.getText()).toContain('1');
 *       expect(debug.getText()).toContain('true');
 *     });
 *
 *     it('should not evaluate the expression if changing from model', function() {
 *       element(by.id('ng-change-example2')).click();

 *       expect(counter.getText()).toContain('0');
 *       expect(debug.getText()).toContain('true');
 *     });
 *   </file>
 * </example>
 */
var ngChangeDirective = valueFn({
  restrict: 'A',
  require: 'ngModel',
  link: function(scope, element, attr, ctrl) {
    ctrl.$viewChangeListeners.push(function() {
      scope.$eval(attr.ngChange);
    });
  }
});

function classDirective(name, selector) {
  name = 'ngClass' + name;
  return ['$animate', function($animate) {
    return {
      restrict: 'AC',
      link: function(scope, element, attr) {
        var oldVal;

        scope.$watch(attr[name], ngClassWatchAction, true);

        attr.$observe('class', function(value) {
          ngClassWatchAction(scope.$eval(attr[name]));
        });


        if (name !== 'ngClass') {
          scope.$watch('$index', function($index, old$index) {
            // jshint bitwise: false
            var mod = $index & 1;
            if (mod !== (old$index & 1)) {
              var classes = arrayClasses(scope.$eval(attr[name]));
              mod === selector ?
                addClasses(classes) :
                removeClasses(classes);
            }
          });
        }

        function addClasses(classes) {
          var newClasses = digestClassCounts(classes, 1);
          attr.$addClass(newClasses);
        }

        function removeClasses(classes) {
          var newClasses = digestClassCounts(classes, -1);
          attr.$removeClass(newClasses);
        }

        function digestClassCounts(classes, count) {
          var classCounts = element.data('$classCounts') || {};
          var classesToUpdate = [];
          forEach(classes, function(className) {
            if (count > 0 || classCounts[className]) {
              classCounts[className] = (classCounts[className] || 0) + count;
              if (classCounts[className] === +(count > 0)) {
                classesToUpdate.push(className);
              }
            }
          });
          element.data('$classCounts', classCounts);
          return classesToUpdate.join(' ');
        }

        function updateClasses(oldClasses, newClasses) {
          var toAdd = arrayDifference(newClasses, oldClasses);
          var toRemove = arrayDifference(oldClasses, newClasses);
          toAdd = digestClassCounts(toAdd, 1);
          toRemove = digestClassCounts(toRemove, -1);
          if (toAdd && toAdd.length) {
            $animate.addClass(element, toAdd);
          }
          if (toRemove && toRemove.length) {
            $animate.removeClass(element, toRemove);
          }
        }

        function ngClassWatchAction(newVal) {
          if (selector === true || scope.$index % 2 === selector) {
            var newClasses = arrayClasses(newVal || []);
            if (!oldVal) {
              addClasses(newClasses);
            } else if (!equals(newVal,oldVal)) {
              var oldClasses = arrayClasses(oldVal);
              updateClasses(oldClasses, newClasses);
            }
          }
          oldVal = shallowCopy(newVal);
        }
      }
    };

    function arrayDifference(tokens1, tokens2) {
      var values = [];

      outer:
      for (var i = 0; i < tokens1.length; i++) {
        var token = tokens1[i];
        for (var j = 0; j < tokens2.length; j++) {
          if (token == tokens2[j]) continue outer;
        }
        values.push(token);
      }
      return values;
    }

    function arrayClasses(classVal) {
      if (isArray(classVal)) {
        return classVal;
      } else if (isString(classVal)) {
        return classVal.split(' ');
      } else if (isObject(classVal)) {
        var classes = [];
        forEach(classVal, function(v, k) {
          if (v) {
            classes = classes.concat(k.split(' '));
          }
        });
        return classes;
      }
      return classVal;
    }
  }];
}

/**
 * @ngdoc directive
 * @name ngClass
 * @restrict AC
 *
 * @description
 * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
 * an expression that represents all classes to be added.
 *
 * The directive operates in three different ways, depending on which of three types the expression
 * evaluates to:
 *
 * 1. If the expression evaluates to a string, the string should be one or more space-delimited class
 * names.
 *
 * 2. If the expression evaluates to an array, each element of the array should be a string that is
 * one or more space-delimited class names.
 *
 * 3. If the expression evaluates to an object, then for each key-value pair of the
 * object with a truthy value the corresponding key is used as a class name.
 *
 * The directive won't add duplicate classes if a particular class was already set.
 *
 * When the expression changes, the previously added classes are removed and only then the
 * new classes are added.
 *
 * @animations
 * **add** - happens just before the class is applied to the elements
 *
 * **remove** - happens just before the class is removed from the element
 *
 * @element ANY
 * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class
 *   names, an array, or a map of class names to boolean values. In the case of a map, the
 *   names of the properties whose values are truthy will be added as css classes to the
 *   element.
 *
 * @example Example that demonstrates basic bindings via ngClass directive.
   <example>
     <file name="index.html">
       <p ng-class="{strike: deleted, bold: important, red: error}">Map Syntax Example</p>
       <input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)<br>
       <input type="checkbox" ng-model="important"> important (apply "bold" class)<br>
       <input type="checkbox" ng-model="error"> error (apply "red" class)
       <hr>
       <p ng-class="style">Using String Syntax</p>
       <input type="text" ng-model="style" placeholder="Type: bold strike red">
       <hr>
       <p ng-class="[style1, style2, style3]">Using Array Syntax</p>
       <input ng-model="style1" placeholder="Type: bold, strike or red"><br>
       <input ng-model="style2" placeholder="Type: bold, strike or red"><br>
       <input ng-model="style3" placeholder="Type: bold, strike or red"><br>
     </file>
     <file name="style.css">
       .strike {
         text-decoration: line-through;
       }
       .bold {
           font-weight: bold;
       }
       .red {
           color: red;
       }
     </file>
     <file name="protractor.js" type="protractor">
       var ps = element.all(by.css('p'));

       it('should let you toggle the class', function() {

         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
         expect(ps.first().getAttribute('class')).not.toMatch(/red/);

         element(by.model('important')).click();
         expect(ps.first().getAttribute('class')).toMatch(/bold/);

         element(by.model('error')).click();
         expect(ps.first().getAttribute('class')).toMatch(/red/);
       });

       it('should let you toggle string example', function() {
         expect(ps.get(1).getAttribute('class')).toBe('');
         element(by.model('style')).clear();
         element(by.model('style')).sendKeys('red');
         expect(ps.get(1).getAttribute('class')).toBe('red');
       });

       it('array example should have 3 classes', function() {
         expect(ps.last().getAttribute('class')).toBe('');
         element(by.model('style1')).sendKeys('bold');
         element(by.model('style2')).sendKeys('strike');
         element(by.model('style3')).sendKeys('red');
         expect(ps.last().getAttribute('class')).toBe('bold strike red');
       });
     </file>
   </example>

   ## Animations

   The example below demonstrates how to perform animations using ngClass.

   <example module="ngAnimate" deps="angular-animate.js" animations="true">
     <file name="index.html">
      <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
      <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
      <br>
      <span class="base-class" ng-class="myVar">Sample Text</span>
     </file>
     <file name="style.css">
       .base-class {
         -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
       }

       .base-class.my-class {
         color: red;
         font-size:3em;
       }
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-class', function() {
         expect(element(by.css('.base-class')).getAttribute('class')).not.
           toMatch(/my-class/);

         element(by.id('setbtn')).click();

         expect(element(by.css('.base-class')).getAttribute('class')).
           toMatch(/my-class/);

         element(by.id('clearbtn')).click();

         expect(element(by.css('.base-class')).getAttribute('class')).not.
           toMatch(/my-class/);
       });
     </file>
   </example>


   ## ngClass and pre-existing CSS3 Transitions/Animations
   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder
   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure
   to view the step by step details of {@link ng.$animate#addClass $animate.addClass} and
   {@link ng.$animate#removeClass $animate.removeClass}.
 */
var ngClassDirective = classDirective('', true);

/**
 * @ngdoc directive
 * @name ngClassOdd
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">
        <ol ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
          <li ng-repeat="name in names">
           <span ng-class-odd="'odd'" ng-class-even="'even'">
             {{name}}
           </span>
          </li>
        </ol>
     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
           toMatch(/odd/);
         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassOddDirective = classDirective('Odd', 0);

/**
 * @ngdoc directive
 * @name ngClassEven
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
 *   result of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">
        <ol ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
          <li ng-repeat="name in names">
           <span ng-class-odd="'odd'" ng-class-even="'even'">
             {{name}} &nbsp; &nbsp; &nbsp;
           </span>
          </li>
        </ol>
     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
           toMatch(/odd/);
         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassEvenDirective = classDirective('Even', 1);

/**
 * @ngdoc directive
 * @name ngCloak
 * @restrict AC
 *
 * @description
 * The `ngCloak` directive is used to prevent the Angular html template from being briefly
 * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this
 * directive to avoid the undesirable flicker effect caused by the html template display.
 *
 * The directive can be applied to the `<body>` element, but the preferred usage is to apply
 * multiple `ngCloak` directives to small portions of the page to permit progressive rendering
 * of the browser view.
 *
 * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and
 * `angular.min.js`.
 * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).
 *
 * ```css
 * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
 *   display: none !important;
 * }
 * ```
 *
 * When this css rule is loaded by the browser, all html elements (including their children) that
 * are tagged with the `ngCloak` directive are hidden. When Angular encounters this directive
 * during the compilation of the template it deletes the `ngCloak` element attribute, making
 * the compiled element visible.
 *
 * For the best result, the `angular.js` script must be loaded in the head section of the html
 * document; alternatively, the css rule above must be included in the external stylesheet of the
 * application.
 *
 * @element ANY
 *
 * @example
   <example>
     <file name="index.html">
        <div id="template1" ng-cloak>{{ 'hello' }}</div>
        <div id="template2" class="ng-cloak">{{ 'world' }}</div>
     </file>
     <file name="protractor.js" type="protractor">
       it('should remove the template directive and css class', function() {
         expect($('#template1').getAttribute('ng-cloak')).
           toBeNull();
         expect($('#template2').getAttribute('ng-cloak')).
           toBeNull();
       });
     </file>
   </example>
 *
 */
var ngCloakDirective = ngDirective({
  compile: function(element, attr) {
    attr.$set('ngCloak', undefined);
    element.removeClass('ng-cloak');
  }
});

/**
 * @ngdoc directive
 * @name ngController
 *
 * @description
 * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular
 * supports the principles behind the Model-View-Controller design pattern.
 *
 * MVC components in angular:
 *
 * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties
 *   are accessed through bindings.
 * * View — The template (HTML with data bindings) that is rendered into the View.
 * * Controller — The `ngController` directive specifies a Controller class; the class contains business
 *   logic behind the application to decorate the scope with functions and values
 *
 * Note that you can also attach controllers to the DOM by declaring it in a route definition
 * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller
 * again using `ng-controller` in the template itself.  This will cause the controller to be attached
 * and executed twice.
 *
 * @element ANY
 * @scope
 * @priority 500
 * @param {expression} ngController Name of a constructor function registered with the current
 * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression}
 * that on the current scope evaluates to a constructor function.
 *
 * The controller instance can be published into a scope property by specifying
 * `ng-controller="as propertyName"`.
 *
 * If the current `$controllerProvider` is configured to use globals (via
 * {@link ng.$controllerProvider#allowGlobals `$controllerProvider.allowGlobals()` }), this may
 * also be the name of a globally accessible constructor function (not recommended).
 *
 * @example
 * Here is a simple form for editing user contact information. Adding, removing, clearing, and
 * greeting are methods declared on the controller (see source tab). These methods can
 * easily be called from the angular markup. Any changes to the data are automatically reflected
 * in the View without the need for a manual update.
 *
 * Two different declaration styles are included below:
 *
 * * one binds methods and properties directly onto the controller using `this`:
 * `ng-controller="SettingsController1 as settings"`
 * * one injects `$scope` into the controller:
 * `ng-controller="SettingsController2"`
 *
 * The second option is more common in the Angular community, and is generally used in boilerplates
 * and in this guide. However, there are advantages to binding properties directly to the controller
 * and avoiding scope.
 *
 * * Using `controller as` makes it obvious which controller you are accessing in the template when
 * multiple controllers apply to an element.
 * * If you are writing your controllers as classes you have easier access to the properties and
 * methods, which will appear on the scope, from inside the controller code.
 * * Since there is always a `.` in the bindings, you don't have to worry about prototypal
 * inheritance masking primitives.
 *
 * This example demonstrates the `controller as` syntax.
 *
 * <example name="ngControllerAs" module="controllerAsExample">
 *   <file name="index.html">
 *    <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
 *      Name: <input type="text" ng-model="settings.name"/>
 *      [ <a href="" ng-click="settings.greet()">greet</a> ]<br/>
 *      Contact:
 *      <ul>
 *        <li ng-repeat="contact in settings.contacts">
 *          <select ng-model="contact.type">
 *             <option>phone</option>
 *             <option>email</option>
 *          </select>
 *          <input type="text" ng-model="contact.value"/>
 *          [ <a href="" ng-click="settings.clearContact(contact)">clear</a>
 *          | <a href="" ng-click="settings.removeContact(contact)">X</a> ]
 *        </li>
 *        <li>[ <a href="" ng-click="settings.addContact()">add</a> ]</li>
 *     </ul>
 *    </div>
 *   </file>
 *   <file name="app.js">
 *    angular.module('controllerAsExample', [])
 *      .controller('SettingsController1', SettingsController1);
 *
 *    function SettingsController1() {
 *      this.name = "John Smith";
 *      this.contacts = [
 *        {type: 'phone', value: '408 555 1212'},
 *        {type: 'email', value: 'john.smith@example.org'} ];
 *    }
 *
 *    SettingsController1.prototype.greet = function() {
 *      alert(this.name);
 *    };
 *
 *    SettingsController1.prototype.addContact = function() {
 *      this.contacts.push({type: 'email', value: 'yourname@example.org'});
 *    };
 *
 *    SettingsController1.prototype.removeContact = function(contactToRemove) {
 *     var index = this.contacts.indexOf(contactToRemove);
 *      this.contacts.splice(index, 1);
 *    };
 *
 *    SettingsController1.prototype.clearContact = function(contact) {
 *      contact.type = 'phone';
 *      contact.value = '';
 *    };
 *   </file>
 *   <file name="protractor.js" type="protractor">
 *     it('should check controller as', function() {
 *       var container = element(by.id('ctrl-as-exmpl'));
 *         expect(container.element(by.model('settings.name'))
 *           .getAttribute('value')).toBe('John Smith');
 *
 *       var firstRepeat =
 *           container.element(by.repeater('contact in settings.contacts').row(0));
 *       var secondRepeat =
 *           container.element(by.repeater('contact in settings.contacts').row(1));
 *
 *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
 *           .toBe('408 555 1212');
 *
 *       expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
 *           .toBe('john.smith@example.org');
 *
 *       firstRepeat.element(by.linkText('clear')).click();
 *
 *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
 *           .toBe('');
 *
 *       container.element(by.linkText('add')).click();
 *
 *       expect(container.element(by.repeater('contact in settings.contacts').row(2))
 *           .element(by.model('contact.value'))
 *           .getAttribute('value'))
 *           .toBe('yourname@example.org');
 *     });
 *   </file>
 * </example>
 *
 * This example demonstrates the "attach to `$scope`" style of controller.
 *
 * <example name="ngController" module="controllerExample">
 *  <file name="index.html">
 *   <div id="ctrl-exmpl" ng-controller="SettingsController2">
 *     Name: <input type="text" ng-model="name"/>
 *     [ <a href="" ng-click="greet()">greet</a> ]<br/>
 *     Contact:
 *     <ul>
 *       <li ng-repeat="contact in contacts">
 *         <select ng-model="contact.type">
 *            <option>phone</option>
 *            <option>email</option>
 *         </select>
 *         <input type="text" ng-model="contact.value"/>
 *         [ <a href="" ng-click="clearContact(contact)">clear</a>
 *         | <a href="" ng-click="removeContact(contact)">X</a> ]
 *       </li>
 *       <li>[ <a href="" ng-click="addContact()">add</a> ]</li>
 *    </ul>
 *   </div>
 *  </file>
 *  <file name="app.js">
 *   angular.module('controllerExample', [])
 *     .controller('SettingsController2', ['$scope', SettingsController2]);
 *
 *   function SettingsController2($scope) {
 *     $scope.name = "John Smith";
 *     $scope.contacts = [
 *       {type:'phone', value:'408 555 1212'},
 *       {type:'email', value:'john.smith@example.org'} ];
 *
 *     $scope.greet = function() {
 *       alert($scope.name);
 *     };
 *
 *     $scope.addContact = function() {
 *       $scope.contacts.push({type:'email', value:'yourname@example.org'});
 *     };
 *
 *     $scope.removeContact = function(contactToRemove) {
 *       var index = $scope.contacts.indexOf(contactToRemove);
 *       $scope.contacts.splice(index, 1);
 *     };
 *
 *     $scope.clearContact = function(contact) {
 *       contact.type = 'phone';
 *       contact.value = '';
 *     };
 *   }
 *  </file>
 *  <file name="protractor.js" type="protractor">
 *    it('should check controller', function() {
 *      var container = element(by.id('ctrl-exmpl'));
 *
 *      expect(container.element(by.model('name'))
 *          .getAttribute('value')).toBe('John Smith');
 *
 *      var firstRepeat =
 *          container.element(by.repeater('contact in contacts').row(0));
 *      var secondRepeat =
 *          container.element(by.repeater('contact in contacts').row(1));
 *
 *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
 *          .toBe('408 555 1212');
 *      expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
 *          .toBe('john.smith@example.org');
 *
 *      firstRepeat.element(by.linkText('clear')).click();
 *
 *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
 *          .toBe('');
 *
 *      container.element(by.linkText('add')).click();
 *
 *      expect(container.element(by.repeater('contact in contacts').row(2))
 *          .element(by.model('contact.value'))
 *          .getAttribute('value'))
 *          .toBe('yourname@example.org');
 *    });
 *  </file>
 *</example>

 */
var ngControllerDirective = [function() {
  return {
    restrict: 'A',
    scope: true,
    controller: '@',
    priority: 500
  };
}];

/**
 * @ngdoc directive
 * @name ngCsp
 *
 * @element html
 * @description
 * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
 *
 * This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.
 *
 * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
 * For Angular to be CSP compatible there are only two things that we need to do differently:
 *
 * - don't use `Function` constructor to generate optimized value getters
 * - don't inject custom stylesheet into the document
 *
 * AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp`
 * directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will
 * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
 * be raised.
 *
 * CSP forbids JavaScript to inline stylesheet rules. In non CSP mode Angular automatically
 * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}).
 * To make those directives work in CSP mode, include the `angular-csp.css` manually.
 *
 * Angular tries to autodetect if CSP is active and automatically turn on the CSP-safe mode. This
 * autodetection however triggers a CSP error to be logged in the console:
 *
 * ```
 * Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of
 * script in the following Content Security Policy directive: "default-src 'self'". Note that
 * 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
 * ```
 *
 * This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp`
 * directive on the root element of the application or on the `angular.js` script tag, whichever
 * appears first in the html document.
 *
 * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.*
 *
 * @example
 * This example shows how to apply the `ngCsp` directive to the `html` tag.
   ```html
     <!doctype html>
     <html ng-app ng-csp>
     ...
     ...
     </html>
   ```
  * @example
      // Note: the suffix `.csp` in the example name triggers
      // csp mode in our http server!
      <example name="example.csp" module="cspExample" ng-csp="true">
        <file name="index.html">
          <div ng-controller="MainController as ctrl">
            <div>
              <button ng-click="ctrl.inc()" id="inc">Increment</button>
              <span id="counter">
                {{ctrl.counter}}
              </span>
            </div>

            <div>
              <button ng-click="ctrl.evil()" id="evil">Evil</button>
              <span id="evilError">
                {{ctrl.evilError}}
              </span>
            </div>
          </div>
        </file>
        <file name="script.js">
           angular.module('cspExample', [])
             .controller('MainController', function() {
                this.counter = 0;
                this.inc = function() {
                  this.counter++;
                };
                this.evil = function() {
                  // jshint evil:true
                  try {
                    eval('1+2');
                  } catch (e) {
                    this.evilError = e.message;
                  }
                };
              });
        </file>
        <file name="protractor.js" type="protractor">
          var util, webdriver;

          var incBtn = element(by.id('inc'));
          var counter = element(by.id('counter'));
          var evilBtn = element(by.id('evil'));
          var evilError = element(by.id('evilError'));

          function getAndClearSevereErrors() {
            return browser.manage().logs().get('browser').then(function(browserLog) {
              return browserLog.filter(function(logEntry) {
                return logEntry.level.value > webdriver.logging.Level.WARNING.value;
              });
            });
          }

          function clearErrors() {
            getAndClearSevereErrors();
          }

          function expectNoErrors() {
            getAndClearSevereErrors().then(function(filteredLog) {
              expect(filteredLog.length).toEqual(0);
              if (filteredLog.length) {
                console.log('browser console errors: ' + util.inspect(filteredLog));
              }
            });
          }

          function expectError(regex) {
            getAndClearSevereErrors().then(function(filteredLog) {
              var found = false;
              filteredLog.forEach(function(log) {
                if (log.message.match(regex)) {
                  found = true;
                }
              });
              if (!found) {
                throw new Error('expected an error that matches ' + regex);
              }
            });
          }

          beforeEach(function() {
            util = require('util');
            webdriver = require('protractor/node_modules/selenium-webdriver');
          });

          // For now, we only test on Chrome,
          // as Safari does not load the page with Protractor's injected scripts,
          // and Firefox webdriver always disables content security policy (#6358)
          if (browser.params.browser !== 'chrome') {
            return;
          }

          it('should not report errors when the page is loaded', function() {
            // clear errors so we are not dependent on previous tests
            clearErrors();
            // Need to reload the page as the page is already loaded when
            // we come here
            browser.driver.getCurrentUrl().then(function(url) {
              browser.get(url);
            });
            expectNoErrors();
          });

          it('should evaluate expressions', function() {
            expect(counter.getText()).toEqual('0');
            incBtn.click();
            expect(counter.getText()).toEqual('1');
            expectNoErrors();
          });

          it('should throw and report an error when using "eval"', function() {
            evilBtn.click();
            expect(evilError.getText()).toMatch(/Content Security Policy/);
            expectError(/Content Security Policy/);
          });
        </file>
      </example>
  */

// ngCsp is not implemented as a proper directive any more, because we need it be processed while we
// bootstrap the system (before $parse is instantiated), for this reason we just have
// the csp.isActive() fn that looks for ng-csp attribute anywhere in the current doc

/**
 * @ngdoc directive
 * @name ngClick
 *
 * @description
 * The ngClick directive allows you to specify custom behavior when
 * an element is clicked.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
 * click. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-click="count = count + 1" ng-init="count=0">
        Increment
      </button>
      <span>
        count: {{count}}
      </span>
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-click', function() {
         expect(element(by.binding('count')).getText()).toMatch('0');
         element(by.css('button')).click();
         expect(element(by.binding('count')).getText()).toMatch('1');
       });
     </file>
   </example>
 */
/*
 * A collection of directives that allows creation of custom event handlers that are defined as
 * angular expressions and are compiled and executed within the current scope.
 */
var ngEventDirectives = {};

// For events that might fire synchronously during DOM manipulation
// we need to execute their event handlers asynchronously using $evalAsync,
// so that they are not executed in an inconsistent state.
var forceAsyncEvents = {
  'blur': true,
  'focus': true
};
forEach(
  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
  function(eventName) {
    var directiveName = directiveNormalize('ng-' + eventName);
    ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
      return {
        restrict: 'A',
        compile: function($element, attr) {
          // We expose the powerful $event object on the scope that provides access to the Window,
          // etc. that isn't protected by the fast paths in $parse.  We explicitly request better
          // checks at the cost of speed since event handler expressions are not executed as
          // frequently as regular change detection.
          var fn = $parse(attr[directiveName], /* interceptorFn */ null, /* expensiveChecks */ true);
          return function ngEventHandler(scope, element) {
            element.on(eventName, function(event) {
              var callback = function() {
                fn(scope, {$event:event});
              };
              if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
                scope.$evalAsync(callback);
              } else {
                scope.$apply(callback);
              }
            });
          };
        }
      };
    }];
  }
);

/**
 * @ngdoc directive
 * @name ngDblclick
 *
 * @description
 * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
 * a dblclick. (The Event object is available as `$event`)
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-dblclick="count = count + 1" ng-init="count=0">
        Increment (on double click)
      </button>
      count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngMousedown
 *
 * @description
 * The ngMousedown directive allows you to specify custom behavior on mousedown event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
 * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mousedown="count = count + 1" ng-init="count=0">
        Increment (on mouse down)
      </button>
      count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngMouseup
 *
 * @description
 * Specify custom behavior on mouseup event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
 * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseup="count = count + 1" ng-init="count=0">
        Increment (on mouse up)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseover
 *
 * @description
 * Specify custom behavior on mouseover event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
 * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseover="count = count + 1" ng-init="count=0">
        Increment (when mouse is over)
      </button>
      count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngMouseenter
 *
 * @description
 * Specify custom behavior on mouseenter event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
 * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseenter="count = count + 1" ng-init="count=0">
        Increment (when mouse enters)
      </button>
      count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngMouseleave
 *
 * @description
 * Specify custom behavior on mouseleave event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
 * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseleave="count = count + 1" ng-init="count=0">
        Increment (when mouse leaves)
      </button>
      count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngMousemove
 *
 * @description
 * Specify custom behavior on mousemove event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
 * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mousemove="count = count + 1" ng-init="count=0">
        Increment (when mouse moves)
      </button>
      count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngKeydown
 *
 * @description
 * Specify custom behavior on keydown event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
 * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-keydown="count = count + 1" ng-init="count=0">
      key down count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngKeyup
 *
 * @description
 * Specify custom behavior on keyup event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
 * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
       <p>Typing in the input box below updates the key count</p>
       <input ng-keyup="count = count + 1" ng-init="count=0"> key up count: {{count}}

       <p>Typing in the input box below updates the keycode</p>
       <input ng-keyup="event=$event">
       <p>event keyCode: {{ event.keyCode }}</p>
       <p>event altKey: {{ event.altKey }}</p>
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngKeypress
 *
 * @description
 * Specify custom behavior on keypress event.
 *
 * @element ANY
 * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
 * keypress. ({@link guide/expression#-event- Event object is available as `$event`}
 * and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-keypress="count = count + 1" ng-init="count=0">
      key press count: {{count}}
     </file>
   </example>
 */


/**
 * @ngdoc directive
 * @name ngSubmit
 *
 * @description
 * Enables binding angular expressions to onsubmit events.
 *
 * Additionally it prevents the default action (which for form means sending the request to the
 * server and reloading the current page), but only if the form does not contain `action`,
 * `data-action`, or `x-action` attributes.
 *
 * <div class="alert alert-warning">
 * **Warning:** Be careful not to cause "double-submission" by using both the `ngClick` and
 * `ngSubmit` handlers together. See the
 * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}
 * for a detailed discussion of when `ngSubmit` may be triggered.
 * </div>
 *
 * @element form
 * @priority 0
 * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
 * ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example module="submitExample">
     <file name="index.html">
      <script>
        angular.module('submitExample', [])
          .controller('ExampleController', ['$scope', function($scope) {
            $scope.list = [];
            $scope.text = 'hello';
            $scope.submit = function() {
              if ($scope.text) {
                $scope.list.push(this.text);
                $scope.text = '';
              }
            };
          }]);
      </script>
      <form ng-submit="submit()" ng-controller="ExampleController">
        Enter text and hit enter:
        <input type="text" ng-model="text" name="text" />
        <input type="submit" id="submit" value="Submit" />
        <pre>list={{list}}</pre>
      </form>
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-submit', function() {
         expect(element(by.binding('list')).getText()).toBe('list=[]');
         element(by.css('#submit')).click();
         expect(element(by.binding('list')).getText()).toContain('hello');
         expect(element(by.model('text')).getAttribute('value')).toBe('');
       });
       it('should ignore empty strings', function() {
         expect(element(by.binding('list')).getText()).toBe('list=[]');
         element(by.css('#submit')).click();
         element(by.css('#submit')).click();
         expect(element(by.binding('list')).getText()).toContain('hello');
        });
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngFocus
 *
 * @description
 * Specify custom behavior on focus event.
 *
 * Note: As the `focus` event is executed synchronously when calling `input.focus()`
 * AngularJS executes the expression using `scope.$evalAsync` if the event is fired
 * during an `$apply` to ensure a consistent state.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
 * focus. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
 * See {@link ng.directive:ngClick ngClick}
 */

/**
 * @ngdoc directive
 * @name ngBlur
 *
 * @description
 * Specify custom behavior on blur event.
 *
 * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when
 * an element has lost focus.
 *
 * Note: As the `blur` event is executed synchronously also during DOM manipulations
 * (e.g. removing a focussed input),
 * AngularJS executes the expression using `scope.$evalAsync` if the event is fired
 * during an `$apply` to ensure a consistent state.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
 * blur. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
 * See {@link ng.directive:ngClick ngClick}
 */

/**
 * @ngdoc directive
 * @name ngCopy
 *
 * @description
 * Specify custom behavior on copy event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
 * copy. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
      copied: {{copied}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngCut
 *
 * @description
 * Specify custom behavior on cut event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
 * cut. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
      cut: {{cut}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngPaste
 *
 * @description
 * Specify custom behavior on paste event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
 * paste. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
      pasted: {{paste}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngIf
 * @restrict A
 *
 * @description
 * The `ngIf` directive removes or recreates a portion of the DOM tree based on an
 * {expression}. If the expression assigned to `ngIf` evaluates to a false
 * value then the element is removed from the DOM, otherwise a clone of the
 * element is reinserted into the DOM.
 *
 * `ngIf` differs from `ngShow` and `ngHide` in that `ngIf` completely removes and recreates the
 * element in the DOM rather than changing its visibility via the `display` css property.  A common
 * case when this difference is significant is when using css selectors that rely on an element's
 * position within the DOM, such as the `:first-child` or `:last-child` pseudo-classes.
 *
 * Note that when an element is removed using `ngIf` its scope is destroyed and a new scope
 * is created when the element is restored.  The scope created within `ngIf` inherits from
 * its parent scope using
 * [prototypal inheritance](https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance).
 * An important implication of this is if `ngModel` is used within `ngIf` to bind to
 * a javascript primitive defined in the parent scope. In this case any modifications made to the
 * variable within the child scope will override (hide) the value in the parent scope.
 *
 * Also, `ngIf` recreates elements using their compiled state. An example of this behavior
 * is if an element's class attribute is directly modified after it's compiled, using something like
 * jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element
 * the added class will be lost because the original compiled state is used to regenerate the element.
 *
 * Additionally, you can provide animations via the `ngAnimate` module to animate the `enter`
 * and `leave` effects.
 *
 * @animations
 * enter - happens just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container
 * leave - happens just before the `ngIf` contents are removed from the DOM
 *
 * @element ANY
 * @scope
 * @priority 600
 * @param {expression} ngIf If the {@link guide/expression expression} is falsy then
 *     the element is removed from the DOM tree. If it is truthy a copy of the compiled
 *     element is added to the DOM tree.
 *
 * @example
  <example module="ngAnimate" deps="angular-animate.js" animations="true">
    <file name="index.html">
      Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /><br/>
      Show when checked:
      <span ng-if="checked" class="animate-if">
        This is removed when the checkbox is unchecked.
      </span>
    </file>
    <file name="animations.css">
      .animate-if {
        background:white;
        border:1px solid black;
        padding:10px;
      }

      .animate-if.ng-enter, .animate-if.ng-leave {
        -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
      }

      .animate-if.ng-enter,
      .animate-if.ng-leave.ng-leave-active {
        opacity:0;
      }

      .animate-if.ng-leave,
      .animate-if.ng-enter.ng-enter-active {
        opacity:1;
      }
    </file>
  </example>
 */
var ngIfDirective = ['$animate', function($animate) {
  return {
    multiElement: true,
    transclude: 'element',
    priority: 600,
    terminal: true,
    restrict: 'A',
    $$tlb: true,
    link: function($scope, $element, $attr, ctrl, $transclude) {
        var block, childScope, previousElements;
        $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {

          if (value) {
            if (!childScope) {
              $transclude(function(clone, newScope) {
                childScope = newScope;
                clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
                // Note: We only need the first/last node of the cloned nodes.
                // However, we need to keep the reference to the jqlite wrapper as it might be changed later
                // by a directive with templateUrl when its template arrives.
                block = {
                  clone: clone
                };
                $animate.enter(clone, $element.parent(), $element);
              });
            }
          } else {
            if (previousElements) {
              previousElements.remove();
              previousElements = null;
            }
            if (childScope) {
              childScope.$destroy();
              childScope = null;
            }
            if (block) {
              previousElements = getBlockNodes(block.clone);
              $animate.leave(previousElements).then(function() {
                previousElements = null;
              });
              block = null;
            }
          }
        });
    }
  };
}];

/**
 * @ngdoc directive
 * @name ngInclude
 * @restrict ECA
 *
 * @description
 * Fetches, compiles and includes an external HTML fragment.
 *
 * By default, the template URL is restricted to the same domain and protocol as the
 * application document. This is done by calling {@link $sce#getTrustedResourceUrl
 * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols
 * you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or
 * {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link
 * ng.$sce Strict Contextual Escaping}.
 *
 * In addition, the browser's
 * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
 * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)
 * policy may further restrict whether the template is successfully loaded.
 * For example, `ngInclude` won't work for cross-domain requests on all browsers and for `file://`
 * access on some browsers.
 *
 * @animations
 * enter - animation is used to bring new content into the browser.
 * leave - animation is used to animate existing content away.
 *
 * The enter and leave animation occur concurrently.
 *
 * @scope
 * @priority 400
 *
 * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant,
 *                 make sure you wrap it in **single** quotes, e.g. `src="'myPartialTemplate.html'"`.
 * @param {string=} onload Expression to evaluate when a new partial is loaded.
 *
 * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll
 *                  $anchorScroll} to scroll the viewport after the content is loaded.
 *
 *                  - If the attribute is not set, disable scrolling.
 *                  - If the attribute is set without value, enable scrolling.
 *                  - Otherwise enable scrolling only if the expression evaluates to truthy value.
 *
 * @example
  <example module="includeExample" deps="angular-animate.js" animations="true">
    <file name="index.html">
     <div ng-controller="ExampleController">
       <select ng-model="template" ng-options="t.name for t in templates">
        <option value="">(blank)</option>
       </select>
       url of the template: <code>{{template.url}}</code>
       <hr/>
       <div class="slide-animate-container">
         <div class="slide-animate" ng-include="template.url"></div>
       </div>
     </div>
    </file>
    <file name="script.js">
      angular.module('includeExample', ['ngAnimate'])
        .controller('ExampleController', ['$scope', function($scope) {
          $scope.templates =
            [ { name: 'template1.html', url: 'template1.html'},
              { name: 'template2.html', url: 'template2.html'} ];
          $scope.template = $scope.templates[0];
        }]);
     </file>
    <file name="template1.html">
      Content of template1.html
    </file>
    <file name="template2.html">
      Content of template2.html
    </file>
    <file name="animations.css">
      .slide-animate-container {
        position:relative;
        background:white;
        border:1px solid black;
        height:40px;
        overflow:hidden;
      }

      .slide-animate {
        padding:10px;
      }

      .slide-animate.ng-enter, .slide-animate.ng-leave {
        -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;

        position:absolute;
        top:0;
        left:0;
        right:0;
        bottom:0;
        display:block;
        padding:10px;
      }

      .slide-animate.ng-enter {
        top:-50px;
      }
      .slide-animate.ng-enter.ng-enter-active {
        top:0;
      }

      .slide-animate.ng-leave {
        top:0;
      }
      .slide-animate.ng-leave.ng-leave-active {
        top:50px;
      }
    </file>
    <file name="protractor.js" type="protractor">
      var templateSelect = element(by.model('template'));
      var includeElem = element(by.css('[ng-include]'));

      it('should load template1.html', function() {
        expect(includeElem.getText()).toMatch(/Content of template1.html/);
      });

      it('should load template2.html', function() {
        if (browser.params.browser == 'firefox') {
          // Firefox can't handle using selects
          // See https://github.com/angular/protractor/issues/480
          return;
        }
        templateSelect.click();
        templateSelect.all(by.css('option')).get(2).click();
        expect(includeElem.getText()).toMatch(/Content of template2.html/);
      });

      it('should change to blank', function() {
        if (browser.params.browser == 'firefox') {
          // Firefox can't handle using selects
          return;
        }
        templateSelect.click();
        templateSelect.all(by.css('option')).get(0).click();
        expect(includeElem.isPresent()).toBe(false);
      });
    </file>
  </example>
 */


/**
 * @ngdoc event
 * @name ngInclude#$includeContentRequested
 * @eventType emit on the scope ngInclude was declared in
 * @description
 * Emitted every time the ngInclude content is requested.
 *
 * @param {Object} angularEvent Synthetic event object.
 * @param {String} src URL of content to load.
 */


/**
 * @ngdoc event
 * @name ngInclude#$includeContentLoaded
 * @eventType emit on the current ngInclude scope
 * @description
 * Emitted every time the ngInclude content is reloaded.
 *
 * @param {Object} angularEvent Synthetic event object.
 * @param {String} src URL of content to load.
 */


/**
 * @ngdoc event
 * @name ngInclude#$includeContentError
 * @eventType emit on the scope ngInclude was declared in
 * @description
 * Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299)
 *
 * @param {Object} angularEvent Synthetic event object.
 * @param {String} src URL of content to load.
 */
var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',
                  function($templateRequest,   $anchorScroll,   $animate) {
  return {
    restrict: 'ECA',
    priority: 400,
    terminal: true,
    transclude: 'element',
    controller: angular.noop,
    compile: function(element, attr) {
      var srcExp = attr.ngInclude || attr.src,
          onloadExp = attr.onload || '',
          autoScrollExp = attr.autoscroll;

      return function(scope, $element, $attr, ctrl, $transclude) {
        var changeCounter = 0,
            currentScope,
            previousElement,
            currentElement;

        var cleanupLastIncludeContent = function() {
          if (previousElement) {
            previousElement.remove();
            previousElement = null;
          }
          if (currentScope) {
            currentScope.$destroy();
            currentScope = null;
          }
          if (currentElement) {
            $animate.leave(currentElement).then(function() {
              previousElement = null;
            });
            previousElement = currentElement;
            currentElement = null;
          }
        };

        scope.$watch(srcExp, function ngIncludeWatchAction(src) {
          var afterAnimation = function() {
            if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
              $anchorScroll();
            }
          };
          var thisChangeId = ++changeCounter;

          if (src) {
            //set the 2nd param to true to ignore the template request error so that the inner
            //contents and scope can be cleaned up.
            $templateRequest(src, true).then(function(response) {
              if (thisChangeId !== changeCounter) return;
              var newScope = scope.$new();
              ctrl.template = response;

              // Note: This will also link all children of ng-include that were contained in the original
              // html. If that content contains controllers, ... they could pollute/change the scope.
              // However, using ng-include on an element with additional content does not make sense...
              // Note: We can't remove them in the cloneAttchFn of $transclude as that
              // function is called before linking the content, which would apply child
              // directives to non existing elements.
              var clone = $transclude(newScope, function(clone) {
                cleanupLastIncludeContent();
                $animate.enter(clone, null, $element).then(afterAnimation);
              });

              currentScope = newScope;
              currentElement = clone;

              currentScope.$emit('$includeContentLoaded', src);
              scope.$eval(onloadExp);
            }, function() {
              if (thisChangeId === changeCounter) {
                cleanupLastIncludeContent();
                scope.$emit('$includeContentError', src);
              }
            });
            scope.$emit('$includeContentRequested', src);
          } else {
            cleanupLastIncludeContent();
            ctrl.template = null;
          }
        });
      };
    }
  };
}];

// This directive is called during the $transclude call of the first `ngInclude` directive.
// It will replace and compile the content of the element with the loaded template.
// We need this directive so that the element content is already filled when
// the link function of another directive on the same element as ngInclude
// is called.
var ngIncludeFillContentDirective = ['$compile',
  function($compile) {
    return {
      restrict: 'ECA',
      priority: -400,
      require: 'ngInclude',
      link: function(scope, $element, $attr, ctrl) {
        if (/SVG/.test($element[0].toString())) {
          // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not
          // support innerHTML, so detect this here and try to generate the contents
          // specially.
          $element.empty();
          $compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope,
              function namespaceAdaptedClone(clone) {
            $element.append(clone);
          }, {futureParentElement: $element});
          return;
        }

        $element.html(ctrl.template);
        $compile($element.contents())(scope);
      }
    };
  }];

/**
 * @ngdoc directive
 * @name ngInit
 * @restrict AC
 *
 * @description
 * The `ngInit` directive allows you to evaluate an expression in the
 * current scope.
 *
 * <div class="alert alert-error">
 * The only appropriate use of `ngInit` is for aliasing special properties of
 * {@link ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below. Besides this case, you
 * should use {@link guide/controller controllers} rather than `ngInit`
 * to initialize values on a scope.
 * </div>
 * <div class="alert alert-warning">
 * **Note**: If you have assignment in `ngInit` along with {@link ng.$filter `$filter`}, make
 * sure you have parenthesis for correct precedence:
 * <pre class="prettyprint">
 * `<div ng-init="test1 = (data | orderBy:'name')"></div>`
 * </pre>
 * </div>
 *
 * @priority 450
 *
 * @element ANY
 * @param {expression} ngInit {@link guide/expression Expression} to eval.
 *
 * @example
   <example module="initExample">
     <file name="index.html">
   <script>
     angular.module('initExample', [])
       .controller('ExampleController', ['$scope', function($scope) {
         $scope.list = [['a', 'b'], ['c', 'd']];
       }]);
   </script>
   <div ng-controller="ExampleController">
     <div ng-repeat="innerList in list" ng-init="outerIndex = $index">
       <div ng-repeat="value in innerList" ng-init="innerIndex = $index">
          <span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
       </div>
     </div>
   </div>
     </file>
     <file name="protractor.js" type="protractor">
       it('should alias index positions', function() {
         var elements = element.all(by.css('.example-init'));
         expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
         expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
         expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
         expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
       });
     </file>
   </example>
 */
var ngInitDirective = ngDirective({
  priority: 450,
  compile: function() {
    return {
      pre: function(scope, element, attrs) {
        scope.$eval(attrs.ngInit);
      }
    };
  }
});

/**
 * @ngdoc directive
 * @name ngList
 *
 * @description
 * Text input that converts between a delimited string and an array of strings. The default
 * delimiter is a comma followed by a space - equivalent to `ng-list=", "`. You can specify a custom
 * delimiter as the value of the `ngList` attribute - for example, `ng-list=" | "`.
 *
 * The behaviour of the directive is affected by the use of the `ngTrim` attribute.
 * * If `ngTrim` is set to `"false"` then whitespace around both the separator and each
 *   list item is respected. This implies that the user of the directive is responsible for
 *   dealing with whitespace but also allows you to use whitespace as a delimiter, such as a
 *   tab or newline character.
 * * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected
 *   when joining the list items back together) and whitespace around each list item is stripped
 *   before it is added to the model.
 *
 * ### Example with Validation
 *
 * <example name="ngList-directive" module="listExample">
 *   <file name="app.js">
 *      angular.module('listExample', [])
 *        .controller('ExampleController', ['$scope', function($scope) {
 *          $scope.names = ['morpheus', 'neo', 'trinity'];
 *        }]);
 *   </file>
 *   <file name="index.html">
 *    <form name="myForm" ng-controller="ExampleController">
 *      List: <input name="namesInput" ng-model="names" ng-list required>
 *      <span class="error" ng-show="myForm.namesInput.$error.required">
 *        Required!</span>
 *      <br>
 *      <tt>names = {{names}}</tt><br/>
 *      <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
 *      <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
 *      <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
 *      <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
 *     </form>
 *   </file>
 *   <file name="protractor.js" type="protractor">
 *     var listInput = element(by.model('names'));
 *     var names = element(by.exactBinding('names'));
 *     var valid = element(by.binding('myForm.namesInput.$valid'));
 *     var error = element(by.css('span.error'));
 *
 *     it('should initialize to model', function() {
 *       expect(names.getText()).toContain('["morpheus","neo","trinity"]');
 *       expect(valid.getText()).toContain('true');
 *       expect(error.getCssValue('display')).toBe('none');
 *     });
 *
 *     it('should be invalid if empty', function() {
 *       listInput.clear();
 *       listInput.sendKeys('');
 *
 *       expect(names.getText()).toContain('');
 *       expect(valid.getText()).toContain('false');
 *       expect(error.getCssValue('display')).not.toBe('none');
 *     });
 *   </file>
 * </example>
 *
 * ### Example - splitting on whitespace
 * <example name="ngList-directive-newlines">
 *   <file name="index.html">
 *    <textarea ng-model="list" ng-list="&#10;" ng-trim="false"></textarea>
 *    <pre>{{ list | json }}</pre>
 *   </file>
 *   <file name="protractor.js" type="protractor">
 *     it("should split the text by newlines", function() {
 *       var listInput = element(by.model('list'));
 *       var output = element(by.binding('list | json'));
 *       listInput.sendKeys('abc\ndef\nghi');
 *       expect(output.getText()).toContain('[\n  "abc",\n  "def",\n  "ghi"\n]');
 *     });
 *   </file>
 * </example>
 *
 * @element input
 * @param {string=} ngList optional delimiter that should be used to split the value.
 */
var ngListDirective = function() {
  return {
    restrict: 'A',
    priority: 100,
    require: 'ngModel',
    link: function(scope, element, attr, ctrl) {
      // We want to control whitespace trimming so we use this convoluted approach
      // to access the ngList attribute, which doesn't pre-trim the attribute
      var ngList = element.attr(attr.$attr.ngList) || ', ';
      var trimValues = attr.ngTrim !== 'false';
      var separator = trimValues ? trim(ngList) : ngList;

      var parse = function(viewValue) {
        // If the viewValue is invalid (say required but empty) it will be `undefined`
        if (isUndefined(viewValue)) return;

        var list = [];

        if (viewValue) {
          forEach(viewValue.split(separator), function(value) {
            if (value) list.push(trimValues ? trim(value) : value);
          });
        }

        return list;
      };

      ctrl.$parsers.push(parse);
      ctrl.$formatters.push(function(value) {
        if (isArray(value)) {
          return value.join(ngList);
        }

        return undefined;
      });

      // Override the standard $isEmpty because an empty array means the input is empty.
      ctrl.$isEmpty = function(value) {
        return !value || !value.length;
      };
    }
  };
};

/* global VALID_CLASS: true,
  INVALID_CLASS: true,
  PRISTINE_CLASS: true,
  DIRTY_CLASS: true,
  UNTOUCHED_CLASS: true,
  TOUCHED_CLASS: true,
*/

var VALID_CLASS = 'ng-valid',
    INVALID_CLASS = 'ng-invalid',
    PRISTINE_CLASS = 'ng-pristine',
    DIRTY_CLASS = 'ng-dirty',
    UNTOUCHED_CLASS = 'ng-untouched',
    TOUCHED_CLASS = 'ng-touched',
    PENDING_CLASS = 'ng-pending';

var ngModelMinErr = minErr('ngModel');

/**
 * @ngdoc type
 * @name ngModel.NgModelController
 *
 * @property {string} $viewValue Actual string value in the view.
 * @property {*} $modelValue The value in the model that the control is bound to.
 * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
       the control reads value from the DOM. The functions are called in array order, each passing
       its return value through to the next. The last return value is forwarded to the
       {@link ngModel.NgModelController#$validators `$validators`} collection.

Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue
`$viewValue`}.

Returning `undefined` from a parser means a parse error occurred. In that case,
no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`
will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}
is set to `true`. The parse error is stored in `ngModel.$error.parse`.

 *
 * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
       the model value changes. The functions are called in reverse array order, each passing the value through to the
       next. The last return value is used as the actual DOM value.
       Used to format / convert values for display in the control.
 * ```js
 * function formatter(value) {
 *   if (value) {
 *     return value.toUpperCase();
 *   }
 * }
 * ngModel.$formatters.push(formatter);
 * ```
 *
 * @property {Object.<string, function>} $validators A collection of validators that are applied
 *      whenever the model value changes. The key value within the object refers to the name of the
 *      validator while the function refers to the validation operation. The validation operation is
 *      provided with the model value as an argument and must return a true or false value depending
 *      on the response of that validation.
 *
 * ```js
 * ngModel.$validators.validCharacters = function(modelValue, viewValue) {
 *   var value = modelValue || viewValue;
 *   return /[0-9]+/.test(value) &&
 *          /[a-z]+/.test(value) &&
 *          /[A-Z]+/.test(value) &&
 *          /\W+/.test(value);
 * };
 * ```
 *
 * @property {Object.<string, function>} $asyncValidators A collection of validations that are expected to
 *      perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided
 *      is expected to return a promise when it is run during the model validation process. Once the promise
 *      is delivered then the validation status will be set to true when fulfilled and false when rejected.
 *      When the asynchronous validators are triggered, each of the validators will run in parallel and the model
 *      value will only be updated once all validators have been fulfilled. As long as an asynchronous validator
 *      is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators
 *      will only run once all synchronous validators have passed.
 *
 * Please note that if $http is used then it is important that the server returns a success HTTP response code
 * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.
 *
 * ```js
 * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
 *   var value = modelValue || viewValue;
 *
 *   // Lookup user by username
 *   return $http.get('/api/users/' + value).
 *      then(function resolved() {
 *        //username exists, this means validation fails
 *        return $q.reject('exists');
 *      }, function rejected() {
 *        //username does not exist, therefore this validation passes
 *        return true;
 *      });
 * };
 * ```
 *
 * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
 *     view value has changed. It is called with no arguments, and its return value is ignored.
 *     This can be used in place of additional $watches against the model value.
 *
 * @property {Object} $error An object hash with all failing validator ids as keys.
 * @property {Object} $pending An object hash with all pending validator ids as keys.
 *
 * @property {boolean} $untouched True if control has not lost focus yet.
 * @property {boolean} $touched True if control has lost focus.
 * @property {boolean} $pristine True if user has not interacted with the control yet.
 * @property {boolean} $dirty True if user has already interacted with the control.
 * @property {boolean} $valid True if there is no error.
 * @property {boolean} $invalid True if at least one error on the control.
 * @property {string} $name The name attribute of the control.
 *
 * @description
 *
 * `NgModelController` provides API for the {@link ngModel `ngModel`} directive.
 * The controller contains services for data-binding, validation, CSS updates, and value formatting
 * and parsing. It purposefully does not contain any logic which deals with DOM rendering or
 * listening to DOM events.
 * Such DOM related logic should be provided by other directives which make use of
 * `NgModelController` for data-binding to control elements.
 * Angular provides this DOM logic for most {@link input `input`} elements.
 * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example
 * custom control example} that uses `ngModelController` to bind to `contenteditable` elements.
 *
 * @example
 * ### Custom Control Example
 * This example shows how to use `NgModelController` with a custom control to achieve
 * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
 * collaborate together to achieve the desired result.
 *
 * `contenteditable` is an HTML5 attribute, which tells the browser to let the element
 * contents be edited in place by the user.
 *
 * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
 * module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
 * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks
 * that content using the `$sce` service.
 *
 * <example name="NgModelController" module="customControl" deps="angular-sanitize.js">
    <file name="style.css">
      [contenteditable] {
        border: 1px solid black;
        background-color: white;
        min-height: 20px;
      }

      .ng-invalid {
        border: 1px solid red;
      }

    </file>
    <file name="script.js">
      angular.module('customControl', ['ngSanitize']).
        directive('contenteditable', ['$sce', function($sce) {
          return {
            restrict: 'A', // only activate on element attribute
            require: '?ngModel', // get a hold of NgModelController
            link: function(scope, element, attrs, ngModel) {
              if (!ngModel) return; // do nothing if no ng-model

              // Specify how UI should be updated
              ngModel.$render = function() {
                element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
              };

              // Listen for change events to enable binding
              element.on('blur keyup change', function() {
                scope.$evalAsync(read);
              });
              read(); // initialize

              // Write data to the model
              function read() {
                var html = element.html();
                // When we clear the content editable the browser leaves a <br> behind
                // If strip-br attribute is provided then we strip this out
                if ( attrs.stripBr && html == '<br>' ) {
                  html = '';
                }
                ngModel.$setViewValue(html);
              }
            }
          };
        }]);
    </file>
    <file name="index.html">
      <form name="myForm">
       <div contenteditable
            name="myWidget" ng-model="userContent"
            strip-br="true"
            required>Change me!</div>
        <span ng-show="myForm.myWidget.$error.required">Required!</span>
       <hr>
       <textarea ng-model="userContent"></textarea>
      </form>
    </file>
    <file name="protractor.js" type="protractor">
    it('should data-bind and become invalid', function() {
      if (browser.params.browser == 'safari' || browser.params.browser == 'firefox') {
        // SafariDriver can't handle contenteditable
        // and Firefox driver can't clear contenteditables very well
        return;
      }
      var contentEditable = element(by.css('[contenteditable]'));
      var content = 'Change me!';

      expect(contentEditable.getText()).toEqual(content);

      contentEditable.clear();
      contentEditable.sendKeys(protractor.Key.BACK_SPACE);
      expect(contentEditable.getText()).toEqual('');
      expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
    });
    </file>
 * </example>
 *
 *
 */
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$rootScope', '$q', '$interpolate',
    function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate) {
  this.$viewValue = Number.NaN;
  this.$modelValue = Number.NaN;
  this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
  this.$validators = {};
  this.$asyncValidators = {};
  this.$parsers = [];
  this.$formatters = [];
  this.$viewChangeListeners = [];
  this.$untouched = true;
  this.$touched = false;
  this.$pristine = true;
  this.$dirty = false;
  this.$valid = true;
  this.$invalid = false;
  this.$error = {}; // keep invalid keys here
  this.$$success = {}; // keep valid keys here
  this.$pending = undefined; // keep pending keys here
  this.$name = $interpolate($attr.name || '', false)($scope);


  var parsedNgModel = $parse($attr.ngModel),
      parsedNgModelAssign = parsedNgModel.assign,
      ngModelGet = parsedNgModel,
      ngModelSet = parsedNgModelAssign,
      pendingDebounce = null,
      parserValid,
      ctrl = this;

  this.$$setOptions = function(options) {
    ctrl.$options = options;
    if (options && options.getterSetter) {
      var invokeModelGetter = $parse($attr.ngModel + '()'),
          invokeModelSetter = $parse($attr.ngModel + '($$$p)');

      ngModelGet = function($scope) {
        var modelValue = parsedNgModel($scope);
        if (isFunction(modelValue)) {
          modelValue = invokeModelGetter($scope);
        }
        return modelValue;
      };
      ngModelSet = function($scope, newValue) {
        if (isFunction(parsedNgModel($scope))) {
          invokeModelSetter($scope, {$$$p: ctrl.$modelValue});
        } else {
          parsedNgModelAssign($scope, ctrl.$modelValue);
        }
      };
    } else if (!parsedNgModel.assign) {
      throw ngModelMinErr('nonassign', "Expression '{0}' is non-assignable. Element: {1}",
          $attr.ngModel, startingTag($element));
    }
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$render
   *
   * @description
   * Called when the view needs to be updated. It is expected that the user of the ng-model
   * directive will implement this method.
   *
   * The `$render()` method is invoked in the following situations:
   *
   * * `$rollbackViewValue()` is called.  If we are rolling back the view value to the last
   *   committed value then `$render()` is called to update the input control.
   * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and
   *   the `$viewValue` are different to last time.
   *
   * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
   * `$modelValue` and `$viewValue` are actually different to their previous value. If `$modelValue`
   * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
   * invoked if you only change a property on the objects.
   */
  this.$render = noop;

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$isEmpty
   *
   * @description
   * This is called when we need to determine if the value of an input is empty.
   *
   * For instance, the required directive does this to work out if the input has data or not.
   *
   * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.
   *
   * You can override this for input directives whose concept of being empty is different to the
   * default. The `checkboxInputType` directive does this because in its case a value of `false`
   * implies empty.
   *
   * @param {*} value The value of the input to check for emptiness.
   * @returns {boolean} True if `value` is "empty".
   */
  this.$isEmpty = function(value) {
    return isUndefined(value) || value === '' || value === null || value !== value;
  };

  var parentForm = $element.inheritedData('$formController') || nullFormCtrl,
      currentValidationRunId = 0;

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$setValidity
   *
   * @description
   * Change the validity state, and notify the form.
   *
   * This method can be called within $parsers/$formatters or a custom validation implementation.
   * However, in most cases it should be sufficient to use the `ngModel.$validators` and
   * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.
   *
   * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned
   *        to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`
   *        (for unfulfilled `$asyncValidators`), so that it is available for data-binding.
   *        The `validationErrorKey` should be in camelCase and will get converted into dash-case
   *        for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
   *        class and can be bound to as  `{{someForm.someControl.$error.myError}}` .
   * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),
   *                          or skipped (null). Pending is used for unfulfilled `$asyncValidators`.
   *                          Skipped is used by Angular when validators do not run because of parse errors and
   *                          when `$asyncValidators` do not run because any of the `$validators` failed.
   */
  addSetValidityMethod({
    ctrl: this,
    $element: $element,
    set: function(object, property) {
      object[property] = true;
    },
    unset: function(object, property) {
      delete object[property];
    },
    parentForm: parentForm,
    $animate: $animate
  });

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$setPristine
   *
   * @description
   * Sets the control to its pristine state.
   *
   * This method can be called to remove the `ng-dirty` class and set the control to its pristine
   * state (`ng-pristine` class). A model is considered to be pristine when the control
   * has not been changed from when first compiled.
   */
  this.$setPristine = function() {
    ctrl.$dirty = false;
    ctrl.$pristine = true;
    $animate.removeClass($element, DIRTY_CLASS);
    $animate.addClass($element, PRISTINE_CLASS);
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$setDirty
   *
   * @description
   * Sets the control to its dirty state.
   *
   * This method can be called to remove the `ng-pristine` class and set the control to its dirty
   * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed
   * from when first compiled.
   */
  this.$setDirty = function() {
    ctrl.$dirty = true;
    ctrl.$pristine = false;
    $animate.removeClass($element, PRISTINE_CLASS);
    $animate.addClass($element, DIRTY_CLASS);
    parentForm.$setDirty();
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$setUntouched
   *
   * @description
   * Sets the control to its untouched state.
   *
   * This method can be called to remove the `ng-touched` class and set the control to its
   * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched
   * by default, however this function can be used to restore that state if the model has
   * already been touched by the user.
   */
  this.$setUntouched = function() {
    ctrl.$touched = false;
    ctrl.$untouched = true;
    $animate.setClass($element, UNTOUCHED_CLASS, TOUCHED_CLASS);
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$setTouched
   *
   * @description
   * Sets the control to its touched state.
   *
   * This method can be called to remove the `ng-untouched` class and set the control to its
   * touched state (`ng-touched` class). A model is considered to be touched when the user has
   * first focused the control element and then shifted focus away from the control (blur event).
   */
  this.$setTouched = function() {
    ctrl.$touched = true;
    ctrl.$untouched = false;
    $animate.setClass($element, TOUCHED_CLASS, UNTOUCHED_CLASS);
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$rollbackViewValue
   *
   * @description
   * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`,
   * which may be caused by a pending debounced event or because the input is waiting for a some
   * future event.
   *
   * If you have an input that uses `ng-model-options` to set up debounced events or events such
   * as blur you can have a situation where there is a period when the `$viewValue`
   * is out of synch with the ngModel's `$modelValue`.
   *
   * In this case, you can run into difficulties if you try to update the ngModel's `$modelValue`
   * programmatically before these debounced/future events have resolved/occurred, because Angular's
   * dirty checking mechanism is not able to tell whether the model has actually changed or not.
   *
   * The `$rollbackViewValue()` method should be called before programmatically changing the model of an
   * input which may have such events pending. This is important in order to make sure that the
   * input field will be updated with the new model value and any pending operations are cancelled.
   *
   * <example name="ng-model-cancel-update" module="cancel-update-example">
   *   <file name="app.js">
   *     angular.module('cancel-update-example', [])
   *
   *     .controller('CancelUpdateController', ['$scope', function($scope) {
   *       $scope.resetWithCancel = function(e) {
   *         if (e.keyCode == 27) {
   *           $scope.myForm.myInput1.$rollbackViewValue();
   *           $scope.myValue = '';
   *         }
   *       };
   *       $scope.resetWithoutCancel = function(e) {
   *         if (e.keyCode == 27) {
   *           $scope.myValue = '';
   *         }
   *       };
   *     }]);
   *   </file>
   *   <file name="index.html">
   *     <div ng-controller="CancelUpdateController">
   *       <p>Try typing something in each input.  See that the model only updates when you
   *          blur off the input.
   *        </p>
   *        <p>Now see what happens if you start typing then press the Escape key</p>
   *
   *       <form name="myForm" ng-model-options="{ updateOn: 'blur' }">
   *         <p>With $rollbackViewValue()</p>
   *         <input name="myInput1" ng-model="myValue" ng-keydown="resetWithCancel($event)"><br/>
   *         myValue: "{{ myValue }}"
   *
   *         <p>Without $rollbackViewValue()</p>
   *         <input name="myInput2" ng-model="myValue" ng-keydown="resetWithoutCancel($event)"><br/>
   *         myValue: "{{ myValue }}"
   *       </form>
   *     </div>
   *   </file>
   * </example>
   */
  this.$rollbackViewValue = function() {
    $timeout.cancel(pendingDebounce);
    ctrl.$viewValue = ctrl.$$lastCommittedViewValue;
    ctrl.$render();
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$validate
   *
   * @description
   * Runs each of the registered validators (first synchronous validators and then
   * asynchronous validators).
   * If the validity changes to invalid, the model will be set to `undefined`,
   * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.
   * If the validity changes to valid, it will set the model to the last available valid
   * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.
   */
  this.$validate = function() {
    // ignore $validate before model is initialized
    if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
      return;
    }

    var viewValue = ctrl.$$lastCommittedViewValue;
    // Note: we use the $$rawModelValue as $modelValue might have been
    // set to undefined during a view -> model update that found validation
    // errors. We can't parse the view here, since that could change
    // the model although neither viewValue nor the model on the scope changed
    var modelValue = ctrl.$$rawModelValue;

    var prevValid = ctrl.$valid;
    var prevModelValue = ctrl.$modelValue;

    var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;

    ctrl.$$runValidators(modelValue, viewValue, function(allValid) {
      // If there was no change in validity, don't update the model
      // This prevents changing an invalid modelValue to undefined
      if (!allowInvalid && prevValid !== allValid) {
        // Note: Don't check ctrl.$valid here, as we could have
        // external validators (e.g. calculated on the server),
        // that just call $setValidity and need the model value
        // to calculate their validity.
        ctrl.$modelValue = allValid ? modelValue : undefined;

        if (ctrl.$modelValue !== prevModelValue) {
          ctrl.$$writeModelToScope();
        }
      }
    });

  };

  this.$$runValidators = function(modelValue, viewValue, doneCallback) {
    currentValidationRunId++;
    var localValidationRunId = currentValidationRunId;

    // check parser error
    if (!processParseErrors()) {
      validationDone(false);
      return;
    }
    if (!processSyncValidators()) {
      validationDone(false);
      return;
    }
    processAsyncValidators();

    function processParseErrors() {
      var errorKey = ctrl.$$parserName || 'parse';
      if (parserValid === undefined) {
        setValidity(errorKey, null);
      } else {
        if (!parserValid) {
          forEach(ctrl.$validators, function(v, name) {
            setValidity(name, null);
          });
          forEach(ctrl.$asyncValidators, function(v, name) {
            setValidity(name, null);
          });
        }
        // Set the parse error last, to prevent unsetting it, should a $validators key == parserName
        setValidity(errorKey, parserValid);
        return parserValid;
      }
      return true;
    }

    function processSyncValidators() {
      var syncValidatorsValid = true;
      forEach(ctrl.$validators, function(validator, name) {
        var result = validator(modelValue, viewValue);
        syncValidatorsValid = syncValidatorsValid && result;
        setValidity(name, result);
      });
      if (!syncValidatorsValid) {
        forEach(ctrl.$asyncValidators, function(v, name) {
          setValidity(name, null);
        });
        return false;
      }
      return true;
    }

    function processAsyncValidators() {
      var validatorPromises = [];
      var allValid = true;
      forEach(ctrl.$asyncValidators, function(validator, name) {
        var promise = validator(modelValue, viewValue);
        if (!isPromiseLike(promise)) {
          throw ngModelMinErr("$asyncValidators",
            "Expected asynchronous validator to return a promise but got '{0}' instead.", promise);
        }
        setValidity(name, undefined);
        validatorPromises.push(promise.then(function() {
          setValidity(name, true);
        }, function(error) {
          allValid = false;
          setValidity(name, false);
        }));
      });
      if (!validatorPromises.length) {
        validationDone(true);
      } else {
        $q.all(validatorPromises).then(function() {
          validationDone(allValid);
        }, noop);
      }
    }

    function setValidity(name, isValid) {
      if (localValidationRunId === currentValidationRunId) {
        ctrl.$setValidity(name, isValid);
      }
    }

    function validationDone(allValid) {
      if (localValidationRunId === currentValidationRunId) {

        doneCallback(allValid);
      }
    }
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$commitViewValue
   *
   * @description
   * Commit a pending update to the `$modelValue`.
   *
   * Updates may be pending by a debounced event or because the input is waiting for a some future
   * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`
   * usually handles calling this in response to input events.
   */
  this.$commitViewValue = function() {
    var viewValue = ctrl.$viewValue;

    $timeout.cancel(pendingDebounce);

    // If the view value has not changed then we should just exit, except in the case where there is
    // a native validator on the element. In this case the validation state may have changed even though
    // the viewValue has stayed empty.
    if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
      return;
    }
    ctrl.$$lastCommittedViewValue = viewValue;

    // change to dirty
    if (ctrl.$pristine) {
      this.$setDirty();
    }
    this.$$parseAndValidate();
  };

  this.$$parseAndValidate = function() {
    var viewValue = ctrl.$$lastCommittedViewValue;
    var modelValue = viewValue;
    parserValid = isUndefined(modelValue) ? undefined : true;

    if (parserValid) {
      for (var i = 0; i < ctrl.$parsers.length; i++) {
        modelValue = ctrl.$parsers[i](modelValue);
        if (isUndefined(modelValue)) {
          parserValid = false;
          break;
        }
      }
    }
    if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
      // ctrl.$modelValue has not been touched yet...
      ctrl.$modelValue = ngModelGet($scope);
    }
    var prevModelValue = ctrl.$modelValue;
    var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
    ctrl.$$rawModelValue = modelValue;

    if (allowInvalid) {
      ctrl.$modelValue = modelValue;
      writeToModelIfNeeded();
    }

    // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
    // This can happen if e.g. $setViewValue is called from inside a parser
    ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
      if (!allowInvalid) {
        // Note: Don't check ctrl.$valid here, as we could have
        // external validators (e.g. calculated on the server),
        // that just call $setValidity and need the model value
        // to calculate their validity.
        ctrl.$modelValue = allValid ? modelValue : undefined;
        writeToModelIfNeeded();
      }
    });

    function writeToModelIfNeeded() {
      if (ctrl.$modelValue !== prevModelValue) {
        ctrl.$$writeModelToScope();
      }
    }
  };

  this.$$writeModelToScope = function() {
    ngModelSet($scope, ctrl.$modelValue);
    forEach(ctrl.$viewChangeListeners, function(listener) {
      try {
        listener();
      } catch (e) {
        $exceptionHandler(e);
      }
    });
  };

  /**
   * @ngdoc method
   * @name ngModel.NgModelController#$setViewValue
   *
   * @description
   * Update the view value.
   *
   * This method should be called when an input directive want to change the view value; typically,
   * this is done from within a DOM event handler.
   *
   * For example {@link ng.directive:input input} calls it when the value of the input changes and
   * {@link ng.directive:select select} calls it when an option is selected.
   *
   * If the new `value` is an object (rather than a string or a number), we should make a copy of the
   * object before passing it to `$setViewValue`.  This is because `ngModel` does not perform a deep
   * watch of objects, it only looks for a change of identity. If you only change the property of
   * the object then ngModel will not realise that the object has changed and will not invoke the
   * `$parsers` and `$validators` pipelines.
   *
   * For this reason, you should not change properties of the copy once it has been passed to
   * `$setViewValue`. Otherwise you may cause the model value on the scope to change incorrectly.
   *
   * When this method is called, the new `value` will be staged for committing through the `$parsers`
   * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged
   * value sent directly for processing, finally to be applied to `$modelValue` and then the
   * **expression** specified in the `ng-model` attribute.
   *
   * Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
   *
   * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`
   * and the `default` trigger is not listed, all those actions will remain pending until one of the
   * `updateOn` events is triggered on the DOM element.
   * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}
   * directive is used with a custom debounce for this particular event.
   *
   * Note that calling this function does not trigger a `$digest`.
   *
   * @param {string} value Value from the view.
   * @param {string} trigger Event that triggered the update.
   */
  this.$setViewValue = function(value, trigger) {
    ctrl.$viewValue = value;
    if (!ctrl.$options || ctrl.$options.updateOnDefault) {
      ctrl.$$debounceViewValueCommit(trigger);
    }
  };

  this.$$debounceViewValueCommit = function(trigger) {
    var debounceDelay = 0,
        options = ctrl.$options,
        debounce;

    if (options && isDefined(options.debounce)) {
      debounce = options.debounce;
      if (isNumber(debounce)) {
        debounceDelay = debounce;
      } else if (isNumber(debounce[trigger])) {
        debounceDelay = debounce[trigger];
      } else if (isNumber(debounce['default'])) {
        debounceDelay = debounce['default'];
      }
    }

    $timeout.cancel(pendingDebounce);
    if (debounceDelay) {
      pendingDebounce = $timeout(function() {
        ctrl.$commitViewValue();
      }, debounceDelay);
    } else if ($rootScope.$$phase) {
      ctrl.$commitViewValue();
    } else {
      $scope.$apply(function() {
        ctrl.$commitViewValue();
      });
    }
  };

  // model -> value
  // Note: we cannot use a normal scope.$watch as we want to detect the following:
  // 1. scope value is 'a'
  // 2. user enters 'b'
  // 3. ng-change kicks in and reverts scope value to 'a'
  //    -> scope value did not change since the last digest as
  //       ng-change executes in apply phase
  // 4. view should be changed back to 'a'
  $scope.$watch(function ngModelWatch() {
    var modelValue = ngModelGet($scope);

    // if scope model value and ngModel value are out of sync
    // TODO(perf): why not move this to the action fn?
    if (modelValue !== ctrl.$modelValue &&
       // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator
       (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)
    ) {
      ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
      parserValid = undefined;

      var formatters = ctrl.$formatters,
          idx = formatters.length;

      var viewValue = modelValue;
      while (idx--) {
        viewValue = formatters[idx](viewValue);
      }
      if (ctrl.$viewValue !== viewValue) {
        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
        ctrl.$render();

        ctrl.$$runValidators(modelValue, viewValue, noop);
      }
    }

    return modelValue;
  });
}];


/**
 * @ngdoc directive
 * @name ngModel
 *
 * @element input
 * @priority 1
 *
 * @description
 * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a
 * property on the scope using {@link ngModel.NgModelController NgModelController},
 * which is created and exposed by this directive.
 *
 * `ngModel` is responsible for:
 *
 * - Binding the view into the model, which other directives such as `input`, `textarea` or `select`
 *   require.
 * - Providing validation behavior (i.e. required, number, email, url).
 * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
 * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`, `ng-untouched`) including animations.
 * - Registering the control with its parent {@link ng.directive:form form}.
 *
 * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
 * current scope. If the property doesn't already exist on this scope, it will be created
 * implicitly and added to the scope.
 *
 * For best practices on using `ngModel`, see:
 *
 *  - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)
 *
 * For basic examples, how to use `ngModel`, see:
 *
 *  - {@link ng.directive:input input}
 *    - {@link input[text] text}
 *    - {@link input[checkbox] checkbox}
 *    - {@link input[radio] radio}
 *    - {@link input[number] number}
 *    - {@link input[email] email}
 *    - {@link input[url] url}
 *    - {@link input[date] date}
 *    - {@link input[datetime-local] datetime-local}
 *    - {@link input[time] time}
 *    - {@link input[month] month}
 *    - {@link input[week] week}
 *  - {@link ng.directive:select select}
 *  - {@link ng.directive:textarea textarea}
 *
 * # CSS classes
 * The following CSS classes are added and removed on the associated input/select/textarea element
 * depending on the validity of the model.
 *
 *  - `ng-valid`: the model is valid
 *  - `ng-invalid`: the model is invalid
 *  - `ng-valid-[key]`: for each valid key added by `$setValidity`
 *  - `ng-invalid-[key]`: for each invalid key added by `$setValidity`
 *  - `ng-pristine`: the control hasn't been interacted with yet
 *  - `ng-dirty`: the control has been interacted with
 *  - `ng-touched`: the control has been blurred
 *  - `ng-untouched`: the control hasn't been blurred
 *  - `ng-pending`: any `$asyncValidators` are unfulfilled
 *
 * Keep in mind that ngAnimate can detect each of these classes when added and removed.
 *
 * ## Animation Hooks
 *
 * Animations within models are triggered when any of the associated CSS classes are added and removed
 * on the input element which is attached to the model. These classes are: `.ng-pristine`, `.ng-dirty`,
 * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself.
 * The animations that are triggered within ngModel are similar to how they work in ngClass and
 * animations can be hooked into using CSS transitions, keyframes as well as JS animations.
 *
 * The following example shows a simple way to utilize CSS transitions to style an input element
 * that has been rendered as invalid after it has been validated:
 *
 * <pre>
 * //be sure to include ngAnimate as a module to hook into more
 * //advanced animations
 * .my-input {
 *   transition:0.5s linear all;
 *   background: white;
 * }
 * .my-input.ng-invalid {
 *   background: red;
 *   color:white;
 * }
 * </pre>
 *
 * @example
 * <example deps="angular-animate.js" animations="true" fixBase="true" module="inputExample">
     <file name="index.html">
       <script>
        angular.module('inputExample', [])
          .controller('ExampleController', ['$scope', function($scope) {
            $scope.val = '1';
          }]);
       </script>
       <style>
         .my-input {
           -webkit-transition:all linear 0.5s;
           transition:all linear 0.5s;
           background: transparent;
         }
         .my-input.ng-invalid {
           color:white;
           background: red;
         }
       </style>
       Update input to see transitions when valid/invalid.
       Integer is a valid value.
       <form name="testForm" ng-controller="ExampleController">
         <input ng-model="val" ng-pattern="/^\d+$/" name="anim" class="my-input" />
       </form>
     </file>
 * </example>
 *
 * ## Binding to a getter/setter
 *
 * Sometimes it's helpful to bind `ngModel` to a getter/setter function.  A getter/setter is a
 * function that returns a representation of the model when called with zero arguments, and sets
 * the internal state of a model when called with an argument. It's sometimes useful to use this
 * for models that have an internal representation that's different than what the model exposes
 * to the view.
 *
 * <div class="alert alert-success">
 * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more
 * frequently than other parts of your code.
 * </div>
 *
 * You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that
 * has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to
 * a `<form>`, which will enable this behavior for all `<input>`s within it. See
 * {@link ng.directive:ngModelOptions `ngModelOptions`} for more.
 *
 * The following example shows how to use `ngModel` with a getter/setter:
 *
 * @example
 * <example name="ngModel-getter-setter" module="getterSetterExample">
     <file name="index.html">
       <div ng-controller="ExampleController">
         <form name="userForm">
           Name:
           <input type="text" name="userName"
                  ng-model="user.name"
                  ng-model-options="{ getterSetter: true }" />
         </form>
         <pre>user.name = <span ng-bind="user.name()"></span></pre>
       </div>
     </file>
     <file name="app.js">
       angular.module('getterSetterExample', [])
         .controller('ExampleController', ['$scope', function($scope) {
           var _name = 'Brian';
           $scope.user = {
             name: function(newName) {
              // Note that newName can be undefined for two reasons:
              // 1. Because it is called as a getter and thus called with no arguments
              // 2. Because the property should actually be set to undefined. This happens e.g. if the
              //    input is invalid
              return arguments.length ? (_name = newName) : _name;
             }
           };
         }]);
     </file>
 * </example>
 */
var ngModelDirective = ['$rootScope', function($rootScope) {
  return {
    restrict: 'A',
    require: ['ngModel', '^?form', '^?ngModelOptions'],
    controller: NgModelController,
    // Prelink needs to run before any input directive
    // so that we can set the NgModelOptions in NgModelController
    // before anyone else uses it.
    priority: 1,
    compile: function ngModelCompile(element) {
      // Setup initial state of the control
      element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);

      return {
        pre: function ngModelPreLink(scope, element, attr, ctrls) {
          var modelCtrl = ctrls[0],
              formCtrl = ctrls[1] || nullFormCtrl;

          modelCtrl.$$setOptions(ctrls[2] && ctrls[2].$options);

          // notify others, especially parent forms
          formCtrl.$addControl(modelCtrl);

          attr.$observe('name', function(newValue) {
            if (modelCtrl.$name !== newValue) {
              formCtrl.$$renameControl(modelCtrl, newValue);
            }
          });

          scope.$on('$destroy', function() {
            formCtrl.$removeControl(modelCtrl);
          });
        },
        post: function ngModelPostLink(scope, element, attr, ctrls) {
          var modelCtrl = ctrls[0];
          if (modelCtrl.$options && modelCtrl.$options.updateOn) {
            element.on(modelCtrl.$options.updateOn, function(ev) {
              modelCtrl.$$debounceViewValueCommit(ev && ev.type);
            });
          }

          element.on('blur', function(ev) {
            if (modelCtrl.$touched) return;

            if ($rootScope.$$phase) {
              scope.$evalAsync(modelCtrl.$setTouched);
            } else {
              scope.$apply(modelCtrl.$setTouched);
            }
          });
        }
      };
    }
  };
}];

var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;

/**
 * @ngdoc directive
 * @name ngModelOptions
 *
 * @description
 * Allows tuning how model updates are done. Using `ngModelOptions` you can specify a custom list of
 * events that will trigger a model update and/or a debouncing delay so that the actual update only
 * takes place when a timer expires; this timer will be reset after another change takes place.
 *
 * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might
 * be different than the value in the actual model. This means that if you update the model you
 * should also invoke {@link ngModel.NgModelController `$rollbackViewValue`} on the relevant input field in
 * order to make sure it is synchronized with the model and that any debounced action is canceled.
 *
 * The easiest way to reference the control's {@link ngModel.NgModelController `$rollbackViewValue`}
 * method is by making sure the input is placed inside a form that has a `name` attribute. This is
 * important because `form` controllers are published to the related scope under the name in their
 * `name` attribute.
 *
 * Any pending changes will take place immediately when an enclosing form is submitted via the
 * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
 * to have access to the updated model.
 *
 * `ngModelOptions` has an effect on the element it's declared on and its descendants.
 *
 * @param {Object} ngModelOptions options to apply to the current model. Valid keys are:
 *   - `updateOn`: string specifying which event should the input be bound to. You can set several
 *     events using an space delimited list. There is a special event called `default` that
 *     matches the default events belonging of the control.
 *   - `debounce`: integer value which contains the debounce model update value in milliseconds. A
 *     value of 0 triggers an immediate update. If an object is supplied instead, you can specify a
 *     custom value for each event. For example:
 *     `ng-model-options="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }"`
 *   - `allowInvalid`: boolean value which indicates that the model can be set with values that did
 *     not validate correctly instead of the default behavior of setting the model to undefined.
 *   - `getterSetter`: boolean value which determines whether or not to treat functions bound to
       `ngModel` as getters/setters.
 *   - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for
 *     `<input type="date">`, `<input type="time">`, ... . Right now, the only supported value is `'UTC'`,
 *     otherwise the default timezone of the browser will be used.
 *
 * @example

  The following example shows how to override immediate updates. Changes on the inputs within the
  form will update the model only when the control loses focus (blur event). If `escape` key is
  pressed while the input field is focused, the value is reset to the value in the current model.

  <example name="ngModelOptions-directive-blur" module="optionsExample">
    <file name="index.html">
      <div ng-controller="ExampleController">
        <form name="userForm">
          Name:
          <input type="text" name="userName"
                 ng-model="user.name"
                 ng-model-options="{ updateOn: 'blur' }"
                 ng-keyup="cancel($event)" /><br />

          Other data:
          <input type="text" ng-model="user.data" /><br />
        </form>
        <pre>user.name = <span ng-bind="user.name"></span></pre>
      </div>
    </file>
    <file name="app.js">
      angular.module('optionsExample', [])
        .controller('ExampleController', ['$scope', function($scope) {
          $scope.user = { name: 'say', data: '' };

          $scope.cancel = function(e) {
            if (e.keyCode == 27) {
              $scope.userForm.userName.$rollbackViewValue();
            }
          };
        }]);
    </file>
    <file name="protractor.js" type="protractor">
      var model = element(by.binding('user.name'));
      var input = element(by.model('user.name'));
      var other = element(by.model('user.data'));

      it('should allow custom events', function() {
        input.sendKeys(' hello');
        input.click();
        expect(model.getText()).toEqual('say');
        other.click();
        expect(model.getText()).toEqual('say hello');
      });

      it('should $rollbackViewValue when model changes', function() {
        input.sendKeys(' hello');
        expect(input.getAttribute('value')).toEqual('say hello');
        input.sendKeys(protractor.Key.ESCAPE);
        expect(input.getAttribute('value')).toEqual('say');
        other.click();
        expect(model.getText()).toEqual('say');
      });
    </file>
  </example>

  This one shows how to debounce model changes. Model will be updated only 1 sec after last change.
  If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.

  <example name="ngModelOptions-directive-debounce" module="optionsExample">
    <file name="index.html">
      <div ng-controller="ExampleController">
        <form name="userForm">
          Name:
          <input type="text" name="userName"
                 ng-model="user.name"
                 ng-model-options="{ debounce: 1000 }" />
          <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button><br />
        </form>
        <pre>user.name = <span ng-bind="user.name"></span></pre>
      </div>
    </file>
    <file name="app.js">
      angular.module('optionsExample', [])
        .controller('ExampleController', ['$scope', function($scope) {
          $scope.user = { name: 'say' };
        }]);
    </file>
  </example>

  This one shows how to bind to getter/setters:

  <example name="ngModelOptions-directive-getter-setter" module="getterSetterExample">
    <file name="index.html">
      <div ng-controller="ExampleController">
        <form name="userForm">
          Name:
          <input type="text" name="userName"
                 ng-model="user.name"
                 ng-model-options="{ getterSetter: true }" />
        </form>
        <pre>user.name = <span ng-bind="user.name()"></span></pre>
      </div>
    </file>
    <file name="app.js">
      angular.module('getterSetterExample', [])
        .controller('ExampleController', ['$scope', function($scope) {
          var _name = 'Brian';
          $scope.user = {
            name: function(newName) {
              // Note that newName can be undefined for two reasons:
              // 1. Because it is called as a getter and thus called with no arguments
              // 2. Because the property should actually be set to undefined. This happens e.g. if the
              //    input is invalid
              return arguments.length ? (_name = newName) : _name;
            }
          };
        }]);
    </file>
  </example>
 */
var ngModelOptionsDirective = function() {
  return {
    restrict: 'A',
    controller: ['$scope', '$attrs', function($scope, $attrs) {
      var that = this;
      this.$options = $scope.$eval($attrs.ngModelOptions);
      // Allow adding/overriding bound events
      if (this.$options.updateOn !== undefined) {
        this.$options.updateOnDefault = false;
        // extract "default" pseudo-event from list of events that can trigger a model update
        this.$options.updateOn = trim(this.$options.updateOn.replace(DEFAULT_REGEXP, function() {
          that.$options.updateOnDefault = true;
          return ' ';
        }));
      } else {
        this.$options.updateOnDefault = true;
      }
    }]
  };
};



// helper methods
function addSetValidityMethod(context) {
  var ctrl = context.ctrl,
      $element = context.$element,
      classCache = {},
      set = context.set,
      unset = context.unset,
      parentForm = context.parentForm,
      $animate = context.$animate;

  classCache[INVALID_CLASS] = !(classCache[VALID_CLASS] = $element.hasClass(VALID_CLASS));

  ctrl.$setValidity = setValidity;

  function setValidity(validationErrorKey, state, controller) {
    if (state === undefined) {
      createAndSet('$pending', validationErrorKey, controller);
    } else {
      unsetAndCleanup('$pending', validationErrorKey, controller);
    }
    if (!isBoolean(state)) {
      unset(ctrl.$error, validationErrorKey, controller);
      unset(ctrl.$$success, validationErrorKey, controller);
    } else {
      if (state) {
        unset(ctrl.$error, validationErrorKey, controller);
        set(ctrl.$$success, validationErrorKey, controller);
      } else {
        set(ctrl.$error, validationErrorKey, controller);
        unset(ctrl.$$success, validationErrorKey, controller);
      }
    }
    if (ctrl.$pending) {
      cachedToggleClass(PENDING_CLASS, true);
      ctrl.$valid = ctrl.$invalid = undefined;
      toggleValidationCss('', null);
    } else {
      cachedToggleClass(PENDING_CLASS, false);
      ctrl.$valid = isObjectEmpty(ctrl.$error);
      ctrl.$invalid = !ctrl.$valid;
      toggleValidationCss('', ctrl.$valid);
    }

    // re-read the state as the set/unset methods could have
    // combined state in ctrl.$error[validationError] (used for forms),
    // where setting/unsetting only increments/decrements the value,
    // and does not replace it.
    var combinedState;
    if (ctrl.$pending && ctrl.$pending[validationErrorKey]) {
      combinedState = undefined;
    } else if (ctrl.$error[validationErrorKey]) {
      combinedState = false;
    } else if (ctrl.$$success[validationErrorKey]) {
      combinedState = true;
    } else {
      combinedState = null;
    }

    toggleValidationCss(validationErrorKey, combinedState);
    parentForm.$setValidity(validationErrorKey, combinedState, ctrl);
  }

  function createAndSet(name, value, controller) {
    if (!ctrl[name]) {
      ctrl[name] = {};
    }
    set(ctrl[name], value, controller);
  }

  function unsetAndCleanup(name, value, controller) {
    if (ctrl[name]) {
      unset(ctrl[name], value, controller);
    }
    if (isObjectEmpty(ctrl[name])) {
      ctrl[name] = undefined;
    }
  }

  function cachedToggleClass(className, switchValue) {
    if (switchValue && !classCache[className]) {
      $animate.addClass($element, className);
      classCache[className] = true;
    } else if (!switchValue && classCache[className]) {
      $animate.removeClass($element, className);
      classCache[className] = false;
    }
  }

  function toggleValidationCss(validationErrorKey, isValid) {
    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';

    cachedToggleClass(VALID_CLASS + validationErrorKey, isValid === true);
    cachedToggleClass(INVALID_CLASS + validationErrorKey, isValid === false);
  }
}

function isObjectEmpty(obj) {
  if (obj) {
    for (var prop in obj) {
      return false;
    }
  }
  return true;
}

/**
 * @ngdoc directive
 * @name ngNonBindable
 * @restrict AC
 * @priority 1000
 *
 * @description
 * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current
 * DOM element. This is useful if the element contains what appears to be Angular directives and
 * bindings but which should be ignored by Angular. This could be the case if you have a site that
 * displays snippets of code, for instance.
 *
 * @element ANY
 *
 * @example
 * In this example there are two locations where a simple interpolation binding (`{{}}`) is present,
 * but the one wrapped in `ngNonBindable` is left alone.
 *
 * @example
    <example>
      <file name="index.html">
        <div>Normal: {{1 + 2}}</div>
        <div ng-non-bindable>Ignored: {{1 + 2}}</div>
      </file>
      <file name="protractor.js" type="protractor">
       it('should check ng-non-bindable', function() {
         expect(element(by.binding('1 + 2')).getText()).toContain('3');
         expect(element.all(by.css('div')).last().getText()).toMatch(/1 \+ 2/);
       });
      </file>
    </example>
 */
var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });

/**
 * @ngdoc directive
 * @name ngPluralize
 * @restrict EA
 *
 * @description
 * `ngPluralize` is a directive that displays messages according to en-US localization rules.
 * These rules are bundled with angular.js, but can be overridden
 * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
 * by specifying the mappings between
 * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)
 * and the strings to be displayed.
 *
 * # Plural categories and explicit number rules
 * There are two
 * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)
 * in Angular's default en-US locale: "one" and "other".
 *
 * While a plural category may match many numbers (for example, in en-US locale, "other" can match
 * any number that is not 1), an explicit number rule can only match one number. For example, the
 * explicit number rule for "3" matches the number 3. There are examples of plural categories
 * and explicit number rules throughout the rest of this documentation.
 *
 * # Configuring ngPluralize
 * You configure ngPluralize by providing 2 attributes: `count` and `when`.
 * You can also provide an optional attribute, `offset`.
 *
 * The value of the `count` attribute can be either a string or an {@link guide/expression
 * Angular expression}; these are evaluated on the current scope for its bound value.
 *
 * The `when` attribute specifies the mappings between plural categories and the actual
 * string to be displayed. The value of the attribute should be a JSON object.
 *
 * The following example shows how to configure ngPluralize:
 *
 * ```html
 * <ng-pluralize count="personCount"
                 when="{'0': 'Nobody is viewing.',
 *                      'one': '1 person is viewing.',
 *                      'other': '{} people are viewing.'}">
 * </ng-pluralize>
 *```
 *
 * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not
 * specify this rule, 0 would be matched to the "other" category and "0 people are viewing"
 * would be shown instead of "Nobody is viewing". You can specify an explicit number rule for
 * other numbers, for example 12, so that instead of showing "12 people are viewing", you can
 * show "a dozen people are viewing".
 *
 * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
 * into pluralized strings. In the previous example, Angular will replace `{}` with
 * <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
 * for <span ng-non-bindable>{{numberExpression}}</span>.
 *
 * # Configuring ngPluralize with offset
 * The `offset` attribute allows further customization of pluralized text, which can result in
 * a better user experience. For example, instead of the message "4 people are viewing this document",
 * you might display "John, Kate and 2 others are viewing this document".
 * The offset attribute allows you to offset a number by any desired value.
 * Let's take a look at an example:
 *
 * ```html
 * <ng-pluralize count="personCount" offset=2
 *               when="{'0': 'Nobody is viewing.',
 *                      '1': '{{person1}} is viewing.',
 *                      '2': '{{person1}} and {{person2}} are viewing.',
 *                      'one': '{{person1}}, {{person2}} and one other person are viewing.',
 *                      'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
 * </ng-pluralize>
 * ```
 *
 * Notice that we are still using two plural categories(one, other), but we added
 * three explicit number rules 0, 1 and 2.
 * When one person, perhaps John, views the document, "John is viewing" will be shown.
 * When three people view the document, no explicit number rule is found, so
 * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
 * In this case, plural category 'one' is matched and "John, Mary and one other person are viewing"
 * is shown.
 *
 * Note that when you specify offsets, you must provide explicit number rules for
 * numbers from 0 up to and including the offset. If you use an offset of 3, for example,
 * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for
 * plural categories "one" and "other".
 *
 * @param {string|expression} count The variable to be bound to.
 * @param {string} when The mapping between plural category to its corresponding strings.
 * @param {number=} offset Offset to deduct from the total number.
 *
 * @example
    <example module="pluralizeExample">
      <file name="index.html">
        <script>
          angular.module('pluralizeExample', [])
            .controller('ExampleController', ['$scope', function($scope) {
              $scope.person1 = 'Igor';
              $scope.person2 = 'Misko';
              $scope.personCount = 1;
            }]);
        </script>
        <div ng-controller="ExampleController">
          Person 1:<input type="text" ng-model="person1" value="Igor" /><br/>
          Person 2:<input type="text" ng-model="person2" value="Misko" /><br/>
          Number of People:<input type="text" ng-model="personCount" value="1" /><br/>

          <!--- Example with simple pluralization rules for en locale --->
          Without Offset:
          <ng-pluralize count="personCount"
                        when="{'0': 'Nobody is viewing.',
                               'one': '1 person is viewing.',
                               'other': '{} people are viewing.'}">
          </ng-pluralize><br>

          <!--- Example with offset --->
          With Offset(2):
          <ng-pluralize count="personCount" offset=2
                        when="{'0': 'Nobody is viewing.',
                               '1': '{{person1}} is viewing.',
                               '2': '{{person1}} and {{person2}} are viewing.',
                               'one': '{{person1}}, {{person2}} and one other person are viewing.',
                               'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
          </ng-pluralize>
        </div>
      </file>
      <file name="protractor.js" type="protractor">
        it('should show correct pluralized string', function() {
          var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
          var withOffset = element.all(by.css('ng-pluralize')).get(1);
          var countInput = element(by.model('personCount'));

          expect(withoutOffset.getText()).toEqual('1 person is viewing.');
          expect(withOffset.getText()).toEqual('Igor is viewing.');

          countInput.clear();
          countInput.sendKeys('0');

          expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
          expect(withOffset.getText()).toEqual('Nobody is viewing.');

          countInput.clear();
          countInput.sendKeys('2');

          expect(withoutOffset.getText()).toEqual('2 people are viewing.');
          expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');

          countInput.clear();
          countInput.sendKeys('3');

          expect(withoutOffset.getText()).toEqual('3 people are viewing.');
          expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');

          countInput.clear();
          countInput.sendKeys('4');

          expect(withoutOffset.getText()).toEqual('4 people are viewing.');
          expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
        });
        it('should show data-bound names', function() {
          var withOffset = element.all(by.css('ng-pluralize')).get(1);
          var personCount = element(by.model('personCount'));
          var person1 = element(by.model('person1'));
          var person2 = element(by.model('person2'));
          personCount.clear();
          personCount.sendKeys('4');
          person1.clear();
          person1.sendKeys('Di');
          person2.clear();
          person2.sendKeys('Vojta');
          expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
        });
      </file>
    </example>
 */
var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
  var BRACE = /{}/g,
      IS_WHEN = /^when(Minus)?(.+)$/;

  return {
    restrict: 'EA',
    link: function(scope, element, attr) {
      var numberExp = attr.count,
          whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs
          offset = attr.offset || 0,
          whens = scope.$eval(whenExp) || {},
          whensExpFns = {},
          startSymbol = $interpolate.startSymbol(),
          endSymbol = $interpolate.endSymbol(),
          braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
          watchRemover = angular.noop,
          lastCount;

      forEach(attr, function(expression, attributeName) {
        var tmpMatch = IS_WHEN.exec(attributeName);
        if (tmpMatch) {
          var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
          whens[whenKey] = element.attr(attr.$attr[attributeName]);
        }
      });
      forEach(whens, function(expression, key) {
        whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));

      });

      scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
        var count = parseFloat(newVal);
        var countIsNaN = isNaN(count);

        if (!countIsNaN && !(count in whens)) {
          // If an explicit number rule such as 1, 2, 3... is defined, just use it.
          // Otherwise, check it against pluralization rules in $locale service.
          count = $locale.pluralCat(count - offset);
        }

        // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
        // In JS `NaN !== NaN`, so we have to exlicitly check.
        if ((count !== lastCount) && !(countIsNaN && isNaN(lastCount))) {
          watchRemover();
          watchRemover = scope.$watch(whensExpFns[count], updateElementText);
          lastCount = count;
        }
      });

      function updateElementText(newText) {
        element.text(newText || '');
      }
    }
  };
}];

/**
 * @ngdoc directive
 * @name ngRepeat
 *
 * @description
 * The `ngRepeat` directive instantiates a template once per item from a collection. Each template
 * instance gets its own scope, where the given loop variable is set to the current collection item,
 * and `$index` is set to the item index or key.
 *
 * Special properties are exposed on the local scope of each template instance, including:
 *
 * | Variable  | Type            | Details                                                                     |
 * |-----------|-----------------|-----------------------------------------------------------------------------|
 * | `$index`  | {@type number}  | iterator offset of the repeated element (0..length-1)                       |
 * | `$first`  | {@type boolean} | true if the repeated element is first in the iterator.                      |
 * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |
 * | `$last`   | {@type boolean} | true if the repeated element is last in the iterator.                       |
 * | `$even`   | {@type boolean} | true if the iterator position `$index` is even (otherwise false).           |
 * | `$odd`    | {@type boolean} | true if the iterator position `$index` is odd (otherwise false).            |
 *
 * Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.
 * This may be useful when, for instance, nesting ngRepeats.
 *
 * # Iterating over object properties
 *
 * It is possible to get `ngRepeat` to iterate over the properties of an object using the following
 * syntax:
 *
 * ```js
 * <div ng-repeat="(key, value) in myObj"> ... </div>
 * ```
 *
 * You need to be aware that the JavaScript specification does not define what order
 * it will return the keys for an object. In order to have a guaranteed deterministic order
 * for the keys, Angular versions up to and including 1.3 **sort the keys alphabetically**.
 *
 * If this is not desired, the recommended workaround is to convert your object into an array
 * that is sorted into the order that you prefer before providing it to `ngRepeat`.  You could
 * do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
 * or implement a `$watch` on the object yourself.
 *
 * In version 1.4 we will remove the sorting, since it seems that browsers generally follow the
 * strategy of providing keys in the order in which they were defined, although there are exceptions
 * when keys are deleted and reinstated.
 *
 *
 * # Tracking and Duplicates
 *
 * When the contents of the collection change, `ngRepeat` makes the corresponding changes to the DOM:
 *
 * * When an item is added, a new instance of the template is added to the DOM.
 * * When an item is removed, its template instance is removed from the DOM.
 * * When items are reordered, their respective templates are reordered in the DOM.
 *
 * By default, `ngRepeat` does not allow duplicate items in arrays. This is because when
 * there are duplicates, it is not possible to maintain a one-to-one mapping between collection
 * items and DOM elements.
 *
 * If you do need to repeat duplicate items, you can substitute the default tracking behavior
 * with your own using the `track by` expression.
 *
 * For example, you may track items by the index of each item in the collection, using the
 * special scope property `$index`:
 * ```html
 *    <div ng-repeat="n in [42, 42, 43, 43] track by $index">
 *      {{n}}
 *    </div>
 * ```
 *
 * You may use arbitrary expressions in `track by`, including references to custom functions
 * on the scope:
 * ```html
 *    <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
 *      {{n}}
 *    </div>
 * ```
 *
 * If you are working with objects that have an identifier property, you can track
 * by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
 * will not have to rebuild the DOM elements for items it has already rendered, even if the
 * JavaScript objects in the collection have been substituted for new ones:
 * ```html
 *    <div ng-repeat="model in collection track by model.id">
 *      {{model.name}}
 *    </div>
 * ```
 *
 * When no `track by` expression is provided, it is equivalent to tracking by the built-in
 * `$id` function, which tracks items by their identity:
 * ```html
 *    <div ng-repeat="obj in collection track by $id(obj)">
 *      {{obj.prop}}
 *    </div>
 * ```
 *
 * # Special repeat start and end points
 * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
 * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
 * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)
 * up to and including the ending HTML tag where **ng-repeat-end** is placed.
 *
 * The example below makes use of this feature:
 * ```html
 *   <header ng-repeat-start="item in items">
 *     Header {{ item }}
 *   </header>
 *   <div class="body">
 *     Body {{ item }}
 *   </div>
 *   <footer ng-repeat-end>
 *     Footer {{ item }}
 *   </footer>
 * ```
 *
 * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:
 * ```html
 *   <header>
 *     Header A
 *   </header>
 *   <div class="body">
 *     Body A
 *   </div>
 *   <footer>
 *     Footer A
 *   </footer>
 *   <header>
 *     Header B
 *   </header>
 *   <div class="body">
 *     Body B
 *   </div>
 *   <footer>
 *     Footer B
 *   </footer>
 * ```
 *
 * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such
 * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).
 *
 * @animations
 * **.enter** - when a new item is added to the list or when an item is revealed after a filter
 *
 * **.leave** - when an item is removed from the list or when an item is filtered out
 *
 * **.move** - when an adjacent item is filtered out causing a reorder or when the item contents are reordered
 *
 * @element ANY
 * @scope
 * @priority 1000
 * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. These
 *   formats are currently supported:
 *
 *   * `variable in expression` – where variable is the user defined loop variable and `expression`
 *     is a scope expression giving the collection to enumerate.
 *
 *     For example: `album in artist.albums`.
 *
 *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
 *     and `expression` is the scope expression giving the collection to enumerate.
 *
 *     For example: `(name, age) in {'adam':10, 'amalie':12}`.
 *
 *   * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression
 *     which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
 *     is specified, ng-repeat associates elements by identity. It is an error to have
 *     more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
 *     mapped to the same DOM element, which is not possible.)  If filters are used in the expression, they should be
 *     applied before the tracking expression.
 *
 *     For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
 *     will be associated by item identity in the array.
 *
 *     For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
 *     `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
 *     with the corresponding item in the array by identity. Moving the same object in array would move the DOM
 *     element in the same way in the DOM.
 *
 *     For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
 *     case the object identity does not matter. Two objects are considered equivalent as long as their `id`
 *     property is same.
 *
 *     For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter
 *     to items in conjunction with a tracking expression.
 *
 *   * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the
 *     intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message
 *     when a filter is active on the repeater, but the filtered result set is empty.
 *
 *     For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
 *     the items have been processed through the filter.
 *
 * @example
 * This example initializes the scope to a list of names and
 * then uses `ngRepeat` to display every person:
  <example module="ngAnimate" deps="angular-animate.js" animations="true">
    <file name="index.html">
      <div ng-init="friends = [
        {name:'John', age:25, gender:'boy'},
        {name:'Jessie', age:30, gender:'girl'},
        {name:'Johanna', age:28, gender:'girl'},
        {name:'Joy', age:15, gender:'girl'},
        {name:'Mary', age:28, gender:'girl'},
        {name:'Peter', age:95, gender:'boy'},
        {name:'Sebastian', age:50, gender:'boy'},
        {name:'Erika', age:27, gender:'girl'},
        {name:'Patrick', age:40, gender:'boy'},
        {name:'Samantha', age:60, gender:'girl'}
      ]">
        I have {{friends.length}} friends. They are:
        <input type="search" ng-model="q" placeholder="filter friends..." />
        <ul class="example-animate-container">
          <li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
          </li>
          <li class="animate-repeat" ng-if="results.length == 0">
            <strong>No results found...</strong>
          </li>
        </ul>
      </div>
    </file>
    <file name="animations.css">
      .example-animate-container {
        background:white;
        border:1px solid black;
        list-style:none;
        margin:0;
        padding:0 10px;
      }

      .animate-repeat {
        line-height:40px;
        list-style:none;
        box-sizing:border-box;
      }

      .animate-repeat.ng-move,
      .animate-repeat.ng-enter,
      .animate-repeat.ng-leave {
        -webkit-transition:all linear 0.5s;
        transition:all linear 0.5s;
      }

      .animate-repeat.ng-leave.ng-leave-active,
      .animate-repeat.ng-move,
      .animate-repeat.ng-enter {
        opacity:0;
        max-height:0;
      }

      .animate-repeat.ng-leave,
      .animate-repeat.ng-move.ng-move-active,
      .animate-repeat.ng-enter.ng-enter-active {
        opacity:1;
        max-height:40px;
      }
    </file>
    <file name="protractor.js" type="protractor">
      var friends = element.all(by.repeater('friend in friends'));

      it('should render initial data set', function() {
        expect(friends.count()).toBe(10);
        expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
        expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
        expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
        expect(element(by.binding('friends.length')).getText())
            .toMatch("I have 10 friends. They are:");
      });

       it('should update repeater when filter predicate changes', function() {
         expect(friends.count()).toBe(10);

         element(by.model('q')).sendKeys('ma');

         expect(friends.count()).toBe(2);
         expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
         expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
       });
      </file>
    </example>
 */
var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
  var NG_REMOVED = '$$NG_REMOVED';
  var ngRepeatMinErr = minErr('ngRepeat');

  var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {
    // TODO(perf): generate setters to shave off ~40ms or 1-1.5%
    scope[valueIdentifier] = value;
    if (keyIdentifier) scope[keyIdentifier] = key;
    scope.$index = index;
    scope.$first = (index === 0);
    scope.$last = (index === (arrayLength - 1));
    scope.$middle = !(scope.$first || scope.$last);
    // jshint bitwise: false
    scope.$odd = !(scope.$even = (index&1) === 0);
    // jshint bitwise: true
  };

  var getBlockStart = function(block) {
    return block.clone[0];
  };

  var getBlockEnd = function(block) {
    return block.clone[block.clone.length - 1];
  };


  return {
    restrict: 'A',
    multiElement: true,
    transclude: 'element',
    priority: 1000,
    terminal: true,
    $$tlb: true,
    compile: function ngRepeatCompile($element, $attr) {
      var expression = $attr.ngRepeat;
      var ngRepeatEndComment = document.createComment(' end ngRepeat: ' + expression + ' ');

      var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);

      if (!match) {
        throw ngRepeatMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.",
            expression);
      }

      var lhs = match[1];
      var rhs = match[2];
      var aliasAs = match[3];
      var trackByExp = match[4];

      match = lhs.match(/^(?:(\s*[\$\w]+)|\(\s*([\$\w]+)\s*,\s*([\$\w]+)\s*\))$/);

      if (!match) {
        throw ngRepeatMinErr('iidexp', "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.",
            lhs);
      }
      var valueIdentifier = match[3] || match[1];
      var keyIdentifier = match[2];

      if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||
          /^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) {
        throw ngRepeatMinErr('badident', "alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.",
          aliasAs);
      }

      var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;
      var hashFnLocals = {$id: hashKey};

      if (trackByExp) {
        trackByExpGetter = $parse(trackByExp);
      } else {
        trackByIdArrayFn = function(key, value) {
          return hashKey(value);
        };
        trackByIdObjFn = function(key) {
          return key;
        };
      }

      return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {

        if (trackByExpGetter) {
          trackByIdExpFn = function(key, value, index) {
            // assign key, value, and $index to the locals so that they can be used in hash functions
            if (keyIdentifier) hashFnLocals[keyIdentifier] = key;
            hashFnLocals[valueIdentifier] = value;
            hashFnLocals.$index = index;
            return trackByExpGetter($scope, hashFnLocals);
          };
        }

        // Store a list of elements from previous run. This is a hash where key is the item from the
        // iterator, and the value is objects with following properties.
        //   - scope: bound scope
        //   - element: previous element.
        //   - index: position
        //
        // We are using no-proto object so that we don't need to guard against inherited props via
        // hasOwnProperty.
        var lastBlockMap = createMap();

        //watch props
        $scope.$watchCollection(rhs, function ngRepeatAction(collection) {
          var index, length,
              previousNode = $element[0],     // node that cloned nodes should be inserted after
                                              // initialized to the comment node anchor
              nextNode,
              // Same as lastBlockMap but it has the current state. It will become the
              // lastBlockMap on the next iteration.
              nextBlockMap = createMap(),
              collectionLength,
              key, value, // key/value of iteration
              trackById,
              trackByIdFn,
              collectionKeys,
              block,       // last object information {scope, element, id}
              nextBlockOrder,
              elementsToRemove;

          if (aliasAs) {
            $scope[aliasAs] = collection;
          }

          if (isArrayLike(collection)) {
            collectionKeys = collection;
            trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
          } else {
            trackByIdFn = trackByIdExpFn || trackByIdObjFn;
            // if object, extract keys, sort them and use to determine order of iteration over obj props
            collectionKeys = [];
            for (var itemKey in collection) {
              if (collection.hasOwnProperty(itemKey) && itemKey.charAt(0) != '$') {
                collectionKeys.push(itemKey);
              }
            }
            collectionKeys.sort();
          }

          collectionLength = collectionKeys.length;
          nextBlockOrder = new Array(collectionLength);

          // locate existing items
          for (index = 0; index < collectionLength; index++) {
            key = (collection === collectionKeys) ? index : collectionKeys[index];
            value = collection[key];
            trackById = trackByIdFn(key, value, index);
            if (lastBlockMap[trackById]) {
              // found previously seen block
              block = lastBlockMap[trackById];
              delete lastBlockMap[trackById];
              nextBlockMap[trackById] = block;
              nextBlockOrder[index] = block;
            } else if (nextBlockMap[trackById]) {
              // if collision detected. restore lastBlockMap and throw an error
              forEach(nextBlockOrder, function(block) {
                if (block && block.scope) lastBlockMap[block.id] = block;
              });
              throw ngRepeatMinErr('dupes',
                  "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}",
                  expression, trackById, value);
            } else {
              // new never before seen block
              nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};
              nextBlockMap[trackById] = true;
            }
          }

          // remove leftover items
          for (var blockKey in lastBlockMap) {
            block = lastBlockMap[blockKey];
            elementsToRemove = getBlockNodes(block.clone);
            $animate.leave(elementsToRemove);
            if (elementsToRemove[0].parentNode) {
              // if the element was not removed yet because of pending animation, mark it as deleted
              // so that we can ignore it later
              for (index = 0, length = elementsToRemove.length; index < length; index++) {
                elementsToRemove[index][NG_REMOVED] = true;
              }
            }
            block.scope.$destroy();
          }

          // we are not using forEach for perf reasons (trying to avoid #call)
          for (index = 0; index < collectionLength; index++) {
            key = (collection === collectionKeys) ? index : collectionKeys[index];
            value = collection[key];
            block = nextBlockOrder[index];

            if (block.scope) {
              // if we have already seen this object, then we need to reuse the
              // associated scope/element

              nextNode = previousNode;

              // skip nodes that are already pending removal via leave animation
              do {
                nextNode = nextNode.nextSibling;
              } while (nextNode && nextNode[NG_REMOVED]);

              if (getBlockStart(block) != nextNode) {
                // existing item which got moved
                $animate.move(getBlockNodes(block.clone), null, jqLite(previousNode));
              }
              previousNode = getBlockEnd(block);
              updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
            } else {
              // new item which we don't know about
              $transclude(function ngRepeatTransclude(clone, scope) {
                block.scope = scope;
                // http://jsperf.com/clone-vs-createcomment
                var endNode = ngRepeatEndComment.cloneNode(false);
                clone[clone.length++] = endNode;

                // TODO(perf): support naked previousNode in `enter` to avoid creation of jqLite wrapper?
                $animate.enter(clone, null, jqLite(previousNode));
                previousNode = endNode;
                // Note: We only need the first/last node of the cloned nodes.
                // However, we need to keep the reference to the jqlite wrapper as it might be changed later
                // by a directive with templateUrl when its template arrives.
                block.clone = clone;
                nextBlockMap[block.id] = block;
                updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
              });
            }
          }
          lastBlockMap = nextBlockMap;
        });
      };
    }
  };
}];

var NG_HIDE_CLASS = 'ng-hide';
var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
/**
 * @ngdoc directive
 * @name ngShow
 *
 * @description
 * The `ngShow` directive shows or hides the given HTML element based on the expression
 * provided to the `ngShow` attribute. The element is shown or hidden by removing or adding
 * the `.ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined
 * in AngularJS and sets the display style to none (using an !important flag).
 * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).
 *
 * ```html
 * <!-- when $scope.myValue is truthy (element is visible) -->
 * <div ng-show="myValue"></div>
 *
 * <!-- when $scope.myValue is falsy (element is hidden) -->
 * <div ng-show="myValue" class="ng-hide"></div>
 * ```
 *
 * When the `ngShow` expression evaluates to a falsy value then the `.ng-hide` CSS class is added to the class
 * attribute on the element causing it to become hidden. When truthy, the `.ng-hide` CSS class is removed
 * from the element causing the element not to appear hidden.
 *
 * ## Why is !important used?
 *
 * You may be wondering why !important is used for the `.ng-hide` CSS class. This is because the `.ng-hide` selector
 * can be easily overridden by heavier selectors. For example, something as simple
 * as changing the display style on a HTML list item would make hidden elements appear visible.
 * This also becomes a bigger issue when dealing with CSS frameworks.
 *
 * By using !important, the show and hide behavior will work as expected despite any clash between CSS selector
 * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the
 * styling to change how to hide an element then it is just a matter of using !important in their own CSS code.
 *
 * ### Overriding `.ng-hide`
 *
 * By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
 * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
 * class CSS. Note that the selector that needs to be used is actually `.ng-hide:not(.ng-hide-animate)` to cope
 * with extra animation classes that can be added.
 *
 * ```css
 * .ng-hide:not(.ng-hide-animate) {
 *   /&#42; this is just another form of hiding an element &#42;/
 *   display: block!important;
 *   position: absolute;
 *   top: -9999px;
 *   left: -9999px;
 * }
 * ```
 *
 * By default you don't need to override in CSS anything and the animations will work around the display style.
 *
 * ## A note about animations with `ngShow`
 *
 * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
 * is true and false. This system works like the animation system present with ngClass except that
 * you must also include the !important flag to override the display property
 * so that you can perform an animation when the element is hidden during the time of the animation.
 *
 * ```css
 * //
 * //a working example can be found at the bottom of this page
 * //
 * .my-element.ng-hide-add, .my-element.ng-hide-remove {
 *   /&#42; this is required as of 1.3x to properly
 *      apply all styling in a show/hide animation &#42;/
 *   transition: 0s linear all;
 * }
 *
 * .my-element.ng-hide-add-active,
 * .my-element.ng-hide-remove-active {
 *   /&#42; the transition is defined in the active class &#42;/
 *   transition: 1s linear all;
 * }
 *
 * .my-element.ng-hide-add { ... }
 * .my-element.ng-hide-add.ng-hide-add-active { ... }
 * .my-element.ng-hide-remove { ... }
 * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
 * ```
 *
 * Keep in mind that, as of AngularJS version 1.3.0-beta.11, there is no need to change the display
 * property to block during animation states--ngAnimate will handle the style toggling automatically for you.
 *
 * @animations
 * addClass: `.ng-hide` - happens after the `ngShow` expression evaluates to a truthy value and the just before contents are set to visible
 * removeClass: `.ng-hide` - happens after the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden
 *
 * @element ANY
 * @param {expression} ngShow If the {@link guide/expression expression} is truthy
 *     then the element is shown or hidden respectively.
 *
 * @example
  <example module="ngAnimate" deps="angular-animate.js" animations="true">
    <file name="index.html">
      Click me: <input type="checkbox" ng-model="checked"><br/>
      <div>
        Show:
        <div class="check-element animate-show" ng-show="checked">
          <span class="glyphicon glyphicon-thumbs-up"></span> I show up when your checkbox is checked.
        </div>
      </div>
      <div>
        Hide:
        <div class="check-element animate-show" ng-hide="checked">
          <span class="glyphicon glyphicon-thumbs-down"></span> I hide when your checkbox is checked.
        </div>
      </div>
    </file>
    <file name="glyphicons.css">
      @import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
    </file>
    <file name="animations.css">
      .animate-show {
        line-height: 20px;
        opacity: 1;
        padding: 10px;
        border: 1px solid black;
        background: white;
      }

      .animate-show.ng-hide-add.ng-hide-add-active,
      .animate-show.ng-hide-remove.ng-hide-remove-active {
        -webkit-transition: all linear 0.5s;
        transition: all linear 0.5s;
      }

      .animate-show.ng-hide {
        line-height: 0;
        opacity: 0;
        padding: 0 10px;
      }

      .check-element {
        padding: 10px;
        border: 1px solid black;
        background: white;
      }
    </file>
    <file name="protractor.js" type="protractor">
      var thumbsUp = element(by.css('span.glyphicon-thumbs-up'));
      var thumbsDown = element(by.css('span.glyphicon-thumbs-down'));

      it('should check ng-show / ng-hide', function() {
        expect(thumbsUp.isDisplayed()).toBeFalsy();
        expect(thumbsDown.isDisplayed()).toBeTruthy();

        element(by.model('checked')).click();

        expect(thumbsUp.isDisplayed()).toBeTruthy();
        expect(thumbsDown.isDisplayed()).toBeFalsy();
      });
    </file>
  </example>
 */
var ngShowDirective = ['$animate', function($animate) {
  return {
    restrict: 'A',
    multiElement: true,
    link: function(scope, element, attr) {
      scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
        // we're adding a temporary, animation-specific class for ng-hide since this way
        // we can control when the element is actually displayed on screen without having
        // to have a global/greedy CSS selector that breaks when other animations are run.
        // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
        $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
          tempClasses: NG_HIDE_IN_PROGRESS_CLASS
        });
      });
    }
  };
}];


/**
 * @ngdoc directive
 * @name ngHide
 *
 * @description
 * The `ngHide` directive shows or hides the given HTML element based on the expression
 * provided to the `ngHide` attribute. The element is shown or hidden by removing or adding
 * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined
 * in AngularJS and sets the display style to none (using an !important flag).
 * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).
 *
 * ```html
 * <!-- when $scope.myValue is truthy (element is hidden) -->
 * <div ng-hide="myValue" class="ng-hide"></div>
 *
 * <!-- when $scope.myValue is falsy (element is visible) -->
 * <div ng-hide="myValue"></div>
 * ```
 *
 * When the `ngHide` expression evaluates to a truthy value then the `.ng-hide` CSS class is added to the class
 * attribute on the element causing it to become hidden. When falsy, the `.ng-hide` CSS class is removed
 * from the element causing the element not to appear hidden.
 *
 * ## Why is !important used?
 *
 * You may be wondering why !important is used for the `.ng-hide` CSS class. This is because the `.ng-hide` selector
 * can be easily overridden by heavier selectors. For example, something as simple
 * as changing the display style on a HTML list item would make hidden elements appear visible.
 * This also becomes a bigger issue when dealing with CSS frameworks.
 *
 * By using !important, the show and hide behavior will work as expected despite any clash between CSS selector
 * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the
 * styling to change how to hide an element then it is just a matter of using !important in their own CSS code.
 *
 * ### Overriding `.ng-hide`
 *
 * By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
 * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
 * class in CSS:
 *
 * ```css
 * .ng-hide {
 *   /&#42; this is just another form of hiding an element &#42;/
 *   display: block!important;
 *   position: absolute;
 *   top: -9999px;
 *   left: -9999px;
 * }
 * ```
 *
 * By default you don't need to override in CSS anything and the animations will work around the display style.
 *
 * ## A note about animations with `ngHide`
 *
 * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
 * is true and false. This system works like the animation system present with ngClass, except that the `.ng-hide`
 * CSS class is added and removed for you instead of your own CSS class.
 *
 * ```css
 * //
 * //a working example can be found at the bottom of this page
 * //
 * .my-element.ng-hide-add, .my-element.ng-hide-remove {
 *   transition: 0.5s linear all;
 * }
 *
 * .my-element.ng-hide-add { ... }
 * .my-element.ng-hide-add.ng-hide-add-active { ... }
 * .my-element.ng-hide-remove { ... }
 * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
 * ```
 *
 * Keep in mind that, as of AngularJS version 1.3.0-beta.11, there is no need to change the display
 * property to block during animation states--ngAnimate will handle the style toggling automatically for you.
 *
 * @animations
 * removeClass: `.ng-hide` - happens after the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden
 * addClass: `.ng-hide` - happens after the `ngHide` expression evaluates to a non truthy value and just before the contents are set to visible
 *
 * @element ANY
 * @param {expression} ngHide If the {@link guide/expression expression} is truthy then
 *     the element is shown or hidden respectively.
 *
 * @example
  <example module="ngAnimate" deps="angular-animate.js" animations="true">
    <file name="index.html">
      Click me: <input type="checkbox" ng-model="checked"><br/>
      <div>
        Show:
        <div class="check-element animate-hide" ng-show="checked">
          <span class="glyphicon glyphicon-thumbs-up"></span> I show up when your checkbox is checked.
        </div>
      </div>
      <div>
        Hide:
        <div class="check-element animate-hide" ng-hide="checked">
          <span class="glyphicon glyphicon-thumbs-down"></span> I hide when your checkbox is checked.
        </div>
      </div>
    </file>
    <file name="glyphicons.css">
      @import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
    </file>
    <file name="animations.css">
      .animate-hide {
        -webkit-transition: all linear 0.5s;
        transition: all linear 0.5s;
        line-height: 20px;
        opacity: 1;
        padding: 10px;
        border: 1px solid black;
        background: white;
      }

      .animate-hide.ng-hide {
        line-height: 0;
        opacity: 0;
        padding: 0 10px;
      }

      .check-element {
        padding: 10px;
        border: 1px solid black;
        background: white;
      }
    </file>
    <file name="protractor.js" type="protractor">
      var thumbsUp = element(by.css('span.glyphicon-thumbs-up'));
      var thumbsDown = element(by.css('span.glyphicon-thumbs-down'));

      it('should check ng-show / ng-hide', function() {
        expect(thumbsUp.isDisplayed()).toBeFalsy();
        expect(thumbsDown.isDisplayed()).toBeTruthy();

        element(by.model('checked')).click();

        expect(thumbsUp.isDisplayed()).toBeTruthy();
        expect(thumbsDown.isDisplayed()).toBeFalsy();
      });
    </file>
  </example>
 */
var ngHideDirective = ['$animate', function($animate) {
  return {
    restrict: 'A',
    multiElement: true,
    link: function(scope, element, attr) {
      scope.$watch(attr.ngHide, function ngHideWatchAction(value) {
        // The comment inside of the ngShowDirective explains why we add and
        // remove a temporary class for the show/hide animation
        $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
          tempClasses: NG_HIDE_IN_PROGRESS_CLASS
        });
      });
    }
  };
}];

/**
 * @ngdoc directive
 * @name ngStyle
 * @restrict AC
 *
 * @description
 * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally.
 *
 * @element ANY
 * @param {expression} ngStyle
 *
 * {@link guide/expression Expression} which evals to an
 * object whose keys are CSS style names and values are corresponding values for those CSS
 * keys.
 *
 * Since some CSS style names are not valid keys for an object, they must be quoted.
 * See the 'background-color' style in the example below.
 *
 * @example
   <example>
     <file name="index.html">
        <input type="button" value="set color" ng-click="myStyle={color:'red'}">
        <input type="button" value="set background" ng-click="myStyle={'background-color':'blue'}">
        <input type="button" value="clear" ng-click="myStyle={}">
        <br/>
        <span ng-style="myStyle">Sample Text</span>
        <pre>myStyle={{myStyle}}</pre>
     </file>
     <file name="style.css">
       span {
         color: black;
       }
     </file>
     <file name="protractor.js" type="protractor">
       var colorSpan = element(by.css('span'));

       it('should check ng-style', function() {
         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
         element(by.css('input[value=\'set color\']')).click();
         expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
         element(by.css('input[value=clear]')).click();
         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
       });
     </file>
   </example>
 */
var ngStyleDirective = ngDirective(function(scope, element, attr) {
  scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) {
    if (oldStyles && (newStyles !== oldStyles)) {
      forEach(oldStyles, function(val, style) { element.css(style, '');});
    }
    if (newStyles) element.css(newStyles);
  }, true);
});

/**
 * @ngdoc directive
 * @name ngSwitch
 * @restrict EA
 *
 * @description
 * The `ngSwitch` directive is used to conditionally swap DOM structure on your template based on a scope expression.
 * Elements within `ngSwitch` but without `ngSwitchWhen` or `ngSwitchDefault` directives will be preserved at the location
 * as specified in the template.
 *
 * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
 * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
 * matches the value obtained from the evaluated expression. In other words, you define a container element
 * (where you place the directive), place an expression on the **`on="..."` attribute**
 * (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
 * a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on
 * expression is evaluated. If a matching expression is not found via a when attribute then an element with the default
 * attribute is displayed.
 *
 * <div class="alert alert-info">
 * Be aware that the attribute values to match against cannot be expressions. They are interpreted
 * as literal string values to match against.
 * For example, **`ng-switch-when="someVal"`** will match against the string `"someVal"` not against the
 * value of the expression `$scope.someVal`.
 * </div>

 * @animations
 * enter - happens after the ngSwitch contents change and the matched child element is placed inside the container
 * leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM
 *
 * @usage
 *
 * ```
 * <ANY ng-switch="expression">
 *   <ANY ng-switch-when="matchValue1">...</ANY>
 *   <ANY ng-switch-when="matchValue2">...</ANY>
 *   <ANY ng-switch-default>...</ANY>
 * </ANY>
 * ```
 *
 *
 * @scope
 * @priority 1200
 * @param {*} ngSwitch|on expression to match against <code>ng-switch-when</code>.
 * On child elements add:
 *
 * * `ngSwitchWhen`: the case statement to match against. If match then this
 *   case will be displayed. If the same match appears multiple times, all the
 *   elements will be displayed.
 * * `ngSwitchDefault`: the default case when no other case match. If there
 *   are multiple default cases, all of them will be displayed when no other
 *   case match.
 *
 *
 * @example
  <example module="switchExample" deps="angular-animate.js" animations="true">
    <file name="index.html">
      <div ng-controller="ExampleController">
        <select ng-model="selection" ng-options="item for item in items">
        </select>
        <code>selection={{selection}}</code>
        <hr/>
        <div class="animate-switch-container"
          ng-switch on="selection">
            <div class="animate-switch" ng-switch-when="settings">Settings Div</div>
            <div class="animate-switch" ng-switch-when="home">Home Span</div>
            <div class="animate-switch" ng-switch-default>default</div>
        </div>
      </div>
    </file>
    <file name="script.js">
      angular.module('switchExample', ['ngAnimate'])
        .controller('ExampleController', ['$scope', function($scope) {
          $scope.items = ['settings', 'home', 'other'];
          $scope.selection = $scope.items[0];
        }]);
    </file>
    <file name="animations.css">
      .animate-switch-container {
        position:relative;
        background:white;
        border:1px solid black;
        height:40px;
        overflow:hidden;
      }

      .animate-switch {
        padding:10px;
      }

      .animate-switch.ng-animate {
        -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;

        position:absolute;
        top:0;
        left:0;
        right:0;
        bottom:0;
      }

      .animate-switch.ng-leave.ng-leave-active,
      .animate-switch.ng-enter {
        top:-50px;
      }
      .animate-switch.ng-leave,
      .animate-switch.ng-enter.ng-enter-active {
        top:0;
      }
    </file>
    <file name="protractor.js" type="protractor">
      var switchElem = element(by.css('[ng-switch]'));
      var select = element(by.model('selection'));

      it('should start in settings', function() {
        expect(switchElem.getText()).toMatch(/Settings Div/);
      });
      it('should change to home', function() {
        select.all(by.css('option')).get(1).click();
        expect(switchElem.getText()).toMatch(/Home Span/);
      });
      it('should select default', function() {
        select.all(by.css('option')).get(2).click();
        expect(switchElem.getText()).toMatch(/default/);
      });
    </file>
  </example>
 */
var ngSwitchDirective = ['$animate', function($animate) {
  return {
    restrict: 'EA',
    require: 'ngSwitch',

    // asks for $scope to fool the BC controller module
    controller: ['$scope', function ngSwitchController() {
     this.cases = {};
    }],
    link: function(scope, element, attr, ngSwitchController) {
      var watchExpr = attr.ngSwitch || attr.on,
          selectedTranscludes = [],
          selectedElements = [],
          previousLeaveAnimations = [],
          selectedScopes = [];

      var spliceFactory = function(array, index) {
          return function() { array.splice(index, 1); };
      };

      scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
        var i, ii;
        for (i = 0, ii = previousLeaveAnimations.length; i < ii; ++i) {
          $animate.cancel(previousLeaveAnimations[i]);
        }
        previousLeaveAnimations.length = 0;

        for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
          var selected = getBlockNodes(selectedElements[i].clone);
          selectedScopes[i].$destroy();
          var promise = previousLeaveAnimations[i] = $animate.leave(selected);
          promise.then(spliceFactory(previousLeaveAnimations, i));
        }

        selectedElements.length = 0;
        selectedScopes.length = 0;

        if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
          forEach(selectedTranscludes, function(selectedTransclude) {
            selectedTransclude.transclude(function(caseElement, selectedScope) {
              selectedScopes.push(selectedScope);
              var anchor = selectedTransclude.element;
              caseElement[caseElement.length++] = document.createComment(' end ngSwitchWhen: ');
              var block = { clone: caseElement };

              selectedElements.push(block);
              $animate.enter(caseElement, anchor.parent(), anchor);
            });
          });
        }
      });
    }
  };
}];

var ngSwitchWhenDirective = ngDirective({
  transclude: 'element',
  priority: 1200,
  require: '^ngSwitch',
  multiElement: true,
  link: function(scope, element, attrs, ctrl, $transclude) {
    ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
    ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
  }
});

var ngSwitchDefaultDirective = ngDirective({
  transclude: 'element',
  priority: 1200,
  require: '^ngSwitch',
  multiElement: true,
  link: function(scope, element, attr, ctrl, $transclude) {
    ctrl.cases['?'] = (ctrl.cases['?'] || []);
    ctrl.cases['?'].push({ transclude: $transclude, element: element });
   }
});

/**
 * @ngdoc directive
 * @name ngTransclude
 * @restrict EAC
 *
 * @description
 * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
 *
 * Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.
 *
 * @element ANY
 *
 * @example
   <example module="transcludeExample">
     <file name="index.html">
       <script>
         angular.module('transcludeExample', [])
          .directive('pane', function(){
             return {
               restrict: 'E',
               transclude: true,
               scope: { title:'@' },
               template: '<div style="border: 1px solid black;">' +
                           '<div style="background-color: gray">{{title}}</div>' +
                           '<ng-transclude></ng-transclude>' +
                         '</div>'
             };
         })
         .controller('ExampleController', ['$scope', function($scope) {
           $scope.title = 'Lorem Ipsum';
           $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
         }]);
       </script>
       <div ng-controller="ExampleController">
         <input ng-model="title"> <br/>
         <textarea ng-model="text"></textarea> <br/>
         <pane title="{{title}}">{{text}}</pane>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
        it('should have transcluded', function() {
          var titleElement = element(by.model('title'));
          titleElement.clear();
          titleElement.sendKeys('TITLE');
          var textElement = element(by.model('text'));
          textElement.clear();
          textElement.sendKeys('TEXT');
          expect(element(by.binding('title')).getText()).toEqual('TITLE');
          expect(element(by.binding('text')).getText()).toEqual('TEXT');
        });
     </file>
   </example>
 *
 */
var ngTranscludeDirective = ngDirective({
  restrict: 'EAC',
  link: function($scope, $element, $attrs, controller, $transclude) {
    if (!$transclude) {
      throw minErr('ngTransclude')('orphan',
       'Illegal use of ngTransclude directive in the template! ' +
       'No parent directive that requires a transclusion found. ' +
       'Element: {0}',
       startingTag($element));
    }

    $transclude(function(clone) {
      $element.empty();
      $element.append(clone);
    });
  }
});

/**
 * @ngdoc directive
 * @name script
 * @restrict E
 *
 * @description
 * Load the content of a `<script>` element into {@link ng.$templateCache `$templateCache`}, so that the
 * template can be used by {@link ng.directive:ngInclude `ngInclude`},
 * {@link ngRoute.directive:ngView `ngView`}, or {@link guide/directive directives}. The type of the
 * `<script>` element must be specified as `text/ng-template`, and a cache name for the template must be
 * assigned through the element's `id`, which can then be used as a directive's `templateUrl`.
 *
 * @param {string} type Must be set to `'text/ng-template'`.
 * @param {string} id Cache name of the template.
 *
 * @example
  <example>
    <file name="index.html">
      <script type="text/ng-template" id="/tpl.html">
        Content of the template.
      </script>

      <a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
      <div id="tpl-content" ng-include src="currentTpl"></div>
    </file>
    <file name="protractor.js" type="protractor">
      it('should load template defined inside script tag', function() {
        element(by.css('#tpl-link')).click();
        expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
      });
    </file>
  </example>
 */
var scriptDirective = ['$templateCache', function($templateCache) {
  return {
    restrict: 'E',
    terminal: true,
    compile: function(element, attr) {
      if (attr.type == 'text/ng-template') {
        var templateUrl = attr.id,
            text = element[0].text;

        $templateCache.put(templateUrl, text);
      }
    }
  };
}];

var ngOptionsMinErr = minErr('ngOptions');
/**
 * @ngdoc directive
 * @name select
 * @restrict E
 *
 * @description
 * HTML `SELECT` element with angular data-binding.
 *
 * # `ngOptions`
 *
 * The `ngOptions` attribute can be used to dynamically generate a list of `<option>`
 * elements for the `<select>` element using the array or object obtained by evaluating the
 * `ngOptions` comprehension expression.
 *
 * In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
 * similar result. However, `ngOptions` provides some benefits such as reducing memory and
 * increasing speed by not creating a new scope for each repeated instance, as well as providing
 * more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
 * comprehension expression. `ngOptions` should be used when the `<select>` model needs to be bound
 *  to a non-string value. This is because an option element can only be bound to string values at
 * present.
 *
 * When an item in the `<select>` menu is selected, the array element or object property
 * represented by the selected option will be bound to the model identified by the `ngModel`
 * directive.
 *
 * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
 * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
 * option. See example below for demonstration.
 *
 * <div class="alert alert-warning">
 * **Note:** `ngModel` compares by reference, not value. This is important when binding to an
 * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
 * </div>
 *
 * ## `select` **`as`**
 *
 * Using `select` **`as`** will bind the result of the `select` expression to the model, but
 * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
 * or property name (for object data sources) of the value within the collection. If a **`track by`** expression
 * is used, the result of that expression will be set as the value of the `option` and `select` elements.
 *
 *
 * ### `select` **`as`** and **`track by`**
 *
 * <div class="alert alert-warning">
 * Do not use `select` **`as`** and **`track by`** in the same expression. They are not designed to work together.
 * </div>
 *
 * Consider the following example:
 *
 * ```html
 * <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
 * ```
 *
 * ```js
 * $scope.values = [{
 *   id: 1,
 *   label: 'aLabel',
 *   subItem: { name: 'aSubItem' }
 * }, {
 *   id: 2,
 *   label: 'bLabel',
 *   subItem: { name: 'bSubItem' }
 * }];
 *
 * $scope.selected = { name: 'aSubItem' };
 * ```
 *
 * With the purpose of preserving the selection, the **`track by`** expression is always applied to the element
 * of the data source (to `item` in this example). To calculate whether an element is selected, we do the
 * following:
 *
 * 1. Apply **`track by`** to the elements in the array. In the example: `[1, 2]`
 * 2. Apply **`track by`** to the already selected value in `ngModel`.
 *    In the example: this is not possible as **`track by`** refers to `item.id`, but the selected
 *    value from `ngModel` is `{name: 'aSubItem'}`, so the **`track by`** expression is applied to
 *    a wrong object, the selected element can't be found, `<select>` is always reset to the "not
 *    selected" option.
 *
 *
 * @param {string} ngModel Assignable angular expression to data-bind to.
 * @param {string=} name Property name of the form under which the control is published.
 * @param {string=} required The control is considered valid only if value is entered.
 * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
 *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
 *    `required` when you want to data-bind to the `required` attribute.
 * @param {comprehension_expression=} ngOptions in one of the following forms:
 *
 *   * for array data sources:
 *     * `label` **`for`** `value` **`in`** `array`
 *     * `select` **`as`** `label` **`for`** `value` **`in`** `array`
 *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
 *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
 *     * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`
 *        (for including a filter with `track by`)
 *   * for object data sources:
 *     * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
 *     * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
 *     * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`
 *     * `select` **`as`** `label` **`group by`** `group`
 *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`
 *
 * Where:
 *
 *   * `array` / `object`: an expression which evaluates to an array / object to iterate over.
 *   * `value`: local variable which will refer to each item in the `array` or each property value
 *      of `object` during iteration.
 *   * `key`: local variable which will refer to a property name in `object` during iteration.
 *   * `label`: The result of this expression will be the label for `<option>` element. The
 *     `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).
 *   * `select`: The result of this expression will be bound to the model of the parent `<select>`
 *      element. If not specified, `select` expression will default to `value`.
 *   * `group`: The result of this expression will be used to group options using the `<optgroup>`
 *      DOM element.
 *   * `trackexpr`: Used when working with an array of objects. The result of this expression will be
 *      used to identify the objects in the array. The `trackexpr` will most likely refer to the
 *     `value` variable (e.g. `value.propertyName`). With this the selection is preserved
 *      even when the options are recreated (e.g. reloaded from the server).
 *
 * @example
    <example module="selectExample">
      <file name="index.html">
        <script>
        angular.module('selectExample', [])
          .controller('ExampleController', ['$scope', function($scope) {
            $scope.colors = [
              {name:'black', shade:'dark'},
              {name:'white', shade:'light'},
              {name:'red', shade:'dark'},
              {name:'blue', shade:'dark'},
              {name:'yellow', shade:'light'}
            ];
            $scope.myColor = $scope.colors[2]; // red
          }]);
        </script>
        <div ng-controller="ExampleController">
          <ul>
            <li ng-repeat="color in colors">
              Name: <input ng-model="color.name">
              [<a href ng-click="colors.splice($index, 1)">X</a>]
            </li>
            <li>
              [<a href ng-click="colors.push({})">add</a>]
            </li>
          </ul>
          <hr/>
          Color (null not allowed):
          <select ng-model="myColor" ng-options="color.name for color in colors"></select><br>

          Color (null allowed):
          <span  class="nullable">
            <select ng-model="myColor" ng-options="color.name for color in colors">
              <option value="">-- choose color --</option>
            </select>
          </span><br/>

          Color grouped by shade:
          <select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
          </select><br/>


          Select <a href ng-click="myColor = { name:'not in list', shade: 'other' }">bogus</a>.<br>
          <hr/>
          Currently selected: {{ {selected_color:myColor} }}
          <div style="border:solid 1px black; height:20px"
               ng-style="{'background-color':myColor.name}">
          </div>
        </div>
      </file>
      <file name="protractor.js" type="protractor">
         it('should check ng-options', function() {
           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');
           element.all(by.model('myColor')).first().click();
           element.all(by.css('select[ng-model="myColor"] option')).first().click();
           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');
           element(by.css('.nullable select[ng-model="myColor"]')).click();
           element.all(by.css('.nullable select[ng-model="myColor"] option')).first().click();
           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null');
         });
      </file>
    </example>
 */

var ngOptionsDirective = valueFn({
  restrict: 'A',
  terminal: true
});

// jshint maxlen: false
var selectDirective = ['$compile', '$parse', function($compile,   $parse) {
                         //000011111111110000000000022222222220000000000000000000003333333333000000000000004444444444444440000000005555555555555550000000666666666666666000000000000000777777777700000000000000000008888888888
  var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/,
      nullModelCtrl = {$setViewValue: noop};
// jshint maxlen: 100

  return {
    restrict: 'E',
    require: ['select', '?ngModel'],
    controller: ['$element', '$scope', '$attrs', function($element, $scope, $attrs) {
      var self = this,
          optionsMap = {},
          ngModelCtrl = nullModelCtrl,
          nullOption,
          unknownOption;


      self.databound = $attrs.ngModel;


      self.init = function(ngModelCtrl_, nullOption_, unknownOption_) {
        ngModelCtrl = ngModelCtrl_;
        nullOption = nullOption_;
        unknownOption = unknownOption_;
      };


      self.addOption = function(value, element) {
        assertNotHasOwnProperty(value, '"option value"');
        optionsMap[value] = true;

        if (ngModelCtrl.$viewValue == value) {
          $element.val(value);
          if (unknownOption.parent()) unknownOption.remove();
        }
        // Workaround for https://code.google.com/p/chromium/issues/detail?id=381459
        // Adding an <option selected="selected"> element to a <select required="required"> should
        // automatically select the new element
        if (element && element[0].hasAttribute('selected')) {
          element[0].selected = true;
        }
      };


      self.removeOption = function(value) {
        if (this.hasOption(value)) {
          delete optionsMap[value];
          if (ngModelCtrl.$viewValue === value) {
            this.renderUnknownOption(value);
          }
        }
      };


      self.renderUnknownOption = function(val) {
        var unknownVal = '? ' + hashKey(val) + ' ?';
        unknownOption.val(unknownVal);
        $element.prepend(unknownOption);
        $element.val(unknownVal);
        unknownOption.prop('selected', true); // needed for IE
      };


      self.hasOption = function(value) {
        return optionsMap.hasOwnProperty(value);
      };

      $scope.$on('$destroy', function() {
        // disable unknown option so that we don't do work when the whole select is being destroyed
        self.renderUnknownOption = noop;
      });
    }],

    link: function(scope, element, attr, ctrls) {
      // if ngModel is not defined, we don't need to do anything
      if (!ctrls[1]) return;

      var selectCtrl = ctrls[0],
          ngModelCtrl = ctrls[1],
          multiple = attr.multiple,
          optionsExp = attr.ngOptions,
          nullOption = false, // if false, user will not be able to select it (used by ngOptions)
          emptyOption,
          renderScheduled = false,
          // we can't just jqLite('<option>') since jqLite is not smart enough
          // to create it in <select> and IE barfs otherwise.
          optionTemplate = jqLite(document.createElement('option')),
          optGroupTemplate =jqLite(document.createElement('optgroup')),
          unknownOption = optionTemplate.clone();

      // find "null" option
      for (var i = 0, children = element.children(), ii = children.length; i < ii; i++) {
        if (children[i].value === '') {
          emptyOption = nullOption = children.eq(i);
          break;
        }
      }

      selectCtrl.init(ngModelCtrl, nullOption, unknownOption);

      // required validator
      if (multiple) {
        ngModelCtrl.$isEmpty = function(value) {
          return !value || value.length === 0;
        };
      }

      if (optionsExp) setupAsOptions(scope, element, ngModelCtrl);
      else if (multiple) setupAsMultiple(scope, element, ngModelCtrl);
      else setupAsSingle(scope, element, ngModelCtrl, selectCtrl);


      ////////////////////////////



      function setupAsSingle(scope, selectElement, ngModelCtrl, selectCtrl) {
        ngModelCtrl.$render = function() {
          var viewValue = ngModelCtrl.$viewValue;

          if (selectCtrl.hasOption(viewValue)) {
            if (unknownOption.parent()) unknownOption.remove();
            selectElement.val(viewValue);
            if (viewValue === '') emptyOption.prop('selected', true); // to make IE9 happy
          } else {
            if (viewValue == null && emptyOption) {
              selectElement.val('');
            } else {
              selectCtrl.renderUnknownOption(viewValue);
            }
          }
        };

        selectElement.on('change', function() {
          scope.$apply(function() {
            if (unknownOption.parent()) unknownOption.remove();
            ngModelCtrl.$setViewValue(selectElement.val());
          });
        });
      }

      function setupAsMultiple(scope, selectElement, ctrl) {
        var lastView;
        ctrl.$render = function() {
          var items = new HashMap(ctrl.$viewValue);
          forEach(selectElement.find('option'), function(option) {
            option.selected = isDefined(items.get(option.value));
          });
        };

        // we have to do it on each watch since ngModel watches reference, but
        // we need to work of an array, so we need to see if anything was inserted/removed
        scope.$watch(function selectMultipleWatch() {
          if (!equals(lastView, ctrl.$viewValue)) {
            lastView = shallowCopy(ctrl.$viewValue);
            ctrl.$render();
          }
        });

        selectElement.on('change', function() {
          scope.$apply(function() {
            var array = [];
            forEach(selectElement.find('option'), function(option) {
              if (option.selected) {
                array.push(option.value);
              }
            });
            ctrl.$setViewValue(array);
          });
        });
      }

      function setupAsOptions(scope, selectElement, ctrl) {
        var match;

        if (!(match = optionsExp.match(NG_OPTIONS_REGEXP))) {
          throw ngOptionsMinErr('iexp',
            "Expected expression in form of " +
            "'_select_ (as _label_)? for (_key_,)?_value_ in _collection_'" +
            " but got '{0}'. Element: {1}",
            optionsExp, startingTag(selectElement));
        }

        var displayFn = $parse(match[2] || match[1]),
            valueName = match[4] || match[6],
            selectAs = / as /.test(match[0]) && match[1],
            selectAsFn = selectAs ? $parse(selectAs) : null,
            keyName = match[5],
            groupByFn = $parse(match[3] || ''),
            valueFn = $parse(match[2] ? match[1] : valueName),
            valuesFn = $parse(match[7]),
            track = match[8],
            trackFn = track ? $parse(match[8]) : null,
            trackKeysCache = {},
            // This is an array of array of existing option groups in DOM.
            // We try to reuse these if possible
            // - optionGroupsCache[0] is the options with no option group
            // - optionGroupsCache[?][0] is the parent: either the SELECT or OPTGROUP element
            optionGroupsCache = [[{element: selectElement, label:''}]],
            //re-usable object to represent option's locals
            locals = {};

        if (nullOption) {
          // compile the element since there might be bindings in it
          $compile(nullOption)(scope);

          // remove the class, which is added automatically because we recompile the element and it
          // becomes the compilation root
          nullOption.removeClass('ng-scope');

          // we need to remove it before calling selectElement.empty() because otherwise IE will
          // remove the label from the element. wtf?
          nullOption.remove();
        }

        // clear contents, we'll add what's needed based on the model
        selectElement.empty();

        selectElement.on('change', selectionChanged);

        ctrl.$render = render;

        scope.$watchCollection(valuesFn, scheduleRendering);
        scope.$watchCollection(getLabels, scheduleRendering);

        if (multiple) {
          scope.$watchCollection(function() { return ctrl.$modelValue; }, scheduleRendering);
        }

        // ------------------------------------------------------------------ //

        function callExpression(exprFn, key, value) {
          locals[valueName] = value;
          if (keyName) locals[keyName] = key;
          return exprFn(scope, locals);
        }

        function selectionChanged() {
          scope.$apply(function() {
            var collection = valuesFn(scope) || [];
            var viewValue;
            if (multiple) {
              viewValue = [];
              forEach(selectElement.val(), function(selectedKey) {
                  selectedKey = trackFn ? trackKeysCache[selectedKey] : selectedKey;
                viewValue.push(getViewValue(selectedKey, collection[selectedKey]));
              });
            } else {
              var selectedKey = trackFn ? trackKeysCache[selectElement.val()] : selectElement.val();
              viewValue = getViewValue(selectedKey, collection[selectedKey]);
            }
            ctrl.$setViewValue(viewValue);
            render();
          });
        }

        function getViewValue(key, value) {
          if (key === '?') {
            return undefined;
          } else if (key === '') {
            return null;
          } else {
            var viewValueFn = selectAsFn ? selectAsFn : valueFn;
            return callExpression(viewValueFn, key, value);
          }
        }

        function getLabels() {
          var values = valuesFn(scope);
          var toDisplay;
          if (values && isArray(values)) {
            toDisplay = new Array(values.length);
            for (var i = 0, ii = values.length; i < ii; i++) {
              toDisplay[i] = callExpression(displayFn, i, values[i]);
            }
            return toDisplay;
          } else if (values) {
            // TODO: Add a test for this case
            toDisplay = {};
            for (var prop in values) {
              if (values.hasOwnProperty(prop)) {
                toDisplay[prop] = callExpression(displayFn, prop, values[prop]);
              }
            }
          }
          return toDisplay;
        }

        function createIsSelectedFn(viewValue) {
          var selectedSet;
          if (multiple) {
            if (trackFn && isArray(viewValue)) {

              selectedSet = new HashMap([]);
              for (var trackIndex = 0; trackIndex < viewValue.length; trackIndex++) {
                // tracking by key
                selectedSet.put(callExpression(trackFn, null, viewValue[trackIndex]), true);
              }
            } else {
              selectedSet = new HashMap(viewValue);
            }
          } else if (trackFn) {
            viewValue = callExpression(trackFn, null, viewValue);
          }

          return function isSelected(key, value) {
            var compareValueFn;
            if (trackFn) {
              compareValueFn = trackFn;
            } else if (selectAsFn) {
              compareValueFn = selectAsFn;
            } else {
              compareValueFn = valueFn;
            }

            if (multiple) {
              return isDefined(selectedSet.remove(callExpression(compareValueFn, key, value)));
            } else {
              return viewValue === callExpression(compareValueFn, key, value);
            }
          };
        }

        function scheduleRendering() {
          if (!renderScheduled) {
            scope.$$postDigest(render);
            renderScheduled = true;
          }
        }

        /**
         * A new labelMap is created with each render.
         * This function is called for each existing option with added=false,
         * and each new option with added=true.
         * - Labels that are passed to this method twice,
         * (once with added=true and once with added=false) will end up with a value of 0, and
         * will cause no change to happen to the corresponding option.
         * - Labels that are passed to this method only once with added=false will end up with a
         * value of -1 and will eventually be passed to selectCtrl.removeOption()
         * - Labels that are passed to this method only once with added=true will end up with a
         * value of 1 and will eventually be passed to selectCtrl.addOption()
        */
        function updateLabelMap(labelMap, label, added) {
          labelMap[label] = labelMap[label] || 0;
          labelMap[label] += (added ? 1 : -1);
        }

        function render() {
          renderScheduled = false;

          // Temporary location for the option groups before we render them
          var optionGroups = {'':[]},
              optionGroupNames = [''],
              optionGroupName,
              optionGroup,
              option,
              existingParent, existingOptions, existingOption,
              viewValue = ctrl.$viewValue,
              values = valuesFn(scope) || [],
              keys = keyName ? sortedKeys(values) : values,
              key,
              value,
              groupLength, length,
              groupIndex, index,
              labelMap = {},
              selected,
              isSelected = createIsSelectedFn(viewValue),
              anySelected = false,
              lastElement,
              element,
              label,
              optionId;

          trackKeysCache = {};

          // We now build up the list of options we need (we merge later)
          for (index = 0; length = keys.length, index < length; index++) {
            key = index;
            if (keyName) {
              key = keys[index];
              if (key.charAt(0) === '$') continue;
            }
            value = values[key];

            optionGroupName = callExpression(groupByFn, key, value) || '';
            if (!(optionGroup = optionGroups[optionGroupName])) {
              optionGroup = optionGroups[optionGroupName] = [];
              optionGroupNames.push(optionGroupName);
            }

            selected = isSelected(key, value);
            anySelected = anySelected || selected;

            label = callExpression(displayFn, key, value); // what will be seen by the user

            // doing displayFn(scope, locals) || '' overwrites zero values
            label = isDefined(label) ? label : '';
            optionId = trackFn ? trackFn(scope, locals) : (keyName ? keys[index] : index);
            if (trackFn) {
              trackKeysCache[optionId] = key;
            }

            optionGroup.push({
              // either the index into array or key from object
              id: optionId,
              label: label,
              selected: selected                   // determine if we should be selected
            });
          }
          if (!multiple) {
            if (nullOption || viewValue === null) {
              // insert null option if we have a placeholder, or the model is null
              optionGroups[''].unshift({id:'', label:'', selected:!anySelected});
            } else if (!anySelected) {
              // option could not be found, we have to insert the undefined item
              optionGroups[''].unshift({id:'?', label:'', selected:true});
            }
          }

          // Now we need to update the list of DOM nodes to match the optionGroups we computed above
          for (groupIndex = 0, groupLength = optionGroupNames.length;
               groupIndex < groupLength;
               groupIndex++) {
            // current option group name or '' if no group
            optionGroupName = optionGroupNames[groupIndex];

            // list of options for that group. (first item has the parent)
            optionGroup = optionGroups[optionGroupName];

            if (optionGroupsCache.length <= groupIndex) {
              // we need to grow the optionGroups
              existingParent = {
                element: optGroupTemplate.clone().attr('label', optionGroupName),
                label: optionGroup.label
              };
              existingOptions = [existingParent];
              optionGroupsCache.push(existingOptions);
              selectElement.append(existingParent.element);
            } else {
              existingOptions = optionGroupsCache[groupIndex];
              existingParent = existingOptions[0];  // either SELECT (no group) or OPTGROUP element

              // update the OPTGROUP label if not the same.
              if (existingParent.label != optionGroupName) {
                existingParent.element.attr('label', existingParent.label = optionGroupName);
              }
            }

            lastElement = null;  // start at the beginning
            for (index = 0, length = optionGroup.length; index < length; index++) {
              option = optionGroup[index];
              if ((existingOption = existingOptions[index + 1])) {
                // reuse elements
                lastElement = existingOption.element;
                if (existingOption.label !== option.label) {
                  updateLabelMap(labelMap, existingOption.label, false);
                  updateLabelMap(labelMap, option.label, true);
                  lastElement.text(existingOption.label = option.label);
                  lastElement.prop('label', existingOption.label);
                }
                if (existingOption.id !== option.id) {
                  lastElement.val(existingOption.id = option.id);
                }
                // lastElement.prop('selected') provided by jQuery has side-effects
                if (lastElement[0].selected !== option.selected) {
                  lastElement.prop('selected', (existingOption.selected = option.selected));
                  if (msie) {
                    // See #7692
                    // The selected item wouldn't visually update on IE without this.
                    // Tested on Win7: IE9, IE10 and IE11. Future IEs should be tested as well
                    lastElement.prop('selected', existingOption.selected);
                  }
                }
              } else {
                // grow elements

                // if it's a null option
                if (option.id === '' && nullOption) {
                  // put back the pre-compiled element
                  element = nullOption;
                } else {
                  // jQuery(v1.4.2) Bug: We should be able to chain the method calls, but
                  // in this version of jQuery on some browser the .text() returns a string
                  // rather then the element.
                  (element = optionTemplate.clone())
                      .val(option.id)
                      .prop('selected', option.selected)
                      .attr('selected', option.selected)
                      .prop('label', option.label)
                      .text(option.label);
                }

                existingOptions.push(existingOption = {
                    element: element,
                    label: option.label,
                    id: option.id,
                    selected: option.selected
                });
                updateLabelMap(labelMap, option.label, true);
                if (lastElement) {
                  lastElement.after(element);
                } else {
                  existingParent.element.append(element);
                }
                lastElement = element;
              }
            }
            // remove any excessive OPTIONs in a group
            index++; // increment since the existingOptions[0] is parent element not OPTION
            while (existingOptions.length > index) {
              option = existingOptions.pop();
              updateLabelMap(labelMap, option.label, false);
              option.element.remove();
            }
          }
          // remove any excessive OPTGROUPs from select
          while (optionGroupsCache.length > groupIndex) {
            // remove all the labels in the option group
            optionGroup = optionGroupsCache.pop();
            for (index = 1; index < optionGroup.length; ++index) {
              updateLabelMap(labelMap, optionGroup[index].label, false);
            }
            optionGroup[0].element.remove();
          }
          forEach(labelMap, function(count, label) {
            if (count > 0) {
              selectCtrl.addOption(label);
            } else if (count < 0) {
              selectCtrl.removeOption(label);
            }
          });
        }
      }
    }
  };
}];

var optionDirective = ['$interpolate', function($interpolate) {
  var nullSelectCtrl = {
    addOption: noop,
    removeOption: noop
  };

  return {
    restrict: 'E',
    priority: 100,
    compile: function(element, attr) {
      if (isUndefined(attr.value)) {
        var interpolateFn = $interpolate(element.text(), true);
        if (!interpolateFn) {
          attr.$set('value', element.text());
        }
      }

      return function(scope, element, attr) {
        var selectCtrlName = '$selectController',
            parent = element.parent(),
            selectCtrl = parent.data(selectCtrlName) ||
              parent.parent().data(selectCtrlName); // in case we are in optgroup

        if (!selectCtrl || !selectCtrl.databound) {
          selectCtrl = nullSelectCtrl;
        }

        if (interpolateFn) {
          scope.$watch(interpolateFn, function interpolateWatchAction(newVal, oldVal) {
            attr.$set('value', newVal);
            if (oldVal !== newVal) {
              selectCtrl.removeOption(oldVal);
            }
            selectCtrl.addOption(newVal, element);
          });
        } else {
          selectCtrl.addOption(attr.value, element);
        }

        element.on('$destroy', function() {
          selectCtrl.removeOption(attr.value);
        });
      };
    }
  };
}];

var styleDirective = valueFn({
  restrict: 'E',
  terminal: false
});

var requiredDirective = function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) return;
      attr.required = true; // force truthy in case we are on non input element

      ctrl.$validators.required = function(modelValue, viewValue) {
        return !attr.required || !ctrl.$isEmpty(viewValue);
      };

      attr.$observe('required', function() {
        ctrl.$validate();
      });
    }
  };
};


var patternDirective = function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) return;

      var regexp, patternExp = attr.ngPattern || attr.pattern;
      attr.$observe('pattern', function(regex) {
        if (isString(regex) && regex.length > 0) {
          regex = new RegExp('^' + regex + '$');
        }

        if (regex && !regex.test) {
          throw minErr('ngPattern')('noregexp',
            'Expected {0} to be a RegExp but was {1}. Element: {2}', patternExp,
            regex, startingTag(elm));
        }

        regexp = regex || undefined;
        ctrl.$validate();
      });

      ctrl.$validators.pattern = function(modelValue, viewValue) {
        // HTML5 pattern constraint validates the input value, so we validate the viewValue
        return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);
      };
    }
  };
};


var maxlengthDirective = function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) return;

      var maxlength = -1;
      attr.$observe('maxlength', function(value) {
        var intVal = int(value);
        maxlength = isNaN(intVal) ? -1 : intVal;
        ctrl.$validate();
      });
      ctrl.$validators.maxlength = function(modelValue, viewValue) {
        return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);
      };
    }
  };
};

var minlengthDirective = function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) return;

      var minlength = 0;
      attr.$observe('minlength', function(value) {
        minlength = int(value) || 0;
        ctrl.$validate();
      });
      ctrl.$validators.minlength = function(modelValue, viewValue) {
        return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
      };
    }
  };
};

  if (window.angular.bootstrap) {
    //AngularJS is already loaded, so we can return here...
    console.log('WARNING: Tried to load angular more than once.');
    return;
  }

  //try to bind to jquery now so that one can write jqLite(document).ready()
  //but we will rebind on bootstrap again.
  bindJQuery();

  publishExternalAPI(angular);

  jqLite(document).ready(function() {
    angularInit(document, bootstrap);
  });

})(window, document);

!window.angular.$$csp() && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}</style>');
'use strict';
/**
 * Binds a CodeMirror widget to a <textarea> element.
 */
angular.module('ui.codemirror', []).constant('uiCodemirrorConfig', {}).directive('uiCodemirror', [
  'uiCodemirrorConfig',
  function (uiCodemirrorConfig) {
    return {
      restrict: 'EA',
      require: '?ngModel',
      priority: 1,
      compile: function compile() {
        // Require CodeMirror
        if (angular.isUndefined(window.CodeMirror)) {
          throw new Error('ui-codemirror need CodeMirror to work... (o rly?)');
        }
        return function postLink(scope, iElement, iAttrs, ngModel) {
          var options, opts, codeMirror, initialTextValue;
          initialTextValue = iElement.text();
          options = uiCodemirrorConfig.codemirror || {};
          opts = angular.extend({ value: initialTextValue }, options, scope.$eval(iAttrs.uiCodemirror), scope.$eval(iAttrs.uiCodemirrorOpts));
          if (iElement[0].tagName === 'TEXTAREA') {
            // Might bug but still ...
            codeMirror = window.CodeMirror.fromTextArea(iElement[0], opts);
          } else {
            iElement.html('');
            codeMirror = new window.CodeMirror(function (cm_el) {
              iElement.append(cm_el);
            }, opts);
          }
          if (iAttrs.uiCodemirror || iAttrs.uiCodemirrorOpts) {
            var codemirrorDefaultsKeys = Object.keys(window.CodeMirror.defaults);
            scope.$watch(iAttrs.uiCodemirror || iAttrs.uiCodemirrorOpts, function updateOptions(newValues, oldValue) {
              if (!angular.isObject(newValues)) {
                return;
              }
              codemirrorDefaultsKeys.forEach(function (key) {
                if (newValues.hasOwnProperty(key)) {
                  if (oldValue && newValues[key] === oldValue[key]) {
                    return;
                  }
                  codeMirror.setOption(key, newValues[key]);
                }
              });
            }, true);
          }
          if (ngModel) {
            // CodeMirror expects a string, so make sure it gets one.
            // This does not change the model.
            ngModel.$formatters.push(function (value) {
              if (angular.isUndefined(value) || value === null) {
                return '';
              } else if (angular.isObject(value) || angular.isArray(value)) {
                throw new Error('ui-codemirror cannot use an object or an array as a model');
              }
              return value;
            });
            // Override the ngModelController $render method, which is what gets called when the model is updated.
            // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
            ngModel.$render = function () {
              //Code mirror expects a string so make sure it gets one
              //Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive)
              var safeViewValue = ngModel.$viewValue || '';
              codeMirror.setValue(safeViewValue);
            };
            // Keep the ngModel in sync with changes from CodeMirror
            codeMirror.on('change', function (instance) {
              var newValue = instance.getValue();
              if (newValue !== ngModel.$viewValue) {
                // Changes to the model from a callback need to be wrapped in $apply or angular will not notice them
                scope.$apply(function () {
                  ngModel.$setViewValue(newValue);
                });
              }
            });
          }
          // Watch ui-refresh and refresh the directive
          if (iAttrs.uiRefresh) {
            scope.$watch(iAttrs.uiRefresh, function (newVal, oldVal) {
              // Skip the initial watch firing
              if (newVal !== oldVal) {
                codeMirror.refresh();
              }
            });
          }
          // Allow access to the CodeMirror instance through a broadcasted event
          // eg: $broadcast('CodeMirror', function(cm){...});
          scope.$on('CodeMirror', function (event, callback) {
            if (angular.isFunction(callback)) {
              callback(codeMirror);
            } else {
              throw new Error('the CodeMirror event requires a callback function');
            }
          });
          // onLoad callback
          if (angular.isFunction(opts.onLoad)) {
            opts.onLoad(codeMirror);
          }
        };
      }
    };
  }
]);
/*
 * angular-marked
 * (c) 2014 J. Harshbarger
 * Licensed MIT
 */

/* jshint undef: true, unused: true */
/* global angular:true */
/* global marked:true */
/* global module */
/* global require */

(function () {
  'use strict';

  /**
   * @ngdoc overview
   * @name index
   *
   * @description
   * AngularJS Markdown using [marked](https://github.com/chjj/marked).
   *
   * ## Why?
   *
   * I wanted to use [marked](https://github.com/chjj/marked) instead of [showdown](https://github.com/coreyti/showdown) as used in [angular-markdown-directive](https://github.com/btford/angular-markdown-directive) as well as expose the option to globally set defaults.
   *
   * ## How?
   *
   * - {@link hc.marked.directive:marked As a directive}
   * - {@link hc.marked.service:marked As a service}
   * - {@link hc.marked.service:markedProvider Set default options}
   *
   * @example

      Convert markdown to html at run time.  For example:

      <example module="hc.marked">
        <file name=".html">
          <form ng-controller="MainController">
            Markdown:<br />
            <textarea ng-model="my_markdown" cols="60" rows="5" class="span8" /><br />
            Output:<br />
            <div marked="my_markdown" />
          </form>
        </file>
        <file  name=".js">
          function MainController($scope) {
            $scope.my_markdown = "*This* **is** [markdown](https://daringfireball.net/projects/markdown/)";
          }
        </file>
      </example>

    *
    */

    /**
     * @ngdoc overview
     * @name hc.marked
     * @description # angular-marked (core module)
       # Installation
      First include angular-marked.js in your HTML:

      ```js
        <script src="angular-marked.js">
      ```

      Then load the module in your application by adding it as a dependency:

      ```js
      angular.module('yourApp', ['hc.marked']);
      ```

      With that you're ready to get started!
     */

  if (typeof module !== 'undefined' && typeof exports === 'object') {
    module.exports = 'hc.marked';
  }

  angular.module('hc.marked', [])

    /**
    * @ngdoc service
    * @name hc.marked.service:marked
    * @requires $window
    * @description
    * A reference to the [marked](https://github.com/chjj/marked) parser.
    *
    * @example
    <example module="hc.marked">
      <file name=".html">
        <div ng-controller="MainController">
          html: {{html}}
        </div>
      </file>
      <file  name=".js">
        function MainController($scope, marked) {
          $scope.html = marked('#TEST');
        }
      </file>
    </example>
   **/

   /**
   * @ngdoc service
   * @name hc.marked.service:markedProvider
   * @description
   * Use `markedProvider` to change the default behavior of the {@link hc.marked.service:marked marked} service.
   *
   * @example

    ## Example using [google-code-prettify syntax highlighter](https://code.google.com/p/google-code-prettify/) (must include google-code-prettify.js script).  Also works with [highlight.js Javascript syntax highlighter](http://highlightjs.org/).

    <example module="myApp">
    <file name=".js">
    angular.module('myApp', ['hc.marked'])
      .config(['markedProvider', function(markedProvider) {
        markedProvider.setOptions({
          gfm: true,
          tables: true,
          highlight: function (code) {
            return prettyPrintOne(code);
          }
        });
      }]);
    </file>
    <file name=".html">
      <marked>
      ```js
      angular.module('myApp', ['hc.marked'])
        .config(['markedProvider', function(markedProvider) {
          markedProvider.setOptions({
            gfm: true,
            tables: true,
            highlight: function (code) {
              return prettyPrintOne(code);
            }
          });
        }]);
      ```
      </marked>
    </file>
    </example>
  **/

  .provider('marked', function () {

    var self = this;

    /**
     * @ngdoc method
     * @name markedProvider#setOptions
     * @methodOf hc.marked.service:markedProvider
     *
     * @param {object} opts Default options for [marked](https://github.com/chjj/marked#options-1).
     */

    self.setRenderer = function (opts) {
      this.renderer = opts;
    };

    self.setOptions = function(opts) {  // Store options for later
      this.defaults = opts;
    };

    self.$get = ['$window', '$log', function ($window, $log) {

      var m =  (function() {

        if (typeof module !== 'undefined' && typeof exports === 'object') {
          return require('marked');
        } else {
          return $window.marked || marked;
        }

      })();

      if (angular.isUndefined(m)) {
        $log.error('angular-marked Error: marked not loaded.  See installation instructions.');
        return;
      }

      // override rendered markdown html
      // with custom definitions if defined
      if (self.renderer) {
        var r = new m.Renderer();
        var o = Object.keys(self.renderer),
            l = o.length;

        while (l--) {
          r[o[l]] = self.renderer[o[l]];
        }

        // add the new renderer to the options if need be
        self.defaults = self.defaults || {};
        self.defaults.renderer = r;
      }

      m.setOptions(self.defaults);

      return m;
    }];

  })

  // TODO: filter tests */
  //app.filter('marked', ['marked', function(marked) {
  //  return marked;
  //}]);

  /**
   * @ngdoc directive
   * @name hc.marked.directive:marked
   * @restrict AE
   * @element any
   *
   * @description
   * Compiles source test into HTML.
   *
   * @param {expression} marked The source text to be compiled.  If blank uses content as the source.
   * @param {expression=} opts Hash of options that override defaults.
   *
   * @example

     ## A simple block of text

      <example module="hc.marked">
        <file name="exampleA.html">
         * <marked>
         * ### Markdown directive
         *
         * *It works!*
         *
         * *This* **is** [markdown](https://daringfireball.net/projects/markdown/) in the view.
         * </marked>
        </file>
      </example>

     ## Bind to a scope variable

      <example module="hc.marked">
        <file name="exampleB.html">
          <form ng-controller="MainController">
            Markdown:<br />
            <textarea ng-model="my_markdown" class="span8" cols="60" rows="5"></textarea><br />
            Output:<br />
            <blockquote marked="my_markdown"></blockquote>
          </form>
        </file>
        <file  name="exampleB.js">
          * function MainController($scope) {
          *   $scope.my_markdown = '*This* **is** [markdown](https://daringfireball.net/projects/markdown/)';
          *   $scope.my_markdown += ' in a scope variable';
          * }
        </file>
      </example>

      ## Include a markdown file:

       <example module="hc.marked">
         <file name="exampleC.html">
           <div marked ng-include="'include.html'" />
         </file>
         * <file name="include.html">
         * *This* **is** [markdown](https://daringfireball.net/projects/markdown/) in a include file.
         * </file>
       </example>
   */

  .directive('marked', ['marked', function (marked) {
    return {
      restrict: 'AE',
      replace: true,
      scope: {
        opts: '=',
        marked: '='
      },
      link: function (scope, element, attrs) {
        set(scope.marked || element.text() || '');

        function unindent(text) {
          if (!text) return text;

          var lines  = text
            .replace(/\t/g, '  ')
            .split(/\r?\n/);

          var i, l, min = null, line, len = lines.length;
          for (i = 0; i < len; i++) {
            line = lines[i];
            l = line.match(/^(\s*)/)[0].length;
            if (l === line.length) { continue; }
            min = (l < min || min === null) ? l : min;
          }

          if (min !== null && min > 0) {
            for (i = 0; i < len; i++) {
              lines[i] = lines[i].substr(min);
            }
          }
          return lines.join('\n');
        }

        function set(text) {
          text = unindent(text || '');
          element.html(marked(text, scope.opts || null));
        }

        if (attrs.marked) {
          scope.$watch('marked', set);
        }

      }
    };
  }]);

}());

/*global angular*/
(function (module) {

var dirHljs, dirLanguageFactory, dirSourceFactory, dirIncludeFactory;

function shouldHighlightStatics(attrs) {
  var should = true;
  angular.forEach([
    'source', 'include'
  ], function (name) {
    if (attrs[name]) {
      should = false;
    }
  });
  return should;
}

module

/**
 * hljsService service
 */
.provider('hljsService', function () {
  var _hljsOptions = {};

  return {
    setOptions: function (options) {
      angular.extend(_hljsOptions, options);
    },
    getOptions: function () {
      return angular.copy(_hljsOptions);
    },
    $get: ['$window', function ($window) {
      ($window.hljs.configure || angular.noop)(_hljsOptions);
      return $window.hljs;
    }]
  };
})

/**
 * hljsCache service
 */
.factory('hljsCache', [
         '$cacheFactory',
function ($cacheFactory) {
  return $cacheFactory('hljsCache');
}])

/**
 * HljsCtrl controller
 */
.controller('HljsCtrl', [
                  'hljsCache', 'hljsService',
function HljsCtrl (hljsCache,   hljsService) {
  var ctrl = this;

  var _elm = null,
      _lang = null,
      _code = null,
      _hlCb = null;

  ctrl.init = function (codeElm) {
    _elm = codeElm;
  };

  ctrl.setLanguage = function (lang) {
    _lang = lang;

    if (_code) {
      ctrl.highlight(_code);
    }
  };

  ctrl.highlightCallback = function (cb) {
    _hlCb = cb;
  };

  ctrl.highlight = function (code) {
    if (!_elm) {
      return;
    }

    var res, cacheKey;

    _code = code;

    if (_lang) {
      // language specified
      cacheKey = ctrl._cacheKey(_lang, _code);
      res = hljsCache.get(cacheKey);

      if (!res) {
        res = hljsService.highlight(_lang, hljsService.fixMarkup(_code), true);
        hljsCache.put(cacheKey, res);
      }
    }
    else {
      // language auto-detect
      cacheKey = ctrl._cacheKey(_code);
      res = hljsCache.get(cacheKey);

      if (!res) {
        res = hljsService.highlightAuto(hljsService.fixMarkup(_code));
        hljsCache.put(cacheKey, res);
      }
    }

    _elm.html(res.value);
    // language as class on the <code> tag
    _elm.addClass(res.language);

    if (_hlCb !== null && angular.isFunction(_hlCb)) {
      _hlCb();
    }
  };

  ctrl.clear = function () {
    if (!_elm) {
      return;
    }
    _code = null;
    _elm.text('');
  };

  ctrl.release = function () {
    _elm = null;
  };

  ctrl._cacheKey = function () {
    var args = Array.prototype.slice.call(arguments),
        glue = "!angular-highlightjs!";
    return args.join(glue);
  };
}]);

/**
 * hljs directive
 */
dirHljs = ['$compile', '$parse', function ($compile, $parse) {
  return {
    restrict: 'EA',
    controller: 'HljsCtrl',
    compile: function(tElm, tAttrs, transclude) {
      // get static code
      // strip the starting "new line" character
      var staticHTML = tElm[0].innerHTML.replace(/^(\r\n|\r|\n)/m, ''),
          staticText = tElm[0].textContent.replace(/^(\r\n|\r|\n)/m, '');

      // put template
      tElm.html('<pre><code class="hljs"></code></pre>');

      return function postLink(scope, iElm, iAttrs, ctrl) {
        var compileCheck, escapeCheck;

        if (angular.isDefined(iAttrs.compile)) {
          compileCheck = $parse(iAttrs.compile);
        }

        if (angular.isDefined(iAttrs.escape)) {
          escapeCheck = $parse(iAttrs.escape);
        } else if (angular.isDefined(iAttrs.noEscape)) {
          escapeCheck = $parse('false');
        }

        ctrl.init(iElm.find('code'));

        if (iAttrs.onhighlight) {
          ctrl.highlightCallback(function () {
            scope.$eval(iAttrs.onhighlight);
          });
        }

        if ((staticHTML || staticText) && shouldHighlightStatics(iAttrs)) {

          var code;

          // Auto-escape check
          // default to "true"
          if (escapeCheck && !escapeCheck(scope)) {
            code = staticText;
          }
          else {
            code = staticHTML;
          }

          ctrl.highlight(code);

          // Check if the highlight result needs to be compiled
          if (compileCheck && compileCheck(scope)) {
            // compile the new DOM and link it to the current scope.
            // NOTE: we only compile .childNodes so that
            // we don't get into infinite loop compiling ourselves
            $compile(iElm.find('code').contents())(scope);
          }
        }

        scope.$on('$destroy', function () {
          ctrl.release();
        });
      };
    }
  };
}];

/**
 * language directive
 */
dirLanguageFactory = function (dirName) {
  return [function () {
    return {
      require: '?hljs',
      restrict: 'A',
      link: function (scope, iElm, iAttrs, ctrl) {
        if (!ctrl) {
          return;
        }      
        iAttrs.$observe(dirName, function (lang) {
          if (angular.isDefined(lang)) {
            ctrl.setLanguage(lang);
          }
        });
      }
    };
  }];
};

/**
 * source directive
 */
dirSourceFactory = function (dirName) {
  return ['$compile', '$parse', function ($compile, $parse) {
    return {
      require: '?hljs',
      restrict: 'A',
      link: function(scope, iElm, iAttrs, ctrl) {
        var compileCheck;

        if (!ctrl) {
          return;
        }

        if (angular.isDefined(iAttrs.compile)) {
          compileCheck = $parse(iAttrs.compile);
        }

        scope.$watch(iAttrs[dirName], function (newCode, oldCode) {
          if (newCode) {
            ctrl.highlight(newCode);

            // Check if the highlight result needs to be compiled
            if (compileCheck && compileCheck(scope)) {
              // compile the new DOM and link it to the current scope.
              // NOTE: we only compile .childNodes so that
              // we don't get into infinite loop compiling ourselves
              $compile(iElm.find('code').contents())(scope);
            }
          }
          else {
            ctrl.clear();
          }
        });
      }
    };
  }];
};

/**
 * include directive
 */
dirIncludeFactory = function (dirName) {
  return [
             '$http', '$templateCache', '$q', '$compile', '$parse',
    function ($http,   $templateCache,   $q,   $compile,   $parse) {
      return {
        require: '?hljs',
        restrict: 'A',
        compile: function(tElm, tAttrs, transclude) {
          var srcExpr = tAttrs[dirName];

          return function postLink(scope, iElm, iAttrs, ctrl) {
            var changeCounter = 0, compileCheck;

            if (!ctrl) {
              return;
            }

            if (angular.isDefined(iAttrs.compile)) {
              compileCheck = $parse(iAttrs.compile);
            }

            scope.$watch(srcExpr, function (src) {
              var thisChangeId = ++changeCounter;

              if (src && angular.isString(src)) {
                var templateCachePromise, dfd;

                templateCachePromise = $templateCache.get(src);
                if (!templateCachePromise) {
                  dfd = $q.defer();
                  $http.get(src, {
                    cache: $templateCache,
                    transformResponse: function(data, headersGetter) {
                      // Return the raw string, so $http doesn't parse it
                      // if it's json.
                      return data;
                    }
                  }).success(function (code) {
                    if (thisChangeId !== changeCounter) {
                      return;
                    }
                    dfd.resolve(code);
                  }).error(function() {
                    if (thisChangeId === changeCounter) {
                      ctrl.clear();
                    }
                    dfd.resolve();
                  });
                  templateCachePromise = dfd.promise;
                }

                $q.when(templateCachePromise)
                .then(function (code) {
                  if (!code) {
                    return;
                  }

                  // $templateCache from $http
                  if (angular.isArray(code)) {
                    // 1.1.5
                    code = code[1];
                  }
                  else if (angular.isObject(code)) {
                    // 1.0.7
                    code = code.data;
                  }

                  code = code.replace(/^(\r\n|\r|\n)/m, '');
                  ctrl.highlight(code);

                  // Check if the highlight result needs to be compiled
                  if (compileCheck && compileCheck(scope)) {
                    // compile the new DOM and link it to the current scope.
                    // NOTE: we only compile .childNodes so that
                    // we don't get into infinite loop compiling ourselves
                    $compile(iElm.find('code').contents())(scope);
                  }
                });
              }
              else {
                ctrl.clear();
              }
            });
          };
        }
      };
  }];
};

module
.directive('hljs', dirHljs)
.directive('language', dirLanguageFactory('language'))
.directive('source', dirSourceFactory('source'))
.directive('include', dirIncludeFactory('include'));

})(angular.module('hljs', []));
/**
 * @license AngularJS v1.3.20
 * (c) 2010-2014 Google, Inc. http://angularjs.org
 * License: MIT
 */
(function(window, angular, undefined) {'use strict';

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *     Any commits to this file should be reviewed with security in mind.  *
 *   Changes to this file can potentially create security vulnerabilities. *
 *          An approval from 2 Core members with history of modifying      *
 *                         this file is required.                          *
 *                                                                         *
 *  Does the change somehow allow for arbitrary javascript to be executed? *
 *    Or allows for someone to change the prototype of built-in objects?   *
 *     Or gives undesired access to variables likes document or window?    *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var $sanitizeMinErr = angular.$$minErr('$sanitize');

/**
 * @ngdoc module
 * @name ngSanitize
 * @description
 *
 * # ngSanitize
 *
 * The `ngSanitize` module provides functionality to sanitize HTML.
 *
 *
 * <div doc-module-components="ngSanitize"></div>
 *
 * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
 */

/*
 * HTML Parser By Misko Hevery (misko@hevery.com)
 * based on:  HTML Parser By John Resig (ejohn.org)
 * Original code by Erik Arvidsson, Mozilla Public License
 * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
 *
 * // Use like so:
 * htmlParser(htmlString, {
 *     start: function(tag, attrs, unary) {},
 *     end: function(tag) {},
 *     chars: function(text) {},
 *     comment: function(text) {}
 * });
 *
 */


/**
 * @ngdoc service
 * @name $sanitize
 * @kind function
 *
 * @description
 *   The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are
 *   then serialized back to properly escaped html string. This means that no unsafe input can make
 *   it into the returned string, however, since our parser is more strict than a typical browser
 *   parser, it's possible that some obscure input, which would be recognized as valid HTML by a
 *   browser, won't make it through the sanitizer. The input may also contain SVG markup.
 *   The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
 *   `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
 *
 * @param {string} html HTML input.
 * @returns {string} Sanitized HTML.
 *
 * @example
   <example module="sanitizeExample" deps="angular-sanitize.js">
   <file name="index.html">
     <script>
         angular.module('sanitizeExample', ['ngSanitize'])
           .controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
             $scope.snippet =
               '<p style="color:blue">an html\n' +
               '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
               'snippet</p>';
             $scope.deliberatelyTrustDangerousSnippet = function() {
               return $sce.trustAsHtml($scope.snippet);
             };
           }]);
     </script>
     <div ng-controller="ExampleController">
        Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
       <table>
         <tr>
           <td>Directive</td>
           <td>How</td>
           <td>Source</td>
           <td>Rendered</td>
         </tr>
         <tr id="bind-html-with-sanitize">
           <td>ng-bind-html</td>
           <td>Automatically uses $sanitize</td>
           <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
           <td><div ng-bind-html="snippet"></div></td>
         </tr>
         <tr id="bind-html-with-trust">
           <td>ng-bind-html</td>
           <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
           <td>
           <pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
&lt;/div&gt;</pre>
           </td>
           <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
         </tr>
         <tr id="bind-default">
           <td>ng-bind</td>
           <td>Automatically escapes</td>
           <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
           <td><div ng-bind="snippet"></div></td>
         </tr>
       </table>
       </div>
   </file>
   <file name="protractor.js" type="protractor">
     it('should sanitize the html snippet by default', function() {
       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
         toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
     });

     it('should inline raw snippet if bound to a trusted value', function() {
       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
         toBe("<p style=\"color:blue\">an html\n" +
              "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
              "snippet</p>");
     });

     it('should escape snippet without any filter', function() {
       expect(element(by.css('#bind-default div')).getInnerHtml()).
         toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
              "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
              "snippet&lt;/p&gt;");
     });

     it('should update', function() {
       element(by.model('snippet')).clear();
       element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
         toBe('new <b>text</b>');
       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
         'new <b onclick="alert(1)">text</b>');
       expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
         "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
     });
   </file>
   </example>
 */
function $SanitizeProvider() {
  this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
    return function(html) {
      var buf = [];
      htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
        return !/^unsafe/.test($$sanitizeUri(uri, isImage));
      }));
      return buf.join('');
    };
  }];
}

function sanitizeText(chars) {
  var buf = [];
  var writer = htmlSanitizeWriter(buf, angular.noop);
  writer.chars(chars);
  return buf.join('');
}


// Regular Expressions for parsing tags and attributes
var START_TAG_REGEXP =
       /^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,
  END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/,
  ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
  BEGIN_TAG_REGEXP = /^</,
  BEGING_END_TAGE_REGEXP = /^<\//,
  COMMENT_REGEXP = /<!--(.*?)-->/g,
  DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
  CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
  SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
  // Match everything outside of normal chars and " (quote character)
  NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;


// Good source of info about elements and attributes
// http://dev.w3.org/html5/spec/Overview.html#semantics
// http://simon.html5.org/html-elements

// Safe Void Elements - HTML5
// http://dev.w3.org/html5/spec/Overview.html#void-elements
var voidElements = makeMap("area,br,col,hr,img,wbr");

// Elements that you can, intentionally, leave open (and which close themselves)
// http://dev.w3.org/html5/spec/Overview.html#optional-tags
var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
    optionalEndTagInlineElements = makeMap("rp,rt"),
    optionalEndTagElements = angular.extend({},
                                            optionalEndTagInlineElements,
                                            optionalEndTagBlockElements);

// Safe Block Elements - HTML5
var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
        "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
        "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));

// Inline Elements - HTML5
var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
        "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
        "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));

// SVG Elements
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
var svgElements = makeMap("animate,animateColor,animateMotion,animateTransform,circle,defs," +
        "desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient," +
        "line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set," +
        "stop,svg,switch,text,title,tspan,use");

// Special Elements (can contain anything)
var specialElements = makeMap("script,style");

var validElements = angular.extend({},
                                   voidElements,
                                   blockElements,
                                   inlineElements,
                                   optionalEndTagElements,
                                   svgElements);

//Attributes that have href and hence need to be sanitized
var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap,xlink:href");

var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
    'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
    'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
    'scope,scrolling,shape,size,span,start,summary,target,title,type,' +
    'valign,value,vspace,width');

// SVG attributes (without "id" and "name" attributes)
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
    'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,' +
    'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,' +
    'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,' +
    'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,' +
    'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,' +
    'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,' +
    'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,' +
    'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,' +
    'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,' +
    'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,' +
    'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,' +
    'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,' +
    'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,' +
    'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,' +
    'zoomAndPan');

var validAttrs = angular.extend({},
                                uriAttrs,
                                svgAttrs,
                                htmlAttrs);

function makeMap(str) {
  var obj = {}, items = str.split(','), i;
  for (i = 0; i < items.length; i++) obj[items[i]] = true;
  return obj;
}


/**
 * @example
 * htmlParser(htmlString, {
 *     start: function(tag, attrs, unary) {},
 *     end: function(tag) {},
 *     chars: function(text) {},
 *     comment: function(text) {}
 * });
 *
 * @param {string} html string
 * @param {object} handler
 */
function htmlParser(html, handler) {
  if (typeof html !== 'string') {
    if (html === null || typeof html === 'undefined') {
      html = '';
    } else {
      html = '' + html;
    }
  }
  var index, chars, match, stack = [], last = html, text;
  stack.last = function() { return stack[stack.length - 1]; };

  while (html) {
    text = '';
    chars = true;

    // Make sure we're not in a script or style element
    if (!stack.last() || !specialElements[stack.last()]) {

      // Comment
      if (html.indexOf("<!--") === 0) {
        // comments containing -- are not allowed unless they terminate the comment
        index = html.indexOf("--", 4);

        if (index >= 0 && html.lastIndexOf("-->", index) === index) {
          if (handler.comment) handler.comment(html.substring(4, index));
          html = html.substring(index + 3);
          chars = false;
        }
      // DOCTYPE
      } else if (DOCTYPE_REGEXP.test(html)) {
        match = html.match(DOCTYPE_REGEXP);

        if (match) {
          html = html.replace(match[0], '');
          chars = false;
        }
      // end tag
      } else if (BEGING_END_TAGE_REGEXP.test(html)) {
        match = html.match(END_TAG_REGEXP);

        if (match) {
          html = html.substring(match[0].length);
          match[0].replace(END_TAG_REGEXP, parseEndTag);
          chars = false;
        }

      // start tag
      } else if (BEGIN_TAG_REGEXP.test(html)) {
        match = html.match(START_TAG_REGEXP);

        if (match) {
          // We only have a valid start-tag if there is a '>'.
          if (match[4]) {
            html = html.substring(match[0].length);
            match[0].replace(START_TAG_REGEXP, parseStartTag);
          }
          chars = false;
        } else {
          // no ending tag found --- this piece should be encoded as an entity.
          text += '<';
          html = html.substring(1);
        }
      }

      if (chars) {
        index = html.indexOf("<");

        text += index < 0 ? html : html.substring(0, index);
        html = index < 0 ? "" : html.substring(index);

        if (handler.chars) handler.chars(decodeEntities(text));
      }

    } else {
      // IE versions 9 and 10 do not understand the regex '[^]', so using a workaround with [\W\w].
      html = html.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
        function(all, text) {
          text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");

          if (handler.chars) handler.chars(decodeEntities(text));

          return "";
      });

      parseEndTag("", stack.last());
    }

    if (html == last) {
      throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
                                        "of html: {0}", html);
    }
    last = html;
  }

  // Clean up any remaining tags
  parseEndTag();

  function parseStartTag(tag, tagName, rest, unary) {
    tagName = angular.lowercase(tagName);
    if (blockElements[tagName]) {
      while (stack.last() && inlineElements[stack.last()]) {
        parseEndTag("", stack.last());
      }
    }

    if (optionalEndTagElements[tagName] && stack.last() == tagName) {
      parseEndTag("", tagName);
    }

    unary = voidElements[tagName] || !!unary;

    if (!unary)
      stack.push(tagName);

    var attrs = {};

    rest.replace(ATTR_REGEXP,
      function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
        var value = doubleQuotedValue
          || singleQuotedValue
          || unquotedValue
          || '';

        attrs[name] = decodeEntities(value);
    });
    if (handler.start) handler.start(tagName, attrs, unary);
  }

  function parseEndTag(tag, tagName) {
    var pos = 0, i;
    tagName = angular.lowercase(tagName);
    if (tagName)
      // Find the closest opened tag of the same type
      for (pos = stack.length - 1; pos >= 0; pos--)
        if (stack[pos] == tagName)
          break;

    if (pos >= 0) {
      // Close all the open elements, up the stack
      for (i = stack.length - 1; i >= pos; i--)
        if (handler.end) handler.end(stack[i]);

      // Remove the open elements from the stack
      stack.length = pos;
    }
  }
}

var hiddenPre=document.createElement("pre");
/**
 * decodes all entities into regular string
 * @param value
 * @returns {string} A string with decoded entities.
 */
function decodeEntities(value) {
  if (!value) { return ''; }

  hiddenPre.innerHTML = value.replace(/</g,"&lt;");
  // innerText depends on styling as it doesn't display hidden elements.
  // Therefore, it's better to use textContent not to cause unnecessary reflows.
  return hiddenPre.textContent;
}

/**
 * Escapes all potentially dangerous characters, so that the
 * resulting string can be safely inserted into attribute or
 * element text.
 * @param value
 * @returns {string} escaped text
 */
function encodeEntities(value) {
  return value.
    replace(/&/g, '&amp;').
    replace(SURROGATE_PAIR_REGEXP, function(value) {
      var hi = value.charCodeAt(0);
      var low = value.charCodeAt(1);
      return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
    }).
    replace(NON_ALPHANUMERIC_REGEXP, function(value) {
      return '&#' + value.charCodeAt(0) + ';';
    }).
    replace(/</g, '&lt;').
    replace(/>/g, '&gt;');
}

/**
 * create an HTML/XML writer which writes to buffer
 * @param {Array} buf use buf.jain('') to get out sanitized html string
 * @returns {object} in the form of {
 *     start: function(tag, attrs, unary) {},
 *     end: function(tag) {},
 *     chars: function(text) {},
 *     comment: function(text) {}
 * }
 */
function htmlSanitizeWriter(buf, uriValidator) {
  var ignore = false;
  var out = angular.bind(buf, buf.push);
  return {
    start: function(tag, attrs, unary) {
      tag = angular.lowercase(tag);
      if (!ignore && specialElements[tag]) {
        ignore = tag;
      }
      if (!ignore && validElements[tag] === true) {
        out('<');
        out(tag);
        angular.forEach(attrs, function(value, key) {
          var lkey=angular.lowercase(key);
          var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
          if (validAttrs[lkey] === true &&
            (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
            out(' ');
            out(key);
            out('="');
            out(encodeEntities(value));
            out('"');
          }
        });
        out(unary ? '/>' : '>');
      }
    },
    end: function(tag) {
        tag = angular.lowercase(tag);
        if (!ignore && validElements[tag] === true) {
          out('</');
          out(tag);
          out('>');
        }
        if (tag == ignore) {
          ignore = false;
        }
      },
    chars: function(chars) {
        if (!ignore) {
          out(encodeEntities(chars));
        }
      }
  };
}


// define ngSanitize module and register $sanitize service
angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);

/* global sanitizeText: false */

/**
 * @ngdoc filter
 * @name linky
 * @kind function
 *
 * @description
 * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
 * plain email address links.
 *
 * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
 *
 * @param {string} text Input text.
 * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
 * @returns {string} Html-linkified text.
 *
 * @usage
   <span ng-bind-html="linky_expression | linky"></span>
 *
 * @example
   <example module="linkyExample" deps="angular-sanitize.js">
     <file name="index.html">
       <script>
         angular.module('linkyExample', ['ngSanitize'])
           .controller('ExampleController', ['$scope', function($scope) {
             $scope.snippet =
               'Pretty text with some links:\n'+
               'http://angularjs.org/,\n'+
               'mailto:us@somewhere.org,\n'+
               'another@somewhere.org,\n'+
               'and one more: ftp://127.0.0.1/.';
             $scope.snippetWithTarget = 'http://angularjs.org/';
           }]);
       </script>
       <div ng-controller="ExampleController">
       Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
       <table>
         <tr>
           <td>Filter</td>
           <td>Source</td>
           <td>Rendered</td>
         </tr>
         <tr id="linky-filter">
           <td>linky filter</td>
           <td>
             <pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
           </td>
           <td>
             <div ng-bind-html="snippet | linky"></div>
           </td>
         </tr>
         <tr id="linky-target">
          <td>linky target</td>
          <td>
            <pre>&lt;div ng-bind-html="snippetWithTarget | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
          </td>
          <td>
            <div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
          </td>
         </tr>
         <tr id="escaped-html">
           <td>no filter</td>
           <td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
           <td><div ng-bind="snippet"></div></td>
         </tr>
       </table>
     </file>
     <file name="protractor.js" type="protractor">
       it('should linkify the snippet with urls', function() {
         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
             toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
                  'another@somewhere.org, and one more: ftp://127.0.0.1/.');
         expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
       });

       it('should not linkify snippet without the linky filter', function() {
         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
             toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
                  'another@somewhere.org, and one more: ftp://127.0.0.1/.');
         expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
       });

       it('should update', function() {
         element(by.model('snippet')).clear();
         element(by.model('snippet')).sendKeys('new http://link.');
         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
             toBe('new http://link.');
         expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
             .toBe('new http://link.');
       });

       it('should work with the target property', function() {
        expect(element(by.id('linky-target')).
            element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
            toBe('http://angularjs.org/');
        expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
       });
     </file>
   </example>
 */
angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
  var LINKY_URL_REGEXP =
        /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"”’]/i,
      MAILTO_REGEXP = /^mailto:/i;

  return function(text, target) {
    if (!text) return text;
    var match;
    var raw = text;
    var html = [];
    var url;
    var i;
    while ((match = raw.match(LINKY_URL_REGEXP))) {
      // We can not end in these as they are sometimes found at the end of the sentence
      url = match[0];
      // if we did not match ftp/http/www/mailto then assume mailto
      if (!match[2] && !match[4]) {
        url = (match[3] ? 'http://' : 'mailto:') + url;
      }
      i = match.index;
      addText(raw.substr(0, i));
      addLink(url, match[0].replace(MAILTO_REGEXP, ''));
      raw = raw.substring(i + match[0].length);
    }
    addText(raw);
    return $sanitize(html.join(''));

    function addText(text) {
      if (!text) {
        return;
      }
      html.push(sanitizeText(text));
    }

    function addLink(url, text) {
      html.push('<a ');
      if (angular.isDefined(target)) {
        html.push('target="',
                  target,
                  '" ');
      }
      html.push('href="',
                url.replace(/"/g, '&quot;'),
                '">');
      addText(text);
      html.push('</a>');
    }
  };
}]);


})(window, window.angular);

/**

JSZip - A Javascript class for generating and reading zip files
<http://stuartk.com/jszip>

(c) 2009-2012 Stuart Knightley <stuart [at] stuartk.com>
Dual licenced under the MIT license or GPLv3. See LICENSE.markdown.

Usage:
   zip = new JSZip();
   zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing");
   zip.folder("images").file("smile.gif", base64Data, {base64: true});
   zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")});
   zip.remove("tempfile");

   base64zip = zip.generate();

**/
// We use strict, but it should not be placed outside of a function because
// the environment is shared inside the browser.
// "use strict";

/**
 * Representation a of zip file in js
 * @constructor
 * @param {String=|ArrayBuffer=|Uint8Array=|Buffer=} data the data to load, if any (optional).
 * @param {Object=} options the options for creating this objects (optional).
 */
var JSZip = function(data, options) {
   // object containing the files :
   // {
   //   "folder/" : {...},
   //   "folder/data.txt" : {...}
   // }
   this.files = {};

   // Where we are in the hierarchy
   this.root = "";

   if (data) {
      this.load(data, options);
   }
};

JSZip.signature = {
   LOCAL_FILE_HEADER : "\x50\x4b\x03\x04",
   CENTRAL_FILE_HEADER : "\x50\x4b\x01\x02",
   CENTRAL_DIRECTORY_END : "\x50\x4b\x05\x06",
   ZIP64_CENTRAL_DIRECTORY_LOCATOR : "\x50\x4b\x06\x07",
   ZIP64_CENTRAL_DIRECTORY_END : "\x50\x4b\x06\x06",
   DATA_DESCRIPTOR : "\x50\x4b\x07\x08"
};

// Default properties for a new file
JSZip.defaults = {
   base64: false,
   binary: false,
   dir: false,
   date: null,
   compression: null
};

/*
 * List features that require a modern browser, and if the current browser support them.
 */
JSZip.support = {
   // contains true if JSZip can read/generate ArrayBuffer, false otherwise.
   arraybuffer : (function(){
      return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
   })(),
   // contains true if JSZip can read/generate nodejs Buffer, false otherwise.
   nodebuffer : (function(){
      return typeof Buffer !== "undefined";
   })(),
   // contains true if JSZip can read/generate Uint8Array, false otherwise.
   uint8array : (function(){
      return typeof Uint8Array !== "undefined";
   })(),
   // contains true if JSZip can read/generate Blob, false otherwise.
   blob : (function(){
      // the spec started with BlobBuilder then replaced it with a construtor for Blob.
      // Result : we have browsers that :
      // * know the BlobBuilder (but with prefix)
      // * know the Blob constructor
      // * know about Blob but not about how to build them
      // About the "=== 0" test : if given the wrong type, it may be converted to a string.
      // Instead of an empty content, we will get "[object Uint8Array]" for example.
      if (typeof ArrayBuffer === "undefined") {
         return false;
      }
      var buffer = new ArrayBuffer(0);
      try {
         return new Blob([buffer], { type: "application/zip" }).size === 0;
      }
      catch(e) {}

      try {
         var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
         var builder = new BlobBuilder();
         builder.append(buffer);
         return builder.getBlob('application/zip').size === 0;
      }
      catch(e) {}

      return false;
   })()
};

JSZip.prototype = (function () {
   var textEncoder, textDecoder;
   if (
      JSZip.support.uint8array &&
      typeof TextEncoder === "function" &&
      typeof TextDecoder === "function"
   ) {
      textEncoder = new TextEncoder("utf-8");
      textDecoder = new TextDecoder("utf-8");
   }

   /**
    * Returns the raw data of a ZipObject, decompress the content if necessary.
    * @param {ZipObject} file the file to use.
    * @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
    */
   var getRawData = function (file) {
      if (file._data instanceof JSZip.CompressedObject) {
         file._data = file._data.getContent();
         file.options.binary = true;
         file.options.base64 = false;

         if (JSZip.utils.getTypeOf(file._data) === "uint8array") {
            var copy = file._data;
            // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array.
            // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file).
            file._data = new Uint8Array(copy.length);
            // with an empty Uint8Array, Opera fails with a "Offset larger than array size"
            if (copy.length !== 0) {
               file._data.set(copy, 0);
            }
         }
      }
      return file._data;
   };

   /**
    * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it.
    * @param {ZipObject} file the file to use.
    * @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
    */
   var getBinaryData = function (file) {
      var result = getRawData(file), type = JSZip.utils.getTypeOf(result);
      if (type === "string") {
         if (!file.options.binary) {
            // unicode text !
            // unicode string => binary string is a painful process, check if we can avoid it.
            if (textEncoder) {
               return textEncoder.encode(result);
            }
            if (JSZip.support.nodebuffer) {
               return new Buffer(result, "utf-8");
            }
         }
         return file.asBinary();
      }
      return result;
   };

   /**
    * Transform this._data into a string.
    * @param {function} filter a function String -> String, applied if not null on the result.
    * @return {String} the string representing this._data.
    */
   var dataToString = function (asUTF8) {
      var result = getRawData(this);
      if (result === null || typeof result === "undefined") {
         return "";
      }
      // if the data is a base64 string, we decode it before checking the encoding !
      if (this.options.base64) {
         result = JSZip.base64.decode(result);
      }
      if (asUTF8 && this.options.binary) {
         // JSZip.prototype.utf8decode supports arrays as input
         // skip to array => string step, utf8decode will do it.
         result = JSZip.prototype.utf8decode(result);
      } else {
         // no utf8 transformation, do the array => string step.
         result = JSZip.utils.transformTo("string", result);
      }

      if (!asUTF8 && !this.options.binary) {
         result = JSZip.prototype.utf8encode(result);
      }
      return result;
   };
   /**
    * A simple object representing a file in the zip file.
    * @constructor
    * @param {string} name the name of the file
    * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
    * @param {Object} options the options of the file
    */
   var ZipObject = function (name, data, options) {
      this.name = name;
      this._data = data;
      this.options = options;
   };

   ZipObject.prototype = {
      /**
       * Return the content as UTF8 string.
       * @return {string} the UTF8 string.
       */
      asText : function () {
         return dataToString.call(this, true);
      },
      /**
       * Returns the binary content.
       * @return {string} the content as binary.
       */
      asBinary : function () {
         return dataToString.call(this, false);
      },
      /**
       * Returns the content as a nodejs Buffer.
       * @return {Buffer} the content as a Buffer.
       */
      asNodeBuffer : function () {
         var result = getBinaryData(this);
         return JSZip.utils.transformTo("nodebuffer", result);
      },
      /**
       * Returns the content as an Uint8Array.
       * @return {Uint8Array} the content as an Uint8Array.
       */
      asUint8Array : function () {
         var result = getBinaryData(this);
         return JSZip.utils.transformTo("uint8array", result);
      },
      /**
       * Returns the content as an ArrayBuffer.
       * @return {ArrayBuffer} the content as an ArrayBufer.
       */
      asArrayBuffer : function () {
         return this.asUint8Array().buffer;
      }
   };

   /**
    * Transform an integer into a string in hexadecimal.
    * @private
    * @param {number} dec the number to convert.
    * @param {number} bytes the number of bytes to generate.
    * @returns {string} the result.
    */
   var decToHex = function(dec, bytes) {
      var hex = "", i;
      for(i = 0; i < bytes; i++) {
         hex += String.fromCharCode(dec&0xff);
         dec=dec>>>8;
      }
      return hex;
   };

   /**
    * Merge the objects passed as parameters into a new one.
    * @private
    * @param {...Object} var_args All objects to merge.
    * @return {Object} a new object with the data of the others.
    */
   var extend = function () {
      var result = {}, i, attr;
      for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers
         for (attr in arguments[i]) {
            if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {
               result[attr] = arguments[i][attr];
            }
         }
      }
      return result;
   };

   /**
    * Transforms the (incomplete) options from the user into the complete
    * set of options to create a file.
    * @private
    * @param {Object} o the options from the user.
    * @return {Object} the complete set of options.
    */
   var prepareFileAttrs = function (o) {
      o = o || {};
      /*jshint -W041 */
      if (o.base64 === true && o.binary == null) {
         o.binary = true;
      }
      /*jshint +W041 */
      o = extend(o, JSZip.defaults);
      o.date = o.date || new Date();
      if (o.compression !== null) o.compression = o.compression.toUpperCase();

      return o;
   };

   /**
    * Add a file in the current folder.
    * @private
    * @param {string} name the name of the file
    * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
    * @param {Object} o the options of the file
    * @return {Object} the new file.
    */
   var fileAdd = function (name, data, o) {
      // be sure sub folders exist
      var parent = parentFolder(name), dataType = JSZip.utils.getTypeOf(data);
      if (parent) {
         folderAdd.call(this, parent);
      }

      o = prepareFileAttrs(o);

      if (o.dir || data === null || typeof data === "undefined") {
         o.base64 = false;
         o.binary = false;
         data = null;
      } else if (dataType === "string") {
         if (o.binary && !o.base64) {
            // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask
            if (o.optimizedBinaryString !== true) {
               // this is a string, not in a base64 format.
               // Be sure that this is a correct "binary string"
               data = JSZip.utils.string2binary(data);
            }
         }
      } else { // arraybuffer, uint8array, ...
         o.base64 = false;
         o.binary = true;

         if (!dataType && !(data instanceof JSZip.CompressedObject)) {
            throw new Error("The data of '" + name + "' is in an unsupported format !");
         }

         // special case : it's way easier to work with Uint8Array than with ArrayBuffer
         if (dataType === "arraybuffer") {
            data = JSZip.utils.transformTo("uint8array", data);
         }
      }

      var object = new ZipObject(name, data, o);
      this.files[name] = object;
      return object;
   };


   /**
    * Find the parent folder of the path.
    * @private
    * @param {string} path the path to use
    * @return {string} the parent folder, or ""
    */
   var parentFolder = function (path) {
      if (path.slice(-1) == '/') {
         path = path.substring(0, path.length - 1);
      }
      var lastSlash = path.lastIndexOf('/');
      return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
   };

   /**
    * Add a (sub) folder in the current folder.
    * @private
    * @param {string} name the folder's name
    * @return {Object} the new folder.
    */
   var folderAdd = function (name) {
      // Check the name ends with a /
      if (name.slice(-1) != "/") {
         name += "/"; // IE doesn't like substr(-1)
      }

      // Does this folder already exist?
      if (!this.files[name]) {
         fileAdd.call(this, name, null, {dir:true});
      }
      return this.files[name];
   };

   /**
    * Generate a JSZip.CompressedObject for a given zipOject.
    * @param {ZipObject} file the object to read.
    * @param {JSZip.compression} compression the compression to use.
    * @return {JSZip.CompressedObject} the compressed result.
    */
   var generateCompressedObjectFrom = function (file, compression) {
      var result = new JSZip.CompressedObject(), content;

      // the data has not been decompressed, we might reuse things !
      if (file._data instanceof JSZip.CompressedObject) {
         result.uncompressedSize = file._data.uncompressedSize;
         result.crc32 = file._data.crc32;

         if (result.uncompressedSize === 0 || file.options.dir) {
            compression = JSZip.compressions['STORE'];
            result.compressedContent = "";
            result.crc32 = 0;
         } else if (file._data.compressionMethod === compression.magic) {
            result.compressedContent = file._data.getCompressedContent();
         } else {
            content = file._data.getContent();
            // need to decompress / recompress
            result.compressedContent = compression.compress(JSZip.utils.transformTo(compression.compressInputType, content));
         }
      } else {
         // have uncompressed data
         content = getBinaryData(file);
         if (!content || content.length === 0 || file.options.dir) {
            compression = JSZip.compressions['STORE'];
            content = "";
         }
         result.uncompressedSize = content.length;
         result.crc32 = this.crc32(content);
         result.compressedContent = compression.compress(JSZip.utils.transformTo(compression.compressInputType, content));
      }

      result.compressedSize = result.compressedContent.length;
      result.compressionMethod = compression.magic;

      return result;
   };

   /**
    * Generate the various parts used in the construction of the final zip file.
    * @param {string} name the file name.
    * @param {ZipObject} file the file content.
    * @param {JSZip.CompressedObject} compressedObject the compressed object.
    * @param {number} offset the current offset from the start of the zip file.
    * @return {object} the zip parts.
    */
   var generateZipParts = function(name, file, compressedObject, offset) {
      var data = compressedObject.compressedContent,
          utfEncodedFileName = this.utf8encode(file.name),
          useUTF8 = utfEncodedFileName !== file.name,
          o       = file.options,
          dosTime,
          dosDate;

      // date
      // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
      // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
      // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html

      dosTime = o.date.getHours();
      dosTime = dosTime << 6;
      dosTime = dosTime | o.date.getMinutes();
      dosTime = dosTime << 5;
      dosTime = dosTime | o.date.getSeconds() / 2;

      dosDate = o.date.getFullYear() - 1980;
      dosDate = dosDate << 4;
      dosDate = dosDate | (o.date.getMonth() + 1);
      dosDate = dosDate << 5;
      dosDate = dosDate | o.date.getDate();


      var header = "";

      // version needed to extract
      header += "\x0A\x00";
      // general purpose bit flag
      // set bit 11 if utf8
      header += useUTF8 ? "\x00\x08" : "\x00\x00";
      // compression method
      header += compressedObject.compressionMethod;
      // last mod file time
      header += decToHex(dosTime, 2);
      // last mod file date
      header += decToHex(dosDate, 2);
      // crc-32
      header += decToHex(compressedObject.crc32, 4);
      // compressed size
      header += decToHex(compressedObject.compressedSize, 4);
      // uncompressed size
      header += decToHex(compressedObject.uncompressedSize, 4);
      // file name length
      header += decToHex(utfEncodedFileName.length, 2);
      // extra field length
      header += "\x00\x00";


      var fileRecord = JSZip.signature.LOCAL_FILE_HEADER + header + utfEncodedFileName;

      var dirRecord = JSZip.signature.CENTRAL_FILE_HEADER +
      // version made by (00: DOS)
      "\x14\x00" +
      // file header (common to file and central directory)
      header +
      // file comment length
      "\x00\x00" +
      // disk number start
      "\x00\x00" +
      // internal file attributes TODO
      "\x00\x00" +
      // external file attributes
      (file.options.dir===true?"\x10\x00\x00\x00":"\x00\x00\x00\x00")+
      // relative offset of local header
      decToHex(offset, 4) +
      // file name
      utfEncodedFileName;


      return {
         fileRecord : fileRecord,
         dirRecord : dirRecord,
         compressedObject : compressedObject
      };
   };

   /**
    * An object to write any content to a string.
    * @constructor
    */
   var StringWriter = function () {
      this.data = [];
   };
   StringWriter.prototype = {
      /**
       * Append any content to the current string.
       * @param {Object} input the content to add.
       */
      append : function (input) {
         input = JSZip.utils.transformTo("string", input);
         this.data.push(input);
      },
      /**
       * Finalize the construction an return the result.
       * @return {string} the generated string.
       */
      finalize : function () {
         return this.data.join("");
      }
   };
   /**
    * An object to write any content to an Uint8Array.
    * @constructor
    * @param {number} length The length of the array.
    */
   var Uint8ArrayWriter = function (length) {
      this.data = new Uint8Array(length);
      this.index = 0;
   };
   Uint8ArrayWriter.prototype = {
      /**
       * Append any content to the current array.
       * @param {Object} input the content to add.
       */
      append : function (input) {
         if (input.length !== 0) {
            // with an empty Uint8Array, Opera fails with a "Offset larger than array size"
            input = JSZip.utils.transformTo("uint8array", input);
            this.data.set(input, this.index);
            this.index += input.length;
         }
      },
      /**
       * Finalize the construction an return the result.
       * @return {Uint8Array} the generated array.
       */
      finalize : function () {
         return this.data;
      }
   };

   // return the actual prototype of JSZip
   return {
      /**
       * Read an existing zip and merge the data in the current JSZip object.
       * The implementation is in jszip-load.js, don't forget to include it.
       * @param {String|ArrayBuffer|Uint8Array|Buffer} stream  The stream to load
       * @param {Object} options Options for loading the stream.
       *  options.base64 : is the stream in base64 ? default : false
       * @return {JSZip} the current JSZip object
       */
      load : function (stream, options) {
         throw new Error("Load method is not defined. Is the file jszip-load.js included ?");
      },

      /**
       * Filter nested files/folders with the specified function.
       * @param {Function} search the predicate to use :
       * function (relativePath, file) {...}
       * It takes 2 arguments : the relative path and the file.
       * @return {Array} An array of matching elements.
       */
      filter : function (search) {
         var result = [], filename, relativePath, file, fileClone;
         for (filename in this.files) {
            if ( !this.files.hasOwnProperty(filename) ) { continue; }
            file = this.files[filename];
            // return a new object, don't let the user mess with our internal objects :)
            fileClone = new ZipObject(file.name, file._data, extend(file.options));
            relativePath = filename.slice(this.root.length, filename.length);
            if (filename.slice(0, this.root.length) === this.root && // the file is in the current root
                search(relativePath, fileClone)) { // and the file matches the function
               result.push(fileClone);
            }
         }
         return result;
      },

      /**
       * Add a file to the zip file, or search a file.
       * @param   {string|RegExp} name The name of the file to add (if data is defined),
       * the name of the file to find (if no data) or a regex to match files.
       * @param   {String|ArrayBuffer|Uint8Array|Buffer} data  The file data, either raw or base64 encoded
       * @param   {Object} o     File options
       * @return  {JSZip|Object|Array} this JSZip object (when adding a file),
       * a file (when searching by string) or an array of files (when searching by regex).
       */
      file : function(name, data, o) {
         if (arguments.length === 1) {
            if (JSZip.utils.isRegExp(name)) {
               var regexp = name;
               return this.filter(function(relativePath, file) {
                  return !file.options.dir && regexp.test(relativePath);
               });
            } else { // text
               return this.filter(function (relativePath, file) {
                  return !file.options.dir && relativePath === name;
               })[0]||null;
            }
         } else { // more than one argument : we have data !
            name = this.root+name;
            fileAdd.call(this, name, data, o);
         }
         return this;
      },

      /**
       * Add a directory to the zip file, or search.
       * @param   {String|RegExp} arg The name of the directory to add, or a regex to search folders.
       * @return  {JSZip} an object with the new directory as the root, or an array containing matching folders.
       */
      folder : function(arg) {
         if (!arg) {
            return this;
         }

         if (JSZip.utils.isRegExp(arg)) {
            return this.filter(function(relativePath, file) {
               return file.options.dir && arg.test(relativePath);
            });
         }

         // else, name is a new folder
         var name = this.root + arg;
         var newFolder = folderAdd.call(this, name);

         // Allow chaining by returning a new object with this folder as the root
         var ret = this.clone();
         ret.root = newFolder.name;
         return ret;
      },

      /**
       * Delete a file, or a directory and all sub-files, from the zip
       * @param {string} name the name of the file to delete
       * @return {JSZip} this JSZip object
       */
      remove : function(name) {
         name = this.root + name;
         var file = this.files[name];
         if (!file) {
            // Look for any folders
            if (name.slice(-1) != "/") {
               name += "/";
            }
            file = this.files[name];
         }

         if (file) {
            if (!file.options.dir) {
               // file
               delete this.files[name];
            } else {
               // folder
               var kids = this.filter(function (relativePath, file) {
                  return file.name.slice(0, name.length) === name;
               });
               for (var i = 0; i < kids.length; i++) {
                  delete this.files[kids[i].name];
               }
            }
         }

         return this;
      },

      /**
       * Generate the complete zip file
       * @param {Object} options the options to generate the zip file :
       * - base64, (deprecated, use type instead) true to generate base64.
       * - compression, "STORE" by default.
       * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
       * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
       */
      generate : function(options) {
         options = extend(options || {}, {
            base64 : true,
            compression : "STORE",
            type : "base64"
         });

         JSZip.utils.checkSupport(options.type);

         var zipData = [], localDirLength = 0, centralDirLength = 0, writer, i;


         // first, generate all the zip parts.
         for (var name in this.files) {
            if ( !this.files.hasOwnProperty(name) ) { continue; }
            var file = this.files[name];

            var compressionName = file.options.compression || options.compression.toUpperCase();
            var compression = JSZip.compressions[compressionName];
            if (!compression) {
               throw new Error(compressionName + " is not a valid compression method !");
            }

            var compressedObject = generateCompressedObjectFrom.call(this, file, compression);

            var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength);
            localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize;
            centralDirLength += zipPart.dirRecord.length;
            zipData.push(zipPart);
         }

         var dirEnd = "";

         // end of central dir signature
         dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END +
         // number of this disk
         "\x00\x00" +
         // number of the disk with the start of the central directory
         "\x00\x00" +
         // total number of entries in the central directory on this disk
         decToHex(zipData.length, 2) +
         // total number of entries in the central directory
         decToHex(zipData.length, 2) +
         // size of the central directory   4 bytes
         decToHex(centralDirLength, 4) +
         // offset of start of central directory with respect to the starting disk number
         decToHex(localDirLength, 4) +
         // .ZIP file comment length
         "\x00\x00";


         // we have all the parts (and the total length)
         // time to create a writer !
         switch(options.type.toLowerCase()) {
            case "uint8array" :
            case "arraybuffer" :
            case "blob" :
            case "nodebuffer" :
               writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length);
               break;
            // case "base64" :
            // case "string" :
            default :
               writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length);
               break;
         }

         for (i = 0; i < zipData.length; i++) {
            writer.append(zipData[i].fileRecord);
            writer.append(zipData[i].compressedObject.compressedContent);
         }
         for (i = 0; i < zipData.length; i++) {
            writer.append(zipData[i].dirRecord);
         }

         writer.append(dirEnd);

         var zip = writer.finalize();



         switch(options.type.toLowerCase()) {
            // case "zip is an Uint8Array"
            case "uint8array" :
            case "arraybuffer" :
            case "nodebuffer" :
               return JSZip.utils.transformTo(options.type.toLowerCase(), zip);
            case "blob" :
               return JSZip.utils.arrayBuffer2Blob(JSZip.utils.transformTo("arraybuffer", zip));

            // case "zip is a string"
            case "base64" :
               return (options.base64) ? JSZip.base64.encode(zip) : zip;
            default : // case "string" :
               return zip;
         }
      },

      /**
       *
       *  Javascript crc32
       *  http://www.webtoolkit.info/
       *
       */
      crc32 : function crc32(input, crc) {
         if (typeof input === "undefined" || !input.length) {
            return 0;
         }

         var isArray = JSZip.utils.getTypeOf(input) !== "string";

         var table = [
            0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
            0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
            0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
            0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
            0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
            0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
            0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
            0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
            0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
            0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
            0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
            0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
            0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
            0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
            0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
            0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
            0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
            0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
            0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
            0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
            0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
            0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
            0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
            0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
            0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
            0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
            0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
            0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
            0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
            0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
            0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
            0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
            0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
            0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
            0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
            0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
            0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
            0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
            0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
            0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
            0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
            0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
            0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
            0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
            0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
            0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
            0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
            0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
            0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
            0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
            0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
            0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
            0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
            0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
            0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
            0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
            0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
            0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
            0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
            0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
            0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
            0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
            0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
            0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
         ];

         if (typeof(crc) == "undefined") { crc = 0; }
         var x = 0;
         var y = 0;
         var byte = 0;

         crc = crc ^ (-1);
         for( var i = 0, iTop = input.length; i < iTop; i++ ) {
            byte = isArray ? input[i] : input.charCodeAt(i);
            y = ( crc ^ byte ) & 0xFF;
            x = table[y];
            crc = ( crc >>> 8 ) ^ x;
         }

         return crc ^ (-1);
      },

      // Inspired by http://my.opera.com/GreyWyvern/blog/show.dml/1725165
      clone : function() {
         var newObj = new JSZip();
         for (var i in this) {
            if (typeof this[i] !== "function") {
               newObj[i] = this[i];
            }
         }
         return newObj;
      },


      /**
       * http://www.webtoolkit.info/javascript-utf8.html
       */
      utf8encode : function (string) {
         // TextEncoder + Uint8Array to binary string is faster than checking every bytes on long strings.
         // http://jsperf.com/utf8encode-vs-textencoder
         // On short strings (file names for example), the TextEncoder API is (currently) slower.
         if (textEncoder) {
            var u8 = textEncoder.encode(string);
            return JSZip.utils.transformTo("string", u8);
         }
         if (JSZip.support.nodebuffer) {
            return JSZip.utils.transformTo("string", new Buffer(string, "utf-8"));
         }

         // array.join may be slower than string concatenation but generates less objects (less time spent garbage collecting).
         // See also http://jsperf.com/array-direct-assignment-vs-push/31
         var result = [], resIndex = 0;

         for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
               result[resIndex++] = String.fromCharCode(c);
            } else if ((c > 127) && (c < 2048)) {
               result[resIndex++] = String.fromCharCode((c >> 6) | 192);
               result[resIndex++] = String.fromCharCode((c & 63) | 128);
            } else {
               result[resIndex++] = String.fromCharCode((c >> 12) | 224);
               result[resIndex++] = String.fromCharCode(((c >> 6) & 63) | 128);
               result[resIndex++] = String.fromCharCode((c & 63) | 128);
            }

         }

         return result.join("");
      },

      /**
       * http://www.webtoolkit.info/javascript-utf8.html
       */
      utf8decode : function (input) {
         var result = [], resIndex = 0;
         var type = JSZip.utils.getTypeOf(input);
         var isArray = type !== "string";
         var i = 0;
         var c = 0, c1 = 0, c2 = 0, c3 = 0;

         // check if we can use the TextDecoder API
         // see http://encoding.spec.whatwg.org/#api
         if (textDecoder) {
            return textDecoder.decode(
               JSZip.utils.transformTo("uint8array", input)
            );
         }
         if (JSZip.support.nodebuffer) {
            return JSZip.utils.transformTo("nodebuffer", input).toString("utf-8");
         }

         while ( i < input.length ) {

            c = isArray ? input[i] : input.charCodeAt(i);

            if (c < 128) {
               result[resIndex++] = String.fromCharCode(c);
               i++;
            } else if ((c > 191) && (c < 224)) {
               c2 = isArray ? input[i+1] : input.charCodeAt(i+1);
               result[resIndex++] = String.fromCharCode(((c & 31) << 6) | (c2 & 63));
               i += 2;
            } else {
               c2 = isArray ? input[i+1] : input.charCodeAt(i+1);
               c3 = isArray ? input[i+2] : input.charCodeAt(i+2);
               result[resIndex++] = String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
               i += 3;
            }

         }

         return result.join("");
      }
   };
}());

/*
 * Compression methods
 * This object is filled in as follow :
 * name : {
 *    magic // the 2 bytes indentifying the compression method
 *    compress // function, take the uncompressed content and return it compressed.
 *    uncompress // function, take the compressed content and return it uncompressed.
 *    compressInputType // string, the type accepted by the compress method. null to accept everything.
 *    uncompressInputType // string, the type accepted by the uncompress method. null to accept everything.
 * }
 *
 * STORE is the default compression method, so it's included in this file.
 * Other methods should go to separated files : the user wants modularity.
 */
JSZip.compressions = {
   "STORE" : {
      magic : "\x00\x00",
      compress : function (content) {
         return content; // no compression
      },
      uncompress : function (content) {
         return content; // no compression
      },
      compressInputType : null,
      uncompressInputType : null
   }
};

(function () {
   JSZip.utils = {
      /**
       * Convert a string to a "binary string" : a string containing only char codes between 0 and 255.
       * @param {string} str the string to transform.
       * @return {String} the binary string.
       */
      string2binary : function (str) {
         var result = "";
         for (var i = 0; i < str.length; i++) {
            result += String.fromCharCode(str.charCodeAt(i) & 0xff);
         }
         return result;
      },
      /**
       * Create a Uint8Array from the string.
       * @param {string} str the string to transform.
       * @return {Uint8Array} the typed array.
       * @throws {Error} an Error if the browser doesn't support the requested feature.
       * @deprecated : use JSZip.utils.transformTo instead.
       */
      string2Uint8Array : function (str) {
         return JSZip.utils.transformTo("uint8array", str);
      },

      /**
       * Create a string from the Uint8Array.
       * @param {Uint8Array} array the array to transform.
       * @return {string} the string.
       * @throws {Error} an Error if the browser doesn't support the requested feature.
       * @deprecated : use JSZip.utils.transformTo instead.
       */
      uint8Array2String : function (array) {
         return JSZip.utils.transformTo("string", array);
      },
      /**
       * Create a blob from the given ArrayBuffer.
       * @param {ArrayBuffer} buffer the buffer to transform.
       * @return {Blob} the result.
       * @throws {Error} an Error if the browser doesn't support the requested feature.
       */
      arrayBuffer2Blob : function (buffer) {
         JSZip.utils.checkSupport("blob");

         try {
            // Blob constructor
            return new Blob([buffer], { type: "application/zip" });
         }
         catch(e) {}

         try {
            // deprecated, browser only, old way
            var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
            var builder = new BlobBuilder();
            builder.append(buffer);
            return builder.getBlob('application/zip');
         }
         catch(e) {}

         // well, fuck ?!
         throw new Error("Bug : can't construct the Blob.");
      },
      /**
       * Create a blob from the given string.
       * @param {string} str the string to transform.
       * @return {Blob} the result.
       * @throws {Error} an Error if the browser doesn't support the requested feature.
       */
      string2Blob : function (str) {
         var buffer = JSZip.utils.transformTo("arraybuffer", str);
         return JSZip.utils.arrayBuffer2Blob(buffer);
      }
   };

   /**
    * The identity function.
    * @param {Object} input the input.
    * @return {Object} the same input.
    */
   function identity(input) {
      return input;
   }

   /**
    * Fill in an array with a string.
    * @param {String} str the string to use.
    * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated).
    * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array.
    */
   function stringToArrayLike(str, array) {
      for (var i = 0; i < str.length; ++i) {
         array[i] = str.charCodeAt(i) & 0xFF;
      }
      return array;
   }

   /**
    * Transform an array-like object to a string.
    * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
    * @return {String} the result.
    */
   function arrayLikeToString(array) {
      // Performances notes :
      // --------------------
      // String.fromCharCode.apply(null, array) is the fastest, see
      // see http://jsperf.com/converting-a-uint8array-to-a-string/2
      // but the stack is limited (and we can get huge arrays !).
      //
      // result += String.fromCharCode(array[i]); generate too many strings !
      //
      // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2
      var chunk = 65536;
      var result = [], len = array.length, type = JSZip.utils.getTypeOf(array), k = 0;

      var canUseApply = true;
      try {
         switch(type) {
            case "uint8array":
               String.fromCharCode.apply(null, new Uint8Array(0));
               break;
            case "nodebuffer":
               String.fromCharCode.apply(null, new Buffer(0));
               break;
         }
      } catch(e) {
         canUseApply = false;
      }

      // no apply : slow and painful algorithm
      // default browser on android 4.*
      if (!canUseApply) {
         var resultStr = "";
         for(var i = 0; i < array.length;i++) {
            resultStr += String.fromCharCode(array[i]);
         }
         return resultStr;
      }

      while (k < len && chunk > 1) {
         try {
            if (type === "array" || type === "nodebuffer") {
               result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len))));
            } else {
               result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len))));
            }
            k += chunk;
         } catch (e) {
            chunk = Math.floor(chunk / 2);
         }
      }
      return result.join("");
   }

   /**
    * Copy the data from an array-like to an other array-like.
    * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array.
    * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated.
    * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array.
    */
   function arrayLikeToArrayLike(arrayFrom, arrayTo) {
      for(var i = 0; i < arrayFrom.length; i++) {
         arrayTo[i] = arrayFrom[i];
      }
      return arrayTo;
   }

   // a matrix containing functions to transform everything into everything.
   var transform = {};

   // string to ?
   transform["string"] = {
      "string" : identity,
      "array" : function (input) {
         return stringToArrayLike(input, new Array(input.length));
      },
      "arraybuffer" : function (input) {
         return transform["string"]["uint8array"](input).buffer;
      },
      "uint8array" : function (input) {
         return stringToArrayLike(input, new Uint8Array(input.length));
      },
      "nodebuffer" : function (input) {
         return stringToArrayLike(input, new Buffer(input.length));
      }
   };

   // array to ?
   transform["array"] = {
      "string" : arrayLikeToString,
      "array" : identity,
      "arraybuffer" : function (input) {
         return (new Uint8Array(input)).buffer;
      },
      "uint8array" : function (input) {
         return new Uint8Array(input);
      },
      "nodebuffer" : function (input) {
         return new Buffer(input);
      }
   };

   // arraybuffer to ?
   transform["arraybuffer"] = {
      "string" : function (input) {
         return arrayLikeToString(new Uint8Array(input));
      },
      "array" : function (input) {
         return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength));
      },
      "arraybuffer" : identity,
      "uint8array" : function (input) {
         return new Uint8Array(input);
      },
      "nodebuffer" : function (input) {
         return new Buffer(new Uint8Array(input));
      }
   };

   // uint8array to ?
   transform["uint8array"] = {
      "string" : arrayLikeToString,
      "array" : function (input) {
         return arrayLikeToArrayLike(input, new Array(input.length));
      },
      "arraybuffer" : function (input) {
         return input.buffer;
      },
      "uint8array" : identity,
      "nodebuffer" : function(input) {
         return new Buffer(input);
      }
   };

   // nodebuffer to ?
   transform["nodebuffer"] = {
      "string" : arrayLikeToString,
      "array" : function (input) {
         return arrayLikeToArrayLike(input, new Array(input.length));
      },
      "arraybuffer" : function (input) {
         return transform["nodebuffer"]["uint8array"](input).buffer;
      },
      "uint8array" : function (input) {
         return arrayLikeToArrayLike(input, new Uint8Array(input.length));
      },
      "nodebuffer" : identity
   };

   /**
    * Transform an input into any type.
    * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer.
    * If no output type is specified, the unmodified input will be returned.
    * @param {String} outputType the output type.
    * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert.
    * @throws {Error} an Error if the browser doesn't support the requested output type.
    */
   JSZip.utils.transformTo = function (outputType, input) {
      if (!input) {
         // undefined, null, etc
         // an empty string won't harm.
         input = "";
      }
      if (!outputType) {
         return input;
      }
      JSZip.utils.checkSupport(outputType);
      var inputType = JSZip.utils.getTypeOf(input);
      var result = transform[inputType][outputType](input);
      return result;
   };

   /**
    * Return the type of the input.
    * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
    * @param {Object} input the input to identify.
    * @return {String} the (lowercase) type of the input.
    */
   JSZip.utils.getTypeOf = function (input) {
      if (typeof input === "string") {
         return "string";
      }
      if (Object.prototype.toString.call(input) === "[object Array]") {
         return "array";
      }
      if (JSZip.support.nodebuffer && Buffer.isBuffer(input)) {
         return "nodebuffer";
      }
      if (JSZip.support.uint8array && input instanceof Uint8Array) {
         return "uint8array";
      }
      if (JSZip.support.arraybuffer && input instanceof ArrayBuffer) {
         return "arraybuffer";
      }
   };

   /**
    * Cross-window, cross-Node-context regular expression detection
    * @param  {Object}  object Anything
    * @return {Boolean}        true if the object is a regular expression,
    * false otherwise
    */
   JSZip.utils.isRegExp = function (object) {
      return Object.prototype.toString.call(object) === "[object RegExp]";
   };

   /**
    * Throw an exception if the type is not supported.
    * @param {String} type the type to check.
    * @throws {Error} an Error if the browser doesn't support the requested type.
    */
   JSZip.utils.checkSupport = function (type) {
      var supported = true;
      switch (type.toLowerCase()) {
         case "uint8array":
            supported = JSZip.support.uint8array;
         break;
         case "arraybuffer":
            supported = JSZip.support.arraybuffer;
         break;
         case "nodebuffer":
            supported = JSZip.support.nodebuffer;
         break;
         case "blob":
            supported = JSZip.support.blob;
         break;
      }
      if (!supported) {
         throw new Error(type + " is not supported by this browser");
      }
   };


})();

(function (){
   /**
    * Represents an entry in the zip.
    * The content may or may not be compressed.
    * @constructor
    */
   JSZip.CompressedObject = function () {
         this.compressedSize = 0;
         this.uncompressedSize = 0;
         this.crc32 = 0;
         this.compressionMethod = null;
         this.compressedContent = null;
   };

   JSZip.CompressedObject.prototype = {
      /**
       * Return the decompressed content in an unspecified format.
       * The format will depend on the decompressor.
       * @return {Object} the decompressed content.
       */
      getContent : function () {
         return null; // see implementation
      },
      /**
       * Return the compressed content in an unspecified format.
       * The format will depend on the compressed conten source.
       * @return {Object} the compressed content.
       */
      getCompressedContent : function () {
         return null; // see implementation
      }
   };
})();

/**
 *
 *  Base64 encode / decode
 *  http://www.webtoolkit.info/
 *
 *  Hacked so that it doesn't utf8 en/decode everything
 **/
JSZip.base64 = (function() {
   // private property
   var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

   return {
      // public method for encoding
      encode : function(input, utf8) {
         var output = "";
         var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
         var i = 0;

         while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
               enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
               enc4 = 64;
            }

            output = output +
               _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
               _keyStr.charAt(enc3) + _keyStr.charAt(enc4);

         }

         return output;
      },

      // public method for decoding
      decode : function(input, utf8) {
         var output = "";
         var chr1, chr2, chr3;
         var enc1, enc2, enc3, enc4;
         var i = 0;

         input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

         while (i < input.length) {

            enc1 = _keyStr.indexOf(input.charAt(i++));
            enc2 = _keyStr.indexOf(input.charAt(i++));
            enc3 = _keyStr.indexOf(input.charAt(i++));
            enc4 = _keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
               output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
               output = output + String.fromCharCode(chr3);
            }

         }

         return output;

      }
   };
}());

// enforcing Stuk's coding style
// vim: set shiftwidth=3 softtabstop=3:

(function (root) {
// lazy require symbols table
var _symbols, removelist;
function symbols(code) {
    if (_symbols) return _symbols[code];
    _symbols = require('unicode/category/So');
    removelist = ['sign','cross','of','symbol','staff','hand','black','white']
        .map(function (word) {return new RegExp(word, 'gi')});
    return _symbols[code];
}

function slug(string, opts) {
    opts = opts || {};
    string = string.toString();
    if ('string' === typeof opts)
        opts = {replacement:opts};
    opts.mode = opts.mode || slug.defaults.mode;
    var defaults = slug.defaults.modes[opts.mode];
    ['replacement','multicharmap','charmap','remove'].forEach(function (key) {
        opts[key] = opts[key] || defaults[key];
    });
    if ('undefined' === typeof opts.symbols)
        opts.symbols = defaults.symbols;
    var lengths = [];
    Object.keys(opts.multicharmap).forEach(function (key) {
        var len = key.length;
        if (lengths.indexOf(len) === -1)
            lengths.push(len);
    });
    var code, unicode, result = "";
    for (var char, i = 0, l = string.length; i < l; i++) { char = string[i];
        if (!lengths.some(function (len) {
            var str = string.substr(i, len);
            if (opts.multicharmap[str]) {
                i += len - 1;
                char = opts.multicharmap[str];
                return true;
            } else return false;
        })) {
            if (opts.charmap[char]) {
                char = opts.charmap[char];
                code = char.charCodeAt(0);
            } else {
                code = string.charCodeAt(i);
            }
            if (opts.symbols && (unicode = symbols(code))) {
                char = unicode.name.toLowerCase();
                for(var j = 0, rl = removelist.length; j < rl; j++) {
                    char = char.replace(removelist[j], '');
                }
                char = char.replace(/^\s+|\s+$/g, '');
            }
        }
        char = char.replace(/[^\w\s\-\.\_~]/g, ''); // allowed
        if (opts.remove) char = char.replace(opts.remove, ''); // add flavour
        result += char;
    }
    result = result.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
    result = result.replace(/[-\s]+/g, opts.replacement); // convert spaces
    return result.replace(opts.replacement+"$",''); // remove trailing separator
};

slug.defaults = {
    mode: 'pretty',
};

slug.multicharmap = slug.defaults.multicharmap = {
    '<3': 'love', '&&': 'and', '||': 'or', 'w/': 'with',
};

// https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/media/js/urlify.js
slug.charmap  = slug.defaults.charmap = {
    // latin
    'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
    'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
    'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
    'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U',
    'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a',
    'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e',
    'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i',
    'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o',
    'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u',
    'ý': 'y', 'þ': 'th', 'ÿ': 'y', 'ẞ': 'SS',
    // greek
    'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8',
    'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
    'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
    'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
    'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
    'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
    'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
    'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W',
    'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
    'Ϋ':'Y',
    // turkish
    'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I',
    'ğ':'g', 'Ğ':'G',
    // russian
    'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh',
    'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o',
    'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c',
    'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'u', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu',
    'я':'ya',
    'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh',
    'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O',
    'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C',
    'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'U', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
    'Я':'Ya',
    // ukranian
    'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g',
    // czech
    'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
    'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T',
    'Ů':'U', 'Ž':'Z',
    // polish
    'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ś':'s', 'ź':'z',
    'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ś':'S',
    'Ź':'Z', 'Ż':'Z',
    // latvian
    'ā':'a', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n',
    'ū':'u', 'Ā':'A', 'Ē':'E', 'Ģ':'G', 'Ī':'I',
    'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Ū':'U',
    // lithuanian
    'ė':'e', 'į':'i', 'ų':'u', 'Ė': 'E', 'Į': 'I', 'Ų':'U',
    // romanian
    'ț':'t', 'Ț':'T', 'ţ':'t', 'Ţ':'T', 'ș':'s', 'Ș':'S', 'ă':'a', 'Ă':'A',
    // currency
    '€': 'euro', '₢': 'cruzeiro', '₣': 'french franc', '£': 'pound',
    '₤': 'lira', '₥': 'mill', '₦': 'naira', '₧': 'peseta', '₨': 'rupee',
    '₩': 'won', '₪': 'new shequel', '₫': 'dong', '₭': 'kip', '₮': 'tugrik',
    '₯': 'drachma', '₰': 'penny', '₱': 'peso', '₲': 'guarani', '₳': 'austral',
    '₴': 'hryvnia', '₵': 'cedi', '¢': 'cent', '¥': 'yen', '元': 'yuan',
    '円': 'yen', '﷼': 'rial', '₠': 'ecu', '¤': 'currency', '฿': 'baht',
    "$": 'dollar', '₹': 'indian rupee',
    // symbols
    '©':'(c)', 'œ': 'oe', 'Œ': 'OE', '∑': 'sum', '®': '(r)', '†': '+',
    '“': '"', '”': '"', '‘': "'", '’': "'", '∂': 'd', 'ƒ': 'f', '™': 'tm',
    '℠': 'sm', '…': '...', '˚': 'o', 'º': 'o', 'ª': 'a', '•': '*',
    '∆': 'delta', '∞': 'infinity', '♥': 'love', '&': 'and', '|': 'or',
    '<': 'less', '>': 'greater',
};

slug.defaults.modes = {
    rfc3986: {
        replacement: '-',
        symbols: true,
        remove: null,
        charmap: slug.defaults.charmap,
        multicharmap: slug.defaults.multicharmap,
    },
    pretty: {
        replacement: '-',
        symbols: true,
        remove: /[.]/g,
        charmap: slug.defaults.charmap,
        multicharmap: slug.defaults.multicharmap,
    },
};

// Be compatible with different module systems

if (typeof define !== 'undefined' && define.amd) { // AMD
    // dont load symbols table in the browser
    Object.keys(slug.defaults.modes).forEach(function (key) {
        slug.defaults.modes[key].symbols = false;
    });
    define([], function () {return slug});
} else if (typeof module !== 'undefined' && module.exports) { // CommonJS
    symbols(); // preload symbols table
    module.exports = slug;
} else { // Script tag
    // dont load symbols table in the browser
    Object.keys(slug.defaults.modes).forEach(function (key) {
        slug.defaults.modes[key].symbols = false;
    });
    root.slug = slug;
}

}(this));

/* FileSaver.js
 * A saveAs() FileSaver implementation.
 * 1.1.20151003
 *
 * By Eli Grey, http://eligrey.com
 * License: MIT
 *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
 */

/*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */

/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

var saveAs = saveAs || (function(view) {
	"use strict";
	// IE <10 is explicitly unsupported
	if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
		return;
	}
	var
		  doc = view.document
		  // only get URL when necessary in case Blob.js hasn't overridden it yet
		, get_URL = function() {
			return view.URL || view.webkitURL || view;
		}
		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
		, can_use_save_link = "download" in save_link
		, click = function(node) {
			var event = new MouseEvent("click");
			node.dispatchEvent(event);
		}
		, is_safari = /Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
		, webkit_req_fs = view.webkitRequestFileSystem
		, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
		, throw_outside = function(ex) {
			(view.setImmediate || view.setTimeout)(function() {
				throw ex;
			}, 0);
		}
		, force_saveable_type = "application/octet-stream"
		, fs_min_size = 0
		// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
		// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
		// for the reasoning behind the timeout and revocation flow
		, arbitrary_revoke_timeout = 500 // in ms
		, revoke = function(file) {
			var revoker = function() {
				if (typeof file === "string") { // file is an object URL
					get_URL().revokeObjectURL(file);
				} else { // file is a File
					file.remove();
				}
			};
			if (view.chrome) {
				revoker();
			} else {
				setTimeout(revoker, arbitrary_revoke_timeout);
			}
		}
		, dispatch = function(filesaver, event_types, event) {
			event_types = [].concat(event_types);
			var i = event_types.length;
			while (i--) {
				var listener = filesaver["on" + event_types[i]];
				if (typeof listener === "function") {
					try {
						listener.call(filesaver, event || filesaver);
					} catch (ex) {
						throw_outside(ex);
					}
				}
			}
		}
		, auto_bom = function(blob) {
			// prepend BOM for UTF-8 XML and text/* types (including HTML)
			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
				return new Blob(["\ufeff", blob], {type: blob.type});
			}
			return blob;
		}
		, FileSaver = function(blob, name, no_auto_bom) {
			if (!no_auto_bom) {
				blob = auto_bom(blob);
			}
			// First try a.download, then web filesystem, then object URLs
			var
				  filesaver = this
				, type = blob.type
				, blob_changed = false
				, object_url
				, target_view
				, dispatch_all = function() {
					dispatch(filesaver, "writestart progress write writeend".split(" "));
				}
				// on any filesys errors revert to saving with object URLs
				, fs_error = function() {
					if (target_view && is_safari && typeof FileReader !== "undefined") {
						// Safari doesn't allow downloading of blob urls
						var reader = new FileReader();
						reader.onloadend = function() {
							var base64Data = reader.result;
							target_view.location.href = "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/));
							filesaver.readyState = filesaver.DONE;
							dispatch_all();
						};
						reader.readAsDataURL(blob);
						filesaver.readyState = filesaver.INIT;
						return;
					}
					// don't create more object URLs than needed
					if (blob_changed || !object_url) {
						object_url = get_URL().createObjectURL(blob);
					}
					if (target_view) {
						target_view.location.href = object_url;
					} else {
						var new_tab = view.open(object_url, "_blank");
						if (new_tab == undefined && is_safari) {
							//Apple do not allow window.open, see http://bit.ly/1kZffRI
							view.location.href = object_url
						}
					}
					filesaver.readyState = filesaver.DONE;
					dispatch_all();
					revoke(object_url);
				}
				, abortable = function(func) {
					return function() {
						if (filesaver.readyState !== filesaver.DONE) {
							return func.apply(this, arguments);
						}
					};
				}
				, create_if_not_found = {create: true, exclusive: false}
				, slice
			;
			filesaver.readyState = filesaver.INIT;
			if (!name) {
				name = "download";
			}
			if (can_use_save_link) {
				object_url = get_URL().createObjectURL(blob);
				setTimeout(function() {
					save_link.href = object_url;
					save_link.download = name;
					click(save_link);
					dispatch_all();
					revoke(object_url);
					filesaver.readyState = filesaver.DONE;
				});
				return;
			}
			// Object and web filesystem URLs have a problem saving in Google Chrome when
			// viewed in a tab, so I force save with application/octet-stream
			// http://code.google.com/p/chromium/issues/detail?id=91158
			// Update: Google errantly closed 91158, I submitted it again:
			// https://code.google.com/p/chromium/issues/detail?id=389642
			if (view.chrome && type && type !== force_saveable_type) {
				slice = blob.slice || blob.webkitSlice;
				blob = slice.call(blob, 0, blob.size, force_saveable_type);
				blob_changed = true;
			}
			// Since I can't be sure that the guessed media type will trigger a download
			// in WebKit, I append .download to the filename.
			// https://bugs.webkit.org/show_bug.cgi?id=65440
			if (webkit_req_fs && name !== "download") {
				name += ".download";
			}
			if (type === force_saveable_type || webkit_req_fs) {
				target_view = view;
			}
			if (!req_fs) {
				fs_error();
				return;
			}
			fs_min_size += blob.size;
			req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
				fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
					var save = function() {
						dir.getFile(name, create_if_not_found, abortable(function(file) {
							file.createWriter(abortable(function(writer) {
								writer.onwriteend = function(event) {
									target_view.location.href = file.toURL();
									filesaver.readyState = filesaver.DONE;
									dispatch(filesaver, "writeend", event);
									revoke(file);
								};
								writer.onerror = function() {
									var error = writer.error;
									if (error.code !== error.ABORT_ERR) {
										fs_error();
									}
								};
								"writestart progress write abort".split(" ").forEach(function(event) {
									writer["on" + event] = filesaver["on" + event];
								});
								writer.write(blob);
								filesaver.abort = function() {
									writer.abort();
									filesaver.readyState = filesaver.DONE;
								};
								filesaver.readyState = filesaver.WRITING;
							}), fs_error);
						}), fs_error);
					};
					dir.getFile(name, {create: false}, abortable(function(file) {
						// delete file if it already exists
						file.remove();
						save();
					}), abortable(function(ex) {
						if (ex.code === ex.NOT_FOUND_ERR) {
							save();
						} else {
							fs_error();
						}
					}));
				}), fs_error);
			}), fs_error);
		}
		, FS_proto = FileSaver.prototype
		, saveAs = function(blob, name, no_auto_bom) {
			return new FileSaver(blob, name, no_auto_bom);
		}
	;
	// IE 10+ (native saveAs)
	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
		return function(blob, name, no_auto_bom) {
			if (!no_auto_bom) {
				blob = auto_bom(blob);
			}
			return navigator.msSaveOrOpenBlob(blob, name || "download");
		};
	}

	FS_proto.abort = function() {
		var filesaver = this;
		filesaver.readyState = filesaver.DONE;
		dispatch(filesaver, "abort");
	};
	FS_proto.readyState = FS_proto.INIT = 0;
	FS_proto.WRITING = 1;
	FS_proto.DONE = 2;

	FS_proto.error =
	FS_proto.onwritestart =
	FS_proto.onprogress =
	FS_proto.onwrite =
	FS_proto.onabort =
	FS_proto.onerror =
	FS_proto.onwriteend =
		null;

	return saveAs;
}(
	   typeof self !== "undefined" && self
	|| typeof window !== "undefined" && window
	|| this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window

if (typeof module !== "undefined" && module.exports) {
  module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
  define([], function() {
    return saveAs;
  });
}

!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.ramlClientGenerator=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/**
 * Map dependencies to their environment.
 *
 * @type {Object}
 */
var DEPS_MAP = {
  node: {
    popsicle:     'require(\'popsicle\')',
    ClientOAuth2: 'require(\'client-oauth2\')'
  },
  amd: {
    popsicle:     '\'popsicle\'',
    ClientOAuth2: '\'ClientOAuth2\''
  },
  browser: {
    popsicle:     'root.popsicle',
    ClientOAuth2: 'root.ClientOAuth2'
  }
};

/**
 * Map an array of dependency names to values.
 *
 * @param  {Array}  deps
 * @param  {String} env
 * @return {Array}
 */
function mapDeps (deps, env) {
  if (!env) {
    return deps;
  }

  return deps.map(function (dep) {
    return DEPS_MAP[env][dep];
  });
}

/**
 * Create a dependencies string.
 *
 * @param  {Object} context
 * @param  {String} env
 * @return {String}
 */
module.exports = function (context, env) {
  var deps = ['popsicle'];

  // OAuth 2.0 depends on ClientOAuth2 to work.
  if (context.security['OAuth 2.0']) {
    deps.push('ClientOAuth2');
  }

  // Returns an array of strings for AMD.
  if (env === 'amd') {
    return '[' + mapDeps(deps, env).join(', ') + ']';
  }

  return mapDeps(deps, env).join(', ');
};

},{}],2:[function(require,module,exports){
/**
 * Iterate over the parameters and turn into a string.
 *
 * @param  {Object} parameters
 * @return {String}
 */
module.exports = function (parameters) {
  return Object.keys(parameters).map(function (key) {
    var parameter = parameters[key];
    var title     = '* **' + parameter.displayName + '**';
    var options   = [];

    if (parameter.type) {
      options.push(parameter.type);
    }

    if (Array.isArray(parameter.enum) && parameter.enum.length) {
      options.push('one of (' + parameter.enum.join(', ') + ')');
    }

    if (parameter.default) {
      options.push('default: ' + parameter.default);
    }

    return title +
      (options.length ? ' _' + options.join(', ') + '_' : '') +
      (parameter.description ? '\n\n' + parameter.description : '');
  }).join('\n\n');
};

},{}],3:[function(require,module,exports){
/**
 * Pull out request parameters from the resource.
 *
 * @param  {Object} resource
 * @return {String}
 */
var params = function (resource) {
  return resource.uriParameters.map(function (param) {
    return param.displayName;
  }).join(', ');
};

/**
 * Stringify a resource into a request snippet.
 *
 * @param  {Object} resource
 * @return {String}
 */
module.exports = function (resource) {
  var parts = [];
  var part  = resource;

  while (part && part.parent) {
    var segment = part.key;

    // If uri parameters exist, push onto the stack.
    if (part.uriParameters.length) {
      segment += '(' + params(part) + ')';
    }

    parts.unshift(segment);

    part = part.parent;
  }

  return 'resources' + (parts.length ? '.' + parts.join('.') : '');
};

},{}],4:[function(require,module,exports){
var generator = require('../../lib/generator');

/**
 * Export a client generator instance.
 *
 * @type {Function}
 */
module.exports = generator({
  templates: {
    '.gitignore':   require('./templates/.gitignore.hbs'),
    'index.js':     require('./templates/index.js.hbs'),
    'README.md':    require('./templates/README.md.hbs'),
    'INSTALL.md':   require('./templates/INSTALL.md.hbs'),
    'package.json': require('./templates/package.json.hbs')
  },
  format: {
    variable: require('camel-case')
  },
  partials: {
    auth:      require('./partials/auth.js.hbs'),
    utils:     require('./partials/utils.js.hbs'),
    client:    require('./partials/client.js.hbs'),
    resources: require('./partials/resources.js.hbs')
  },
  helpers: {
    stringify:         require('javascript-stringify'),
    dependencies:      require('./helpers/dependencies'),
    requestSnippet:    require('./helpers/request-snippet'),
    parametersSnippet: require('./helpers/parameters-snippet')
  }
});

},{"../../lib/generator":20,"./helpers/dependencies":1,"./helpers/parameters-snippet":2,"./helpers/request-snippet":3,"./partials/auth.js.hbs":5,"./partials/client.js.hbs":6,"./partials/resources.js.hbs":7,"./partials/utils.js.hbs":8,"./templates/.gitignore.hbs":9,"./templates/INSTALL.md.hbs":10,"./templates/README.md.hbs":11,"./templates/index.js.hbs":12,"./templates/package.json.hbs":13,"camel-case":27,"javascript-stringify":45}],5:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"1":function(depth0,helpers,partials,data) {
    var stack1;

  return "/**\n * @param {Object} options\n */\nfunction OAuth2 (options) {\n  ClientOAuth2.call(this, extend("
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || helpers.helperMissing).call(depth0,((stack1 = ((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1)) != null ? stack1.settings : stack1),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ", options));\n}\n\nOAuth2.prototype = Object.create(ClientOAuth2.prototype);\nOAuth2.prototype.constructor = OAuth2;\nOAuth2.prototype.request = popsicle;\n\nClient.OAuth2 = OAuth2;\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var stack1;

  return ((stack1 = helpers['if'].call(depth0,((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1),{"name":"if","hash":{},"fn":this.program(1, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"useData":true});

},{"hbsfy/runtime":41}],6:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing;

  return "function Client (options) {\n  this.options = extend({\n    baseUri: "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(depth0 != null ? depth0.baseUri : depth0),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ",\n    baseUriParameters: "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(helpers.object || (depth0 && depth0.object) || alias1).call(depth0,(helpers.keys || (depth0 && depth0.keys) || alias1).call(depth0,(depth0 != null ? depth0.baseUriParameters : depth0),{"name":"keys","hash":{},"data":data}),(helpers.pluck || (depth0 && depth0.pluck) || alias1).call(depth0,(depth0 != null ? depth0.baseUriParameters : depth0),"default",{"name":"pluck","hash":{},"data":data}),{"name":"object","hash":{},"data":data}),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + "\n  }, options);\n\n  this.resources = new "
    + this.escapeExpression((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,((stack1 = (depth0 != null ? depth0.resources : depth0)) != null ? stack1.id : stack1),{"name":"pascalCase","hash":{},"data":data}))
    + "('', this);\n};\n\nClient.prototype.resource = function (route, parameters) {\n  var path = '/' + template(route, parameters).replace(/^\\//, '');\n\n  return new CustomResource(path, this);\n};\n\nClient.prototype.request = popsicle;\nClient.prototype.form = Client.form = popsicle.form;\nClient.prototype.version  = "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(depth0 != null ? depth0.version : depth0),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ";\n";
},"useData":true});

},{"hbsfy/runtime":41}],7:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"1":function(depth0,helpers,partials,data,blockParams,depths) {
    var stack1;

  return "function "
    + this.escapeExpression((helpers.pascalCase || (depth0 && depth0.pascalCase) || helpers.helperMissing).call(depth0,(depth0 != null ? depth0.id : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + " (uri, client) {\n  this._uri    = uri;\n  this._client = client;\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.children : depth0),{"name":"each","hash":{},"fn":this.program(2, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "};\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.children : depth0),{"name":"each","hash":{},"fn":this.program(5, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.methods : depth0),{"name":"each","hash":{},"fn":this.program(8, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"2":function(depth0,helpers,partials,data) {
    var stack1;

  return ((stack1 = helpers.unless.call(depth0,(depth0 != null ? depth0.uriParameters : depth0),{"name":"unless","hash":{},"fn":this.program(3, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"3":function(depth0,helpers,partials,data) {
    var stack1, helper, alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return "  this."
    + alias2(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias1),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + " = new "
    + alias2((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.id : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "(uri + "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(depth0 != null ? depth0.relativeUri : depth0),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ", client);\n";
},"5":function(depth0,helpers,partials,data,blockParams,depths) {
    var stack1;

  return ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.uriParameters : depth0),{"name":"if","hash":{},"fn":this.program(6, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"6":function(depth0,helpers,partials,data,blockParams,depths) {
    var stack1, helper, alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return alias2((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depths[2] != null ? depths[2].id : depths[2]),{"name":"pascalCase","hash":{},"data":data}))
    + ".prototype."
    + alias2(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias1),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + " = function (/* ...args */) {\n  var uri = this._uri + template("
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(depth0 != null ? depth0.relativeUri : depth0),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ", arguments, "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(helpers.pluck || (depth0 && depth0.pluck) || alias1).call(depth0,(depth0 != null ? depth0.uriParameters : depth0),"default",{"name":"pluck","hash":{},"data":data}),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ");\n\n  return new "
    + alias2((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.id : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "(uri, this._client);\n};\n";
},"8":function(depth0,helpers,partials,data,blockParams,depths) {
    var stack1, helper, alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return alias2((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depths[1] != null ? depths[1].id : depths[1]),{"name":"pascalCase","hash":{},"data":data}))
    + ".prototype."
    + alias2(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias1),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + " = function (body, options) {\n"
    + ((stack1 = helpers['if'].call(depth0,(helpers.keys || (depth0 && depth0.keys) || alias1).call(depth0,(depth0 != null ? depth0.headers : depth0),{"name":"keys","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(9, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "  return handleRequest(this._client, this._uri, "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(helpers.upperCase || (depth0 && depth0.upperCase) || alias1).call(depth0,(depth0 != null ? depth0.method : depth0),{"name":"upperCase","hash":{},"data":data}),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ", body, options);\n};\n";
},"9":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing;

  return "  options = extend({}, options);\n  options.headers = extend("
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(helpers.object || (depth0 && depth0.object) || alias1).call(depth0,(helpers.keys || (depth0 && depth0.keys) || alias1).call(depth0,(depth0 != null ? depth0.headers : depth0),{"name":"keys","hash":{},"data":data}),(helpers.pluck || (depth0 && depth0.pluck) || alias1).call(depth0,(depth0 != null ? depth0.headers : depth0),"default",{"name":"pluck","hash":{},"data":data}),{"name":"object","hash":{},"data":data}),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ", options.headers);\n\n";
},"11":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing;

  return "CustomResource.prototype."
    + this.escapeExpression((helpers.camelCase || (depth0 && depth0.camelCase) || alias1).call(depth0,depth0,{"name":"camelCase","hash":{},"data":data}))
    + " = function (body, options) {\n  return handleRequest(this._client, this._uri, "
    + ((stack1 = (helpers.stringify || (depth0 && depth0.stringify) || alias1).call(depth0,(helpers.upperCase || (depth0 && depth0.upperCase) || alias1).call(depth0,depth0,{"name":"upperCase","hash":{},"data":data}),{"name":"stringify","hash":{},"data":data})) != null ? stack1 : "")
    + ", body, options);\n};\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data,blockParams,depths) {
    var stack1;

  return "function handleRequest (client, path, method, body, options) {\n  options = extend({}, client.options, options);\n\n  var baseUri = template(options.baseUri, options.baseUriParameters);\n  var hasBody = method !== 'GET' && method !== 'HEAD';\n  var reqOpts = {};\n\n  var reqBody = hasBody && body != null ? body : options.body;\n  var reqQuery = !hasBody && body != null ? body : options.query;\n\n  var reqOpts = {\n    url: baseUri.replace(/\\/$/, '') + path,\n    method: method,\n    headers: extend({}, options.headers),\n    body: reqBody,\n    query: typeof reqQuery === 'object' ? extend({}, reqQuery) : reqQuery\n  };\n\n  if (options.user && typeof options.user.sign === 'function') {\n    options.user.sign(reqOpts);\n  }\n\n  return client.request(reqOpts);\n}\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.allResources : depth0),{"name":"each","hash":{},"fn":this.program(1, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "\nfunction CustomResource (uri, client) {\n  this._uri    = uri;\n  this._client = client;\n}\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.supportedMethods : depth0),{"name":"each","hash":{},"fn":this.program(11, data, 0, blockParams, depths),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"useData":true,"useDepths":true});

},{"hbsfy/runtime":41}],8:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    return "var TEMPLATE_REGEXP = /\\{([^\\{\\}]+)\\}/g;\n\n/**\n * @param  {String} string\n * @param  {Object} interpolate\n * @param  {Object} defaults\n * @return {String}\n */\nfunction template (string, interpolate, defaults) {\n  defaults    = defaults || {};\n  interpolate = interpolate || {};\n\n  return string.replace(TEMPLATE_REGEXP, function (match, key) {\n    if (interpolate[key] != null) {\n      return encodeURIComponent(interpolate[key]);\n    }\n\n    if (defaults[key] != null) {\n      return encodeURIComponent(defaults[key]);\n    }\n\n    return '';\n  });\n}\n\n/**\n * @param  {Object} dest\n * @param  {Object} ...source\n * @return {Object}\n */\nfunction extend (dest /*, ...source */) {\n  for (var i = 1; i < arguments.length; i++) {\n    for (var key in arguments[i]) {\n      dest[key] = arguments[i][key];\n    }\n  }\n\n  return dest;\n}\n";
},"useData":true});

},{"hbsfy/runtime":41}],9:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    return "node_modules\n";
},"useData":true});

},{"hbsfy/runtime":41}],10:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return "# Installation\n\nFollow these instructions to publish and subsequently install the module in your project.\n\n## Git\n\n```\n# Initialize with git\ngit init\ngit add .\ngit commit -m \"initial commit\"\ngit push [git-url]\n\n# Install in project from git\nnpm install [git-url] --save\n```\n\n## Source Directory\n\n```\n# Link module globally\nnpm link\n\n# Link in project to local module\nnpm link "
    + alias2((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + "\n```\n\n**Note:** You should publish it before you use it publicly.\n\n## NPM\n\n```\n# Publish to npm\nnpm publish\n\n# Install from npm\nnpm install "
    + alias2((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + " --save\n```\n\n## Bower\n\n```\n# Register with bower\nbower register "
    + alias2((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + " [git-url]\n\n# Install from bower\nbower install "
    + alias2((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + " --save\n```\n";
},"useData":true});

},{"hbsfy/runtime":41}],11:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"1":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return "### Authentication\n\n#### OAuth 2.0\n\nThis API supports authentication with [OAuth 2.0](https://github.com/mulesoft/js-client-oauth2). Initialize the `OAuth2` instance with the application client id, client secret and a redirect uri to authenticate with users.\n\n```js\nvar auth = new "
    + alias2((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + ".OAuth2({\n  clientId:     '123',\n  clientSecret: 'abc',\n  redirectUri:  'http://example.com/auth/callback'\n});\n```\n\n**All `getToken()` calls are asynchronous and return promise objects which resolve to an access token instance.**\n\n"
    + ((stack1 = helpers['if'].call(depth0,(helpers.contains || (depth0 && depth0.contains) || alias1).call(depth0,((stack1 = ((stack1 = ((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1)) != null ? stack1.settings : stack1)) != null ? stack1.authorizationGrants : stack1),"code",{"name":"contains","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(2, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(helpers.contains || (depth0 && depth0.contains) || alias1).call(depth0,((stack1 = ((stack1 = ((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1)) != null ? stack1.settings : stack1)) != null ? stack1.authorizationGrants : stack1),"token",{"name":"contains","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(4, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(helpers.contains || (depth0 && depth0.contains) || alias1).call(depth0,((stack1 = ((stack1 = ((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1)) != null ? stack1.settings : stack1)) != null ? stack1.authorizationGrants : stack1),"owner",{"name":"contains","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(6, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(helpers.contains || (depth0 && depth0.contains) || alias1).call(depth0,((stack1 = ((stack1 = ((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1)) != null ? stack1.settings : stack1)) != null ? stack1.authorizationGrants : stack1),"credentials",{"name":"contains","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(8, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "##### Access Tokens\n\nAccess token instances can be manually re-created. This is critical for access token reuse, such as saving credentials to a database for reusing later in the codebase.\n\n```js\nvar token = auth.createToken('access token', 'refresh token');\n```\n\nAn access token instance (manually created or automatically generated by a `getToken()` method) can be passed into any API request. This will sign the API request with the current users access token credentials.\n\n```js\n// Existing API client instance.\nclient.resource('/').get(null, {\n  user: token\n});\n\n// New API client instance.\nvar client = new "
    + alias2((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "({\n  user: token\n});\n```\n\n";
},"2":function(depth0,helpers,partials,data) {
    return "##### [Authorization Code Grant](https://github.com/mulesoft/js-client-oauth2#authorization-code-grant)\n\n1. Redirect user to `auth.code.getUri()`.\n2. Parse response uri and get an access token instance using `auth.code.getToken(uri)`.\n\n";
},"4":function(depth0,helpers,partials,data) {
    return "\n##### [Implicit Grant](https://github.com/mulesoft/js-client-oauth2#implicit-grant)\n\n1. Redirect user to `auth.token.getUri()` in a browser.\n2. Parse response uri and get an access token instance using `auth.token.getToken(uri)`.\n\n";
},"6":function(depth0,helpers,partials,data) {
    return "\n##### [Resource Owner Password Credentials Grant](https://github.com/mulesoft/js-client-oauth2#resource-owner-password-credentials-grant)\n\n1. Make a direct request for the access token on behalf of the user using `auth.owner.getToken(username, password)`.\n\n";
},"8":function(depth0,helpers,partials,data) {
    return "\n##### [Client Credentials Grant](https://github.com/mulesoft/js-client-oauth2#client-credentials-grant)\n\n1. Get the access token for the application by using `auth.credentials.getToken()`.\n\n";
},"10":function(depth0,helpers,partials,data) {
    var helper;

  return this.escapeExpression(((helper = (helper = helpers.version || (depth0 != null ? depth0.version : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0,{"name":"version","hash":{},"data":data}) : helper)));
},"12":function(depth0,helpers,partials,data) {
    return "v3";
},"14":function(depth0,helpers,partials,data) {
    var stack1;

  return ((stack1 = helpers['if'].call(depth0,(helpers.keys || (depth0 && depth0.keys) || helpers.helperMissing).call(depth0,(depth0 != null ? depth0.methods : depth0),{"name":"keys","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(15, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"15":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing;

  return "#### "
    + ((stack1 = (helpers.requestSnippet || (depth0 && depth0.requestSnippet) || alias1).call(depth0,depth0,{"name":"requestSnippet","hash":{},"data":data})) != null ? stack1 : "")
    + "\n\n"
    + ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.uriParameters : depth0),{"name":"if","hash":{},"fn":this.program(16, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.description : depth0),{"name":"if","hash":{},"fn":this.program(18, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "```js\nvar resource = client."
    + ((stack1 = (helpers.requestSnippet || (depth0 && depth0.requestSnippet) || alias1).call(depth0,depth0,{"name":"requestSnippet","hash":{},"data":data})) != null ? stack1 : "")
    + ";\n```\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.methods : depth0),{"name":"each","hash":{},"fn":this.program(20, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"16":function(depth0,helpers,partials,data) {
    var stack1;

  return ((stack1 = (helpers.parametersSnippet || (depth0 && depth0.parametersSnippet) || helpers.helperMissing).call(depth0,(depth0 != null ? depth0.uriParameters : depth0),{"name":"parametersSnippet","hash":{},"data":data})) != null ? stack1 : "")
    + "\n\n";
},"18":function(depth0,helpers,partials,data) {
    var stack1, helper;

  return ((stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0,{"name":"description","hash":{},"data":data}) : helper))) != null ? stack1 : "")
    + "\n\n";
},"20":function(depth0,helpers,partials,data) {
    var stack1, helper, alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return "##### "
    + alias2((helpers.upperCase || (depth0 && depth0.upperCase) || alias1).call(depth0,(depth0 != null ? depth0.method : depth0),{"name":"upperCase","hash":{},"data":data}))
    + "\n\n"
    + ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.description : depth0),{"name":"if","hash":{},"fn":this.program(18, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "```js\nresource."
    + alias2(((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : alias1),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + "().then(function (res) { ... });\n```\n\n"
    + ((stack1 = helpers['if'].call(depth0,(helpers.keys || (depth0 && depth0.keys) || alias1).call(depth0,(depth0 != null ? depth0.queryParameters : depth0),{"name":"keys","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(21, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(helpers.keys || (depth0 && depth0.keys) || alias1).call(depth0,(depth0 != null ? depth0.headers : depth0),{"name":"keys","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(26, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(helpers.keys || (depth0 && depth0.keys) || alias1).call(depth0,(depth0 != null ? depth0.body : depth0),{"name":"keys","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(28, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"21":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing;

  return "##### Query Parameters\n\n```javascript\n"
    + ((stack1 = helpers['if'].call(depth0,(helpers.equal || (depth0 && depth0.equal) || alias1).call(depth0,(depth0 != null ? depth0.method : depth0),"get",{"name":"equal","hash":{},"data":data}),{"name":"if","hash":{},"fn":this.program(22, data, 0),"inverse":this.program(24, data, 0),"data":data})) != null ? stack1 : "")
    + "```\n\n"
    + ((stack1 = (helpers.parametersSnippet || (depth0 && depth0.parametersSnippet) || alias1).call(depth0,(depth0 != null ? depth0.queryParameters : depth0),{"name":"parametersSnippet","hash":{},"data":data})) != null ? stack1 : "")
    + "\n\n";
},"22":function(depth0,helpers,partials,data) {
    var helper;

  return "resource."
    + this.escapeExpression(((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + "({ ... });\n";
},"24":function(depth0,helpers,partials,data) {
    var helper;

  return "resource."
    + this.escapeExpression(((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + "(null, { query: { ... } });\n";
},"26":function(depth0,helpers,partials,data) {
    var stack1, helper, alias1=helpers.helperMissing;

  return "##### Headers\n\n```javascript\nresource."
    + this.escapeExpression(((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : alias1),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + "(null, {\n  headers: { ... }\n});\n```\n\n"
    + ((stack1 = (helpers.parametersSnippet || (depth0 && depth0.parametersSnippet) || alias1).call(depth0,(depth0 != null ? depth0.headers : depth0),{"name":"parametersSnippet","hash":{},"data":data})) != null ? stack1 : "")
    + "\n\n";
},"28":function(depth0,helpers,partials,data) {
    var stack1;

  return "##### Body\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.body : depth0),{"name":"each","hash":{},"fn":this.program(29, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"29":function(depth0,helpers,partials,data) {
    var stack1, helper;

  return "**"
    + this.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0,{"name":"key","hash":{},"data":data}) : helper)))
    + "**\n\n"
    + ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.schema : depth0),{"name":"if","hash":{},"fn":this.program(30, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.formParameters : depth0),{"name":"if","hash":{},"fn":this.program(32, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"30":function(depth0,helpers,partials,data) {
    var stack1, helper;

  return "```\n"
    + ((stack1 = ((helper = (helper = helpers.schema || (depth0 != null ? depth0.schema : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0,{"name":"schema","hash":{},"data":data}) : helper))) != null ? stack1 : "")
    + "\n```\n\n";
},"32":function(depth0,helpers,partials,data) {
    var stack1;

  return ((stack1 = (helpers.json || (depth0 && depth0.json) || helpers.helperMissing).call(depth0,(depth0 != null ? depth0.formParameters : depth0),2,{"name":"json","hash":{},"data":data})) != null ? stack1 : "")
    + "\n\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var stack1, helper, alias1=helpers.helperMissing, alias2="function", alias3=this.escapeExpression;

  return "# "
    + alias3(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"title","hash":{},"data":data}) : helper)))
    + "\n\nBrowser and node module for making API requests against ["
    + alias3(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"title","hash":{},"data":data}) : helper)))
    + "]("
    + alias3(((helper = (helper = helpers.baseUri || (depth0 != null ? depth0.baseUri : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"baseUri","hash":{},"data":data}) : helper)))
    + ").\n\n**Please note: This module uses [Popsicle](https://github.com/blakeembrey/popsicle) to make API requests. Promises must be supported or polyfilled on all target environments.**\n\n## Installation\n\n```\nnpm install "
    + alias3((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + " --save\nbower install "
    + alias3((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + " --save\n```\n\n## Usage\n\n### Node\n\n```javascript\nvar "
    + alias3((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + " = require('"
    + alias3((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + "');\n\nvar client = new "
    + alias3((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "();\n```\n\n### Browsers\n\n```html\n<script src=\""
    + alias3((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + "/index.js\">\n\n<script>\n  var client = new window."
    + alias3((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "();\n</script>\n```\n\n"
    + ((stack1 = helpers['if'].call(depth0,((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1),{"name":"if","hash":{},"fn":this.program(1, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "### Options\n\nYou can set options when you initialize a client or at any time with the `options` property. You may also override options for a single request by passing an object as the second argument of any request method. For example:\n\n```javascript\nvar client = new "
    + alias3((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "({ ... });\n\nclient.options = { ... };\n\nclient.resource('/').get(null, {\n  baseUri: 'http://example.com',\n  headers: {\n    'Content-Type': 'application/json'\n  }\n});\n```\n\n#### Base URI\n\nYou can override the base URI by setting the `baseUri` property, or initializing a client with a base URI. For example:\n\n```javascript\nnew "
    + alias3((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + "({\n  baseUri: 'https://example.com'\n});\n```\n\n#### Base URI Parameters\n\nIf the base URI has parameters inline, you can set them by updating the `baseUriParameters` property. For example:\n\n```javascript\nclient.options.baseUriParameters.version = '"
    + ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.version : depth0),{"name":"if","hash":{},"fn":this.program(10, data, 0),"inverse":this.program(12, data, 0),"data":data})) != null ? stack1 : "")
    + "';\n```\n\n### Resources\n\nAll methods return a HTTP request instance of [Popsicle](https://github.com/blakeembrey/popsicle), which allows the use of promises (and streaming in node).\n\n"
    + ((stack1 = helpers.each.call(depth0,(depth0 != null ? depth0.allResources : depth0),{"name":"each","hash":{},"fn":this.program(14, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "\n\n### Custom Resources\n\nYou can make requests to a custom path in the API using the `#resource(path)` method.\n\n```javascript\nclient.resource('/example/path').get();\n```\n\n## License\n\nApache 2.0\n";
},"useData":true});

},{"hbsfy/runtime":41}],12:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"1":function(depth0,helpers,partials,data) {
    var stack1;

  return ((stack1 = this.invokePartial(partials.utils,depth0,{"name":"utils","data":data,"helpers":helpers,"partials":partials})) != null ? stack1 : "")
    + "\n"
    + ((stack1 = this.invokePartial(partials.resources,depth0,{"name":"resources","data":data,"helpers":helpers,"partials":partials})) != null ? stack1 : "")
    + "\n"
    + ((stack1 = this.invokePartial(partials.client,depth0,{"name":"client","data":data,"helpers":helpers,"partials":partials})) != null ? stack1 : "")
    + "\n"
    + ((stack1 = this.invokePartial(partials.auth,depth0,{"name":"auth","data":data,"helpers":helpers,"partials":partials})) != null ? stack1 : "")
    + "\nreturn Client;\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var stack1, alias1=helpers.helperMissing;

  return "(function (root, client) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define("
    + ((stack1 = (helpers.dependencies || (depth0 && depth0.dependencies) || alias1).call(depth0,depth0,"amd",{"name":"dependencies","hash":{},"data":data})) != null ? stack1 : "")
    + ", client);\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but only CommonJS-like\n    // environments that support `module.exports`, like Node.\n    module.exports = client("
    + ((stack1 = (helpers.dependencies || (depth0 && depth0.dependencies) || alias1).call(depth0,depth0,"node",{"name":"dependencies","hash":{},"data":data})) != null ? stack1 : "")
    + ");\n  } else {\n    // Browser globals (root is window).\n    root."
    + this.escapeExpression((helpers.pascalCase || (depth0 && depth0.pascalCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"pascalCase","hash":{},"data":data}))
    + " = client("
    + ((stack1 = (helpers.dependencies || (depth0 && depth0.dependencies) || alias1).call(depth0,depth0,"browser",{"name":"dependencies","hash":{},"data":data})) != null ? stack1 : "")
    + ");\n  }\n})(this, function ("
    + ((stack1 = (helpers.dependencies || (depth0 && depth0.dependencies) || alias1).call(depth0,depth0,false,{"name":"dependencies","hash":{},"data":data})) != null ? stack1 : "")
    + ") {\n"
    + ((stack1 = (helpers.indent || (depth0 && depth0.indent) || alias1).call(depth0,2,{"name":"indent","hash":{},"fn":this.program(1, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "});\n";
},"usePartial":true,"useData":true});

},{"hbsfy/runtime":41}],13:[function(require,module,exports){
// hbsfy compiled Handlebars template
var HandlebarsCompiler = require('hbsfy/runtime');
module.exports = HandlebarsCompiler.template({"1":function(depth0,helpers,partials,data) {
    return "\"client-oauth2\": \"^0.1.0\",\n    ";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var stack1, helper, alias1=helpers.helperMissing, alias2=this.escapeExpression;

  return "{\n  \"name\": \""
    + alias2((helpers.paramCase || (depth0 && depth0.paramCase) || alias1).call(depth0,(depth0 != null ? depth0.title : depth0),{"name":"paramCase","hash":{},"data":data}))
    + "\",\n  \"version\": \"0.0.0\",\n  \"description\": \""
    + alias2(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : alias1),(typeof helper === "function" ? helper.call(depth0,{"name":"description","hash":{},"data":data}) : helper)))
    + "\",\n  \"main\": \"index.js\",\n  \"files\": [\n    \"index.js\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/mulesoft/raml-client-generator.git\"\n  },\n  \"keywords\": [\n    \"raml-api\"\n  ],\n  \"author\": \"MuleSoft, Inc.\",\n  \"license\": \"Apache 2.0\",\n  \"bugs\": {\n    \"url\": \"https://github.com/mulesoft/raml-client-generator/issues\"\n  },\n  \"homepage\": \"https://github.com/mulesoft/raml-client-generator\",\n  \"dependencies\": {\n    "
    + ((stack1 = helpers['if'].call(depth0,((stack1 = (depth0 != null ? depth0.security : depth0)) != null ? stack1['OAuth 2.0'] : stack1),{"name":"if","hash":{},"fn":this.program(1, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "")
    + "\"popsicle\": \"^0.3.6\"\n  }\n}\n";
},"useData":true});

},{"hbsfy/runtime":41}],14:[function(require,module,exports){
var extend             = require('extend');
var sanitizeUri        = require('./uri');
var sanitizeSecurity   = require('./security');
var sanitizeResources  = require('./resources');
var sanitizeParameters = require('./parameters');

/**
 * Track indexes of each generated id.
 *
 * @type {Object}
 */
var PARAM_IDS;

/**
 * Default formatting options.
 *
 * @type {Object}
 */
var DEFAULT_FORMAT = {
  /**
   * Replace with your preferred uri templating language.
   *
   * @param  {String} uri
   * @return {String}
   */
  uri: function (uri) {
    return uri;
  },
  /**
   * Variable formatting support. By default, we'll just throw an error.
   */
  variable: function () {
    throw new Error('No variable format specified');
  },
  /**
   * Generate unique ids each spec iteration.
   */
  uniqueId: function (prefix) {
    var id = ++PARAM_IDS[prefix] || (PARAM_IDS[prefix] = 0);

    return prefix + id;
  }
};

/**
 * Validate (and sanitize) the passed in spec object.
 *
 * @param  {Obejct} spec
 * @return {Obejct}
 */
var validateSpec = function (spec) {
  // Reset the id generations.
  PARAM_IDS = {};

  spec.format = extend({}, DEFAULT_FORMAT, spec.format);

  return extend({}, spec);
};

/**
 * Flatten the resources object tree into an array.
 *
 * @param  {Object} resources
 * @return {Array}
 */
var flattenResources = function (resources) {
  var array = [];

  // Recursively push all resources into a single flattened array.
  (function recurse (resource) {
    array.push(resource);

    Object.keys(resource.children).forEach(function (key) {
      recurse(resource.children[key]);
    });
  })(resources);

  return array;
};

/**
 * Flatten the resources object into an array of methods.
 *
 * @param  {Object} resources
 * @return {Array}
 */
var flattenMethods = function (resources) {
  var array = [];

  // Recursively push all methods into a single flattened array.
  (function recurse (resource) {
    if (resource.methods) {
      Object.keys(resource.methods).forEach(function (key) {
        array.push(resource.methods[key]);
      });
    }

    Object.keys(resource.children).forEach(function (key) {
      recurse(resource.children[key]);
    });
  })(resources);

  return array;
};

/**
 * Create a context object for the templates to use during compilation.
 *
 * @param  {Object} ast
 * @param  {Object} spec
 * @return {Object}
 */
module.exports = function (ast, spec) {
  // Validate the spec before using.
  spec = validateSpec(spec);

  // Create an empty context object.
  var context = {
    id:                spec.format.uniqueId('client'),
    title:             ast.title || 'API Client',
    version:           ast.version,
    baseUri:           sanitizeUri(ast.baseUri, spec),
    security:          sanitizeSecurity(ast.securitySchemes, spec),
    resources:         sanitizeResources(ast.resources, spec),
    baseUriParameters: sanitizeParameters(ast.baseUriParameters, spec)
  };

  context.allMethods       = flattenMethods(context.resources);
  context.allResources     = flattenResources(context.resources);
  context.supportedMethods = require('methods');

  return context;
};

},{"./parameters":16,"./resources":17,"./security":18,"./uri":19,"extend":33,"methods":47}],15:[function(require,module,exports){
var pick               = require('object.pick');
var sanitizeParameters = require('./parameters');

/**
 * Sanitize a method into a flatter, more readable structure.
 *
 * @param  {Object} method
 * @param  {Object} resource
 * @param  {Object} spec
 * @return {Object}
 */
var sanitizeMethod = function (method, resource, spec) {
  // Pick only the usable properties.
  var obj = pick(method, [
    'method',
    'protocols',
    'responses',
    'body',
    'headers'
  ]);

  // Attach a unique id to every method.
  obj.id              = spec.format.uniqueId('method');
  obj.resource        = resource;
  obj.queryParameters = sanitizeParameters(method.queryParameters);
  obj.description     = (method.description || '').trim();

  // TODO: Add `securedBy` support.
  // TODO: Automatically infer content-type header from body.

  return obj;
};

/**
 * Sanitize a methods array into a more reusable object.
 *
 * @param  {Array}  methods
 * @param  {Object} resource
 * @param  {Object} spec
 * @return {Object}
 */
module.exports = function (methods, resource, spec) {
  var obj = {};

  if (!methods) {
    return obj;
  }

  methods.forEach(function (method) {
    var key             = spec.format.variable(method.method);
    var sanitizedMethod = sanitizeMethod(method, resource, spec);

    obj[key] = sanitizedMethod;
    sanitizedMethod.key = key;
  });

  return obj;
};

},{"./parameters":16,"object.pick":48}],16:[function(require,module,exports){
var pick = require('object.pick');

/**
 * Sanitize the parameter into a more reusable object.
 *
 * @param  {Object} parameter
 * @return {Object}
 */
var sanitizeParameter = function (parameter) {
  var obj = pick(parameter, [
    'displayName',
    'type',
    'enum',
    'pattern',
    'minLength',
    'maxLength',
    'minimum',
    'maximum',
    'example',
    'repeat',
    'required',
    'default'
  ]);

  obj.description = (parameter.description || '').trim();

  // Automatically set the default parameter from the enum value.
  if (obj.default == null && Array.isArray(obj.enum)) {
    obj.default = obj.enum[0];
  }

  return obj;
};

/**
 * Sanitize parameters into something more consumable.
 *
 * @param  {Object} parameters
 * @return {Object}
 */
module.exports = function (parameters) {
  var obj = {};

  if (!parameters) {
    return obj;
  }

  // Iterate over every parameter and generate a new parameters object.
  Object.keys(parameters).forEach(function (key) {
    obj[key] = sanitizeParameter(parameters[key]);
  });

  return obj;
};

},{"object.pick":48}],17:[function(require,module,exports){
var sanitizeUri        = require('./uri');
var sanitizeMethods    = require('./methods');
var sanitizeParameters = require('./parameters');

/**
 * Match template tags in a string.
 *
 * @type {RegExp}
 */
var TEMPLATE_REGEXP = /\{[^\{\}]+\}/g;

/**
 * Convert a URI parameter into a variable name.
 *
 * @param  {String} uri
 * @param  {Object} spec
 * @return {String}
 */
var toPropertyFormat = function (uri, spec) {
  // Replace the prefixed path segment.
  uri = uri.replace(/^[\.\/]/, '');

  // Handle a only a single parameter. E.g. "/{param}".
  if (/^\{[^\{\}]+\}$/.test(uri)) {
    return spec.format.variable(uri.slice(1, -1));
  }

  // Handle static text with trailing parameters. E.g. "/string{id}".
  if (/^[^\{\}]+(?:\{[^\{\}]+\})*$/.test(uri)) {
    return spec.format.variable(uri.replace(/\{.+\}$/, ''));
  }
};

/**
 * Convert the uri to the language replacement format.
 *
 * @param  {String} uri
 * @param  {Object} spec
 * @return {String}
 */
var toUriFormat = function (uri, spec) {
  var index = 0;

  // Index the template parameters instead of having unique names. This
  // saves a minor amount of space and makes processing *a lot* easier.
  var indexedUri = uri.replace(/\{[^\{\}]+\}/g, function () {
    return '{' + (index++) + '}';
  });

  return sanitizeUri(indexedUri, spec);
};

/**
 * Attach the current resource to the object structure.
 *
 * @param {Object} obj
 * @param {Object} resource
 * @param {Object} spec
 */
var attachResource = function (obj, resource, spec) {
  // Split the relative uri into the valid parts. This includes special-case
  // handling for the `mediaTypeExtension` parameter according to the spec.
  var uriParts = resource.relativeUri.split(
    /(?=\.|\/|\{mediaTypeExtension\}$)/
  );

  // Sanitize the uri parameters before extracting.
  var parameters = sanitizeParameters(resource.uriParameters);

  /**
   * Return the parameter from the parameters object based on the passed in tag.
   *
   * @param  {String} param
   * @return {Object}
   */
  var getParamTag = function (param) {
    return parameters[param.slice(1, -1)];
  };

  // Iterate over each of the uri parts and nest on the root object.
  (function recurse (obj, parts) {
    var part = parts[0];

    // Add a period to the beginning of the manual media type extension.
    if (part === '{mediaTypeExtension}' && parts.length === 1) {
      if (Array.isArray(parameters.mediaTypeExtension.enum)) {
        parameters.mediaTypeExtension.enum.forEach(function (extension) {
          extension = '.' + extension.replace(/^\./, '');

          return recurse(obj, [extension]);
        });
      }

      // Remove the media type enum from documentation purposes.
      delete parameters.mediaTypeExtension.enum;

      part = '.{mediaTypeExtension}';
    }

    // Recursively create (or select) the child resource. If the resource is
    // a single slash, it should be attached to the same object.
    if (part !== '/') {
      // Convert the uri part into a variable name.
      var key = toPropertyFormat(part, spec);

      // TODO: Handle duplicate variable names and missing variable names.
      if (!key || obj.children.hasOwnProperty(key)) {
        // Handle exact matching relative uris. If they don't match exactly,
        // it's impossible for us to handle generically.
        if (part === obj.children[key].relativeUri) {
          obj = obj.children[key];
        } else {
          return;
        }
      } else {
        var matches       = part.match(TEMPLATE_REGEXP) || [];
        var uriParameters = Array.prototype.map.call(matches, getParamTag);

        obj = obj.children[key] = {
          id:            spec.format.uniqueId('resource'),
          key:           key,
          parent:        obj,
          children:      {},
          relativeUri:   toUriFormat(part, spec),
          uriParameters: uriParameters
        };
      }
    }

    // Recursively append uri parts.
    if (parts.length > 1) {
      return recurse(obj, parts.slice(1));
    }

    obj.methods     = sanitizeMethods(resource.methods, obj, spec);
    obj.description = (resource.description || '').trim();

    if (resource.resources) {
      resource.resources.forEach(function (resource) {
        attachResource(obj, resource, spec);
      });
    }

    // TODO: Implement node backtracking when no methods are available.

    return obj;
  })(obj, uriParts);
};

/**
 * Sanitize resources into nested object form.
 *
 * @param  {Object} resources
 * @param  {Object} spec
 * @return {Object}
 */
module.exports = function (resources, spec) {
  // Create the root resource object for consistency of behaviour.
  var obj = {
    id:            spec.format.uniqueId('resource'),
    children:      {},
    relativeUri:   '',
    uriParameters: []
  };

  if (!resources) {
    return obj;
  }

  // Iterate over the resources array and attach each .
  resources.forEach(function (resource) {
    return attachResource(obj, resource, spec);
  });

  return obj;
};

},{"./methods":15,"./parameters":16,"./uri":19}],18:[function(require,module,exports){
/**
 * Sanitize resources into nested object form.
 *
 * @param  {Object} securitySchemes
 * @return {Object}
 */
module.exports = function (securitySchemes) {
  var obj = {};

  if (!Array.isArray(securitySchemes)) {
    return obj;
  }

  securitySchemes.forEach(function (schemes) {
    Object.keys(schemes).forEach(function (key) {
      var scheme = schemes[key];

      obj[scheme.type] = scheme;
    });
  });

  return obj;
};

},{}],19:[function(require,module,exports){
/**
 * Sanitize all uris.
 *
 * @param  {String} uri
 * @param  {Object} spec
 * @return {String}
 */
module.exports = function (uri, spec) {
  return spec.format.uri(uri || '').replace(/\/+$/, '');
};

},{}],20:[function(require,module,exports){
var extend        = require('extend');
var helpers       = require('./helpers');
var createContext = require('./context');

// Handlebars required in node to support `require('x.hbs')`.
require('handlebars');

/**
 * Compile an api client using a combination of the ast, spec and user data.
 *
 * @param  {Object} ast
 * @param  {Object} spec
 * @param  {Object} data
 * @return {Object}
 */
function generate (ast, spec, data) {
  // Handlebars compile options from the specification.
  var options = {
    data:     data,
    helpers:  extend({}, helpers, spec.helpers),
    partials: extend({}, spec.partials)
  };

  // Allow the language to override the file generator.
  var createFiles = spec.files || generateFiles;
  var context = createContext(ast, spec);
  var files = createFiles(spec.templates, context, options);

  // Create the compile object. We resolve this object instead of just the
  // files so that external utilities have access to the context object. For
  // example, the "API Notebook" project needs to add runtime documentation.
  return {
    files: files,
    context: context,
    options: options
  };
}

/**
 * Default file generator directly from templates.
 *
 * @param  {Object} templates
 * @param  {Object} context
 * @param  {Object} options
 * @return {Object}
 */
function generateFiles (templates, context, options) {
  var files = {};

  Object.keys(templates).forEach(function (key) {
    files[key] = templates[key](context, options);
  });

  return files;
}

/**
 * Generate a language specific client generator based on passed in spec.
 *
 * @param  {Object}   spec
 * @return {Function}
 */
module.exports = function (spec) {
  /**
   * Generate an API client by passed in an AST.
   *
   * @param  {Object} ast
   * @param  {Object} options
   * @return {Object}
   */
  return function (ast, options) {
    return generate(ast, spec, options);
  };
};

},{"./context":14,"./helpers":21,"extend":33,"handlebars":22}],21:[function(require,module,exports){
var indent = require('indent-string');
var trim   = String.prototype.trim;
var hasOwn = Object.prototype.hasOwnProperty;

/**
 * Case sanitization support.
 */
exports.camelCase    = require('camel-case');
exports.pascalCase   = require('pascal-case');
exports.constantCase = require('constant-case');
exports.paramCase    = require('param-case');
exports.lowerCase    = require('lower-case');
exports.upperCase    = require('upper-case');
exports.snakeCase    = require('snake-case');

/**
 * Formatting utilities.
 */
exports.indent = function (/* input, count, character, opts */) {
  var args      = Array.prototype.slice.call(arguments);
  var opts      = args.pop();
  var input     = (opts.fn ? opts.fn(this) : args[0]);
  var count     = (opts.fn ? args[0] : args[1]) || 2;
  var character = (opts.fn ? args[1] : args[2]) || ' ';

  return indent(input, character, count);
};

/**
 * The `||` conditional as a helper.
 *
 * @return {Boolean}
 */
exports.or = function (/* ...condition, opts */) {
  for (var i = 0; i < arguments.length - 1; i++) {
    if (arguments[i]) {
      return true;
    }
  }

  return false;
};

/**
 * The `&&` conditional as a helper.
 *
 * @return {Boolean}
 */
exports.and = function (/* ...condition, opts */) {
  for (var i = 0; i < arguments.length - 1; i++) {
    if (!arguments[i]) {
      return false;
    }
  }

  return true;
};

/**
 * The `!` conditional as a helper.
 *
 * @return {Boolean}
 */
exports.not = function (condition) {
  return !condition;
};

/**
 * Get the keys of an object.
 */
exports.keys = function (obj) {
  var keys = [];

  for (var prop in obj) {
    if (hasOwn.call(obj, prop)) {
      keys.push(prop);
    }
  }

  return keys;
};

/**
 * Return all the nested by the name.
 *
 * @param  {Object} obj
 * @param  {String} name
 * @return {Array}
 */
exports.pluck = function (obj, name) {
  return Object.keys(obj).map(function (key) {
    return obj[key] && obj[key][name];
  });
};

/**
 * Turn an array of keys into an object.
 *
 * @param  {Array}  keys
 * @param  {Array}  values
 * @return {Object}
 */
exports.object = function (keys, values) {
  var obj = {};

  for (var i = 0; i < keys.length; i++) {
    obj[keys[i]] = values[i];
  }

  return obj;
};

/**
 * Check whether a value is contained within an array.
 *
 * @param  {Array}   array
 * @param  {*}       value
 * @return {Boolean}
 */
exports.contains = function (array, value) {
  return array.indexOf(value) > -1;
};

/**
 * Debugging.
 */
exports.log = function () {
  var opts = arguments[arguments.length - 1];

  if (opts.fn) {
    console.log(opts.fn(this));
  } else {
    console.log.apply(console, Array.prototype.slice.call(arguments, 0, -1));
  }
};

/**
 * Trim a string.
 *
 * @return {String}
 */
exports.trim = function () {
  var opts = arguments[arguments.length - 1];

  if (arguments.length > 1) {
    return trim.call(arguments[0] == null ? '' : arguments[0]);
  }

  return trim.call(opts.fn(this));
};

/**
 * Check that a number of arguments are equal.
 *
 * @return {Boolean}
 */
exports.equal = function () {
  var args = Array.prototype.slice.call(arguments, 0, -1);
  var opts = arguments[arguments.length - 1];

  for (var i = 1; i < args.length; i++) {
    if (args[i - 1] !== args[i]) {
      return opts.fn ? opts.inverse(this) : false;
    }
  }

  return opts.fn ? opts.fn(this) : true;
};

/**
 * Serialize as a JSON string.
 *
 * @return {String}
 */
exports.json = function () {
  if (arguments.length > 2) {
    return JSON.stringify(arguments[0], null, arguments[1]);
  }

  if (arguments.length === 2) {
    return JSON.stringify(arguments[0]);
  }

  throw new Error('Unsupported usage of json helper');
};

/**
 * Join an array of values together.
 *
 * @param  {Array}  array
 * @param  {String} value
 * @return {String}
 */
exports.join = function (array, value) {
  return Array.isArray(array) ? array.join(value) : array;
};

},{"camel-case":27,"constant-case":32,"indent-string":42,"lower-case":46,"param-case":53,"pascal-case":55,"snake-case":60,"upper-case":61}],22:[function(require,module,exports){

},{}],23:[function(require,module,exports){
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
 * @license  MIT
 */

var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('is-array')

exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
Buffer.poolSize = 8192 // not used by this implementation

var kMaxLength = 0x3fffffff
var rootParent = {}

/**
 * If `Buffer.TYPED_ARRAY_SUPPORT`:
 *   === true    Use Uint8Array implementation (fastest)
 *   === false   Use Object implementation (most compatible, even IE6)
 *
 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
 * Opera 11.6+, iOS 4.2+.
 *
 * Note:
 *
 * - Implementation must support adding new properties to `Uint8Array` instances.
 *   Firefox 4-29 lacked support, fixed in Firefox 30+.
 *   See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
 *
 *  - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
 *
 *  - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
 *    incorrect length in some situations.
 *
 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will
 * get the Object implementation, which is slower but will work correctly.
 */
Buffer.TYPED_ARRAY_SUPPORT = (function () {
  try {
    var buf = new ArrayBuffer(0)
    var arr = new Uint8Array(buf)
    arr.foo = function () { return 42 }
    return arr.foo() === 42 && // typed array instances can be augmented
        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
        new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
  } catch (e) {
    return false
  }
})()

/**
 * Class: Buffer
 * =============
 *
 * The Buffer constructor returns instances of `Uint8Array` that are augmented
 * with function properties for all the node `Buffer` API functions. We use
 * `Uint8Array` so that square bracket notation works as expected -- it returns
 * a single octet.
 *
 * By augmenting the instances, we can avoid modifying the `Uint8Array`
 * prototype.
 */
function Buffer (subject, encoding, noZero) {
  if (!(this instanceof Buffer))
    return new Buffer(subject, encoding, noZero)

  var type = typeof subject

  // Find the length
  var length
  if (type === 'number') {
    length = +subject
  } else if (type === 'string') {
    length = Buffer.byteLength(subject, encoding)
  } else if (type === 'object' && subject !== null) { // assume object is array-like
    if (subject.type === 'Buffer' && isArray(subject.data))
      subject = subject.data
    length = +subject.length
  } else {
    throw new TypeError('must start with number, buffer, array or string')
  }

  if (length > kMaxLength)
    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
      'size: 0x' + kMaxLength.toString(16) + ' bytes')

  if (length < 0)
    length = 0
  else
    length >>>= 0 // Coerce to uint32.

  var self = this
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    // Preferred: Return an augmented `Uint8Array` instance for best performance
    /*eslint-disable consistent-this */
    self = Buffer._augment(new Uint8Array(length))
    /*eslint-enable consistent-this */
  } else {
    // Fallback: Return THIS instance of Buffer (created by `new`)
    self.length = length
    self._isBuffer = true
  }

  var i
  if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') {
    // Speed optimization -- use set if we're copying from a typed array
    self._set(subject)
  } else if (isArrayish(subject)) {
    // Treat array-ish objects as a byte array
    if (Buffer.isBuffer(subject)) {
      for (i = 0; i < length; i++)
        self[i] = subject.readUInt8(i)
    } else {
      for (i = 0; i < length; i++)
        self[i] = ((subject[i] % 256) + 256) % 256
    }
  } else if (type === 'string') {
    self.write(subject, 0, encoding)
  } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) {
    for (i = 0; i < length; i++) {
      self[i] = 0
    }
  }

  if (length > 0 && length <= Buffer.poolSize)
    self.parent = rootParent

  return self
}

function SlowBuffer (subject, encoding, noZero) {
  if (!(this instanceof SlowBuffer))
    return new SlowBuffer(subject, encoding, noZero)

  var buf = new Buffer(subject, encoding, noZero)
  delete buf.parent
  return buf
}

Buffer.isBuffer = function (b) {
  return !!(b != null && b._isBuffer)
}

Buffer.compare = function (a, b) {
  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b))
    throw new TypeError('Arguments must be Buffers')

  if (a === b) return 0

  var x = a.length
  var y = b.length
  for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
  if (i !== len) {
    x = a[i]
    y = b[i]
  }
  if (x < y) return -1
  if (y < x) return 1
  return 0
}

Buffer.isEncoding = function (encoding) {
  switch (String(encoding).toLowerCase()) {
    case 'hex':
    case 'utf8':
    case 'utf-8':
    case 'ascii':
    case 'binary':
    case 'base64':
    case 'raw':
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      return true
    default:
      return false
  }
}

Buffer.concat = function (list, totalLength) {
  if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])')

  if (list.length === 0) {
    return new Buffer(0)
  } else if (list.length === 1) {
    return list[0]
  }

  var i
  if (totalLength === undefined) {
    totalLength = 0
    for (i = 0; i < list.length; i++) {
      totalLength += list[i].length
    }
  }

  var buf = new Buffer(totalLength)
  var pos = 0
  for (i = 0; i < list.length; i++) {
    var item = list[i]
    item.copy(buf, pos)
    pos += item.length
  }
  return buf
}

Buffer.byteLength = function (str, encoding) {
  var ret
  str = str + ''
  switch (encoding || 'utf8') {
    case 'ascii':
    case 'binary':
    case 'raw':
      ret = str.length
      break
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      ret = str.length * 2
      break
    case 'hex':
      ret = str.length >>> 1
      break
    case 'utf8':
    case 'utf-8':
      ret = utf8ToBytes(str).length
      break
    case 'base64':
      ret = base64ToBytes(str).length
      break
    default:
      ret = str.length
  }
  return ret
}

// pre-set for values that may exist in the future
Buffer.prototype.length = undefined
Buffer.prototype.parent = undefined

// toString(encoding, start=0, end=buffer.length)
Buffer.prototype.toString = function (encoding, start, end) {
  var loweredCase = false

  start = start >>> 0
  end = end === undefined || end === Infinity ? this.length : end >>> 0

  if (!encoding) encoding = 'utf8'
  if (start < 0) start = 0
  if (end > this.length) end = this.length
  if (end <= start) return ''

  while (true) {
    switch (encoding) {
      case 'hex':
        return hexSlice(this, start, end)

      case 'utf8':
      case 'utf-8':
        return utf8Slice(this, start, end)

      case 'ascii':
        return asciiSlice(this, start, end)

      case 'binary':
        return binarySlice(this, start, end)

      case 'base64':
        return base64Slice(this, start, end)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return utf16leSlice(this, start, end)

      default:
        if (loweredCase)
          throw new TypeError('Unknown encoding: ' + encoding)
        encoding = (encoding + '').toLowerCase()
        loweredCase = true
    }
  }
}

Buffer.prototype.equals = function (b) {
  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  if (this === b) return true
  return Buffer.compare(this, b) === 0
}

Buffer.prototype.inspect = function () {
  var str = ''
  var max = exports.INSPECT_MAX_BYTES
  if (this.length > 0) {
    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
    if (this.length > max)
      str += ' ... '
  }
  return '<Buffer ' + str + '>'
}

Buffer.prototype.compare = function (b) {
  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  if (this === b) return 0
  return Buffer.compare(this, b)
}

// `get` will be removed in Node 0.13+
Buffer.prototype.get = function (offset) {
  console.log('.get() is deprecated. Access using array indexes instead.')
  return this.readUInt8(offset)
}

// `set` will be removed in Node 0.13+
Buffer.prototype.set = function (v, offset) {
  console.log('.set() is deprecated. Access using array indexes instead.')
  return this.writeUInt8(v, offset)
}

function hexWrite (buf, string, offset, length) {
  offset = Number(offset) || 0
  var remaining = buf.length - offset
  if (!length) {
    length = remaining
  } else {
    length = Number(length)
    if (length > remaining) {
      length = remaining
    }
  }

  // must be an even number of digits
  var strLen = string.length
  if (strLen % 2 !== 0) throw new Error('Invalid hex string')

  if (length > strLen / 2) {
    length = strLen / 2
  }
  for (var i = 0; i < length; i++) {
    var byte = parseInt(string.substr(i * 2, 2), 16)
    if (isNaN(byte)) throw new Error('Invalid hex string')
    buf[offset + i] = byte
  }
  return i
}

function utf8Write (buf, string, offset, length) {
  var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  return charsWritten
}

function asciiWrite (buf, string, offset, length) {
  var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
  return charsWritten
}

function binaryWrite (buf, string, offset, length) {
  return asciiWrite(buf, string, offset, length)
}

function base64Write (buf, string, offset, length) {
  var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
  return charsWritten
}

function utf16leWrite (buf, string, offset, length) {
  var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
  return charsWritten
}

Buffer.prototype.write = function (string, offset, length, encoding) {
  // Support both (string, offset, length, encoding)
  // and the legacy (string, encoding, offset, length)
  if (isFinite(offset)) {
    if (!isFinite(length)) {
      encoding = length
      length = undefined
    }
  } else {  // legacy
    var swap = encoding
    encoding = offset
    offset = length
    length = swap
  }

  offset = Number(offset) || 0

  if (length < 0 || offset < 0 || offset > this.length)
    throw new RangeError('attempt to write outside buffer bounds')

  var remaining = this.length - offset
  if (!length) {
    length = remaining
  } else {
    length = Number(length)
    if (length > remaining) {
      length = remaining
    }
  }
  encoding = String(encoding || 'utf8').toLowerCase()

  var ret
  switch (encoding) {
    case 'hex':
      ret = hexWrite(this, string, offset, length)
      break
    case 'utf8':
    case 'utf-8':
      ret = utf8Write(this, string, offset, length)
      break
    case 'ascii':
      ret = asciiWrite(this, string, offset, length)
      break
    case 'binary':
      ret = binaryWrite(this, string, offset, length)
      break
    case 'base64':
      ret = base64Write(this, string, offset, length)
      break
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      ret = utf16leWrite(this, string, offset, length)
      break
    default:
      throw new TypeError('Unknown encoding: ' + encoding)
  }
  return ret
}

Buffer.prototype.toJSON = function () {
  return {
    type: 'Buffer',
    data: Array.prototype.slice.call(this._arr || this, 0)
  }
}

function base64Slice (buf, start, end) {
  if (start === 0 && end === buf.length) {
    return base64.fromByteArray(buf)
  } else {
    return base64.fromByteArray(buf.slice(start, end))
  }
}

function utf8Slice (buf, start, end) {
  var res = ''
  var tmp = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; i++) {
    if (buf[i] <= 0x7F) {
      res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
      tmp = ''
    } else {
      tmp += '%' + buf[i].toString(16)
    }
  }

  return res + decodeUtf8Char(tmp)
}

function asciiSlice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; i++) {
    ret += String.fromCharCode(buf[i] & 0x7F)
  }
  return ret
}

function binarySlice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; i++) {
    ret += String.fromCharCode(buf[i])
  }
  return ret
}

function hexSlice (buf, start, end) {
  var len = buf.length

  if (!start || start < 0) start = 0
  if (!end || end < 0 || end > len) end = len

  var out = ''
  for (var i = start; i < end; i++) {
    out += toHex(buf[i])
  }
  return out
}

function utf16leSlice (buf, start, end) {
  var bytes = buf.slice(start, end)
  var res = ''
  for (var i = 0; i < bytes.length; i += 2) {
    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
  }
  return res
}

Buffer.prototype.slice = function (start, end) {
  var len = this.length
  start = ~~start
  end = end === undefined ? len : ~~end

  if (start < 0) {
    start += len
    if (start < 0)
      start = 0
  } else if (start > len) {
    start = len
  }

  if (end < 0) {
    end += len
    if (end < 0)
      end = 0
  } else if (end > len) {
    end = len
  }

  if (end < start)
    end = start

  var newBuf
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    newBuf = Buffer._augment(this.subarray(start, end))
  } else {
    var sliceLen = end - start
    newBuf = new Buffer(sliceLen, undefined, true)
    for (var i = 0; i < sliceLen; i++) {
      newBuf[i] = this[i + start]
    }
  }

  if (newBuf.length)
    newBuf.parent = this.parent || this

  return newBuf
}

/*
 * Need to make sure that buffer isn't trying to write out of bounds.
 */
function checkOffset (offset, ext, length) {
  if ((offset % 1) !== 0 || offset < 0)
    throw new RangeError('offset is not uint')
  if (offset + ext > length)
    throw new RangeError('Trying to access beyond buffer length')
}

Buffer.prototype.readUIntLE = function (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert)
    checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100))
    val += this[offset + i] * mul

  return val
}

Buffer.prototype.readUIntBE = function (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert)
    checkOffset(offset, byteLength, this.length)

  var val = this[offset + --byteLength]
  var mul = 1
  while (byteLength > 0 && (mul *= 0x100))
    val += this[offset + --byteLength] * mul

  return val
}

Buffer.prototype.readUInt8 = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 1, this.length)
  return this[offset]
}

Buffer.prototype.readUInt16LE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 2, this.length)
  return this[offset] | (this[offset + 1] << 8)
}

Buffer.prototype.readUInt16BE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 2, this.length)
  return (this[offset] << 8) | this[offset + 1]
}

Buffer.prototype.readUInt32LE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 4, this.length)

  return ((this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16)) +
      (this[offset + 3] * 0x1000000)
}

Buffer.prototype.readUInt32BE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 4, this.length)

  return (this[offset] * 0x1000000) +
      ((this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      this[offset + 3])
}

Buffer.prototype.readIntLE = function (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert)
    checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100))
    val += this[offset + i] * mul
  mul *= 0x80

  if (val >= mul)
    val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readIntBE = function (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert)
    checkOffset(offset, byteLength, this.length)

  var i = byteLength
  var mul = 1
  var val = this[offset + --i]
  while (i > 0 && (mul *= 0x100))
    val += this[offset + --i] * mul
  mul *= 0x80

  if (val >= mul)
    val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readInt8 = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 1, this.length)
  if (!(this[offset] & 0x80))
    return (this[offset])
  return ((0xff - this[offset] + 1) * -1)
}

Buffer.prototype.readInt16LE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 2, this.length)
  var val = this[offset] | (this[offset + 1] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt16BE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 2, this.length)
  var val = this[offset + 1] | (this[offset] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt32LE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 4, this.length)

  return (this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16) |
      (this[offset + 3] << 24)
}

Buffer.prototype.readInt32BE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 4, this.length)

  return (this[offset] << 24) |
      (this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      (this[offset + 3])
}

Buffer.prototype.readFloatLE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, true, 23, 4)
}

Buffer.prototype.readFloatBE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, false, 23, 4)
}

Buffer.prototype.readDoubleLE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, true, 52, 8)
}

Buffer.prototype.readDoubleBE = function (offset, noAssert) {
  if (!noAssert)
    checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, false, 52, 8)
}

function checkInt (buf, value, offset, ext, max, min) {
  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
  if (value > max || value < min) throw new RangeError('value is out of bounds')
  if (offset + ext > buf.length) throw new RangeError('index out of range')
}

Buffer.prototype.writeUIntLE = function (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert)
    checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)

  var mul = 1
  var i = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100))
    this[offset + i] = (value / mul) >>> 0 & 0xFF

  return offset + byteLength
}

Buffer.prototype.writeUIntBE = function (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert)
    checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)

  var i = byteLength - 1
  var mul = 1
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100))
    this[offset + i] = (value / mul) >>> 0 & 0xFF

  return offset + byteLength
}

Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 1, 0xff, 0)
  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
  this[offset] = value
  return offset + 1
}

function objectWriteUInt16 (buf, value, offset, littleEndian) {
  if (value < 0) value = 0xffff + value + 1
  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
      (littleEndian ? i : 1 - i) * 8
  }
}

Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 2, 0xffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = value
    this[offset + 1] = (value >>> 8)
  } else objectWriteUInt16(this, value, offset, true)
  return offset + 2
}

Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 2, 0xffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 8)
    this[offset + 1] = value
  } else objectWriteUInt16(this, value, offset, false)
  return offset + 2
}

function objectWriteUInt32 (buf, value, offset, littleEndian) {
  if (value < 0) value = 0xffffffff + value + 1
  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
  }
}

Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 4, 0xffffffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset + 3] = (value >>> 24)
    this[offset + 2] = (value >>> 16)
    this[offset + 1] = (value >>> 8)
    this[offset] = value
  } else objectWriteUInt32(this, value, offset, true)
  return offset + 4
}

Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 4, 0xffffffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 24)
    this[offset + 1] = (value >>> 16)
    this[offset + 2] = (value >>> 8)
    this[offset + 3] = value
  } else objectWriteUInt32(this, value, offset, false)
  return offset + 4
}

Buffer.prototype.writeIntLE = function (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    checkInt(this,
             value,
             offset,
             byteLength,
             Math.pow(2, 8 * byteLength - 1) - 1,
             -Math.pow(2, 8 * byteLength - 1))
  }

  var i = 0
  var mul = 1
  var sub = value < 0 ? 1 : 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100))
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF

  return offset + byteLength
}

Buffer.prototype.writeIntBE = function (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    checkInt(this,
             value,
             offset,
             byteLength,
             Math.pow(2, 8 * byteLength - 1) - 1,
             -Math.pow(2, 8 * byteLength - 1))
  }

  var i = byteLength - 1
  var mul = 1
  var sub = value < 0 ? 1 : 0
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100))
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF

  return offset + byteLength
}

Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 1, 0x7f, -0x80)
  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
  if (value < 0) value = 0xff + value + 1
  this[offset] = value
  return offset + 1
}

Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = value
    this[offset + 1] = (value >>> 8)
  } else objectWriteUInt16(this, value, offset, true)
  return offset + 2
}

Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 8)
    this[offset + 1] = value
  } else objectWriteUInt16(this, value, offset, false)
  return offset + 2
}

Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = value
    this[offset + 1] = (value >>> 8)
    this[offset + 2] = (value >>> 16)
    this[offset + 3] = (value >>> 24)
  } else objectWriteUInt32(this, value, offset, true)
  return offset + 4
}

Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert)
    checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  if (value < 0) value = 0xffffffff + value + 1
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 24)
    this[offset + 1] = (value >>> 16)
    this[offset + 2] = (value >>> 8)
    this[offset + 3] = value
  } else objectWriteUInt32(this, value, offset, false)
  return offset + 4
}

function checkIEEE754 (buf, value, offset, ext, max, min) {
  if (value > max || value < min) throw new RangeError('value is out of bounds')
  if (offset + ext > buf.length) throw new RangeError('index out of range')
  if (offset < 0) throw new RangeError('index out of range')
}

function writeFloat (buf, value, offset, littleEndian, noAssert) {
  if (!noAssert)
    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
  ieee754.write(buf, value, offset, littleEndian, 23, 4)
  return offset + 4
}

Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
  return writeFloat(this, value, offset, true, noAssert)
}

Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
  return writeFloat(this, value, offset, false, noAssert)
}

function writeDouble (buf, value, offset, littleEndian, noAssert) {
  if (!noAssert)
    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
  ieee754.write(buf, value, offset, littleEndian, 52, 8)
  return offset + 8
}

Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
  return writeDouble(this, value, offset, true, noAssert)
}

Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
  return writeDouble(this, value, offset, false, noAssert)
}

// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function (target, target_start, start, end) {
  var self = this // source

  if (!start) start = 0
  if (!end && end !== 0) end = this.length
  if (target_start >= target.length) target_start = target.length
  if (!target_start) target_start = 0
  if (end > 0 && end < start) end = start

  // Copy 0 bytes; we're done
  if (end === start) return 0
  if (target.length === 0 || self.length === 0) return 0

  // Fatal error conditions
  if (target_start < 0)
    throw new RangeError('targetStart out of bounds')
  if (start < 0 || start >= self.length) throw new RangeError('sourceStart out of bounds')
  if (end < 0) throw new RangeError('sourceEnd out of bounds')

  // Are we oob?
  if (end > this.length)
    end = this.length
  if (target.length - target_start < end - start)
    end = target.length - target_start + start

  var len = end - start

  if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
    for (var i = 0; i < len; i++) {
      target[i + target_start] = this[i + start]
    }
  } else {
    target._set(this.subarray(start, start + len), target_start)
  }

  return len
}

// fill(value, start=0, end=buffer.length)
Buffer.prototype.fill = function (value, start, end) {
  if (!value) value = 0
  if (!start) start = 0
  if (!end) end = this.length

  if (end < start) throw new RangeError('end < start')

  // Fill 0 bytes; we're done
  if (end === start) return
  if (this.length === 0) return

  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')

  var i
  if (typeof value === 'number') {
    for (i = start; i < end; i++) {
      this[i] = value
    }
  } else {
    var bytes = utf8ToBytes(value.toString())
    var len = bytes.length
    for (i = start; i < end; i++) {
      this[i] = bytes[i % len]
    }
  }

  return this
}

/**
 * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
 * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
 */
Buffer.prototype.toArrayBuffer = function () {
  if (typeof Uint8Array !== 'undefined') {
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      return (new Buffer(this)).buffer
    } else {
      var buf = new Uint8Array(this.length)
      for (var i = 0, len = buf.length; i < len; i += 1) {
        buf[i] = this[i]
      }
      return buf.buffer
    }
  } else {
    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
  }
}

// HELPER FUNCTIONS
// ================

var BP = Buffer.prototype

/**
 * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
 */
Buffer._augment = function (arr) {
  arr.constructor = Buffer
  arr._isBuffer = true

  // save reference to original Uint8Array get/set methods before overwriting
  arr._get = arr.get
  arr._set = arr.set

  // deprecated, will be removed in node 0.13+
  arr.get = BP.get
  arr.set = BP.set

  arr.write = BP.write
  arr.toString = BP.toString
  arr.toLocaleString = BP.toString
  arr.toJSON = BP.toJSON
  arr.equals = BP.equals
  arr.compare = BP.compare
  arr.copy = BP.copy
  arr.slice = BP.slice
  arr.readUIntLE = BP.readUIntLE
  arr.readUIntBE = BP.readUIntBE
  arr.readUInt8 = BP.readUInt8
  arr.readUInt16LE = BP.readUInt16LE
  arr.readUInt16BE = BP.readUInt16BE
  arr.readUInt32LE = BP.readUInt32LE
  arr.readUInt32BE = BP.readUInt32BE
  arr.readIntLE = BP.readIntLE
  arr.readIntBE = BP.readIntBE
  arr.readInt8 = BP.readInt8
  arr.readInt16LE = BP.readInt16LE
  arr.readInt16BE = BP.readInt16BE
  arr.readInt32LE = BP.readInt32LE
  arr.readInt32BE = BP.readInt32BE
  arr.readFloatLE = BP.readFloatLE
  arr.readFloatBE = BP.readFloatBE
  arr.readDoubleLE = BP.readDoubleLE
  arr.readDoubleBE = BP.readDoubleBE
  arr.writeUInt8 = BP.writeUInt8
  arr.writeUIntLE = BP.writeUIntLE
  arr.writeUIntBE = BP.writeUIntBE
  arr.writeUInt16LE = BP.writeUInt16LE
  arr.writeUInt16BE = BP.writeUInt16BE
  arr.writeUInt32LE = BP.writeUInt32LE
  arr.writeUInt32BE = BP.writeUInt32BE
  arr.writeIntLE = BP.writeIntLE
  arr.writeIntBE = BP.writeIntBE
  arr.writeInt8 = BP.writeInt8
  arr.writeInt16LE = BP.writeInt16LE
  arr.writeInt16BE = BP.writeInt16BE
  arr.writeInt32LE = BP.writeInt32LE
  arr.writeInt32BE = BP.writeInt32BE
  arr.writeFloatLE = BP.writeFloatLE
  arr.writeFloatBE = BP.writeFloatBE
  arr.writeDoubleLE = BP.writeDoubleLE
  arr.writeDoubleBE = BP.writeDoubleBE
  arr.fill = BP.fill
  arr.inspect = BP.inspect
  arr.toArrayBuffer = BP.toArrayBuffer

  return arr
}

var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g

function base64clean (str) {
  // Node strips out invalid characters like \n and \t from the string, base64-js does not
  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
  // Node converts strings with length < 2 to ''
  if (str.length < 2) return ''
  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  while (str.length % 4 !== 0) {
    str = str + '='
  }
  return str
}

function stringtrim (str) {
  if (str.trim) return str.trim()
  return str.replace(/^\s+|\s+$/g, '')
}

function isArrayish (subject) {
  return isArray(subject) || Buffer.isBuffer(subject) ||
      subject && typeof subject === 'object' &&
      typeof subject.length === 'number'
}

function toHex (n) {
  if (n < 16) return '0' + n.toString(16)
  return n.toString(16)
}

function utf8ToBytes (string, units) {
  units = units || Infinity
  var codePoint
  var length = string.length
  var leadSurrogate = null
  var bytes = []
  var i = 0

  for (; i < length; i++) {
    codePoint = string.charCodeAt(i)

    // is surrogate component
    if (codePoint > 0xD7FF && codePoint < 0xE000) {
      // last char was a lead
      if (leadSurrogate) {
        // 2 leads in a row
        if (codePoint < 0xDC00) {
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          leadSurrogate = codePoint
          continue
        } else {
          // valid surrogate pair
          codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
          leadSurrogate = null
        }
      } else {
        // no lead yet

        if (codePoint > 0xDBFF) {
          // unexpected trail
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        } else if (i + 1 === length) {
          // unpaired lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        } else {
          // valid lead
          leadSurrogate = codePoint
          continue
        }
      }
    } else if (leadSurrogate) {
      // valid bmp char, but last char was a lead
      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
      leadSurrogate = null
    }

    // encode utf8
    if (codePoint < 0x80) {
      if ((units -= 1) < 0) break
      bytes.push(codePoint)
    } else if (codePoint < 0x800) {
      if ((units -= 2) < 0) break
      bytes.push(
        codePoint >> 0x6 | 0xC0,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x10000) {
      if ((units -= 3) < 0) break
      bytes.push(
        codePoint >> 0xC | 0xE0,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x200000) {
      if ((units -= 4) < 0) break
      bytes.push(
        codePoint >> 0x12 | 0xF0,
        codePoint >> 0xC & 0x3F | 0x80,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else {
      throw new Error('Invalid code point')
    }
  }

  return bytes
}

function asciiToBytes (str) {
  var byteArray = []
  for (var i = 0; i < str.length; i++) {
    // Node's code seems to be doing this and not & 0x7F..
    byteArray.push(str.charCodeAt(i) & 0xFF)
  }
  return byteArray
}

function utf16leToBytes (str, units) {
  var c, hi, lo
  var byteArray = []
  for (var i = 0; i < str.length; i++) {
    if ((units -= 2) < 0) break

    c = str.charCodeAt(i)
    hi = c >> 8
    lo = c % 256
    byteArray.push(lo)
    byteArray.push(hi)
  }

  return byteArray
}

function base64ToBytes (str) {
  return base64.toByteArray(base64clean(str))
}

function blitBuffer (src, dst, offset, length) {
  for (var i = 0; i < length; i++) {
    if ((i + offset >= dst.length) || (i >= src.length))
      break
    dst[i + offset] = src[i]
  }
  return i
}

function decodeUtf8Char (str) {
  try {
    return decodeURIComponent(str)
  } catch (err) {
    return String.fromCharCode(0xFFFD) // UTF 8 invalid char
  }
}

},{"base64-js":24,"ieee754":25,"is-array":26}],24:[function(require,module,exports){
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

;(function (exports) {
	'use strict';

  var Arr = (typeof Uint8Array !== 'undefined')
    ? Uint8Array
    : Array

	var PLUS   = '+'.charCodeAt(0)
	var SLASH  = '/'.charCodeAt(0)
	var NUMBER = '0'.charCodeAt(0)
	var LOWER  = 'a'.charCodeAt(0)
	var UPPER  = 'A'.charCodeAt(0)
	var PLUS_URL_SAFE = '-'.charCodeAt(0)
	var SLASH_URL_SAFE = '_'.charCodeAt(0)

	function decode (elt) {
		var code = elt.charCodeAt(0)
		if (code === PLUS ||
		    code === PLUS_URL_SAFE)
			return 62 // '+'
		if (code === SLASH ||
		    code === SLASH_URL_SAFE)
			return 63 // '/'
		if (code < NUMBER)
			return -1 //no match
		if (code < NUMBER + 10)
			return code - NUMBER + 26 + 26
		if (code < UPPER + 26)
			return code - UPPER
		if (code < LOWER + 26)
			return code - LOWER + 26
	}

	function b64ToByteArray (b64) {
		var i, j, l, tmp, placeHolders, arr

		if (b64.length % 4 > 0) {
			throw new Error('Invalid string. Length must be a multiple of 4')
		}

		// the number of equal signs (place holders)
		// if there are two placeholders, than the two characters before it
		// represent one byte
		// if there is only one, then the three characters before it represent 2 bytes
		// this is just a cheap hack to not do indexOf twice
		var len = b64.length
		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0

		// base64 is 4/3 + up to two characters of the original data
		arr = new Arr(b64.length * 3 / 4 - placeHolders)

		// if there are placeholders, only get up to the last complete 4 chars
		l = placeHolders > 0 ? b64.length - 4 : b64.length

		var L = 0

		function push (v) {
			arr[L++] = v
		}

		for (i = 0, j = 0; i < l; i += 4, j += 3) {
			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
			push((tmp & 0xFF0000) >> 16)
			push((tmp & 0xFF00) >> 8)
			push(tmp & 0xFF)
		}

		if (placeHolders === 2) {
			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
			push(tmp & 0xFF)
		} else if (placeHolders === 1) {
			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
			push((tmp >> 8) & 0xFF)
			push(tmp & 0xFF)
		}

		return arr
	}

	function uint8ToBase64 (uint8) {
		var i,
			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
			output = "",
			temp, length

		function encode (num) {
			return lookup.charAt(num)
		}

		function tripletToBase64 (num) {
			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
		}

		// go through the array every three bytes, we'll deal with trailing stuff later
		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
			output += tripletToBase64(temp)
		}

		// pad the end with zeros, but make sure to not forget the extra bytes
		switch (extraBytes) {
			case 1:
				temp = uint8[uint8.length - 1]
				output += encode(temp >> 2)
				output += encode((temp << 4) & 0x3F)
				output += '=='
				break
			case 2:
				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
				output += encode(temp >> 10)
				output += encode((temp >> 4) & 0x3F)
				output += encode((temp << 2) & 0x3F)
				output += '='
				break
		}

		return output
	}

	exports.toByteArray = b64ToByteArray
	exports.fromByteArray = uint8ToBase64
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))

},{}],25:[function(require,module,exports){
exports.read = function(buffer, offset, isLE, mLen, nBytes) {
  var e, m,
      eLen = nBytes * 8 - mLen - 1,
      eMax = (1 << eLen) - 1,
      eBias = eMax >> 1,
      nBits = -7,
      i = isLE ? (nBytes - 1) : 0,
      d = isLE ? -1 : 1,
      s = buffer[offset + i];

  i += d;

  e = s & ((1 << (-nBits)) - 1);
  s >>= (-nBits);
  nBits += eLen;
  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);

  m = e & ((1 << (-nBits)) - 1);
  e >>= (-nBits);
  nBits += mLen;
  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);

  if (e === 0) {
    e = 1 - eBias;
  } else if (e === eMax) {
    return m ? NaN : ((s ? -1 : 1) * Infinity);
  } else {
    m = m + Math.pow(2, mLen);
    e = e - eBias;
  }
  return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
};

exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
  var e, m, c,
      eLen = nBytes * 8 - mLen - 1,
      eMax = (1 << eLen) - 1,
      eBias = eMax >> 1,
      rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
      i = isLE ? 0 : (nBytes - 1),
      d = isLE ? 1 : -1,
      s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;

  value = Math.abs(value);

  if (isNaN(value) || value === Infinity) {
    m = isNaN(value) ? 1 : 0;
    e = eMax;
  } else {
    e = Math.floor(Math.log(value) / Math.LN2);
    if (value * (c = Math.pow(2, -e)) < 1) {
      e--;
      c *= 2;
    }
    if (e + eBias >= 1) {
      value += rt / c;
    } else {
      value += rt * Math.pow(2, 1 - eBias);
    }
    if (value * c >= 2) {
      e++;
      c /= 2;
    }

    if (e + eBias >= eMax) {
      m = 0;
      e = eMax;
    } else if (e + eBias >= 1) {
      m = (value * c - 1) * Math.pow(2, mLen);
      e = e + eBias;
    } else {
      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
      e = 0;
    }
  }

  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);

  e = (e << mLen) | m;
  eLen += mLen;
  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);

  buffer[offset + i - d] |= s * 128;
};

},{}],26:[function(require,module,exports){

/**
 * isArray
 */

var isArray = Array.isArray;

/**
 * toString
 */

var str = Object.prototype.toString;

/**
 * Whether or not the given `val`
 * is an array.
 *
 * example:
 *
 *        isArray([]);
 *        // > true
 *        isArray(arguments);
 *        // > false
 *        isArray('');
 *        // > false
 *
 * @param {mixed} val
 * @return {bool}
 */

module.exports = isArray || function (val) {
  return !! val && '[object Array]' == str.call(val);
};

},{}],27:[function(require,module,exports){
var upperCase    = require('upper-case');
var sentenceCase = require('sentence-case');

/**
 * Camel case a string.
 *
 * @param  {String} string
 * @param  {String} [locale]
 * @return {String}
 */
module.exports = function (string, locale) {
  return sentenceCase(string, locale)
    // Replace periods between numeric entities with an underscore.
    .replace(/(\d) (?=\d)/g, '$1_')
    // Replace spaces between words with an upper cased character.
    .replace(/ (.)/g, function (m, $1) {
      return upperCase($1, locale);
    });
};

},{"sentence-case":28,"upper-case":61}],28:[function(require,module,exports){
var lowerCase = require('lower-case')

var NON_WORD_REGEXP = require('./vendor/non-word-regexp')
var CAMEL_CASE_REGEXP = require('./vendor/camel-case-regexp')
var TRAILING_DIGIT_REGEXP = require('./vendor/trailing-digit-regexp')

/**
 * Sentence case a string.
 *
 * @param  {String} str
 * @param  {String} locale
 * @param  {String} replacement
 * @return {String}
 */
module.exports = function (str, locale, replacement) {
  if (str == null) {
    return ''
  }

  replacement = replacement || ' '

  function replace (match, index, string) {
    if (index === 0 || index === (string.length - match.length)) {
      return ''
    }

    return replacement
  }

  str = String(str)
    // Support camel case ("camelCase" -> "camel Case").
    .replace(CAMEL_CASE_REGEXP, '$1 $2')
    // Support digit groups ("test2012" -> "test 2012").
    .replace(TRAILING_DIGIT_REGEXP, '$1 $2')
    // Remove all non-word characters and replace with a single space.
    .replace(NON_WORD_REGEXP, replace)

  // Lower case the entire string.
  return lowerCase(str, locale)
}

},{"./vendor/camel-case-regexp":29,"./vendor/non-word-regexp":30,"./vendor/trailing-digit-regexp":31,"lower-case":46}],29:[function(require,module,exports){
module.exports = /([\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0561-\u0587\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7FA\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A])([\u0041-\u005A\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA\uFF21-\uFF3A\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])/g

},{}],30:[function(require,module,exports){
module.exports = /[^\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]+/g

},{}],31:[function(require,module,exports){
module.exports = /([\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])([^\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])/g

},{}],32:[function(require,module,exports){
var upperCase = require('upper-case');
var snakeCase = require('snake-case');

/**
 * Constant case a string.
 *
 * @param  {String} string
 * @param  {String} [locale]
 * @return {String}
 */
module.exports = function (string, locale) {
  return upperCase(snakeCase(string, locale), locale);
};

},{"snake-case":60,"upper-case":61}],33:[function(require,module,exports){
var hasOwn = Object.prototype.hasOwnProperty;
var toString = Object.prototype.toString;
var undefined;

var isPlainObject = function isPlainObject(obj) {
	'use strict';
	if (!obj || toString.call(obj) !== '[object Object]') {
		return false;
	}

	var has_own_constructor = hasOwn.call(obj, 'constructor');
	var has_is_property_of_method = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
	// Not own constructor property must be Object
	if (obj.constructor && !has_own_constructor && !has_is_property_of_method) {
		return false;
	}

	// Own properties are enumerated firstly, so to speed up,
	// if last one is own, then all properties are own.
	var key;
	for (key in obj) {}

	return key === undefined || hasOwn.call(obj, key);
};

module.exports = function extend() {
	'use strict';
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[0],
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if (typeof target === 'boolean') {
		deep = target;
		target = arguments[1] || {};
		// skip the boolean and the target
		i = 2;
	} else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {
		target = {};
	}

	for (; i < length; ++i) {
		options = arguments[i];
		// Only deal with non-null/undefined values
		if (options != null) {
			// Extend the base object
			for (name in options) {
				src = target[name];
				copy = options[name];

				// Prevent never-ending loop
				if (target === copy) {
					continue;
				}

				// Recurse if we're merging plain objects or arrays
				if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
					if (copyIsArray) {
						copyIsArray = false;
						clone = src && Array.isArray(src) ? src : [];
					} else {
						clone = src && isPlainObject(src) ? src : {};
					}

					// Never move original objects, clone them
					target[name] = extend(deep, clone, copy);

				// Don't bring in undefined values
				} else if (copy !== undefined) {
					target[name] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};


},{}],34:[function(require,module,exports){
(function (global){
"use strict";
/*globals Handlebars: true */
var base = require("./handlebars/base");

// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
var SafeString = require("./handlebars/safe-string")["default"];
var Exception = require("./handlebars/exception")["default"];
var Utils = require("./handlebars/utils");
var runtime = require("./handlebars/runtime");

// For compatibility and usage outside of module systems, make the Handlebars object a namespace
var create = function() {
  var hb = new base.HandlebarsEnvironment();

  Utils.extend(hb, base);
  hb.SafeString = SafeString;
  hb.Exception = Exception;
  hb.Utils = Utils;
  hb.escapeExpression = Utils.escapeExpression;

  hb.VM = runtime;
  hb.template = function(spec) {
    return runtime.template(spec, hb);
  };

  return hb;
};

var Handlebars = create();
Handlebars.create = create;

/*jshint -W040 */
/* istanbul ignore next */
var root = typeof global !== 'undefined' ? global : window,
    $Handlebars = root.Handlebars;
/* istanbul ignore next */
Handlebars.noConflict = function() {
  if (root.Handlebars === Handlebars) {
    root.Handlebars = $Handlebars;
  }
};

Handlebars['default'] = Handlebars;

exports["default"] = Handlebars;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./handlebars/base":35,"./handlebars/exception":36,"./handlebars/runtime":37,"./handlebars/safe-string":38,"./handlebars/utils":39}],35:[function(require,module,exports){
"use strict";
var Utils = require("./utils");
var Exception = require("./exception")["default"];

var VERSION = "3.0.0";
exports.VERSION = VERSION;var COMPILER_REVISION = 6;
exports.COMPILER_REVISION = COMPILER_REVISION;
var REVISION_CHANGES = {
  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
  2: '== 1.0.0-rc.3',
  3: '== 1.0.0-rc.4',
  4: '== 1.x.x',
  5: '== 2.0.0-alpha.x',
  6: '>= 2.0.0-beta.1'
};
exports.REVISION_CHANGES = REVISION_CHANGES;
var isArray = Utils.isArray,
    isFunction = Utils.isFunction,
    toString = Utils.toString,
    objectType = '[object Object]';

function HandlebarsEnvironment(helpers, partials) {
  this.helpers = helpers || {};
  this.partials = partials || {};

  registerDefaultHelpers(this);
}

exports.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
  constructor: HandlebarsEnvironment,

  logger: logger,
  log: log,

  registerHelper: function(name, fn) {
    if (toString.call(name) === objectType) {
      if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
      Utils.extend(this.helpers, name);
    } else {
      this.helpers[name] = fn;
    }
  },
  unregisterHelper: function(name) {
    delete this.helpers[name];
  },

  registerPartial: function(name, partial) {
    if (toString.call(name) === objectType) {
      Utils.extend(this.partials,  name);
    } else {
      if (typeof partial === 'undefined') {
        throw new Exception('Attempting to register a partial as undefined');
      }
      this.partials[name] = partial;
    }
  },
  unregisterPartial: function(name) {
    delete this.partials[name];
  }
};

function registerDefaultHelpers(instance) {
  instance.registerHelper('helperMissing', function(/* [args, ]options */) {
    if(arguments.length === 1) {
      // A missing field in a {{foo}} constuct.
      return undefined;
    } else {
      // Someone is actually trying to call something, blow up.
      throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
    }
  });

  instance.registerHelper('blockHelperMissing', function(context, options) {
    var inverse = options.inverse,
        fn = options.fn;

    if(context === true) {
      return fn(this);
    } else if(context === false || context == null) {
      return inverse(this);
    } else if (isArray(context)) {
      if(context.length > 0) {
        if (options.ids) {
          options.ids = [options.name];
        }

        return instance.helpers.each(context, options);
      } else {
        return inverse(this);
      }
    } else {
      if (options.data && options.ids) {
        var data = createFrame(options.data);
        data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
        options = {data: data};
      }

      return fn(context, options);
    }
  });

  instance.registerHelper('each', function(context, options) {
    if (!options) {
      throw new Exception('Must pass iterator to #each');
    }

    var fn = options.fn, inverse = options.inverse;
    var i = 0, ret = "", data;

    var contextPath;
    if (options.data && options.ids) {
      contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
    }

    if (isFunction(context)) { context = context.call(this); }

    if (options.data) {
      data = createFrame(options.data);
    }

    function execIteration(key, i, last) {
      if (data) {
        data.key = key;
        data.index = i;
        data.first = i === 0;
        data.last  = !!last;

        if (contextPath) {
          data.contextPath = contextPath + key;
        }
      }

      ret = ret + fn(context[key], {
        data: data,
        blockParams: Utils.blockParams([context[key], key], [contextPath + key, null])
      });
    }

    if(context && typeof context === 'object') {
      if (isArray(context)) {
        for(var j = context.length; i<j; i++) {
          execIteration(i, i, i === context.length-1);
        }
      } else {
        var priorKey;

        for(var key in context) {
          if(context.hasOwnProperty(key)) {
            // We're running the iterations one step out of sync so we can detect
            // the last iteration without have to scan the object twice and create
            // an itermediate keys array. 
            if (priorKey) {
              execIteration(priorKey, i-1);
            }
            priorKey = key;
            i++;
          }
        }
        if (priorKey) {
          execIteration(priorKey, i-1, true);
        }
      }
    }

    if(i === 0){
      ret = inverse(this);
    }

    return ret;
  });

  instance.registerHelper('if', function(conditional, options) {
    if (isFunction(conditional)) { conditional = conditional.call(this); }

    // Default behavior is to render the positive path if the value is truthy and not empty.
    // The `includeZero` option may be set to treat the condtional as purely not empty based on the
    // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
    if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
      return options.inverse(this);
    } else {
      return options.fn(this);
    }
  });

  instance.registerHelper('unless', function(conditional, options) {
    return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
  });

  instance.registerHelper('with', function(context, options) {
    if (isFunction(context)) { context = context.call(this); }

    var fn = options.fn;

    if (!Utils.isEmpty(context)) {
      if (options.data && options.ids) {
        var data = createFrame(options.data);
        data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
        options = {data:data};
      }

      return fn(context, options);
    } else {
      return options.inverse(this);
    }
  });

  instance.registerHelper('log', function(message, options) {
    var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
    instance.log(level, message);
  });

  instance.registerHelper('lookup', function(obj, field) {
    return obj && obj[field];
  });
}

var logger = {
  methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },

  // State enum
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3,
  level: 1,

  // Can be overridden in the host environment
  log: function(level, message) {
    if (typeof console !== 'undefined' && logger.level <= level) {
      var method = logger.methodMap[level];
      (console[method] || console.log).call(console, message);
    }
  }
};
exports.logger = logger;
var log = logger.log;
exports.log = log;
var createFrame = function(object) {
  var frame = Utils.extend({}, object);
  frame._parent = object;
  return frame;
};
exports.createFrame = createFrame;
},{"./exception":36,"./utils":39}],36:[function(require,module,exports){
"use strict";

var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];

function Exception(message, node) {
  var loc = node && node.loc,
      line,
      column;
  if (loc) {
    line = loc.start.line;
    column = loc.start.column;

    message += ' - ' + line + ':' + column;
  }

  var tmp = Error.prototype.constructor.call(this, message);

  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
  for (var idx = 0; idx < errorProps.length; idx++) {
    this[errorProps[idx]] = tmp[errorProps[idx]];
  }

  if (loc) {
    this.lineNumber = line;
    this.column = column;
  }
}

Exception.prototype = new Error();

exports["default"] = Exception;
},{}],37:[function(require,module,exports){
"use strict";
var Utils = require("./utils");
var Exception = require("./exception")["default"];
var COMPILER_REVISION = require("./base").COMPILER_REVISION;
var REVISION_CHANGES = require("./base").REVISION_CHANGES;
var createFrame = require("./base").createFrame;

function checkRevision(compilerInfo) {
  var compilerRevision = compilerInfo && compilerInfo[0] || 1,
      currentRevision = COMPILER_REVISION;

  if (compilerRevision !== currentRevision) {
    if (compilerRevision < currentRevision) {
      var runtimeVersions = REVISION_CHANGES[currentRevision],
          compilerVersions = REVISION_CHANGES[compilerRevision];
      throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
            "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
    } else {
      // Use the embedded version info since the runtime doesn't know about this revision yet
      throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
            "Please update your runtime to a newer version ("+compilerInfo[1]+").");
    }
  }
}

exports.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial

function template(templateSpec, env) {
  /* istanbul ignore next */
  if (!env) {
    throw new Exception("No environment passed to template");
  }
  if (!templateSpec || !templateSpec.main) {
    throw new Exception('Unknown template object: ' + typeof templateSpec);
  }

  // Note: Using env.VM references rather than local var references throughout this section to allow
  // for external users to override these as psuedo-supported APIs.
  env.VM.checkRevision(templateSpec.compiler);

  var invokePartialWrapper = function(partial, context, options) {
    if (options.hash) {
      context = Utils.extend({}, context, options.hash);
    }

    partial = env.VM.resolvePartial.call(this, partial, context, options);
    var result = env.VM.invokePartial.call(this, partial, context, options);

    if (result == null && env.compile) {
      options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
      result = options.partials[options.name](context, options);
    }
    if (result != null) {
      if (options.indent) {
        var lines = result.split('\n');
        for (var i = 0, l = lines.length; i < l; i++) {
          if (!lines[i] && i + 1 === l) {
            break;
          }

          lines[i] = options.indent + lines[i];
        }
        result = lines.join('\n');
      }
      return result;
    } else {
      throw new Exception("The partial " + options.name + " could not be compiled when running in runtime-only mode");
    }
  };

  // Just add water
  var container = {
    strict: function(obj, name) {
      if (!(name in obj)) {
        throw new Exception('"' + name + '" not defined in ' + obj);
      }
      return obj[name];
    },
    lookup: function(depths, name) {
      var len = depths.length;
      for (var i = 0; i < len; i++) {
        if (depths[i] && depths[i][name] != null) {
          return depths[i][name];
        }
      }
    },
    lambda: function(current, context) {
      return typeof current === 'function' ? current.call(context) : current;
    },

    escapeExpression: Utils.escapeExpression,
    invokePartial: invokePartialWrapper,

    fn: function(i) {
      return templateSpec[i];
    },

    programs: [],
    program: function(i, data, declaredBlockParams, blockParams, depths) {
      var programWrapper = this.programs[i],
          fn = this.fn(i);
      if (data || depths || blockParams || declaredBlockParams) {
        programWrapper = program(this, i, fn, data, declaredBlockParams, blockParams, depths);
      } else if (!programWrapper) {
        programWrapper = this.programs[i] = program(this, i, fn);
      }
      return programWrapper;
    },

    data: function(data, depth) {
      while (data && depth--) {
        data = data._parent;
      }
      return data;
    },
    merge: function(param, common) {
      var ret = param || common;

      if (param && common && (param !== common)) {
        ret = Utils.extend({}, common, param);
      }

      return ret;
    },

    noop: env.VM.noop,
    compilerInfo: templateSpec.compiler
  };

  var ret = function(context, options) {
    options = options || {};
    var data = options.data;

    ret._setup(options);
    if (!options.partial && templateSpec.useData) {
      data = initData(context, data);
    }
    var depths,
        blockParams = templateSpec.useBlockParams ? [] : undefined;
    if (templateSpec.useDepths) {
      depths = options.depths ? [context].concat(options.depths) : [context];
    }

    return templateSpec.main.call(container, context, container.helpers, container.partials, data, blockParams, depths);
  };
  ret.isTop = true;

  ret._setup = function(options) {
    if (!options.partial) {
      container.helpers = container.merge(options.helpers, env.helpers);

      if (templateSpec.usePartial) {
        container.partials = container.merge(options.partials, env.partials);
      }
    } else {
      container.helpers = options.helpers;
      container.partials = options.partials;
    }
  };

  ret._child = function(i, data, blockParams, depths) {
    if (templateSpec.useBlockParams && !blockParams) {
      throw new Exception('must pass block params');
    }
    if (templateSpec.useDepths && !depths) {
      throw new Exception('must pass parent depths');
    }

    return program(container, i, templateSpec[i], data, 0, blockParams, depths);
  };
  return ret;
}

exports.template = template;function program(container, i, fn, data, declaredBlockParams, blockParams, depths) {
  var prog = function(context, options) {
    options = options || {};

    return fn.call(container,
        context,
        container.helpers, container.partials,
        options.data || data,
        blockParams && [options.blockParams].concat(blockParams),
        depths && [context].concat(depths));
  };
  prog.program = i;
  prog.depth = depths ? depths.length : 0;
  prog.blockParams = declaredBlockParams || 0;
  return prog;
}

exports.program = program;function resolvePartial(partial, context, options) {
  if (!partial) {
    partial = options.partials[options.name];
  } else if (!partial.call && !options.name) {
    // This is a dynamic partial that returned a string
    options.name = partial;
    partial = options.partials[partial];
  }
  return partial;
}

exports.resolvePartial = resolvePartial;function invokePartial(partial, context, options) {
  options.partial = true;

  if(partial === undefined) {
    throw new Exception("The partial " + options.name + " could not be found");
  } else if(partial instanceof Function) {
    return partial(context, options);
  }
}

exports.invokePartial = invokePartial;function noop() { return ""; }

exports.noop = noop;function initData(context, data) {
  if (!data || !('root' in data)) {
    data = data ? createFrame(data) : {};
    data.root = context;
  }
  return data;
}
},{"./base":35,"./exception":36,"./utils":39}],38:[function(require,module,exports){
"use strict";
// Build out our basic SafeString type
function SafeString(string) {
  this.string = string;
}

SafeString.prototype.toString = SafeString.prototype.toHTML = function() {
  return "" + this.string;
};

exports["default"] = SafeString;
},{}],39:[function(require,module,exports){
"use strict";
/*jshint -W004 */
var escape = {
  "&": "&amp;",
  "<": "&lt;",
  ">": "&gt;",
  '"': "&quot;",
  "'": "&#x27;",
  "`": "&#x60;"
};

var badChars = /[&<>"'`]/g;
var possible = /[&<>"'`]/;

function escapeChar(chr) {
  return escape[chr];
}

function extend(obj /* , ...source */) {
  for (var i = 1; i < arguments.length; i++) {
    for (var key in arguments[i]) {
      if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
        obj[key] = arguments[i][key];
      }
    }
  }

  return obj;
}

exports.extend = extend;var toString = Object.prototype.toString;
exports.toString = toString;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
var isFunction = function(value) {
  return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
/* istanbul ignore next */
if (isFunction(/x/)) {
  isFunction = function(value) {
    return typeof value === 'function' && toString.call(value) === '[object Function]';
  };
}
var isFunction;
exports.isFunction = isFunction;
/* istanbul ignore next */
var isArray = Array.isArray || function(value) {
  return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
};
exports.isArray = isArray;
// Older IE versions do not directly support indexOf so we must implement our own, sadly.
function indexOf(array, value) {
  for (var i = 0, len = array.length; i < len; i++) {
    if (array[i] === value) {
      return i;
    }
  }
  return -1;
}

exports.indexOf = indexOf;
function escapeExpression(string) {
  // don't escape SafeStrings, since they're already safe
  if (string && string.toHTML) {
    return string.toHTML();
  } else if (string == null) {
    return "";
  } else if (!string) {
    return string + '';
  }

  // Force a string conversion as this will be done by the append regardless and
  // the regex test will do this transparently behind the scenes, causing issues if
  // an object's to string has escaped characters in it.
  string = "" + string;

  if(!possible.test(string)) { return string; }
  return string.replace(badChars, escapeChar);
}

exports.escapeExpression = escapeExpression;function isEmpty(value) {
  if (!value && value !== 0) {
    return true;
  } else if (isArray(value) && value.length === 0) {
    return true;
  } else {
    return false;
  }
}

exports.isEmpty = isEmpty;function blockParams(params, ids) {
  params.path = ids;
  return params;
}

exports.blockParams = blockParams;function appendContextPath(contextPath, id) {
  return (contextPath ? contextPath + '.' : '') + id;
}

exports.appendContextPath = appendContextPath;
},{}],40:[function(require,module,exports){
// Create a simple path alias to allow browserify to resolve
// the runtime on a supported path.
module.exports = require('./dist/cjs/handlebars.runtime').default;

},{"./dist/cjs/handlebars.runtime":34}],41:[function(require,module,exports){
module.exports = require("handlebars/runtime")["default"];

},{"handlebars/runtime":40}],42:[function(require,module,exports){
'use strict';
var repeating = require('repeating');

module.exports = function (str, indent, count) {
	if (typeof str !== 'string' || typeof indent !== 'string') {
		throw new TypeError('`string` and `indent` should be strings');
	}

	if (count != null && typeof count !== 'number') {
		throw new TypeError('`count` should be a number');
	}

	indent = count > 1 ? repeating(indent, count) : indent;

	return str.replace(/^(?!\s*$)/mg, indent);
};

},{"repeating":43}],43:[function(require,module,exports){
'use strict';
var isFinite = require('is-finite');

module.exports = function (str, n) {
	if (typeof str !== 'string') {
		throw new TypeError('Expected a string as the first argument');
	}

	if (n < 0 || !isFinite(n)) {
		throw new TypeError('Expected a finite positive number');
	}

	var ret = '';

	do {
		if (n & 1) {
			ret += str;
		}

		str += str;
	} while (n = n >> 1);

	return ret;
};

},{"is-finite":44}],44:[function(require,module,exports){
'use strict';
module.exports = Number.isFinite || function (val) {
	// Number.isNaN() => val !== val
	if (typeof val !== 'number' || val !== val || val === Infinity || val === -Infinity) {
		return false;
	}

	return true;
};

},{}],45:[function(require,module,exports){
(function (Buffer){
(function (root, stringify) {
  /* istanbul ignore else */
  if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
    // Node.
    module.exports = stringify();
  } else if (typeof define === 'function' && define.amd) {
    // AMD, registers as an anonymous module.
    define(function () {
      return stringify();
    });
  } else {
    // Browser global.
    root.javascriptStringify = stringify();
  }
})(this, function () {
  /**
   * Match all characters that need to be escaped in a string. Modified from
   * source to match single quotes instead of double.
   *
   * Source: https://github.com/douglascrockford/JSON-js/blob/master/json2.js
   *
   * @type {RegExp}
   */
  var ESCAPABLE = /[\\\'\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

  /**
   * Map of characters to escape characters.
   *
   * @type {Object}
   */
  var META_CHARS = {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    "'":  "\\'",
    '"':  '\\"',
    '\\': '\\\\'
  };

  /**
   * Escape any character into its literal JavaScript string.
   *
   * @param  {String} char
   * @return {String}
   */
  var escapeChar = function (char) {
    var meta = META_CHARS[char];

    return meta || '\\u' + ('0000' + char.charCodeAt(0).toString(16)).slice(-4);
  };

  /**
   * JavaScript reserved word list.
   */
  var RESERVED_WORDS = {};

  /**
   * Map reserved words to the object.
   */
  (
    'break else new var case finally return void catch for switch while ' +
    'continue function this with default if throw delete in try ' +
    'do instanceof typeof abstract enum int short boolean export ' +
    'interface static byte extends long super char final native synchronized ' +
    'class float package throws const goto private transient debugger ' +
    'implements protected volatile double import public let yield'
  ).split(' ').map(function (key) {
    RESERVED_WORDS[key] = true;
  });

  /**
   * Check if a variable name is valid.
   *
   * @param  {String}  name
   * @return {Boolean}
   */
  var isValidVariableName = function (name) {
    return !RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
  };

  /**
   * Return the global variable name.
   *
   * @return {String}
   */
  var getGlobalVariable = function (value, indent, stringify) {
    return 'Function(' + stringify('return this;') + ')()';
  };

  /**
   * Convert JavaScript objects into strings.
   *
   * @type {Object}
   */
  var OBJECT_TYPES = {
    '[object Array]': function (array, indent, stringify) {
      // Map array values to their stringified values with correct indentation.
      var values = array.map(function (value) {
        return indent + stringify(value).split('\n').join('\n' + indent);
      }).join(indent ? ',\n' : ',');

      // Wrap the array in newlines if we have indentation set.
      if (indent && values) {
        return '[\n' + values + '\n]';
      }

      return '[' + values + ']';
    },
    '[object Object]': function (object, indent, stringify) {
      if (typeof Buffer === 'function' && Buffer.isBuffer(object)) {
        return 'new Buffer(' + stringify(object.toString()) + ')';
      }

      // Iterate over object keys and concat string together.
      var values = Object.keys(object).reduce(function (values, key) {
        var value = stringify(object[key]);

        // Omit `undefined` object values.
        if (value === undefined) {
          return values;
        }

        // String format the key and value data.
        key   = isValidVariableName(key) ? key : stringify(key);
        value = String(value).split('\n').join('\n' + indent);

        // Push the current object key and value into the values array.
        values.push(indent + key + ':' + (indent ? ' ' : '') + value);

        return values;
      }, []).join(indent ? ',\n' : ',');

      // Wrap the object in newlines if we have indentation set.
      if (indent && values) {
        return '{\n' + values + '\n}';
      }

      return '{' + values + '}';
    },
    '[object Date]': function (date, indent, stringify) {
      return 'new Date(' + date.getTime() + ')';
    },
    '[object String]': function (string, indent, stringify) {
      return 'new String(' + stringify(string.toString()) + ')';
    },
    '[object Number]': function (number, indent, stringify) {
      return 'new Number(' + number + ')';
    },
    '[object Boolean]': function (boolean, indent, stringify) {
      return 'new Boolean(' + boolean + ')';
    },
    '[object RegExp]': String,
    '[object Function]': String,
    '[object global]': getGlobalVariable,
    '[object Window]': getGlobalVariable
  };

  /**
   * Convert JavaScript primitives into strings.
   *
   * @type {Object}
   */
  var PRIMITIVE_TYPES = {
    'string': function (string) {
      return "'" + string.replace(ESCAPABLE, escapeChar) + "'";
    },
    'number': String,
    'object': String,
    'boolean': String,
    'undefined': String
  };

  /**
   * Convert any value to a string.
   *
   * @param  {*}        value
   * @param  {String}   indent
   * @param  {Function} stringify
   * @return {String}
   */
  var stringify = function (value, indent, stringify) {
    // Convert primitives into strings.
    if (Object(value) !== value) {
      return PRIMITIVE_TYPES[typeof value](value, indent, stringify);
    }

    // Use the internal object string to select stringification method.
    var toString = OBJECT_TYPES[Object.prototype.toString.call(value)];

    // Convert objects into strings.
    return toString && toString(value, indent, stringify);
  };

  /**
   * Stringify an object into the literal string.
   *
   * @param  {Object}          value
   * @param  {Function}        [replacer]
   * @param  {(Number|String)} [space]
   * @return {String}
   */
  return function (value, replacer, space) {
    // Convert the spaces into a string.
    if (typeof space !== 'string') {
      space = new Array(Math.max(0, space|0) + 1).join(' ');
    }

    /**
     * Handle recursion by checking if we've visited this node every iteration.
     *
     * @param  {*}      value
     * @param  {Array}  cache
     * @return {String}
     */
    var recurse = function (value, cache, next) {
      // If we've already visited this node before, break the recursion.
      if (cache.indexOf(value) > -1) {
        return;
      }

      // Push the value into the values cache to avoid an infinite loop.
      cache.push(value);

      // Stringify the value and fallback to
      return next(value, space, function (value) {
        return recurse(value, cache.slice(), next);
      });
    };

    // If the user defined a replacer function, make the recursion function
    // a double step process - `replacer -> stringify -> replacer -> etc`.
    if (typeof replacer === 'function') {
      return recurse(value, [], function (value, space, next) {
        return replacer(value, space, function (value) {
          return stringify(value, space, next);
        });
      });
    }

    return recurse(value, [], stringify);
  };
});

}).call(this,require("buffer").Buffer)
},{"buffer":23}],46:[function(require,module,exports){
/**
 * Special language-specific overrides.
 *
 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
 *
 * @type {Object}
 */
var LANGUAGES = {
  tr: {
    regexp: /\u0130|\u0049|\u0049\u0307/g,
    map: {
      '\u0130': '\u0069',
      '\u0049': '\u0131',
      '\u0049\u0307': '\u0069'
    }
  },
  az: {
    regexp: /[\u0130]/g,
    map: {
      '\u0130': '\u0069',
      '\u0049': '\u0131',
      '\u0049\u0307': '\u0069'
    }
  },
  lt: {
    regexp: /[\u0049\u004A\u012E\u00CC\u00CD\u0128]/g,
    map: {
      '\u0049': '\u0069\u0307',
      '\u004A': '\u006A\u0307',
      '\u012E': '\u012F\u0307',
      '\u00CC': '\u0069\u0307\u0300',
      '\u00CD': '\u0069\u0307\u0301',
      '\u0128': '\u0069\u0307\u0303'
    }
  }
}

/**
 * Lowercase a string.
 *
 * @param  {String} str
 * @return {String}
 */
module.exports = function (str, locale) {
  var lang = LANGUAGES[locale]

  str = str == null ? '' : String(str)

  if (lang) {
    str = str.replace(lang.regexp, function (m) { return lang.map[m] })
  }

  return str.toLowerCase()
}

},{}],47:[function(require,module,exports){

var http = require('http');

/* istanbul ignore next: implementation differs on version */
if (http.METHODS) {

  module.exports = http.METHODS.map(function(method){
    return method.toLowerCase();
  });

} else {

  module.exports = [
    'get',
    'post',
    'put',
    'head',
    'delete',
    'options',
    'trace',
    'copy',
    'lock',
    'mkcol',
    'move',
    'purge',
    'propfind',
    'proppatch',
    'unlock',
    'report',
    'mkactivity',
    'checkout',
    'merge',
    'm-search',
    'notify',
    'subscribe',
    'unsubscribe',
    'patch',
    'search',
    'connect'
  ];

}

},{"http":22}],48:[function(require,module,exports){
/*!
 * object.pick <https://github.com/jonschlinkert/object.pick>
 *
 * Copyright (c) 2014-2015 Jon Schlinkert, contributors.
 * Licensed under the MIT License
 */

'use strict';

module.exports = function pick(obj, keys) {
  var res = {};
  var i = 0;

  if (typeof obj !== 'object') {
    return res;
  }

  if (typeof keys === 'string') {
    if (keys in obj) {
      res[keys] = obj[keys];
    }
    return res;
  }

  var len = keys.length;

  while (len--) {
    var key = keys[i++];
    if (key in obj) {
      res[key] = obj[key];
    }
  }
  return res;
};

},{}],49:[function(require,module,exports){
arguments[4][28][0].apply(exports,arguments)
},{"./vendor/camel-case-regexp":50,"./vendor/non-word-regexp":51,"./vendor/trailing-digit-regexp":52,"dup":28,"lower-case":46}],50:[function(require,module,exports){
arguments[4][29][0].apply(exports,arguments)
},{"dup":29}],51:[function(require,module,exports){
arguments[4][30][0].apply(exports,arguments)
},{"dup":30}],52:[function(require,module,exports){
arguments[4][31][0].apply(exports,arguments)
},{"dup":31}],53:[function(require,module,exports){
var sentenceCase = require('sentence-case');

/**
 * Param case a string.
 *
 * @param  {String} string
 * @param  {String} [locale]
 * @return {String}
 */
module.exports = function (string, locale) {
  return sentenceCase(string, locale, '-');
};

},{"sentence-case":49}],54:[function(require,module,exports){
var upperCase = require('upper-case');

/**
 * Upper case the first character of a string.
 *
 * @param  {String} str
 * @return {String}
 */
module.exports = function (str, locale) {
  if (str == null) {
    return '';
  }

  str = String(str);

  return upperCase(str.charAt(0), locale) + str.substr(1);
};

},{"upper-case":61}],55:[function(require,module,exports){
var camelCase      = require('camel-case');
var upperCaseFirst = require('upper-case-first');

/**
 * Pascal case a string.
 *
 * @param  {String} string
 * @param  {String} [locale]
 * @return {String}
 */
module.exports = function (string, locale) {
  return upperCaseFirst(camelCase(string, locale), locale);
};

},{"camel-case":27,"upper-case-first":54}],56:[function(require,module,exports){
arguments[4][28][0].apply(exports,arguments)
},{"./vendor/camel-case-regexp":57,"./vendor/non-word-regexp":58,"./vendor/trailing-digit-regexp":59,"dup":28,"lower-case":46}],57:[function(require,module,exports){
arguments[4][29][0].apply(exports,arguments)
},{"dup":29}],58:[function(require,module,exports){
arguments[4][30][0].apply(exports,arguments)
},{"dup":30}],59:[function(require,module,exports){
arguments[4][31][0].apply(exports,arguments)
},{"dup":31}],60:[function(require,module,exports){
var sentenceCase = require('sentence-case');

/**
 * Snake case a string.
 *
 * @param  {String} str
 * @param  {String} [locale]
 * @return {String}
 */
module.exports = function (str, locale) {
  return sentenceCase(str, locale, '_');
};

},{"sentence-case":56}],61:[function(require,module,exports){
/**
 * Special language-specific overrides.
 *
 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
 *
 * @type {Object}
 */
var LANGUAGES = {
  tr: {
    regexp: /[\u0069]/g,
    map: {
      '\u0069': '\u0130'
    }
  },
  az: {
    regexp: /[\u0069]/g,
    map: {
      '\u0069': '\u0130'
    }
  },
  lt: {
    regexp: /[\u0069\u006A\u012F]\u0307|\u0069\u0307[\u0300\u0301\u0303]/g,
    map: {
      '\u0069\u0307': '\u0049',
      '\u006A\u0307': '\u004A',
      '\u012F\u0307': '\u012E',
      '\u0069\u0307\u0300': '\u00CC',
      '\u0069\u0307\u0301': '\u00CD',
      '\u0069\u0307\u0303': '\u0128'
    }
  }
}

/**
 * Upper case a string.
 *
 * @param  {String} str
 * @return {String}
 */
module.exports = function (str, locale) {
  var lang = LANGUAGES[locale]

  str = str == null ? '' : String(str)

  if (lang) {
    str = str.replace(lang.regexp, function (m) { return lang.map[m] })
  }

  return str.toUpperCase()
}

},{}],62:[function(require,module,exports){
/**
 * Export all implemented languages.
 */
exports.javascript = require('./javascript');

},{"./javascript":4}]},{},[62])(62)
});
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["Parser"] = factory();
	else
		root["RAML"] = root["RAML"] || {}, root["RAML"]["Parser"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	module.exports =
	/******/ (function(modules) { // webpackBootstrap
	/******/ 	// The module cache
	/******/ 	var installedModules = {};

	/******/ 	// The require function
	/******/ 	function __webpack_require__(moduleId) {

	/******/ 		// Check if module is in cache
	/******/ 		if(installedModules[moduleId])
	/******/ 			return installedModules[moduleId].exports;

	/******/ 		// Create a new module (and put it into the cache)
	/******/ 		var module = installedModules[moduleId] = {
	/******/ 			exports: {},
	/******/ 			id: moduleId,
	/******/ 			loaded: false
	/******/ 		};

	/******/ 		// Execute the module function
	/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

	/******/ 		// Flag the module as loaded
	/******/ 		module.loaded = true;

	/******/ 		// Return the exports of the module
	/******/ 		return module.exports;
	/******/ 	}


	/******/ 	// expose the modules object (__webpack_modules__)
	/******/ 	__webpack_require__.m = modules;

	/******/ 	// expose the module cache
	/******/ 	__webpack_require__.c = installedModules;

	/******/ 	// __webpack_public_path__
	/******/ 	__webpack_require__.p = "";

	/******/ 	// Load entry module and return exports
	/******/ 	return __webpack_require__(0);
	/******/ })
	/************************************************************************/
	/******/ ([
	/* 0 */
	/***/ function(module, exports, __webpack_require__) {

		var RamlWrapper = __webpack_require__(1);
		function loadApiSync(apiPath, extensionsAndOverlays, options) {
		    return RamlWrapper.loadApiSync(apiPath, extensionsAndOverlays, options);
		}
		exports.loadApiSync = loadApiSync;
		function loadApi(apiPath, extensionsAndOverlays, options) {
		    return RamlWrapper.loadApi(apiPath, extensionsAndOverlays, options);
		}
		exports.loadApi = loadApi;
		function loadRAMLSync(apiPath, extensionsAndOverlays, options) {
		    return RamlWrapper.loadRAMLSync(apiPath, extensionsAndOverlays, options);
		}
		exports.loadRAMLSync = loadRAMLSync;
		function loadRAML(apiPath, extensionsAndOverlays, options) {
		    return RamlWrapper.loadRAML(apiPath, extensionsAndOverlays, options);
		}
		exports.loadRAML = loadRAML;
		/**
		 * Gets AST node by runtime type, if runtime type matches any.
		 * @param runtimeType - runtime type to find the match for
		 */
		function getLanguageElementByRuntimeType(runtimeType) {
		    return RamlWrapper.getLanguageElementByRuntimeType(runtimeType);
		}
		exports.getLanguageElementByRuntimeType = getLanguageElementByRuntimeType;


	/***/ },
	/* 1 */
	/***/ function(module, exports, __webpack_require__) {

		/**
		 * <p>See <a href="http://raml.org">http://raml.org</a> for more information about RAML.</p>
		 *
		 * <p>This parser is at a beta state of development, as part of the API Workbench development cycle (<a href="http://apiworkbench.com">http://apiworkbench.com</a>).</p>
		 *
		 * <p><a href="https://github.com/raml-org/raml-js-parser-2/blob/master/documentation/GettingStarted.md">Getting Started Guide</a> describes the first steps with the parser.</p>
		 *
		 * <h2>Installation</h2>
		 *
		 * <pre><code>git clone https://github.com/raml-org/raml-js-parser-2
		 *
		 * cd raml-js-parser-2
		 *
		 * npm install
		 *
		 * node test/test.js  //here you should observe JSON representation of XKCD API in your console
		 *
		 * node test/testAsync.js  //same as above but in asynchronous mode
		 * </code></pre>
		 *
		 * <h2>Usage</h2>
		 *
		 * <ul>
		 * <li>For parser usage example refer to <code>test/test.js</code></li>
		 * <li>For asynchrounous usage example refer to <code>test/testAsync.js</code></li>
		 * </ul>
		 **/
		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var hl = __webpack_require__(2);
		var services = __webpack_require__(49);
		var core = __webpack_require__(75);
		var apiLoader = __webpack_require__(77);
		var helper = __webpack_require__(65);
		var RAMLLanguageElementImpl = (function (_super) {
		    __extends(RAMLLanguageElementImpl, _super);
		    function RAMLLanguageElementImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLLanguageElementImpl.prototype.wrapperClassName = function () {
		        return "RAMLLanguageElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLLanguageElementImpl.prototype.kind = function () {
		        return "RAMLLanguageElement";
		    };
		    /**
		     * The displayName attribute specifies the $self's display name. It is a friendly name used only for display or documentation purposes. If displayName is not specified, it defaults to the element's key (the name of the property itself).
		     **/
		    RAMLLanguageElementImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    RAMLLanguageElementImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * The description attribute describes the intended use or meaning of the $self. This value MAY be formatted using Markdown [MARKDOWN]
		     **/
		    RAMLLanguageElementImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    RAMLLanguageElementImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    return RAMLLanguageElementImpl;
		})(core.BasicNodeImpl);
		exports.RAMLLanguageElementImpl = RAMLLanguageElementImpl;
		var ValueTypeImpl = (function (_super) {
		    __extends(ValueTypeImpl, _super);
		    function ValueTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ValueTypeImpl.prototype.wrapperClassName = function () {
		        return "ValueTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ValueTypeImpl.prototype.kind = function () {
		        return "ValueType";
		    };
		    /**
		     * @return String representation of the node value
		     **/
		    ValueTypeImpl.prototype.value = function () {
		        return this.attr.value();
		    };
		    return ValueTypeImpl;
		})(core.AttributeNodeImpl);
		exports.ValueTypeImpl = ValueTypeImpl;
		var NumberTypeImpl = (function (_super) {
		    __extends(NumberTypeImpl, _super);
		    function NumberTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    NumberTypeImpl.prototype.wrapperClassName = function () {
		        return "NumberTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    NumberTypeImpl.prototype.kind = function () {
		        return "NumberType";
		    };
		    return NumberTypeImpl;
		})(ValueTypeImpl);
		exports.NumberTypeImpl = NumberTypeImpl;
		var BooleanTypeImpl = (function (_super) {
		    __extends(BooleanTypeImpl, _super);
		    function BooleanTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BooleanTypeImpl.prototype.wrapperClassName = function () {
		        return "BooleanTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BooleanTypeImpl.prototype.kind = function () {
		        return "BooleanType";
		    };
		    return BooleanTypeImpl;
		})(ValueTypeImpl);
		exports.BooleanTypeImpl = BooleanTypeImpl;
		var ReferenceImpl = (function (_super) {
		    __extends(ReferenceImpl, _super);
		    function ReferenceImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ReferenceImpl.prototype.wrapperClassName = function () {
		        return "ReferenceImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ReferenceImpl.prototype.kind = function () {
		        return "Reference";
		    };
		    /**
		     * @return StructuredValue object representing the node value
		     **/
		    ReferenceImpl.prototype.value = function () {
		        return core.toStructuredValue(this.attr);
		    };
		    return ReferenceImpl;
		})(core.AttributeNodeImpl);
		exports.ReferenceImpl = ReferenceImpl;
		var ResourceTypeRefImpl = (function (_super) {
		    __extends(ResourceTypeRefImpl, _super);
		    function ResourceTypeRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceTypeRefImpl.prototype.wrapperClassName = function () {
		        return "ResourceTypeRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceTypeRefImpl.prototype.kind = function () {
		        return "ResourceTypeRef";
		    };
		    return ResourceTypeRefImpl;
		})(ReferenceImpl);
		exports.ResourceTypeRefImpl = ResourceTypeRefImpl;
		var TraitRefImpl = (function (_super) {
		    __extends(TraitRefImpl, _super);
		    function TraitRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    TraitRefImpl.prototype.wrapperClassName = function () {
		        return "TraitRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    TraitRefImpl.prototype.kind = function () {
		        return "TraitRef";
		    };
		    return TraitRefImpl;
		})(ReferenceImpl);
		exports.TraitRefImpl = TraitRefImpl;
		var SecuritySchemeRefImpl = (function (_super) {
		    __extends(SecuritySchemeRefImpl, _super);
		    function SecuritySchemeRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SecuritySchemeRefImpl.prototype.wrapperClassName = function () {
		        return "SecuritySchemeRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SecuritySchemeRefImpl.prototype.kind = function () {
		        return "SecuritySchemeRef";
		    };
		    /**
		     * Returns the name of security scheme, this reference refers to.
		     **/
		    SecuritySchemeRefImpl.prototype.securitySchemeName = function () {
		        return helper.securitySchemeName(this);
		    };
		    /**
		     * Returns AST node of security scheme, this reference refers to, or null.
		     **/
		    SecuritySchemeRefImpl.prototype.securityScheme = function () {
		        return helper.securityScheme(this);
		    };
		    return SecuritySchemeRefImpl;
		})(ReferenceImpl);
		exports.SecuritySchemeRefImpl = SecuritySchemeRefImpl;
		/**
		 * Annotations allow you to attach information to your API
		 **/
		var AnnotationRefImpl = (function (_super) {
		    __extends(AnnotationRefImpl, _super);
		    function AnnotationRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    AnnotationRefImpl.prototype.wrapperClassName = function () {
		        return "AnnotationRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    AnnotationRefImpl.prototype.kind = function () {
		        return "AnnotationRef";
		    };
		    return AnnotationRefImpl;
		})(ReferenceImpl);
		exports.AnnotationRefImpl = AnnotationRefImpl;
		var DataElementRefImpl = (function (_super) {
		    __extends(DataElementRefImpl, _super);
		    function DataElementRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DataElementRefImpl.prototype.wrapperClassName = function () {
		        return "DataElementRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DataElementRefImpl.prototype.kind = function () {
		        return "DataElementRef";
		    };
		    return DataElementRefImpl;
		})(ReferenceImpl);
		exports.DataElementRefImpl = DataElementRefImpl;
		/**
		 * Elements to which this Annotation can be applied (enum)
		 **/
		var AnnotationTargetImpl = (function (_super) {
		    __extends(AnnotationTargetImpl, _super);
		    function AnnotationTargetImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    AnnotationTargetImpl.prototype.wrapperClassName = function () {
		        return "AnnotationTargetImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    AnnotationTargetImpl.prototype.kind = function () {
		        return "AnnotationTarget";
		    };
		    return AnnotationTargetImpl;
		})(ValueTypeImpl);
		exports.AnnotationTargetImpl = AnnotationTargetImpl;
		var pointerImpl = (function (_super) {
		    __extends(pointerImpl, _super);
		    function pointerImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    pointerImpl.prototype.wrapperClassName = function () {
		        return "pointerImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    pointerImpl.prototype.kind = function () {
		        return "pointer";
		    };
		    return pointerImpl;
		})(ValueTypeImpl);
		exports.pointerImpl = pointerImpl;
		var StringTypeImpl = (function (_super) {
		    __extends(StringTypeImpl, _super);
		    function StringTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    StringTypeImpl.prototype.wrapperClassName = function () {
		        return "StringTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    StringTypeImpl.prototype.kind = function () {
		        return "StringType";
		    };
		    return StringTypeImpl;
		})(ValueTypeImpl);
		exports.StringTypeImpl = StringTypeImpl;
		/**
		 * This type currently serves both for absolute and relative urls
		 **/
		var UriTemplateImpl = (function (_super) {
		    __extends(UriTemplateImpl, _super);
		    function UriTemplateImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    UriTemplateImpl.prototype.wrapperClassName = function () {
		        return "UriTemplateImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    UriTemplateImpl.prototype.kind = function () {
		        return "UriTemplate";
		    };
		    return UriTemplateImpl;
		})(StringTypeImpl);
		exports.UriTemplateImpl = UriTemplateImpl;
		/**
		 * This  type describes relative uri templates
		 **/
		var RelativeUriStringImpl = (function (_super) {
		    __extends(RelativeUriStringImpl, _super);
		    function RelativeUriStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RelativeUriStringImpl.prototype.wrapperClassName = function () {
		        return "RelativeUriStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RelativeUriStringImpl.prototype.kind = function () {
		        return "RelativeUriString";
		    };
		    return RelativeUriStringImpl;
		})(UriTemplateImpl);
		exports.RelativeUriStringImpl = RelativeUriStringImpl;
		/**
		 * This  type describes absolute uri templates
		 **/
		var FullUriTemplateStringImpl = (function (_super) {
		    __extends(FullUriTemplateStringImpl, _super);
		    function FullUriTemplateStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FullUriTemplateStringImpl.prototype.wrapperClassName = function () {
		        return "FullUriTemplateStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FullUriTemplateStringImpl.prototype.kind = function () {
		        return "FullUriTemplateString";
		    };
		    return FullUriTemplateStringImpl;
		})(UriTemplateImpl);
		exports.FullUriTemplateStringImpl = FullUriTemplateStringImpl;
		var StatusCodeStringImpl = (function (_super) {
		    __extends(StatusCodeStringImpl, _super);
		    function StatusCodeStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    StatusCodeStringImpl.prototype.wrapperClassName = function () {
		        return "StatusCodeStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    StatusCodeStringImpl.prototype.kind = function () {
		        return "StatusCodeString";
		    };
		    return StatusCodeStringImpl;
		})(StringTypeImpl);
		exports.StatusCodeStringImpl = StatusCodeStringImpl;
		/**
		 * This  type describes fixed uris
		 **/
		var FixedUriStringImpl = (function (_super) {
		    __extends(FixedUriStringImpl, _super);
		    function FixedUriStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FixedUriStringImpl.prototype.wrapperClassName = function () {
		        return "FixedUriStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FixedUriStringImpl.prototype.kind = function () {
		        return "FixedUriString";
		    };
		    return FixedUriStringImpl;
		})(StringTypeImpl);
		exports.FixedUriStringImpl = FixedUriStringImpl;
		var ContentTypeImpl = (function (_super) {
		    __extends(ContentTypeImpl, _super);
		    function ContentTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ContentTypeImpl.prototype.wrapperClassName = function () {
		        return "ContentTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ContentTypeImpl.prototype.kind = function () {
		        return "ContentType";
		    };
		    return ContentTypeImpl;
		})(StringTypeImpl);
		exports.ContentTypeImpl = ContentTypeImpl;
		var ValidityExpressionImpl = (function (_super) {
		    __extends(ValidityExpressionImpl, _super);
		    function ValidityExpressionImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ValidityExpressionImpl.prototype.wrapperClassName = function () {
		        return "ValidityExpressionImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ValidityExpressionImpl.prototype.kind = function () {
		        return "ValidityExpression";
		    };
		    return ValidityExpressionImpl;
		})(StringTypeImpl);
		exports.ValidityExpressionImpl = ValidityExpressionImpl;
		var DateFormatSpecImpl = (function (_super) {
		    __extends(DateFormatSpecImpl, _super);
		    function DateFormatSpecImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DateFormatSpecImpl.prototype.wrapperClassName = function () {
		        return "DateFormatSpecImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DateFormatSpecImpl.prototype.kind = function () {
		        return "DateFormatSpec";
		    };
		    return DateFormatSpecImpl;
		})(StringTypeImpl);
		exports.DateFormatSpecImpl = DateFormatSpecImpl;
		var FunctionalInterfaceImpl = (function (_super) {
		    __extends(FunctionalInterfaceImpl, _super);
		    function FunctionalInterfaceImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FunctionalInterfaceImpl.prototype.wrapperClassName = function () {
		        return "FunctionalInterfaceImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FunctionalInterfaceImpl.prototype.kind = function () {
		        return "FunctionalInterface";
		    };
		    return FunctionalInterfaceImpl;
		})(StringTypeImpl);
		exports.FunctionalInterfaceImpl = FunctionalInterfaceImpl;
		/**
		 * Schema at this moment only two subtypes are supported (json schema and xsd)
		 **/
		var SchemaStringImpl = (function (_super) {
		    __extends(SchemaStringImpl, _super);
		    function SchemaStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SchemaStringImpl.prototype.wrapperClassName = function () {
		        return "SchemaStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SchemaStringImpl.prototype.kind = function () {
		        return "SchemaString";
		    };
		    return SchemaStringImpl;
		})(StringTypeImpl);
		exports.SchemaStringImpl = SchemaStringImpl;
		/**
		 * JSON schema
		 **/
		var JSonSchemaStringImpl = (function (_super) {
		    __extends(JSonSchemaStringImpl, _super);
		    function JSonSchemaStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    JSonSchemaStringImpl.prototype.wrapperClassName = function () {
		        return "JSonSchemaStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    JSonSchemaStringImpl.prototype.kind = function () {
		        return "JSonSchemaString";
		    };
		    return JSonSchemaStringImpl;
		})(SchemaStringImpl);
		exports.JSonSchemaStringImpl = JSonSchemaStringImpl;
		/**
		 * XSD schema
		 **/
		var XMLSchemaStringImpl = (function (_super) {
		    __extends(XMLSchemaStringImpl, _super);
		    function XMLSchemaStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    XMLSchemaStringImpl.prototype.wrapperClassName = function () {
		        return "XMLSchemaStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    XMLSchemaStringImpl.prototype.kind = function () {
		        return "XMLSchemaString";
		    };
		    return XMLSchemaStringImpl;
		})(SchemaStringImpl);
		exports.XMLSchemaStringImpl = XMLSchemaStringImpl;
		/**
		 * Examples at this moment only two subtypes are supported (json  and xml)
		 **/
		var ExampleStringImpl = (function (_super) {
		    __extends(ExampleStringImpl, _super);
		    function ExampleStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ExampleStringImpl.prototype.wrapperClassName = function () {
		        return "ExampleStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ExampleStringImpl.prototype.kind = function () {
		        return "ExampleString";
		    };
		    return ExampleStringImpl;
		})(StringTypeImpl);
		exports.ExampleStringImpl = ExampleStringImpl;
		var RAMLPointerImpl = (function (_super) {
		    __extends(RAMLPointerImpl, _super);
		    function RAMLPointerImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLPointerImpl.prototype.wrapperClassName = function () {
		        return "RAMLPointerImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLPointerImpl.prototype.kind = function () {
		        return "RAMLPointer";
		    };
		    return RAMLPointerImpl;
		})(StringTypeImpl);
		exports.RAMLPointerImpl = RAMLPointerImpl;
		var RAMLSelectorImpl = (function (_super) {
		    __extends(RAMLSelectorImpl, _super);
		    function RAMLSelectorImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLSelectorImpl.prototype.wrapperClassName = function () {
		        return "RAMLSelectorImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLSelectorImpl.prototype.kind = function () {
		        return "RAMLSelector";
		    };
		    return RAMLSelectorImpl;
		})(StringTypeImpl);
		exports.RAMLSelectorImpl = RAMLSelectorImpl;
		/**
		 * This sub type of the string represents mime types
		 **/
		var MimeTypeImpl = (function (_super) {
		    __extends(MimeTypeImpl, _super);
		    function MimeTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MimeTypeImpl.prototype.wrapperClassName = function () {
		        return "MimeTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MimeTypeImpl.prototype.kind = function () {
		        return "MimeType";
		    };
		    return MimeTypeImpl;
		})(StringTypeImpl);
		exports.MimeTypeImpl = MimeTypeImpl;
		/**
		 * [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/)
		 **/
		var MarkdownStringImpl = (function (_super) {
		    __extends(MarkdownStringImpl, _super);
		    function MarkdownStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MarkdownStringImpl.prototype.wrapperClassName = function () {
		        return "MarkdownStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MarkdownStringImpl.prototype.kind = function () {
		        return "MarkdownString";
		    };
		    return MarkdownStringImpl;
		})(StringTypeImpl);
		exports.MarkdownStringImpl = MarkdownStringImpl;
		var DocumentationItemImpl = (function (_super) {
		    __extends(DocumentationItemImpl, _super);
		    function DocumentationItemImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createDocumentationItem(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DocumentationItemImpl.prototype.wrapperClassName = function () {
		        return "DocumentationItemImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DocumentationItemImpl.prototype.kind = function () {
		        return "DocumentationItem";
		    };
		    /**
		     * Title of documentation section
		     **/
		    DocumentationItemImpl.prototype.title = function () {
		        return _super.prototype.attribute.call(this, 'title', this.toString);
		    };
		    /**
		     * @hidden
		     * Set title value
		     **/
		    DocumentationItemImpl.prototype.setTitle = function (param) {
		        this.highLevel().attrOrCreate("title").setValue("" + param);
		        return this;
		    };
		    /**
		     * Content of documentation section
		     **/
		    DocumentationItemImpl.prototype.content = function () {
		        return _super.prototype.attribute.call(this, 'content', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    return DocumentationItemImpl;
		})(RAMLLanguageElementImpl);
		exports.DocumentationItemImpl = DocumentationItemImpl;
		var ScriptSpecImpl = (function (_super) {
		    __extends(ScriptSpecImpl, _super);
		    function ScriptSpecImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createScriptSpec(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ScriptSpecImpl.prototype.wrapperClassName = function () {
		        return "ScriptSpecImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ScriptSpecImpl.prototype.kind = function () {
		        return "ScriptSpec";
		    };
		    ScriptSpecImpl.prototype.language = function () {
		        return _super.prototype.attribute.call(this, 'language', this.toString);
		    };
		    /**
		     * @hidden
		     * Set language value
		     **/
		    ScriptSpecImpl.prototype.setLanguage = function (param) {
		        this.highLevel().attrOrCreate("language").setValue("" + param);
		        return this;
		    };
		    ScriptSpecImpl.prototype.content = function () {
		        return _super.prototype.attribute.call(this, 'content', this.toString);
		    };
		    /**
		     * @hidden
		     * Set content value
		     **/
		    ScriptSpecImpl.prototype.setContent = function (param) {
		        this.highLevel().attrOrCreate("content").setValue("" + param);
		        return this;
		    };
		    return ScriptSpecImpl;
		})(RAMLLanguageElementImpl);
		exports.ScriptSpecImpl = ScriptSpecImpl;
		var ApiDescriptionImpl = (function (_super) {
		    __extends(ApiDescriptionImpl, _super);
		    function ApiDescriptionImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createApiDescription(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ApiDescriptionImpl.prototype.wrapperClassName = function () {
		        return "ApiDescriptionImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ApiDescriptionImpl.prototype.kind = function () {
		        return "ApiDescription";
		    };
		    ApiDescriptionImpl.prototype.apiFiles = function () {
		        return _super.prototype.elements.call(this, 'apiFiles');
		    };
		    ApiDescriptionImpl.prototype.script = function () {
		        return _super.prototype.elements.call(this, 'script');
		    };
		    ApiDescriptionImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', this.toString);
		    };
		    /**
		     * @hidden
		     * Set type value
		     **/
		    ApiDescriptionImpl.prototype.setType = function (param) {
		        this.highLevel().attrOrCreate("type").setValue("" + param);
		        return this;
		    };
		    return ApiDescriptionImpl;
		})(RAMLLanguageElementImpl);
		exports.ApiDescriptionImpl = ApiDescriptionImpl;
		var CallbackAPIDescriptionImpl = (function (_super) {
		    __extends(CallbackAPIDescriptionImpl, _super);
		    function CallbackAPIDescriptionImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createCallbackAPIDescription(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    CallbackAPIDescriptionImpl.prototype.wrapperClassName = function () {
		        return "CallbackAPIDescriptionImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    CallbackAPIDescriptionImpl.prototype.kind = function () {
		        return "CallbackAPIDescription";
		    };
		    CallbackAPIDescriptionImpl.prototype.callbackFor = function () {
		        return _super.prototype.element.call(this, 'callbackFor');
		    };
		    return CallbackAPIDescriptionImpl;
		})(ApiDescriptionImpl);
		exports.CallbackAPIDescriptionImpl = CallbackAPIDescriptionImpl;
		var RAMLProjectImpl = (function (_super) {
		    __extends(RAMLProjectImpl, _super);
		    function RAMLProjectImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createRAMLProject(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLProjectImpl.prototype.wrapperClassName = function () {
		        return "RAMLProjectImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLProjectImpl.prototype.kind = function () {
		        return "RAMLProject";
		    };
		    RAMLProjectImpl.prototype.relatedProjects = function () {
		        return _super.prototype.elements.call(this, 'relatedProjects');
		    };
		    RAMLProjectImpl.prototype.declaredApis = function () {
		        return _super.prototype.elements.call(this, 'declaredApis');
		    };
		    RAMLProjectImpl.prototype.license = function () {
		        return _super.prototype.attribute.call(this, 'license', this.toString);
		    };
		    /**
		     * @hidden
		     * Set license value
		     **/
		    RAMLProjectImpl.prototype.setLicense = function (param) {
		        this.highLevel().attrOrCreate("license").setValue("" + param);
		        return this;
		    };
		    RAMLProjectImpl.prototype.overview = function () {
		        return _super.prototype.attribute.call(this, 'overview', this.toString);
		    };
		    /**
		     * @hidden
		     * Set overview value
		     **/
		    RAMLProjectImpl.prototype.setOverview = function (param) {
		        this.highLevel().attrOrCreate("overview").setValue("" + param);
		        return this;
		    };
		    RAMLProjectImpl.prototype.url = function () {
		        return _super.prototype.attribute.call(this, 'url', this.toString);
		    };
		    /**
		     * @hidden
		     * Set url value
		     **/
		    RAMLProjectImpl.prototype.setUrl = function (param) {
		        this.highLevel().attrOrCreate("url").setValue("" + param);
		        return this;
		    };
		    return RAMLProjectImpl;
		})(RAMLLanguageElementImpl);
		exports.RAMLProjectImpl = RAMLProjectImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var AbstractSecuritySchemeImpl = (function (_super) {
		    __extends(AbstractSecuritySchemeImpl, _super);
		    function AbstractSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createAbstractSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    AbstractSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "AbstractSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    AbstractSecuritySchemeImpl.prototype.kind = function () {
		        return "AbstractSecurityScheme";
		    };
		    AbstractSecuritySchemeImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    AbstractSecuritySchemeImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * The securitySchemes property MUST be used to specify an API's security mechanisms, including the required settings and the authentication methods that the API supports. one authentication method is allowed if the API supports them.
		     **/
		    AbstractSecuritySchemeImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', this.toString);
		    };
		    /**
		     * @hidden
		     * Set type value
		     **/
		    AbstractSecuritySchemeImpl.prototype.setType = function (param) {
		        this.highLevel().attrOrCreate("type").setValue("" + param);
		        return this;
		    };
		    /**
		     * The description MAY be used to describe a securityScheme.
		     **/
		    AbstractSecuritySchemeImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * A description of the request components related to Security that are determined by the scheme: the headers, query parameters or responses. As a best practice, even for standard security schemes, API designers SHOULD describe these properties of security schemes.
		     * Including the security scheme description completes an API documentation.
		     **/
		    AbstractSecuritySchemeImpl.prototype.describedBy = function () {
		        return _super.prototype.element.call(this, 'describedBy');
		    };
		    /**
		     * The settings attribute MAY be used to provide security scheme-specific information. The required attributes vary depending on the type of security scheme is being declared.
		     * It describes the minimum set of properties which any processing application MUST provide and validate if it chooses to implement the security scheme. Processing applications MAY choose to recognize other properties for things such as token lifetime, preferred cryptographic algorithms, and more.
		     **/
		    AbstractSecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return AbstractSecuritySchemeImpl;
		})(RAMLLanguageElementImpl);
		exports.AbstractSecuritySchemeImpl = AbstractSecuritySchemeImpl;
		var HasNormalParametersImpl = (function (_super) {
		    __extends(HasNormalParametersImpl, _super);
		    function HasNormalParametersImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createHasNormalParameters(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    HasNormalParametersImpl.prototype.wrapperClassName = function () {
		        return "HasNormalParametersImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    HasNormalParametersImpl.prototype.kind = function () {
		        return "HasNormalParameters";
		    };
		    /**
		     * An APIs resources MAY be filtered (to return a subset of results) or altered (such as transforming a response body from JSON to XML format) by the use of query strings. If the resource or its method supports a query string, the query string MUST be defined by the queryParameters property
		     **/
		    HasNormalParametersImpl.prototype.queryParameters = function () {
		        return _super.prototype.elements.call(this, 'queryParameters');
		    };
		    /**
		     * Headers that allowed at this position
		     **/
		    HasNormalParametersImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    HasNormalParametersImpl.prototype.queryString = function () {
		        return _super.prototype.element.call(this, 'queryString');
		    };
		    return HasNormalParametersImpl;
		})(RAMLLanguageElementImpl);
		exports.HasNormalParametersImpl = HasNormalParametersImpl;
		var TypeDeclarationImpl = (function (_super) {
		    __extends(TypeDeclarationImpl, _super);
		    function TypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    TypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "TypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    TypeDeclarationImpl.prototype.kind = function () {
		        return "TypeDeclaration";
		    };
		    /**
		     * name of the parameter
		     **/
		    TypeDeclarationImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    TypeDeclarationImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * When extending from a type you can define new facets (which can then be set to concrete values by subtypes).
		     **/
		    TypeDeclarationImpl.prototype.facets = function () {
		        return _super.prototype.elements.call(this, 'facets');
		    };
		    /**
		     * Alias for the equivalent "type" property, for compatibility with RAML 0.8. Deprecated - API definitions should use the "type" property, as the "schema" alias for that property name may be removed in a future RAML version. The "type" property allows for XML and JSON schemas.
		     **/
		    TypeDeclarationImpl.prototype.schema = function () {
		        return _super.prototype.attribute.call(this, 'schema', this.toString);
		    };
		    /**
		     * @hidden
		     * Set schema value
		     **/
		    TypeDeclarationImpl.prototype.setSchema = function (param) {
		        this.highLevel().attrOrCreate("schema").setValue("" + param);
		        return this;
		    };
		    TypeDeclarationImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    TypeDeclarationImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    /**
		     * A base type which the current type extends, or more generally a type expression.
		     **/
		    TypeDeclarationImpl.prototype["type"] = function () {
		        return _super.prototype.attributes.call(this, 'type', this.toString);
		    };
		    /**
		     * @hidden
		     * Set type value
		     **/
		    TypeDeclarationImpl.prototype.setType = function (param) {
		        this.highLevel().attrOrCreate("type").setValue("" + param);
		        return this;
		    };
		    /**
		     * Location of the parameter (can not be edited by user)
		     **/
		    TypeDeclarationImpl.prototype.location = function () {
		        return _super.prototype.attribute.call(this, 'location', function (attr) { return new ModelLocationImpl(attr); });
		    };
		    /**
		     * Kind of location
		     **/
		    TypeDeclarationImpl.prototype.locationKind = function () {
		        return _super.prototype.attribute.call(this, 'locationKind', function (attr) { return new LocationKindImpl(attr); });
		    };
		    /**
		     * Provides default value for a property
		     **/
		    TypeDeclarationImpl.prototype["default"] = function () {
		        return _super.prototype.attribute.call(this, 'default', this.toString);
		    };
		    /**
		     * @hidden
		     * Set default value
		     **/
		    TypeDeclarationImpl.prototype.setDefault = function (param) {
		        this.highLevel().attrOrCreate("default").setValue("" + param);
		        return this;
		    };
		    /**
		     * An example of an instance of this type. This can be used, e.g., by documentation generators to generate sample values for an object of this type. Cannot be present if the examples property is present.
		     **/
		    TypeDeclarationImpl.prototype.example = function () {
		        return _super.prototype.attribute.call(this, 'example', this.toString);
		    };
		    /**
		     * @hidden
		     * Set example value
		     **/
		    TypeDeclarationImpl.prototype.setExample = function (param) {
		        this.highLevel().attrOrCreate("example").setValue("" + param);
		        return this;
		    };
		    /**
		     * An object containing named examples of instances of this type. This can be used, e.g., by documentation generators to generate sample values for an object of this type. Cannot be present if the examples property is present.
		     **/
		    TypeDeclarationImpl.prototype.examples = function () {
		        return _super.prototype.elements.call(this, 'examples');
		    };
		    /**
		     * The repeat attribute specifies that the parameter can be repeated. If the parameter can be used multiple times, the repeat parameter value MUST be set to 'true'. Otherwise, the default value is 'false' and the parameter may not be repeated.
		     **/
		    TypeDeclarationImpl.prototype.repeat = function () {
		        return _super.prototype.attribute.call(this, 'repeat', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set repeat value
		     **/
		    TypeDeclarationImpl.prototype.setRepeat = function (param) {
		        this.highLevel().attrOrCreate("repeat").setValue("" + param);
		        return this;
		    };
		    /**
		     * Sets if property is optional or not
		     **/
		    TypeDeclarationImpl.prototype.required = function () {
		        return _super.prototype.attribute.call(this, 'required', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set required value
		     **/
		    TypeDeclarationImpl.prototype.setRequired = function (param) {
		        this.highLevel().attrOrCreate("required").setValue("" + param);
		        return this;
		    };
		    /**
		     * An alternate, human-friendly name for the type
		     **/
		    TypeDeclarationImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    TypeDeclarationImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the type
		     **/
		    TypeDeclarationImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    TypeDeclarationImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    /**
		     * Runtime representation of type represented by this AST node
		     **/
		    TypeDeclarationImpl.prototype.runtimeType = function () {
		        return helper.runtimeType(this);
		    };
		    /**
		     * validate an instance against type
		     **/
		    TypeDeclarationImpl.prototype.validateInstance = function (value) {
		        return helper.validateInstance(this, value);
		    };
		    /**
		     * Returns schema content for the cases when schema is inlined, when schema is included, and when schema is a reference.
		     **/
		    TypeDeclarationImpl.prototype.schemaContent = function () {
		        return helper.schemaContent(this);
		    };
		    return TypeDeclarationImpl;
		})(RAMLLanguageElementImpl);
		exports.TypeDeclarationImpl = TypeDeclarationImpl;
		var ModelLocationImpl = (function () {
		    function ModelLocationImpl(attr) {
		        this.attr = attr;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ModelLocationImpl.prototype.wrapperClassName = function () {
		        return "ModelLocationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ModelLocationImpl.prototype.kind = function () {
		        return "ModelLocation";
		    };
		    return ModelLocationImpl;
		})();
		exports.ModelLocationImpl = ModelLocationImpl;
		var LocationKindImpl = (function () {
		    function LocationKindImpl(attr) {
		        this.attr = attr;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    LocationKindImpl.prototype.wrapperClassName = function () {
		        return "LocationKindImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    LocationKindImpl.prototype.kind = function () {
		        return "LocationKind";
		    };
		    return LocationKindImpl;
		})();
		exports.LocationKindImpl = LocationKindImpl;
		var ExampleSpecImpl = (function (_super) {
		    __extends(ExampleSpecImpl, _super);
		    function ExampleSpecImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createExampleSpec(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ExampleSpecImpl.prototype.wrapperClassName = function () {
		        return "ExampleSpecImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ExampleSpecImpl.prototype.kind = function () {
		        return "ExampleSpec";
		    };
		    /**
		     * The example itself
		     **/
		    ExampleSpecImpl.prototype.content = function () {
		        return _super.prototype.attribute.call(this, 'content', this.toString);
		    };
		    /**
		     * @hidden
		     * Set content value
		     **/
		    ExampleSpecImpl.prototype.setContent = function (param) {
		        this.highLevel().attrOrCreate("content").setValue("" + param);
		        return this;
		    };
		    /**
		     * By default, examples are validated against any type declaration. Set this to false to allow examples that need not validate.
		     **/
		    ExampleSpecImpl.prototype.strict = function () {
		        return _super.prototype.attribute.call(this, 'strict', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set strict value
		     **/
		    ExampleSpecImpl.prototype.setStrict = function (param) {
		        this.highLevel().attrOrCreate("strict").setValue("" + param);
		        return this;
		    };
		    ExampleSpecImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    ExampleSpecImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * An alternate, human-friendly name for the example
		     **/
		    ExampleSpecImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ExampleSpecImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the example
		     **/
		    ExampleSpecImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    ExampleSpecImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    return ExampleSpecImpl;
		})(RAMLLanguageElementImpl);
		exports.ExampleSpecImpl = ExampleSpecImpl;
		/**
		 * (Applicable only to Form properties) Value is a file. Client generators SHOULD use this type to handle file uploads correctly.
		 **/
		var FileTypeDeclarationImpl = (function (_super) {
		    __extends(FileTypeDeclarationImpl, _super);
		    function FileTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createFileTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FileTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "FileTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FileTypeDeclarationImpl.prototype.kind = function () {
		        return "FileTypeDeclaration";
		    };
		    /**
		     * It should also include a new property: fileTypes, which should be a list of valid content-type strings for the file. The file type * /* should be a valid value.
		     **/
		    FileTypeDeclarationImpl.prototype.fileTypes = function () {
		        return _super.prototype.attributes.call(this, 'fileTypes', function (attr) { return new ContentTypeImpl(attr); });
		    };
		    /**
		     * The minLength attribute specifies the parameter value's minimum number of bytes.
		     **/
		    FileTypeDeclarationImpl.prototype.minLength = function () {
		        return _super.prototype.attribute.call(this, 'minLength', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minLength value
		     **/
		    FileTypeDeclarationImpl.prototype.setMinLength = function (param) {
		        this.highLevel().attrOrCreate("minLength").setValue("" + param);
		        return this;
		    };
		    /**
		     * The maxLength attribute specifies the parameter value's maximum number of bytes.
		     **/
		    FileTypeDeclarationImpl.prototype.maxLength = function () {
		        return _super.prototype.attribute.call(this, 'maxLength', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maxLength value
		     **/
		    FileTypeDeclarationImpl.prototype.setMaxLength = function (param) {
		        this.highLevel().attrOrCreate("maxLength").setValue("" + param);
		        return this;
		    };
		    return FileTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.FileTypeDeclarationImpl = FileTypeDeclarationImpl;
		var ArrayTypeDeclarationImpl = (function (_super) {
		    __extends(ArrayTypeDeclarationImpl, _super);
		    function ArrayTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createArrayTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ArrayTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "ArrayTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ArrayTypeDeclarationImpl.prototype.kind = function () {
		        return "ArrayTypeDeclaration";
		    };
		    /**
		     * Should items in array be unique
		     **/
		    ArrayTypeDeclarationImpl.prototype.uniqueItems = function () {
		        return _super.prototype.attribute.call(this, 'uniqueItems', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set uniqueItems value
		     **/
		    ArrayTypeDeclarationImpl.prototype.setUniqueItems = function (param) {
		        this.highLevel().attrOrCreate("uniqueItems").setValue("" + param);
		        return this;
		    };
		    /**
		     * Array component type.
		     **/
		    ArrayTypeDeclarationImpl.prototype.items = function () {
		        return _super.prototype.element.call(this, 'items');
		    };
		    /**
		     * Minimum amount of items in array
		     **/
		    ArrayTypeDeclarationImpl.prototype.minItems = function () {
		        return _super.prototype.attribute.call(this, 'minItems', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minItems value
		     **/
		    ArrayTypeDeclarationImpl.prototype.setMinItems = function (param) {
		        this.highLevel().attrOrCreate("minItems").setValue("" + param);
		        return this;
		    };
		    /**
		     * Maximum amount of items in array
		     **/
		    ArrayTypeDeclarationImpl.prototype.maxItems = function () {
		        return _super.prototype.attribute.call(this, 'maxItems', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maxItems value
		     **/
		    ArrayTypeDeclarationImpl.prototype.setMaxItems = function (param) {
		        this.highLevel().attrOrCreate("maxItems").setValue("" + param);
		        return this;
		    };
		    return ArrayTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.ArrayTypeDeclarationImpl = ArrayTypeDeclarationImpl;
		var UnionTypeDeclarationImpl = (function (_super) {
		    __extends(UnionTypeDeclarationImpl, _super);
		    function UnionTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createUnionTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    UnionTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "UnionTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    UnionTypeDeclarationImpl.prototype.kind = function () {
		        return "UnionTypeDeclaration";
		    };
		    /**
		     * Type property name to be used as a discriminator or boolean
		     **/
		    UnionTypeDeclarationImpl.prototype.discriminator = function () {
		        return _super.prototype.attribute.call(this, 'discriminator', this.toString);
		    };
		    /**
		     * @hidden
		     * Set discriminator value
		     **/
		    UnionTypeDeclarationImpl.prototype.setDiscriminator = function (param) {
		        this.highLevel().attrOrCreate("discriminator").setValue("" + param);
		        return this;
		    };
		    return UnionTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.UnionTypeDeclarationImpl = UnionTypeDeclarationImpl;
		var ObjectTypeDeclarationImpl = (function (_super) {
		    __extends(ObjectTypeDeclarationImpl, _super);
		    function ObjectTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createObjectTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ObjectTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "ObjectTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ObjectTypeDeclarationImpl.prototype.kind = function () {
		        return "ObjectTypeDeclaration";
		    };
		    /**
		     * The properties that instances of this type may or must have.
		     **/
		    ObjectTypeDeclarationImpl.prototype.properties = function () {
		        return _super.prototype.elements.call(this, 'properties');
		    };
		    /**
		     * The minimum number of properties allowed for instances of this type.
		     **/
		    ObjectTypeDeclarationImpl.prototype.minProperties = function () {
		        return _super.prototype.attribute.call(this, 'minProperties', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minProperties value
		     **/
		    ObjectTypeDeclarationImpl.prototype.setMinProperties = function (param) {
		        this.highLevel().attrOrCreate("minProperties").setValue("" + param);
		        return this;
		    };
		    /**
		     * The maximum number of properties allowed for instances of this type.
		     **/
		    ObjectTypeDeclarationImpl.prototype.maxProperties = function () {
		        return _super.prototype.attribute.call(this, 'maxProperties', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maxProperties value
		     **/
		    ObjectTypeDeclarationImpl.prototype.setMaxProperties = function (param) {
		        this.highLevel().attrOrCreate("maxProperties").setValue("" + param);
		        return this;
		    };
		    /**
		     * JSON schema style syntax for declaring maps
		     **/
		    ObjectTypeDeclarationImpl.prototype.additionalProperties = function () {
		        return _super.prototype.element.call(this, 'additionalProperties');
		    };
		    /**
		     * JSON schema style syntax for declaring key restricted maps
		     **/
		    ObjectTypeDeclarationImpl.prototype.patternProperties = function () {
		        return _super.prototype.elements.call(this, 'patternProperties');
		    };
		    /**
		     * Type property name to be used as discriminator, or boolean
		     **/
		    ObjectTypeDeclarationImpl.prototype.discriminator = function () {
		        return _super.prototype.attribute.call(this, 'discriminator', function (attr) { return new pointerImpl(attr); });
		    };
		    /**
		     * The value of discriminator for the type.
		     **/
		    ObjectTypeDeclarationImpl.prototype.discriminatorValue = function () {
		        return _super.prototype.attribute.call(this, 'discriminatorValue', this.toString);
		    };
		    /**
		     * @hidden
		     * Set discriminatorValue value
		     **/
		    ObjectTypeDeclarationImpl.prototype.setDiscriminatorValue = function (param) {
		        this.highLevel().attrOrCreate("discriminatorValue").setValue("" + param);
		        return this;
		    };
		    return ObjectTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.ObjectTypeDeclarationImpl = ObjectTypeDeclarationImpl;
		/**
		 * Value must be a string
		 **/
		var StringTypeDeclarationImpl = (function (_super) {
		    __extends(StringTypeDeclarationImpl, _super);
		    function StringTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createStringTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    StringTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "StringTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    StringTypeDeclarationImpl.prototype.kind = function () {
		        return "StringTypeDeclaration";
		    };
		    /**
		     * Regular expression that this string should path
		     **/
		    StringTypeDeclarationImpl.prototype.pattern = function () {
		        return _super.prototype.attribute.call(this, 'pattern', this.toString);
		    };
		    /**
		     * @hidden
		     * Set pattern value
		     **/
		    StringTypeDeclarationImpl.prototype.setPattern = function (param) {
		        this.highLevel().attrOrCreate("pattern").setValue("" + param);
		        return this;
		    };
		    /**
		     * Minimum length of the string
		     **/
		    StringTypeDeclarationImpl.prototype.minLength = function () {
		        return _super.prototype.attribute.call(this, 'minLength', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minLength value
		     **/
		    StringTypeDeclarationImpl.prototype.setMinLength = function (param) {
		        this.highLevel().attrOrCreate("minLength").setValue("" + param);
		        return this;
		    };
		    /**
		     * Maximum length of the string
		     **/
		    StringTypeDeclarationImpl.prototype.maxLength = function () {
		        return _super.prototype.attribute.call(this, 'maxLength', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maxLength value
		     **/
		    StringTypeDeclarationImpl.prototype.setMaxLength = function (param) {
		        this.highLevel().attrOrCreate("maxLength").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type string) The enum attribute provides an enumeration of the parameter's valid values. This MUST be an array. If the enum attribute is defined, API clients and servers MUST verify that a parameter's value matches a value in the enum array. If there is no matching value, the clients and servers MUST treat this as an error.
		     **/
		    StringTypeDeclarationImpl.prototype.enum = function () {
		        return _super.prototype.attributes.call(this, 'enum', this.toString);
		    };
		    /**
		     * @hidden
		     * Set enum value
		     **/
		    StringTypeDeclarationImpl.prototype.setEnum = function (param) {
		        this.highLevel().attrOrCreate("enum").setValue("" + param);
		        return this;
		    };
		    return StringTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.StringTypeDeclarationImpl = StringTypeDeclarationImpl;
		/**
		 * Value must be a boolean
		 **/
		var BooleanTypeDeclarationImpl = (function (_super) {
		    __extends(BooleanTypeDeclarationImpl, _super);
		    function BooleanTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createBooleanTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BooleanTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "BooleanTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BooleanTypeDeclarationImpl.prototype.kind = function () {
		        return "BooleanTypeDeclaration";
		    };
		    return BooleanTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.BooleanTypeDeclarationImpl = BooleanTypeDeclarationImpl;
		/**
		 * Value must be a boolean
		 **/
		var ValueTypeDeclarationImpl = (function (_super) {
		    __extends(ValueTypeDeclarationImpl, _super);
		    function ValueTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createValueTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ValueTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "ValueTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ValueTypeDeclarationImpl.prototype.kind = function () {
		        return "ValueTypeDeclaration";
		    };
		    return ValueTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.ValueTypeDeclarationImpl = ValueTypeDeclarationImpl;
		/**
		 * Value MUST be a number. Indicate floating point numbers as defined by YAML.
		 **/
		var NumberTypeDeclarationImpl = (function (_super) {
		    __extends(NumberTypeDeclarationImpl, _super);
		    function NumberTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createNumberTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    NumberTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "NumberTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    NumberTypeDeclarationImpl.prototype.kind = function () {
		        return "NumberTypeDeclaration";
		    };
		    /**
		     * (Optional, applicable only for parameters of type number or integer) The minimum attribute specifies the parameter's minimum value.
		     **/
		    NumberTypeDeclarationImpl.prototype.minimum = function () {
		        return _super.prototype.attribute.call(this, 'minimum', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minimum value
		     **/
		    NumberTypeDeclarationImpl.prototype.setMinimum = function (param) {
		        this.highLevel().attrOrCreate("minimum").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type number or integer) The maximum attribute specifies the parameter's maximum value.
		     **/
		    NumberTypeDeclarationImpl.prototype.maximum = function () {
		        return _super.prototype.attribute.call(this, 'maximum', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maximum value
		     **/
		    NumberTypeDeclarationImpl.prototype.setMaximum = function (param) {
		        this.highLevel().attrOrCreate("maximum").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type string) The enum attribute provides an enumeration of the parameter's valid values. This MUST be an array. If the enum attribute is defined, API clients and servers MUST verify that a parameter's value matches a value in the enum array. If there is no matching value, the clients and servers MUST treat this as an error.
		     **/
		    NumberTypeDeclarationImpl.prototype.enum = function () {
		        return _super.prototype.attributes.call(this, 'enum', this.toString);
		    };
		    /**
		     * @hidden
		     * Set enum value
		     **/
		    NumberTypeDeclarationImpl.prototype.setEnum = function (param) {
		        this.highLevel().attrOrCreate("enum").setValue("" + param);
		        return this;
		    };
		    /**
		     * Value format
		     **/
		    NumberTypeDeclarationImpl.prototype.format = function () {
		        return _super.prototype.attribute.call(this, 'format', this.toString);
		    };
		    /**
		     * @hidden
		     * Set format value
		     **/
		    NumberTypeDeclarationImpl.prototype.setFormat = function (param) {
		        this.highLevel().attrOrCreate("format").setValue("" + param);
		        return this;
		    };
		    /**
		     * A numeric instance is valid against "multipleOf" if the result of the division of the instance by this keyword's value is an integer.
		     **/
		    NumberTypeDeclarationImpl.prototype.multipleOf = function () {
		        return _super.prototype.attribute.call(this, 'multipleOf', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set multipleOf value
		     **/
		    NumberTypeDeclarationImpl.prototype.setMultipleOf = function (param) {
		        this.highLevel().attrOrCreate("multipleOf").setValue("" + param);
		        return this;
		    };
		    return NumberTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.NumberTypeDeclarationImpl = NumberTypeDeclarationImpl;
		/**
		 * Value MUST be a integer.
		 **/
		var IntegerTypeDeclarationImpl = (function (_super) {
		    __extends(IntegerTypeDeclarationImpl, _super);
		    function IntegerTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createIntegerTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    IntegerTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "IntegerTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    IntegerTypeDeclarationImpl.prototype.kind = function () {
		        return "IntegerTypeDeclaration";
		    };
		    IntegerTypeDeclarationImpl.prototype.format = function () {
		        return _super.prototype.attribute.call(this, 'format', this.toString);
		    };
		    /**
		     * @hidden
		     * Set format value
		     **/
		    IntegerTypeDeclarationImpl.prototype.setFormat = function (param) {
		        this.highLevel().attrOrCreate("format").setValue("" + param);
		        return this;
		    };
		    return IntegerTypeDeclarationImpl;
		})(NumberTypeDeclarationImpl);
		exports.IntegerTypeDeclarationImpl = IntegerTypeDeclarationImpl;
		var RAMLPointerElementImpl = (function (_super) {
		    __extends(RAMLPointerElementImpl, _super);
		    function RAMLPointerElementImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createRAMLPointerElement(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLPointerElementImpl.prototype.wrapperClassName = function () {
		        return "RAMLPointerElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLPointerElementImpl.prototype.kind = function () {
		        return "RAMLPointerElement";
		    };
		    RAMLPointerElementImpl.prototype.target = function () {
		        return _super.prototype.attribute.call(this, 'target', function (attr) { return new RAMLSelectorImpl(attr); });
		    };
		    return RAMLPointerElementImpl;
		})(TypeDeclarationImpl);
		exports.RAMLPointerElementImpl = RAMLPointerElementImpl;
		var RAMLExpressionImpl = (function (_super) {
		    __extends(RAMLExpressionImpl, _super);
		    function RAMLExpressionImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createRAMLExpression(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLExpressionImpl.prototype.wrapperClassName = function () {
		        return "RAMLExpressionImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLExpressionImpl.prototype.kind = function () {
		        return "RAMLExpression";
		    };
		    return RAMLExpressionImpl;
		})(TypeDeclarationImpl);
		exports.RAMLExpressionImpl = RAMLExpressionImpl;
		var ScriptHookElementImpl = (function (_super) {
		    __extends(ScriptHookElementImpl, _super);
		    function ScriptHookElementImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createScriptHookElement(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ScriptHookElementImpl.prototype.wrapperClassName = function () {
		        return "ScriptHookElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ScriptHookElementImpl.prototype.kind = function () {
		        return "ScriptHookElement";
		    };
		    /**
		     * Typescript file defining interface which this scrip should comply to
		     **/
		    ScriptHookElementImpl.prototype.declaredIn = function () {
		        return _super.prototype.attribute.call(this, 'declaredIn', this.toString);
		    };
		    /**
		     * @hidden
		     * Set declaredIn value
		     **/
		    ScriptHookElementImpl.prototype.setDeclaredIn = function (param) {
		        this.highLevel().attrOrCreate("declaredIn").setValue("" + param);
		        return this;
		    };
		    /**
		     * Name of the interface which scripts should comply to
		     **/
		    ScriptHookElementImpl.prototype.interfaceName = function () {
		        return _super.prototype.attribute.call(this, 'interfaceName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set interfaceName value
		     **/
		    ScriptHookElementImpl.prototype.setInterfaceName = function (param) {
		        this.highLevel().attrOrCreate("interfaceName").setValue("" + param);
		        return this;
		    };
		    return ScriptHookElementImpl;
		})(TypeDeclarationImpl);
		exports.ScriptHookElementImpl = ScriptHookElementImpl;
		var SchemaElementImpl = (function (_super) {
		    __extends(SchemaElementImpl, _super);
		    function SchemaElementImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createSchemaElement(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SchemaElementImpl.prototype.wrapperClassName = function () {
		        return "SchemaElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SchemaElementImpl.prototype.kind = function () {
		        return "SchemaElement";
		    };
		    return SchemaElementImpl;
		})(TypeDeclarationImpl);
		exports.SchemaElementImpl = SchemaElementImpl;
		/**
		 * Value MUST be a string representation of a date as defined in RFC2616 Section 3.3 [RFC2616]. or according to specified date format
		 **/
		var DateTypeDeclarationImpl = (function (_super) {
		    __extends(DateTypeDeclarationImpl, _super);
		    function DateTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createDateTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DateTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "DateTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DateTypeDeclarationImpl.prototype.kind = function () {
		        return "DateTypeDeclaration";
		    };
		    DateTypeDeclarationImpl.prototype.dateFormat = function () {
		        return _super.prototype.attribute.call(this, 'dateFormat', function (attr) { return new DateFormatSpecImpl(attr); });
		    };
		    return DateTypeDeclarationImpl;
		})(TypeDeclarationImpl);
		exports.DateTypeDeclarationImpl = DateTypeDeclarationImpl;
		var MethodBaseImpl = (function (_super) {
		    __extends(MethodBaseImpl, _super);
		    function MethodBaseImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createMethodBase(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MethodBaseImpl.prototype.wrapperClassName = function () {
		        return "MethodBaseImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MethodBaseImpl.prototype.kind = function () {
		        return "MethodBase";
		    };
		    /**
		     * Information about the expected responses to a request
		     **/
		    MethodBaseImpl.prototype.responses = function () {
		        return _super.prototype.elements.call(this, 'responses');
		    };
		    /**
		     * Some method verbs expect the resource to be sent as a request body. For example, to create a resource, the request must include the details of the resource to create.
		     * Resources CAN have alternate representations. For example, an API might support both JSON and XML representations.
		     * A method's body is defined in the body property as a hashmap, in which the key MUST be a valid media type.
		     **/
		    MethodBaseImpl.prototype.body = function () {
		        return _super.prototype.elements.call(this, 'body');
		    };
		    /**
		     * A method can override the protocols specified in the resource or at the API root, by employing this property.
		     **/
		    MethodBaseImpl.prototype.protocols = function () {
		        return _super.prototype.attributes.call(this, 'protocols', this.toString);
		    };
		    /**
		     * @hidden
		     * Set protocols value
		     **/
		    MethodBaseImpl.prototype.setProtocols = function (param) {
		        this.highLevel().attrOrCreate("protocols").setValue("" + param);
		        return this;
		    };
		    /**
		     * Instantiation of applyed traits
		     **/
		    MethodBaseImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     **/
		    MethodBaseImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    return MethodBaseImpl;
		})(HasNormalParametersImpl);
		exports.MethodBaseImpl = MethodBaseImpl;
		var ResponseImpl = (function (_super) {
		    __extends(ResponseImpl, _super);
		    function ResponseImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResponse(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResponseImpl.prototype.wrapperClassName = function () {
		        return "ResponseImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResponseImpl.prototype.kind = function () {
		        return "Response";
		    };
		    /**
		     * Responses MUST be a map of one or more HTTP status codes, where each status code itself is a map that describes that status code.
		     **/
		    ResponseImpl.prototype.code = function () {
		        return _super.prototype.attribute.call(this, 'code', function (attr) { return new StatusCodeStringImpl(attr); });
		    };
		    /**
		     * Detailed information about any response headers returned by this method
		     **/
		    ResponseImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    /**
		     * The body of the response: a body declaration
		     **/
		    ResponseImpl.prototype.body = function () {
		        return _super.prototype.elements.call(this, 'body');
		    };
		    /**
		     * An alternate, human-friendly name for the response
		     **/
		    ResponseImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ResponseImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the response
		     **/
		    ResponseImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    ResponseImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    /**
		     * true for codes < 400 and false otherwise
		     **/
		    ResponseImpl.prototype.isOkRange = function () {
		        return helper.isOkRange(this);
		    };
		    return ResponseImpl;
		})(RAMLLanguageElementImpl);
		exports.ResponseImpl = ResponseImpl;
		var TraitImpl = (function (_super) {
		    __extends(TraitImpl, _super);
		    function TraitImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createTrait(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    TraitImpl.prototype.wrapperClassName = function () {
		        return "TraitImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    TraitImpl.prototype.kind = function () {
		        return "Trait";
		    };
		    /**
		     * Name of the trait
		     **/
		    TraitImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    TraitImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    TraitImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    TraitImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    /**
		     * You may import library locally here it contents is accessible only inside of this trait
		     **/
		    TraitImpl.prototype.uses = function () {
		        return _super.prototype.elements.call(this, 'uses');
		    };
		    return TraitImpl;
		})(MethodBaseImpl);
		exports.TraitImpl = TraitImpl;
		var LibraryBaseImpl = (function (_super) {
		    __extends(LibraryBaseImpl, _super);
		    function LibraryBaseImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createLibraryBase(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    LibraryBaseImpl.prototype.wrapperClassName = function () {
		        return "LibraryBaseImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    LibraryBaseImpl.prototype.kind = function () {
		        return "LibraryBase";
		    };
		    LibraryBaseImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    LibraryBaseImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * Alias for the equivalent "types" property, for compatibility with RAML 0.8. Deprecated - API definitions should use the "types" property, as the "schemas" alias for that property name may be removed in a future RAML version. The "types" property allows for XML and JSON schemas.
		     **/
		    LibraryBaseImpl.prototype.schemas = function () {
		        return _super.prototype.elements.call(this, 'schemas');
		    };
		    /**
		     * Declarations of (data) types for use within this API
		     **/
		    LibraryBaseImpl.prototype.types = function () {
		        return _super.prototype.elements.call(this, 'types');
		    };
		    /**
		     * Declarations of traits for use within this API
		     **/
		    LibraryBaseImpl.prototype.traits = function () {
		        return _super.prototype.elements.call(this, 'traits');
		    };
		    /**
		     * Declarations of resource types for use within this API
		     **/
		    LibraryBaseImpl.prototype.resourceTypes = function () {
		        return _super.prototype.elements.call(this, 'resourceTypes');
		    };
		    /**
		     * Declarations of annotation types for use by annotations
		     **/
		    LibraryBaseImpl.prototype.annotationTypes = function () {
		        return _super.prototype.elements.call(this, 'annotationTypes');
		    };
		    /**
		     * Declarations of security schemes for use within this API.
		     **/
		    LibraryBaseImpl.prototype.securitySchemes = function () {
		        return _super.prototype.elements.call(this, 'securitySchemes');
		    };
		    /**
		     * Importing libraries
		     **/
		    LibraryBaseImpl.prototype.uses = function () {
		        return _super.prototype.elements.call(this, 'uses');
		    };
		    return LibraryBaseImpl;
		})(RAMLLanguageElementImpl);
		exports.LibraryBaseImpl = LibraryBaseImpl;
		var LibraryImpl = (function (_super) {
		    __extends(LibraryImpl, _super);
		    function LibraryImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createLibrary(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    LibraryImpl.prototype.wrapperClassName = function () {
		        return "LibraryImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    LibraryImpl.prototype.kind = function () {
		        return "Library";
		    };
		    /**
		     * contains description of why library exist
		     **/
		    LibraryImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    LibraryImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    return LibraryImpl;
		})(LibraryBaseImpl);
		exports.LibraryImpl = LibraryImpl;
		var MethodImpl = (function (_super) {
		    __extends(MethodImpl, _super);
		    function MethodImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createMethod(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MethodImpl.prototype.wrapperClassName = function () {
		        return "MethodImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MethodImpl.prototype.kind = function () {
		        return "Method";
		    };
		    /**
		     * Method that can be called
		     **/
		    MethodImpl.prototype.method = function () {
		        return _super.prototype.attribute.call(this, 'method', this.toString);
		    };
		    /**
		     * @hidden
		     * Set method value
		     **/
		    MethodImpl.prototype.setMethod = function (param) {
		        this.highLevel().attrOrCreate("method").setValue("" + param);
		        return this;
		    };
		    /**
		     * An alternate, human-friendly name for the method (in the resource's context).
		     **/
		    MethodImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    MethodImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the method (in the resource's context)
		     **/
		    MethodImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Specifies the query string needed by this method. Mutually exclusive with queryParameters.
		     **/
		    MethodImpl.prototype.queryString = function () {
		        return _super.prototype.element.call(this, 'queryString');
		    };
		    /**
		     * Detailed information about any query parameters needed by this method. Mutually exclusive with queryString.
		     **/
		    MethodImpl.prototype.queryParameters = function () {
		        return _super.prototype.elements.call(this, 'queryParameters');
		    };
		    /**
		     * Detailed information about any request headers needed by this method.
		     **/
		    MethodImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    /**
		     * Some methods admit request bodies, which are described by this property.
		     **/
		    MethodImpl.prototype.body = function () {
		        return _super.prototype.elements.call(this, 'body');
		    };
		    /**
		     * A list of the traits to apply to this method. See [[raml-10-spec-applying-resource-types-and-traits|Applying Resource Types and Traits]] section.
		     **/
		    MethodImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    MethodImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    /**
		     * The security schemes that apply to this method
		     **/
		    MethodImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * For methods of Resources returns parent resource. For methods of ResourceTypes returns null.
		     **/
		    MethodImpl.prototype.parentResource = function () {
		        return helper.parentResource(this);
		    };
		    /**
		     * Api owning the resource as a sibling
		     **/
		    MethodImpl.prototype.ownerApi = function () {
		        return helper.ownerApi(this);
		    };
		    /**
		     * For methods of Resources: `{parent Resource relative path} {methodName}`.
		     * For methods of ResourceTypes: `{parent ResourceType name} {methodName}`.
		     * For other methods throws Exception.
		     **/
		    MethodImpl.prototype.methodId = function () {
		        return helper.methodId(this);
		    };
		    /**
		     * Returns security schemes, resource or method is secured with. If no security schemes are set at resource or method level,
		     * returns schemes defined with `securedBy` at API level.
		     **/
		    MethodImpl.prototype.allSecuredBy = function () {
		        return helper.allSecuredBy(this);
		    };
		    return MethodImpl;
		})(MethodBaseImpl);
		exports.MethodImpl = MethodImpl;
		var SecuritySchemePartImpl = (function (_super) {
		    __extends(SecuritySchemePartImpl, _super);
		    function SecuritySchemePartImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createSecuritySchemePart(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SecuritySchemePartImpl.prototype.wrapperClassName = function () {
		        return "SecuritySchemePartImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SecuritySchemePartImpl.prototype.kind = function () {
		        return "SecuritySchemePart";
		    };
		    /**
		     * Headers that allowed at this position
		     **/
		    SecuritySchemePartImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    /**
		     * An APIs resources MAY be filtered (to return a subset of results) or altered (such as transforming a response body from JSON to XML format) by the use of query strings. If the resource or its method supports a query string, the query string MUST be defined by the queryParameters property
		     **/
		    SecuritySchemePartImpl.prototype.queryParameters = function () {
		        return _super.prototype.elements.call(this, 'queryParameters');
		    };
		    /**
		     * Specifies the query string, used by the scheme in order to authorize the request. Mutually exclusive with queryParameters.
		     **/
		    SecuritySchemePartImpl.prototype.queryString = function () {
		        return _super.prototype.element.call(this, 'queryString');
		    };
		    /**
		     * Optional array of responses, describing the possible responses that could be sent. See [[raml-10-spec-responses|Responses]] section.
		     **/
		    SecuritySchemePartImpl.prototype.responses = function () {
		        return _super.prototype.elements.call(this, 'responses');
		    };
		    /**
		     * Instantiation of applyed traits
		     **/
		    SecuritySchemePartImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     **/
		    SecuritySchemePartImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * An alternate, human-friendly name for the security scheme part
		     **/
		    SecuritySchemePartImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    SecuritySchemePartImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the security scheme part
		     **/
		    SecuritySchemePartImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Annotations to be applied to this security scheme part. Annotations are any property whose key begins with "(" and ends with ")" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See [[raml-10-spec-annotations|the section on annotations]].
		     **/
		    SecuritySchemePartImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    return SecuritySchemePartImpl;
		})(MethodBaseImpl);
		exports.SecuritySchemePartImpl = SecuritySchemePartImpl;
		var SecuritySchemeSettingsImpl = (function (_super) {
		    __extends(SecuritySchemeSettingsImpl, _super);
		    function SecuritySchemeSettingsImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "SecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "SecuritySchemeSettings";
		    };
		    return SecuritySchemeSettingsImpl;
		})(core.BasicNodeImpl);
		exports.SecuritySchemeSettingsImpl = SecuritySchemeSettingsImpl;
		var OAuth1SecuritySchemeSettingsImpl = (function (_super) {
		    __extends(OAuth1SecuritySchemeSettingsImpl, _super);
		    function OAuth1SecuritySchemeSettingsImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth1SecuritySchemeSettings(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "OAuth1SecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "OAuth1SecuritySchemeSettings";
		    };
		    /**
		     * The URI of the Temporary Credential Request endpoint as defined in RFC5849 Section 2.1
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.requestTokenUri = function () {
		        return _super.prototype.attribute.call(this, 'requestTokenUri', function (attr) { return new FixedUriStringImpl(attr); });
		    };
		    /**
		     * The URI of the Resource Owner Authorization endpoint as defined in RFC5849 Section 2.2
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.authorizationUri = function () {
		        return _super.prototype.attribute.call(this, 'authorizationUri', function (attr) { return new FixedUriStringImpl(attr); });
		    };
		    /**
		     * The URI of the Token Request endpoint as defined in RFC5849 Section 2.3
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.tokenCredentialsUri = function () {
		        return _super.prototype.attribute.call(this, 'tokenCredentialsUri', function (attr) { return new FixedUriStringImpl(attr); });
		    };
		    OAuth1SecuritySchemeSettingsImpl.prototype.signatures = function () {
		        return _super.prototype.attributes.call(this, 'signatures', this.toString);
		    };
		    /**
		     * @hidden
		     * Set signatures value
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.setSignatures = function (param) {
		        this.highLevel().attrOrCreate("signatures").setValue("" + param);
		        return this;
		    };
		    return OAuth1SecuritySchemeSettingsImpl;
		})(SecuritySchemeSettingsImpl);
		exports.OAuth1SecuritySchemeSettingsImpl = OAuth1SecuritySchemeSettingsImpl;
		var OAuth2SecuritySchemeSettingsImpl = (function (_super) {
		    __extends(OAuth2SecuritySchemeSettingsImpl, _super);
		    function OAuth2SecuritySchemeSettingsImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth2SecuritySchemeSettings(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "OAuth2SecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "OAuth2SecuritySchemeSettings";
		    };
		    /**
		     * The URI of the Token Endpoint as defined in RFC6749 [RFC6748] Section 3.2. Not required forby implicit grant type.
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.accessTokenUri = function () {
		        return _super.prototype.attribute.call(this, 'accessTokenUri', function (attr) { return new FixedUriStringImpl(attr); });
		    };
		    /**
		     * The URI of the Authorization Endpoint as defined in RFC6749 [RFC6748] Section 3.1. Required forby authorization_code and implicit grant types.
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.authorizationUri = function () {
		        return _super.prototype.attribute.call(this, 'authorizationUri', function (attr) { return new FixedUriStringImpl(attr); });
		    };
		    OAuth2SecuritySchemeSettingsImpl.prototype.authorizationGrants = function () {
		        return _super.prototype.attributes.call(this, 'authorizationGrants', this.toString);
		    };
		    /**
		     * @hidden
		     * Set authorizationGrants value
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.setAuthorizationGrants = function (param) {
		        this.highLevel().attrOrCreate("authorizationGrants").setValue("" + param);
		        return this;
		    };
		    /**
		     * A list of scopes supported by the security scheme as defined in RFC6749 [RFC6749] Section 3.3
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.scopes = function () {
		        return _super.prototype.attributes.call(this, 'scopes', this.toString);
		    };
		    /**
		     * @hidden
		     * Set scopes value
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.setScopes = function (param) {
		        this.highLevel().attrOrCreate("scopes").setValue("" + param);
		        return this;
		    };
		    return OAuth2SecuritySchemeSettingsImpl;
		})(SecuritySchemeSettingsImpl);
		exports.OAuth2SecuritySchemeSettingsImpl = OAuth2SecuritySchemeSettingsImpl;
		var PassThroughSecuritySchemeSettingsImpl = (function (_super) {
		    __extends(PassThroughSecuritySchemeSettingsImpl, _super);
		    function PassThroughSecuritySchemeSettingsImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createPassThroughSecuritySchemeSettings(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    PassThroughSecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "PassThroughSecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    PassThroughSecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "PassThroughSecuritySchemeSettings";
		    };
		    PassThroughSecuritySchemeSettingsImpl.prototype.queryParameterName = function () {
		        return _super.prototype.attribute.call(this, 'queryParameterName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set queryParameterName value
		     **/
		    PassThroughSecuritySchemeSettingsImpl.prototype.setQueryParameterName = function (param) {
		        this.highLevel().attrOrCreate("queryParameterName").setValue("" + param);
		        return this;
		    };
		    PassThroughSecuritySchemeSettingsImpl.prototype.headerName = function () {
		        return _super.prototype.attribute.call(this, 'headerName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set headerName value
		     **/
		    PassThroughSecuritySchemeSettingsImpl.prototype.setHeaderName = function (param) {
		        this.highLevel().attrOrCreate("headerName").setValue("" + param);
		        return this;
		    };
		    return PassThroughSecuritySchemeSettingsImpl;
		})(SecuritySchemeSettingsImpl);
		exports.PassThroughSecuritySchemeSettingsImpl = PassThroughSecuritySchemeSettingsImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var OAuth2SecuritySchemeImpl = (function (_super) {
		    __extends(OAuth2SecuritySchemeImpl, _super);
		    function OAuth2SecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth2SecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth2SecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "OAuth2SecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth2SecuritySchemeImpl.prototype.kind = function () {
		        return "OAuth2SecurityScheme";
		    };
		    OAuth2SecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return OAuth2SecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.OAuth2SecuritySchemeImpl = OAuth2SecuritySchemeImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var OAuth1SecuritySchemeImpl = (function (_super) {
		    __extends(OAuth1SecuritySchemeImpl, _super);
		    function OAuth1SecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth1SecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth1SecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "OAuth1SecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth1SecuritySchemeImpl.prototype.kind = function () {
		        return "OAuth1SecurityScheme";
		    };
		    OAuth1SecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return OAuth1SecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.OAuth1SecuritySchemeImpl = OAuth1SecuritySchemeImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var PassThroughSecuritySchemeImpl = (function (_super) {
		    __extends(PassThroughSecuritySchemeImpl, _super);
		    function PassThroughSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createPassThroughSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    PassThroughSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "PassThroughSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    PassThroughSecuritySchemeImpl.prototype.kind = function () {
		        return "PassThroughSecurityScheme";
		    };
		    PassThroughSecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return PassThroughSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.PassThroughSecuritySchemeImpl = PassThroughSecuritySchemeImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var BasicSecuritySchemeImpl = (function (_super) {
		    __extends(BasicSecuritySchemeImpl, _super);
		    function BasicSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createBasicSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BasicSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "BasicSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BasicSecuritySchemeImpl.prototype.kind = function () {
		        return "BasicSecurityScheme";
		    };
		    return BasicSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.BasicSecuritySchemeImpl = BasicSecuritySchemeImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var DigestSecuritySchemeImpl = (function (_super) {
		    __extends(DigestSecuritySchemeImpl, _super);
		    function DigestSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createDigestSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DigestSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "DigestSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DigestSecuritySchemeImpl.prototype.kind = function () {
		        return "DigestSecurityScheme";
		    };
		    return DigestSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.DigestSecuritySchemeImpl = DigestSecuritySchemeImpl;
		/**
		 * Declares globally referable security scheme definition
		 **/
		var CustomSecuritySchemeImpl = (function (_super) {
		    __extends(CustomSecuritySchemeImpl, _super);
		    function CustomSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createCustomSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    CustomSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "CustomSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    CustomSecuritySchemeImpl.prototype.kind = function () {
		        return "CustomSecurityScheme";
		    };
		    return CustomSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.CustomSecuritySchemeImpl = CustomSecuritySchemeImpl;
		var ResourceBaseImpl = (function (_super) {
		    __extends(ResourceBaseImpl, _super);
		    function ResourceBaseImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResourceBase(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceBaseImpl.prototype.wrapperClassName = function () {
		        return "ResourceBaseImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceBaseImpl.prototype.kind = function () {
		        return "ResourceBase";
		    };
		    /**
		     * Methods that are part of this resource type definition
		     **/
		    ResourceBaseImpl.prototype.methods = function () {
		        return _super.prototype.elements.call(this, 'methods');
		    };
		    /**
		     * A list of the traits to apply to all methods declared (implicitly or explicitly) for this resource. See [[raml-10-spec-applying-resource-types-and-traits|Applying Resource Types and Traits]] section. Individual methods may override this declaration
		     **/
		    ResourceBaseImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * The resource type which this resource inherits. . See [[raml-10-spec-applying-resource-types-and-traits|Applying Resource Types and Traits]] section.
		     **/
		    ResourceBaseImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', function (attr) { return new ResourceTypeRefImpl(attr); });
		    };
		    /**
		     * The security schemes that apply to all methods declared (implicitly or explicitly) for this resource.
		     **/
		    ResourceBaseImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * Detailed information about any URI parameters of this resource
		     **/
		    ResourceBaseImpl.prototype.uriParameters = function () {
		        return _super.prototype.elements.call(this, 'uriParameters');
		    };
		    return ResourceBaseImpl;
		})(RAMLLanguageElementImpl);
		exports.ResourceBaseImpl = ResourceBaseImpl;
		var ResourceTypeImpl = (function (_super) {
		    __extends(ResourceTypeImpl, _super);
		    function ResourceTypeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResourceType(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceTypeImpl.prototype.wrapperClassName = function () {
		        return "ResourceTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceTypeImpl.prototype.kind = function () {
		        return "ResourceType";
		    };
		    /**
		     * Name of the resource type
		     **/
		    ResourceTypeImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    ResourceTypeImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    ResourceTypeImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    ResourceTypeImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    /**
		     * You may import library locally here it contents is accessible only inside of this resource type
		     **/
		    ResourceTypeImpl.prototype.uses = function () {
		        return _super.prototype.elements.call(this, 'uses');
		    };
		    return ResourceTypeImpl;
		})(ResourceBaseImpl);
		exports.ResourceTypeImpl = ResourceTypeImpl;
		var ResourceImpl = (function (_super) {
		    __extends(ResourceImpl, _super);
		    function ResourceImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResource(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceImpl.prototype.wrapperClassName = function () {
		        return "ResourceImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceImpl.prototype.kind = function () {
		        return "Resource";
		    };
		    /**
		     * Relative URL of this resource from the parent resource
		     **/
		    ResourceImpl.prototype.relativeUri = function () {
		        return _super.prototype.attribute.call(this, 'relativeUri', function (attr) { return new RelativeUriStringImpl(attr); });
		    };
		    /**
		     * A nested resource is identified as any property whose name begins with a slash ("/") and is therefore treated as a relative URI.
		     **/
		    ResourceImpl.prototype.resources = function () {
		        return _super.prototype.elements.call(this, 'resources');
		    };
		    /**
		     * An alternate, human-friendly name for the resource.
		     **/
		    ResourceImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ResourceImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the resource.
		     **/
		    ResourceImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    ResourceImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    /**
		     * Path relative to API root
		     **/
		    ResourceImpl.prototype.completeRelativeUri = function () {
		        return helper.completeRelativeUri(this);
		    };
		    /**
		     * baseUri of owning Api concatenated with completeRelativeUri
		     **/
		    ResourceImpl.prototype.absoluteUri = function () {
		        return helper.absoluteUri(this);
		    };
		    /**
		     * Parent resource for non top level resources
		     **/
		    ResourceImpl.prototype.parentResource = function () {
		        return helper.parent(this);
		    };
		    /**
		     * Get child resource by its relative path
		     **/
		    ResourceImpl.prototype.childResource = function (relPath) {
		        return helper.childResource(this, relPath);
		    };
		    /**
		     * Get child method by its name
		     **/
		    ResourceImpl.prototype.childMethod = function (method) {
		        return helper.childMethod(this, method);
		    };
		    /**
		     * Api owning the resource as a sibling
		     **/
		    ResourceImpl.prototype.ownerApi = function () {
		        return helper.ownerApi(this);
		    };
		    /**
		     * Retrieve an ordered list of all uri parameters including those which are not described in the `uriParameters` node.
		     * Consider a fragment of RAML specification:
		     * ```yaml
		     * /resource/{objectId}/{propertyId}:
		     * uriParameters:
		     * objectId:
		     * ```
		     * Here `propertyId` uri parameter is not described in the `uriParameters` node.
		     * Thus, it is not among Resource.uriParameters(), but it is among Resource.allUriParameters().
		     **/
		    ResourceImpl.prototype.allUriParameters = function () {
		        return helper.uriParameters(this);
		    };
		    /**
		     * Retrieve an ordered list of all absolute uri parameters. Returns a union of `Api.allBaseUriParameters()`
		     * for `Api` owning the `Resource` and `Resource.allUriParameters()`.
		     **/
		    ResourceImpl.prototype.absoluteUriParameters = function () {
		        return helper.absoluteUriParameters(this);
		    };
		    /**
		     * Returns security schemes, resource or method is secured with. If no security schemes are set at resource or method level,
		     * returns schemes defined with `securedBy` at API level.
		     **/
		    ResourceImpl.prototype.allSecuredBy = function () {
		        return helper.allSecuredBy(this);
		    };
		    return ResourceImpl;
		})(ResourceBaseImpl);
		exports.ResourceImpl = ResourceImpl;
		var AnnotationTypeDeclarationImpl = (function (_super) {
		    __extends(AnnotationTypeDeclarationImpl, _super);
		    function AnnotationTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createAnnotationTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    AnnotationTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "AnnotationTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    AnnotationTypeDeclarationImpl.prototype.kind = function () {
		        return "AnnotationTypeDeclaration";
		    };
		    /**
		     * Whether multiple instances of annotations of this type may be applied simultaneously at the same location
		     **/
		    AnnotationTypeDeclarationImpl.prototype.allowMultiple = function () {
		        return _super.prototype.attribute.call(this, 'allowMultiple', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set allowMultiple value
		     **/
		    AnnotationTypeDeclarationImpl.prototype.setAllowMultiple = function (param) {
		        this.highLevel().attrOrCreate("allowMultiple").setValue("" + param);
		        return this;
		    };
		    /**
		     * Restrictions on where annotations of this type can be applied. If this property is specified, annotations of this type may only be applied on a property corresponding to one of the target names specified as the value of this property.
		     **/
		    AnnotationTypeDeclarationImpl.prototype.allowedTargets = function () {
		        return _super.prototype.attributes.call(this, 'allowedTargets', function (attr) { return new AnnotationTargetImpl(attr); });
		    };
		    return AnnotationTypeDeclarationImpl;
		})(RAMLLanguageElementImpl);
		exports.AnnotationTypeDeclarationImpl = AnnotationTypeDeclarationImpl;
		var RAMLSimpleElementImpl = (function (_super) {
		    __extends(RAMLSimpleElementImpl, _super);
		    function RAMLSimpleElementImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLSimpleElementImpl.prototype.wrapperClassName = function () {
		        return "RAMLSimpleElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLSimpleElementImpl.prototype.kind = function () {
		        return "RAMLSimpleElement";
		    };
		    return RAMLSimpleElementImpl;
		})(core.BasicNodeImpl);
		exports.RAMLSimpleElementImpl = RAMLSimpleElementImpl;
		var ImportDeclarationImpl = (function (_super) {
		    __extends(ImportDeclarationImpl, _super);
		    function ImportDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createImportDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ImportDeclarationImpl.prototype.wrapperClassName = function () {
		        return "ImportDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ImportDeclarationImpl.prototype.kind = function () {
		        return "ImportDeclaration";
		    };
		    /**
		     * Name prefix (without dot) used to refer imported declarations
		     **/
		    ImportDeclarationImpl.prototype.key = function () {
		        return _super.prototype.attribute.call(this, 'key', this.toString);
		    };
		    /**
		     * @hidden
		     * Set key value
		     **/
		    ImportDeclarationImpl.prototype.setKey = function (param) {
		        this.highLevel().attrOrCreate("key").setValue("" + param);
		        return this;
		    };
		    /**
		     * Content of the declared namespace
		     **/
		    ImportDeclarationImpl.prototype.value = function () {
		        return _super.prototype.element.call(this, 'value');
		    };
		    return ImportDeclarationImpl;
		})(RAMLSimpleElementImpl);
		exports.ImportDeclarationImpl = ImportDeclarationImpl;
		/**
		 * Content of the schema
		 **/
		var GlobalSchemaImpl = (function (_super) {
		    __extends(GlobalSchemaImpl, _super);
		    function GlobalSchemaImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createGlobalSchema(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    GlobalSchemaImpl.prototype.wrapperClassName = function () {
		        return "GlobalSchemaImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    GlobalSchemaImpl.prototype.kind = function () {
		        return "GlobalSchema";
		    };
		    /**
		     * Name of the global schema, used to refer on schema content
		     **/
		    GlobalSchemaImpl.prototype.key = function () {
		        return _super.prototype.attribute.call(this, 'key', this.toString);
		    };
		    /**
		     * @hidden
		     * Set key value
		     **/
		    GlobalSchemaImpl.prototype.setKey = function (param) {
		        this.highLevel().attrOrCreate("key").setValue("" + param);
		        return this;
		    };
		    /**
		     * Content of the schema
		     **/
		    GlobalSchemaImpl.prototype.value = function () {
		        return _super.prototype.attribute.call(this, 'value', function (attr) { return new SchemaStringImpl(attr); });
		    };
		    return GlobalSchemaImpl;
		})(RAMLSimpleElementImpl);
		exports.GlobalSchemaImpl = GlobalSchemaImpl;
		var ApiImpl = (function (_super) {
		    __extends(ApiImpl, _super);
		    function ApiImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createApi(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ApiImpl.prototype.wrapperClassName = function () {
		        return "ApiImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ApiImpl.prototype.kind = function () {
		        return "Api";
		    };
		    /**
		     * Short plain-text label for the API
		     **/
		    ApiImpl.prototype.title = function () {
		        return _super.prototype.attribute.call(this, 'title', this.toString);
		    };
		    /**
		     * @hidden
		     * Set title value
		     **/
		    ApiImpl.prototype.setTitle = function (param) {
		        this.highLevel().attrOrCreate("title").setValue("" + param);
		        return this;
		    };
		    /**
		     * The version of the API, e.g. "v1"
		     **/
		    ApiImpl.prototype.version = function () {
		        return _super.prototype.attribute.call(this, 'version', this.toString);
		    };
		    /**
		     * @hidden
		     * Set version value
		     **/
		    ApiImpl.prototype.setVersion = function (param) {
		        this.highLevel().attrOrCreate("version").setValue("" + param);
		        return this;
		    };
		    /**
		     * A URI that's to be used as the base of all the resources' URIs. Often used as the base of the URL of each resource, containing the location of the API. Can be a template URI.
		     **/
		    ApiImpl.prototype.baseUri = function () {
		        return _super.prototype.attribute.call(this, 'baseUri', function (attr) { return new FullUriTemplateStringImpl(attr); });
		    };
		    /**
		     * Named parameters used in the baseUri (template)
		     **/
		    ApiImpl.prototype.baseUriParameters = function () {
		        return _super.prototype.elements.call(this, 'baseUriParameters');
		    };
		    /**
		     * The protocols supported by the API
		     **/
		    ApiImpl.prototype.protocols = function () {
		        return _super.prototype.attributes.call(this, 'protocols', this.toString);
		    };
		    /**
		     * @hidden
		     * Set protocols value
		     **/
		    ApiImpl.prototype.setProtocols = function (param) {
		        this.highLevel().attrOrCreate("protocols").setValue("" + param);
		        return this;
		    };
		    /**
		     * The default media type to use for request and response bodies (payloads), e.g. "application/json"
		     **/
		    ApiImpl.prototype.mediaType = function () {
		        return _super.prototype.attribute.call(this, 'mediaType', function (attr) { return new MimeTypeImpl(attr); });
		    };
		    /**
		     * The security schemes that apply to every resource and method in the API
		     **/
		    ApiImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * The resources of the API, identified as relative URIs that begin with a slash (/). Every property whose key begins with a slash (/), and is either at the root of the API definition or is the child property of a resource property, is a resource property, e.g.: /users, /{groupId}, etc
		     **/
		    ApiImpl.prototype.resources = function () {
		        return _super.prototype.elements.call(this, 'resources');
		    };
		    /**
		     * Additional overall documentation for the API
		     **/
		    ApiImpl.prototype.documentation = function () {
		        return _super.prototype.elements.call(this, 'documentation');
		    };
		    /**
		     * The displayName attribute specifies the $self's display name. It is a friendly name used only for display or documentation purposes. If displayName is not specified, it defaults to the element's key (the name of the property itself).
		     **/
		    ApiImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ApiImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    ApiImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    ApiImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the API
		     **/
		    ApiImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * Most of RAML model elements may have attached annotations decribing additional meta data about this element
		     **/
		    ApiImpl.prototype.annotations = function () {
		        return _super.prototype.attributes.call(this, 'annotations', function (attr) { return new AnnotationRefImpl(attr); });
		    };
		    /**
		     * Equivalent API with traits and resource types expanded
		     **/
		    ApiImpl.prototype.expand = function () {
		        return helper.expandTraitsAndResourceTypes(this);
		    };
		    /**
		     * Retrieve all traits including those defined in libraries
		     **/
		    ApiImpl.prototype.allTraits = function () {
		        return helper.allTraits(this);
		    };
		    /**
		     * Retrieve all resource types including those defined in libraries
		     **/
		    ApiImpl.prototype.allResourceTypes = function () {
		        return helper.allResourceTypes(this);
		    };
		    /**
		     * Get child resource by its relative path
		     **/
		    ApiImpl.prototype.childResource = function (relPath) {
		        return helper.childResource(this, relPath);
		    };
		    /**
		     * Retrieve all resources of the Api
		     **/
		    ApiImpl.prototype.allResources = function () {
		        return helper.allResources(this);
		    };
		    /**
		     * Retrieve an ordered list of all base uri parameters regardless of whether they are described in `baseUriParameters` or not
		     * Consider a fragment of RAML specification:
		     * ```yaml
		     * version: v1
		     * baseUri: https://{organization}.example.com/{version}/{service}
		     * baseUriParameters:
		     * service:
		     * ```
		     * Here `version` and `organization` are base uri parameters which are not described in the `baseUriParameters` node.
		     * Thus, they are not among `Api.baseUriParameters()`, but they are among `Api.allBaseUriParameters()`.
		     **/
		    ApiImpl.prototype.allBaseUriParameters = function () {
		        return helper.baseUriParameters(this);
		    };
		    /**
		     * Protocols used by the API. Returns the `protocols` property value if it is specified.
		     * Otherwise, returns protocol, specified in the base URI.
		     **/
		    ApiImpl.prototype.allProtocols = function () {
		        return helper.allProtocols(this);
		    };
		    /**
		     * Returns RAML version. "RAML10" string is returned for RAML 1.0. "RAML08" string is returned for RAML 0.8.
		     **/
		    ApiImpl.prototype.RAMLVersion = function () {
		        return helper.RAMLVersion(this);
		    };
		    return ApiImpl;
		})(LibraryBaseImpl);
		exports.ApiImpl = ApiImpl;
		var OverlayImpl = (function (_super) {
		    __extends(OverlayImpl, _super);
		    function OverlayImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOverlay(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OverlayImpl.prototype.wrapperClassName = function () {
		        return "OverlayImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OverlayImpl.prototype.kind = function () {
		        return "Overlay";
		    };
		    /**
		     * contains description of why overlay exist
		     **/
		    OverlayImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    OverlayImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    OverlayImpl.prototype.masterRef = function () {
		        return _super.prototype.attribute.call(this, 'masterRef', this.toString);
		    };
		    /**
		     * @hidden
		     * Set masterRef value
		     **/
		    OverlayImpl.prototype.setMasterRef = function (param) {
		        this.highLevel().attrOrCreate("masterRef").setValue("" + param);
		        return this;
		    };
		    /**
		     * Short plain-text label for the API
		     **/
		    OverlayImpl.prototype.title = function () {
		        return _super.prototype.attribute.call(this, 'title', this.toString);
		    };
		    /**
		     * @hidden
		     * Set title value
		     **/
		    OverlayImpl.prototype.setTitle = function (param) {
		        this.highLevel().attrOrCreate("title").setValue("" + param);
		        return this;
		    };
		    return OverlayImpl;
		})(ApiImpl);
		exports.OverlayImpl = OverlayImpl;
		var ExtensionImpl = (function (_super) {
		    __extends(ExtensionImpl, _super);
		    function ExtensionImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createExtension(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ExtensionImpl.prototype.wrapperClassName = function () {
		        return "ExtensionImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ExtensionImpl.prototype.kind = function () {
		        return "Extension";
		    };
		    /**
		     * contains description of why extension exist
		     **/
		    ExtensionImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    ExtensionImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    ExtensionImpl.prototype.masterRef = function () {
		        return _super.prototype.attribute.call(this, 'masterRef', this.toString);
		    };
		    /**
		     * @hidden
		     * Set masterRef value
		     **/
		    ExtensionImpl.prototype.setMasterRef = function (param) {
		        this.highLevel().attrOrCreate("masterRef").setValue("" + param);
		        return this;
		    };
		    /**
		     * Short plain-text label for the API
		     **/
		    ExtensionImpl.prototype.title = function () {
		        return _super.prototype.attribute.call(this, 'title', this.toString);
		    };
		    /**
		     * @hidden
		     * Set title value
		     **/
		    ExtensionImpl.prototype.setTitle = function (param) {
		        this.highLevel().attrOrCreate("title").setValue("" + param);
		        return this;
		    };
		    return ExtensionImpl;
		})(ApiImpl);
		exports.ExtensionImpl = ExtensionImpl;
		/**
		 * @hidden
		 **/
		function createApi(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Api");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createLibraryBase(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("LibraryBase");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLLanguageElement(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("RAMLLanguageElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createDocumentationItem(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("DocumentationItem");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createScriptSpec(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ScriptSpec");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createApiDescription(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ApiDescription");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createCallbackAPIDescription(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("CallbackAPIDescription");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLProject(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("RAMLProject");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createAbstractSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("AbstractSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createSecuritySchemePart(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("SecuritySchemePart");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createMethodBase(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("MethodBase");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createHasNormalParameters(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("HasNormalParameters");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("TypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createExampleSpec(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ExampleSpec");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createFileTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("FileTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createArrayTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ArrayTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createUnionTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("UnionTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createObjectTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ObjectTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createStringTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("StringTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createBooleanTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("BooleanTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createValueTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ValueTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createNumberTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("NumberTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createIntegerTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("IntegerTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLPointerElement(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("RAMLPointerElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLExpression(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("RAMLExpression");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createScriptHookElement(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ScriptHookElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createSchemaElement(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("SchemaElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createDateTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("DateTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResponse(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Response");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createTrait(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Trait");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createLibrary(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Library");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createMethod(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Method");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createSecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("SecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth1SecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("OAuth1SecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth2SecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("OAuth2SecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createPassThroughSecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("PassThroughSecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth2SecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("OAuth2SecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth1SecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("OAuth1SecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createPassThroughSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("PassThroughSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createBasicSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("BasicSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createDigestSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("DigestSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createCustomSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("CustomSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResourceBase(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ResourceBase");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResourceType(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ResourceType");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResource(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Resource");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createAnnotationTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("AnnotationTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createGlobalSchema(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("GlobalSchema");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLSimpleElement(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("RAMLSimpleElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createImportDeclaration(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("ImportDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOverlay(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Overlay");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createExtension(key) {
		    var universe = hl.universeProvider("RAML10");
		    var nc = universe.type("Extension");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		function loadApiSync(apiPath, arg1, arg2) {
		    return apiLoader.loadApi(apiPath, arg1, arg2).getOrElse(null);
		}
		exports.loadApiSync = loadApiSync;
		function loadRAMLSync(ramlPath, arg1, arg2) {
		    return apiLoader.loadApi(ramlPath, arg1, arg2).getOrElse(null);
		}
		exports.loadRAMLSync = loadRAMLSync;
		function loadApi(apiPath, arg1, arg2) {
		    return apiLoader.loadApiAsync(apiPath, arg1, arg2);
		}
		exports.loadApi = loadApi;
		function loadRAML(ramlPath, arg1, arg2) {
		    return apiLoader.loadRAMLAsync(ramlPath, arg1, arg2);
		}
		exports.loadRAML = loadRAML;
		/**
		 * Gets AST node by runtime type, if runtime type matches any.
		 * @param runtimeType - runtime type to find the match for
		 */
		function getLanguageElementByRuntimeType(runtimeType) {
		    return apiLoader.getLanguageElementByRuntimeType(runtimeType);
		}
		exports.getLanguageElementByRuntimeType = getLanguageElementByRuntimeType;


	/***/ },
	/* 2 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var ds = __webpack_require__(3);
		(function (NodeKind) {
		    NodeKind[NodeKind["BASIC"] = 0] = "BASIC";
		    NodeKind[NodeKind["NODE"] = 1] = "NODE";
		    NodeKind[NodeKind["ATTRIBUTE"] = 2] = "ATTRIBUTE";
		})(exports.NodeKind || (exports.NodeKind = {}));
		var NodeKind = exports.NodeKind;
		(function (RAMLVersion) {
		    RAMLVersion[RAMLVersion["RAML10"] = 0] = "RAML10";
		    RAMLVersion[RAMLVersion["RAML08"] = 1] = "RAML08";
		})(exports.RAMLVersion || (exports.RAMLVersion = {}));
		var RAMLVersion = exports.RAMLVersion;
		(function (IssueCode) {
		    IssueCode[IssueCode["UNRESOLVED_REFERENCE"] = 0] = "UNRESOLVED_REFERENCE";
		    IssueCode[IssueCode["YAML_ERROR"] = 1] = "YAML_ERROR";
		    IssueCode[IssueCode["UNKNOWN_NODE"] = 2] = "UNKNOWN_NODE";
		    IssueCode[IssueCode["MISSING_REQUIRED_PROPERTY"] = 3] = "MISSING_REQUIRED_PROPERTY";
		    IssueCode[IssueCode["PROPERTY_EXPECT_TO_HAVE_SINGLE_VALUE"] = 4] = "PROPERTY_EXPECT_TO_HAVE_SINGLE_VALUE";
		    //TODO IMPLEMENT
		    IssueCode[IssueCode["KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT"] = 5] = "KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT";
		    IssueCode[IssueCode["UNABLE_TO_RESOLVE_INCLUDE_FILE"] = 6] = "UNABLE_TO_RESOLVE_INCLUDE_FILE";
		    IssueCode[IssueCode["INVALID_VALUE_SCHEMA"] = 7] = "INVALID_VALUE_SCHEMA";
		    IssueCode[IssueCode["MISSED_CONTEXT_REQUIREMENT"] = 8] = "MISSED_CONTEXT_REQUIREMENT";
		    IssueCode[IssueCode["NODE_HAS_VALUE"] = 9] = "NODE_HAS_VALUE";
		    IssueCode[IssueCode["ONLY_OVERRIDE_ALLOWED"] = 10] = "ONLY_OVERRIDE_ALLOWED";
		})(exports.IssueCode || (exports.IssueCode = {}));
		var IssueCode = exports.IssueCode;
		exports.universeProvider = __webpack_require__(78);
		var hlImpl = __webpack_require__(5);
		var getDefinitionSystemType = function (contents, ast) {
		    var spec = "";
		    var ptype = "Api";
		    var num = 0;
		    var pt = 0;
		    for (var n = 0; n < contents.length; n++) {
		        var c = contents.charAt(n);
		        if (c == '\r' || c == '\n') {
		            if (spec) {
		                ptype = contents.substring(pt, n).trim();
		            }
		            else {
		                spec = contents.substring(0, n).trim();
		            }
		            break;
		        }
		        if (c == ' ') {
		            num++;
		            if (!spec && num == 2) {
		                spec = contents.substring(0, n);
		                pt = n;
		            }
		        }
		    }
		    var localUniverse = spec == "#%RAML 1.0" ? new ds.Universe("RAML10", exports.universeProvider("RAML10"), "RAML10") : new ds.Universe("RAML08", exports.universeProvider("RAML08"));
		    if (ptype == 'API') {
		        ptype = "Api";
		    }
		    if (ptype == 'NamedExample') {
		        ptype = "ExampleSpec";
		    }
		    if (ptype == 'DataType') {
		        ptype = "TypeDeclaration";
		    }
		    if (ptype == 'SecurityScheme') {
		        ptype = "AbstractSecurityScheme";
		    }
		    localUniverse.setTopLevel(ptype);
		    localUniverse.setTypedVersion(spec);
		    // localUniverse.setDescription(spec);
		    return { ptype: ptype, localUniverse: localUniverse };
		};
		function getFragmentDefenitionName(highLevelNode) {
		    var contents = highLevelNode.lowLevel() && highLevelNode.lowLevel().unit() && highLevelNode.lowLevel().unit().contents();
		    return getDefinitionSystemType(contents, highLevelNode.lowLevel()).ptype;
		}
		exports.getFragmentDefenitionName = getFragmentDefenitionName;
		function fromUnit(l) {
		    if (l == null)
		        return null;
		    var contents = l.contents();
		    var ast = l.ast();
		    var __ret = getDefinitionSystemType(contents, ast);
		    var ptype = __ret.ptype;
		    var localUniverse = __ret.localUniverse;
		    var apiType = localUniverse.type(ptype);
		    if (!apiType)
		        apiType = localUniverse.type("Api");
		    var api = new hlImpl.ASTNodeImpl(ast, null, apiType, null);
		    api.setUniverse(localUniverse);
		    //forcing discrimination
		    api.children();
		    return api;
		}
		exports.fromUnit = fromUnit;


	/***/ },
	/* 3 */
	/***/ function(module, exports, __webpack_require__) {

		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var _ = __webpack_require__(4);
		var hlimpl = __webpack_require__(5);
		var selector = __webpack_require__(126);
		var universes = __webpack_require__(54);
		var typeSystem = __webpack_require__(63);
		var ramlServices = __webpack_require__(49);
		var example = __webpack_require__(128);
		function registerAdapters(a) {
		    if (a instanceof typeSystem.AbstractType) {
		        a.addAdapter(new ramlServices.RAMLService(a));
		    }
		    if (a instanceof typeSystem.Property) {
		        a.addAdapter(new ramlServices.RAMLPropertyService(a));
		    }
		}
		var injector = {
		    inject: function (a) {
		        registerAdapters(a);
		    }
		};
		typeSystem.registerInjector(injector);
		var Annotation = (function () {
		    function Annotation(_name) {
		        this._name = _name;
		    }
		    Annotation.prototype.name = function () {
		        return this._name;
		    };
		    return Annotation;
		})();
		exports.Annotation = Annotation;
		var ValueRequirement = (function () {
		    function ValueRequirement(name, value) {
		        this.name = name;
		        this.value = value;
		    }
		    return ValueRequirement;
		})();
		exports.ValueRequirement = ValueRequirement;
		var AbstractType = (function (_super) {
		    __extends(AbstractType, _super);
		    function AbstractType() {
		        _super.apply(this, arguments);
		    }
		    return AbstractType;
		})(typeSystem.AbstractType);
		exports.AbstractType = AbstractType;
		var ValueType = (function (_super) {
		    __extends(ValueType, _super);
		    function ValueType() {
		        _super.apply(this, arguments);
		    }
		    return ValueType;
		})(typeSystem.ValueType);
		exports.ValueType = ValueType;
		var EnumType = (function (_super) {
		    __extends(EnumType, _super);
		    function EnumType() {
		        _super.apply(this, arguments);
		        this.values = [];
		    }
		    return EnumType;
		})(ValueType);
		exports.EnumType = EnumType;
		var ReferenceType = (function (_super) {
		    __extends(ReferenceType, _super);
		    function ReferenceType(name, path, referenceTo, _universe) {
		        _super.call(this, name, _universe, path);
		        this.referenceTo = referenceTo;
		    }
		    ReferenceType.prototype.getReferencedType = function () {
		        return this.universe().type(this.referenceTo);
		    };
		    ReferenceType.prototype.hasStructure = function () {
		        var rt = this.getReferencedType();
		        if (rt) {
		            if (rt.key() == universes.Universe10.AnnotationTypeDeclaration) {
		                return true;
		            }
		            return rt.getAdapter(ramlServices.RAMLService).isInlinedTemplates() || (rt.getAdapter(ramlServices.RAMLService).findMembersDeterminer() != null) || rt.key() == universes.Universe08.AbstractSecurityScheme || rt.key() === universes.Universe10.AbstractSecurityScheme; //FIXME
		        }
		        else {
		            return false;
		        }
		    };
		    return ReferenceType;
		})(ValueType);
		exports.ReferenceType = ReferenceType;
		var NodeClass = (function (_super) {
		    __extends(NodeClass, _super);
		    function NodeClass(_name, universe, path, _description) {
		        if (_description === void 0) { _description = ""; }
		        _super.call(this, _name, universe, path);
		    }
		    NodeClass.prototype.isUserDefined = function () {
		        return false;
		    };
		    NodeClass.prototype.getRepresentationOf = function () {
		        return this.getAdapter(ramlServices.RAMLService).getRepresentationOf();
		    };
		    NodeClass.prototype.allProperties = function (v) {
		        if (v === void 0) { v = {}; }
		        return _super.prototype.allProperties.call(this, v);
		    };
		    return NodeClass;
		})(typeSystem.StructuredType);
		exports.NodeClass = NodeClass;
		var UserDefinedClass = (function (_super) {
		    __extends(UserDefinedClass, _super);
		    function UserDefinedClass(name, universe, hl, path, description) {
		        _super.call(this, name, universe, path, description);
		        this.getAdapter(ramlServices.RAMLService).setDeclaringNode(hl);
		    }
		    UserDefinedClass.prototype.key = function () {
		        return null;
		    };
		    UserDefinedClass.prototype.isUserDefined = function () {
		        return true;
		    };
		    UserDefinedClass.prototype.contributeFacets = function (x) {
		        this.findFacets(this.getAdapter(ramlServices.RAMLService).getDeclaringNode(), x);
		    };
		    UserDefinedClass.prototype.findFacets = function (node, x) {
		        if (node) {
		            var chd = node.lowLevel().children();
		            var mi = _.find(chd, function (x) { return x.key() == "minProperties"; });
		            if (mi) {
		                x[mi.key()] = mi;
		            }
		            var mi = _.find(chd, function (x) { return x.key() == "maxProperties"; });
		            if (mi) {
		                x[mi.key()] = mi;
		            }
		        }
		    };
		    UserDefinedClass.prototype.typeId = function () {
		        var rs = this.nameId();
		        var node = this.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		        if (node) {
		            rs = rs + node.lowLevel().start();
		            var unit = node.lowLevel().unit();
		            if (unit) {
		                rs = rs + unit.absolutePath();
		            }
		        }
		        return rs;
		    };
		    UserDefinedClass.prototype.hasValueTypeInHierarchy = function () {
		        if (this._value) {
		            return true;
		        }
		        if (this.isAssignableFrom("ObjectTypeDeclaration")) {
		            return false;
		        }
		        return false;
		    };
		    /**
		     * Returns example for this type.
		     * Returned example should be tested for being empty and being expandable.
		     */
		    UserDefinedClass.prototype.examples = function () {
		        return example.createExamples(this);
		    };
		    /**
		     * Returns whether this type contain genuine user defined type in its hierarchy.
		     * Genuine user defined type is a type user intentionally defined and filled with
		     * properties or facets, or having user-defined name as opposed to a synthetic user-defined type.
		     */
		    UserDefinedClass.prototype.isGenuineUserDefinedType = function () {
		        return this.genuineUserDefinedType() != null;
		    };
		    /**
		     * Returns nearest genuine user-define type in the hierarchy.
		     * Genuine user defined type is a type user intentionally defined and filled with
		     * properties or facets, or having user-defined name as opposed to a synthetic user-defined type.
		     */
		    UserDefinedClass.prototype.genuineUserDefinedType = function () {
		        var declaringNode = this.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		        if (!declaringNode) {
		            return null;
		        }
		        var foundMeaningfulChild = false;
		        declaringNode.children().forEach(function (child) {
		            if (!((child.isAttr() && child.asAttr().name() == universes.Universe10.TypeDeclaration.properties.name.name) || (child.isAttr() && child.asAttr().name() == universes.Universe10.TypeDeclaration.properties.type.name))) {
		                foundMeaningfulChild = true;
		            }
		        });
		        if (foundMeaningfulChild)
		            return this;
		        //if the type is defined at top-level, we also need to return it as at least it has a meaningful user-defined name
		        if (declaringNode.property().nameId() == universes.Universe10.LibraryBase.properties.types.name) {
		            return this;
		        }
		        var superTypes = this.superTypes();
		        //there should be nothing in super types but a single user defined class
		        if (superTypes == null || superTypes.length != 1) {
		            return null;
		        }
		        return superTypes[0].genuineUserDefinedType();
		    };
		    return UserDefinedClass;
		})(NodeClass);
		exports.UserDefinedClass = UserDefinedClass;
		var AnnotationType = (function (_super) {
		    __extends(AnnotationType, _super);
		    function AnnotationType() {
		        _super.apply(this, arguments);
		    }
		    AnnotationType.prototype.allProperties = function (ps) {
		        if (ps === void 0) { ps = {}; }
		        var rs = this.superTypes()[0].allProperties();
		        if (rs.length == 0) {
		            var up = new UserDefinedProp("value");
		            up.withDomain(this);
		            up._node = this.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		            up.withCanBeValue();
		            up.withRequired(false);
		            var tp = this.superTypes()[0];
		            rs = [];
		            up.withRange(tp.getAdapter(ramlServices.RAMLService).getRepresentationOf().getAdapter(ramlServices.RAMLService).toRuntime());
		            rs.push(up);
		        }
		        return rs;
		    };
		    AnnotationType.prototype.getKey = function (n) {
		        var up = new UserDefinedProp("name");
		        //up.withDomain(this);
		        up.withRange(this.universe().type(universes.Universe10.StringType.name));
		        up.withFromParentKey(true);
		        var node = this.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		        //node:ll.ILowLevelASTNode, parent:hl.IHighLevelNode, private _def:hl.IValueTypeDefinition, private _prop:hl.IProperty, private fromKey:boolean = false
		        return new hlimpl.ASTPropImpl(n, node, up.range(), up, true);
		        //rs.push(up);
		    };
		    AnnotationType.prototype.isAnnotationType = function () {
		        return true;
		    };
		    return AnnotationType;
		})(UserDefinedClass);
		exports.AnnotationType = AnnotationType;
		var Universe = (function (_super) {
		    __extends(Universe, _super);
		    function Universe(name, _parent, v) {
		        if (name === void 0) { name = ""; }
		        if (_parent === void 0) { _parent = null; }
		        if (v === void 0) { v = "RAML08"; }
		        _super.call(this, name);
		        this._parent = _parent;
		        this._classes = [];
		        this._uversion = "RAML08";
		        this.aMap = {};
		        this._uversion = v;
		    }
		    Universe.prototype.matched = function () {
		        if (this.matchedObjects) {
		            return this.matchedObjects;
		        }
		        if (this._parent) {
		            return this._parent.matched();
		        }
		        if (this._uversion == "RAML08") {
		            this.matchedObjects = universes.Universe08;
		            return this.matchedObjects;
		        }
		        else {
		            this.matchedObjects = universes.Universe10;
		            return this.matchedObjects;
		        }
		    };
		    Universe.prototype.setTopLevel = function (t) {
		        this._topLevel = t;
		    };
		    Universe.prototype.getTopLevel = function () {
		        return this._topLevel;
		    };
		    Universe.prototype.setTypedVersion = function (tv) {
		        this._typedVersion = tv;
		    };
		    Universe.prototype.getTypedVersion = function () {
		        return this._typedVersion;
		    };
		    Universe.prototype.version = function () {
		        return this._uversion;
		    };
		    Universe.prototype.setUniverseVersion = function (version) {
		        this._uversion = version;
		    };
		    Universe.prototype.types = function () {
		        var result = [].concat(this._classes);
		        if (this._parent != null) {
		            result = result.concat(this._parent.types());
		        }
		        return result;
		    };
		    Universe.prototype.type = function (name) {
		        if (this.aMap[name]) {
		            return this.aMap[name];
		        }
		        var tp = _.find(this._classes, function (x) { return x.nameId() == name; });
		        if (tp == null) {
		            if (this._parent) {
		                var tp = this._parent.type(name);
		                if (tp instanceof AbstractType) {
		                    var at = tp;
		                    at._universe = this; //FIXME
		                }
		            }
		        }
		        return tp;
		    };
		    Universe.prototype.register = function (t) {
		        this._classes.push(t);
		        if (t instanceof NodeClass) {
		            this._classes.forEach(function (x) {
		                if (x instanceof NodeClass) {
		                    var nc = x;
		                    if (nc.getAdapter(ramlServices.RAMLService).getExtendedType() == t) {
		                        t.getAdapter(ramlServices.RAMLService).getRuntimeExtenders().push(x);
		                    }
		                }
		            });
		        }
		        return this;
		    };
		    Universe.prototype.registerAlias = function (a, t) {
		        this.aMap[a] = t;
		    };
		    Universe.prototype.unregister = function (t) {
		        this._classes = this._classes.filter(function (x) { return x != t; });
		        var st = t.superTypes();
		        st.forEach(function (x) {
		            var a = x;
		            a._superTypes = a._superTypes.filter(function (x) { return x != t; });
		        });
		        st = t.subTypes();
		        st.forEach(function (x) {
		            var a = x;
		            a._subTypes = a._subTypes.filter(function (x) { return x != t; });
		        });
		        return this;
		    };
		    Universe.prototype.registerSuperClass = function (t0, t1) {
		        var a0 = t0;
		        var a1 = t1;
		        a0._superTypes.push(t1);
		        a1._subTypes.push(t0);
		    };
		    return Universe;
		})(typeSystem.Described);
		exports.Universe = Universe;
		function prop(name, desc, domain, range) {
		    var prop = new Property(name, desc);
		    return prop.withDomain(domain).withRange(range);
		}
		exports.prop = prop;
		var ChildValueConstraint = (function () {
		    function ChildValueConstraint(name, value) {
		        this.name = name;
		        this.value = value;
		    }
		    return ChildValueConstraint;
		})();
		exports.ChildValueConstraint = ChildValueConstraint;
		var Property = (function (_super) {
		    __extends(Property, _super);
		    function Property() {
		        _super.apply(this, arguments);
		        this._isFromParentValue = false;
		        this._isFromParentKey = false;
		        this._key = false;
		        this._describes = null;
		        this._selfNode = false;
		        this._noDirectParse = false;
		        this._contextReq = [];
		        this.determinesChildValues = [];
		    }
		    Property.prototype.withNoDirectParse = function () {
		        this._noDirectParse = true;
		    };
		    Property.prototype.isNoDirectParse = function () {
		        return this._noDirectParse;
		    };
		    Property.prototype.withSelfNode = function () {
		        this._selfNode = true;
		    };
		    Property.prototype.isSelfNode = function () {
		        return this._selfNode;
		    };
		    Property.prototype.matchKey = function (k) {
		        if (this._groupName != null) {
		            if (this.isAnnotation()) {
		                if (k.charAt(0) == '(' && k.charAt(k.length - 1) == ')') {
		                    return true;
		                }
		                return false;
		            }
		            return this._groupName == k;
		        }
		        else {
		            return _super.prototype.matchKey.call(this, k);
		        }
		    };
		    Property.prototype.getSelector = function (h) {
		        var sl = this._selector;
		        if (sl instanceof selector.Selector) {
		            return sl;
		        }
		        if (!h) {
		            return null;
		        }
		        if (this._selector) {
		            return selector.parse(h, this._selector);
		        }
		        return null;
		    };
		    Property.prototype.setSelector = function (s) {
		        this._selector = s;
		        return this;
		    };
		    Property.prototype.valueDocProvider = function () {
		        return this._vprovider;
		    };
		    Property.prototype.setValueDocProvider = function (v) {
		        this._vprovider = v;
		        return this;
		    };
		    Property.prototype.suggester = function () {
		        return this._suggester;
		    };
		    Property.prototype.setValueSuggester = function (s) {
		        this._suggester = s;
		    };
		    Property.prototype.enumOptions = function () {
		        if (this._enumOptions && typeof this._enumOptions == 'string') {
		            return [this._enumOptions + ""];
		        }
		        return this._enumOptions;
		    };
		    Property.prototype.getOftenKeys = function () {
		        return this._oftenKeys;
		    };
		    Property.prototype.withOftenKeys = function (keys) {
		        this._oftenKeys = keys;
		        return this;
		    };
		    Property.prototype.withCanBeValue = function () {
		        this._canBeValue = true;
		        return this;
		    };
		    Property.prototype.withInherited = function (w) {
		        this._isInherited = w;
		    };
		    Property.prototype.isInherited = function () {
		        return this._isInherited;
		    };
		    Property.prototype.isAllowNull = function () {
		        return this._allowsNull;
		    };
		    Property.prototype.withAllowNull = function () {
		        this._allowsNull = true;
		    };
		    Property.prototype.getCanBeDuplicator = function () {
		        return this._canBeDuplicator;
		    };
		    Property.prototype.canBeValue = function () {
		        return this._canBeValue;
		    };
		    Property.prototype.setCanBeDuplicator = function () {
		        this._canBeDuplicator = true;
		        return true;
		    };
		    Property.prototype.inheritedContextValue = function () {
		        return this._inheritsValueFromContext;
		    };
		    Property.prototype.withInheritedContextValue = function (v) {
		        this._inheritsValueFromContext = v;
		        return this;
		    };
		    Property.prototype.withContextRequirement = function (name, value) {
		        this._contextReq.push({ name: name, value: value });
		    };
		    Property.prototype.getContextRequirements = function () {
		        return this._contextReq;
		    };
		    Property.prototype.withDescribes = function (a) {
		        this._describes = a;
		        return this;
		    };
		    Property.prototype.describesAnnotation = function () {
		        return this._describes != null;
		    };
		    Property.prototype.describedAnnotation = function () {
		        return this._describes;
		    };
		    Property.prototype.isReference = function () {
		        return this.range() instanceof ReferenceType;
		    };
		    Property.prototype.referencesTo = function () {
		        return this.range().getReferencedType();
		    };
		    Property.prototype.newInstanceName = function () {
		        if (this._newInstanceName) {
		            return this._newInstanceName;
		        }
		        return this.range().nameId();
		    };
		    Property.prototype.withThisPropertyDeclaresFields = function (b) {
		        if (b === void 0) { b = true; }
		        this._declaresFields = b;
		        return this;
		    };
		    Property.prototype.isThisPropertyDeclaresTypeFields = function () {
		        return this._declaresFields;
		    };
		    Property.prototype.withNewInstanceName = function (name) {
		        this._newInstanceName = name;
		        return this;
		    };
		    Property.prototype.addChildValueConstraint = function (c) {
		        this.determinesChildValues.push(c);
		    };
		    Property.prototype.getChildValueConstraints = function () {
		        return this.determinesChildValues;
		    };
		    Property.prototype.childRestrictions = function () {
		        return this.determinesChildValues;
		    };
		    Property.prototype.id = function () {
		        if (this._id) {
		            return this._id;
		        }
		        if (!this._groupName) {
		            return null;
		        }
		        if (this.domain().getAdapter(ramlServices.RAMLService).getDeclaringNode()) {
		            return null;
		        }
		        this._id = this._groupName + this.domain().nameId();
		        return this._id;
		    };
		    Property.prototype.isAnnotation = function () {
		        return this._groupName == universes.Universe10.Api.properties.annotations.name && this.domain() && !this.domain().isUserDefined();
		    };
		    Property.prototype.withFromParentValue = function (v) {
		        if (v === void 0) { v = true; }
		        this._isFromParentValue = v;
		        return this;
		    };
		    Property.prototype.withFromParentKey = function (v) {
		        if (v === void 0) { v = true; }
		        this._isFromParentKey = v;
		        return this;
		    };
		    Property.prototype.isFromParentKey = function () {
		        return this._isFromParentKey;
		    };
		    Property.prototype.isFromParentValue = function () {
		        return this._isFromParentValue;
		    };
		    Property.prototype.withGroupName = function (gname) {
		        this._groupName = gname;
		        return this;
		    };
		    Property.prototype.unmerge = function () {
		        this._groupName = this.nameId();
		        return this;
		    };
		    Property.prototype.merge = function () {
		        this._groupName = null;
		        return this;
		    };
		    Property.prototype.withKey = function (isKey) {
		        this._key = isKey;
		        return this;
		    };
		    /**
		     * TODO THIS STUFF SHOULD BE MORE ABSTRACT (LATER...)
		     * @param keyShouldStartFrom
		     * @returns {Property}
		     */
		    Property.prototype.isKey = function () {
		        return this._key;
		    };
		    Property.prototype.isMerged = function () {
		        return this._groupName == null;
		    };
		    Property.prototype.isPrimitive = function () {
		        if (!this.range()) {
		            return true;
		        }
		        var key = this.range().key();
		        if (key == universes.Universe08.StringType || key == universes.Universe10.StringType) {
		            return true;
		        }
		        if (key == universes.Universe08.NumberType || key == universes.Universe10.NumberType) {
		            return true;
		        }
		        if (key == universes.Universe08.BooleanType || key == universes.Universe10.BooleanType) {
		            return true;
		        }
		        return false;
		    };
		    Property.prototype.groupName = function () {
		        return this._groupName;
		    };
		    Property.prototype.key = function () {
		        //TODO implement that
		        return null;
		    };
		    return Property;
		})(typeSystem.Property);
		exports.Property = Property;
		var Array = (function (_super) {
		    __extends(Array, _super);
		    function Array() {
		        _super.apply(this, arguments);
		    }
		    Array.prototype.findFacets = function (node, x) {
		        if (node) {
		            var chd = node.lowLevel().children();
		            var mi = _.find(chd, function (x) { return x.key() == "minItems"; });
		            if (mi) {
		                x[mi.key()] = mi;
		            }
		            var mi = _.find(chd, function (x) { return x.key() == "maxItems"; });
		            if (mi) {
		                x[mi.key()] = mi;
		            }
		            var mi = _.find(chd, function (x) { return x.key() == "uniqueItems"; });
		            if (mi) {
		                x[mi.key()] = mi;
		            }
		        }
		    };
		    return Array;
		})(typeSystem.Array);
		exports.Array = Array;
		var ExternalType = (function (_super) {
		    __extends(ExternalType, _super);
		    function ExternalType() {
		        _super.apply(this, arguments);
		    }
		    return ExternalType;
		})(typeSystem.ExternalType);
		exports.ExternalType = ExternalType;
		var Union = (function (_super) {
		    __extends(Union, _super);
		    function Union() {
		        _super.apply(this, arguments);
		    }
		    return Union;
		})(typeSystem.Union);
		exports.Union = Union;
		var UserDefinedProp = (function (_super) {
		    __extends(UserDefinedProp, _super);
		    function UserDefinedProp() {
		        _super.apply(this, arguments);
		    }
		    UserDefinedProp.prototype.withDisplayName = function (name) {
		        this._displayName = name;
		    };
		    UserDefinedProp.prototype.getDisplayName = function () {
		        return this._displayName;
		    };
		    UserDefinedProp.prototype.node = function () {
		        return this._node;
		    };
		    return UserDefinedProp;
		})(Property);
		exports.UserDefinedProp = UserDefinedProp;


	/***/ },
	/* 4 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(1);

	/***/ },
	/* 5 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var hl = __webpack_require__(2);
		var _ = __webpack_require__(4);
		var proxy = __webpack_require__(6);
		var builder = __webpack_require__(122);
		var mutators = __webpack_require__(123);
		var linter = __webpack_require__(55);
		var typeBuilder = __webpack_require__(50);
		var search = __webpack_require__(53);
		var universes = __webpack_require__(54);
		var jsyaml = __webpack_require__(15);
		var textutil = __webpack_require__(48);
		var services = __webpack_require__(49);
		var factory10 = __webpack_require__(124);
		var factory08 = __webpack_require__(125);
		function qName(x, context) {
		    var dr = search.declRoot(context);
		    var nm = x.name();
		    var o = nm;
		    var ind = nm.indexOf("<"); //TODO SCOPE IT
		    if (ind != -1) {
		        nm = nm.substring(0, ind);
		    }
		    while (true) {
		        var np = x.parent();
		        if (!np || np == dr) {
		            break;
		        }
		        else {
		            if (np.definition().key() == universes.Universe10.Library && np.parent()) {
		                nm = np.name() + "." + nm;
		            }
		            x = np;
		        }
		    }
		    return nm;
		}
		exports.qName = qName;
		var BasicASTNode = (function () {
		    function BasicASTNode(_node, _parent) {
		        this._node = _node;
		        this._parent = _parent;
		        this._implicit = false;
		        this.values = {};
		        if (_node) {
		            _node.setHighLevelParseResult(this);
		        }
		    }
		    BasicASTNode.prototype.getKind = function () {
		        return 0 /* BASIC */;
		    };
		    BasicASTNode.prototype.asAttr = function () {
		        return null;
		    };
		    BasicASTNode.prototype.asElement = function () {
		        return null;
		    };
		    BasicASTNode.prototype.hashkey = function () {
		        if (!this._hashkey)
		            this._hashkey = this.parent() ? this.parent().hashkey() + "/" + this.name() : this.name();
		        return this._hashkey;
		    };
		    BasicASTNode.prototype.root = function () {
		        if (this.parent()) {
		            return this.parent().root();
		        }
		        return this;
		    };
		    BasicASTNode.prototype.version = function () {
		        return "";
		    };
		    BasicASTNode.prototype.getLowLevelStart = function () {
		        if (this.lowLevel().kind() === jsyaml.Kind.SCALAR) {
		            return this.lowLevel().start();
		        }
		        return this.lowLevel().keyStart();
		    };
		    BasicASTNode.prototype.getLowLevelEnd = function () {
		        if (this.lowLevel().kind() === jsyaml.Kind.SCALAR) {
		            return this.lowLevel().end();
		        }
		        return this.lowLevel().keyEnd();
		    };
		    BasicASTNode.prototype.isSameNode = function (n) {
		        if (n) {
		            if (n.lowLevel().actual() == this.lowLevel().actual()) {
		                return true;
		            }
		        }
		        return false;
		    };
		    BasicASTNode.prototype.checkContextValue = function (name, value, thisObj) {
		        var vl = this.computedValue(name);
		        if (vl && vl.indexOf(value) != -1) {
		            return true; //FIXME
		        }
		        return value == vl || value == 'false';
		    };
		    BasicASTNode.prototype.printDetails = function (indent) {
		        return (indent ? indent : "") + "Unkown\n";
		    };
		    /**
		     * Used for test comparison of two trees. Touching this will require AST tests update.
		     * @param indent
		     * @returns {string}
		     */
		    BasicASTNode.prototype.testSerialize = function (indent) {
		        return (indent ? indent : "") + "Unkown\n";
		    };
		    BasicASTNode.prototype.errors = function () {
		        var errors = [];
		        var q = {
		            accept: function (c) {
		                errors.push(c);
		            },
		            begin: function () {
		            },
		            end: function () {
		            }
		        };
		        this.validate(q);
		        return errors;
		    };
		    BasicASTNode.prototype.markCh = function () {
		        var n = this.lowLevel();
		        n = n._node ? n._node : n;
		        if (n['markCh']) {
		            return true;
		        }
		        n['markCh'] = 1;
		    };
		    BasicASTNode.prototype.unmarkCh = function () {
		        var n = this.lowLevel();
		        n = n._node ? n._node : n;
		        delete n['markCh'];
		    };
		    BasicASTNode.prototype.validate = function (v) {
		        linter.validate(this, v);
		    };
		    BasicASTNode.prototype.allowRecursive = function () {
		        return false;
		    };
		    BasicASTNode.prototype.setComputed = function (name, v) {
		        this.values[name] = v;
		    };
		    BasicASTNode.prototype.computedValue = function (name) {
		        var vl = this.values[name];
		        if (!vl && this.parent()) {
		            return this.parent().computedValue(name);
		        }
		        return vl;
		    };
		    BasicASTNode.prototype.lowLevel = function () {
		        return this._node;
		    };
		    BasicASTNode.prototype.name = function () {
		        var c = this.lowLevel().key();
		        if (!c) {
		            return "";
		        }
		        return c;
		    };
		    BasicASTNode.prototype.optional = function () {
		        return this.lowLevel().optional();
		    };
		    BasicASTNode.prototype.parent = function () {
		        return this._parent;
		    };
		    BasicASTNode.prototype.setParent = function (parent) {
		        this._parent = parent;
		    };
		    BasicASTNode.prototype.isElement = function () {
		        return false;
		    };
		    BasicASTNode.prototype.directChildren = function () {
		        return this.children();
		    };
		    BasicASTNode.prototype.children = function () {
		        return [];
		    };
		    BasicASTNode.prototype.isAttached = function () {
		        return this.parent() != null;
		    };
		    BasicASTNode.prototype.isImplicit = function () {
		        return this._implicit;
		    };
		    BasicASTNode.prototype.isAttr = function () {
		        return false;
		    };
		    BasicASTNode.prototype.isUnknown = function () {
		        return true;
		    };
		    BasicASTNode.prototype.id = function () {
		        var _this = this;
		        if (this._parent) {
		            var parentId = this.parent().id();
		            parentId += "." + this.name();
		            var sameName = this.parent().directChildren().filter(function (x) { return x.name() == _this.name(); });
		            if (sameName.length > 1) {
		                var ind = sameName.indexOf(this);
		                parentId += "[" + ind + "]";
		            }
		            return parentId;
		        }
		        return "";
		    };
		    BasicASTNode.prototype.localId = function () {
		        return this.name();
		    };
		    BasicASTNode.prototype.fullLocalId = function () {
		        var _this = this;
		        if (this._parent) {
		            var result = "." + this.name();
		            var sameName = this.parent().directChildren().filter(function (x) { return x.name() == _this.name(); });
		            if (sameName.length > 1) {
		                var ind = sameName.indexOf(this);
		                result += "[" + ind + "]";
		            }
		            return result;
		        }
		        return this.localId();
		    };
		    BasicASTNode.prototype.property = function () {
		        return null;
		    };
		    return BasicASTNode;
		})();
		exports.BasicASTNode = BasicASTNode;
		var StructuredValue = (function () {
		    function StructuredValue(node, _parent, _pr, kv) {
		        if (kv === void 0) { kv = null; }
		        this.node = node;
		        this._parent = _parent;
		        this.kv = kv;
		        this._pr = _pr;
		    }
		    StructuredValue.prototype.valueName = function () {
		        var res = null;
		        if (this.kv) {
		            res = this.kv;
		        }
		        res = this.node.key();
		        if (this._pr && this._pr.isAnnotation()) {
		            if (res && res.charAt(0) == '(') {
		                res = res.substring(1, res.length - 1);
		            }
		        }
		        return res;
		    };
		    StructuredValue.prototype.children = function () {
		        return this.node.children().map(function (x) { return new StructuredValue(x, null, null); });
		    };
		    StructuredValue.prototype.lowLevel = function () {
		        return this.node;
		    };
		    StructuredValue.prototype.toHighLevel = function (parent) {
		        if (!parent && this._parent)
		            parent = this._parent;
		        var vn = this.valueName();
		        var cands = this._pr.getAdapter(services.RAMLPropertyService).referenceTargets(parent).filter(function (x) { return qName(x, parent) == vn; });
		        if (cands && cands[0]) {
		            var tp = typeBuilder.typeFromNode(cands[0]);
		            var node = new ASTNodeImpl(this.node, parent, tp, this._pr);
		            if (this._pr) {
		                this._pr.childRestrictions().forEach(function (y) {
		                    node.setComputed(y.name, y.value);
		                });
		            }
		            return node;
		        }
		        return null;
		    };
		    return StructuredValue;
		})();
		exports.StructuredValue = StructuredValue;
		var ASTPropImpl = (function (_super) {
		    __extends(ASTPropImpl, _super);
		    function ASTPropImpl(node, parent, _def, _prop, fromKey) {
		        if (fromKey === void 0) { fromKey = false; }
		        _super.call(this, node, parent);
		        this._def = _def;
		        this._prop = _prop;
		        this.fromKey = fromKey;
		    }
		    ASTPropImpl.prototype.definition = function () {
		        return this._def;
		    };
		    ASTPropImpl.prototype.asAttr = function () {
		        return this;
		    };
		    ASTPropImpl.prototype.isString = function () {
		        if (this._def) {
		            if (this._def.key() === universes.Universe08.StringType || this._def.key() == universes.Universe10.StringType) {
		                return true;
		            }
		        }
		        return false;
		    };
		    ASTPropImpl.prototype.getKind = function () {
		        return 2 /* ATTRIBUTE */;
		    };
		    ASTPropImpl.prototype.owningWrapper = function () {
		        return {
		            node: this.parent().wrapperNode(),
		            property: this.name()
		        };
		    };
		    ASTPropImpl.prototype.patchType = function (t) {
		        this._def = t;
		    };
		    ASTPropImpl.prototype.findReferenceDeclaration = function () {
		        var _this = this;
		        var targets = this.property().getAdapter(services.RAMLPropertyService).referenceTargets(this.parent());
		        var vl = this.value();
		        if (vl instanceof StructuredValue) {
		            var st = vl;
		            var nm = st.valueName();
		        }
		        else {
		            var nm = "" + vl;
		        }
		        var t = _.find(targets, function (x) { return qName(x, _this.parent()) == nm; });
		        return t;
		    };
		    ASTPropImpl.prototype.findReferencedValue = function () {
		        var c = this.findReferenceDeclaration();
		        if (c) {
		            var vl = c.attr("value");
		            var ck = c.definition().key();
		            if (ck === universes.Universe08.GlobalSchema || ck === universes.Universe10.GlobalSchema) {
		                if (vl) {
		                    var actualValue = vl.value();
		                    if (actualValue) {
		                        var rf = this._def.getAdapter(services.RAMLService).isValid(this.parent(), actualValue, vl.property());
		                        return rf;
		                    }
		                }
		                return null;
		            }
		        }
		        return c;
		    };
		    ASTPropImpl.prototype.isElement = function () {
		        return false;
		    };
		    ASTPropImpl.prototype.property = function () {
		        return this._prop;
		    };
		    ASTPropImpl.prototype.convertMultivalueToString = function (value) {
		        //|\n  xxx\n  yyy\n  zzz
		        var gap = 0;
		        var pos = 2;
		        while (value[pos] == ' ') {
		            gap++;
		            pos++;
		        }
		        //console.log('gap: ' + gap);
		        var lines = textutil.splitOnLines(value);
		        lines = lines.map(function (line) {
		            //console.log('line: ' + line);
		            return line.substring(gap, line.length);
		        });
		        return lines.join('');
		    };
		    ASTPropImpl.prototype.value = function () {
		        if (this._value) {
		            return this._value;
		        }
		        if (this._computed) {
		            return this.computedValue(this.property().nameId());
		        }
		        if (this.fromKey) {
		            return this._node.key();
		        }
		        if (this.property().isAnnotation() && this._node.key() && this._node.key() != 'annotations') {
		            return new StructuredValue(this._node, this.parent(), this._prop);
		        }
		        var actualValue = this._node.value(); //TODO FIXME
		        if (this.property().isSelfNode()) {
		            if (!actualValue || actualValue instanceof jsyaml.ASTNode) {
		                actualValue = this._node;
		                if (actualValue.children().length == 0) {
		                    actualValue = null;
		                }
		            }
		        }
		        if (actualValue instanceof jsyaml.ASTNode || actualValue instanceof proxy.LowLevelProxyNode) {
		            return new StructuredValue(actualValue, this.parent(), this._prop);
		        }
		        if (textutil.isMultiLineValue(actualValue)) {
		            var res = this.convertMultivalueToString(actualValue);
		            //console.log('converted: [' + textutil.replaceNewlines(res) + ']');
		            return res;
		        }
		        return actualValue;
		    };
		    ASTPropImpl.prototype.name = function () {
		        return this._prop.nameId();
		    };
		    ASTPropImpl.prototype.printDetails = function (indent) {
		        var className = this.definition().nameId();
		        var definitionClassName = this.property().range().nameId();
		        var result = (indent ? indent : "") + (this.name() + " : " + className + "[" + definitionClassName + "]" + "  =  " + this.value()) + "\n";
		        if (this.value() instanceof StructuredValue) {
		            var structuredHighLevel = this.value().toHighLevel();
		            if (structuredHighLevel && structuredHighLevel.printDetails) {
		                result += structuredHighLevel.printDetails(indent + "\t");
		            }
		        }
		        return result;
		    };
		    /**
		     * Used for test comparison of two trees. Touching this will require AST tests update.
		     * @param indent
		     * @returns {string}
		     */
		    ASTPropImpl.prototype.testSerialize = function (indent) {
		        var className = this.definition().nameId();
		        var result = (indent ? indent : "") + (this.name() + " : " + className + "  =  " + this.value()) + "\n";
		        if (this.value() instanceof StructuredValue) {
		            var structuredHighLevel = this.value().toHighLevel();
		            if (structuredHighLevel && structuredHighLevel.testSerialize) {
		                result += structuredHighLevel.testSerialize((indent ? indent : "") + "  ");
		            }
		            else {
		                var lowLevel = this.value().lowLevel();
		                var dumpObject = lowLevel.dumpToObject();
		                var dump = JSON.stringify(dumpObject);
		                var indentedDump = "";
		                var dumpLines = dump.split("\n");
		                dumpLines.forEach(function (dumpLine) { return indentedDump += ((indent ? indent : "") + "  " + dumpLine + "\n"); });
		                result += indentedDump + "\n";
		            }
		        }
		        return result;
		    };
		    ASTPropImpl.prototype.isAttr = function () {
		        return true;
		    };
		    ASTPropImpl.prototype.isUnknown = function () {
		        return false;
		    };
		    ASTPropImpl.prototype.setValue = function (value) {
		        mutators.setValue(this, value);
		    };
		    ASTPropImpl.prototype.setKey = function (value) {
		        mutators.setKey(this, value);
		    };
		    ASTPropImpl.prototype.children = function () {
		        return [];
		    };
		    ASTPropImpl.prototype.addStringValue = function (value) {
		        mutators.addStringValue(this, value);
		    };
		    ASTPropImpl.prototype.addStructuredValue = function (sv) {
		        mutators.addStructuredValue(this, sv);
		    };
		    ASTPropImpl.prototype.addValue = function (value) {
		        if (!this.property().isMultiValue())
		            throw new Error("setValue(string) only apply to multi-values properties");
		        if (typeof value == 'string') {
		            this.addStringValue(value);
		        }
		        else {
		            this.addStructuredValue(value);
		        }
		    };
		    ASTPropImpl.prototype.isEmbedded = function () {
		        var keyname = this.lowLevel().asMapping().key.value;
		        //console.log('propery: ' + this.property().name());
		        //console.log('mapping: ' + keyname);
		        return this.property().canBeValue() && keyname != this.property().nameId();
		    };
		    ASTPropImpl.prototype.remove = function () {
		        mutators.removeAttr(this);
		    };
		    ASTPropImpl.prototype.setValues = function (values) {
		        mutators.setValues(this, values);
		    };
		    ASTPropImpl.prototype.isEmpty = function () {
		        if (!this.property().isMultiValue())
		            throw new Error("isEmpty() only apply to multi-values attributes");
		        //console.log('remove: ' + this.name());
		        var node = this.parent();
		        var llnode = node.lowLevel();
		        //node.lowLevel().show('Parent:');
		        var attrs = node.attributes(this.name());
		        //console.log('attributes: ' + attrs.length);
		        if (attrs.length == 0) {
		            return true;
		        }
		        else if (attrs.length == 1) {
		            var anode = attrs[0].lowLevel();
		            //console.log('attribute : ' + anode.kindName());
		            //anode.show("ATTR:");
		            if (anode.isMapping()) {
		                // that's crazy but it means zero length array indeed )
		                return true;
		            }
		            else {
		                return false;
		            }
		        }
		        else {
		            return false;
		        }
		    };
		    return ASTPropImpl;
		})(BasicASTNode);
		exports.ASTPropImpl = ASTPropImpl;
		var nodeBuilder = new builder.BasicNodeBuilder();
		(function (OverlayMergeMode) {
		    OverlayMergeMode[OverlayMergeMode["MERGE"] = 0] = "MERGE";
		    OverlayMergeMode[OverlayMergeMode["AGGREGATE"] = 1] = "AGGREGATE";
		})(exports.OverlayMergeMode || (exports.OverlayMergeMode = {}));
		var OverlayMergeMode = exports.OverlayMergeMode;
		var ASTNodeImpl = (function (_super) {
		    __extends(ASTNodeImpl, _super);
		    function ASTNodeImpl(node, parent, _def, _prop) {
		        _super.call(this, node, parent);
		        this._def = _def;
		        this._prop = _prop;
		        this._expanded = false;
		        this._allowQuestion = false;
		        this._subTypesCache = null;
		        this._auxChecked = false;
		        /**
		         * Depending on the merge mode, overlays and extensions are either merged with the master, or their trees are joined via aggregation
		         * @type {OverlayMergeMode}
		         */
		        this.overlayMergeMode = 0 /* MERGE */;
		        if (node) {
		            node.setHighLevelNode(this);
		        }
		    }
		    ASTNodeImpl.prototype.patchProp = function (pr) {
		        this._prop = pr;
		    };
		    ASTNodeImpl.prototype.getKind = function () {
		        return 1 /* NODE */;
		    };
		    ASTNodeImpl.prototype.wrapperNode = function () {
		        if (!this._wrapperNode) {
		            //forcing discrimination
		            this.children();
		            this._wrapperNode = this.buildWrapperNode();
		        }
		        return this._wrapperNode;
		    };
		    ASTNodeImpl.prototype.asElement = function () {
		        return this;
		    };
		    ASTNodeImpl.prototype.buildWrapperNode = function () {
		        var ramlVersion = this.definition().universe().version();
		        if (ramlVersion == 'RAML10') {
		            return factory10.buildWrapperNode(this);
		        }
		        else if (ramlVersion == 'RAML08') {
		            return factory08.buildWrapperNode(this);
		        }
		        return null;
		    };
		    ASTNodeImpl.prototype.propertiesAllowedToUse = function () {
		        var _this = this;
		        return this.definition().allProperties().filter(function (x) { return _this.isAllowedToUse(x); });
		    };
		    ASTNodeImpl.prototype.isAllowedToUse = function (p) {
		        var _this = this;
		        var ok = true;
		        if (p.getAdapter(services.RAMLPropertyService).isSystem()) {
		            return false;
		        }
		        p.getContextRequirements().forEach(function (y) {
		            if (y.name.indexOf('(') != -1) {
		                //TODO HANDLE IT LATER
		                return true;
		            }
		            var vl = _this.computedValue(y.name);
		            if (vl) {
		                ok = ok && (vl == y.value);
		            }
		            else {
		                if (y.value) {
		                    ok = false;
		                }
		            }
		        });
		        return ok;
		    };
		    ASTNodeImpl.prototype.allowRecursive = function () {
		        if (this.definition().getAdapter(services.RAMLService).isUserDefined()) {
		            return true;
		        }
		        return false;
		    };
		    ASTNodeImpl.prototype.setWrapperNode = function (node) {
		        this._wrapperNode = node;
		    };
		    ASTNodeImpl.prototype.setAssociatedType = function (d) {
		        this._associatedDef = d;
		    };
		    ASTNodeImpl.prototype.associatedType = function () {
		        return this._associatedDef;
		    };
		    ASTNodeImpl.prototype.knownIds = function () {
		        //initializing ids if needed
		        //TODO refactor workaround
		        this.isAuxilary();
		        if (this._knownIds) {
		            return this._knownIds;
		        }
		        else {
		            return {};
		        }
		    };
		    ASTNodeImpl.prototype.findById = function (id) {
		        var _this = this;
		        var v = this._knownIds;
		        if (!v) {
		            this._knownIds = {};
		            var all = search.allChildren(this);
		            all.forEach(function (x) { return _this._knownIds[x.id()] = x; });
		        }
		        return this._knownIds[id];
		    };
		    ASTNodeImpl.prototype.isAuxilary = function () {
		        if (this._isAux) {
		            return true;
		        }
		        if (this._auxChecked) {
		            return false;
		        }
		        this._auxChecked = true;
		        var masterApi = this.getMaster();
		        if (masterApi) {
		            this._isAux = true;
		            this.initilizeKnownIDs(masterApi);
		            return true;
		        }
		        return false;
		    };
		    ASTNodeImpl.prototype.initilizeKnownIDs = function (api) {
		        var _this = this;
		        this._knownIds = {};
		        var allChildren = search.allChildren(api);
		        allChildren.forEach(function (x) { return _this._knownIds[x.id()] = x; });
		        this._knownIds[""] = api;
		    };
		    ASTNodeImpl.prototype.getMaster = function () {
		        if (this.masterApi) {
		            return this.masterApi;
		        }
		        return this.calculateMasterByRef();
		    };
		    /**
		     * Forcefully sets a master unit for this API, which may be different from the one, current unit points to
		     * via masterRef.
		     * @param master
		     */
		    ASTNodeImpl.prototype.overrideMaster = function (master) {
		        this.masterApi = master;
		        this.resetAuxilaryState();
		    };
		    ASTNodeImpl.prototype.setMergeMode = function (mergeMode) {
		        this.overlayMergeMode = mergeMode;
		        this.resetAuxilaryState();
		    };
		    ASTNodeImpl.prototype.getMergeMode = function () {
		        return this.overlayMergeMode;
		    };
		    ASTNodeImpl.prototype.calculateMasterByRef = function () {
		        var masterReference = _.find(this.lowLevel().children(), function (x) { return x.key() == universes.Universe10.Overlay.properties.masterRef.name; });
		        if (!masterReference || !masterReference.value()) {
		            return null;
		        }
		        var masterPath = masterReference.value();
		        var masterUnit = this.lowLevel().unit().project().resolve(this.lowLevel().unit().path(), masterPath);
		        if (!masterUnit) {
		            return null;
		        }
		        var result = hl.fromUnit(masterUnit);
		        result.setMergeMode(this.overlayMergeMode);
		        return result;
		    };
		    ASTNodeImpl.prototype.resetAuxilaryState = function () {
		        this._isAux = false;
		        this._auxChecked = false;
		        this._knownIds = null;
		        this.clearChildrenCache();
		    };
		    ASTNodeImpl.prototype.printDetails = function (indent) {
		        var result = "";
		        if (!indent)
		            indent = "";
		        var classname = this.definition().nameId();
		        var definitionClasName = this.property() ? this.property().range().nameId() : "";
		        var parentPropertyName = this.property() ? this.property().nameId() : "";
		        result += indent + classname + "[" + definitionClasName + "]" + " <--- " + parentPropertyName + "\n";
		        this.children().forEach(function (child) {
		            result += child.printDetails(indent + "\t");
		        });
		        return result;
		    };
		    /**
		     * Used for test comparison of two trees. Touching this will require AST tests update.
		     * @param indent
		     * @returns {string}
		     */
		    ASTNodeImpl.prototype.testSerialize = function (indent) {
		        var result = "";
		        if (!indent)
		            indent = "";
		        var classname = this.definition().nameId();
		        var parentPropertyName = this.property() ? this.property().nameId() : "";
		        result += indent + classname + " <-- " + parentPropertyName + "\n";
		        this.children().forEach(function (child) {
		            if (child.testSerialize) {
		                result += child.testSerialize(indent + "  ");
		            }
		        });
		        return result;
		    };
		    ASTNodeImpl.prototype.getExtractedChildren = function () {
		        var r = this.root();
		        if (r.isAuxilary()) {
		            if (r._knownIds) {
		                var i = r._knownIds[this.id()];
		                if (i) {
		                    return i.children();
		                }
		            }
		            return [];
		        }
		        return [];
		    };
		    ASTNodeImpl.prototype.allowsQuestion = function () {
		        return this._allowQuestion || this.definition().getAdapter(services.RAMLService).getAllowQuestion();
		    };
		    ASTNodeImpl.prototype.findReferences = function () {
		        var rs = [];
		        search.refFinder(this.root(), this, rs);
		        //filtering out equal results
		        var filteredReferences = [];
		        rs.forEach(function (ref) {
		            if (!_.find(filteredReferences, function (existing) { return existing == ref; })) {
		                filteredReferences.push(ref);
		            }
		        });
		        return filteredReferences;
		    };
		    ASTNodeImpl.prototype.setNamePatch = function (s) {
		        this._patchedName = s;
		    };
		    ASTNodeImpl.prototype.isNamePatch = function () {
		        return this._patchedName;
		    };
		    ASTNodeImpl.prototype.name = function () {
		        if (this._patchedName) {
		            return this._patchedName;
		        }
		        var ka = _.find(this.directChildren(), function (x) { return x.property() && x.property().getAdapter(services.RAMLPropertyService).isKey(); });
		        if (ka && ka instanceof ASTPropImpl) {
		            var c = ka.value();
		            if (c) {
		                var io = c.indexOf(':');
		                if (io != -1) {
		                    return c.substring(0, io);
		                }
		            }
		            return c;
		        }
		        return _super.prototype.name.call(this);
		    };
		    ASTNodeImpl.prototype.findElementAtOffset = function (n) {
		        return this._findNode(this, n, n);
		    };
		    ASTNodeImpl.prototype.isElement = function () {
		        return true;
		    };
		    ASTNodeImpl.prototype.universe = function () {
		        if (this._universe) {
		            return this._universe;
		        }
		        return this.definition().universe();
		    };
		    ASTNodeImpl.prototype.setUniverse = function (u) {
		        this._universe = u;
		    };
		    ASTNodeImpl.prototype._findNode = function (n, offset, end) {
		        var _this = this;
		        if (n == null) {
		            return null;
		        }
		        if (n.lowLevel()) {
		            //var node:ASTNode=<ASTNode>n;
		            if (n.lowLevel().start() <= offset && n.lowLevel().end() >= end) {
		                var res = n;
		                //TODO INCLUDES
		                n.elements().forEach(function (x) {
		                    if (x.lowLevel().unit() != n.lowLevel().unit()) {
		                        return;
		                    }
		                    var m = _this._findNode(x, offset, end);
		                    if (m) {
		                        res = m;
		                    }
		                });
		                return res;
		            }
		        }
		        return null;
		    };
		    ASTNodeImpl.prototype.isStub = function () {
		        return (!this.lowLevel().unit()) || this.lowLevel().unit().isStubUnit();
		    };
		    ASTNodeImpl.prototype.add = function (node) {
		        mutators.addToNode(this, node);
		    };
		    ASTNodeImpl.prototype.remove = function (node) {
		        mutators.removeNodeFrom(this, node);
		    };
		    ASTNodeImpl.prototype.dump = function (flavor) {
		        return this._node.dump();
		    };
		    ASTNodeImpl.prototype.patchType = function (d) {
		        this._def = d;
		        var ass = this._associatedDef;
		        this._associatedDef = null;
		        this._children = null;
		    };
		    ASTNodeImpl.prototype.children = function () {
		        if (this._children) {
		            return this.mergeChildren(this._children, this.getExtractedChildren());
		        }
		        if (this._node) {
		            this._children = nodeBuilder.process(this, this._node.children());
		            this._children = this._children.filter(function (x) { return x != null; });
		            //FIXME
		            return this.mergeChildren(this._children, this.getExtractedChildren());
		        }
		        return [];
		    };
		    ASTNodeImpl.prototype.mergeChildren = function (originalChildren, masterChildren) {
		        var _this = this;
		        var root = this.root();
		        if (root.overlayMergeMode == 1 /* AGGREGATE */) {
		            //simply joining the sets
		            return originalChildren.concat(masterChildren);
		        }
		        else if (root.overlayMergeMode == 0 /* MERGE */) {
		            var result = [];
		            originalChildren.forEach(function (originalChild) {
		                var masterCounterpart = _.find(masterChildren, function (masterChild) { return masterChild.fullLocalId() == originalChild.fullLocalId(); });
		                if (!masterCounterpart) {
		                    //we dont have a counterpart, so simply adding to result
		                    result.push(originalChild);
		                }
		                else {
		                    //there is a counterpart, so deciding what to do:
		                    _this.mergeChild(result, originalChild, masterCounterpart);
		                }
		            });
		            masterChildren.forEach(function (masterChild) {
		                var originalCounterpart = _.find(originalChildren, function (originalChild) { return masterChild.fullLocalId() == originalChild.fullLocalId(); });
		                if (!originalCounterpart) {
		                    //we dont have a counterpart, so simply adding to result
		                    result.push(masterChild);
		                }
		            });
		            return result;
		        }
		        return null;
		    };
		    ASTNodeImpl.prototype.mergeChild = function (result, originalChild, masterChild) {
		        if (originalChild.getKind() != masterChild.getKind()) {
		            //should not happen theoretically
		            result.push(originalChild);
		            result.push(masterChild);
		            return;
		        }
		        if (originalChild.getKind() == 1 /* NODE */) {
		            result.push(originalChild);
		            return;
		        }
		        else if (originalChild.getKind() == 2 /* ATTRIBUTE */) {
		            //if ((<ASTPropImpl>originalChild).name() == "displayName" ||
		            //    (<ASTPropImpl>originalChild).name() == "title") {
		            //    console.log("OriginalChildForDisplayName: " + (<ASTPropImpl>originalChild).value())
		            //    console.log("MasterChildForDisplayName: " + (<ASTPropImpl>masterChild).value())
		            //
		            //}
		            result.push(originalChild);
		            return;
		        }
		        else if (originalChild.getKind() == 0 /* BASIC */) {
		            //we do not know what to do with basic nodes, so adding both.
		            result.push(originalChild);
		            result.push(masterChild);
		            return;
		        }
		    };
		    ASTNodeImpl.prototype.directChildren = function () {
		        if (this._children) {
		            return this._children;
		        }
		        if (this._node) {
		            this._children = nodeBuilder.process(this, this._node.children());
		            return this._children;
		        }
		        return [];
		    };
		    ASTNodeImpl.prototype.resetChildren = function () {
		        this._children = null;
		    };
		    ASTNodeImpl.prototype.isEmptyRamlFile = function () {
		        var llroot = this.lowLevel().root();
		        return llroot.isScalar();
		    };
		    ASTNodeImpl.prototype.initRamlFile = function () {
		        mutators.initEmptyRAMLFile(this);
		    };
		    ASTNodeImpl.prototype.createAttr = function (n, v) {
		        mutators.createAttr(this, n, v);
		    };
		    ASTNodeImpl.prototype.isAttr = function () {
		        return false;
		    };
		    ASTNodeImpl.prototype.isUnknown = function () {
		        return false;
		    };
		    ASTNodeImpl.prototype.value = function () {
		        return this._node.value();
		    };
		    ASTNodeImpl.prototype.valuesOf = function (propName) {
		        var pr = this._def.property(propName);
		        if (pr != null) {
		            return this.elements().filter(function (x) { return x.property() == pr; });
		        }
		        return [];
		    };
		    ASTNodeImpl.prototype.attr = function (n) {
		        return _.find(this.attrs(), function (y) { return y.name() == n; });
		    };
		    ASTNodeImpl.prototype.attrOrCreate = function (name) {
		        var a = this.attr(name);
		        if (!a)
		            this.createAttr(name, '');
		        return this.attr(name);
		    };
		    ASTNodeImpl.prototype.attrValue = function (n) {
		        var a = this.attr(n);
		        return a ? a.value() : null;
		    };
		    ASTNodeImpl.prototype.attributes = function (n) {
		        return _.filter(this.attrs(), function (y) { return y.name() == n; });
		    };
		    ASTNodeImpl.prototype.attrs = function () {
		        var rs = this.children().filter(function (x) { return x.isAttr(); });
		        if (this._patchedName) {
		            var kp = _.find(this.definition().allProperties(), function (x) { return x.getAdapter(services.RAMLPropertyService).isKey(); });
		            var mm = new ASTPropImpl(this.lowLevel(), this, kp.range(), kp, true);
		            mm._value = this._patchedName;
		            return [mm].concat(rs);
		        }
		        return rs;
		    };
		    ASTNodeImpl.prototype.elements = function () {
		        return this.children().filter(function (x) { return !x.isAttr() && !x.isUnknown(); });
		    };
		    ASTNodeImpl.prototype.element = function (n) {
		        var r = this.elementsOfKind(n);
		        if (r.length > 0) {
		            return r[0];
		        }
		        return null;
		    };
		    ASTNodeImpl.prototype.elementsOfKind = function (n) {
		        var r = this.elements().filter(function (x) { return x.property().nameId() == n; });
		        return r;
		    };
		    ASTNodeImpl.prototype.definition = function () {
		        return this._def;
		    };
		    ASTNodeImpl.prototype.property = function () {
		        return this._prop;
		    };
		    ASTNodeImpl.prototype.isExpanded = function () {
		        return this._expanded;
		    };
		    ASTNodeImpl.prototype.copy = function () {
		        return new ASTNodeImpl(this.lowLevel().copy(), this.parent(), this.definition(), this.property());
		    };
		    ASTNodeImpl.prototype.clearChildrenCache = function () {
		        this._children = null;
		    };
		    ASTNodeImpl.prototype.optionalProperties = function () {
		        var def = this.definition();
		        if (def == null) {
		            return [];
		        }
		        var result = [];
		        var map = {};
		        var children = this.lowLevel().children();
		        children.forEach(function (x) {
		            if (x.optional()) {
		                map[x.key()] = true;
		            }
		        });
		        var props = def.allProperties();
		        props.forEach(function (x) {
		            var prop = x;
		            if (map[prop.nameId()]) {
		                result.push(prop.nameId());
		            }
		        });
		        return result;
		    };
		    return ASTNodeImpl;
		})(BasicASTNode);
		exports.ASTNodeImpl = ASTNodeImpl;


	/***/ },
	/* 6 */
	/***/ function(module, exports, __webpack_require__) {

		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var yaml = __webpack_require__(7);
		var json = __webpack_require__(8);
		var stringify = __webpack_require__(121);
		var Error = __webpack_require__(9);
		var impl = __webpack_require__(15);
		var universes = __webpack_require__(54);
		var _ = __webpack_require__(4);
		var LowLevelProxyNode = (function () {
		    function LowLevelProxyNode(_parent, _transformer, ramlVersion) {
		        this._parent = _parent;
		        this._transformer = _transformer;
		        this.ramlVersion = ramlVersion;
		    }
		    LowLevelProxyNode.prototype.keyKind = function () {
		        return this._originalNode.keyKind();
		    };
		    LowLevelProxyNode.prototype.actual = function () {
		        if (this._originalNode) {
		            return this._originalNode.actual();
		        }
		        return this;
		    };
		    LowLevelProxyNode.prototype.transformer = function () {
		        return this._transformer;
		    };
		    LowLevelProxyNode.prototype.originalNode = function () {
		        return this._originalNode;
		    };
		    LowLevelProxyNode.prototype.start = function () {
		        return this._originalNode.start();
		    };
		    LowLevelProxyNode.prototype.end = function () {
		        return this._originalNode.end();
		    };
		    LowLevelProxyNode.prototype.value = function () {
		        throw new Error('The method must be overridden');
		    };
		    LowLevelProxyNode.prototype.includeErrors = function () {
		        return this._originalNode.includeErrors();
		    };
		    LowLevelProxyNode.prototype.includePath = function () {
		        return this._originalNode.includePath();
		    };
		    LowLevelProxyNode.prototype.includeReference = function () {
		        return this._originalNode.includeReference();
		    };
		    LowLevelProxyNode.prototype.setKeyOverride = function (_key) {
		        this._keyOverride = _key;
		    };
		    LowLevelProxyNode.prototype.key = function () {
		        if (this._keyOverride) {
		            return this._keyOverride;
		        }
		        return this._originalNode.key();
		    };
		    LowLevelProxyNode.prototype.optional = function () {
		        return this.originalNode().optional();
		    };
		    LowLevelProxyNode.prototype.children = function () {
		        throw new Error('The method must be overridden');
		    };
		    LowLevelProxyNode.prototype.parent = function () {
		        return this._parent;
		    };
		    LowLevelProxyNode.prototype.unit = function () {
		        return this._originalNode.unit();
		    };
		    LowLevelProxyNode.prototype.anchorId = function () {
		        return this._originalNode.anchorId();
		    };
		    LowLevelProxyNode.prototype.errors = function () {
		        return this._originalNode.errors();
		    };
		    LowLevelProxyNode.prototype.anchoredFrom = function () {
		        return this._originalNode.anchoredFrom();
		    };
		    LowLevelProxyNode.prototype.includedFrom = function () {
		        return this._originalNode.includedFrom();
		    };
		    LowLevelProxyNode.prototype.visit = function (v) {
		        if (v(this)) {
		            this.children().forEach(function (x) { return x.visit(v); });
		        }
		    };
		    //TODO
		    LowLevelProxyNode.prototype.addChild = function (n) {
		    };
		    //TODO
		    LowLevelProxyNode.prototype.execute = function (cmd) {
		    };
		    //TODO
		    LowLevelProxyNode.prototype.dump = function () {
		        return null;
		    };
		    //TODO
		    LowLevelProxyNode.prototype.dumpToObject = function () {
		        return json.serialize(this);
		    };
		    LowLevelProxyNode.prototype.keyStart = function () {
		        return this._originalNode.keyStart();
		    };
		    LowLevelProxyNode.prototype.keyEnd = function () {
		        return this._originalNode.keyEnd();
		    };
		    LowLevelProxyNode.prototype.valueStart = function () {
		        return this._originalNode.valueStart();
		    };
		    LowLevelProxyNode.prototype.valueEnd = function () {
		        return this._originalNode.valueEnd();
		    };
		    LowLevelProxyNode.prototype.isValueLocal = function () {
		        return this._originalNode.isValueLocal();
		    };
		    LowLevelProxyNode.prototype.kind = function () {
		        return this._originalNode.kind();
		    };
		    LowLevelProxyNode.prototype.valueKind = function () {
		        return this._originalNode.valueKind();
		    };
		    LowLevelProxyNode.prototype.show = function (msg) {
		        this._originalNode.show(msg);
		    };
		    LowLevelProxyNode.prototype.setHighLevelParseResult = function (highLevelParseResult) {
		        this._highLevelParseResult = highLevelParseResult;
		    };
		    LowLevelProxyNode.prototype.highLevelParseResult = function () {
		        return this._highLevelParseResult;
		    };
		    LowLevelProxyNode.prototype.setHighLevelNode = function (highLevel) {
		        this._highLevelNode = highLevel;
		    };
		    LowLevelProxyNode.prototype.highLevelNode = function () {
		        return this._highLevelNode;
		    };
		    LowLevelProxyNode.prototype.text = function (unitText) {
		        throw new Error("not implemented");
		    };
		    LowLevelProxyNode.prototype.copy = function () {
		        throw new Error("not implemented");
		    };
		    LowLevelProxyNode.prototype.markup = function (json) {
		        throw new Error("not implemented");
		    };
		    LowLevelProxyNode.prototype.nodeDefinition = function () {
		        return impl.getDefinitionForLowLevelNode(this);
		    };
		    LowLevelProxyNode.prototype.includesContents = function () {
		        return this._originalNode.includesContents();
		    };
		    return LowLevelProxyNode;
		})();
		exports.LowLevelProxyNode = LowLevelProxyNode;
		var LowLevelCompositeNode = (function (_super) {
		    __extends(LowLevelCompositeNode, _super);
		    function LowLevelCompositeNode(node, parent, transformer, ramlVersion, isPrimary) {
		        if (isPrimary === void 0) { isPrimary = true; }
		        _super.call(this, parent, transformer, ramlVersion);
		        this.isPrimary = isPrimary;
		        //Colliding nodes of the initioal AST
		        this._adoptedNodes = [];
		        var originalParent = this.parent() ? this.parent().originalNode() : null;
		        this._originalNode = new LowLevelValueTransformingNode(node, originalParent, transformer, this.ramlVersion);
		        this._adoptedNodes.push(this._originalNode);
		    }
		    LowLevelCompositeNode.prototype.adoptedNodes = function () {
		        return this._adoptedNodes;
		    };
		    LowLevelCompositeNode.prototype.primaryNode = function () {
		        return this.isPrimary ? this._originalNode : null;
		    };
		    LowLevelCompositeNode.prototype.parent = function () {
		        return this._parent;
		    };
		    LowLevelCompositeNode.prototype.adopt = function (node, transformer) {
		        if (!transformer) {
		            transformer = this._transformer;
		        }
		        var originalParent = this.parent() ? this.parent().originalNode() : null;
		        var tNode = new LowLevelValueTransformingNode(node, originalParent, transformer, this.ramlVersion);
		        this._adoptedNodes.push(tNode);
		        if (this._children) {
		            this._children.forEach(function (x) { return x._parent = null; });
		        }
		        this._children = null;
		        if (this.highLevelNode()) {
		            this.highLevelNode().resetChildren();
		        }
		    };
		    LowLevelCompositeNode.prototype.value = function () {
		        var valuableNodes = this._adoptedNodes.filter(function (x) { return x.value() != null; });
		        if (valuableNodes.length > 0) {
		            return valuableNodes[0].value();
		        }
		        return this._originalNode.value();
		    };
		    LowLevelCompositeNode.prototype.children = function () {
		        var _this = this;
		        if (this._children) {
		            return this._children;
		        }
		        var result = [];
		        var canBeMap = false;
		        var canBeSeq = false;
		        this._adoptedNodes.forEach(function (x) {
		            if (x.children() && x.children().length > 0) {
		                canBeSeq = true;
		                if (x.children()[0].key()) {
		                    canBeMap = true;
		                }
		            }
		        });
		        if (canBeMap) {
		            result = this.collectChildrenWithKeys();
		        }
		        else if (canBeSeq) {
		            result = this.collectChildrenWithKeys();
		            var map = {};
		            this._adoptedNodes.forEach(function (x) { return x.children().filter(function (y) { return !y.key(); }).forEach(function (y) {
		                var isPrimary = x == _this.primaryNode();
		                var key = _this.buildKey(y);
		                if (!isPrimary && map[key]) {
		                    //filtering away values with repeating keys
		                    //primary node is not subjected to filtration
		                    return;
		                }
		                map[key] = true;
		                var transformer = x.transformer() ? x.transformer() : _this.transformer();
		                var ch = (y instanceof LowLevelValueTransformingNode) ? y.originalNode() : y;
		                result.push(new LowLevelCompositeNode(ch, _this, transformer, _this.ramlVersion, isPrimary));
		            }); });
		        }
		        else {
		            result = [];
		        }
		        this._children = result;
		        return result;
		    };
		    LowLevelCompositeNode.prototype.buildKey = function (y) {
		        var obj = json.serialize(y);
		        var def = this.nodeDefinition();
		        if (def && (def.key() == universes.Universe08.TraitRef || def.key() == universes.Universe08.ResourceTypeRef || def.key() == universes.Universe10.TraitRef || def.key() == universes.Universe10.ResourceTypeRef)) {
		            if (typeof obj == 'object') {
		                var keys = Object.keys(obj);
		                if (keys.length > 0) {
		                    obj = keys[0];
		                }
		            }
		        }
		        return stringify(obj);
		    };
		    LowLevelCompositeNode.prototype.collectChildrenWithKeys = function () {
		        var _this = this;
		        var result = [];
		        var m = {};
		        this._adoptedNodes.forEach(function (x) {
		            var isPrimary = x == _this.primaryNode();
		            x.originalNode().children().forEach(function (y) {
		                var key = y.key();
		                if (_this.skipKey(key, isPrimary)) {
		                    return;
		                }
		                if (!key) {
		                    return;
		                }
		                var arr = m[key];
		                if (!arr) {
		                    arr = [];
		                    m[key] = arr;
		                }
		                arr.push({ node: y, transformer: x.transformer(), isPrimary: isPrimary });
		            });
		        });
		        Object.keys(m).forEach(function (key) {
		            var arr = m[key];
		            var allOptional = true;
		            var hasPrimaryChildren = false;
		            arr.forEach(function (x) {
		                allOptional = allOptional && x.node.optional();
		                hasPrimaryChildren = hasPrimaryChildren || x.isPrimary;
		            });
		            if (hasPrimaryChildren) {
		                var primaryChildren = [];
		                arr.filter(function (x) { return x.isPrimary; }).forEach(function (x) {
		                    var tr = x.transformer ? x.transformer : _this.transformer();
		                    primaryChildren.push(new LowLevelCompositeNode(x.node, _this, tr, _this.ramlVersion, true));
		                });
		                var primaryChild = primaryChildren[0];
		                arr.filter(function (x) { return !x.isPrimary; }).forEach(function (x) {
		                    primaryChild.adopt(x.node, x.transformer);
		                });
		                primaryChildren.forEach(function (x) { return result.push(x); });
		            }
		            else if (!allOptional) {
		                var tr = arr[0].transformer ? arr[0].transformer : _this.transformer();
		                var primaryChild = new LowLevelCompositeNode(arr[0].node, _this, tr, _this.ramlVersion, false);
		                for (var i = 1; i < arr.length; i++) {
		                    primaryChild.adopt(arr[i].node, arr[i].transformer);
		                }
		                result.push(primaryChild);
		            }
		        });
		        return result;
		    };
		    LowLevelCompositeNode.prototype.skipKey = function (key, isPrimary) {
		        if (isPrimary) {
		            return false;
		        }
		        if (this.ramlVersion != 'RAML08') {
		            return false;
		        }
		        var methodDef = universes.Universe08.Method;
		        var hasNormalParametersDef = universes.Universe08.HasNormalParameters;
		        var resourceDef = universes.Universe08.Resource;
		        if (key == hasNormalParametersDef.properties.displayName.name && this.highLevelNode().definition().key().name == methodDef.name) {
		            return true;
		        }
		        if (key == resourceDef.properties.displayName.name && this.highLevelNode().definition().key().name == resourceDef.name) {
		            return true;
		        }
		        return false;
		    };
		    LowLevelCompositeNode.prototype.valueKind = function () {
		        if (this._originalNode.kind() != 1 /* MAPPING */) {
		            return null;
		        }
		        for (var i = 0; i < this._adoptedNodes.length; i++) {
		            var node = this._adoptedNodes[i];
		            if (node.value()) {
		                return node.valueKind();
		            }
		        }
		        return null;
		    };
		    LowLevelCompositeNode.prototype.includePath = function () {
		        for (var i = 0; i < this._adoptedNodes.length; i++) {
		            var node = this._adoptedNodes[i];
		            if (node.value() != null) {
		                return node.includePath();
		            }
		        }
		        return null;
		    };
		    LowLevelCompositeNode.prototype.includeReference = function () {
		        for (var i = 0; i < this._adoptedNodes.length; i++) {
		            var node = this._adoptedNodes[i];
		            if (node.value() != null) {
		                return node.includeReference();
		            }
		        }
		        return null;
		    };
		    LowLevelCompositeNode.prototype.optional = function () {
		        return _.all(this._adoptedNodes, function (x) { return x.optional(); });
		    };
		    return LowLevelCompositeNode;
		})(LowLevelProxyNode);
		exports.LowLevelCompositeNode = LowLevelCompositeNode;
		var LowLevelValueTransformingNode = (function (_super) {
		    __extends(LowLevelValueTransformingNode, _super);
		    function LowLevelValueTransformingNode(node, parent, transformer, ramlVersion) {
		        _super.call(this, parent, transformer, ramlVersion);
		        this._originalNode = node;
		    }
		    LowLevelValueTransformingNode.prototype.value = function () {
		        var val = this.originalNode().value();
		        var t = this.transformer();
		        if (t) {
		            var transformationResult = t.transform(val);
		            val = transformationResult.value;
		        }
		        return val;
		    };
		    LowLevelValueTransformingNode.prototype.children = function () {
		        var _this = this;
		        return this.originalNode().children().map(function (x) { return new LowLevelValueTransformingNode(x, _this, _this._transformer, _this.ramlVersion); });
		    };
		    LowLevelValueTransformingNode.prototype.parent = function () {
		        return this._parent;
		    };
		    LowLevelValueTransformingNode.prototype.key = function () {
		        var key = _super.prototype.key.call(this);
		        if (this.transformer() != null) {
		            return this.transformer().transform(key).value;
		        }
		        return key;
		    };
		    return LowLevelValueTransformingNode;
		})(LowLevelProxyNode);
		exports.LowLevelValueTransformingNode = LowLevelValueTransformingNode;


	/***/ },
	/* 7 */
	/***/ function(module, exports) {

		/// <reference path="../../../typings/main.d.ts" />
		(function (Kind) {
		    Kind[Kind["SCALAR"] = 0] = "SCALAR";
		    Kind[Kind["MAPPING"] = 1] = "MAPPING";
		    Kind[Kind["MAP"] = 2] = "MAP";
		    Kind[Kind["SEQ"] = 3] = "SEQ";
		    Kind[Kind["ANCHOR_REF"] = 4] = "ANCHOR_REF";
		    Kind[Kind["INCLUDE_REF"] = 5] = "INCLUDE_REF";
		})(exports.Kind || (exports.Kind = {}));
		var Kind = exports.Kind;
		function newMapping(key, value) {
		    var end = (value ? value.endPosition : key.endPosition + 1); //FIXME.workaround, end should be defied by position of ':'
		    //console.log('key: ' + key.value + ' ' + key.startPosition + '..' + key.endPosition + ' ' + value + ' end: ' + end);
		    var node = {
		        key: key,
		        value: value,
		        startPosition: key.startPosition,
		        endPosition: end,
		        kind: 1 /* MAPPING */,
		        parent: null,
		        errors: []
		    };
		    return node;
		}
		exports.newMapping = newMapping;
		function newAnchorRef(key, start, end, value) {
		    return {
		        errors: [],
		        referencesAnchor: key,
		        value: value,
		        startPosition: start,
		        endPosition: end,
		        kind: 4 /* ANCHOR_REF */,
		        parent: null
		    };
		}
		exports.newAnchorRef = newAnchorRef;
		function newScalar(v) {
		    if (v === void 0) { v = ""; }
		    return {
		        errors: [],
		        startPosition: -1,
		        endPosition: -1,
		        value: v,
		        kind: 0 /* SCALAR */,
		        parent: null,
		        doubleQuoted: false
		    };
		}
		exports.newScalar = newScalar;
		function newItems() {
		    return {
		        errors: [],
		        startPosition: -1,
		        endPosition: -1,
		        items: [],
		        kind: 3 /* SEQ */,
		        parent: null
		    };
		}
		exports.newItems = newItems;
		function newSeq() {
		    return newItems();
		}
		exports.newSeq = newSeq;
		function newMap(mappings) {
		    return {
		        errors: [],
		        startPosition: -1,
		        endPosition: -1,
		        mappings: mappings ? mappings : [],
		        kind: 2 /* MAP */,
		        parent: null
		    };
		}
		exports.newMap = newMap;


	/***/ },
	/* 8 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		/**
		 * Created by kor on 05/05/15.
		 */
		var Error = __webpack_require__(9);
		var lowlevel = __webpack_require__(10);
		var yaml = __webpack_require__(7);
		var util = __webpack_require__(11);
		var llImpl = __webpack_require__(15);
		var CompilationUnit = (function () {
		    function CompilationUnit(_absolutePath, _path, _content, _project, _isTopoLevel, serializeOptions) {
		        if (serializeOptions === void 0) { serializeOptions = {}; }
		        this._absolutePath = _absolutePath;
		        this._path = _path;
		        this._content = _content;
		        this._project = _project;
		        this._isTopoLevel = _isTopoLevel;
		        this.serializeOptions = serializeOptions;
		        this._node = new AstNode(this, JSON.parse(this._content), null, serializeOptions);
		    }
		    CompilationUnit.prototype.absolutePath = function () {
		        return this._absolutePath;
		    };
		    CompilationUnit.prototype.clone = function () {
		        return null;
		    };
		    CompilationUnit.prototype.contents = function () {
		        return this._content;
		    };
		    CompilationUnit.prototype.lexerErrors = function () {
		        return [];
		    };
		    CompilationUnit.prototype.path = function () {
		        return this._content;
		    };
		    CompilationUnit.prototype.isTopLevel = function () {
		        return this._isTopoLevel;
		    };
		    CompilationUnit.prototype.ast = function () {
		        return this._node;
		    };
		    CompilationUnit.prototype.isDirty = function () {
		        return true;
		    };
		    CompilationUnit.prototype.getIncludeNodes = function () {
		        return [];
		    };
		    CompilationUnit.prototype.resolveAsync = function (p) {
		        return null;
		    };
		    CompilationUnit.prototype.isRAMLUnit = function () {
		        return true;
		    };
		    CompilationUnit.prototype.project = function () {
		        return this._project;
		    };
		    CompilationUnit.prototype.updateContent = function (newContent) {
		    };
		    CompilationUnit.prototype.ramlVersion = function () {
		        throw new Error('not implemented');
		    };
		    CompilationUnit.prototype.lineMapper = function () {
		        return new lowlevel.LineMapperImpl(this.contents(), this.absolutePath());
		    };
		    CompilationUnit.prototype.resolve = function (p) {
		        return null;
		    }; // TODO FIXME 
		    return CompilationUnit;
		})();
		exports.CompilationUnit = CompilationUnit;
		//export interface IProject{
		//    units():ICompilationUnit[];//returns units with apis in this folder
		//
		//    execute(cmd:CompositeCommand)
		//
		//    executeTextChange(textCommand:TextChangeCommand);//this may result in broken nodes?
		//
		//    addListener(listener:IASTListener);
		//
		//    removeListener(listener:IASTListener)
		//
		//    addTextChangeListener(listener:ITextChangeCommandListener);
		//    removeTextChangeListener(listener:ITextChangeCommandListener);
		//}
		//export interface IASTListener{
		//    (delta:ASTDelta)
		//}
		//
		//export interface ITextChangeCommandListener{
		//    (delta:TextChangeCommand)
		//}
		//export class ASTDelta{
		//    commands:ASTChangeCommand[]
		//}
		//export interface ASTVisitor{
		//    (node:ILowLevelASTNode):boolean
		//}
		var AstNode = (function () {
		    function AstNode(_unit, _object, _parent, options, _key) {
		        var _this = this;
		        if (options === void 0) { options = {}; }
		        this._unit = _unit;
		        this._object = _object;
		        this._parent = _parent;
		        this.options = options;
		        this._key = _key;
		        this._isOptional = false;
		        if (this._object instanceof Object) {
		            Object.keys(this._object).forEach(function (x) {
		                var u = unescapeKey(x, _this.options);
		                if (u != x) {
		                    var val = _this._object[x];
		                    delete _this._object[x];
		                    _this._object[u] = val;
		                }
		            });
		        }
		        if (this._key) {
		            if (util.stringEndsWith(this._key, '?')) {
		                this._isOptional = true;
		                this._key = this._key.substring(0, this._key.length - 1);
		            }
		        }
		    }
		    AstNode.prototype.keyKind = function () {
		        return null;
		    };
		    AstNode.prototype.start = function () {
		        return -1;
		    };
		    AstNode.prototype.end = function () {
		        return -1;
		    };
		    AstNode.prototype.value = function () {
		        return this._object;
		    };
		    AstNode.prototype.actual = function () {
		        return this._object;
		    };
		    AstNode.prototype.includeErrors = function () {
		        return [];
		    };
		    AstNode.prototype.includePath = function () {
		        return null;
		    };
		    AstNode.prototype.includeReference = function () {
		        return null;
		    };
		    AstNode.prototype.key = function () {
		        return this._key;
		    };
		    AstNode.prototype.optional = function () {
		        return this._isOptional;
		    };
		    AstNode.prototype.children = function () {
		        var _this = this;
		        if (!this._object) {
		            return [];
		        }
		        if (Array.isArray(this._object)) {
		            return this._object.map(function (x) { return new AstNode(_this._unit, x, _this, _this.options); });
		        }
		        else if (this._object instanceof Object) {
		            return Object.keys(this._object).map(function (x) { return new AstNode(_this._unit, _this._object[x], _this, _this.options, x); });
		        }
		        else {
		            return [];
		        }
		    };
		    AstNode.prototype.parent = function () {
		        return this._parent;
		    };
		    AstNode.prototype.unit = function () {
		        return this._unit;
		    };
		    AstNode.prototype.anchorId = function () {
		        return null;
		    };
		    AstNode.prototype.errors = function () {
		        return [];
		    };
		    AstNode.prototype.anchoredFrom = function () {
		        return this;
		    };
		    AstNode.prototype.includedFrom = function () {
		        return this;
		    };
		    AstNode.prototype.visit = function (v) {
		        if (v(this)) {
		            this.children().forEach(function (x) { return x.visit(v); });
		        }
		    };
		    AstNode.prototype.dumpToObject = function () {
		        return this._object;
		    };
		    AstNode.prototype.addChild = function (n) {
		    };
		    AstNode.prototype.execute = function (cmd) {
		    };
		    AstNode.prototype.dump = function () {
		        return JSON.stringify(this._object);
		    };
		    AstNode.prototype.keyStart = function () {
		        return -1;
		    };
		    AstNode.prototype.keyEnd = function () {
		        return -1;
		    };
		    AstNode.prototype.valueStart = function () {
		        return -1;
		    };
		    AstNode.prototype.valueEnd = function () {
		        return -1;
		    };
		    AstNode.prototype.isValueLocal = function () {
		        return true;
		    };
		    AstNode.prototype.kind = function () {
		        if (Array.isArray(this._object)) {
		            return 3 /* SEQ */;
		        }
		        else if (this._object instanceof Object) {
		            return 2 /* MAP */;
		        }
		        else {
		            return 0 /* SCALAR */;
		        }
		    };
		    AstNode.prototype.valueKind = function () {
		        return null;
		    };
		    AstNode.prototype.show = function (msg) {
		    };
		    AstNode.prototype.setHighLevelParseResult = function (highLevelParseResult) {
		        this._highLevelParseResult = highLevelParseResult;
		    };
		    AstNode.prototype.highLevelParseResult = function () {
		        return this._highLevelParseResult;
		    };
		    AstNode.prototype.setHighLevelNode = function (highLevel) {
		        this._highLevelNode = highLevel;
		    };
		    AstNode.prototype.highLevelNode = function () {
		        return this._highLevelNode;
		    };
		    AstNode.prototype.text = function (unitText) {
		        throw new Error("not implemented");
		    };
		    AstNode.prototype.copy = function () {
		        throw new Error("not implemented");
		    };
		    AstNode.prototype.markup = function (json) {
		        throw new Error("not implemented");
		    };
		    AstNode.prototype.nodeDefinition = function () {
		        return llImpl.getDefinitionForLowLevelNode(this);
		    };
		    AstNode.prototype.includesContents = function () {
		        return false;
		    };
		    return AstNode;
		})();
		exports.AstNode = AstNode;
		function serialize(node, options) {
		    if (options === void 0) { options = {}; }
		    if (node.children().length == 0) {
		        if (node.value()) {
		            return node.value();
		        }
		        return '';
		    }
		    if (!node.children()[0].key()) {
		        var arr = [];
		        node.children().forEach(function (x) {
		            arr.push(serialize(x, options));
		        });
		        return arr;
		    }
		    else {
		        var obj = {};
		        node.children().forEach(function (x) {
		            obj[escapeKey(x.key(), options)] = serialize(x, options);
		        });
		        if (options && options.writeErrors) {
		            var errors = collectErrors(node);
		            if (errors != null && errors.length > 0) {
		                obj['__$errors__'] = errors;
		            }
		        }
		        return obj;
		    }
		}
		exports.serialize = serialize;
		function collectErrors(node) {
		    var errors = [].concat(node.errors());
		    node.children().forEach(function (ch) {
		        var children = ch.children();
		        if (children.length == 0) {
		            ch.errors().forEach(function (e) { return errors.push(e); });
		            return;
		        }
		        if (!children[0].key()) {
		            children.forEach(function (x) {
		                if (x.children().length == 0) {
		                    x.errors().forEach(function (e) { return errors.push(e); });
		                }
		            });
		        }
		    });
		    return errors;
		}
		function escapeKey(key, options) {
		    if (!options || !key) {
		        return key;
		    }
		    if (options.escapeNumericKeys && key.replace(/\d/g, '').trim().length == 0) {
		        return '__$EscapedKey$__' + key;
		    }
		    return key;
		}
		function unescapeKey(key, options) {
		    if (!key) {
		        return key;
		    }
		    if (options.escapeNumericKeys && util.stringStartsWith(key, '__$EscapedKey$__') && key.substring('__$EscapedKey$__'.length).replace(/\d/g, '').trim().length == 0) {
		        return key.substring('__$EscapedKey$__'.length);
		    }
		    return key;
		}


	/***/ },
	/* 9 */
	/***/ function(module, exports) {

		'use strict';
		var YAMLException = (function () {
		    function YAMLException(reason, mark) {
		        if (mark === void 0) { mark = null; }
		        this.name = 'YAMLException';
		        this.reason = reason;
		        this.mark = mark;
		        this.message = this.toString(false);
		    }
		    YAMLException.prototype.toString = function (compact) {
		        if (compact === void 0) { compact = false; }
		        var result;
		        result = 'JS-YAML: ' + (this.reason || '(unknown reason)');
		        if (!compact && this.mark) {
		            result += ' ' + this.mark.toString();
		        }
		        return result;
		    };
		    return YAMLException;
		})();
		module.exports = YAMLException;


	/***/ },
	/* 10 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		/**
		 * Created by kor on 05/05/15.
		 */
		var Error = __webpack_require__(9);
		var ASTDelta = (function () {
		    function ASTDelta() {
		    }
		    return ASTDelta;
		})();
		exports.ASTDelta = ASTDelta;
		(function (CommandKind) {
		    CommandKind[CommandKind["ADD_CHILD"] = 0] = "ADD_CHILD";
		    CommandKind[CommandKind["REMOVE_CHILD"] = 1] = "REMOVE_CHILD";
		    CommandKind[CommandKind["MOVE_CHILD"] = 2] = "MOVE_CHILD";
		    CommandKind[CommandKind["CHANGE_KEY"] = 3] = "CHANGE_KEY";
		    CommandKind[CommandKind["CHANGE_VALUE"] = 4] = "CHANGE_VALUE";
		    CommandKind[CommandKind["INIT_RAML_FILE"] = 5] = "INIT_RAML_FILE";
		})(exports.CommandKind || (exports.CommandKind = {}));
		var CommandKind = exports.CommandKind;
		var TextChangeCommand = (function () {
		    function TextChangeCommand(offset, replacementLength, text, unit, target) {
		        if (target === void 0) { target = null; }
		        this.offset = offset;
		        this.replacementLength = replacementLength;
		        this.text = text;
		        this.unit = unit;
		        this.target = target;
		    }
		    return TextChangeCommand;
		})();
		exports.TextChangeCommand = TextChangeCommand;
		var CompositeCommand = (function () {
		    function CompositeCommand() {
		        this.commands = [];
		    }
		    return CompositeCommand;
		})();
		exports.CompositeCommand = CompositeCommand;
		var ASTChangeCommand = (function () {
		    function ASTChangeCommand(kind, target, value, position) {
		        this.toSeq = false;
		        this.kind = kind;
		        this.target = target;
		        this.value = value;
		        this.position = position;
		    }
		    return ASTChangeCommand;
		})();
		exports.ASTChangeCommand = ASTChangeCommand;
		function setAttr(t, value) {
		    return new ASTChangeCommand(4 /* CHANGE_VALUE */, t, value, -1);
		}
		exports.setAttr = setAttr;
		function setAttrStructured(t, value) {
		    return new ASTChangeCommand(4 /* CHANGE_VALUE */, t, value.lowLevel(), -1);
		}
		exports.setAttrStructured = setAttrStructured;
		function setKey(t, value) {
		    return new ASTChangeCommand(3 /* CHANGE_KEY */, t, value, -1);
		}
		exports.setKey = setKey;
		function removeNode(t, child) {
		    return new ASTChangeCommand(1 /* REMOVE_CHILD */, t, child, -1);
		}
		exports.removeNode = removeNode;
		function insertNode(t, child, insertAfter, toSeq) {
		    if (insertAfter === void 0) { insertAfter = null; }
		    if (toSeq === void 0) { toSeq = false; }
		    var s = new ASTChangeCommand(0 /* ADD_CHILD */, t, child, -1);
		    s.insertionPoint = insertAfter;
		    s.toSeq = toSeq;
		    return s;
		}
		exports.insertNode = insertNode;
		function initRamlFile(root, newroot) {
		    return new ASTChangeCommand(5 /* INIT_RAML_FILE */, root, newroot, -1);
		}
		exports.initRamlFile = initRamlFile;
		var LineMapperImpl = (function () {
		    function LineMapperImpl(content, absPath) {
		        this.content = content;
		        this.absPath = absPath;
		    }
		    LineMapperImpl.prototype.position = function (_pos) {
		        var pos = _pos;
		        this.initMapping();
		        for (var i = 0; i < this.mapping.length; i++) {
		            var lineLength = this.mapping[i];
		            if (pos < lineLength) {
		                return {
		                    line: i,
		                    column: pos,
		                    position: _pos
		                };
		            }
		            pos -= lineLength;
		        }
		        throw new Error("Character position exceeds text length: " + _pos + " > + " + this.content.length + ".\nUnit path: " + this.absPath);
		    };
		    LineMapperImpl.prototype.initMapping = function () {
		        if (this.mapping != null) {
		            return;
		        }
		        if (this.content == null) {
		            throw new Error("Line Mapper has been given null content" + (this.absPath != null ? ('. Path: ' + this.absPath) : ' and null path.'));
		        }
		        this.mapping = [];
		        var ind = 0;
		        var l = this.content.length;
		        for (var i = 0; i < l; i++) {
		            if (this.content.charAt(i) == '\n') {
		                if (i < l - 1 && this.content.charAt(i + 1) == '\r') {
		                    this.mapping.push(i - ind + 2);
		                    ind = i + 2;
		                    i++;
		                }
		                else {
		                    this.mapping.push(i - ind + 1);
		                    ind = i + 1;
		                }
		            }
		            else if (this.content.charAt(i) == '\r') {
		                this.mapping.push(i - ind + 1);
		                ind = i + 1;
		            }
		        }
		        this.mapping.push(l - ind);
		    };
		    return LineMapperImpl;
		})();
		exports.LineMapperImpl = LineMapperImpl;


	/***/ },
	/* 11 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var _ = __webpack_require__(4);
		var Opt = __webpack_require__(12);
		exports.defined = function (x) { return (x !== null) && (x !== undefined); };
		/**
		 * Arrays of Objects are common in RAML08.
		 * @param x
		 * @returns {{}}
		 */
		function flattenArrayOfObjects(x) {
		    var res = {};
		    x.forEach(function (v) { return Object.keys(v).forEach(function (k) { return res[k] = v[k]; }); });
		    return res;
		}
		exports.flattenArrayOfObjects = flattenArrayOfObjects;
		function find(xs, f) {
		    return new Opt(_.find(xs || [], f));
		}
		exports.find = find;
		exports.isInstance = function (v, C) { return (v instanceof C) ? [v] : []; };
		exports.ifInstanceOf = function (v, C, f) { return (v instanceof C) ? f(v) : null; };
		function toTuples(map) {
		    return Object.keys(map).map(function (k) { return [k, map[k]]; });
		}
		exports.toTuples = toTuples;
		function fromTuples(tuples) {
		    var obj = {};
		    tuples.forEach(function (x) { return obj[x[0]] = x[1]; });
		    return obj;
		}
		exports.fromTuples = fromTuples;
		exports.collectInstancesOf = function (xs, C) { return tap([], function (res) { return xs.forEach(function (v) { return exports.ifInstanceOf(v, C, function (x) { return res.push(x); }); }); }); };
		exports.collectInstancesOfInMap = function (map, C) {
		    return Object.keys(map).map(function (k) { return [k, map[k]]; }).filter(function (x) { return x[1] instanceof C; }).map(function (x) { return x; });
		};
		exports.asArray = function (v) { return exports.defined(v) ? ((v instanceof Array) ? v : [v]) : []; };
		exports.shallowCopy = function (obj) { return tap({}, function (copy) { return Object.keys(obj).forEach(function (k) { return copy[k] = obj[k]; }); }); };
		exports.flatMap = function (xs, f) { return exports.flatten(xs.map(f)); };
		exports.flatten = function (xss) { return Array.prototype.concat.apply([], xss); };
		exports.takeWhile = function (xs, f) { return tap([], function (res) {
		    for (var i = 0; i < xs.length; i++) {
		        if (!f(xs[i]))
		            break;
		        res.push(xs[i]);
		    }
		}); };
		function tap(v, f) {
		    f(v);
		    return v;
		}
		exports.tap = tap;
		function kv(obj, iter) {
		    if (typeof obj === 'object')
		        Object.keys(obj).forEach(function (k) { return iter(k, obj[k]); });
		}
		exports.kv = kv;
		function indexed(objects, key, delKey) {
		    if (delKey === void 0) { delKey = false; }
		    var obj = {};
		    objects.forEach(function (original) {
		        var copy = exports.shallowCopy(original);
		        if (delKey)
		            delete copy[key];
		        obj[original[key]] = copy;
		    });
		    return obj;
		}
		exports.indexed = indexed;
		function stringEndsWith(str, search) {
		    var dif = str.length - search.length;
		    return dif >= 0 && str.lastIndexOf(search) === dif;
		}
		exports.stringEndsWith = stringEndsWith;
		function stringStartsWith(str, search) {
		    return str.length - search.length >= 0 && str.substring(0, search.length) === search;
		}
		exports.stringStartsWith = stringStartsWith;
		function lazypropkeyfilter(k) {
		    return k[k.length - 1] == "_"; // ends with underscore
		}
		exports.lazypropkeyfilter = lazypropkeyfilter;
		function lazyprop(obj, key, func) {
		    var result, ready = false;
		    obj[key] = function () {
		        if (!ready) {
		            ready = true;
		            result = func.apply(obj);
		        }
		        return result;
		    };
		}
		function lazyprops(obj, keyfilter) {
		    if (keyfilter === void 0) { keyfilter = lazypropkeyfilter; }
		    for (var k in obj) {
		        if (keyfilter(k)) {
		            exports.ifInstanceOf(obj[k], Function, function (vf) { return (vf.length === 0) ? lazyprop(obj, k, vf) : null; });
		        }
		    }
		}
		exports.lazyprops = lazyprops;
		function iff(v, f) {
		    if (v !== undefined)
		        f(v);
		}
		exports.iff = iff;
		function isRAMLUrl(str) {
		    if (typeof str !== 'string' || str == '')
		        return false;
		    return stringEndsWith(str, ".raml");
		}
		exports.isRAMLUrl = isRAMLUrl;
		function getAllRequiredExternalModulesFromCode(code) {
		    var match;
		    var mods = [];
		    // both quoting styles
		    var r1 = new RegExp("require\\('([^']+)'\\)", "gi");
		    while (match = r1.exec(code)) {
		        mods.push(match[1]);
		    }
		    var r2 = new RegExp('require\\("([^"]+)"\\)', "gi");
		    while (match = r2.exec(code)) {
		        mods.push(match[1]);
		    }
		    mods = _.unique(mods).filter(function (x) { return x != ""; });
		    mods.sort();
		    return mods;
		}
		exports.getAllRequiredExternalModulesFromCode = getAllRequiredExternalModulesFromCode;
		exports.serial = (function () {
		    var i = 0;
		    return function () { return i++; };
		})();
		function isEssential(arg) {
		    return typeof arg !== 'undefined' && arg != null;
		}
		exports.isEssential = isEssential;
		function firstToUpper(q) {
		    if (q.length == 0) {
		        return q;
		    }
		    return q.charAt(0).toUpperCase() + q.substr(1);
		}
		exports.firstToUpper = firstToUpper;
		function updateObject(source, target, addNewFields) {
		    if (addNewFields === void 0) { addNewFields = false; }
		    var keySet = Object.keys(target);
		    if (addNewFields) {
		        var map = {};
		        keySet.forEach(function (x) { return map[x] = true; });
		        Object.keys(source).forEach(function (x) { return map[x] = true; });
		        keySet = Object.keys(map);
		    }
		    keySet.forEach(function (x) {
		        var value = source[x];
		        if (value instanceof Object) {
		            if (!target[x]) {
		                target[x] = {};
		            }
		            updateObject(value, target[x], true);
		        }
		        else if (value != undefined) {
		            target[x] = source[x];
		        }
		    });
		}
		exports.updateObject = updateObject;
		;
		/**
		 * In 'str' replace all occurences of 'map' keys to their values.
		 */
		function replaceMap(str, map) {
		    Object.keys(map).forEach(function (x) { return str = replace(str, x, map[x]); });
		    return str;
		}
		exports.replaceMap = replaceMap;
		/**
		 * Replace all occurences of 'x' in 'str' to 'r' without thinking if 'x' can be passed without
		 * escaping as argument to RegExp constructor
		 */
		function replace(str, x, r) {
		    var result = '';
		    var prev = 0;
		    for (var i = str.indexOf(x); i < str.length && i >= 0; i = str.indexOf(x, prev)) {
		        result += str.substring(prev, i);
		        result += r;
		        prev = i + x.length;
		    }
		    result += str.substring(prev, str.length);
		    return result;
		}
		exports.replace = replace;


	/***/ },
	/* 12 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../typings/main.d.ts" />
		var invariant = __webpack_require__(13);
		var exists = function (v) { return (v != null); };
		var globalEmptyOpt;
		var Opt = (function () {
		    function Opt(_value) {
		        var _this = this;
		        this._value = _value;
		        this._isDefined = false;
		        this._isEmpty = true;
		        this._arr = undefined;
		        this.getOrThrow = function () {
		            invariant(_this._isDefined, 'Opt is empty. Use `Opt#getOrElse` or check `Opt#isDefined`.');
		            return _this._value;
		        };
		        this.value = function () { return _this._value; };
		        this.isDefined = function () { return _this._isDefined; };
		        this.isEmpty = function () { return _this._isEmpty; };
		        this.toArray = function () { return _this._arr || (_this._arr = _this._isDefined ? [_this._value] : []); };
		        this.getOrElse = function (v) { return _this._isDefined ? _this._value : v; };
		        this.getOrElseF = function (v) { return _this._isDefined ? _this._value : v(); };
		        this.map = function (f) { return _this._isEmpty ? Opt.empty() : new Opt(f(_this._value)); };
		        this.flatMap = function (f) { return _this.map(f).getOrElse(Opt.empty()); };
		        this.equals = function (other) {
		            invariant(other instanceof Opt, 'Expected other to be an `Opt`, but got `%s`', typeof other);
		            return (_this._isDefined === other.isDefined()) && (_this._value === other.value());
		        };
		        if (exists(this._value)) {
		            this._isDefined = true;
		            this._isEmpty = false;
		        }
		    }
		    Opt.prototype.forEach = function (fn) {
		        if (this.isDefined()) {
		            fn(this._value);
		        }
		    };
		    /**
		     * You can always create an empty option by hand just by calling new Opt<T>()
		     * but calling this method will return a global instance instead of allocating a new one each time
		     */
		    Opt.empty = function () { return (globalEmptyOpt || (globalEmptyOpt = new Opt())); };
		    return Opt;
		})();
		module.exports = Opt;


	/***/ },
	/* 13 */
	/***/ function(module, exports, __webpack_require__) {

		/* WEBPACK VAR INJECTION */(function(process) {/**
		 * Copyright 2013-2015, Facebook, Inc.
		 * All rights reserved.
		 *
		 * This source code is licensed under the BSD-style license found in the
		 * LICENSE file in the root directory of this source tree. An additional grant
		 * of patent rights can be found in the PATENTS file in the same directory.
		 */

		'use strict';

		/**
		 * Use invariant() to assert state which your program assumes to be true.
		 *
		 * Provide sprintf-style format (only %s is supported) and arguments
		 * to provide information about what broke and what you were
		 * expecting.
		 *
		 * The invariant message will be stripped in production, but the invariant
		 * will remain to ensure logic does not differ in production.
		 */

		var invariant = function(condition, format, a, b, c, d, e, f) {
		  if (process.env.NODE_ENV !== 'production') {
		    if (format === undefined) {
		      throw new Error('invariant requires an error message argument');
		    }
		  }

		  if (!condition) {
		    var error;
		    if (format === undefined) {
		      error = new Error(
		        'Minified exception occurred; use the non-minified dev environment ' +
		        'for the full error message and additional helpful warnings.'
		      );
		    } else {
		      var args = [a, b, c, d, e, f];
		      var argIndex = 0;
		      error = new Error(
		        format.replace(/%s/g, function() { return args[argIndex++]; })
		      );
		      error.name = 'Invariant Violation';
		    }

		    error.framesToPop = 1; // we don't care about invariant's own frame
		    throw error;
		  }
		};

		module.exports = invariant;

		/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(14)))

	/***/ },
	/* 14 */
	/***/ function(module, exports) {

		// shim for using process in browser

		var process = module.exports = {};
		var queue = [];
		var draining = false;
		var currentQueue;
		var queueIndex = -1;

		function cleanUpNextTick() {
		    draining = false;
		    if (currentQueue.length) {
		        queue = currentQueue.concat(queue);
		    } else {
		        queueIndex = -1;
		    }
		    if (queue.length) {
		        drainQueue();
		    }
		}

		function drainQueue() {
		    if (draining) {
		        return;
		    }
		    var timeout = setTimeout(cleanUpNextTick);
		    draining = true;

		    var len = queue.length;
		    while(len) {
		        currentQueue = queue;
		        queue = [];
		        while (++queueIndex < len) {
		            if (currentQueue) {
		                currentQueue[queueIndex].run();
		            }
		        }
		        queueIndex = -1;
		        len = queue.length;
		    }
		    currentQueue = null;
		    draining = false;
		    clearTimeout(timeout);
		}

		process.nextTick = function (fun) {
		    var args = new Array(arguments.length - 1);
		    if (arguments.length > 1) {
		        for (var i = 1; i < arguments.length; i++) {
		            args[i - 1] = arguments[i];
		        }
		    }
		    queue.push(new Item(fun, args));
		    if (queue.length === 1 && !draining) {
		        setTimeout(drainQueue, 0);
		    }
		};

		// v8 likes predictible objects
		function Item(fun, array) {
		    this.fun = fun;
		    this.array = array;
		}
		Item.prototype.run = function () {
		    this.fun.apply(null, this.array);
		};
		process.title = 'browser';
		process.browser = true;
		process.env = {};
		process.argv = [];
		process.version = ''; // empty string to avoid regexp issues
		process.versions = {};

		function noop() {}

		process.on = noop;
		process.addListener = noop;
		process.once = noop;
		process.off = noop;
		process.removeListener = noop;
		process.removeAllListeners = noop;
		process.emit = noop;

		process.binding = function (name) {
		    throw new Error('process.binding is not supported');
		};

		process.cwd = function () { return '/' };
		process.chdir = function (dir) {
		    throw new Error('process.chdir is not supported');
		};
		process.umask = function() { return 0; };


	/***/ },
	/* 15 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var yaml = __webpack_require__(7);
		var lowlevel = __webpack_require__(10);
		var path = __webpack_require__(16);
		var fs = __webpack_require__(17);
		var parser = __webpack_require__(18);
		var dumper = __webpack_require__(47);
		var Error = __webpack_require__(9);
		var textutil = __webpack_require__(48);
		var services = __webpack_require__(49);
		var rr = __webpack_require__(113);
		var SimpleExecutor = __webpack_require__(117);
		var util = __webpack_require__(11);
		var URL = __webpack_require__(119);
		var refResolvers = __webpack_require__(120);
		exports.Kind = {
		    SCALAR: 0 /* SCALAR */
		};
		var MarkupIndentingBuffer = (function () {
		    function MarkupIndentingBuffer(indent) {
		        this.text = '';
		        this.indent = indent;
		    }
		    MarkupIndentingBuffer.prototype.isLastNL = function () {
		        return this.text.length > 0 && this.text[this.text.length - 1] == '\n';
		    };
		    MarkupIndentingBuffer.prototype.addWithIndent = function (lev, s) {
		        if (this.isLastNL()) {
		            this.text += textutil.indent(lev);
		            this.text += this.indent;
		        }
		        this.text += s;
		    };
		    MarkupIndentingBuffer.prototype.addChar = function (ch) {
		        if (this.isLastNL()) {
		            this.text += this.indent;
		        }
		        this.text += ch;
		    };
		    MarkupIndentingBuffer.prototype.append = function (s) {
		        for (var i = 0; i < s.length; i++) {
		            this.addChar(s[i]);
		        }
		    };
		    return MarkupIndentingBuffer;
		})();
		exports.MarkupIndentingBuffer = MarkupIndentingBuffer;
		var CompilationUnit = (function () {
		    function CompilationUnit(_path, _content, _tl, _project, _apath) {
		        this._path = _path;
		        this._content = _content;
		        this._tl = _tl;
		        this._project = _project;
		        this._apath = _apath;
		    }
		    CompilationUnit.prototype.isStubUnit = function () {
		        return this.stu;
		    };
		    CompilationUnit.prototype.resolveAsync = function (p) {
		        var unit = this._project.resolveAsync(this._path, p);
		        return unit;
		    };
		    CompilationUnit.prototype.getIncludeNodes = function () {
		        var ast = this.ast();
		        var arr = [];
		        ast.gatherIncludes(arr);
		        return arr;
		    };
		    CompilationUnit.prototype.cloneToProject = function (p) {
		        var newUnit = new CompilationUnit(this._path, this._content, this._tl, p, this._apath);
		        return newUnit;
		    };
		    CompilationUnit.prototype.clone = function () {
		        var newUnit = new CompilationUnit(this._path, this._content, this._tl, this.project(), this._apath);
		        return newUnit;
		    };
		    CompilationUnit.prototype.stub = function () {
		        var newUnit = new CompilationUnit(this._path, this._content, this._tl, this.project(), this._apath);
		        newUnit.stu = true;
		        return newUnit;
		    };
		    CompilationUnit.prototype.isDirty = function () {
		        return false;
		    };
		    CompilationUnit.prototype.absolutePath = function () {
		        return this._apath;
		    };
		    CompilationUnit.prototype.isRAMLUnit = function () {
		        var en = path.extname(this._path);
		        return en == '.raml' || en == '.yaml' || en == '.yml';
		    };
		    CompilationUnit.prototype.contents = function () {
		        return this._content;
		    };
		    CompilationUnit.prototype.resolve = function (p) {
		        var unit = this._project.resolve(this._path, p);
		        return unit;
		    };
		    CompilationUnit.prototype.path = function () {
		        return this._path;
		    };
		    CompilationUnit.prototype.lexerErrors = function () {
		        if (this.errors == null) {
		            this.ast();
		        }
		        return this.errors;
		    };
		    CompilationUnit.prototype.ast = function () {
		        var _this = this;
		        if (this._node) {
		            return this._node;
		        }
		        try {
		            var result = parser.load(this._content, {});
		            this.errors = result.errors;
		            this.errors.forEach(function (x) {
		                if (x.mark) {
		                    x.mark.filePath = _this.absolutePath();
		                }
		            });
		            this._node = new ASTNode(result, this, null, null, null);
		            this._node._errors = this.errors;
		            return this._node;
		        }
		        catch (e) {
		            this.errors = [];
		            this.errors.push(new Error(e.message));
		            //console.log(this._content)
		            //console.log(e)
		            this._node = null;
		            return this._node;
		        }
		    };
		    CompilationUnit.prototype.isTopLevel = function () {
		        return this._tl;
		    };
		    CompilationUnit.prototype.updateContent = function (n) {
		        this._content = n;
		        this.errors = null;
		        this._node = null; //todo incremental update
		        this._lineMapper = null;
		    };
		    CompilationUnit.prototype.updateContentSafe = function (n) {
		        this._content = n;
		        this._lineMapper = null;
		    };
		    CompilationUnit.prototype.project = function () {
		        return this._project;
		    };
		    CompilationUnit.prototype.lineMapper = function () {
		        if (this._lineMapper == null) {
		            this._lineMapper = new lowlevel.LineMapperImpl(this.contents(), this.absolutePath());
		        }
		        return this._lineMapper;
		    };
		    return CompilationUnit;
		})();
		exports.CompilationUnit = CompilationUnit;
		var HTTPResolverImpl = (function () {
		    function HTTPResolverImpl() {
		        this.executor = new SimpleExecutor.SimpleExecutor();
		    }
		    HTTPResolverImpl.prototype.getResource = function (url) {
		        if (typeof atom !== 'undefined' && atom != null) {
		            var cached = rr.get(url);
		            if (cached) {
		                return cached;
		            }
		            rr.addNotify(url);
		            try {
		                this.getResourceAsync(url).then(function (x) {
		                    try {
		                        x.errorMessage = null;
		                        rr.set(url, x);
		                    }
		                    finally {
		                        rr.removeNotity(url);
		                    }
		                }, function (e) {
		                    rr.set(url, { content: null, errorMessage: null });
		                    rr.removeNotity(url);
		                    //do nothing.
		                });
		                return {
		                    content: ""
		                };
		            }
		            catch (e) {
		                console.log("Error");
		                console.log(e);
		            }
		        }
		        var response = this.executor.execute({
		            method: 'get',
		            url: url
		        });
		        if (!response) {
		            throw new Error("Unable to execute GET " + url);
		        }
		        var result = this.toResponse(response, url);
		        return result;
		    };
		    HTTPResolverImpl.prototype.getResourceAsync = function (url) {
		        var _this = this;
		        return this.executor.executeAsync({
		            method: 'get',
		            url: url
		        }).then(function (x) {
		            if (!x) {
		                return Promise.reject(new Error("Unable to execute GET " + url));
		            }
		            var result = _this.toResponse(x, url);
		            return result;
		        }, function (x) {
		            return Promise.reject(new Error("Unable to execute GET " + url));
		        });
		    };
		    HTTPResolverImpl.prototype.toResponse = function (response, url) {
		        var msg = null;
		        if (response.status >= 400) {
		            msg = "GET " + url + "\nreturned error: " + response.status;
		            if (response.statusText) {
		                msg += " " + response.statusText;
		            }
		        }
		        var content = null;
		        if (response.content && response.content.text) {
		            content = response.content.text;
		        }
		        var result = {
		            content: content,
		            errorMessage: msg
		        };
		        return result;
		    };
		    return HTTPResolverImpl;
		})();
		exports.HTTPResolverImpl = HTTPResolverImpl;
		var FSResolverImpl = (function () {
		    function FSResolverImpl() {
		    }
		    FSResolverImpl.prototype.content = function (path) {
		        if (!fs.existsSync(path)) {
		            return null;
		        }
		        try {
		            return fs.readFileSync(path).toString();
		        }
		        catch (e) {
		            return null;
		        }
		    };
		    FSResolverImpl.prototype.list = function (path) {
		        return fs.readdirSync(path);
		    };
		    FSResolverImpl.prototype.contentAsync = function (path) {
		        return new Promise(function (resolve, reject) {
		            fs.readFile(path, function (err, data) {
		                if (err != null) {
		                    return reject(err);
		                }
		                var content = data.toString();
		                resolve(content);
		            });
		        });
		    };
		    FSResolverImpl.prototype.listAsync = function (path) {
		        return new Promise(function (reject, resolve) {
		            fs.readdir(path, function (err, files) {
		                if (err != null) {
		                    return reject(err);
		                }
		                resolve(files);
		            });
		        });
		    };
		    return FSResolverImpl;
		})();
		exports.FSResolverImpl = FSResolverImpl;
		function copyNode(n) {
		    if (n == null) {
		        return null;
		    }
		    switch (n.kind) {
		        case 0 /* SCALAR */:
		            return {
		                errors: [],
		                startPosition: n.startPosition,
		                endPosition: n.endPosition,
		                value: n.value,
		                kind: 0 /* SCALAR */,
		                parent: n.parent
		            };
		        case 1 /* MAPPING */:
		            var map = n;
		            return {
		                errors: [],
		                key: copyNode(map.key),
		                value: copyNode(map.value),
		                startPosition: map.startPosition,
		                endPosition: map.endPosition,
		                kind: 1 /* MAPPING */,
		                parent: map.parent
		            };
		        case 2 /* MAP */:
		            var ymap = n;
		            return {
		                errors: [],
		                startPosition: n.startPosition,
		                endPosition: n.endPosition,
		                mappings: ymap.mappings.map(function (x) { return copyNode(x); }),
		                kind: 2 /* MAP */,
		                parent: ymap.parent
		            };
		    }
		    return n;
		}
		var innerShift = function (offset, yaNode, shift) {
		    if (!yaNode)
		        return;
		    if (yaNode.startPosition >= offset) {
		        yaNode.startPosition += shift;
		    }
		    if (yaNode.endPosition > offset) {
		        yaNode.endPosition += shift;
		    }
		    //this kind is a separate case
		    if (yaNode.kind == 1 /* MAPPING */) {
		        var m = yaNode;
		        innerShift(offset, m.key, shift);
		        innerShift(offset, m.value, shift);
		    }
		};
		function splitOnLines(text) {
		    var lines = text.match(/^.*((\r\n|\n|\r)|$)/gm);
		    return lines;
		}
		//TODO IMPROVE INDENTS
		function stripIndent(text, indent) {
		    var lines = splitOnLines(text);
		    var rs = [];
		    for (var i = 0; i < lines.length; i++) {
		        if (i == 0) {
		            rs.push(lines[0]);
		        }
		        else {
		            rs.push(lines[i].substring(indent.length));
		        }
		    }
		    return rs.join("");
		}
		var leadingIndent = function (node, text) {
		    var leading = "";
		    var pos = node.start() - 1;
		    while (pos > 0) {
		        var ch = text[pos];
		        //if (ch == '\r' || ch == '\n' || ch != ' ') break;
		        //console.log('char: [' + ch + ']');
		        if (ch != ' ' && ch != '-')
		            break;
		        leading = ' ' + leading;
		        pos--;
		    }
		    return leading;
		};
		function indent(line) {
		    var rs = "";
		    for (var i = 0; i < line.length; i++) {
		        var c = line[i];
		        if (c == '\r' || c == '\n') {
		            continue;
		        }
		        if (c == ' ' || c == '\t') {
		            rs += c;
		            continue;
		        }
		        break;
		    }
		    return rs;
		}
		function indentLines(s, indent) {
		    return s.split("\n").map(function (x) {
		        if (x.trim().length == 0) {
		            return x;
		        }
		        return indent + x;
		    }).join("\n");
		}
		function extraIndent(text, indent) {
		    var lines = splitOnLines(text);
		    var rs = [];
		    for (var i = 0; i < lines.length; i++) {
		        if (i == 0) {
		            rs.push(lines[0]);
		        }
		        else {
		            if (lines[i].trim().length > 0) {
		                rs.push(indent + lines[i]);
		            }
		            else {
		                rs.push("");
		            }
		        }
		    }
		    return rs.join("");
		}
		var Project = (function () {
		    /**
		     *
		     * @param rootPath - path to folder where your root api is located
		     * @param resolver
		     * @param _httpResolver
		     */
		    function Project(rootPath, resolver, _httpResolver) {
		        this.rootPath = rootPath;
		        this.resolver = resolver;
		        this._httpResolver = _httpResolver;
		        this.listeners = [];
		        this.tlisteners = [];
		        this.pathToUnit = {};
		        if (this.resolver == null) {
		            this.resolver = new FSResolverImpl();
		        }
		        if (this._httpResolver == null) {
		            this._httpResolver = new HTTPResolverImpl();
		        }
		    }
		    Project.prototype.cloneWithResolver = function (newResolver, httpResolver) {
		        if (httpResolver === void 0) { httpResolver = null; }
		        var newProject = new Project(this.rootPath, newResolver, httpResolver ? httpResolver : this._httpResolver);
		        for (var unitPath in this.pathToUnit) {
		            newProject.pathToUnit[unitPath] = this.pathToUnit[unitPath].cloneToProject(newProject);
		        }
		        return newProject;
		    };
		    Project.prototype.setCachedUnitContent = function (pth, cnt, tl) {
		        if (tl === void 0) { tl = true; }
		        var relPath = pth;
		        var apath = toAbsolutePath(this.rootPath, pth);
		        var unit = new CompilationUnit(relPath, cnt, tl, this, apath);
		        this.pathToUnit[apath] = unit;
		        return unit;
		    };
		    Project.prototype.resolveAsync = function (unitPath, pathInUnit) {
		        if (!pathInUnit) {
		            return Promise.reject(new Error("Unit path is null"));
		        }
		        if (isWebPath(pathInUnit) || path.isAbsolute(pathInUnit)) {
		            return this.unitAsync(pathInUnit, true);
		        }
		        else if (isWebPath(unitPath) || path.isAbsolute(unitPath)) {
		            var absPath = toAbsolutePath(path.dirname(unitPath), pathInUnit);
		            return this.unitAsync(absPath, true);
		        }
		        var absPath = toAbsolutePath(path.dirname(toAbsolutePath(this.rootPath, unitPath)), pathInUnit);
		        return this.unitAsync(absPath, true);
		    };
		    Project.prototype.resolve = function (unitPath, pathInUnit) {
		        if (!pathInUnit) {
		            return null;
		        }
		        if (isWebPath(pathInUnit) || path.isAbsolute(pathInUnit)) {
		            return this.unit(pathInUnit, true);
		        }
		        else if (isWebPath(unitPath) || path.isAbsolute(unitPath)) {
		            var absPath = toAbsolutePath(path.dirname(unitPath), pathInUnit);
		            return this.unit(absPath, true);
		        }
		        var absPath = toAbsolutePath(path.dirname(toAbsolutePath(this.rootPath, unitPath)), pathInUnit);
		        return this.unit(absPath, true);
		    };
		    Project.prototype.units = function () {
		        var _this = this;
		        if (!this.resolver.list) {
		            throw new Error("Provided FSResolver is unable to list files. Please, use ExtendedFSResolver.");
		        }
		        var names = this.resolver.list(this.rootPath).filter(function (x) { return path.extname(x) == '.raml'; });
		        return names.map(function (x) { return _this.unit(x); }).filter(function (y) { return y.isTopLevel(); });
		    };
		    Project.prototype.unitsAsync = function () {
		        var _this = this;
		        if (!this.resolver.listAsync) {
		            return Promise.reject(new Error("Provided FSResolver is unable to list files. Please, use ExtendedFSResolver."));
		        }
		        return this.resolver.listAsync(this.rootPath).then(function (x) {
		            var promises = x.filter(function (x) { return path.extname(x) == '.raml'; }).map(function (x) { return _this.unitAsync(x).then(function (x) {
		                return x.isTopLevel() ? x : null;
		            }, function (x) {
		                return null;
		            }); });
		            return Promise.all(promises).then(function (arr) {
		                return arr.filter(function (x) { return x != null; });
		            });
		        });
		    };
		    Project.prototype.lexerErrors = function () {
		        var results = [];
		        this.units().forEach(function (x) {
		            results = results.concat(x.lexerErrors());
		        });
		        return results;
		    };
		    Project.prototype.deleteUnit = function (p, absolute) {
		        if (absolute === void 0) { absolute = false; }
		        var apath = null;
		        if (isWebPath(p)) {
		            apath = p;
		        }
		        else {
		            apath = absolute ? p : toAbsolutePath(this.rootPath, p);
		        }
		        delete this.pathToUnit[apath];
		    };
		    Project.prototype.unit = function (p, absolute) {
		        if (absolute === void 0) { absolute = false; }
		        var cnt = null;
		        var apath = p;
		        if (isWebPath(p)) {
		            if (this.pathToUnit[apath]) {
		                return this.pathToUnit[apath];
		            }
		            if (this._httpResolver) {
		                var resp = this._httpResolver.getResource(p);
		                if (resp.errorMessage) {
		                    throw new Error(resp.errorMessage);
		                }
		                cnt = resp.content;
		            }
		            else {
		                cnt = new HTTPResolverImpl().getResource(apath).content;
		            }
		        }
		        else {
		            if (p.charAt(0) == '/' && !absolute) {
		                p = p.substr(1); //TODO REVIEW IT
		            }
		            var apath = toAbsolutePath(this.rootPath, p);
		            if (this.pathToUnit[apath]) {
		                return this.pathToUnit[apath];
		            }
		            if (isWebPath(apath)) {
		                if (this._httpResolver) {
		                    var resp = this._httpResolver.getResource(apath);
		                    if (resp.errorMessage) {
		                        throw new Error(resp.errorMessage);
		                    }
		                    cnt = resp.content;
		                }
		                else {
		                    cnt = new HTTPResolverImpl().getResource(apath).content;
		                }
		            }
		            else {
		                cnt = this.resolver.content(apath);
		            }
		        }
		        if (cnt == null) {
		            return null;
		        }
		        var tl = util.stringStartsWith(cnt, "#%RAML");
		        var relPath = (isWebPath(this.rootPath) == isWebPath(apath)) ? path.relative(this.rootPath, apath) : apath;
		        var unit = new CompilationUnit(relPath, cnt, tl, this, apath);
		        this.pathToUnit[apath] = unit;
		        return unit;
		    };
		    Project.prototype.unitAsync = function (p, absolute) {
		        var _this = this;
		        if (absolute === void 0) { absolute = false; }
		        var cnt = null;
		        var apath = p;
		        if (isWebPath(p)) {
		            if (this.pathToUnit[apath]) {
		                return Promise.resolve(this.pathToUnit[apath]);
		            }
		            if (this._httpResolver) {
		                var resp = this._httpResolver.getResourceAsync(apath);
		                cnt = resp.then(function (x) {
		                    if (x.errorMessage) {
		                        return Promise.reject(new Error(x.errorMessage));
		                    }
		                    return x.content;
		                });
		            }
		            else {
		                cnt = new HTTPResolverImpl().getResourceAsync(apath);
		            }
		        }
		        else {
		            if (p.charAt(0) == '/' && !absolute) {
		                p = p.substr(1); //TODO REVIEW IT
		            }
		            if (absolute) {
		                apath = p;
		            }
		            else {
		                apath = toAbsolutePath(this.rootPath, p);
		            }
		            if (this.pathToUnit[apath]) {
		                return Promise.resolve(this.pathToUnit[apath]);
		            }
		            if (isWebPath(apath)) {
		                if (this._httpResolver) {
		                    var resp = this._httpResolver.getResourceAsync(apath);
		                    cnt = resp.then(function (x) {
		                        if (x.errorMessage) {
		                            return Promise.reject(new Error(x.errorMessage));
		                        }
		                        return x.content;
		                    });
		                }
		                else {
		                    cnt = new HTTPResolverImpl().getResourceAsync(apath);
		                }
		            }
		            else {
		                cnt = this.resolver.contentAsync(apath);
		            }
		        }
		        if (cnt == null) {
		            return Promise.resolve(null);
		        }
		        var relPath = (isWebPath(this.rootPath) == isWebPath(apath)) ? path.relative(this.rootPath, apath) : apath;
		        return cnt.then(function (x) {
		            if (!x) {
		                return Promise.reject(new Error("Can note resolve " + apath));
		            }
		            var tl = util.stringStartsWith(x, "#%RAML");
		            var unit = new CompilationUnit(relPath, x, tl, _this, apath);
		            _this.pathToUnit[apath] = unit;
		            return unit;
		        });
		    };
		    Project.prototype.visualizeNewlines = function (s) {
		        var res = '';
		        for (var i = 0; i < s.length; i++) {
		            var ch = s[i];
		            if (ch == '\r')
		                ch = '\\r';
		            if (ch == '\n')
		                ch = '\\n';
		            res += ch;
		        }
		        return res;
		    };
		    Project.prototype.indent = function (node) {
		        //node.show('NODE');
		        var text = node.unit().contents();
		        //console.log('node text: ' + textutil.replaceNewlines(text.substring(node.start(), node.end())));
		        //console.log('node parent: ' + node.parent());
		        //console.log('node unit: ' + node.unit());
		        if (node == node.root()) {
		            //console.log('node is root');
		            return '';
		        }
		        var leading = leadingIndent(node, text);
		        //console.log('leading: [' + leading + '] ' + leading.length);
		        var dmp = splitOnLines(node.dump());
		        if (dmp.length > 1) {
		            if (dmp[1].trim().length > 0) {
		                //console.log('DMP0: [' + dmp[0] + ']');
		                //console.log('DMP1: [' + dmp[1] + ']');
		                var extra = indent(dmp[1]);
		                return leading + extra;
		            }
		        }
		        //console.log('LEADING: [' + this.visualizeNewlines(leading) + '] ');
		        return leading + '  ';
		    };
		    Project.prototype.startIndent = function (node) {
		        var text = node.unit().contents();
		        //console.log('Node text:\n' + this.visualizeNewlines(text.substring(node.start(), node.end())));
		        if (node == node.root())
		            return '';
		        var dmp = splitOnLines(node.dump());
		        if (dmp.length > 0) {
		            console.log('FIRST: ' + dmp[0]);
		            var extra = indent(dmp[0]);
		            return extra + '  ';
		        }
		        //console.log('LEADING: [' + this.visualizeNewlines(leading) + '] ');
		        return '';
		    };
		    Project.prototype.canWriteInOneLine = function (node) {
		        return false;
		    };
		    Project.prototype.isOneLine = function (node) {
		        return node.text().indexOf('\n') < 0;
		    };
		    Project.prototype.recalcPositionsUp = function (target) {
		        var np = target;
		        while (np) {
		            np.recalcEndPositionFromChilds();
		            np = np.parent();
		        }
		    };
		    Project.prototype.add2 = function (target, node, toSeq, ipoint, json) {
		        if (json === void 0) { json = false; }
		        var unit = target.unit();
		        var api = target.root();
		        //console.log('api: ' + api);
		        var point = null;
		        if (ipoint) {
		            if (ipoint instanceof ASTNode) {
		                //console.log('insertion: ast node');
		                point = ipoint;
		            }
		            if (ipoint instanceof InsertionPoint) {
		                //console.log('insertion: ip');
		                point = ipoint.point;
		            }
		        }
		        //console.log('target: ' + target.kindName() + '/' + target.valueKindName() + ' node: ' + node.kindName());
		        //if(point) point.show('POINT:');
		        if (target.isValueInclude()) {
		            //console.log('insert to include ref');
		            var childs = target.children();
		            if (childs.length == 0) {
		                throw new Error("not implemented: insert into empty include ref");
		            }
		            var parent = childs[0].parent();
		            //console.log('parent: ' + parent);
		            //parent.show('INCLUDE PARENT:');
		            this.add2(parent, node, toSeq, point, json);
		            return;
		        }
		        var range = new textutil.TextRange(unit.contents(), node.start(), node.end());
		        var targetRange = new textutil.TextRange(unit.contents(), target.start(), target.end());
		        var unitText = target.unit().contents();
		        if (target.valueKind() == 3 /* SEQ */) {
		            target = createSeq(target.valueAsSeq(), target, target.unit());
		        }
		        var json = this.isJson(target);
		        //console.log('target: ' + target.start() + '..' + target.end());
		        var originalIndent = json ? '' : this.indent(target.isSeq() ? target.parent() : target);
		        //console.log('indent: [' + originalIndent + '] ' + originalIndent.length + '; toseq: ' + toSeq + '; json: ' + json);
		        var xindent = originalIndent;
		        var indentLength = originalIndent.length;
		        var isTargetSeq = target.isSeq() || target.isMapping() && (target.isValueSeq() || target.isValueScalar() || !target.asMapping().value); //target.valueKind() == yaml.Kind.SEQ || target.isSeq();
		        //toSeq = false;
		        //console.log('target: ' + target.kindName() + '/' + yaml.Kind[target.valueKind()] + '; toseq: ' + toSeq);
		        //target.root().show("API:");
		        //target.show("TARGET:");
		        //console.log('oindent: ' + originalIndent.length);
		        toSeq = toSeq; // || isTargetSeq;
		        if (toSeq) {
		            if (json) {
		            }
		            else {
		                if (isTargetSeq) {
		                    xindent += "  ";
		                    indentLength += 2;
		                }
		            }
		        }
		        //console.log('xindent: ' + xindent.length);
		        var buf = new MarkupIndentingBuffer(xindent);
		        //target.show('TARGET:');
		        //node.show('NODE1');
		        node.markupNode(buf, node._actualNode(), 0, json);
		        var text = buf.text;
		        //node.show('NODE2', 0, text);
		        //console.log('TEXT TO ADD0: ' + textutil.replaceNewlines(text));
		        if (toSeq) {
		            //if(target.valueKind() == yaml.Kind.SEQ) {
		            var trimText = textutil.trimEnd(text);
		            var trimLen = text.length - trimText.length;
		            if (trimLen > 0) {
		                //console.log('trim len: ' + trimLen);
		                var textlen = text.length;
		                text = text.substring(0, textlen - trimLen);
		                node.shiftNodes(textlen - trimLen, -trimLen);
		            }
		        }
		        //target.show('TARGET2');
		        //node.show('NODE2', 0, text);
		        //console.log('TEXT TO ADD1: ' + textutil.replaceNewlines(text));
		        //console.log('TEXT TO ADD:\n' + this.visualizeNewlines(text));
		        //console.log('toseq: ' + toSeq);
		        if (toSeq && !json) {
		            if (node.highLevelNode()) {
		            }
		            //console.log('target: ' + target.kindName());
		            if (target.isMapping()) {
		            }
		            if (target.isSeq() || target.isMapping() && (target.isValueSeq() || target.isValueScalar() || !target.asMapping().value)) {
		                //console.log('--- make it seq');
		                text = originalIndent + '- ' + text;
		            }
		            else {
		                //console.log('--- keep it map');
		                text = originalIndent + text;
		            }
		        }
		        else {
		            text = originalIndent + text;
		        }
		        //console.log('TEXT TO ADD2: ' + textutil.replaceNewlines(text));
		        //target.show('TARGET3');
		        var pos = target.end();
		        //console.log('insert to target end: ' + pos+ ' ; point: ' + point);
		        if (point) {
		            //point.show("POINT");
		            if (point != target) {
		                pos = point.end();
		            }
		            else {
		                if (json && toSeq) {
		                }
		                else {
		                    pos = target.keyEnd() + 1;
		                    pos = new textutil.TextRange(unitText, pos, pos).extendAnyUntilNewLines().endpos();
		                }
		            }
		        }
		        else {
		            if (json && toSeq) {
		                var seq = target.asSeq();
		                if (seq) {
		                    if (seq.items.length > 0) {
		                        pos = seq.items[seq.items.length - 1].endPosition;
		                    }
		                    else {
		                        pos = seq.endPosition - 1;
		                    }
		                }
		            }
		            else {
		                if (ipoint && (ipoint instanceof InsertionPoint)) {
		                    //ipoint.show('insertion point provided');
		                    var ip = ipoint;
		                    if (ip.type == 1 /* START */) {
		                        pos = target.keyEnd() + 1;
		                        pos = new textutil.TextRange(unitText, pos, pos).extendAnyUntilNewLines().endpos();
		                    }
		                }
		            }
		        }
		        //console.log('insert poition: ' + pos);
		        var insertionRange = new textutil.TextRange(unitText, 0, pos);
		        pos = insertionRange.extendToNewlines().reduceSpaces().endpos();
		        if (json && target.isSeq()) {
		            var seq = target.asSeq();
		            if (seq.items.length > 0) {
		                text = ', ' + text;
		                indentLength += 2;
		            }
		        }
		        else if (pos > 0 && unitText[pos - 1] != '\n') {
		            text = "\n" + text;
		            indentLength++;
		        }
		        var suffixLen = 0;
		        if (toSeq && !json) {
		            text += '\n';
		            suffixLen++;
		        }
		        //console.log('FINAL TEXT TO ADD: [' + textutil.replaceNewlines(text) + '] at position ' + pos);
		        var newtext = unitText.substring(0, pos) + text + unitText.substring(pos, unitText.length);
		        var cu = unit;
		        cu.updateContentSafe(newtext);
		        this.executeReplace(new textutil.TextRange(unitText, pos, pos), text, cu);
		        //console.log('shift root from position: ' + pos);
		        target.root().shiftNodes(pos, indentLength + (node.end() - node.start()) + suffixLen);
		        //console.log('node len: ' + (node.end()-node.start()));
		        //console.log('text len: ' + text.length);
		        //(<ASTNode>target.root()).shiftNodes(pos, text.length+indentLength);
		        //target.show('TARGET2:');
		        //node.show('NODE TO ADD:');
		        if (point) {
		            var childs = target.children();
		            var index = -1;
		            for (var i = 0; i < childs.length; i++) {
		                var x = childs[i];
		                if (x.start() == point.start() && x.end() == point.end()) {
		                    index = i;
		                    break;
		                }
		            }
		            //console.log('index: ' + index);
		            if (index >= 0) {
		                target.addChild(node, index + 1);
		            }
		            else {
		                target.addChild(node);
		            }
		        }
		        else {
		            target.addChild(node);
		        }
		        node.shiftNodes(0, pos + indentLength);
		        //target.show('TARGET UPDATED:');
		        this.recalcPositionsUp(target);
		        //target.show('TARGET UPDATED POSITIONS:');
		        //api.show('ROOT UPDATED POSITIONS:');
		        node.setUnit(target.unit());
		        node.visit(function (n) {
		            var node = n;
		            node.setUnit(target.unit());
		            return true;
		        });
		    };
		    Project.prototype.isJsonMap = function (node) {
		        if (!node.isMap())
		            return false;
		        var text = node.text().trim();
		        return text.length >= 2 && text[0] == '{' && text[text.length - 1] == '}';
		    };
		    Project.prototype.isJsonSeq = function (node) {
		        if (!node.isSeq())
		            return false;
		        var text = node.text().trim();
		        return text.length >= 2 && text[0] == '[' && text[text.length - 1] == ']';
		    };
		    Project.prototype.isJson = function (node) {
		        return this.isJsonMap(node) || this.isJsonSeq(node);
		    };
		    Project.prototype.remove = function (unit, target, node) {
		        var parent = node.parent();
		        node._oldText = node.dump();
		        //node.showParents('PARENTS:');
		        //console.log('REMOVE NODE: ' + node.kindName() + ' from ' + target.kindName());
		        //console.log('INITIAL SELECTION: [' + textutil.replaceNewlines(range.text()) + ']');
		        //console.log('  text: \n' + unitText.substring(startpos,endpos));
		        if (this.isOneLine(node) && node.isMapping() && node.parent().isMap()) {
		            var mapnode = node.parent();
		            if (mapnode.asMap().mappings.length == 1 && mapnode.parent() != null) {
		                //console.log('REMOVE MAP INSTEAD!');
		                this.remove(unit, mapnode.parent(), mapnode);
		                return;
		            }
		        }
		        if (this.isOneLine(node) && node.isScalar() && node.parent().isSeq()) {
		            var seqnode = node.parent();
		            var seqn = seqnode.asSeq();
		            //console.log('SEQ: ' + seqn.items.length);
		            if (seqn.items.length == 1) {
		                //console.log('REMOVE SEQ INSTEAD!');
		                this.remove(unit, seqnode.parent(), seqnode);
		                return;
		            }
		        }
		        if (target.isMapping() && node.isSeq()) {
		            //console.log('remove seq from mapping');
		            var map = target.parent();
		            //console.log('REMOVE MAPPING INSTEAD!');
		            this.remove(unit, map, target);
		            return;
		        }
		        //target.show('TARGET:');
		        //node.show('NODE:');
		        var range = new textutil.TextRange(unit.contents(), node.start(), node.end());
		        var targetRange = new textutil.TextRange(unit.contents(), target.start(), target.end());
		        var parentRange = new textutil.TextRange(unit.contents(), parent.start(), parent.end());
		        var originalStartPos = range.startpos();
		        //console.log('REMOVE TEXT: ' +  this.visualizeNewlines(range.text()));
		        if (target.isSeq()) {
		            // extend range to start of line
		            //console.log('RANGE SEQ 0: ' + textutil.replaceNewlines(range.text()));
		            var seq = (node.isSeq() ? node : node.parentOfKind(3 /* SEQ */));
		            //console.log('seq: ' + seq.text() + ' json: ' + this.isJson(seq));
		            if (seq && this.isJson(seq)) {
		                range = range.extendSpaces().extendCharIfAny(',').extendSpaces();
		            }
		            else {
		                range = range.extendToStartOfLine().extendAnyUntilNewLines().extendToNewlines(); //
		            }
		        }
		        if (target.isMap()) {
		            // extend range to end of line
		            //console.log('RANGE MAP 0: [' +  this.visualizeNewlines(range.text()) + ']');
		            range = range.trimEnd().extendAnyUntilNewLines().extendToNewlines();
		            //console.log('RANGE MAP 1: [' +  this.visualizeNewlines(range.text()) + ']');
		            range = range.extendToStartOfLine().extendUntilNewlinesBack();
		        }
		        if (target.kind() == 1 /* MAPPING */) {
		            //console.log('RANGE MAPPING 0: ' +  this.visualizeNewlines(range.text()));
		            //console.log('NODE TEXT: ' + node.text());
		            if (this.isJson(node) && this.isOneLine(node)) {
		            }
		            else {
		                // extend range to end of line
		                //console.log('RANGE MAP 0: ' +  this.visualizeNewlines(range.text()));
		                range = range.extendSpacesUntilNewLines();
		                range = range.extendToNewlines();
		                //console.log('RANGE MAP 2: ' +  this.visualizeNewlines(range.text()));
		                range = range.extendToStartOfLine().extendUntilNewlinesBack();
		            }
		        }
		        if (node.isSeq()) {
		            //console.log('cleanup seq');
		            range = range.reduceSpaces();
		        }
		        //console.log('NODE:\n-----------\n' + range.unitText() + '\n-------------');
		        //console.log('TARGET: ' + target.kindName());
		        //target.show('TARGET');
		        //console.log('FINAL REMOVE TEXT: [' +  this.visualizeNewlines(range.text()) + ']');
		        //console.log('NEW TEXT:\n-----------\n' + range.remove() + '\n-------------');
		        var cu = unit;
		        cu.updateContentSafe(range.remove());
		        this.executeReplace(range, "", cu);
		        //node.parent().show('Before remove');
		        node.parent().removeChild(node);
		        var shift = -range.len();
		        //console.log('shift: ' + shift);
		        target.root().shiftNodes(originalStartPos, shift);
		        this.recalcPositionsUp(target);
		        //this.executeTextChange(new lowlevel.TextChangeCommand(range.startpos(), range.len(), "", unit))
		        //target.show('TARGET AFTER REMOVE:');
		        //target.root().show('API AFTER REMOVE:');
		    };
		    Project.prototype.changeKey = function (unit, attr, newval) {
		        //console.log('set key: ' + newval);
		        var range = new textutil.TextRange(attr.unit().contents(), attr.keyStart(), attr.keyEnd());
		        if (attr.kind() == 1 /* MAPPING */) {
		            var sc = attr._actualNode().key;
		            sc.value = newval;
		            sc.endPosition = sc.startPosition + newval.length;
		        }
		        var cu = unit;
		        this.executeReplace(range, newval, cu);
		        //console.log('new text: ' + this.visualizeNewlines(newtext));
		        var shift = newval.length - range.len();
		        //console.log('shift: ' + shift);
		        attr.root().shiftNodes(range.startpos(), shift, attr);
		        this.recalcPositionsUp(attr);
		    };
		    Project.prototype.executeReplace = function (r, txt, unit) {
		        var command = new lowlevel.TextChangeCommand(r.startpos(), r.endpos() - r.startpos(), txt, unit);
		        unit.project();
		        try {
		            this.tlisteners.forEach(function (x) { return x(command); });
		        }
		        catch (e) {
		            return false;
		        }
		        var newtext = r.replace(txt);
		        unit.updateContentSafe(newtext);
		        return true;
		    };
		    Project.prototype.changeValue = function (unit, attr, newval) {
		        //console.log('set value: ' + newval);mark
		        //console.log('ATTR ' + yaml.Kind[attr.kind()] + '; VALUE: ' + val + ' => ' + newval);
		        //attr.root().show('NODE:');
		        //console.log('TEXT:\n' + attr.unit().contents());
		        var range = new textutil.TextRange(attr.unit().contents(), attr.start(), attr.end());
		        //console.log('Range0: ' + range.startpos() + '..' + range.endpos() + ': [' + this.visualizeNewlines(range.text()) + ']');
		        //console.log('ATTR: ' + attr.kindName());
		        //attr.root().show('BEFORE');
		        var newNodeText;
		        var prefix = 0;
		        var delta = 0;
		        var replacer = null;
		        var mapping = null;
		        //console.log('attr: ' + attr.kindName());
		        if (attr.kind() == 0 /* SCALAR */) {
		            if (typeof newval == 'string') {
		                attr.asScalar().value = newval;
		                //range = range.withStart(attr.valueStart()).withEnd(attr.valueEnd());
		                //console.log('Range1: ' + this.visualizeNewlines(range.text()));
		                //console.log('Range0: ' + range.startpos() + '..' + range.endpos());
		                newNodeText = newval;
		            }
		            else {
		                throw new Error("not implemented");
		            }
		        }
		        else if (attr.kind() == 1 /* MAPPING */) {
		            //attr.show('ATTR:');
		            mapping = attr.asMapping();
		            //console.log('mapping val: ' + attr.valueKindName());
		            if (attr.isValueInclude()) {
		                var inc = attr.valueAsInclude();
		                var includeString = inc.value;
		                var includePath = refResolvers.getIncludePath(includeString);
		                //console.log("attr.setValue: path: " + includePath);
		                var resolved = attr.unit().resolve(includePath);
		                if (resolved == null) {
		                    console.log("attr.setValue: couldn't resolve: " + includePath);
		                    return; // "can not resolve "+includePath
		                }
		                //console.log("attr.setValue: resolved: " + includePath);
		                if (resolved.isRAMLUnit()) {
		                    //TODO DIFFERENT DATA TYPES, inner references
		                    return;
		                }
		                //TODO for now disabling an update from outline details to JSON schema when there is a reference
		                //to an inner element of the schema
		                if (!refResolvers.getIncludeReference(includeString)) {
		                    resolved.updateContent(newval);
		                }
		                return;
		            }
		            //console.log('Range0: ' + range.startpos() + '..' + range.endpos() + ': [' + this.visualizeNewlines(range.text()) + ']');
		            if (mapping.value)
		                range = range.withStart(attr.valueStart()).withEnd(attr.valueEnd());
		            else
		                range = range.withStart(attr.keyEnd() + 1).withEnd(attr.keyEnd() + 1);
		            //console.log('Range1: ' + range.startpos() + '..' + range.endpos());
		            range = range.reduceNewlinesEnd();
		            //console.log('Range2: ' + range.startpos() + '..' + range.endpos() + ': [' + this.visualizeNewlines(range.text()) + ']');
		            if (newval == null) {
		                newNodeText = '';
		                mapping.value = null;
		            }
		            else if (typeof newval == 'string' || newval == null) {
		                var newstr = newval;
		                var ind = this.indent(attr);
		                //console.log('indent: ' + ind.length);
		                if (newstr && textutil.isMultiLine(newstr)) {
		                    newstr = '' + textutil.makeMutiLine(newstr, ind.length / 2);
		                }
		                newNodeText = newstr;
		                //var valueNode = null;
		                if (!mapping.value) {
		                    console.log('no value');
		                    mapping.value = yaml.newScalar(newstr);
		                    mapping.value.startPosition = attr.keyEnd() + 1;
		                    mapping.value.endPosition = mapping.value.startPosition + newstr.length;
		                    mapping.endPosition = mapping.value.endPosition;
		                    if (unit.contents().length > attr.keyEnd() + 1) {
		                        var vlPos = attr.keyEnd() + 1;
		                        if (unit.contents()[vlPos - 1] == ':') {
		                            newNodeText = " " + newNodeText;
		                            mapping.value.startPosition++;
		                            mapping.value.endPosition++;
		                            mapping.endPosition++;
		                            delta++;
		                        }
		                    }
		                }
		                else if (mapping.value.kind == 3 /* SEQ */) {
		                    console.log('seq value');
		                    var v = mapping.value.items[0];
		                    throw "assign value!!!";
		                }
		                else if (mapping.value.kind == 0 /* SCALAR */) {
		                    //console.log('scalar value');
		                    var sc = mapping.value;
		                    var oldtext = sc.value;
		                    //console.log('oldval: ' + sc.value);
		                    //console.log('newstr: ' + newstr + ' ' + newstr.length);
		                    sc.value = newstr;
		                    //console.log('value1: ' + mapping.value.startPosition + '..' + mapping.value.endPosition);
		                    mapping.value.endPosition = mapping.value.startPosition + newstr.length;
		                    //console.log('value2: ' + mapping.value.startPosition + '..' + mapping.value.endPosition);
		                    mapping.endPosition = mapping.value.endPosition;
		                    //console.log('mvalue: ' + mapping.startPosition + '..' + mapping.endPosition);
		                    //console.log('newval: ' + sc.value);
		                    delta += newstr.length - oldtext.length;
		                }
		            }
		            else {
		                var n = newval;
		                if (n.isMapping()) {
		                    newval = createMap([n.asMapping()]);
		                    n = newval;
		                }
		                else if (n.isMap()) {
		                }
		                else {
		                    throw new Error("only MAP/MAPPING nodes allowed as values");
		                }
		                //n.show('NODE1');
		                var buf = new MarkupIndentingBuffer('');
		                n.markupNode(buf, n._actualNode(), 0, true);
		                //n.show('NODE2');
		                newNodeText = '' + buf.text + '';
		                //indent++;
		                //n.shiftNodes(0, 1);
		                //console.log('node text: [[[' + newNodeText + ']]]');
		                //n.show("NN1:", 0, newNodeText);
		                //range = mapping.value? range.withStart(attr.valueStart()).withEnd(attr.valueEnd()) : range.withStart(attr.keyEnd()+1).withEnd(attr.keyEnd()+1 + newNodeText);
		                n.shiftNodes(0, range.startpos() + delta);
		                //n.show("NN2:");
		                replacer = n;
		            }
		        }
		        else {
		            console.log('Unsupported change value case: ' + attr.kindName());
		        }
		        //console.log('RangeX: ' + range.startpos() + '..' + range.endpos() + ': [' + this.visualizeNewlines(range.text()) + ']');
		        //console.log('new node text: ' + newNodeText);
		        var cu = unit;
		        //console.log('Range1: ' + range.startpos() + '..' + range.endpos());
		        //console.log('replace: ' + range.len());
		        //console.log('Range: ' + range.startpos() + '..' + range.endpos());
		        //console.log('OldText: ' + this.visualizeNewlines(cu.contents()));
		        this.executeReplace(range, newNodeText, cu);
		        //var newtext = range.replace(newNodeText);
		        //console.log('NewText: ' + this.visualizeNewlines(newtext));
		        //cu.updateContentSafe(newtext);
		        var shift = newNodeText.length - range.len();
		        //var shift = delta;
		        //attr.root().show('BEFORE SHIFT');
		        //console.log('shift: ' + shift + '; from: ' + (range.endpos() + prefix) + '; delta: ' + delta + '; prefix: ' + prefix);
		        attr.root().shiftNodes(range.endpos() + prefix, shift, attr);
		        //(<ASTNode>attr.root()).shiftNodes(range.endpos()+indent, shift);
		        //attr.show('ATTR2:');
		        if (replacer) {
		            mapping.value = replacer._actualNode();
		        }
		        this.recalcPositionsUp(attr);
		    };
		    Project.prototype.initWithRoot = function (root, newroot) {
		        var shift = root.end();
		        newroot.markup(false);
		        newroot._actualNode().startPosition = shift;
		        newroot._actualNode().endPosition = shift;
		        newroot.setUnit(root.unit());
		    };
		    Project.prototype.execute = function (cmd) {
		        var _this = this;
		        //console.log('Commands: ' + cmd.commands.length);
		        cmd.commands.forEach(function (x) {
		            switch (x.kind) {
		                case 4 /* CHANGE_VALUE */:
		                    var attr = x.target;
		                    var curval = attr.value();
		                    if (!curval) {
		                        curval = "";
		                    }
		                    var newval = x.value;
		                    //console.log('set value: ' + (typeof curval) + ' ==> ' + (typeof newval));
		                    if (typeof curval == 'string' && typeof newval == 'string') {
		                        //console.log('set value: str => str');
		                        if (curval != newval) {
		                            _this.changeValue(attr.unit(), attr, newval);
		                        }
		                    }
		                    else if (typeof curval == 'string' && typeof newval != 'string') {
		                        //console.log('set value: str => obj');
		                        // change structure
		                        //this.changeValue(attr.unit(), attr, null);
		                        _this.changeValue(attr.unit(), attr, newval);
		                    }
		                    else if (typeof curval != 'string' && typeof newval == 'string') {
		                        var newstr = x.value;
		                        if (curval.kind() == 1 /* MAPPING */) {
		                            if (textutil.isMultiLine(newstr)) {
		                                //console.log('multiline');
		                                attr.children().forEach(function (n) {
		                                    _this.remove(attr.unit(), attr, n);
		                                });
		                                _this.changeValue(attr.unit(), attr, newstr);
		                            }
		                            else {
		                                //console.log('singleline');
		                                _this.changeKey(attr.unit(), curval, newstr);
		                            }
		                        }
		                        else {
		                            throw new Error('unsupported case: attribute value conversion: ' + (typeof curval) + ' ==> ' + (typeof newval) + ' not supported');
		                        }
		                    }
		                    else if (typeof curval != 'string' && typeof newval != 'string') {
		                        var newvalnode = newval;
		                        //(<ASTNode>curval).show("OLD:");
		                        //newvalnode.show("NEW:");
		                        if (newvalnode.isMapping()) {
		                            newval = createMap([newvalnode.asMapping()]);
		                        }
		                        //console.log('obj obj: ' + (curval == newval));
		                        if (curval == newval)
		                            break;
		                        // change structure
		                        //console.log('set value: obj => obj');
		                        var node = newval;
		                        var map = node.asMap();
		                        //console.log('attr: ' + attr.kindName() + " " + attr.dump());
		                        attr.children().forEach(function (n) {
		                            _this.remove(attr.unit(), attr, n);
		                        });
		                        node.children().forEach(function (m) {
		                            //this.add2(attr, <ASTNode>m, false, null, true);
		                        });
		                        _this.changeValue(attr.unit(), attr, newval);
		                    }
		                    else {
		                        throw new Error("shouldn't be this case: attribute value conversion " + (typeof curval) + ' ==> ' + (typeof newval) + ' not supported');
		                    }
		                    return;
		                case 3 /* CHANGE_KEY */:
		                    var attr = x.target;
		                    _this.changeKey(attr.unit(), attr, x.value);
		                    return;
		                case 0 /* ADD_CHILD */:
		                    var attr = x.target;
		                    var newValueNode = x.value;
		                    _this.add2(attr, newValueNode, x.toSeq, x.insertionPoint);
		                    return;
		                case 1 /* REMOVE_CHILD */:
		                    var target = x.target;
		                    var node = x.value;
		                    _this.remove(target.unit(), target, node);
		                    return;
		                case 5 /* INIT_RAML_FILE */:
		                    var root = x.target;
		                    var newroot = x.value;
		                    _this.initWithRoot(root, newroot);
		                    return;
		                default:
		                    console.log('UNSUPPORTED COMMAND: ' + lowlevel.CommandKind[x.kind]);
		                    return;
		            }
		        });
		    };
		    Project.prototype.replaceYamlNode = function (target, newNodeContent, offset, shift, unit) {
		        //console.log('New content:\n' + newNodeContent);
		        //target.show('OLD TARGET');
		        var newYamlNode = parser.load(newNodeContent, {});
		        //console.log('new yaml: ' + yaml.Kind[newYamlNode.kind]);
		        this.updatePositions(target.start(), newYamlNode);
		        //console.log('Shift: ' + shift);
		        //(<ASTNode>unit.ast()).shiftNodes(offset, shift);
		        target.root().shiftNodes(offset, shift);
		        var targetParent = target.parent();
		        var targetYamlNode = target._actualNode();
		        var parent = targetYamlNode.parent;
		        newYamlNode.parent = parent;
		        if (targetParent && targetParent.kind() == 2 /* MAP */) {
		            //console.log('MAP!!!');
		            var targetParentMapNode = targetParent._actualNode();
		            targetParentMapNode.mappings = targetParentMapNode.mappings.map(function (x) {
		                if (x != targetYamlNode) {
		                    return x;
		                }
		                return newYamlNode;
		            });
		        }
		        target.updateFrom(newYamlNode);
		        //target.show('MEW TARGET');
		        this.recalcPositionsUp(target);
		    };
		    Project.prototype.executeTextChange2 = function (textCommand) {
		        var cu = textCommand.unit;
		        var unitText = cu.contents();
		        var target = textCommand.target;
		        if (target) {
		            var cnt = unitText.substring(target.start(), target.end());
		            var original = unitText;
		            unitText = unitText.substr(0, textCommand.offset) + textCommand.text + unitText.substr(textCommand.offset + textCommand.replacementLength);
		            var newNodeContent = cnt.substr(0, textCommand.offset - target.start()) + textCommand.text + cnt.substr(textCommand.offset - target.start() + textCommand.replacementLength);
		            cu.updateContentSafe(unitText);
		            if (textCommand.offset > target.start()) {
		                try {
		                    var shift = textCommand.text.length - textCommand.replacementLength;
		                    var offset = textCommand.offset;
		                    target.unit().project().replaceYamlNode(target, newNodeContent, offset, shift, textCommand.unit);
		                }
		                catch (e) {
		                    console.log('New node contents (causes error below): \n' + newNodeContent);
		                    console.log('Reparse error: ' + e.stack);
		                }
		            }
		        }
		        else {
		            unitText = unitText.substr(0, textCommand.offset) + textCommand.text + unitText.substr(textCommand.offset + textCommand.replacementLength);
		        }
		        cu.updateContent(unitText);
		        this.listeners.forEach(function (x) {
		            x(null);
		        });
		        this.tlisteners.forEach(function (x) {
		            x(textCommand);
		        });
		    };
		    Project.prototype.executeTextChange = function (textCommand) {
		        var l0 = new Date().getTime();
		        try {
		            var oc = textCommand.unit.contents();
		            //console.log('Offset: ' + textCommand.offset + '; end: ' + (textCommand.offset + textCommand.replacementLength) + '; len: ' + textCommand.replacementLength);
		            var target = textCommand.target;
		            if (target == null) {
		                target = this.findNode(textCommand.unit.ast(), textCommand.offset, textCommand.offset + textCommand.replacementLength);
		            }
		            var cu = textCommand.unit;
		            if (target) {
		                var cnt = oc.substring(target.start(), target.end());
		                //console.log('Content: ' + cnt);
		                var original = oc;
		                oc = oc.substr(0, textCommand.offset) + textCommand.text + oc.substr(textCommand.offset + textCommand.replacementLength);
		                var newNodeContent = cnt.substr(0, textCommand.offset - target.start()) + textCommand.text + cnt.substr(textCommand.offset - target.start() + textCommand.replacementLength);
		                cu.updateContentSafe(oc);
		                //console.log('UPDATED TEXT: ' + oc);
		                var hasNewLines = breaksTheLine(original, textCommand);
		                if (textCommand.offset > target.start()) {
		                    try {
		                        var newYamlNode = parser.load(newNodeContent, {});
		                        this.updatePositions(target.start(), newYamlNode);
		                        //console.log("Positions updated")
		                        //lets shift all after it
		                        var shift = textCommand.text.length - textCommand.replacementLength;
		                        //console.log('shift: ' + shift);
		                        //console.log('offset: ' + textCommand.offset);
		                        textCommand.unit.ast().shiftNodes(textCommand.offset, shift);
		                        //console.log('Unit AST: ' + textCommand.unit.ast())
		                        if (newYamlNode != null && newYamlNode.kind == 2 /* MAP */) {
		                            var actualResult = newYamlNode.mappings[0];
		                            var targetYamlNode = target._actualNode();
		                            var parent = targetYamlNode.parent;
		                            var cmd = new lowlevel.ASTDelta();
		                            var unit = textCommand.unit;
		                            cmd.commands = [
		                                new lowlevel.ASTChangeCommand(4 /* CHANGE_VALUE */, new ASTNode(copyNode(targetYamlNode), unit, null, null, null), new ASTNode(actualResult, unit, null, null, null), 0)
		                            ];
		                            if (parent && parent.kind == 2 /* MAP */) {
		                                var map = parent;
		                                map.mappings = map.mappings.map(function (x) {
		                                    if (x != targetYamlNode) {
		                                        return x;
		                                    }
		                                    return actualResult;
		                                });
		                            }
		                            actualResult.parent = parent;
		                            //updating low level ast from yaml
		                            this.recalcPositionsUp(target);
		                            target.updateFrom(actualResult);
		                            //console.log("Incremental without listeners: "+(new Date().getTime()-l0));
		                            //console.log("Notify listeners1: " + this.listeners.length + ":" + this.tlisteners.length);
		                            this.listeners.forEach(function (x) {
		                                x(cmd);
		                            });
		                            this.tlisteners.forEach(function (x) {
		                                x(textCommand);
		                            });
		                            //console.log("Incremental update processed");
		                            return;
		                        }
		                    }
		                    catch (e) {
		                        console.log('New node contents (causes error below): \n' + newNodeContent);
		                        console.log('Reparse error: ' + e.stack);
		                    }
		                }
		            }
		            else {
		                oc = oc.substr(0, textCommand.offset) + textCommand.text + oc.substr(textCommand.offset + textCommand.replacementLength);
		            }
		            var t2 = new Date().getTime();
		            //console.log("Full without listeners:"+(t2-l0));
		            //!find node in scope
		            cu.updateContent(oc);
		            //console.log("Notify listeners2: " + this.listeners.length + ":" + this.tlisteners.length);
		            this.listeners.forEach(function (x) {
		                x(null);
		            });
		            this.tlisteners.forEach(function (x) {
		                x(textCommand);
		            });
		        }
		        finally {
		            var t2 = new Date().getTime();
		        }
		    };
		    Project.prototype.updatePositions = function (offset, n) {
		        var _this = this;
		        if (n == null) {
		            return;
		        }
		        if (n.startPosition == -1) {
		            n.startPosition = offset;
		        }
		        else {
		            n.startPosition = offset + n.startPosition;
		        }
		        n.endPosition = offset + n.endPosition;
		        switch (n.kind) {
		            case 2 /* MAP */:
		                var m = n;
		                m.mappings.forEach(function (x) { return _this.updatePositions(offset, x); });
		                break;
		            case 1 /* MAPPING */:
		                var ma = n;
		                this.updatePositions(offset, ma.key);
		                this.updatePositions(offset, ma.value);
		                break;
		            case 0 /* SCALAR */:
		                break;
		            case 3 /* SEQ */:
		                var s = n;
		                s.items.forEach(function (x) { return _this.updatePositions(offset, x); });
		                break;
		        }
		    };
		    Project.prototype.findNode = function (n, offset, end) {
		        var _this = this;
		        if (n == null) {
		            return null;
		        }
		        var node = n;
		        if (n.start() <= offset && n.end() >= end) {
		            var res = n;
		            node.directChildren().forEach(function (x) {
		                var m = _this.findNode(x, offset, end);
		                if (m) {
		                    res = m;
		                }
		            });
		            return res;
		        }
		        return null;
		    };
		    //shiftNodes(n:lowlevel.ILowLevelASTNode, offset:number, shift:number):lowlevel.ILowLevelASTNode{
		    //    var node:ASTNode=<ASTNode>n;
		    //    if (node==null){
		    //        return null;
		    //    }
		    //    node.directChildren().forEach(x=> {
		    //        var m = this.shiftNodes(x, offset, shift);
		    //    })
		    //    var yaNode=(<ASTNode>n)._actualNode();
		    //    if(yaNode) innerShift(offset, yaNode, shift);
		    //    return null;
		    //}
		    Project.prototype.addTextChangeListener = function (listener) {
		        this.tlisteners.push(listener);
		    };
		    Project.prototype.removeTextChangeListener = function (listener) {
		        this.tlisteners = this.tlisteners.filter(function (x) { return x != listener; });
		    };
		    Project.prototype.addListener = function (listener) {
		        this.listeners.push(listener);
		    };
		    Project.prototype.removeListener = function (listener) {
		        this.listeners = this.listeners.filter(function (x) { return x != listener; });
		    };
		    return Project;
		})();
		exports.Project = Project;
		function breaksTheLine(oc, textCommand) {
		    var oldText = oc.substr(textCommand.offset, textCommand.replacementLength);
		    if (oldText.indexOf('\n') != -1) {
		        return true;
		    }
		    if (textCommand.text.indexOf('\n') != -1) {
		        return true;
		    }
		}
		var ASTNode = (function () {
		    function ASTNode(_node, _unit, _parent, _anchor, _include, cacheChildren, _includesContents) {
		        if (cacheChildren === void 0) { cacheChildren = false; }
		        if (_includesContents === void 0) { _includesContents = false; }
		        this._node = _node;
		        this._unit = _unit;
		        this._parent = _parent;
		        this._anchor = _anchor;
		        this._include = _include;
		        this.cacheChildren = cacheChildren;
		        this._includesContents = _includesContents;
		        this._errors = [];
		        if (_node == null) {
		            console.log("null");
		        }
		    }
		    ASTNode.prototype.actual = function () {
		        return this._node;
		    };
		    ASTNode.prototype.yamlNode = function () {
		        return this._node;
		    };
		    ASTNode.prototype.includesContents = function () {
		        return this._includesContents;
		    };
		    ASTNode.prototype.setIncludesContents = function (includesContents) {
		        this._includesContents = includesContents;
		    };
		    ASTNode.prototype.gatherIncludes = function (s, inc, anc, inOneMemberMap) {
		        var _this = this;
		        if (s === void 0) { s = []; }
		        if (inc === void 0) { inc = null; }
		        if (anc === void 0) { anc = null; }
		        if (inOneMemberMap === void 0) { inOneMemberMap = true; }
		        if (this._node == null) {
		            return; //TODO FIXME
		        }
		        var kind = this._node.kind;
		        if (kind == 0 /* SCALAR */) {
		            return;
		        }
		        else if (kind == 2 /* MAP */) {
		            var map = this._node;
		            if (map.mappings.length == 1 && !inOneMemberMap) {
		                new ASTNode(map.mappings[0].value, this._unit, this, inc, anc, this.cacheChildren).gatherIncludes(s);
		            }
		            else {
		                map.mappings.map(function (x) { return new ASTNode(x, _this._unit, _this, anc ? anc : _this._anchor, inc ? inc : _this._include, _this.cacheChildren); }).forEach(function (x) { return x.gatherIncludes(s); });
		            }
		        }
		        else if (kind == 1 /* MAPPING */) {
		            var mapping = this._node;
		            if (mapping.value == null) {
		            }
		            else {
		                new ASTNode(mapping.value, this._unit, this, anc ? anc : this._anchor, inc ? inc : this._include, this.cacheChildren).gatherIncludes(s);
		            }
		        }
		        else if (kind == 3 /* SEQ */) {
		            var seq = this._node;
		            seq.items.filter(function (x) { return x != null; }).map(function (x) { return new ASTNode(x, _this._unit, _this, anc ? anc : _this._anchor, inc ? inc : _this._include, _this.cacheChildren); }).forEach(function (x) { return x.gatherIncludes(s); });
		        }
		        else if (kind == 5 /* INCLUDE_REF */) {
		            if (this._unit) {
		                s.push(this);
		            }
		        }
		    };
		    ASTNode.prototype.setHighLevelParseResult = function (highLevelParseResult) {
		        this._highLevelParseResult = highLevelParseResult;
		    };
		    ASTNode.prototype.highLevelParseResult = function () {
		        return this._highLevelParseResult;
		    };
		    ASTNode.prototype.setHighLevelNode = function (highLevel) {
		        this._highLevelNode = highLevel;
		    };
		    ASTNode.prototype.highLevelNode = function () {
		        return this._highLevelNode;
		    };
		    ASTNode.prototype.start = function () {
		        return this._node.startPosition;
		    };
		    ASTNode.prototype.errors = function () {
		        return this._errors;
		    };
		    ASTNode.prototype.parent = function () {
		        return this._parent;
		    };
		    ASTNode.prototype.recalcEndPositionFromChilds = function () {
		        var childs = this.children();
		        //if(this.children().length == 0) return;
		        var max = 0;
		        var first = this.children()[0];
		        var last = this.children()[this.children().length - 1];
		        //this.children().forEach(n=> {
		        //    var node: ASTNode = <ASTNode>n;
		        //    if(node._node.endPosition > max) max = node._node.endPosition;
		        //});
		        if (this.isMapping()) {
		            var mapping = this.asMapping();
		            //console.log('reposition: mapping');
		            if (mapping.value) {
		                if (mapping.value.kind == 2 /* MAP */) {
		                    var map = mapping.value;
		                    if (map.startPosition < 0 && first) {
		                        map.startPosition = first.start();
		                    }
		                    if (last)
		                        this._node.endPosition = last._node.endPosition;
		                    //console.log('embedded map: ' + map.startPosition + ".." + map.endPosition);
		                    this._node.endPosition = Math.max(this._node.endPosition, mapping.value.endPosition);
		                }
		                else if (mapping.value.kind == 3 /* SEQ */) {
		                    var seq = mapping.value;
		                    if (seq.startPosition < 0) {
		                        //console.log('*** missed start position');
		                        if (seq.items.length > 0) {
		                            var pos = seq.items[0].startPosition;
		                            var range = new textutil.TextRange(this.unit().contents(), pos, pos);
		                            range = range.extendSpacesBack().extendCharIfAnyBack('-');
		                            seq.startPosition = range.startpos();
		                        }
		                        else {
		                        }
		                    }
		                    //console.log('mapping1     : ' + mapping.startPosition + ".." + mapping.endPosition);
		                    //console.log('embedded seq1: ' + seq.startPosition + ".." + seq.endPosition);
		                    if (seq.items.length > 0) {
		                        var ilast = seq.items[seq.items.length - 1];
		                        this._node.endPosition = Math.max(this._node.endPosition, seq.endPosition, ilast.endPosition);
		                        seq.endPosition = Math.max(this._node.endPosition, seq.endPosition, ilast.endPosition);
		                    }
		                }
		                else if (mapping.value.kind == 0 /* SCALAR */) {
		                }
		                else {
		                    if (last)
		                        this._node.endPosition = last._node.endPosition;
		                }
		            }
		        }
		        else {
		            if (last)
		                this._node.endPosition = last._node.endPosition;
		        }
		        //this._node.endPosition = max;;
		    };
		    ASTNode.prototype.isValueLocal = function () {
		        if (this._node.kind == 1 /* MAPPING */) {
		            var knd = this._node.value.kind;
		            return knd != 5 /* INCLUDE_REF */ && knd != 4 /* ANCHOR_REF */;
		        }
		        return true;
		    };
		    ASTNode.prototype.keyStart = function () {
		        if (this._node.kind == 1 /* MAPPING */) {
		            return this._node.key.startPosition;
		        }
		        return -1;
		    };
		    ASTNode.prototype.keyEnd = function () {
		        if (this._node.kind == 1 /* MAPPING */) {
		            return this._node.key.endPosition;
		        }
		        return -1;
		    };
		    ASTNode.prototype.valueStart = function () {
		        if (this._node.kind == 1 /* MAPPING */) {
		            var mapping = this.asMapping();
		            if (mapping.value)
		                return mapping.value.startPosition;
		            else
		                return mapping.endPosition;
		        }
		        return -1;
		    };
		    ASTNode.prototype.valueEnd = function () {
		        if (this._node.kind == 1 /* MAPPING */) {
		            var mn = this.asMapping();
		            return mn.value.endPosition;
		        }
		        return -1;
		    };
		    ASTNode.prototype.end = function () {
		        return this._node.endPosition;
		    };
		    ASTNode.prototype.dump = function () {
		        if (this._oldText) {
		            return this._oldText;
		        }
		        if (this._unit && this._node.startPosition > 0 && this._node.endPosition > 0) {
		            var originalText = this._unit.contents().substring(this._node.startPosition, this._node.endPosition);
		            originalText = stripIndent(originalText, leadingIndent(this, this._unit.contents()));
		            //console.log("L:");
		            //console.log(originalText);
		            return originalText;
		        }
		        return dumper.dump(this.dumpToObject(), {});
		    };
		    ASTNode.prototype.dumpToObject = function (full) {
		        if (full === void 0) { full = false; }
		        return this.dumpNode(this._node, full);
		    };
		    ASTNode.prototype.dumpNode = function (n, full) {
		        var _this = this;
		        if (full === void 0) { full = false; }
		        if (!n) {
		            return null;
		        }
		        if (n.kind == 3 /* SEQ */) {
		            var seq = n;
		            var arr = [];
		            seq.items.forEach(function (x) { return arr.push(_this.dumpNode(x)); });
		            return arr;
		        }
		        if (n.kind == 1 /* MAPPING */) {
		            var c = n;
		            var v = {};
		            var val = c.value;
		            var mm = this.dumpNode(val, full);
		            v["" + this.dumpNode(c.key, full)] = mm;
		            return v;
		        }
		        if (n.kind == 0 /* SCALAR */) {
		            var s = n;
		            return s.value;
		        }
		        if (n.kind == 2 /* MAP */) {
		            var map = n;
		            var res = {};
		            if (map.mappings.length == 1) {
		                if (map.mappings[0].key.value == 'value') {
		                    return this.dumpNode(map.mappings[0].value, full);
		                }
		            }
		            if (map.mappings) {
		                map.mappings.forEach(function (x) {
		                    var ms = _this.dumpNode(x.value, full);
		                    if (ms == null) {
		                        ms = "!$$$novalue";
		                    }
		                    if ((ms + "").length > 0 || full) {
		                        res[_this.dumpNode(x.key, full) + ""] = ms;
		                    }
		                });
		            }
		            return res;
		        }
		    };
		    ASTNode.prototype.keyKind = function () {
		        if (this._node.key) {
		            return this._node.key.kind;
		        }
		        return null;
		    };
		    ASTNode.prototype._actualNode = function () {
		        return this._node;
		    };
		    ASTNode.prototype.execute = function (cmd) {
		        if (this.unit()) {
		            this.unit().project().execute(cmd);
		        }
		        else {
		            cmd.commands.forEach(function (x) {
		                switch (x.kind) {
		                    case 4 /* CHANGE_VALUE */:
		                        var attr = x.target;
		                        var newValue = x.value;
		                        var va = attr._actualNode();
		                        var as = attr.start();
		                        if (va.kind == 1 /* MAPPING */) {
		                            va.value = yaml.newScalar("" + newValue);
		                        }
		                        //this.executeTextChange(new lowlevel.TextChangeCommand(as,attr.value().length,<string>newValue,attr.unit()))
		                        return;
		                    case 3 /* CHANGE_KEY */:
		                        var attr = x.target;
		                        var newValue = x.value;
		                        var va = attr._actualNode();
		                        if (va.kind == 1 /* MAPPING */) {
		                            var sc = va.key;
		                            sc.value = newValue;
		                        }
		                        return;
		                }
		            });
		        }
		    };
		    ASTNode.prototype.updateFrom = function (n) {
		        this._node = n;
		    };
		    ASTNode.prototype.value = function () {
		        if (!this._node) {
		            return "";
		        }
		        if (this._node.kind == 0 /* SCALAR */) {
		            //TODO WHAT IS IT IS INCLUDE ACTUALLY
		            return this._node['value'];
		        }
		        if (this._node.kind == 4 /* ANCHOR_REF */) {
		            var ref = this._node;
		            return new ASTNode(ref.value, this._unit, this, null, null).value();
		        }
		        if (this._node.kind == 1 /* MAPPING */) {
		            var map = this._node;
		            if (map.value == null) {
		                return null;
		            }
		            return new ASTNode(map.value, this._unit, this, null, null).value();
		        }
		        if (this._node.kind == 5 /* INCLUDE_REF */) {
		            //here we should resolve include
		            var includeString = this._node['value'];
		            var includePath = refResolvers.getIncludePath(includeString);
		            var resolved = this._unit.resolve(includePath);
		            if (resolved == null) {
		                return "can not resolve " + includePath;
		            }
		            if (resolved.isRAMLUnit()) {
		                //TODO DIFFERENT DATA TYPES, inner references
		                return null;
		            }
		            var text = refResolvers.resolveContents(includeString, resolved.contents());
		            if (textutil.isMultiLineValue(text)) {
		                text = textutil.fromMutiLine(text);
		            }
		            return text;
		        }
		        if (this._node.kind == 2 /* MAP */) {
		            var amap = this._node;
		            if (amap.mappings.length == 1) {
		                //handle map with one member case differently
		                return new ASTNode(amap.mappings[0], this._unit, this, null, null);
		            }
		        }
		        if (this._node.kind == 3 /* SEQ */) {
		            var aseq = this._node;
		            if (aseq.items.length == 1 && true) {
		                //handle seq with one member case differently
		                return new ASTNode(aseq.items[0], this._unit, this, null, null).value();
		            }
		        }
		        //this are only kinds which has values
		        return null;
		    };
		    ASTNode.prototype.printDetails = function (indent) {
		        var result = "";
		        if (!indent)
		            indent = "";
		        var typeName = this.kindName();
		        if (this.kind() == 0 /* SCALAR */) {
		            result += indent + "[" + typeName + "]" + " " + this.value() + "\n";
		        }
		        else if (this.kind() == 1 /* MAPPING */ && this._node.value && this._node.value.kind == 0 /* SCALAR */) {
		            result += indent + "[" + typeName + "]" + " " + this.key() + " = " + this.value() + "\n";
		        }
		        else if (this.kind() == 1 /* MAPPING */) {
		            result += indent + "[" + typeName + "]" + " " + this.key() + " = :\n";
		            this.children().forEach(function (child) {
		                result += child.printDetails(indent + "\t");
		            });
		        }
		        else {
		            result += indent + "[" + typeName + "]" + " :\n";
		            this.children().forEach(function (child) {
		                result += child.printDetails(indent + "\t");
		            });
		        }
		        return result;
		    };
		    ASTNode.prototype.visit = function (v) {
		        this.children().forEach(function (x) {
		            if (v(x)) {
		                x.visit(v);
		            }
		        });
		    };
		    ASTNode.prototype.rawKey = function () {
		        if (!this._node) {
		            return "";
		        }
		        if (this._node.kind == 1 /* MAPPING */) {
		            var map = this._node;
		            if (map.key.kind == 3 /* SEQ */) {
		                var items = map.key;
		                var mn = "[";
		                items.items.forEach(function (x) { return mn += x.value; });
		                return mn + "]";
		            }
		            return map.key.value;
		        }
		        //other kinds do not have keys
		        return null;
		    };
		    ASTNode.prototype.key = function () {
		        var key = this.rawKey();
		        if (key != null && util.stringEndsWith(key, '?')) {
		            key = key.substring(0, key.length - 1);
		        }
		        return key;
		    };
		    ASTNode.prototype.optional = function () {
		        var key = this.rawKey();
		        return key != null && util.stringEndsWith(key, '?');
		    };
		    ASTNode.prototype.addChild = function (n, pos) {
		        if (pos === void 0) { pos = -1; }
		        //this.show('ADD TARGET:');
		        var node = n;
		        //console.log('add-child: ' + this.kindName() + ' .add ' + node.kindName());
		        node._parent = this;
		        this._oldText = null;
		        if (this.isMap()) {
		            //console.log('pos: ' + pos);
		            var map = this.asMap();
		            if (map.mappings == null || map.mappings == undefined) {
		                map.mappings = [];
		            }
		            if (pos >= 0) {
		                map.mappings.splice(pos, 0, node.asMapping());
		            }
		            else {
		                map.mappings.push(node.asMapping());
		            }
		        }
		        else if (this.isMapping()) {
		            var mapping = this.asMapping();
		            var val = mapping.value;
		            //console.log('mapping value: ' + val);
		            if (!mapping.value && node.isMap()) {
		                mapping.value = node._actualNode();
		                return;
		            }
		            if (mapping.value && mapping.value.kind == 0 /* SCALAR */) {
		                // cleanup old value
		                mapping.value = null;
		                val = null;
		            }
		            if (!val) {
		                if (node.isScalar() || node.highLevelNode() && node.highLevelNode().property().getAdapter(services.RAMLPropertyParserService).isEmbedMap()) {
		                    val = yaml.newSeq();
		                }
		                else {
		                    val = yaml.newMap();
		                }
		                mapping.value = val;
		            }
		            if (val.kind == 2 /* MAP */) {
		                var map = val;
		                if (map.mappings == null || map.mappings == undefined) {
		                    map.mappings = [];
		                }
		                if (node.isScalar()) {
		                }
		                if (pos >= 0) {
		                    map.mappings.splice(pos, 0, node.asMapping());
		                }
		                else {
		                    map.mappings.push(node.asMapping());
		                }
		            }
		            else if (val.kind == 3 /* SEQ */) {
		                var seq = val;
		                if (pos >= 0) {
		                    seq.items.splice(pos, 0, node._actualNode());
		                }
		                else {
		                    seq.items.push(node._actualNode());
		                }
		            }
		            else {
		                throw new Error("Insert into mapping with " + yaml.Kind[mapping.value.kind] + " value not supported");
		            }
		        }
		        else if (this.isSeq()) {
		            var seq = this.asSeq();
		            if (pos >= 0) {
		                seq.items.splice(pos, 0, node._actualNode());
		            }
		            else {
		                seq.items.push(node._actualNode());
		            }
		        }
		        else {
		            throw new Error("Insert into " + this.kindName() + " not supported");
		        }
		    };
		    ASTNode.prototype.removeChild = function (n) {
		        this._oldText = null;
		        var node = n;
		        var ynode;
		        var index;
		        //console.log('*** REMOVE FROM: ' + this.kindName());
		        if (this.kind() == 3 /* SEQ */) {
		            //console.log('remove from seq');
		            var seq = this.asSeq();
		            //val = <yaml.YamlMap>((<yaml.YAMLMapping>this._node).value);
		            ynode = node._node;
		            index = seq.items.indexOf(ynode);
		            if (index > -1)
		                seq.items.splice(index, 1);
		        }
		        else if (this.kind() == 2 /* MAP */) {
		            //val = <yaml.YamlMap>((<yaml.YAMLMapping>this._node).value);
		            var map = this.asMap();
		            //console.log('remove from map: ' + map.mappings.length);
		            ynode = node.asMapping();
		            index = map.mappings.indexOf(ynode);
		            //console.log('  index: ' + index);
		            if (index > -1)
		                map.mappings.splice(index, 1);
		        }
		        else if (this.kind() == 1 /* MAPPING */) {
		            //console.log('*** REMOVE FROM MAPPING');
		            //val = <yaml.YamlMap>((<yaml.YAMLMapping>this._node).value);
		            //console.log('remove from mapping with map as value');
		            var mapping = this.asMapping();
		            //this.show("REMOVE TARGET: ***");
		            //node.show("REMOVE NODE: ***");
		            if (node._actualNode() == mapping.value) {
		                // remove right from mapping
		                //console.log('*** remove map from mapping!');
		                mapping.value = null;
		            }
		            else {
		                var map = (mapping.value);
		                ynode = node.asMapping();
		                if (map && map.mappings) {
		                    index = map.mappings.indexOf(ynode);
		                    if (index > -1)
		                        map.mappings.splice(index, 1);
		                }
		            }
		        }
		        else {
		            throw new Error("Delete from " + yaml.Kind[this.kind()] + " unsupported");
		        }
		    };
		    ASTNode.prototype.includeErrors = function () {
		        if (this._node.kind == 1 /* MAPPING */) {
		            var mapping = this._node;
		            if (mapping.value == null) {
		                return [];
		            }
		            return new ASTNode(mapping.value, this._unit, this, this._anchor, this._include).includeErrors();
		        }
		        var rs = [];
		        if (this._node.kind == 5 /* INCLUDE_REF */) {
		            var mapping = this._node;
		            if (mapping.value == null) {
		                return [];
		            }
		            var includePath = this.includePath();
		            var resolved = this._unit.resolve(includePath);
		            if (resolved == null) {
		                rs.push("Can not resolve " + includePath);
		                return rs;
		            }
		            if (resolved.isRAMLUnit()) {
		                var ast = resolved.ast();
		                if (ast) {
		                    return [];
		                }
		                else {
		                    rs.push("" + includePath + " can not be parsed");
		                }
		            }
		            else if (this.includeReference()) {
		                var content = resolved.contents();
		                if (content) {
		                    var resolvedIncludeReference = refResolvers.resolve(includePath, this.includeReference(), content);
		                    if (resolvedIncludeReference && resolvedIncludeReference.validation && resolvedIncludeReference.validation.length > 0) {
		                        resolvedIncludeReference.validation.forEach(function (validationResult) { return rs.push(validationResult.message); });
		                    }
		                }
		            }
		        }
		        return rs;
		    };
		    ASTNode.prototype.children = function (inc, anc, inOneMemberMap) {
		        var _this = this;
		        if (inc === void 0) { inc = null; }
		        if (anc === void 0) { anc = null; }
		        if (inOneMemberMap === void 0) { inOneMemberMap = true; }
		        if (this._node == null) {
		            return []; //TODO FIXME
		        }
		        if (this.cacheChildren && this._children) {
		            return this._children;
		        }
		        var result;
		        var kind = this._node.kind;
		        if (kind == 0 /* SCALAR */) {
		            result = [];
		        }
		        else if (kind == 2 /* MAP */) {
		            var map = this._node;
		            if (map.mappings.length == 1 && !inOneMemberMap) {
		                //handle map with one member case differently
		                // q:
		                //  []
		                //   - a
		                //   - b
		                // ->
		                // q:
		                //  a
		                //  b
		                result = new ASTNode(map.mappings[0].value, this._unit, this, inc, anc, this.cacheChildren).children(null, null, true);
		            }
		            else {
		                result = map.mappings.map(function (x) { return new ASTNode(x, _this._unit, _this, anc ? anc : _this._anchor, inc ? inc : _this._include, _this.cacheChildren); });
		            }
		        }
		        else if (kind == 1 /* MAPPING */) {
		            var mapping = this._node;
		            if (mapping.value == null) {
		                result = [];
		            }
		            else {
		                var proxy = new ASTNode(mapping.value, this._unit, this, anc ? anc : this._anchor, inc ? inc : this._include, this.cacheChildren);
		                result = proxy.children();
		                if (proxy.includesContents()) {
		                    this.setIncludesContents(true);
		                }
		            }
		        }
		        else if (kind == 3 /* SEQ */) {
		            var seq = this._node;
		            result = seq.items.filter(function (x) { return x != null; }).map(function (x) { return new ASTNode(x, _this._unit, _this, anc ? anc : _this._anchor, inc ? inc : _this._include, _this.cacheChildren); });
		        }
		        else if (kind == 5 /* INCLUDE_REF */) {
		            if (this._unit) {
		                var includePath = this.includePath();
		                var resolved = this._unit.resolve(includePath);
		                if (resolved == null) {
		                    result = [];
		                }
		                else if (resolved.isRAMLUnit() && this.canInclude(resolved)) {
		                    var ast = resolved.ast();
		                    if (ast) {
		                        if (this.cacheChildren) {
		                            ast = toChildCahcingNode(ast);
		                        } //else {
		                        //    ast = <ASTNode>toIncludingNode(ast);
		                        //}
		                        result = resolved.ast().children(this, null);
		                        this.setIncludesContents(true);
		                    }
		                }
		            }
		            if (!result) {
		                result = [];
		            }
		        }
		        else if (kind == 4 /* ANCHOR_REF */) {
		            var ref = this._node;
		            result = new ASTNode(ref.value, this._unit, this, null, null, this.cacheChildren).children();
		        }
		        else {
		            throw new Error("Should never happen; kind : " + yaml.Kind[this._node.kind]);
		        }
		        if (this.cacheChildren) {
		            this._children = result;
		        }
		        return result;
		    };
		    ASTNode.prototype.canInclude = function (unit) {
		        var includedFrom = this.includedFrom();
		        while (includedFrom != null) {
		            if (includedFrom.unit().absolutePath() == unit.absolutePath()) {
		                return false;
		            }
		            includedFrom = includedFrom.includedFrom();
		        }
		        return true;
		    };
		    ASTNode.prototype.directChildren = function (inc, anc, inOneMemberMap) {
		        var _this = this;
		        if (inc === void 0) { inc = null; }
		        if (anc === void 0) { anc = null; }
		        if (inOneMemberMap === void 0) { inOneMemberMap = true; }
		        if (this._node) {
		            switch (this._node.kind) {
		                case 0 /* SCALAR */:
		                    return [];
		                case 2 /* MAP */:
		                    {
		                        var map = this._node;
		                        if (map.mappings.length == 1 && !inOneMemberMap) {
		                            //handle map with one member case differently
		                            return new ASTNode(map.mappings[0].value, this._unit, this, inc, anc).directChildren(null, null, true);
		                        }
		                        return map.mappings.map(function (x) { return new ASTNode(x, _this._unit, _this, anc ? anc : _this._anchor, inc ? inc : _this._include); });
		                    }
		                case 1 /* MAPPING */:
		                    {
		                        var mapping = this._node;
		                        if (mapping.value == null) {
		                            return [];
		                        }
		                        return new ASTNode(mapping.value, this._unit, this, anc ? anc : this._anchor, inc ? inc : this._include).directChildren();
		                    }
		                case 3 /* SEQ */:
		                    {
		                        var seq = this._node;
		                        return seq.items.filter(function (x) { return x != null; }).map(function (x) { return new ASTNode(x, _this._unit, _this, anc ? anc : _this._anchor, inc ? inc : _this._include); });
		                    }
		                case 5 /* INCLUDE_REF */:
		                    {
		                        return [];
		                    }
		                case 4 /* ANCHOR_REF */:
		                    {
		                        return [];
		                    }
		            }
		            throw new Error("Should never happen; kind : " + yaml.Kind[this._node.kind]);
		        }
		        return [];
		    };
		    ASTNode.prototype.anchorId = function () {
		        return this._node.anchorId;
		    };
		    ASTNode.prototype.unit = function () {
		        return this._unit;
		        //if(this._unit) return this._unit;
		        //if(!this.parent()) return null;
		        //return this.parent().unit();
		    };
		    ASTNode.prototype.setUnit = function (unit) {
		        this._unit = unit;
		    };
		    ASTNode.prototype.includePath = function () {
		        var includeString = this.getIncludeString();
		        if (!includeString) {
		            return null;
		        }
		        return refResolvers.getIncludePath(includeString);
		    };
		    ASTNode.prototype.includeReference = function () {
		        var includeString = this.getIncludeString();
		        if (!includeString) {
		            return null;
		        }
		        return refResolvers.getIncludeReference(includeString);
		    };
		    ASTNode.prototype.getIncludeString = function () {
		        if (this._node.kind == 5 /* INCLUDE_REF */) {
		            var includePath = this._node['value'];
		            return includePath;
		        }
		        else if (this._node.kind == 1 /* MAPPING */) {
		            var mapping = this._node;
		            if (mapping.value == null)
		                return null;
		            return new ASTNode(mapping.value, this._unit, this, null, null).getIncludeString();
		        }
		        return null;
		    };
		    ASTNode.prototype.anchoredFrom = function () {
		        return this._anchor;
		    };
		    ASTNode.prototype.includedFrom = function () {
		        return this._include;
		    };
		    ASTNode.prototype.kind = function () {
		        return this._actualNode().kind;
		    };
		    ASTNode.prototype.valueKind = function () {
		        if (this._node.kind != 1 /* MAPPING */) {
		            return null;
		        }
		        var map = this._node;
		        if (!map.value) {
		            return null;
		        }
		        return map.value.kind;
		    };
		    ASTNode.prototype.valueKindName = function () {
		        var kind = this.valueKind();
		        return kind != undefined ? yaml.Kind[kind] : null;
		    };
		    ASTNode.prototype.kindName = function () {
		        return yaml.Kind[this.kind()];
		    };
		    ASTNode.prototype.indent = function (lev, str) {
		        if (str === void 0) { str = ''; }
		        var leading = '';
		        for (var i = 0; i < lev; i++)
		            leading += '  ';
		        return leading + str;
		    };
		    ASTNode.prototype.replaceNewlines = function (s, rep) {
		        if (rep === void 0) { rep = null; }
		        var res = '';
		        for (var i = 0; i < s.length; i++) {
		            var ch = s[i];
		            if (ch == '\r')
		                ch = rep == null ? '\\r' : rep;
		            if (ch == '\n')
		                ch = rep == null ? '\\n' : rep;
		            res += ch;
		        }
		        return res;
		    };
		    ASTNode.prototype.shortText = function (unittext, maxlen) {
		        if (maxlen === void 0) { maxlen = 50; }
		        var elen = this.end() - this.start();
		        var len = elen;
		        //var len = Math.min(elen,50);
		        var unit = this.unit();
		        if (!unittext && unit) {
		            unittext = unit.contents();
		        }
		        var text;
		        if (!unittext) {
		            text = '[no-unit]';
		        }
		        else {
		            var s = unittext;
		            text = s ? s.substring(this.start(), this.end()) : '[no-text]';
		        }
		        text = "[" + this.start() + ".." + this.end() + "] " + elen + " // " + text + ' //';
		        if (len < elen)
		            text += '...';
		        text = this.replaceNewlines(text);
		        return text;
		    };
		    ASTNode.prototype.nodeShortText = function (node, unittext, maxlen) {
		        if (maxlen === void 0) { maxlen = 50; }
		        var elen = node.endPosition - node.startPosition;
		        var len = elen;
		        //var len = Math.min(elen,50);
		        var unit = this.unit();
		        if (!unittext && unit) {
		            unittext = unit.contents();
		        }
		        var text;
		        if (!unittext) {
		            text = '[no-unit]';
		        }
		        else {
		            var s = unittext;
		            text = s ? s.substring(node.startPosition, node.endPosition) : '[no-text]';
		        }
		        text = "[" + node.startPosition + ".." + node.endPosition + "] " + elen + " // " + text + ' //';
		        if (len < elen)
		            text += '...';
		        text = this.replaceNewlines(text);
		        return text;
		    };
		    ASTNode.prototype.show = function (message, lev, text) {
		        if (message === void 0) { message = null; }
		        if (lev === void 0) { lev = 0; }
		        if (text === void 0) { text = null; }
		        if (message && lev == 0) {
		            console.log(message);
		        }
		        var children = this.children();
		        var desc = this.kindName();
		        var val = this._actualNode().value;
		        if (this.kind() == 1 /* MAPPING */) {
		            desc += '[' + this._actualNode().key.value + ']';
		        }
		        if (val) {
		            desc += "/" + yaml.Kind[val.kind];
		        }
		        else
		            desc += "";
		        if (children.length == 0) {
		            //desc += "/" + this.value();
		            console.log(this.indent(lev) + desc + " // " + this.shortText(text));
		            if (this.isMapping() && this.asMapping().value) {
		                console.log(this.indent(lev + 1) + '// ' + this.valueKindName() + ': ' + this.nodeShortText(this.asMapping().value, text));
		            }
		        }
		        else {
		            console.log(this.indent(lev) + desc + " { // " + this.shortText(text));
		            if (this.isMapping() && this.asMapping().value) {
		                console.log(this.indent(lev + 1) + '// ' + this.valueKindName() + ': ' + this.nodeShortText(this.asMapping().value, text));
		            }
		            children.forEach(function (node) {
		                var n = node;
		                n.show(null, lev + 1, text);
		            });
		            console.log(this.indent(lev) + '}');
		        }
		    };
		    ASTNode.prototype.showParents = function (message, lev) {
		        if (lev === void 0) { lev = 0; }
		        if (message && lev == 0) {
		            console.log(message);
		        }
		        var depth = 0;
		        if (this.parent()) {
		            var n = this.parent();
		            depth = n.showParents(null, lev + 1);
		        }
		        var desc = this.kindName();
		        var val = this._actualNode().value;
		        if (val)
		            desc += "/" + yaml.Kind[val.kind];
		        else
		            desc += "/null";
		        console.log(this.indent(depth) + desc + " // " + this.shortText(null));
		        return depth + 1;
		    };
		    ASTNode.prototype.inlined = function (kind) {
		        return kind == 0 /* SCALAR */ || kind == 5 /* INCLUDE_REF */;
		    };
		    ASTNode.prototype.markupNode = function (xbuf, node, lev, json) {
		        if (json === void 0) { json = false; }
		        var start = xbuf.text.length;
		        switch (node.kind) {
		            case 2 /* MAP */:
		                if (json)
		                    xbuf.append('{');
		                var mappings = node.mappings;
		                for (var i = 0; i < mappings.length; i++) {
		                    if (json && i > 0)
		                        xbuf.append(', ');
		                    this.markupNode(xbuf, mappings[i], lev, json);
		                }
		                if (json)
		                    xbuf.append('}');
		                break;
		            case 3 /* SEQ */:
		                var items = node.items;
		                for (var i = 0; i < items.length; i++) {
		                    xbuf.append(this.indent(lev, '- '));
		                    //this.markupNode(xindent, pos+xbuf.text.length-(lev+1)*2, items[i], lev+1, xbuf);
		                    this.markupNode(xbuf, items[i], lev + 1, json);
		                }
		                break;
		            case 1 /* MAPPING */:
		                var mapping = node;
		                var val = mapping.value;
		                //console.log('mapping: ' + mapping.key.value + ' ' + val.kind);
		                if (json) {
		                    xbuf.append(mapping.key.value);
		                    xbuf.append(': ');
		                    if (val.kind == 0 /* SCALAR */) {
		                        var sc = val;
		                        xbuf.append(sc.value);
		                    }
		                    else if (val.kind == 2 /* MAP */) {
		                        //var mp = <yaml.YamlMap>val;
		                        this.markupNode(xbuf, mapping.value, lev + 1, json);
		                    }
		                    else {
		                        throw new Error("markup not implemented: " + yaml.Kind[val.kind]);
		                    }
		                    break;
		                }
		                xbuf.addWithIndent(lev, mapping.key.value + ':');
		                if (!val) {
		                    xbuf.append('\n');
		                    break;
		                }
		                if (val.kind == 0 /* SCALAR */) {
		                    var sc = val;
		                }
		                //xbuf.append(this.indent(lev, mapping.key.value + ':'));
		                if (mapping.value) {
		                    xbuf.append(this.inlined(mapping.value.kind) ? ' ' : '\n');
		                    this.markupNode(xbuf, mapping.value, lev + 1, json);
		                }
		                else {
		                    xbuf.append('\n');
		                }
		                break;
		            case 0 /* SCALAR */:
		                var sc = node;
		                if (textutil.isMultiLine(sc.value)) {
		                    xbuf.append('|\n');
		                    var lines = splitOnLines(sc.value);
		                    for (var i = 0; i < lines.length; i++) {
		                        xbuf.append(this.indent(lev, lines[i]));
		                    }
		                    xbuf.append('\n');
		                }
		                else {
		                    xbuf.append(sc.value + '\n');
		                }
		                break;
		            case 5 /* INCLUDE_REF */:
		                var ref = node;
		                xbuf.append('!include ' + ref.value + '\n');
		                break;
		            default:
		                throw new Error('Unknown node kind: ' + yaml.Kind[node.kind]);
		                break;
		        }
		        while (start < xbuf.text.length && xbuf.text[start] == ' ')
		            start++;
		        node.startPosition = start;
		        node.endPosition = xbuf.text.length;
		    };
		    ASTNode.prototype.markup = function (json) {
		        if (json === void 0) { json = false; }
		        var buf = new MarkupIndentingBuffer('');
		        this.markupNode(buf, this._actualNode(), 0, json);
		        return buf.text;
		    };
		    ASTNode.prototype.root = function () {
		        var node = this;
		        while (node.parent()) {
		            var p = node.parent();
		            //if(p.isValueInclude()) break; // stop on include
		            node = p;
		        }
		        return node;
		    };
		    ASTNode.prototype.parentOfKind = function (kind) {
		        var p = this.parent();
		        while (p) {
		            if (p.kind() == kind)
		                return p;
		            p = p.parent();
		        }
		        return null;
		    };
		    ASTNode.prototype.find = function (name) {
		        var found = null;
		        //console.log('Looking for: ' + name);
		        this.directChildren().forEach(function (y) {
		            if (y.key() && y.key() == name) {
		                if (!found)
		                    found = y;
		            }
		        });
		        return found;
		    };
		    ASTNode.prototype.shiftNodes = function (offset, shift, exclude) {
		        this.directChildren().forEach(function (x) {
		            if (exclude && exclude.start() == x.start() && exclude.end() == x.end()) {
		            }
		            else {
		                var m = x.shiftNodes(offset, shift, exclude);
		            }
		        });
		        if (exclude && exclude.start() == this.start() && exclude.end() == this.end()) {
		        }
		        else {
		            var yaNode = this._actualNode();
		            if (yaNode)
		                innerShift(offset, yaNode, shift);
		        }
		        return null;
		    };
		    ASTNode.prototype.isMap = function () {
		        return this.kind() == 2 /* MAP */;
		    };
		    ASTNode.prototype.isMapping = function () {
		        return this.kind() == 1 /* MAPPING */;
		    };
		    ASTNode.prototype.isSeq = function () {
		        return this.kind() == 3 /* SEQ */;
		    };
		    ASTNode.prototype.isScalar = function () {
		        return this.kind() == 0 /* SCALAR */;
		    };
		    ASTNode.prototype.asMap = function () {
		        if (!this.isMap())
		            throw new Error("map expected instead of " + this.kindName());
		        return (this._actualNode());
		    };
		    ASTNode.prototype.asMapping = function () {
		        if (!this.isMapping())
		            throw new Error("maping expected instead of " + this.kindName());
		        return (this._actualNode());
		    };
		    ASTNode.prototype.asSeq = function () {
		        if (!this.isSeq())
		            throw new Error("seq expected instead of " + this.kindName());
		        return (this._actualNode());
		    };
		    ASTNode.prototype.asScalar = function () {
		        if (!this.isScalar())
		            throw new Error("scalar expected instead of " + this.kindName());
		        return (this._actualNode());
		    };
		    ASTNode.prototype.isValueSeq = function () {
		        return this.valueKind() == 3 /* SEQ */;
		    };
		    ASTNode.prototype.isValueMap = function () {
		        return this.valueKind() == 2 /* MAP */;
		    };
		    ASTNode.prototype.isValueInclude = function () {
		        return this.valueKind() == 5 /* INCLUDE_REF */;
		    };
		    ASTNode.prototype.isValueScalar = function () {
		        return this.valueKind() == 0 /* SCALAR */;
		    };
		    ASTNode.prototype.valueAsSeq = function () {
		        if (!this.isMapping())
		            throw new Error("mapping expected instead of " + this.kindName());
		        if (this.valueKind() != 3 /* SEQ */)
		            throw new Error("mappng/seq expected instead of mapping/" + this.kindName());
		        return (this.asMapping().value);
		    };
		    ASTNode.prototype.valueAsMap = function () {
		        if (!this.isMapping())
		            throw new Error("mapping expected instead of " + this.kindName());
		        if (this.valueKind() != 2 /* MAP */)
		            throw new Error("mappng/map expected instead of mapping/" + this.kindName());
		        return (this.asMapping().value);
		    };
		    ASTNode.prototype.valueAsScalar = function () {
		        if (!this.isMapping())
		            throw new Error("mapping expected instead of " + this.kindName());
		        if (this.valueKind() != 0 /* SCALAR */)
		            throw new Error("mappng/scalar expected instead of mapping/" + this.kindName());
		        return (this.asMapping().value);
		    };
		    ASTNode.prototype.valueAsInclude = function () {
		        if (!this.isMapping())
		            throw new Error("mapping expected instead of " + this.kindName());
		        if (this.valueKind() != 5 /* INCLUDE_REF */)
		            throw new Error("mappng/include expected instead of mapping/" + this.kindName());
		        return (this.asMapping().value);
		    };
		    ASTNode.prototype.text = function (unitText) {
		        if (unitText === void 0) { unitText = null; }
		        if (!unitText) {
		            if (!this.unit())
		                return '[no-text]';
		            unitText = this.unit().contents();
		        }
		        return unitText.substring(this.start(), this.end());
		    };
		    ASTNode.prototype.copy = function () {
		        var yn = copyNode(this._actualNode());
		        return new ASTNode(yn, this._unit, this._parent, this._anchor, this._include, this._includesContents);
		    };
		    ASTNode.prototype.nodeDefinition = function () {
		        return getDefinitionForLowLevelNode(this);
		    };
		    return ASTNode;
		})();
		exports.ASTNode = ASTNode;
		(function (InsertionPointType) {
		    InsertionPointType[InsertionPointType["NONE"] = 0] = "NONE";
		    InsertionPointType[InsertionPointType["START"] = 1] = "START";
		    InsertionPointType[InsertionPointType["END"] = 2] = "END";
		    InsertionPointType[InsertionPointType["POINT"] = 3] = "POINT";
		})(exports.InsertionPointType || (exports.InsertionPointType = {}));
		var InsertionPointType = exports.InsertionPointType;
		var InsertionPoint = (function () {
		    function InsertionPoint(type, point) {
		        if (point === void 0) { point = null; }
		        this.type = type;
		        this.point = point;
		    }
		    InsertionPoint.after = function (point) {
		        return new InsertionPoint(3 /* POINT */, point);
		    };
		    InsertionPoint.atStart = function () {
		        return new InsertionPoint(1 /* START */);
		    };
		    InsertionPoint.atEnd = function () {
		        return new InsertionPoint(2 /* END */);
		    };
		    InsertionPoint.node = function () {
		        return new InsertionPoint(0 /* NONE */);
		    };
		    InsertionPoint.prototype.show = function (msg) {
		        if (msg) {
		            console.log(msg);
		            console.log('  insertion point type: ' + InsertionPointType[this.type]);
		        }
		        else {
		            console.log('insertion point type: ' + InsertionPointType[this.type]);
		        }
		        if (this.type == 3 /* POINT */ && this.point) {
		            this.point.show();
		        }
		    };
		    return InsertionPoint;
		})();
		exports.InsertionPoint = InsertionPoint;
		function createNode(key) {
		    //console.log('create node: ' + key);
		    var node = yaml.newMapping(yaml.newScalar(key), yaml.newMap());
		    return new ASTNode(node, null, null, null, null);
		}
		exports.createNode = createNode;
		function createMap(mappings) {
		    //console.log('create node: ' + key);
		    var node = yaml.newMap(mappings);
		    return new ASTNode(node, null, null, null, null);
		}
		exports.createMap = createMap;
		function createScalar(value) {
		    var node = yaml.newScalar(value);
		    return new ASTNode(node, null, null, null, null);
		}
		exports.createScalar = createScalar;
		function createSeq(sn, parent, unit) {
		    return new ASTNode(sn, unit, parent, null, null);
		}
		exports.createSeq = createSeq;
		/*
		export function createMappingWithMap(key:string, map: yaml.YAMLNode){
		    //console.log('create node: ' + key);
		    var node:yaml.YAMLNode=yaml.newMapping(yaml.newScalar(key),map);
		    return new ASTNode(node,null,null,null,null);
		}

		export function createMap(){
		    //console.log('create node: ' + key);
		    var node:yaml.YAMLNode=yaml.newMap();
		    return new ASTNode(node,null,null,null,null);
		}
		*/
		function createSeqNode(key) {
		    var node = yaml.newMapping(yaml.newScalar(key), yaml.newItems());
		    return new ASTNode(node, null, null, null, null);
		}
		exports.createSeqNode = createSeqNode;
		function createMapNode(key) {
		    var node = yaml.newMapping(yaml.newScalar(key), yaml.newMap());
		    return new ASTNode(node, null, null, null, null);
		}
		exports.createMapNode = createMapNode;
		function createMapping(key, v) {
		    //console.log('create mapping: ' + key);
		    var node = yaml.newMapping(yaml.newScalar(key), yaml.newScalar(v));
		    return new ASTNode(node, null, null, null, null);
		}
		exports.createMapping = createMapping;
		function toChildCahcingNode(node) {
		    if (!(node instanceof ASTNode)) {
		        return null;
		    }
		    var astNode = node;
		    var result = new ASTNode(astNode.yamlNode(), astNode.unit(), null, null, null, true);
		    result._errors = astNode._errors;
		    return result;
		}
		exports.toChildCahcingNode = toChildCahcingNode;
		function toIncludingNode(node) {
		    if (!(node instanceof ASTNode)) {
		        return null;
		    }
		    var astNode = node;
		    var result = new ASTNode(astNode.yamlNode(), astNode.unit(), null, null, null, false);
		    result._errors = astNode._errors;
		    return result;
		}
		exports.toIncludingNode = toIncludingNode;
		function getDefinitionForLowLevelNode(node) {
		    var hl = node.highLevelNode();
		    if (hl) {
		        return hl.definition();
		    }
		    var parent = node.parent();
		    if (!parent) {
		        return null;
		    }
		    var key = node.key();
		    if (!key) {
		        return null;
		    }
		    var parentDef = parent.nodeDefinition();
		    if (!parentDef) {
		        return null;
		    }
		    if (!parentDef.property) {
		        return null;
		    }
		    var prop = parentDef.property(key);
		    if (!prop) {
		        return null;
		    }
		    return prop.range();
		}
		exports.getDefinitionForLowLevelNode = getDefinitionForLowLevelNode;
		function fetchIncludesAsync(project, apiPath) {
		    var map = {};
		    var errors = {};
		    var nodes = [];
		    var units = [];
		    var processUnits = function (ind) {
		        var lMap = {};
		        while (ind < units.length) {
		            var unit = units[ind];
		            var unitPath = path.dirname(unit.absolutePath());
		            var includeNodes = unit.getIncludeNodes();
		            includeNodes.forEach(function (x) {
		                var ip = x.includePath();
		                var absIncludePath = toAbsolutePath(unitPath, ip);
		                if (map[absIncludePath]) {
		                    return;
		                }
		                if (errors[absIncludePath]) {
		                    x.errors().push(new Error(errors[ip]));
		                    return;
		                }
		                var arr = lMap[absIncludePath];
		                if (!arr) {
		                    arr = [];
		                    lMap[absIncludePath] = arr;
		                }
		                arr.push(x);
		            });
		            ind++;
		        }
		        var unitPaths = Object.keys(lMap);
		        if (unitPaths.length == 0) {
		            return Promise.resolve();
		        }
		        var promises = [];
		        unitPaths.forEach(function (unitPath) {
		            promises.push(project.unitAsync(unitPath).then(function (x) {
		                if (!map[x.absolutePath()]) {
		                    map[x.absolutePath()] = true;
		                    units.push(x);
		                }
		            }, function (x) {
		                lMap[unitPath].forEach(function (node) { return node.errors().push(new Error(x)); });
		                errors[unitPath] = x;
		            }));
		        });
		        return Promise.all(promises).then(function (x) {
		            return processUnits(ind);
		        });
		    };
		    return project.unitAsync(apiPath).then(function (x) {
		        units.push(x);
		        map[x.absolutePath()] = true;
		        return processUnits(0);
		    }).then(function (x) {
		        return units.length > 0 ? units[0] : null;
		    });
		}
		exports.fetchIncludesAsync = fetchIncludesAsync;
		function toAbsolutePath(rootPath, relPath) {
		    if (isWebPath(relPath)) {
		        return relPath;
		    }
		    var apath;
		    if (isWebPath(rootPath)) {
		        var rp = util.stringEndsWith(rootPath, "/") ? rootPath : rootPath + "/";
		        apath = URL.resolve(rp, relPath);
		    }
		    else {
		        apath = path.resolve(rootPath, relPath);
		    }
		    return apath;
		}
		function isWebPath(str) {
		    return util.stringStartsWith(str, "http://") || util.stringStartsWith(str, "https://");
		}


	/***/ },
	/* 16 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(2);

	/***/ },
	/* 17 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(4);

	/***/ },
	/* 18 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		'use strict';
		var loader = __webpack_require__(19);
		var dumper = __webpack_require__(47);
		function deprecated(name) {
		    return function () {
		        throw new Error('Function ' + name + ' is deprecated and cannot be used.');
		    };
		}
		exports.Type = __webpack_require__(24);
		exports.Schema = __webpack_require__(23);
		exports.FAILSAFE_SCHEMA = __webpack_require__(27);
		exports.JSON_SCHEMA = __webpack_require__(26);
		exports.CORE_SCHEMA = __webpack_require__(25);
		exports.DEFAULT_SAFE_SCHEMA = __webpack_require__(22);
		exports.DEFAULT_FULL_SCHEMA = __webpack_require__(42);
		exports.load = loader.load;
		exports.loadAll = loader.loadAll;
		exports.safeLoad = loader.safeLoad;
		exports.safeLoadAll = loader.safeLoadAll;
		exports.dump = dumper.dump;
		exports.safeDump = dumper.safeDump;
		exports.YAMLException = __webpack_require__(9);
		// Deprecared schema names from JS-YAML 2.0.x
		exports.MINIMAL_SCHEMA = __webpack_require__(27);
		exports.SAFE_SCHEMA = __webpack_require__(22);
		exports.DEFAULT_SCHEMA = __webpack_require__(42);
		// Deprecated functions from JS-YAML 1.x.x
		exports.scan = deprecated('scan');
		exports.parse = deprecated('parse');
		exports.compose = deprecated('compose');
		exports.addConstructor = deprecated('addConstructor');


	/***/ },
	/* 19 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../../typings/main.d.ts" />
		var ast = __webpack_require__(7);
		'use strict';
		/*eslint-disable max-len,no-use-before-define*/
		var common = __webpack_require__(20);
		var YAMLException = __webpack_require__(9);
		var Mark = __webpack_require__(21);
		var DEFAULT_SAFE_SCHEMA = __webpack_require__(22);
		var DEFAULT_FULL_SCHEMA = __webpack_require__(42);
		var _hasOwnProperty = Object.prototype.hasOwnProperty;
		var CONTEXT_FLOW_IN = 1;
		var CONTEXT_FLOW_OUT = 2;
		var CONTEXT_BLOCK_IN = 3;
		var CONTEXT_BLOCK_OUT = 4;
		var CHOMPING_CLIP = 1;
		var CHOMPING_STRIP = 2;
		var CHOMPING_KEEP = 3;
		var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/;
		var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
		var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
		var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
		var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
		function is_EOL(c) {
		    return (c === 0x0A) || (c === 0x0D);
		}
		function is_WHITE_SPACE(c) {
		    return (c === 0x09) || (c === 0x20);
		}
		function is_WS_OR_EOL(c) {
		    return (c === 0x09) || (c === 0x20) || (c === 0x0A) || (c === 0x0D);
		}
		function is_FLOW_INDICATOR(c) {
		    return 0x2C === c || 0x5B === c || 0x5D === c || 0x7B === c || 0x7D === c;
		}
		function fromHexCode(c) {
		    var lc;
		    if ((0x30 <= c) && (c <= 0x39)) {
		        return c - 0x30;
		    }
		    /*eslint-disable no-bitwise*/
		    lc = c | 0x20;
		    if ((0x61 <= lc) && (lc <= 0x66)) {
		        return lc - 0x61 + 10;
		    }
		    return -1;
		}
		function escapedHexLen(c) {
		    if (c === 0x78) {
		        return 2;
		    }
		    if (c === 0x75) {
		        return 4;
		    }
		    if (c === 0x55) {
		        return 8;
		    }
		    return 0;
		}
		function fromDecimalCode(c) {
		    if ((0x30 <= c) && (c <= 0x39)) {
		        return c - 0x30;
		    }
		    return -1;
		}
		function simpleEscapeSequence(c) {
		    return (c === 0x30) ? '\x00' : (c === 0x61) ? '\x07' : (c === 0x62) ? '\x08' : (c === 0x74) ? '\x09' : (c === 0x09) ? '\x09' : (c === 0x6E) ? '\x0A' : (c === 0x76) ? '\x0B' : (c === 0x66) ? '\x0C' : (c === 0x72) ? '\x0D' : (c === 0x65) ? '\x1B' : (c === 0x20) ? ' ' : (c === 0x22) ? '\x22' : (c === 0x2F) ? '/' : (c === 0x5C) ? '\x5C' : (c === 0x4E) ? '\x85' : (c === 0x5F) ? '\xA0' : (c === 0x4C) ? '\u2028' : (c === 0x50) ? '\u2029' : '';
		}
		function charFromCodepoint(c) {
		    if (c <= 0xFFFF) {
		        return String.fromCharCode(c);
		    }
		    // Encode UTF-16 surrogate pair
		    // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
		    return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, ((c - 0x010000) & 0x03FF) + 0xDC00);
		}
		var simpleEscapeCheck = new Array(256); // integer, for fast access
		var simpleEscapeMap = new Array(256);
		for (var i = 0; i < 256; i++) {
		    simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
		    simpleEscapeMap[i] = simpleEscapeSequence(i);
		}
		var State = (function () {
		    function State(input, options) {
		        this.errorMap = {};
		        this.errors = [];
		        this.input = input;
		        this.filename = options['filename'] || null;
		        this.schema = options['schema'] || DEFAULT_FULL_SCHEMA;
		        this.onWarning = options['onWarning'] || null;
		        this.legacy = options['legacy'] || false;
		        this.implicitTypes = this.schema.compiledImplicit;
		        this.typeMap = this.schema.compiledTypeMap;
		        this.length = input.length;
		        this.position = 0;
		        this.line = 0;
		        this.lineStart = 0;
		        this.lineIndent = 0;
		        this.documents = [];
		    }
		    return State;
		})();
		function generateError(state, message) {
		    return new YAMLException(message, new Mark(state.filename, state.input, state.position, state.line - 1, (state.position - state.lineStart)));
		}
		function throwError(state, message) {
		    //FIXME
		    var error = generateError(state, message);
		    var hash = error.message + error.mark.position;
		    if (!state.errorMap[hash]) {
		        state.errors.push(error);
		        state.errorMap[hash] = 1;
		    }
		    var or = state.position;
		    while (true) {
		        if (state.position >= state.input.length - 1) {
		            return;
		        }
		        var c = state.input.charAt(state.position);
		        if (c == '\n') {
		            state.position--;
		            if (state.position == or) {
		                state.position += 1;
		            }
		            return;
		        }
		        if (c == '\r') {
		            state.position--;
		            if (state.position == or) {
		                state.position += 1;
		            }
		            return;
		        }
		        state.position++;
		    }
		    //throw generateError(state, message);
		}
		function throwWarning(state, message) {
		    var error = generateError(state, message);
		    if (state.onWarning) {
		        state.onWarning.call(null, error);
		    }
		    else {
		    }
		}
		var directiveHandlers = {
		    YAML: function handleYamlDirective(state, name, args) {
		        var match, major, minor;
		        if (null !== state.version) {
		            throwError(state, 'duplication of %YAML directive');
		        }
		        if (1 !== args.length) {
		            throwError(state, 'YAML directive accepts exactly one argument');
		        }
		        match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
		        if (null === match) {
		            throwError(state, 'ill-formed argument of the YAML directive');
		        }
		        major = parseInt(match[1], 10);
		        minor = parseInt(match[2], 10);
		        if (1 !== major) {
		            throwError(state, 'found incompatible YAML document (version 1.2 is required)');
		        }
		        state.version = args[0];
		        state.checkLineBreaks = (minor < 2);
		        if (2 !== minor) {
		            throwError(state, 'found incompatible YAML document (version 1.2 is required)');
		        }
		    },
		    TAG: function handleTagDirective(state, name, args) {
		        var handle, prefix;
		        if (2 !== args.length) {
		            throwError(state, 'TAG directive accepts exactly two arguments');
		        }
		        handle = args[0];
		        prefix = args[1];
		        if (!PATTERN_TAG_HANDLE.test(handle)) {
		            throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
		        }
		        if (_hasOwnProperty.call(state.tagMap, handle)) {
		            throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
		        }
		        if (!PATTERN_TAG_URI.test(prefix)) {
		            throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
		        }
		        state.tagMap[handle] = prefix;
		    }
		};
		function captureSegment(state, start, end, checkJson) {
		    var _position, _length, _character, _result;
		    var scalar = state.result;
		    if (scalar.startPosition == -1) {
		        scalar.startPosition = start;
		    }
		    if (start < end) {
		        _result = state.input.slice(start, end);
		        if (checkJson) {
		            for (_position = 0, _length = _result.length; _position < _length; _position += 1) {
		                _character = _result.charCodeAt(_position);
		                if (!(0x09 === _character || 0x20 <= _character && _character <= 0x10FFFF)) {
		                    throwError(state, 'expected valid JSON character');
		                }
		            }
		        }
		        scalar.value += _result;
		        scalar.endPosition = end;
		    }
		}
		function mergeMappings(state, destination, source) {
		    var sourceKeys, key, index, quantity;
		    if (!common.isObject(source)) {
		        throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
		    }
		    sourceKeys = Object.keys(source);
		    for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
		        key = sourceKeys[index];
		        if (!_hasOwnProperty.call(destination, key)) {
		            destination[key] = source[key];
		        }
		    }
		}
		function storeMappingPair(state, _result, keyTag, keyNode, valueNode) {
		    var index, quantity;
		    if (keyNode == null) {
		        return;
		    }
		    //keyNode = String(keyNode);
		    if (null === _result) {
		        _result = {
		            startPosition: keyNode.startPosition,
		            endPosition: valueNode.endPosition,
		            parent: null,
		            errors: [],
		            mappings: [],
		            kind: 2 /* MAP */
		        };
		    }
		    if ('tag:yaml.org,2002:merge' === keyTag) {
		        throw new Error("Should not happen");
		    }
		    else {
		        var mapping = ast.newMapping(keyNode, valueNode);
		        mapping.parent = _result;
		        keyNode.parent = mapping;
		        if (valueNode != null) {
		            valueNode.parent = mapping;
		        }
		        _result.mappings.push(mapping);
		        _result.endPosition = valueNode ? valueNode.endPosition : keyNode.endPosition + 1; //FIXME.workaround should be position of ':' indeed
		    }
		    return _result;
		}
		function readLineBreak(state) {
		    var ch;
		    ch = state.input.charCodeAt(state.position);
		    if (0x0A === ch) {
		        state.position++;
		    }
		    else if (0x0D === ch) {
		        state.position++;
		        if (0x0A === state.input.charCodeAt(state.position)) {
		            state.position++;
		        }
		    }
		    else {
		        throwError(state, 'a line break is expected');
		    }
		    state.line += 1;
		    state.lineStart = state.position;
		}
		function skipSeparationSpace(state, allowComments, checkIndent) {
		    var lineBreaks = 0, ch = state.input.charCodeAt(state.position);
		    while (0 !== ch) {
		        while (is_WHITE_SPACE(ch)) {
		            ch = state.input.charCodeAt(++state.position);
		        }
		        if (allowComments && 0x23 === ch) {
		            do {
		                ch = state.input.charCodeAt(++state.position);
		            } while (ch !== 0x0A && ch !== 0x0D && 0 !== ch);
		        }
		        if (is_EOL(ch)) {
		            readLineBreak(state);
		            ch = state.input.charCodeAt(state.position);
		            lineBreaks++;
		            state.lineIndent = 0;
		            while (0x20 === ch) {
		                state.lineIndent++;
		                ch = state.input.charCodeAt(++state.position);
		            }
		        }
		        else {
		            break;
		        }
		    }
		    if (-1 !== checkIndent && 0 !== lineBreaks && state.lineIndent < checkIndent) {
		        throwWarning(state, 'deficient indentation');
		    }
		    return lineBreaks;
		}
		function testDocumentSeparator(state) {
		    var _position = state.position, ch;
		    ch = state.input.charCodeAt(_position);
		    // Condition state.position === state.lineStart is tested
		    // in parent on each call, for efficiency. No needs to test here again.
		    if ((0x2D === ch || 0x2E === ch) && state.input.charCodeAt(_position + 1) === ch && state.input.charCodeAt(_position + 2) === ch) {
		        _position += 3;
		        ch = state.input.charCodeAt(_position);
		        if (ch === 0 || is_WS_OR_EOL(ch)) {
		            return true;
		        }
		    }
		    return false;
		}
		function writeFoldedLines(state, scalar, count) {
		    if (1 === count) {
		        scalar.value += ' ';
		    }
		    else if (count > 1) {
		        scalar.value += common.repeat('\n', count - 1);
		    }
		}
		function readPlainScalar(state, nodeIndent, withinFlowCollection) {
		    var preceding, following, captureStart, captureEnd, hasPendingContent, _line, _lineStart, _lineIndent, _kind = state.kind, _result = state.result, ch;
		    var state_result = ast.newScalar();
		    state.result = state_result;
		    ch = state.input.charCodeAt(state.position);
		    if (is_WS_OR_EOL(ch) || is_FLOW_INDICATOR(ch) || 0x23 === ch || 0x26 === ch || 0x2A === ch || 0x21 === ch || 0x7C === ch || 0x3E === ch || 0x27 === ch || 0x22 === ch || 0x25 === ch || 0x40 === ch || 0x60 === ch) {
		        return false;
		    }
		    if (0x3F === ch || 0x2D === ch) {
		        following = state.input.charCodeAt(state.position + 1);
		        if (is_WS_OR_EOL(following) || withinFlowCollection && is_FLOW_INDICATOR(following)) {
		            return false;
		        }
		    }
		    state.kind = 'scalar';
		    //state.result = '';
		    captureStart = captureEnd = state.position;
		    hasPendingContent = false;
		    while (0 !== ch) {
		        if (0x3A === ch) {
		            following = state.input.charCodeAt(state.position + 1);
		            if (is_WS_OR_EOL(following) || withinFlowCollection && is_FLOW_INDICATOR(following)) {
		                break;
		            }
		        }
		        else if (0x23 === ch) {
		            preceding = state.input.charCodeAt(state.position - 1);
		            if (is_WS_OR_EOL(preceding)) {
		                break;
		            }
		        }
		        else if ((state.position === state.lineStart && testDocumentSeparator(state)) || withinFlowCollection && is_FLOW_INDICATOR(ch)) {
		            break;
		        }
		        else if (is_EOL(ch)) {
		            _line = state.line;
		            _lineStart = state.lineStart;
		            _lineIndent = state.lineIndent;
		            skipSeparationSpace(state, false, -1);
		            if (state.lineIndent >= nodeIndent) {
		                hasPendingContent = true;
		                ch = state.input.charCodeAt(state.position);
		                continue;
		            }
		            else {
		                state.position = captureEnd;
		                state.line = _line;
		                state.lineStart = _lineStart;
		                state.lineIndent = _lineIndent;
		                break;
		            }
		        }
		        if (hasPendingContent) {
		            captureSegment(state, captureStart, captureEnd, false);
		            writeFoldedLines(state, state_result, state.line - _line);
		            captureStart = captureEnd = state.position;
		            hasPendingContent = false;
		        }
		        if (!is_WHITE_SPACE(ch)) {
		            captureEnd = state.position + 1;
		        }
		        ch = state.input.charCodeAt(++state.position);
		        if (state.position >= state.input.length) {
		            return false;
		        }
		    }
		    captureSegment(state, captureStart, captureEnd, false);
		    if (state.result.startPosition != -1) {
		        return true;
		    }
		    state.kind = _kind;
		    state.result = _result;
		    return false;
		}
		function readSingleQuotedScalar(state, nodeIndent) {
		    var ch, captureStart, captureEnd;
		    ch = state.input.charCodeAt(state.position);
		    if (0x27 !== ch) {
		        return false;
		    }
		    var scalar = ast.newScalar();
		    state.kind = 'scalar';
		    state.result = scalar;
		    scalar.startPosition = state.position;
		    state.position++;
		    captureStart = captureEnd = state.position;
		    while (0 !== (ch = state.input.charCodeAt(state.position))) {
		        //console.log('ch: <' + String.fromCharCode(ch) + '>');
		        if (0x27 === ch) {
		            captureSegment(state, captureStart, state.position, true);
		            ch = state.input.charCodeAt(++state.position);
		            //console.log('next: <' + String.fromCharCode(ch) + '>');
		            scalar.endPosition = state.position;
		            if (0x27 === ch) {
		                captureStart = captureEnd = state.position;
		                state.position++;
		            }
		            else {
		                return true;
		            }
		        }
		        else if (is_EOL(ch)) {
		            captureSegment(state, captureStart, captureEnd, true);
		            writeFoldedLines(state, scalar, skipSeparationSpace(state, false, nodeIndent));
		            captureStart = captureEnd = state.position;
		        }
		        else if (state.position === state.lineStart && testDocumentSeparator(state)) {
		            throwError(state, 'unexpected end of the document within a single quoted scalar');
		        }
		        else {
		            state.position++;
		            captureEnd = state.position;
		            scalar.endPosition = state.position;
		        }
		    }
		    throwError(state, 'unexpected end of the stream within a single quoted scalar');
		}
		function readDoubleQuotedScalar(state, nodeIndent) {
		    var captureStart, captureEnd, hexLength, hexResult, tmp, tmpEsc, ch;
		    ch = state.input.charCodeAt(state.position);
		    if (0x22 !== ch) {
		        return false;
		    }
		    state.kind = 'scalar';
		    var scalar = ast.newScalar();
		    scalar.doubleQuoted = true;
		    state.result = scalar;
		    scalar.startPosition = state.position;
		    state.position++;
		    captureStart = captureEnd = state.position;
		    while (0 !== (ch = state.input.charCodeAt(state.position))) {
		        if (0x22 === ch) {
		            captureSegment(state, captureStart, state.position, true);
		            state.position++;
		            scalar.endPosition = state.position;
		            return true;
		        }
		        else if (0x5C === ch) {
		            captureSegment(state, captureStart, state.position, true);
		            ch = state.input.charCodeAt(++state.position);
		            if (is_EOL(ch)) {
		                skipSeparationSpace(state, false, nodeIndent);
		            }
		            else if (ch < 256 && simpleEscapeCheck[ch]) {
		                scalar.value += simpleEscapeMap[ch];
		                state.position++;
		            }
		            else if ((tmp = escapedHexLen(ch)) > 0) {
		                hexLength = tmp;
		                hexResult = 0;
		                for (; hexLength > 0; hexLength--) {
		                    ch = state.input.charCodeAt(++state.position);
		                    if ((tmp = fromHexCode(ch)) >= 0) {
		                        hexResult = (hexResult << 4) + tmp;
		                    }
		                    else {
		                        throwError(state, 'expected hexadecimal character');
		                    }
		                }
		                scalar.value += charFromCodepoint(hexResult);
		                state.position++;
		            }
		            else {
		                throwError(state, 'unknown escape sequence');
		            }
		            captureStart = captureEnd = state.position;
		        }
		        else if (is_EOL(ch)) {
		            captureSegment(state, captureStart, captureEnd, true);
		            writeFoldedLines(state, scalar, skipSeparationSpace(state, false, nodeIndent));
		            captureStart = captureEnd = state.position;
		        }
		        else if (state.position === state.lineStart && testDocumentSeparator(state)) {
		            throwError(state, 'unexpected end of the document within a double quoted scalar');
		        }
		        else {
		            state.position++;
		            captureEnd = state.position;
		        }
		    }
		    throwError(state, 'unexpected end of the stream within a double quoted scalar');
		}
		function readFlowCollection(state, nodeIndent) {
		    var readNext = true, _line, _tag = state.tag, _result, _anchor = state.anchor, following, terminator, isPair, isExplicitPair, isMapping, keyNode, keyTag, valueNode, ch;
		    ch = state.input.charCodeAt(state.position);
		    if (ch === 0x5B) {
		        terminator = 0x5D; /* ] */
		        isMapping = false;
		        _result = ast.newItems();
		        _result.startPosition = state.position;
		    }
		    else if (ch === 0x7B) {
		        terminator = 0x7D; /* } */
		        isMapping = true;
		        _result = ast.newMap();
		        _result.startPosition = state.position;
		    }
		    else {
		        return false;
		    }
		    if (null !== state.anchor) {
		        _result.anchorId = state.anchor;
		        state.anchorMap[state.anchor] = _result;
		    }
		    ch = state.input.charCodeAt(++state.position);
		    while (0 !== ch) {
		        skipSeparationSpace(state, true, nodeIndent);
		        ch = state.input.charCodeAt(state.position);
		        if (ch === terminator) {
		            state.position++;
		            state.tag = _tag;
		            state.anchor = _anchor;
		            state.kind = isMapping ? 'mapping' : 'sequence';
		            state.result = _result;
		            _result.endPosition = state.position;
		            return true;
		        }
		        else if (!readNext) {
		            var p = state.position;
		            throwError(state, 'missed comma between flow collection entries');
		            state.position = p + 1;
		        }
		        keyTag = keyNode = valueNode = null;
		        isPair = isExplicitPair = false;
		        if (0x3F === ch) {
		            following = state.input.charCodeAt(state.position + 1);
		            if (is_WS_OR_EOL(following)) {
		                isPair = isExplicitPair = true;
		                state.position++;
		                skipSeparationSpace(state, true, nodeIndent);
		            }
		        }
		        _line = state.line;
		        composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
		        keyTag = state.tag;
		        keyNode = state.result;
		        skipSeparationSpace(state, true, nodeIndent);
		        ch = state.input.charCodeAt(state.position);
		        if ((isExplicitPair || state.line === _line) && 0x3A === ch) {
		            isPair = true;
		            ch = state.input.charCodeAt(++state.position);
		            skipSeparationSpace(state, true, nodeIndent);
		            composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
		            valueNode = state.result;
		        }
		        if (isMapping) {
		            storeMappingPair(state, _result, keyTag, keyNode, valueNode);
		        }
		        else if (isPair) {
		            var mp = storeMappingPair(state, null, keyTag, keyNode, valueNode);
		            mp.parent = _result;
		            _result.items.push(mp);
		        }
		        else {
		            keyNode.parent = _result;
		            _result.items.push(keyNode);
		        }
		        _result.endPosition = state.position + 1;
		        skipSeparationSpace(state, true, nodeIndent);
		        ch = state.input.charCodeAt(state.position);
		        if (0x2C === ch) {
		            readNext = true;
		            ch = state.input.charCodeAt(++state.position);
		        }
		        else {
		            readNext = false;
		        }
		    }
		    throwError(state, 'unexpected end of the stream within a flow collection');
		}
		function readBlockScalar(state, nodeIndent) {
		    var captureStart, folding, chomping = CHOMPING_CLIP, detectedIndent = false, textIndent = nodeIndent, emptyLines = 0, atMoreIndented = false, tmp, ch;
		    ch = state.input.charCodeAt(state.position);
		    if (ch === 0x7C) {
		        folding = false;
		    }
		    else if (ch === 0x3E) {
		        folding = true;
		    }
		    else {
		        return false;
		    }
		    var sc = ast.newScalar();
		    state.kind = 'scalar';
		    state.result = sc;
		    sc.startPosition = state.position;
		    while (0 !== ch) {
		        ch = state.input.charCodeAt(++state.position);
		        if (0x2B === ch || 0x2D === ch) {
		            if (CHOMPING_CLIP === chomping) {
		                chomping = (0x2B === ch) ? CHOMPING_KEEP : CHOMPING_STRIP;
		            }
		            else {
		                throwError(state, 'repeat of a chomping mode identifier');
		            }
		        }
		        else if ((tmp = fromDecimalCode(ch)) >= 0) {
		            if (tmp === 0) {
		                throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');
		            }
		            else if (!detectedIndent) {
		                textIndent = nodeIndent + tmp - 1;
		                detectedIndent = true;
		            }
		            else {
		                throwError(state, 'repeat of an indentation width identifier');
		            }
		        }
		        else {
		            break;
		        }
		    }
		    if (is_WHITE_SPACE(ch)) {
		        do {
		            ch = state.input.charCodeAt(++state.position);
		        } while (is_WHITE_SPACE(ch));
		        if (0x23 === ch) {
		            do {
		                ch = state.input.charCodeAt(++state.position);
		            } while (!is_EOL(ch) && (0 !== ch));
		        }
		    }
		    while (0 !== ch) {
		        readLineBreak(state);
		        state.lineIndent = 0;
		        ch = state.input.charCodeAt(state.position);
		        while ((!detectedIndent || state.lineIndent < textIndent) && (0x20 === ch)) {
		            state.lineIndent++;
		            ch = state.input.charCodeAt(++state.position);
		        }
		        if (!detectedIndent && state.lineIndent > textIndent) {
		            textIndent = state.lineIndent;
		        }
		        if (is_EOL(ch)) {
		            emptyLines++;
		            continue;
		        }
		        // End of the scalar.
		        if (state.lineIndent < textIndent) {
		            // Perform the chomping.
		            if (chomping === CHOMPING_KEEP) {
		                sc.value += common.repeat('\n', emptyLines);
		            }
		            else if (chomping === CHOMPING_CLIP) {
		                if (detectedIndent) {
		                    sc.value += '\n';
		                }
		            }
		            break;
		        }
		        // Folded style: use fancy rules to handle line breaks.
		        if (folding) {
		            // Lines starting with white space characters (more-indented lines) are not folded.
		            if (is_WHITE_SPACE(ch)) {
		                atMoreIndented = true;
		                sc.value += common.repeat('\n', emptyLines + 1);
		            }
		            else if (atMoreIndented) {
		                atMoreIndented = false;
		                sc.value += common.repeat('\n', emptyLines + 1);
		            }
		            else if (0 === emptyLines) {
		                if (detectedIndent) {
		                    sc.value += ' ';
		                }
		            }
		            else {
		                sc.value += common.repeat('\n', emptyLines);
		            }
		        }
		        else if (detectedIndent) {
		            // If current line isn't the first one - count line break from the last content line.
		            sc.value += common.repeat('\n', emptyLines + 1);
		        }
		        else {
		        }
		        detectedIndent = true;
		        emptyLines = 0;
		        captureStart = state.position;
		        while (!is_EOL(ch) && (0 !== ch)) {
		            ch = state.input.charCodeAt(++state.position);
		        }
		        captureSegment(state, captureStart, state.position, false);
		    }
		    sc.endPosition = state.position;
		    var i = state.position - 1;
		    var needMinus = false;
		    while (true) {
		        var c = state.input[i];
		        if (c == '\r' || c == '\n') {
		            if (needMinus) {
		                i--;
		            }
		            break;
		        }
		        if (c != ' ' && c != '\t') {
		            break;
		        }
		        i--;
		    }
		    sc.endPosition = i;
		    return true;
		}
		function readBlockSequence(state, nodeIndent) {
		    var _line, _tag = state.tag, _anchor = state.anchor, _result = ast.newItems(), following, detected = false, ch;
		    if (null !== state.anchor) {
		        _result.anchorId = state.anchor;
		        state.anchorMap[state.anchor] = _result;
		    }
		    _result.startPosition = state.position;
		    ch = state.input.charCodeAt(state.position);
		    while (0 !== ch) {
		        if (0x2D !== ch) {
		            break;
		        }
		        following = state.input.charCodeAt(state.position + 1);
		        if (!is_WS_OR_EOL(following)) {
		            break;
		        }
		        detected = true;
		        state.position++;
		        if (skipSeparationSpace(state, true, -1)) {
		            if (state.lineIndent <= nodeIndent) {
		                _result.items.push(null);
		                ch = state.input.charCodeAt(state.position);
		                continue;
		            }
		        }
		        _line = state.line;
		        composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
		        state.result.parent = _result;
		        _result.items.push(state.result);
		        skipSeparationSpace(state, true, -1);
		        ch = state.input.charCodeAt(state.position);
		        if ((state.line === _line || state.lineIndent > nodeIndent) && (0 !== ch)) {
		            throwError(state, 'bad indentation of a sequence entry');
		        }
		        else if (state.lineIndent < nodeIndent) {
		            break;
		        }
		    }
		    _result.endPosition = state.position;
		    if (detected) {
		        state.tag = _tag;
		        state.anchor = _anchor;
		        state.kind = 'sequence';
		        state.result = _result;
		        _result.endPosition = state.position;
		        return true;
		    }
		    return false;
		}
		function readBlockMapping(state, nodeIndent, flowIndent) {
		    var following, allowCompact, _line, _tag = state.tag, _anchor = state.anchor, _result = ast.newMap(), keyTag = null, keyNode = null, valueNode = null, atExplicitKey = false, detected = false, ch;
		    _result.startPosition = state.position;
		    if (null !== state.anchor) {
		        _result.anchorId = state.anchor;
		        state.anchorMap[state.anchor] = _result;
		    }
		    ch = state.input.charCodeAt(state.position);
		    while (0 !== ch) {
		        following = state.input.charCodeAt(state.position + 1);
		        _line = state.line; // Save the current line.
		        //
		        // Explicit notation case. There are two separate blocks:
		        // first for the key (denoted by "?") and second for the value (denoted by ":")
		        //
		        if ((0x3F === ch || 0x3A === ch) && is_WS_OR_EOL(following)) {
		            if (0x3F === ch) {
		                if (atExplicitKey) {
		                    storeMappingPair(state, _result, keyTag, keyNode, null);
		                    keyTag = keyNode = valueNode = null;
		                }
		                detected = true;
		                atExplicitKey = true;
		                allowCompact = true;
		            }
		            else if (atExplicitKey) {
		                // i.e. 0x3A/* : */ === character after the explicit key.
		                atExplicitKey = false;
		                allowCompact = true;
		            }
		            else {
		                throwError(state, 'incomplete explicit mapping pair; a key node is missed');
		            }
		            state.position += 1;
		            ch = following;
		        }
		        else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
		            if (state.line === _line) {
		                ch = state.input.charCodeAt(state.position);
		                while (is_WHITE_SPACE(ch)) {
		                    ch = state.input.charCodeAt(++state.position);
		                }
		                if (0x3A === ch) {
		                    ch = state.input.charCodeAt(++state.position);
		                    if (!is_WS_OR_EOL(ch)) {
		                        throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');
		                    }
		                    if (atExplicitKey) {
		                        storeMappingPair(state, _result, keyTag, keyNode, null);
		                        keyTag = keyNode = valueNode = null;
		                    }
		                    detected = true;
		                    atExplicitKey = false;
		                    allowCompact = false;
		                    keyTag = state.tag;
		                    keyNode = state.result;
		                }
		                else if (detected) {
		                    throwError(state, 'can not read an implicit mapping pair; a colon is missed');
		                }
		                else {
		                    state.tag = _tag;
		                    state.anchor = _anchor;
		                    return true; // Keep the result of `composeNode`.
		                }
		            }
		            else if (detected) {
		                throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');
		                while (state.position > 0) {
		                    ch = state.input.charCodeAt(--state.position);
		                    if (is_EOL(ch)) {
		                        state.position++;
		                        break;
		                    }
		                }
		            }
		            else {
		                state.tag = _tag;
		                state.anchor = _anchor;
		                return true; // Keep the result of `composeNode`.
		            }
		        }
		        else {
		            break;
		        }
		        //
		        // Common reading code for both explicit and implicit notations.
		        //
		        if (state.line === _line || state.lineIndent > nodeIndent) {
		            if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
		                if (atExplicitKey) {
		                    keyNode = state.result;
		                }
		                else {
		                    valueNode = state.result;
		                }
		            }
		            if (!atExplicitKey) {
		                storeMappingPair(state, _result, keyTag, keyNode, valueNode);
		                keyTag = keyNode = valueNode = null;
		            }
		            skipSeparationSpace(state, true, -1);
		            ch = state.input.charCodeAt(state.position);
		        }
		        if (state.lineIndent > nodeIndent && (0 !== ch)) {
		            throwError(state, 'bad indentation of a mapping entry');
		        }
		        else if (state.lineIndent < nodeIndent) {
		            break;
		        }
		    }
		    //
		    // Epilogue.
		    //
		    // Special case: last mapping's node contains only the key in explicit notation.
		    if (atExplicitKey) {
		        storeMappingPair(state, _result, keyTag, keyNode, null);
		    }
		    // Expose the resulting mapping.
		    if (detected) {
		        state.tag = _tag;
		        state.anchor = _anchor;
		        state.kind = 'mapping';
		        state.result = _result;
		    }
		    return detected;
		}
		function readTagProperty(state) {
		    var _position, isVerbatim = false, isNamed = false, tagHandle, tagName, ch;
		    ch = state.input.charCodeAt(state.position);
		    if (0x21 !== ch) {
		        return false;
		    }
		    if (null !== state.tag) {
		        throwError(state, 'duplication of a tag property');
		    }
		    ch = state.input.charCodeAt(++state.position);
		    if (0x3C === ch) {
		        isVerbatim = true;
		        ch = state.input.charCodeAt(++state.position);
		    }
		    else if (0x21 === ch) {
		        isNamed = true;
		        tagHandle = '!!';
		        ch = state.input.charCodeAt(++state.position);
		    }
		    else {
		        tagHandle = '!';
		    }
		    _position = state.position;
		    if (isVerbatim) {
		        do {
		            ch = state.input.charCodeAt(++state.position);
		        } while (0 !== ch && 0x3E !== ch);
		        if (state.position < state.length) {
		            tagName = state.input.slice(_position, state.position);
		            ch = state.input.charCodeAt(++state.position);
		        }
		        else {
		            throwError(state, 'unexpected end of the stream within a verbatim tag');
		        }
		    }
		    else {
		        while (0 !== ch && !is_WS_OR_EOL(ch)) {
		            if (0x21 === ch) {
		                if (!isNamed) {
		                    tagHandle = state.input.slice(_position - 1, state.position + 1);
		                    if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
		                        throwError(state, 'named tag handle cannot contain such characters');
		                    }
		                    isNamed = true;
		                    _position = state.position + 1;
		                }
		                else {
		                    throwError(state, 'tag suffix cannot contain exclamation marks');
		                }
		            }
		            ch = state.input.charCodeAt(++state.position);
		        }
		        tagName = state.input.slice(_position, state.position);
		        if (PATTERN_FLOW_INDICATORS.test(tagName)) {
		            throwError(state, 'tag suffix cannot contain flow indicator characters');
		        }
		    }
		    if (tagName && !PATTERN_TAG_URI.test(tagName)) {
		        throwError(state, 'tag name cannot contain such characters: ' + tagName);
		    }
		    if (isVerbatim) {
		        state.tag = tagName;
		    }
		    else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {
		        state.tag = state.tagMap[tagHandle] + tagName;
		    }
		    else if ('!' === tagHandle) {
		        state.tag = '!' + tagName;
		    }
		    else if ('!!' === tagHandle) {
		        state.tag = 'tag:yaml.org,2002:' + tagName;
		    }
		    else {
		        throwError(state, 'undeclared tag handle "' + tagHandle + '"');
		    }
		    return true;
		}
		function readAnchorProperty(state) {
		    var _position, ch;
		    ch = state.input.charCodeAt(state.position);
		    if (0x26 !== ch) {
		        return false;
		    }
		    if (null !== state.anchor) {
		        throwError(state, 'duplication of an anchor property');
		    }
		    ch = state.input.charCodeAt(++state.position);
		    _position = state.position;
		    while (0 !== ch && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
		        ch = state.input.charCodeAt(++state.position);
		    }
		    if (state.position === _position) {
		        throwError(state, 'name of an anchor node must contain at least one character');
		    }
		    state.anchor = state.input.slice(_position, state.position);
		    return true;
		}
		function readAlias(state) {
		    var _position, alias, len = state.length, input = state.input, ch;
		    ch = state.input.charCodeAt(state.position);
		    if (0x2A !== ch) {
		        return false;
		    }
		    ch = state.input.charCodeAt(++state.position);
		    _position = state.position;
		    while (0 !== ch && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
		        ch = state.input.charCodeAt(++state.position);
		    }
		    if (state.position <= _position) {
		        throwError(state, 'name of an alias node must contain at least one character');
		        state.position = _position + 1;
		    }
		    alias = state.input.slice(_position, state.position);
		    if (!state.anchorMap.hasOwnProperty(alias)) {
		        throwError(state, 'unidentified alias "' + alias + '"');
		        if (state.position <= _position) {
		            state.position = _position + 1;
		        }
		    }
		    state.result = ast.newAnchorRef(alias, _position, state.position, state.anchorMap[alias]);
		    skipSeparationSpace(state, true, -1);
		    return true;
		}
		function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
		    var allowBlockStyles, allowBlockScalars, allowBlockCollections, indentStatus = 1, atNewLine = false, hasContent = false, typeIndex, typeQuantity, type, flowIndent, blockIndent, _result;
		    state.tag = null;
		    state.anchor = null;
		    state.kind = null;
		    state.result = null;
		    allowBlockStyles = allowBlockScalars = allowBlockCollections = CONTEXT_BLOCK_OUT === nodeContext || CONTEXT_BLOCK_IN === nodeContext;
		    if (allowToSeek) {
		        if (skipSeparationSpace(state, true, -1)) {
		            atNewLine = true;
		            if (state.lineIndent > parentIndent) {
		                indentStatus = 1;
		            }
		            else if (state.lineIndent === parentIndent) {
		                indentStatus = 0;
		            }
		            else if (state.lineIndent < parentIndent) {
		                indentStatus = -1;
		            }
		        }
		    }
		    if (1 === indentStatus) {
		        while (readTagProperty(state) || readAnchorProperty(state)) {
		            if (skipSeparationSpace(state, true, -1)) {
		                atNewLine = true;
		                allowBlockCollections = allowBlockStyles;
		                if (state.lineIndent > parentIndent) {
		                    indentStatus = 1;
		                }
		                else if (state.lineIndent === parentIndent) {
		                    indentStatus = 0;
		                }
		                else if (state.lineIndent < parentIndent) {
		                    indentStatus = -1;
		                }
		            }
		            else {
		                allowBlockCollections = false;
		            }
		        }
		    }
		    if (allowBlockCollections) {
		        allowBlockCollections = atNewLine || allowCompact;
		    }
		    if (1 === indentStatus || CONTEXT_BLOCK_OUT === nodeContext) {
		        if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
		            flowIndent = parentIndent;
		        }
		        else {
		            flowIndent = parentIndent + 1;
		        }
		        blockIndent = state.position - state.lineStart;
		        if (1 === indentStatus) {
		            if (allowBlockCollections && (readBlockSequence(state, blockIndent) || readBlockMapping(state, blockIndent, flowIndent)) || readFlowCollection(state, flowIndent)) {
		                hasContent = true;
		            }
		            else {
		                if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || readSingleQuotedScalar(state, flowIndent) || readDoubleQuotedScalar(state, flowIndent)) {
		                    hasContent = true;
		                }
		                else if (readAlias(state)) {
		                    hasContent = true;
		                    if (null !== state.tag || null !== state.anchor) {
		                        throwError(state, 'alias node should not have any properties');
		                    }
		                }
		                else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
		                    hasContent = true;
		                    if (null === state.tag) {
		                        state.tag = '?';
		                    }
		                }
		                if (null !== state.anchor) {
		                    state.anchorMap[state.anchor] = state.result;
		                    state.result.anchorId = state.anchor;
		                }
		            }
		        }
		        else if (0 === indentStatus) {
		            // Special case: block sequences are allowed to have same indentation level as the parent.
		            // http://www.yaml.org/spec/1.2/spec.html#id2799784
		            hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
		        }
		    }
		    if (null !== state.tag && '!' !== state.tag) {
		        if (state.tag == "!include") {
		            if (!state.result) {
		                state.result = ast.newScalar();
		                state.result.startPosition = state.position;
		                state.result.endPosition = state.position;
		                throwError(state, "!include without value");
		            }
		            state.result.kind = 5 /* INCLUDE_REF */;
		        }
		        else if ('?' === state.tag) {
		            for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {
		                type = state.implicitTypes[typeIndex];
		                // Implicit resolving is not allowed for non-scalar types, and '?'
		                // non-specific tag is only assigned to plain scalars. So, it isn't
		                // needed to check for 'kind' conformity.
		                var vl = state.result['value'];
		                if (type.resolve(vl)) {
		                    state.result.valueObject = type.construct(state.result['value']);
		                    state.tag = type.tag;
		                    if (null !== state.anchor) {
		                        state.result.anchorId = state.anchor;
		                        state.anchorMap[state.anchor] = state.result;
		                    }
		                    break;
		                }
		            }
		        }
		        else if (_hasOwnProperty.call(state.typeMap, state.tag)) {
		            type = state.typeMap[state.tag];
		            if (null !== state.result && type.kind !== state.kind) {
		                throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
		            }
		            if (!type.resolve(state.result)) {
		                throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');
		            }
		            else {
		                state.result = type.construct(state.result);
		                if (null !== state.anchor) {
		                    state.result.anchorId = state.anchor;
		                    state.anchorMap[state.anchor] = state.result;
		                }
		            }
		        }
		        else {
		            throwWarning(state, 'unknown tag !<' + state.tag + '>');
		        }
		    }
		    return null !== state.tag || null !== state.anchor || hasContent;
		}
		function readDocument(state) {
		    var documentStart = state.position, _position, directiveName, directiveArgs, hasDirectives = false, ch;
		    state.version = null;
		    state.checkLineBreaks = state.legacy;
		    state.tagMap = {};
		    state.anchorMap = {};
		    while (0 !== (ch = state.input.charCodeAt(state.position))) {
		        skipSeparationSpace(state, true, -1);
		        ch = state.input.charCodeAt(state.position);
		        if (state.lineIndent > 0 || 0x25 !== ch) {
		            break;
		        }
		        hasDirectives = true;
		        ch = state.input.charCodeAt(++state.position);
		        _position = state.position;
		        while (0 !== ch && !is_WS_OR_EOL(ch)) {
		            ch = state.input.charCodeAt(++state.position);
		        }
		        directiveName = state.input.slice(_position, state.position);
		        directiveArgs = [];
		        if (directiveName.length < 1) {
		            throwError(state, 'directive name must not be less than one character in length');
		        }
		        while (0 !== ch) {
		            while (is_WHITE_SPACE(ch)) {
		                ch = state.input.charCodeAt(++state.position);
		            }
		            if (0x23 === ch) {
		                do {
		                    ch = state.input.charCodeAt(++state.position);
		                } while (0 !== ch && !is_EOL(ch));
		                break;
		            }
		            if (is_EOL(ch)) {
		                break;
		            }
		            _position = state.position;
		            while (0 !== ch && !is_WS_OR_EOL(ch)) {
		                ch = state.input.charCodeAt(++state.position);
		            }
		            directiveArgs.push(state.input.slice(_position, state.position));
		        }
		        if (0 !== ch) {
		            readLineBreak(state);
		        }
		        if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
		            directiveHandlers[directiveName](state, directiveName, directiveArgs);
		        }
		        else {
		            throwWarning(state, 'unknown document directive "' + directiveName + '"');
		            state.position++;
		        }
		    }
		    skipSeparationSpace(state, true, -1);
		    if (0 === state.lineIndent && 0x2D === state.input.charCodeAt(state.position) && 0x2D === state.input.charCodeAt(state.position + 1) && 0x2D === state.input.charCodeAt(state.position + 2)) {
		        state.position += 3;
		        skipSeparationSpace(state, true, -1);
		    }
		    else if (hasDirectives) {
		        throwError(state, 'directives end mark is expected');
		    }
		    composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
		    skipSeparationSpace(state, true, -1);
		    if (state.checkLineBreaks && PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
		        throwWarning(state, 'non-ASCII line breaks are interpreted as content');
		    }
		    state.documents.push(state.result);
		    if (state.position === state.lineStart && testDocumentSeparator(state)) {
		        if (0x2E === state.input.charCodeAt(state.position)) {
		            state.position += 3;
		            skipSeparationSpace(state, true, -1);
		        }
		        return;
		    }
		    if (state.position < (state.length - 1)) {
		        throwError(state, 'end of the stream or a document separator is expected');
		    }
		    else {
		        return;
		    }
		}
		function loadDocuments(input, options) {
		    input = String(input);
		    options = options || {};
		    if (input.length !== 0) {
		        // Add tailing `\n` if not exists
		        if (0x0A !== input.charCodeAt(input.length - 1) && 0x0D !== input.charCodeAt(input.length - 1)) {
		            input += '\n';
		        }
		        // Strip BOM
		        if (input.charCodeAt(0) === 0xFEFF) {
		            input = input.slice(1);
		        }
		    }
		    var state = new State(input, options);
		    if (PATTERN_NON_PRINTABLE.test(state.input)) {
		        throwError(state, 'the stream contains non-printable characters');
		    }
		    // Use 0 as string terminator. That significantly simplifies bounds check.
		    state.input += '\0';
		    while (0x20 === state.input.charCodeAt(state.position)) {
		        state.lineIndent += 1;
		        state.position += 1;
		    }
		    while (state.position < (state.length - 1)) {
		        var q = state.position;
		        readDocument(state);
		        if (state.position <= q) {
		            for (; state.position < state.length - 1; state.position++) {
		                var c = state.input.charAt(state.position);
		                if (c == '\n') {
		                    break;
		                }
		            }
		        }
		    }
		    state.documents.forEach(function (x) { return x.errors = state.errors; });
		    return state.documents;
		}
		function loadAll(input, iterator, options) {
		    var documents = loadDocuments(input, options), index, length;
		    for (index = 0, length = documents.length; index < length; index += 1) {
		        iterator(documents[index]);
		    }
		}
		exports.loadAll = loadAll;
		function load(input, options) {
		    var documents = loadDocuments(input, options), index, length;
		    if (0 === documents.length) {
		        /*eslint-disable no-undefined*/
		        return undefined;
		    }
		    else if (1 === documents.length) {
		        //root node always takes whole file
		        documents[0].endPosition = input.length;
		        return documents[0];
		    }
		    var e = new YAMLException('expected a single document in the stream, but found more');
		    e.mark = new Mark("", "", 0, 0, 0);
		    e.mark.position = documents[0].endPosition;
		    documents[0].errors.push(e);
		    //it is an artifact which is caused by the fact that we are checking next char before stopping parse
		    return documents[0];
		}
		exports.load = load;
		function safeLoadAll(input, output, options) {
		    loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
		}
		exports.safeLoadAll = safeLoadAll;
		function safeLoad(input, options) {
		    return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
		}
		exports.safeLoad = safeLoad;
		module.exports.loadAll = loadAll;
		module.exports.load = load;
		module.exports.safeLoadAll = safeLoadAll;
		module.exports.safeLoad = safeLoad;


	/***/ },
	/* 20 */
	/***/ function(module, exports) {

		/// <reference path="../../../../typings/main.d.ts" />
		'use strict';
		function isNothing(subject) {
		    return (typeof subject === 'undefined') || (null === subject);
		}
		exports.isNothing = isNothing;
		function isObject(subject) {
		    return (typeof subject === 'object') && (null !== subject);
		}
		exports.isObject = isObject;
		function toArray(sequence) {
		    if (Array.isArray(sequence)) {
		        return sequence;
		    }
		    else if (isNothing(sequence)) {
		        return [];
		    }
		    return [sequence];
		}
		exports.toArray = toArray;
		function extend(target, source) {
		    var index, length, key, sourceKeys;
		    if (source) {
		        sourceKeys = Object.keys(source);
		        for (index = 0, length = sourceKeys.length; index < length; index += 1) {
		            key = sourceKeys[index];
		            target[key] = source[key];
		        }
		    }
		    return target;
		}
		exports.extend = extend;
		function repeat(string, count) {
		    var result = '', cycle;
		    for (cycle = 0; cycle < count; cycle += 1) {
		        result += string;
		    }
		    return result;
		}
		exports.repeat = repeat;
		function isNegativeZero(number) {
		    return (0 === number) && (Number.NEGATIVE_INFINITY === 1 / number);
		}
		exports.isNegativeZero = isNegativeZero;


	/***/ },
	/* 21 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../../typings/main.d.ts" />
		'use strict';
		var common = __webpack_require__(20);
		var Mark = (function () {
		    function Mark(name, buffer, position, line, column) {
		        this.name = name;
		        this.buffer = buffer;
		        this.position = position;
		        this.line = line;
		        this.column = column;
		    }
		    Mark.prototype.getSnippet = function (indent, maxLength) {
		        if (indent === void 0) { indent = 0; }
		        if (maxLength === void 0) { maxLength = 75; }
		        var head, start, tail, end, snippet;
		        if (!this.buffer) {
		            return null;
		        }
		        indent = indent || 4;
		        maxLength = maxLength || 75;
		        head = '';
		        start = this.position;
		        while (start > 0 && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1))) {
		            start -= 1;
		            if (this.position - start > (maxLength / 2 - 1)) {
		                head = ' ... ';
		                start += 5;
		                break;
		            }
		        }
		        tail = '';
		        end = this.position;
		        while (end < this.buffer.length && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end))) {
		            end += 1;
		            if (end - this.position > (maxLength / 2 - 1)) {
		                tail = ' ... ';
		                end -= 5;
		                break;
		            }
		        }
		        snippet = this.buffer.slice(start, end);
		        return common.repeat(' ', indent) + head + snippet + tail + '\n' + common.repeat(' ', indent + this.position - start + head.length) + '^';
		    };
		    Mark.prototype.toString = function (compact) {
		        if (compact === void 0) { compact = true; }
		        var snippet, where = '';
		        if (this.name) {
		            where += 'in "' + this.name + '" ';
		        }
		        where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);
		        if (!compact) {
		            snippet = this.getSnippet();
		            if (snippet) {
		                where += ':\n' + snippet;
		            }
		        }
		        return where;
		    };
		    return Mark;
		})();
		module.exports = Mark;


	/***/ },
	/* 22 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../../../typings/main.d.ts" />
		// JS-YAML's default schema for `safeLoad` function.
		// It is not described in the YAML specification.
		//
		// This schema is based on standard YAML's Core schema and includes most of
		// extra types described at YAML tag repository. (http://yaml.org/type/)
		'use strict';
		var Schema = __webpack_require__(23);
		var schema = new Schema({
		    include: [
		        __webpack_require__(25)
		    ],
		    implicit: [
		        __webpack_require__(35),
		        __webpack_require__(36)
		    ],
		    explicit: [
		        __webpack_require__(37),
		        __webpack_require__(39),
		        __webpack_require__(40),
		        __webpack_require__(41)
		    ]
		});
		module.exports = schema;


	/***/ },
	/* 23 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../../typings/main.d.ts" />
		'use strict';
		/*eslint-disable max-len*/
		var common = __webpack_require__(20);
		var YAMLException = __webpack_require__(9);
		var Type = __webpack_require__(24);
		function compileList(schema, name, result) {
		    var exclude = [];
		    schema.include.forEach(function (includedSchema) {
		        result = compileList(includedSchema, name, result);
		    });
		    schema[name].forEach(function (currentType) {
		        result.forEach(function (previousType, previousIndex) {
		            if (previousType.tag === currentType.tag) {
		                exclude.push(previousIndex);
		            }
		        });
		        result.push(currentType);
		    });
		    return result.filter(function (type, index) {
		        return -1 === exclude.indexOf(index);
		    });
		}
		function compileMap() {
		    var result = {}, index, length;
		    function collectType(type) {
		        result[type.tag] = type;
		    }
		    for (index = 0, length = arguments.length; index < length; index += 1) {
		        arguments[index].forEach(collectType);
		    }
		    return result;
		}
		var Schema = (function () {
		    function Schema(definition) {
		        this.include = definition.include || [];
		        this.implicit = definition.implicit || [];
		        this.explicit = definition.explicit || [];
		        this.implicit.forEach(function (type) {
		            if (type.loadKind && 'scalar' !== type.loadKind) {
		                throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
		            }
		        });
		        this.compiledImplicit = compileList(this, 'implicit', []);
		        this.compiledExplicit = compileList(this, 'explicit', []);
		        this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit);
		    }
		    Schema.DEFAULT = null;
		    Schema.create = function createSchema() {
		        var schemas, types;
		        switch (arguments.length) {
		            case 1:
		                schemas = Schema.DEFAULT;
		                types = arguments[0];
		                break;
		            case 2:
		                schemas = arguments[0];
		                types = arguments[1];
		                break;
		            default:
		                throw new YAMLException('Wrong number of arguments for Schema.create function');
		        }
		        schemas = common.toArray(schemas);
		        types = common.toArray(types);
		        if (!schemas.every(function (schema) {
		            return schema instanceof Schema;
		        })) {
		            throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');
		        }
		        if (!types.every(function (type) {
		            return type instanceof Type;
		        })) {
		            throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
		        }
		        return new Schema({
		            include: schemas,
		            explicit: types
		        });
		    };
		    return Schema;
		})();
		module.exports = Schema;


	/***/ },
	/* 24 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var YAMLException = __webpack_require__(9);
		var TYPE_CONSTRUCTOR_OPTIONS = [
		    'kind',
		    'resolve',
		    'construct',
		    'instanceOf',
		    'predicate',
		    'represent',
		    'defaultStyle',
		    'styleAliases'
		];
		var YAML_NODE_KINDS = [
		    'scalar',
		    'sequence',
		    'mapping'
		];
		function compileStyleAliases(map) {
		    var result = {};
		    if (null !== map) {
		        Object.keys(map).forEach(function (style) {
		            map[style].forEach(function (alias) {
		                result[String(alias)] = style;
		            });
		        });
		    }
		    return result;
		}
		function Type(tag, options) {
		    options = options || {};
		    Object.keys(options).forEach(function (name) {
		        if (-1 === TYPE_CONSTRUCTOR_OPTIONS.indexOf(name)) {
		            throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
		        }
		    });
		    // TODO: Add tag format check.
		    this.tag = tag;
		    this.kind = options['kind'] || null;
		    this.resolve = options['resolve'] || function () {
		        return true;
		    };
		    this.construct = options['construct'] || function (data) {
		        return data;
		    };
		    this.instanceOf = options['instanceOf'] || null;
		    this.predicate = options['predicate'] || null;
		    this.represent = options['represent'] || null;
		    this.defaultStyle = options['defaultStyle'] || null;
		    this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
		    if (-1 === YAML_NODE_KINDS.indexOf(this.kind)) {
		        throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
		    }
		}
		module.exports = Type;


	/***/ },
	/* 25 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Schema = __webpack_require__(23);
		module.exports = new Schema({
		    include: [
		        __webpack_require__(26)
		    ]
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC9zY2hlbWEvY29yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFTQSxZQUFZLENBQUM7QUFHYixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFHbEMsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLE1BQU0sQ0FBQztJQUMxQixPQUFPLEVBQUU7UUFDUCxPQUFPLENBQUMsUUFBUSxDQUFDO0tBQ2xCO0NBQ0YsQ0FBQyxDQUFDIiwiZmlsZSI6InNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC9zY2hlbWEvY29yZS5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuLi8uLi8uLi8uLi8uLi90eXBpbmdzL21haW4uZC50c1wiIC8+XG5cbi8vIFN0YW5kYXJkIFlBTUwncyBDb3JlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwNDkyM1xuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIENvcmUgc2NoZW1hIGhhcyBubyBkaXN0aW5jdGlvbnMgZnJvbSBKU09OIHNjaGVtYSBpcyBKUy1ZQU1MLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vanNvbicpXG4gIF1cbn0pO1xuIl19


	/***/ },
	/* 26 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Schema = __webpack_require__(23);
		module.exports = new Schema({
		    include: [
		        __webpack_require__(27)
		    ],
		    implicit: [
		        __webpack_require__(31),
		        __webpack_require__(32),
		        __webpack_require__(33),
		        __webpack_require__(34)
		    ]
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC9zY2hlbWEvanNvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFVQSxZQUFZLENBQUM7QUFHYixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFHbEMsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLE1BQU0sQ0FBQztJQUMxQixPQUFPLEVBQUU7UUFDUCxPQUFPLENBQUMsWUFBWSxDQUFDO0tBQ3RCO0lBQ0QsUUFBUSxFQUFFO1FBQ1IsT0FBTyxDQUFDLGNBQWMsQ0FBQztRQUN2QixPQUFPLENBQUMsY0FBYyxDQUFDO1FBQ3ZCLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFDdEIsT0FBTyxDQUFDLGVBQWUsQ0FBQztLQUN6QjtDQUNGLENBQUMsQ0FBQyIsImZpbGUiOiJzcmMvcmFtbDEvanN5YW1sL2pzLXlhbWwvc2NoZW1hL2pzb24uanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi4vLi4vLi4vLi4vLi4vdHlwaW5ncy9tYWluLmQudHNcIiAvPlxuXG4vLyBTdGFuZGFyZCBZQU1MJ3MgSlNPTiBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDMyMzFcbi8vXG4vLyBOT1RFOiBKUy1ZQU1MIGRvZXMgbm90IHN1cHBvcnQgc2NoZW1hLXNwZWNpZmljIHRhZyByZXNvbHV0aW9uIHJlc3RyaWN0aW9ucy5cbi8vIFNvLCB0aGlzIHNjaGVtYSBpcyBub3Qgc3VjaCBzdHJpY3QgYXMgZGVmaW5lZCBpbiB0aGUgWUFNTCBzcGVjaWZpY2F0aW9uLlxuLy8gSXQgYWxsb3dzIG51bWJlcnMgaW4gYmluYXJ5IG5vdGFpb24sIHVzZSBgTnVsbGAgYW5kIGBOVUxMYCBhcyBgbnVsbGAsIGV0Yy5cblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2ZhaWxzYWZlJylcbiAgXSxcbiAgaW1wbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL251bGwnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2Jvb2wnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvZmxvYXQnKVxuICBdXG59KTtcbiJdfQ==


	/***/ },
	/* 27 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Schema = __webpack_require__(23);
		module.exports = new Schema({
		    explicit: [
		        __webpack_require__(28),
		        __webpack_require__(29),
		        __webpack_require__(30)
		    ]
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsWUFBWSxDQUFDO0FBR2IsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBR2xDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxNQUFNLENBQUM7SUFDMUIsUUFBUSxFQUFFO1FBQ1IsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUN0QixPQUFPLENBQUMsYUFBYSxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxhQUFhLENBQUM7S0FDdkI7Q0FDRixDQUFDLENBQUMiLCJmaWxlIjoic3JjL3JhbWwxL2pzeWFtbC9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZS5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuLi8uLi8uLi8uLi8uLi90eXBpbmdzL21haW4uZC50c1wiIC8+XG5cbi8vIFN0YW5kYXJkIFlBTUwncyBGYWlsc2FmZSBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDIzNDZcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zdHInKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NlcScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJylcbiAgXVxufSk7XG4iXX0=


	/***/ },
	/* 28 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		module.exports = new Type('tag:yaml.org,2002:str', {
		    kind: 'scalar',
		    construct: function (data) {
		        return null !== data ? data : '';
		    }
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL3N0ci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxZQUFZLENBQUM7QUFFYixJQUFPLElBQUksV0FBVyxTQUFTLENBQUMsQ0FBQztBQUVqQyxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO0lBQ2pELElBQUksRUFBRSxRQUFRO0lBQ2QsU0FBUyxFQUFFLFVBQVUsSUFBSTtRQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7SUFBQyxDQUFDO0NBQ2pFLENBQUMsQ0FBQyIsImZpbGUiOiJzcmMvcmFtbDEvanN5YW1sL2pzLXlhbWwvdHlwZS9zdHIuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi4vLi4vLi4vLi4vLi4vdHlwaW5ncy9tYWluLmQudHNcIiAvPlxuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBudWxsICE9PSBkYXRhID8gZGF0YSA6ICcnOyB9XG59KTtcbiJdfQ==


	/***/ },
	/* 29 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		module.exports = new Type('tag:yaml.org,2002:seq', {
		    kind: 'sequence',
		    construct: function (data) {
		        return null !== data ? data : [];
		    }
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL3NlcS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxZQUFZLENBQUM7QUFFYixJQUFPLElBQUksV0FBVyxTQUFTLENBQUMsQ0FBQztBQUVqQyxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO0lBQ2pELElBQUksRUFBRSxVQUFVO0lBQ2hCLFNBQVMsRUFBRSxVQUFVLElBQUk7UUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQUMsQ0FBQztDQUNqRSxDQUFDLENBQUMiLCJmaWxlIjoic3JjL3JhbWwxL2pzeWFtbC9qcy15YW1sL3R5cGUvc2VxLmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uLy4uLy4uLy4uLy4uL3R5cGluZ3MvbWFpbi5kLnRzXCIgLz5cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6c2VxJywge1xuICBraW5kOiAnc2VxdWVuY2UnLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBudWxsICE9PSBkYXRhID8gZGF0YSA6IFtdOyB9XG59KTtcbiJdfQ==


	/***/ },
	/* 30 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		module.exports = new Type('tag:yaml.org,2002:map', {
		    kind: 'mapping',
		    construct: function (data) {
		        return null !== data ? data : {};
		    }
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL21hcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxZQUFZLENBQUM7QUFFYixJQUFPLElBQUksV0FBVyxTQUFTLENBQUMsQ0FBQztBQUVqQyxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO0lBQ2pELElBQUksRUFBRSxTQUFTO0lBQ2YsU0FBUyxFQUFFLFVBQVUsSUFBSTtRQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7SUFBQyxDQUFDO0NBQ2pFLENBQUMsQ0FBQyIsImZpbGUiOiJzcmMvcmFtbDEvanN5YW1sL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi4vLi4vLi4vLi4vLi4vdHlwaW5ncy9tYWluLmQudHNcIiAvPlxuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjptYXAnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gbnVsbCAhPT0gZGF0YSA/IGRhdGEgOiB7fTsgfVxufSk7XG4iXX0=


	/***/ },
	/* 31 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		function resolveYamlNull(data) {
		    if (null === data) {
		        return true;
		    }
		    var max = data.length;
		    return (max === 1 && data === '~') || (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
		}
		function constructYamlNull() {
		    return null;
		}
		function isNull(object) {
		    return null === object;
		}
		module.exports = new Type('tag:yaml.org,2002:null', {
		    kind: 'scalar',
		    resolve: resolveYamlNull,
		    construct: constructYamlNull,
		    predicate: isNull,
		    represent: {
		        canonical: function () {
		            return '~';
		        },
		        lowercase: function () {
		            return 'null';
		        },
		        uppercase: function () {
		            return 'NULL';
		        },
		        camelcase: function () {
		            return 'Null';
		        }
		    },
		    defaultStyle: 'lowercase'
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL251bGwudHMiXSwibmFtZXMiOlsicmVzb2x2ZVlhbWxOdWxsIiwiY29uc3RydWN0WWFtbE51bGwiLCJpc051bGwiXSwibWFwcGluZ3MiOiJBQUVBLFlBQVksQ0FBQztBQUViLElBQU8sSUFBSSxXQUFXLFNBQVMsQ0FBQyxDQUFDO0FBRWpDLFNBQVMsZUFBZSxDQUFDLElBQUk7SUFDM0JBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLEtBQUtBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO1FBQ2xCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNkQSxDQUFDQTtJQUVEQSxJQUFJQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQTtJQUV0QkEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsSUFBSUEsSUFBSUEsS0FBS0EsR0FBR0EsQ0FBQ0EsSUFDM0JBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLEtBQUtBLE1BQU1BLElBQUlBLElBQUlBLEtBQUtBLE1BQU1BLElBQUlBLElBQUlBLEtBQUtBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBO0FBQ2hGQSxDQUFDQTtBQUVELFNBQVMsaUJBQWlCO0lBQ3hCQyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtBQUNkQSxDQUFDQTtBQUVELFNBQVMsTUFBTSxDQUFDLE1BQU07SUFDcEJDLE1BQU1BLENBQUNBLElBQUlBLEtBQUtBLE1BQU1BLENBQUNBO0FBQ3pCQSxDQUFDQTtBQUVELE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7SUFDbEQsSUFBSSxFQUFFLFFBQVE7SUFDZCxPQUFPLEVBQUUsZUFBZTtJQUN4QixTQUFTLEVBQUUsaUJBQWlCO0lBQzVCLFNBQVMsRUFBRSxNQUFNO0lBQ2pCLFNBQVMsRUFBRTtRQUNULFNBQVMsRUFBRTtZQUFjLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFBSSxDQUFDO1FBQ3pDLFNBQVMsRUFBRTtZQUFjLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFBQyxDQUFDO1FBQ3pDLFNBQVMsRUFBRTtZQUFjLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFBQyxDQUFDO1FBQ3pDLFNBQVMsRUFBRTtZQUFjLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFBQyxDQUFDO0tBQzFDO0lBQ0QsWUFBWSxFQUFFLFdBQVc7Q0FDMUIsQ0FBQyxDQUFDIiwiZmlsZSI6InNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL251bGwuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi4vLi4vLi4vLi4vLi4vdHlwaW5ncy9tYWluLmQudHNcIiAvPlxuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkge1xuICBpZiAobnVsbCA9PT0gZGF0YSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSAxICYmIGRhdGEgPT09ICd+JykgfHxcbiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKG9iamVjdCkge1xuICByZXR1cm4gbnVsbCA9PT0gb2JqZWN0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpudWxsJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxOdWxsLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxOdWxsLFxuICBwcmVkaWNhdGU6IGlzTnVsbCxcbiAgcmVwcmVzZW50OiB7XG4gICAgY2Fub25pY2FsOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnfic7ICAgIH0sXG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTlVMTCc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTnVsbCc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iXX0=


	/***/ },
	/* 32 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		function resolveYamlBoolean(data) {
		    if (null === data) {
		        return false;
		    }
		    var max = data.length;
		    return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
		}
		function constructYamlBoolean(data) {
		    return data === 'true' || data === 'True' || data === 'TRUE';
		}
		function isBoolean(object) {
		    return '[object Boolean]' === Object.prototype.toString.call(object);
		}
		module.exports = new Type('tag:yaml.org,2002:bool', {
		    kind: 'scalar',
		    resolve: resolveYamlBoolean,
		    construct: constructYamlBoolean,
		    predicate: isBoolean,
		    represent: {
		        lowercase: function (object) {
		            return object ? 'true' : 'false';
		        },
		        uppercase: function (object) {
		            return object ? 'TRUE' : 'FALSE';
		        },
		        camelcase: function (object) {
		            return object ? 'True' : 'False';
		        }
		    },
		    defaultStyle: 'lowercase'
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL2Jvb2wudHMiXSwibmFtZXMiOlsicmVzb2x2ZVlhbWxCb29sZWFuIiwiY29uc3RydWN0WWFtbEJvb2xlYW4iLCJpc0Jvb2xlYW4iXSwibWFwcGluZ3MiOiJBQUVBLFlBQVksQ0FBQztBQUViLElBQU8sSUFBSSxXQUFXLFNBQVMsQ0FBQyxDQUFDO0FBRWpDLFNBQVMsa0JBQWtCLENBQUMsSUFBSTtJQUM5QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDbEJBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBO0lBQ2ZBLENBQUNBO0lBRURBLElBQUlBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBO0lBRXRCQSxNQUFNQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxLQUFLQSxNQUFNQSxJQUFJQSxJQUFJQSxLQUFLQSxNQUFNQSxJQUFJQSxJQUFJQSxLQUFLQSxNQUFNQSxDQUFDQSxDQUFDQSxJQUN0RUEsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsS0FBS0EsT0FBT0EsSUFBSUEsSUFBSUEsS0FBS0EsT0FBT0EsSUFBSUEsSUFBSUEsS0FBS0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7QUFDbkZBLENBQUNBO0FBRUQsU0FBUyxvQkFBb0IsQ0FBQyxJQUFJO0lBQ2hDQyxNQUFNQSxDQUFDQSxJQUFJQSxLQUFLQSxNQUFNQSxJQUNmQSxJQUFJQSxLQUFLQSxNQUFNQSxJQUNmQSxJQUFJQSxLQUFLQSxNQUFNQSxDQUFDQTtBQUN6QkEsQ0FBQ0E7QUFFRCxTQUFTLFNBQVMsQ0FBQyxNQUFNO0lBQ3ZCQyxNQUFNQSxDQUFDQSxrQkFBa0JBLEtBQUtBLE1BQU1BLENBQUNBLFNBQVNBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBO0FBQ3ZFQSxDQUFDQTtBQUVELE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7SUFDbEQsSUFBSSxFQUFFLFFBQVE7SUFDZCxPQUFPLEVBQUUsa0JBQWtCO0lBQzNCLFNBQVMsRUFBRSxvQkFBb0I7SUFDL0IsU0FBUyxFQUFFLFNBQVM7SUFDcEIsU0FBUyxFQUFFO1FBQ1QsU0FBUyxFQUFFLFVBQVUsTUFBTTtZQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQztRQUFDLENBQUM7UUFDbEUsU0FBUyxFQUFFLFVBQVUsTUFBTTtZQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQztRQUFDLENBQUM7UUFDbEUsU0FBUyxFQUFFLFVBQVUsTUFBTTtZQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQztRQUFDLENBQUM7S0FDbkU7SUFDRCxZQUFZLEVBQUUsV0FBVztDQUMxQixDQUFDLENBQUMiLCJmaWxlIjoic3JjL3JhbWwxL2pzeWFtbC9qcy15YW1sL3R5cGUvYm9vbC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuLi8uLi8uLi8uLi8uLi90eXBpbmdzL21haW4uZC50c1wiIC8+XG5cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQm9vbGVhbihkYXRhKSB7XG4gIGlmIChudWxsID09PSBkYXRhKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSA0ICYmIChkYXRhID09PSAndHJ1ZScgfHwgZGF0YSA9PT0gJ1RydWUnIHx8IGRhdGEgPT09ICdUUlVFJykpIHx8XG4gICAgICAgICAobWF4ID09PSA1ICYmIChkYXRhID09PSAnZmFsc2UnIHx8IGRhdGEgPT09ICdGYWxzZScgfHwgZGF0YSA9PT0gJ0ZBTFNFJykpO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQm9vbGVhbihkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAndHJ1ZScgfHxcbiAgICAgICAgIGRhdGEgPT09ICdUcnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RSVUUnO1xufVxuXG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqZWN0KSB7XG4gIHJldHVybiAnW29iamVjdCBCb29sZWFuXScgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpib29sJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxCb29sZWFuLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxCb29sZWFuLFxuICBwcmVkaWNhdGU6IGlzQm9vbGVhbixcbiAgcmVwcmVzZW50OiB7XG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAndHJ1ZScgOiAnZmFsc2UnOyB9LFxuICAgIHVwcGVyY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RSVUUnIDogJ0ZBTFNFJzsgfSxcbiAgICBjYW1lbGNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICdUcnVlJyA6ICdGYWxzZSc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iXX0=


	/***/ },
	/* 33 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var common = __webpack_require__(20);
		var Type = __webpack_require__(24);
		function isHexCode(c) {
		    return ((0x30 <= c) && (c <= 0x39)) || ((0x41 <= c) && (c <= 0x46)) || ((0x61 <= c) && (c <= 0x66));
		}
		function isOctCode(c) {
		    return ((0x30 <= c) && (c <= 0x37));
		}
		function isDecCode(c) {
		    return ((0x30 <= c) && (c <= 0x39));
		}
		function resolveYamlInteger(data) {
		    if (null === data) {
		        return false;
		    }
		    var max = data.length, index = 0, hasDigits = false, ch;
		    if (!max) {
		        return false;
		    }
		    ch = data[index];
		    if (ch === '-' || ch === '+') {
		        ch = data[++index];
		    }
		    if (ch === '0') {
		        if (index + 1 === max) {
		            return true;
		        }
		        ch = data[++index];
		        if (ch === 'b') {
		            index++;
		            for (; index < max; index++) {
		                ch = data[index];
		                if (ch === '_') {
		                    continue;
		                }
		                if (ch !== '0' && ch !== '1') {
		                    return false;
		                }
		                hasDigits = true;
		            }
		            return hasDigits;
		        }
		        if (ch === 'x') {
		            index++;
		            for (; index < max; index++) {
		                ch = data[index];
		                if (ch === '_') {
		                    continue;
		                }
		                if (!isHexCode(data.charCodeAt(index))) {
		                    return false;
		                }
		                hasDigits = true;
		            }
		            return hasDigits;
		        }
		        for (; index < max; index++) {
		            ch = data[index];
		            if (ch === '_') {
		                continue;
		            }
		            if (!isOctCode(data.charCodeAt(index))) {
		                return false;
		            }
		            hasDigits = true;
		        }
		        return hasDigits;
		    }
		    for (; index < max; index++) {
		        ch = data[index];
		        if (ch === '_') {
		            continue;
		        }
		        if (ch === ':') {
		            break;
		        }
		        if (!isDecCode(data.charCodeAt(index))) {
		            return false;
		        }
		        hasDigits = true;
		    }
		    if (!hasDigits) {
		        return false;
		    }
		    if (ch !== ':') {
		        return true;
		    }
		    return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
		}
		function constructYamlInteger(data) {
		    var value = data, sign = 1, ch, base, digits = [];
		    if (value.indexOf('_') !== -1) {
		        value = value.replace(/_/g, '');
		    }
		    ch = value[0];
		    if (ch === '-' || ch === '+') {
		        if (ch === '-') {
		            sign = -1;
		        }
		        value = value.slice(1);
		        ch = value[0];
		    }
		    if ('0' === value) {
		        return 0;
		    }
		    if (ch === '0') {
		        if (value[1] === 'b') {
		            return sign * parseInt(value.slice(2), 2);
		        }
		        if (value[1] === 'x') {
		            return sign * parseInt(value, 16);
		        }
		        return sign * parseInt(value, 8);
		    }
		    if (value.indexOf(':') !== -1) {
		        value.split(':').forEach(function (v) {
		            digits.unshift(parseInt(v, 10));
		        });
		        value = 0;
		        base = 1;
		        digits.forEach(function (d) {
		            value += (d * base);
		            base *= 60;
		        });
		        return sign * value;
		    }
		    return sign * parseInt(value, 10);
		}
		function isInteger(object) {
		    return ('[object Number]' === Object.prototype.toString.call(object)) && (0 === object % 1 && !common.isNegativeZero(object));
		}
		module.exports = new Type('tag:yaml.org,2002:int', {
		    kind: 'scalar',
		    resolve: resolveYamlInteger,
		    construct: constructYamlInteger,
		    predicate: isInteger,
		    represent: {
		        binary: function (object) {
		            return '0b' + object.toString(2);
		        },
		        octal: function (object) {
		            return '0' + object.toString(8);
		        },
		        decimal: function (object) {
		            return object.toString(10);
		        },
		        hexadecimal: function (object) {
		            return '0x' + object.toString(16).toUpperCase();
		        }
		    },
		    defaultStyle: 'decimal',
		    styleAliases: {
		        binary: [2, 'bin'],
		        octal: [8, 'oct'],
		        decimal: [10, 'dec'],
		        hexadecimal: [16, 'hex']
		    }
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 34 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var common = __webpack_require__(20);
		var Type = __webpack_require__(24);
		var YAML_FLOAT_PATTERN = new RegExp('^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + '|[-+]?\\.(?:inf|Inf|INF)' + '|\\.(?:nan|NaN|NAN))$');
		function resolveYamlFloat(data) {
		    if (null === data) {
		        return false;
		    }
		    var value, sign, base, digits;
		    if (!YAML_FLOAT_PATTERN.test(data)) {
		        return false;
		    }
		    return true;
		}
		function constructYamlFloat(data) {
		    var value, sign, base, digits;
		    value = data.replace(/_/g, '').toLowerCase();
		    sign = '-' === value[0] ? -1 : 1;
		    digits = [];
		    if (0 <= '+-'.indexOf(value[0])) {
		        value = value.slice(1);
		    }
		    if ('.inf' === value) {
		        return (1 === sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
		    }
		    else if ('.nan' === value) {
		        return NaN;
		    }
		    else if (0 <= value.indexOf(':')) {
		        value.split(':').forEach(function (v) {
		            digits.unshift(parseFloat(v, 10));
		        });
		        value = 0.0;
		        base = 1;
		        digits.forEach(function (d) {
		            value += d * base;
		            base *= 60;
		        });
		        return sign * value;
		    }
		    return sign * parseFloat(value, 10);
		}
		function representYamlFloat(object, style) {
		    if (isNaN(object)) {
		        switch (style) {
		            case 'lowercase':
		                return '.nan';
		            case 'uppercase':
		                return '.NAN';
		            case 'camelcase':
		                return '.NaN';
		        }
		    }
		    else if (Number.POSITIVE_INFINITY === object) {
		        switch (style) {
		            case 'lowercase':
		                return '.inf';
		            case 'uppercase':
		                return '.INF';
		            case 'camelcase':
		                return '.Inf';
		        }
		    }
		    else if (Number.NEGATIVE_INFINITY === object) {
		        switch (style) {
		            case 'lowercase':
		                return '-.inf';
		            case 'uppercase':
		                return '-.INF';
		            case 'camelcase':
		                return '-.Inf';
		        }
		    }
		    else if (common.isNegativeZero(object)) {
		        return '-0.0';
		    }
		    return object.toString(10);
		}
		function isFloat(object) {
		    return ('[object Number]' === Object.prototype.toString.call(object)) && (0 !== object % 1 || common.isNegativeZero(object));
		}
		module.exports = new Type('tag:yaml.org,2002:float', {
		    kind: 'scalar',
		    resolve: resolveYamlFloat,
		    construct: constructYamlFloat,
		    predicate: isFloat,
		    represent: representYamlFloat,
		    defaultStyle: 'lowercase'
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 35 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		var YAML_TIMESTAMP_REGEXP = new RegExp('^([0-9][0-9][0-9][0-9])' + '-([0-9][0-9]?)' + '-([0-9][0-9]?)' + '(?:(?:[Tt]|[ \\t]+)' + '([0-9][0-9]?)' + ':([0-9][0-9])' + ':([0-9][0-9])' + '(?:\\.([0-9]*))?' + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + '(?::([0-9][0-9]))?))?)?$');
		function resolveYamlTimestamp(data) {
		    if (null === data) {
		        return false;
		    }
		    var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date;
		    match = YAML_TIMESTAMP_REGEXP.exec(data);
		    if (null === match) {
		        return false;
		    }
		    return true;
		}
		function constructYamlTimestamp(data) {
		    var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date;
		    match = YAML_TIMESTAMP_REGEXP.exec(data);
		    if (null === match) {
		        throw new Error('Date resolve error');
		    }
		    year = +(match[1]);
		    month = +(match[2]) - 1;
		    day = +(match[3]);
		    if (!match[4]) {
		        return new Date(Date.UTC(year, month, day));
		    }
		    hour = +(match[4]);
		    minute = +(match[5]);
		    second = +(match[6]);
		    if (match[7]) {
		        fraction = match[7].slice(0, 3);
		        while (fraction.length < 3) {
		            fraction = fraction + '0';
		        }
		        fraction = +fraction;
		    }
		    if (match[9]) {
		        tz_hour = +(match[10]);
		        tz_minute = +(match[11] || 0);
		        delta = (tz_hour * 60 + tz_minute) * 60000;
		        if ('-' === match[9]) {
		            delta = -delta;
		        }
		    }
		    date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
		    if (delta) {
		        date.setTime(date.getTime() - delta);
		    }
		    return date;
		}
		function representYamlTimestamp(object) {
		    return object.toISOString();
		}
		module.exports = new Type('tag:yaml.org,2002:timestamp', {
		    kind: 'scalar',
		    resolve: resolveYamlTimestamp,
		    construct: constructYamlTimestamp,
		    instanceOf: Date,
		    represent: representYamlTimestamp
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 36 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		function resolveYamlMerge(data) {
		    return '<<' === data || null === data;
		}
		module.exports = new Type('tag:yaml.org,2002:merge', {
		    kind: 'scalar',
		    resolve: resolveYamlMerge
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL21lcmdlLnRzIl0sIm5hbWVzIjpbInJlc29sdmVZYW1sTWVyZ2UiXSwibWFwcGluZ3MiOiJBQUVBLFlBQVksQ0FBQztBQUViLElBQU8sSUFBSSxXQUFXLFNBQVMsQ0FBQyxDQUFDO0FBRWpDLFNBQVMsZ0JBQWdCLENBQUMsSUFBSTtJQUM1QkEsTUFBTUEsQ0FBQ0EsSUFBSUEsS0FBS0EsSUFBSUEsSUFBSUEsSUFBSUEsS0FBS0EsSUFBSUEsQ0FBQ0E7QUFDeENBLENBQUNBO0FBRUQsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyx5QkFBeUIsRUFBRTtJQUNuRCxJQUFJLEVBQUUsUUFBUTtJQUNkLE9BQU8sRUFBRSxnQkFBZ0I7Q0FDMUIsQ0FBQyxDQUFDIiwiZmlsZSI6InNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL21lcmdlLmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uLy4uLy4uLy4uLy4uL3R5cGluZ3MvbWFpbi5kLnRzXCIgLz5cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7XG4gIHJldHVybiAnPDwnID09PSBkYXRhIHx8IG51bGwgPT09IGRhdGE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZVxufSk7XG4iXX0=


	/***/ },
	/* 37 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var NodeBuffer = __webpack_require__(38).Buffer;
		var Type = __webpack_require__(24);
		var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
		function resolveYamlBinary(data) {
		    if (null === data) {
		        return false;
		    }
		    var code, idx, bitlen = 0, len = 0, max = data.length, map = BASE64_MAP;
		    for (idx = 0; idx < max; idx++) {
		        code = map.indexOf(data.charAt(idx));
		        if (code > 64) {
		            continue;
		        }
		        if (code < 0) {
		            return false;
		        }
		        bitlen += 6;
		    }
		    return (bitlen % 8) === 0;
		}
		function constructYamlBinary(data) {
		    var code, idx, tailbits, input = data.replace(/[\r\n=]/g, ''), max = input.length, map = BASE64_MAP, bits = 0, result = [];
		    for (idx = 0; idx < max; idx++) {
		        if ((idx % 4 === 0) && idx) {
		            result.push((bits >> 16) & 0xFF);
		            result.push((bits >> 8) & 0xFF);
		            result.push(bits & 0xFF);
		        }
		        bits = (bits << 6) | map.indexOf(input.charAt(idx));
		    }
		    tailbits = (max % 4) * 6;
		    if (tailbits === 0) {
		        result.push((bits >> 16) & 0xFF);
		        result.push((bits >> 8) & 0xFF);
		        result.push(bits & 0xFF);
		    }
		    else if (tailbits === 18) {
		        result.push((bits >> 10) & 0xFF);
		        result.push((bits >> 2) & 0xFF);
		    }
		    else if (tailbits === 12) {
		        result.push((bits >> 4) & 0xFF);
		    }
		    if (NodeBuffer) {
		        return new NodeBuffer(result);
		    }
		    return result;
		}
		function representYamlBinary(object) {
		    var result = '', bits = 0, idx, tail, max = object.length, map = BASE64_MAP;
		    for (idx = 0; idx < max; idx++) {
		        if ((idx % 3 === 0) && idx) {
		            result += map[(bits >> 18) & 0x3F];
		            result += map[(bits >> 12) & 0x3F];
		            result += map[(bits >> 6) & 0x3F];
		            result += map[bits & 0x3F];
		        }
		        bits = (bits << 8) + object[idx];
		    }
		    tail = max % 3;
		    if (tail === 0) {
		        result += map[(bits >> 18) & 0x3F];
		        result += map[(bits >> 12) & 0x3F];
		        result += map[(bits >> 6) & 0x3F];
		        result += map[bits & 0x3F];
		    }
		    else if (tail === 2) {
		        result += map[(bits >> 10) & 0x3F];
		        result += map[(bits >> 4) & 0x3F];
		        result += map[(bits << 2) & 0x3F];
		        result += map[64];
		    }
		    else if (tail === 1) {
		        result += map[(bits >> 2) & 0x3F];
		        result += map[(bits << 4) & 0x3F];
		        result += map[64];
		        result += map[64];
		    }
		    return result;
		}
		function isBinary(object) {
		    return NodeBuffer && NodeBuffer.isBuffer(object);
		}
		module.exports = new Type('tag:yaml.org,2002:binary', {
		    kind: 'scalar',
		    resolve: resolveYamlBinary,
		    construct: constructYamlBinary,
		    predicate: isBinary,
		    represent: representYamlBinary
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 38 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(5);

	/***/ },
	/* 39 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		var _hasOwnProperty = Object.prototype.hasOwnProperty;
		var _toString = Object.prototype.toString;
		function resolveYamlOmap(data) {
		    if (null === data) {
		        return true;
		    }
		    var objectKeys = [], index, length, pair, pairKey, pairHasKey, object = data;
		    for (index = 0, length = object.length; index < length; index += 1) {
		        pair = object[index];
		        pairHasKey = false;
		        if ('[object Object]' !== _toString.call(pair)) {
		            return false;
		        }
		        for (pairKey in pair) {
		            if (_hasOwnProperty.call(pair, pairKey)) {
		                if (!pairHasKey) {
		                    pairHasKey = true;
		                }
		                else {
		                    return false;
		                }
		            }
		        }
		        if (!pairHasKey) {
		            return false;
		        }
		        if (-1 === objectKeys.indexOf(pairKey)) {
		            objectKeys.push(pairKey);
		        }
		        else {
		            return false;
		        }
		    }
		    return true;
		}
		function constructYamlOmap(data) {
		    return null !== data ? data : [];
		}
		module.exports = new Type('tag:yaml.org,2002:omap', {
		    kind: 'sequence',
		    resolve: resolveYamlOmap,
		    construct: constructYamlOmap
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 40 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		var _toString = Object.prototype.toString;
		function resolveYamlPairs(data) {
		    if (null === data) {
		        return true;
		    }
		    var index, length, pair, keys, result, object = data;
		    result = new Array(object.length);
		    for (index = 0, length = object.length; index < length; index += 1) {
		        pair = object[index];
		        if ('[object Object]' !== _toString.call(pair)) {
		            return false;
		        }
		        keys = Object.keys(pair);
		        if (1 !== keys.length) {
		            return false;
		        }
		        result[index] = [keys[0], pair[keys[0]]];
		    }
		    return true;
		}
		function constructYamlPairs(data) {
		    if (null === data) {
		        return [];
		    }
		    var index, length, pair, keys, result, object = data;
		    result = new Array(object.length);
		    for (index = 0, length = object.length; index < length; index += 1) {
		        pair = object[index];
		        keys = Object.keys(pair);
		        result[index] = [keys[0], pair[keys[0]]];
		    }
		    return result;
		}
		module.exports = new Type('tag:yaml.org,2002:pairs', {
		    kind: 'sequence',
		    resolve: resolveYamlPairs,
		    construct: constructYamlPairs
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 41 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		var _hasOwnProperty = Object.prototype.hasOwnProperty;
		function resolveYamlSet(data) {
		    if (null === data) {
		        return true;
		    }
		    var key, object = data;
		    for (key in object) {
		        if (_hasOwnProperty.call(object, key)) {
		            if (null !== object[key]) {
		                return false;
		            }
		        }
		    }
		    return true;
		}
		function constructYamlSet(data) {
		    return null !== data ? data : {};
		}
		module.exports = new Type('tag:yaml.org,2002:set', {
		    kind: 'mapping',
		    resolve: resolveYamlSet,
		    construct: constructYamlSet
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL3NldC50cyJdLCJuYW1lcyI6WyJyZXNvbHZlWWFtbFNldCIsImNvbnN0cnVjdFlhbWxTZXQiXSwibWFwcGluZ3MiOiJBQUVBLFlBQVksQ0FBQztBQUViLElBQU8sSUFBSSxXQUFXLFNBQVMsQ0FBQyxDQUFDO0FBRWpDLElBQUksZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDO0FBRXRELFNBQVMsY0FBYyxDQUFDLElBQUk7SUFDMUJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLEtBQUtBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO1FBQ2xCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNkQSxDQUFDQTtJQUVEQSxJQUFJQSxHQUFHQSxFQUFFQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUV2QkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDbkJBLEVBQUVBLENBQUNBLENBQUNBLGVBQWVBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3RDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxLQUFLQSxNQUFNQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDekJBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBO1lBQ2ZBLENBQUNBO1FBQ0hBLENBQUNBO0lBQ0hBLENBQUNBO0lBRURBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0FBQ2RBLENBQUNBO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxJQUFJO0lBQzVCQyxNQUFNQSxDQUFDQSxJQUFJQSxLQUFLQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxFQUFFQSxDQUFDQTtBQUNuQ0EsQ0FBQ0E7QUFFRCxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO0lBQ2pELElBQUksRUFBRSxTQUFTO0lBQ2YsT0FBTyxFQUFFLGNBQWM7SUFDdkIsU0FBUyxFQUFFLGdCQUFnQjtDQUM1QixDQUFDLENBQUMiLCJmaWxlIjoic3JjL3JhbWwxL2pzeWFtbC9qcy15YW1sL3R5cGUvc2V0LmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uLy4uLy4uLy4uLy4uL3R5cGluZ3MvbWFpbi5kLnRzXCIgLz5cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIF9oYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sU2V0KGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBrZXksIG9iamVjdCA9IGRhdGE7XG5cbiAgZm9yIChrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgaWYgKG51bGwgIT09IG9iamVjdFtrZXldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFNldChkYXRhKSB7XG4gIHJldHVybiBudWxsICE9PSBkYXRhID8gZGF0YSA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxTZXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldFxufSk7XG4iXX0=


	/***/ },
	/* 42 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../../../typings/main.d.ts" />
		// JS-YAML's default schema for `load` function.
		// It is not described in the YAML specification.
		//
		// This schema is based on JS-YAML's default safe schema and includes
		// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
		//
		// Also this schema is used as default base schema at `Schema.create` function.
		'use strict';
		var Schema = __webpack_require__(23);
		var schema = new Schema({
		    include: [
		        __webpack_require__(22)
		    ],
		    explicit: [
		        __webpack_require__(43),
		        __webpack_require__(44),
		        __webpack_require__(45)
		    ]
		});
		Schema.DEFAULT = schema;
		module.exports = schema;


	/***/ },
	/* 43 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		function resolveJavascriptUndefined() {
		    return true;
		}
		function constructJavascriptUndefined() {
		    return undefined;
		}
		function representJavascriptUndefined() {
		    return '';
		}
		function isUndefined(object) {
		    return 'undefined' === typeof object;
		}
		module.exports = new Type('tag:yaml.org,2002:js/undefined', {
		    kind: 'scalar',
		    resolve: resolveJavascriptUndefined,
		    construct: constructJavascriptUndefined,
		    predicate: isUndefined,
		    represent: representJavascriptUndefined
		});

		//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL2pzL3VuZGVmaW5lZC50cyJdLCJuYW1lcyI6WyJyZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCIsImNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQiLCJyZXByZXNlbnRKYXZhc2NyaXB0VW5kZWZpbmVkIiwiaXNVbmRlZmluZWQiXSwibWFwcGluZ3MiOiJBQUVBLFlBQVksQ0FBQztBQUViLElBQU8sSUFBSSxXQUFXLFlBQVksQ0FBQyxDQUFDO0FBRXBDLFNBQVMsMEJBQTBCO0lBQ2pDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtBQUNkQSxDQUFDQTtBQUVELFNBQVMsNEJBQTRCO0lBRW5DQyxNQUFNQSxDQUFDQSxTQUFTQSxDQUFDQTtBQUNuQkEsQ0FBQ0E7QUFFRCxTQUFTLDRCQUE0QjtJQUNuQ0MsTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7QUFDWkEsQ0FBQ0E7QUFFRCxTQUFTLFdBQVcsQ0FBQyxNQUFNO0lBQ3pCQyxNQUFNQSxDQUFDQSxXQUFXQSxLQUFLQSxPQUFPQSxNQUFNQSxDQUFDQTtBQUN2Q0EsQ0FBQ0E7QUFFRCxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLGdDQUFnQyxFQUFFO0lBQzFELElBQUksRUFBRSxRQUFRO0lBQ2QsT0FBTyxFQUFFLDBCQUEwQjtJQUNuQyxTQUFTLEVBQUUsNEJBQTRCO0lBQ3ZDLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFNBQVMsRUFBRSw0QkFBNEI7Q0FDeEMsQ0FBQyxDQUFDIiwiZmlsZSI6InNyYy9yYW1sMS9qc3lhbWwvanMteWFtbC90eXBlL2pzL3VuZGVmaW5lZC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuLi8uLi8uLi8uLi8uLi8uLi90eXBpbmdzL21haW4uZC50c1wiIC8+XG5cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IFR5cGUgPSByZXF1aXJlKCcuLi8uLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgLyplc2xpbnQtZGlzYWJsZSBuby11bmRlZmluZWQqL1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKG9iamVjdCkge1xuICByZXR1cm4gJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3VuZGVmaW5lZCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQsXG4gIHByZWRpY2F0ZTogaXNVbmRlZmluZWQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZFxufSk7XG4iXX0=


	/***/ },
	/* 44 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var Type = __webpack_require__(24);
		function resolveJavascriptRegExp(data) {
		    if (null === data) {
		        return false;
		    }
		    if (0 === data.length) {
		        return false;
		    }
		    var regexp = data, tail = /\/([gim]*)$/.exec(data), modifiers = '';
		    if ('/' === regexp[0]) {
		        if (tail) {
		            modifiers = tail[1];
		        }
		        if (modifiers.length > 3) {
		            return false;
		        }
		        if (regexp[regexp.length - modifiers.length - 1] !== '/') {
		            return false;
		        }
		        regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
		    }
		    try {
		        var dummy = new RegExp(regexp, modifiers);
		        return true;
		    }
		    catch (error) {
		        return false;
		    }
		}
		function constructJavascriptRegExp(data) {
		    var regexp = data, tail = /\/([gim]*)$/.exec(data), modifiers = '';
		    if ('/' === regexp[0]) {
		        if (tail) {
		            modifiers = tail[1];
		        }
		        regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
		    }
		    return new RegExp(regexp, modifiers);
		}
		function representJavascriptRegExp(object) {
		    var result = '/' + object.source + '/';
		    if (object.global) {
		        result += 'g';
		    }
		    if (object.multiline) {
		        result += 'm';
		    }
		    if (object.ignoreCase) {
		        result += 'i';
		    }
		    return result;
		}
		function isRegExp(object) {
		    return '[object RegExp]' === Object.prototype.toString.call(object);
		}
		module.exports = new Type('tag:yaml.org,2002:js/regexp', {
		    kind: 'scalar',
		    resolve: resolveJavascriptRegExp,
		    construct: constructJavascriptRegExp,
		    predicate: isRegExp,
		    represent: representJavascriptRegExp
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 45 */
	/***/ function(module, exports, __webpack_require__) {

		'use strict';
		var esprima = __webpack_require__(46);
		var Type = __webpack_require__(24);
		function resolveJavascriptFunction(data) {
		    if (null === data) {
		        return false;
		    }
		    try {
		        var source = '(' + data + ')', ast = esprima.parse(source, { range: true }), params = [], body;
		        if ('Program' !== ast.type || 1 !== ast.body.length || 'ExpressionStatement' !== ast.body[0].type || 'FunctionExpression' !== ast.body[0]['expression'].type) {
		            return false;
		        }
		        return true;
		    }
		    catch (err) {
		        return false;
		    }
		}
		function constructJavascriptFunction(data) {
		    var source = '(' + data + ')', ast = esprima.parse(source, { range: true }), params = [], body;
		    if ('Program' !== ast.type || 1 !== ast.body.length || 'ExpressionStatement' !== ast.body[0].type || 'FunctionExpression' !== ast.body[0]['expression'].type) {
		        throw new Error('Failed to resolve function');
		    }
		    ast.body[0]['expression'].params.forEach(function (param) {
		        params.push(param.name);
		    });
		    body = ast.body[0]['expression'].body.range;
		    return new Function(params, source.slice(body[0] + 1, body[1] - 1));
		}
		function representJavascriptFunction(object) {
		    return object.toString();
		}
		function isFunction(object) {
		    return '[object Function]' === Object.prototype.toString.call(object);
		}
		module.exports = new Type('tag:yaml.org,2002:js/function', {
		    kind: 'scalar',
		    resolve: resolveJavascriptFunction,
		    construct: constructJavascriptFunction,
		    predicate: isFunction,
		    represent: representJavascriptFunction
		});

		//# sourceMappingURL=data:application/json;base64, 


	/***/ },
	/* 46 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(9);

	/***/ },
	/* 47 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../../typings/main.d.ts" />
		'use strict';
		/*eslint-disable no-use-before-define*/
		var common = __webpack_require__(20);
		var YAMLException = __webpack_require__(9);
		var DEFAULT_FULL_SCHEMA = __webpack_require__(42);
		var DEFAULT_SAFE_SCHEMA = __webpack_require__(22);
		var _toString = Object.prototype.toString;
		var _hasOwnProperty = Object.prototype.hasOwnProperty;
		var CHAR_TAB = 0x09; /* Tab */
		var CHAR_LINE_FEED = 0x0A; /* LF */
		var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */
		var CHAR_SPACE = 0x20; /* Space */
		var CHAR_EXCLAMATION = 0x21; /* ! */
		var CHAR_DOUBLE_QUOTE = 0x22; /* " */
		var CHAR_SHARP = 0x23; /* # */
		var CHAR_PERCENT = 0x25; /* % */
		var CHAR_AMPERSAND = 0x26; /* & */
		var CHAR_SINGLE_QUOTE = 0x27; /* ' */
		var CHAR_ASTERISK = 0x2A; /* * */
		var CHAR_COMMA = 0x2C; /* , */
		var CHAR_MINUS = 0x2D; /* - */
		var CHAR_COLON = 0x3A; /* : */
		var CHAR_GREATER_THAN = 0x3E; /* > */
		var CHAR_QUESTION = 0x3F; /* ? */
		var CHAR_COMMERCIAL_AT = 0x40; /* @ */
		var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */
		var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
		var CHAR_GRAVE_ACCENT = 0x60; /* ` */
		var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */
		var CHAR_VERTICAL_LINE = 0x7C; /* | */
		var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */
		var ESCAPE_SEQUENCES = {};
		ESCAPE_SEQUENCES[0x00] = '\\0';
		ESCAPE_SEQUENCES[0x07] = '\\a';
		ESCAPE_SEQUENCES[0x08] = '\\b';
		ESCAPE_SEQUENCES[0x09] = '\\t';
		ESCAPE_SEQUENCES[0x0A] = '\\n';
		ESCAPE_SEQUENCES[0x0B] = '\\v';
		ESCAPE_SEQUENCES[0x0C] = '\\f';
		ESCAPE_SEQUENCES[0x0D] = '\\r';
		ESCAPE_SEQUENCES[0x1B] = '\\e';
		ESCAPE_SEQUENCES[0x22] = '\\"';
		ESCAPE_SEQUENCES[0x5C] = '\\\\';
		ESCAPE_SEQUENCES[0x85] = '\\N';
		ESCAPE_SEQUENCES[0xA0] = '\\_';
		ESCAPE_SEQUENCES[0x2028] = '\\L';
		ESCAPE_SEQUENCES[0x2029] = '\\P';
		var DEPRECATED_BOOLEANS_SYNTAX = [
		    'y',
		    'Y',
		    'yes',
		    'Yes',
		    'YES',
		    'on',
		    'On',
		    'ON',
		    'n',
		    'N',
		    'no',
		    'No',
		    'NO',
		    'off',
		    'Off',
		    'OFF'
		];
		function compileStyleMap(schema, map) {
		    var result, keys, index, length, tag, style, type;
		    if (null === map) {
		        return {};
		    }
		    result = {};
		    keys = Object.keys(map);
		    for (index = 0, length = keys.length; index < length; index += 1) {
		        tag = keys[index];
		        style = String(map[tag]);
		        if ('!!' === tag.slice(0, 2)) {
		            tag = 'tag:yaml.org,2002:' + tag.slice(2);
		        }
		        type = schema.compiledTypeMap[tag];
		        if (type && _hasOwnProperty.call(type.styleAliases, style)) {
		            style = type.styleAliases[style];
		        }
		        result[tag] = style;
		    }
		    return result;
		}
		function encodeHex(character) {
		    var string, handle, length;
		    string = character.toString(16).toUpperCase();
		    if (character <= 0xFF) {
		        handle = 'x';
		        length = 2;
		    }
		    else if (character <= 0xFFFF) {
		        handle = 'u';
		        length = 4;
		    }
		    else if (character <= 0xFFFFFFFF) {
		        handle = 'U';
		        length = 8;
		    }
		    else {
		        throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
		    }
		    return '\\' + handle + common.repeat('0', length - string.length) + string;
		}
		function State(options) {
		    this.schema = options['schema'] || DEFAULT_FULL_SCHEMA;
		    this.indent = Math.max(1, (options['indent'] || 2));
		    this.skipInvalid = options['skipInvalid'] || false;
		    this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
		    this.styleMap = compileStyleMap(this.schema, options['styles'] || null);
		    this.implicitTypes = this.schema.compiledImplicit;
		    this.explicitTypes = this.schema.compiledExplicit;
		    this.tag = null;
		    this.result = '';
		    this.duplicates = [];
		    this.usedDuplicates = null;
		}
		function indentString(string, spaces) {
		    var ind = common.repeat(' ', spaces), position = 0, next = -1, result = '', line, length = string.length;
		    while (position < length) {
		        next = string.indexOf('\n', position);
		        if (next === -1) {
		            line = string.slice(position);
		            position = length;
		        }
		        else {
		            line = string.slice(position, next + 1);
		            position = next + 1;
		        }
		        if (line.length && line !== '\n') {
		            result += ind;
		        }
		        result += line;
		    }
		    return result;
		}
		function generateNextLine(state, level) {
		    return '\n' + common.repeat(' ', state.indent * level);
		}
		function testImplicitResolving(state, str) {
		    var index, length, type;
		    for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
		        type = state.implicitTypes[index];
		        if (type.resolve(str)) {
		            return true;
		        }
		    }
		    return false;
		}
		function StringBuilder(source) {
		    this.source = source;
		    this.result = '';
		    this.checkpoint = 0;
		}
		StringBuilder.prototype.takeUpTo = function (position) {
		    var er;
		    if (position < this.checkpoint) {
		        er = new Error('position should be > checkpoint');
		        er.position = position;
		        er.checkpoint = this.checkpoint;
		        throw er;
		    }
		    this.result += this.source.slice(this.checkpoint, position);
		    this.checkpoint = position;
		    return this;
		};
		StringBuilder.prototype.escapeChar = function () {
		    var character, esc;
		    character = this.source.charCodeAt(this.checkpoint);
		    esc = ESCAPE_SEQUENCES[character] || encodeHex(character);
		    this.result += esc;
		    this.checkpoint += 1;
		    return this;
		};
		StringBuilder.prototype.finish = function () {
		    if (this.source.length > this.checkpoint) {
		        this.takeUpTo(this.source.length);
		    }
		};
		function writeScalar(state, object, level) {
		    var simple, first, spaceWrap, folded, literal, single, double, sawLineFeed, linePosition, longestLine, indent, max, character, position, escapeSeq, hexEsc, previous, lineLength, modifier, trailingLineBreaks, result;
		    if (0 === object.length) {
		        state.dump = "''";
		        return;
		    }
		    if (object.indexOf("!include") == 0) {
		        state.dump = "" + object; //FIXME
		        return;
		    }
		    if (object.indexOf("!$$$novalue") == 0) {
		        state.dump = ""; //FIXME
		        return;
		    }
		    if (-1 !== DEPRECATED_BOOLEANS_SYNTAX.indexOf(object)) {
		        state.dump = "'" + object + "'";
		        return;
		    }
		    simple = true;
		    first = object.length ? object.charCodeAt(0) : 0;
		    spaceWrap = (CHAR_SPACE === first || CHAR_SPACE === object.charCodeAt(object.length - 1));
		    // Simplified check for restricted first characters
		    // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29
		    if (CHAR_MINUS === first || CHAR_QUESTION === first || CHAR_COMMERCIAL_AT === first || CHAR_GRAVE_ACCENT === first) {
		        simple = false;
		    }
		    // can only use > and | if not wrapped in spaces.
		    if (spaceWrap) {
		        simple = false;
		        folded = false;
		        literal = false;
		    }
		    else {
		        folded = true;
		        literal = true;
		    }
		    single = true;
		    double = new StringBuilder(object);
		    sawLineFeed = false;
		    linePosition = 0;
		    longestLine = 0;
		    indent = state.indent * level;
		    max = 80;
		    if (indent < 40) {
		        max -= indent;
		    }
		    else {
		        max = 40;
		    }
		    for (position = 0; position < object.length; position++) {
		        character = object.charCodeAt(position);
		        if (simple) {
		            // Characters that can never appear in the simple scalar
		            if (!simpleChar(character)) {
		                simple = false;
		            }
		            else {
		                continue;
		            }
		        }
		        if (single && character === CHAR_SINGLE_QUOTE) {
		            single = false;
		        }
		        escapeSeq = ESCAPE_SEQUENCES[character];
		        hexEsc = needsHexEscape(character);
		        if (!escapeSeq && !hexEsc) {
		            continue;
		        }
		        if (character !== CHAR_LINE_FEED && character !== CHAR_DOUBLE_QUOTE && character !== CHAR_SINGLE_QUOTE) {
		            folded = false;
		            literal = false;
		        }
		        else if (character === CHAR_LINE_FEED) {
		            sawLineFeed = true;
		            single = false;
		            if (position > 0) {
		                previous = object.charCodeAt(position - 1);
		                if (previous === CHAR_SPACE) {
		                    literal = false;
		                    folded = false;
		                }
		            }
		            if (folded) {
		                lineLength = position - linePosition;
		                linePosition = position;
		                if (lineLength > longestLine) {
		                    longestLine = lineLength;
		                }
		            }
		        }
		        if (character !== CHAR_DOUBLE_QUOTE) {
		            single = false;
		        }
		        double.takeUpTo(position);
		        double.escapeChar();
		    }
		    if (simple && testImplicitResolving(state, object)) {
		        simple = false;
		    }
		    modifier = '';
		    if (folded || literal) {
		        trailingLineBreaks = 0;
		        if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) {
		            trailingLineBreaks += 1;
		            if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) {
		                trailingLineBreaks += 1;
		            }
		        }
		        if (trailingLineBreaks === 0) {
		            modifier = '-';
		        }
		        else if (trailingLineBreaks === 2) {
		            modifier = '+';
		        }
		    }
		    if (literal && longestLine < max) {
		        folded = false;
		    }
		    // If it's literally one line, then don't bother with the literal.
		    // We may still want to do a fold, though, if it's a super long line.
		    if (!sawLineFeed) {
		        literal = false;
		    }
		    if (simple) {
		        state.dump = object;
		    }
		    else if (single) {
		        state.dump = '\'' + object + '\'';
		    }
		    else if (folded) {
		        result = fold(object, max);
		        state.dump = '>' + modifier + '\n' + indentString(result, indent);
		    }
		    else if (literal) {
		        if (!modifier) {
		            object = object.replace(/\n$/, '');
		        }
		        state.dump = '|' + modifier + '\n' + indentString(object, indent);
		    }
		    else if (double) {
		        double.finish();
		        state.dump = '"' + double.result + '"';
		    }
		    else {
		        throw new Error('Failed to dump scalar value');
		    }
		    return;
		}
		// The `trailing` var is a regexp match of any trailing `\n` characters.
		//
		// There are three cases we care about:
		//
		// 1. One trailing `\n` on the string.  Just use `|` or `>`.
		//    This is the assumed default. (trailing = null)
		// 2. No trailing `\n` on the string.  Use `|-` or `>-` to "chomp" the end.
		// 3. More than one trailing `\n` on the string.  Use `|+` or `>+`.
		//
		// In the case of `>+`, these line breaks are *not* doubled (like the line
		// breaks within the string), so it's important to only end with the exact
		// same number as we started.
		function fold(object, max) {
		    var result = '', position = 0, length = object.length, trailing = /\n+$/.exec(object), newLine;
		    if (trailing) {
		        length = trailing.index + 1;
		    }
		    while (position < length) {
		        newLine = object.indexOf('\n', position);
		        if (newLine > length || newLine === -1) {
		            if (result) {
		                result += '\n\n';
		            }
		            result += foldLine(object.slice(position, length), max);
		            position = length;
		        }
		        else {
		            if (result) {
		                result += '\n\n';
		            }
		            result += foldLine(object.slice(position, newLine), max);
		            position = newLine + 1;
		        }
		    }
		    if (trailing && trailing[0] !== '\n') {
		        result += trailing[0];
		    }
		    return result;
		}
		function foldLine(line, max) {
		    if (line === '') {
		        return line;
		    }
		    var foldRe = /[^\s] [^\s]/g, result = '', prevMatch = 0, foldStart = 0, match = foldRe.exec(line), index, foldEnd, folded;
		    while (match) {
		        index = match.index;
		        // when we cross the max len, if the previous match would've
		        // been ok, use that one, and carry on.  If there was no previous
		        // match on this fold section, then just have a long line.
		        if (index - foldStart > max) {
		            if (prevMatch !== foldStart) {
		                foldEnd = prevMatch;
		            }
		            else {
		                foldEnd = index;
		            }
		            if (result) {
		                result += '\n';
		            }
		            folded = line.slice(foldStart, foldEnd);
		            result += folded;
		            foldStart = foldEnd + 1;
		        }
		        prevMatch = index + 1;
		        match = foldRe.exec(line);
		    }
		    if (result) {
		        result += '\n';
		    }
		    // if we end up with one last word at the end, then the last bit might
		    // be slightly bigger than we wanted, because we exited out of the loop.
		    if (foldStart !== prevMatch && line.length - foldStart > max) {
		        result += line.slice(foldStart, prevMatch) + '\n' + line.slice(prevMatch + 1);
		    }
		    else {
		        result += line.slice(foldStart);
		    }
		    return result;
		}
		// Returns true if character can be found in a simple scalar
		function simpleChar(character) {
		    return CHAR_TAB !== character && CHAR_LINE_FEED !== character && CHAR_CARRIAGE_RETURN !== character && CHAR_COMMA !== character && CHAR_LEFT_SQUARE_BRACKET !== character && CHAR_RIGHT_SQUARE_BRACKET !== character && CHAR_LEFT_CURLY_BRACKET !== character && CHAR_RIGHT_CURLY_BRACKET !== character && CHAR_SHARP !== character && CHAR_AMPERSAND !== character && CHAR_ASTERISK !== character && CHAR_EXCLAMATION !== character && CHAR_VERTICAL_LINE !== character && CHAR_GREATER_THAN !== character && CHAR_SINGLE_QUOTE !== character && CHAR_DOUBLE_QUOTE !== character && CHAR_PERCENT !== character && CHAR_COLON !== character && !ESCAPE_SEQUENCES[character] && !needsHexEscape(character);
		}
		// Returns true if the character code needs to be escaped.
		function needsHexEscape(character) {
		    return !((0x00020 <= character && character <= 0x00007E) || (0x00085 === character) || (0x000A0 <= character && character <= 0x00D7FF) || (0x0E000 <= character && character <= 0x00FFFD) || (0x10000 <= character && character <= 0x10FFFF));
		}
		function writeFlowSequence(state, level, object) {
		    var _result = '', _tag = state.tag, index, length;
		    for (index = 0, length = object.length; index < length; index += 1) {
		        // Write only valid elements.
		        if (writeNode(state, level, object[index], false, false)) {
		            if (0 !== index) {
		                _result += ', ';
		            }
		            _result += state.dump;
		        }
		    }
		    state.tag = _tag;
		    state.dump = '[' + _result + ']';
		}
		function writeBlockSequence(state, level, object, compact) {
		    var _result = '', _tag = state.tag, index, length;
		    for (index = 0, length = object.length; index < length; index += 1) {
		        // Write only valid elements.
		        if (writeNode(state, level + 1, object[index], true, true)) {
		            if (!compact || 0 !== index) {
		                _result += generateNextLine(state, level);
		            }
		            _result += '- ' + state.dump;
		        }
		    }
		    state.tag = _tag;
		    state.dump = _result || '[]'; // Empty sequence if no valid values.
		}
		function writeFlowMapping(state, level, object) {
		    var _result = '', _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, pairBuffer;
		    for (index = 0, length = objectKeyList.length; index < length; index += 1) {
		        pairBuffer = '';
		        if (0 !== index) {
		            pairBuffer += ', ';
		        }
		        objectKey = objectKeyList[index];
		        objectValue = object[objectKey];
		        if (!writeNode(state, level, objectKey, false, false)) {
		            continue;
		        }
		        if (state.dump.length > 1024) {
		            pairBuffer += '? ';
		        }
		        pairBuffer += state.dump + ': ';
		        if (!writeNode(state, level, objectValue, false, false)) {
		            continue;
		        }
		        pairBuffer += state.dump;
		        // Both key and value are valid.
		        _result += pairBuffer;
		    }
		    state.tag = _tag;
		    state.dump = '{' + _result + '}';
		}
		function writeBlockMapping(state, level, object, compact) {
		    var _result = '', _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, explicitPair, pairBuffer;
		    for (index = 0, length = objectKeyList.length; index < length; index += 1) {
		        pairBuffer = '';
		        if (!compact || 0 !== index) {
		            pairBuffer += generateNextLine(state, level);
		        }
		        objectKey = objectKeyList[index];
		        objectValue = object[objectKey];
		        if (!writeNode(state, level + 1, objectKey, true, true)) {
		            continue;
		        }
		        explicitPair = (null !== state.tag && '?' !== state.tag) || (state.dump && state.dump.length > 1024);
		        if (explicitPair) {
		            if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
		                pairBuffer += '?';
		            }
		            else {
		                pairBuffer += '? ';
		            }
		        }
		        pairBuffer += state.dump;
		        if (explicitPair) {
		            pairBuffer += generateNextLine(state, level);
		        }
		        if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
		            continue;
		        }
		        if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
		            pairBuffer += ':';
		        }
		        else {
		            pairBuffer += ': ';
		        }
		        pairBuffer += state.dump;
		        // Both key and value are valid.
		        _result += pairBuffer;
		    }
		    state.tag = _tag;
		    state.dump = _result || '{}'; // Empty mapping if no valid pairs.
		}
		function detectType(state, object, explicit) {
		    var _result, typeList, index, length, type, style;
		    typeList = explicit ? state.explicitTypes : state.implicitTypes;
		    for (index = 0, length = typeList.length; index < length; index += 1) {
		        type = typeList[index];
		        if ((type.instanceOf || type.predicate) && (!type.instanceOf || (('object' === typeof object) && (object instanceof type.instanceOf))) && (!type.predicate || type.predicate(object))) {
		            state.tag = explicit ? type.tag : '?';
		            if (type.represent) {
		                style = state.styleMap[type.tag] || type.defaultStyle;
		                if ('[object Function]' === _toString.call(type.represent)) {
		                    _result = type.represent(object, style);
		                }
		                else if (_hasOwnProperty.call(type.represent, style)) {
		                    _result = type.represent[style](object, style);
		                }
		                else {
		                    throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
		                }
		                state.dump = _result;
		            }
		            return true;
		        }
		    }
		    return false;
		}
		// Serializes `object` and writes it to global `result`.
		// Returns true on success, or false on invalid object.
		//
		function writeNode(state, level, object, block, compact) {
		    state.tag = null;
		    state.dump = object;
		    if (!detectType(state, object, false)) {
		        detectType(state, object, true);
		    }
		    var type = _toString.call(state.dump);
		    if (block) {
		        block = (0 > state.flowLevel || state.flowLevel > level);
		    }
		    if ((null !== state.tag && '?' !== state.tag) || (2 !== state.indent && level > 0)) {
		        compact = false;
		    }
		    var objectOrArray = '[object Object]' === type || '[object Array]' === type, duplicateIndex, duplicate;
		    if (objectOrArray) {
		        duplicateIndex = state.duplicates.indexOf(object);
		        duplicate = duplicateIndex !== -1;
		    }
		    if (duplicate && state.usedDuplicates[duplicateIndex]) {
		        state.dump = '*ref_' + duplicateIndex;
		    }
		    else {
		        if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
		            state.usedDuplicates[duplicateIndex] = true;
		        }
		        if ('[object Object]' === type) {
		            if (block && (0 !== Object.keys(state.dump).length)) {
		                writeBlockMapping(state, level, state.dump, compact);
		                if (duplicate) {
		                    state.dump = '&ref_' + duplicateIndex + (0 === level ? '\n' : '') + state.dump;
		                }
		            }
		            else {
		                writeFlowMapping(state, level, state.dump);
		                if (duplicate) {
		                    state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
		                }
		            }
		        }
		        else if ('[object Array]' === type) {
		            if (block && (0 !== state.dump.length)) {
		                writeBlockSequence(state, level, state.dump, compact);
		                if (duplicate) {
		                    state.dump = '&ref_' + duplicateIndex + (0 === level ? '\n' : '') + state.dump;
		                }
		            }
		            else {
		                writeFlowSequence(state, level, state.dump);
		                if (duplicate) {
		                    state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
		                }
		            }
		        }
		        else if ('[object String]' === type) {
		            if ('?' !== state.tag) {
		                writeScalar(state, state.dump, level);
		            }
		        }
		        else {
		            if (state.skipInvalid) {
		                return false;
		            }
		            throw new YAMLException('unacceptable kind of an object to dump ' + type);
		        }
		        if (null !== state.tag && '?' !== state.tag) {
		            state.dump = '!<' + state.tag + '> ' + state.dump;
		        }
		    }
		    return true;
		}
		function getDuplicateReferences(object, state) {
		    var objects = [], duplicatesIndexes = [], index, length;
		    inspectNode(object, objects, duplicatesIndexes);
		    for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
		        state.duplicates.push(objects[duplicatesIndexes[index]]);
		    }
		    state.usedDuplicates = new Array(length);
		}
		function inspectNode(object, objects, duplicatesIndexes) {
		    var type = _toString.call(object), objectKeyList, index, length;
		    if (null !== object && 'object' === typeof object) {
		        index = objects.indexOf(object);
		        if (-1 !== index) {
		            if (-1 === duplicatesIndexes.indexOf(index)) {
		                duplicatesIndexes.push(index);
		            }
		        }
		        else {
		            objects.push(object);
		            if (Array.isArray(object)) {
		                for (index = 0, length = object.length; index < length; index += 1) {
		                    inspectNode(object[index], objects, duplicatesIndexes);
		                }
		            }
		            else {
		                objectKeyList = Object.keys(object);
		                for (index = 0, length = objectKeyList.length; index < length; index += 1) {
		                    inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
		                }
		            }
		        }
		    }
		}
		function dump(input, options) {
		    options = options || {};
		    var state = new State(options);
		    getDuplicateReferences(input, state);
		    if (writeNode(state, 0, input, true, true)) {
		        return state.dump + '\n';
		    }
		    return '';
		}
		exports.dump = dump;
		function safeDump(input, options) {
		    return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
		}
		exports.safeDump = safeDump;


	/***/ },
	/* 48 */
	/***/ function(module, exports) {

		/// <reference path="../../typings/main.d.ts" />
		function isMultiLine(s) {
		    return s && s.indexOf('\n') >= 0;
		}
		exports.isMultiLine = isMultiLine;
		function isMultiLineValue(s) {
		    return isMultiLine(s) && s.length > 2 && s[0] == '|' && (s[1] == '\n' || s[1] == '\r' || s[2] == '\n');
		}
		exports.isMultiLineValue = isMultiLineValue;
		function makeMutiLine(s, lev) {
		    var xbuf = '';
		    if (isMultiLine(s)) {
		        xbuf += '|\n';
		        var lines = splitOnLines(s);
		        for (var i = 0; i < lines.length; i++) {
		            xbuf += indent(lev, lines[i]);
		        }
		    }
		    else {
		        xbuf += s;
		    }
		    return xbuf;
		}
		exports.makeMutiLine = makeMutiLine;
		function fromMutiLine(s) {
		    if (!isMultiLineValue(s))
		        return s;
		    var res = null;
		    var lines = splitOnLines(s);
		    for (var i = 1; i < lines.length; i++) {
		        var line = lines[i];
		        var str = line.substring(2);
		        if (!res)
		            res = str;
		        else
		            res += str;
		    }
		    return res;
		}
		exports.fromMutiLine = fromMutiLine;
		function trimStart(s) {
		    if (!s)
		        return s;
		    var pos = 0;
		    while (pos < s.length) {
		        var ch = s[pos];
		        if (ch != '\r' && ch != '\n' && ch != ' ' && ch != '\t')
		            break;
		        pos++;
		    }
		    return s.substring(pos, s.length);
		}
		exports.trimStart = trimStart;
		function indent(lev, str) {
		    if (str === void 0) { str = ''; }
		    var leading = '';
		    for (var i = 0; i < lev; i++)
		        leading += '  ';
		    return leading + str;
		}
		exports.indent = indent;
		function print(lev, str) {
		    if (str === void 0) { str = ''; }
		    console.log(indent(lev, str));
		}
		exports.print = print;
		function replaceNewlines(s, rep) {
		    if (rep === void 0) { rep = null; }
		    var res = '';
		    for (var i = 0; i < s.length; i++) {
		        var ch = s[i];
		        if (ch == '\r')
		            ch = rep == null ? '\\r' : rep;
		        if (ch == '\n')
		            ch = rep == null ? '\\n' : rep;
		        res += ch;
		    }
		    return res;
		}
		exports.replaceNewlines = replaceNewlines;
		function trimEnd(s) {
		    var pos = s.length;
		    while (pos > 0) {
		        var ch = s[pos - 1];
		        if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n')
		            break;
		        pos--;
		    }
		    return s.substring(0, pos);
		}
		exports.trimEnd = trimEnd;
		function splitOnLines(text) {
		    var lines = text.match(/^.*((\r\n|\n|\r)|$)/gm);
		    return lines;
		}
		exports.splitOnLines = splitOnLines;
		function startsWith(s, suffix) {
		    if (!s || !suffix || s.length < suffix.length)
		        return false;
		    for (var i = 0; i < suffix.length; i++) {
		        if (s[i] != suffix[i])
		            return false;
		    }
		    return true;
		}
		exports.startsWith = startsWith;
		function endsWith(s, suffix) {
		    if (!s || !suffix || s.length < suffix.length)
		        return false;
		    for (var i = 0; i < suffix.length; i++) {
		        if (s[s.length - 1 - i] != suffix[suffix.length - 1 - i])
		            return false;
		    }
		    return true;
		}
		exports.endsWith = endsWith;
		var TextRange = (function () {
		    function TextRange(contents, start, end) {
		        this.contents = contents;
		        this.start = start;
		        this.end = end;
		    }
		    TextRange.prototype.text = function () {
		        return this.contents.substring(this.start, this.end);
		    };
		    TextRange.prototype.startpos = function () {
		        return this.start;
		    };
		    TextRange.prototype.endpos = function () {
		        return this.end;
		    };
		    TextRange.prototype.len = function () {
		        return this.end - this.start;
		    };
		    TextRange.prototype.unitText = function () {
		        return this.contents;
		    };
		    TextRange.prototype.withStart = function (start) {
		        return new TextRange(this.contents, start, this.end);
		    };
		    TextRange.prototype.withEnd = function (end) {
		        return new TextRange(this.contents, this.start, end);
		    };
		    TextRange.prototype.sub = function (start, end) {
		        return this.contents.substring(start, end);
		    };
		    TextRange.prototype.trimStart = function () {
		        var pos = this.start;
		        while (pos < this.contents.length - 1) {
		            var ch = this.contents[pos];
		            if (ch != ' ' && ch != '\t')
		                break;
		            pos++;
		        }
		        return new TextRange(this.contents, pos, this.end);
		    };
		    TextRange.prototype.trimEnd = function () {
		        var pos = this.end;
		        while (pos > 0) {
		            var ch = this.contents[pos - 1];
		            if (ch != ' ' && ch != '\t')
		                break;
		            pos--;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.extendToStartOfLine = function () {
		        var pos = this.start;
		        while (pos > 0) {
		            var prevchar = this.contents[pos - 1];
		            if (prevchar == '\r' || prevchar == '\n')
		                break;
		            pos--;
		        }
		        return new TextRange(this.contents, pos, this.end);
		    };
		    TextRange.prototype.extendAnyUntilNewLines = function () {
		        var pos = this.end;
		        if (pos > 0) {
		            var last = this.contents[pos - 1];
		            if (last == '\n')
		                return this;
		        }
		        while (pos < this.contents.length - 1) {
		            var nextchar = this.contents[pos];
		            if (nextchar == '\r' || nextchar == '\n')
		                break;
		            pos++;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.extendSpacesUntilNewLines = function () {
		        var pos = this.end;
		        if (pos > 0) {
		            var last = this.contents[pos - 1];
		            if (last == '\n')
		                return this;
		        }
		        while (pos < this.contents.length - 1) {
		            var nextchar = this.contents[pos];
		            if (nextchar != ' ' || nextchar == '\r' || nextchar == '\n')
		                break;
		            pos++;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.extendSpaces = function () {
		        var pos = this.end;
		        while (pos < this.contents.length - 1) {
		            var nextchar = this.contents[pos];
		            if (nextchar != ' ')
		                break;
		            pos++;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.extendSpacesBack = function () {
		        var pos = this.start;
		        while (pos > 0) {
		            var nextchar = this.contents[pos - 1];
		            if (nextchar != ' ')
		                break;
		            pos--;
		        }
		        return new TextRange(this.contents, pos, this.end);
		    };
		    TextRange.prototype.extendCharIfAny = function (ch) {
		        var pos = this.end;
		        if (pos < this.contents.length - 1 && this.contents[pos] == ch) {
		            pos++;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.extendCharIfAnyBack = function (ch) {
		        var pos = this.start;
		        if (pos > 0 && this.contents[pos - 1] == ch) {
		            pos--;
		        }
		        return new TextRange(this.contents, pos, this.end);
		    };
		    TextRange.prototype.extendToNewlines = function () {
		        var pos = this.end;
		        if (pos > 0) {
		            var last = this.contents[pos - 1];
		            if (last == '\n')
		                return this;
		        }
		        while (pos < this.contents.length - 1) {
		            var nextchar = this.contents[pos];
		            if (nextchar != '\r' && nextchar != '\n')
		                break;
		            pos++;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.extendUntilNewlinesBack = function () {
		        var pos = this.start;
		        while (pos > 0) {
		            var nextchar = this.contents[pos - 1];
		            if (nextchar == '\r' || nextchar == '\n')
		                break;
		            pos--;
		        }
		        return new TextRange(this.contents, pos, this.end);
		    };
		    TextRange.prototype.reduceNewlinesEnd = function () {
		        var pos = this.end;
		        while (pos > this.start) {
		            var last = this.contents[pos - 1];
		            if (last != '\r' && last != '\n')
		                break;
		            pos--;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.reduceSpaces = function () {
		        var pos = this.end;
		        while (pos > this.start) {
		            var last = this.contents[pos - 1];
		            if (last != ' ')
		                break;
		            pos--;
		        }
		        return new TextRange(this.contents, this.start, pos);
		    };
		    TextRange.prototype.replace = function (text) {
		        return this.sub(0, this.start) + text + this.sub(this.end, this.unitText().length);
		    };
		    TextRange.prototype.remove = function () {
		        return this.sub(0, this.start) + this.sub(this.end, this.unitText().length);
		    };
		    return TextRange;
		})();
		exports.TextRange = TextRange;


	/***/ },
	/* 49 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var _ = __webpack_require__(4);
		var hlImpl = __webpack_require__(5);
		var jsyaml = __webpack_require__(15);
		var typeBuilder = __webpack_require__(50);
		var typeSystem = __webpack_require__(63);
		var search = __webpack_require__(53);
		var def = __webpack_require__(3);
		var universes = __webpack_require__(54);
		var su = __webpack_require__(56);
		var RAMLPropertyDocumentationService = (function () {
		    function RAMLPropertyDocumentationService() {
		    }
		    RAMLPropertyDocumentationService.prototype.setDocTableName = function (val) {
		        this._documentationTableName = val;
		    };
		    RAMLPropertyDocumentationService.prototype.docTableName = function () {
		        return this._documentationTableName;
		    };
		    RAMLPropertyDocumentationService.prototype.setHidden = function (val) {
		        this._isHidden = val;
		    };
		    RAMLPropertyDocumentationService.prototype.isHidden = function () {
		        return this._isHidden;
		    };
		    RAMLPropertyDocumentationService.prototype.setMarkdownDescription = function (val) {
		        this._markdownDescription = val;
		    };
		    RAMLPropertyDocumentationService.prototype.markdownDescription = function () {
		        return this._markdownDescription;
		    };
		    RAMLPropertyDocumentationService.prototype.setValueDescription = function (val) {
		        this._valueDescription = val;
		    };
		    RAMLPropertyDocumentationService.prototype.valueDescription = function () {
		        return this._valueDescription;
		    };
		    return RAMLPropertyDocumentationService;
		})();
		exports.RAMLPropertyDocumentationService = RAMLPropertyDocumentationService;
		var RAMLPropertyParserService = (function (_super) {
		    __extends(RAMLPropertyParserService, _super);
		    function RAMLPropertyParserService() {
		        _super.apply(this, arguments);
		    }
		    RAMLPropertyParserService.prototype.isSystem = function () {
		        return this._isSystemProperty;
		    };
		    RAMLPropertyParserService.prototype.withSystem = function (s) {
		        this._isSystemProperty = s;
		        return this;
		    };
		    RAMLPropertyParserService.prototype.isEmbedMap = function () {
		        return this._isEmbededMap;
		    };
		    RAMLPropertyParserService.prototype.withEmbedMap = function () {
		        this._isEmbededMap = true;
		        return this;
		    };
		    return RAMLPropertyParserService;
		})(RAMLPropertyDocumentationService);
		exports.RAMLPropertyParserService = RAMLPropertyParserService;
		var RAMLPropertyService = (function (_super) {
		    __extends(RAMLPropertyService, _super);
		    function RAMLPropertyService(_property) {
		        _super.call(this);
		        this._property = _property;
		        if (!_property) {
		            throw new Error();
		        }
		        _super.call(this);
		    }
		    RAMLPropertyService.prototype.valueDocProvider = function () {
		        return this._property.valueDocProvider();
		    };
		    RAMLPropertyService.prototype.withPropertyGrammarType = function (pt) {
		        this._propertyGrammarType = pt;
		    };
		    RAMLPropertyService.prototype.getPropertyGrammarType = function () {
		        return this._propertyGrammarType;
		    };
		    RAMLPropertyService.prototype.id = function () {
		        return this._property.nameId();
		    };
		    RAMLPropertyService.prototype.range = function () {
		        return this._property.range();
		    };
		    RAMLPropertyService.prototype.domain = function () {
		        return this._property.domain();
		    };
		    RAMLPropertyService.prototype.createAttr = function (val) {
		        var lowLevel = jsyaml.createMapping(this._property.nameId(), val);
		        var nm = new hlImpl.ASTPropImpl(lowLevel, null, this.range(), this._property);
		        return nm;
		    };
		    RAMLPropertyService.prototype.isValidValue = function (vl, c) {
		        var node = search.declRoot(c);
		        if (!node._cach) {
		            node._cach = {};
		        }
		        var id = this.id();
		        if (this.domain()) {
		            id += this.domain().nameId();
		        }
		        if (id) {
		            var cached = node._cach[id];
		            if (cached) {
		                return cached[vl] != null;
		            }
		        }
		        var vls = this.enumValues(c);
		        var mm = {};
		        vls.forEach(function (x) { return mm[x] = 1; });
		        if (this.id()) {
		            node._cach[id] = mm;
		        }
		        return mm[vl] != null;
		    };
		    RAMLPropertyService.prototype.enumValues = function (c) {
		        if (c) {
		            var rs = [];
		            //TODO FIXME it is very very weird idea but I need to get it working right now
		            if (this.isTypeExpr()) {
		                var definitionNodes = search.globalDeclarations(c).filter(function (node) {
		                    var nc = node.definition().key();
		                    if (nc === universes.Universe08.GlobalSchema || nc === universes.Universe10.GlobalSchema) {
		                        return true;
		                    }
		                    return (node.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name));
		                    //return true;
		                });
		                rs = definitionNodes.map(function (x) { return hlImpl.qName(x, c); });
		                var de = c.definition().universe().type(universes.Universe10.TypeDeclaration.name);
		                if (de) {
		                    var subTypes = de.allSubTypes();
		                    rs = rs.concat(subTypes.map(function (x) { return (x).getAdapter(RAMLService).descriminatorValue(); }));
		                }
		                return rs;
		            }
		            else {
		                if (this.range().key() == universes.Universe08.SchemaString || this.range().key() == universes.Universe10.SchemaString) {
		                    if (this.range().universe().version() == "RAML10") {
		                        if (this.range().hasValueTypeInHierarchy()) {
		                            var definitionNodes = search.globalDeclarations(c).filter(function (node) {
		                                if (node.definition().key() == universes.Universe10.GlobalSchema) {
		                                    return true;
		                                }
		                                return node.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name);
		                            });
		                            rs = definitionNodes.map(function (x) { return hlImpl.qName(x, c); });
		                        }
		                    }
		                }
		            }
		            if (this.isDescriminating()) {
		                var subTypes = search.subTypesWithLocals(this.domain(), c);
		                rs = rs.concat(subTypes.map(function (x) { return (x).getAdapter(RAMLService).descriminatorValue(); }));
		            }
		            else if (this.isReference()) {
		                rs = search.nodesDeclaringType(this.referencesTo(), c).map(function (x) { return hlImpl.qName(x, c); });
		            }
		            else if (this.range().hasValueTypeInHierarchy() && this.range().hasValueTypeInHierarchy()) {
		                var vt = this.range().getAdapter(RAMLService);
		                if (vt.globallyDeclaredBy().length > 0) {
		                    var definitionNodes = search.globalDeclarations(c).filter(function (z) { return _.find(vt.globallyDeclaredBy(), function (x) { return x == z.definition(); }) != null; });
		                    rs = rs.concat(definitionNodes.map(function (x) { return hlImpl.qName(x, c); }));
		                }
		            }
		            if (this.isAllowNull()) {
		                rs.push("null");
		            }
		            if (this._property.enumOptions()) {
		                rs = rs.concat(this._property.enumOptions());
		            }
		            return rs;
		        }
		        if (this._property.enumOptions() && typeof this._property.enumOptions() == 'string') {
		            return [this._property.enumOptions() + ""];
		        }
		        return this._property.enumOptions();
		    };
		    RAMLPropertyService.prototype.isAllowNull = function () {
		        return this._property.isAllowNull();
		    };
		    RAMLPropertyService.prototype.referencesTo = function () {
		        return this._property.referencesTo();
		    };
		    RAMLPropertyService.prototype.isReference = function () {
		        return this._property.isReference();
		    };
		    RAMLPropertyService.prototype.nameId = function () {
		        return this._property.nameId();
		    };
		    RAMLPropertyService.prototype.priority = function () {
		        if (this.isKey())
		            return 128;
		        else if (this.isReference())
		            return 64;
		        else if (this.isTypeExpr())
		            return 32;
		        else if (this.nameId() == 'example')
		            return 0;
		        else
		            return -1024;
		    };
		    RAMLPropertyService.prototype.isKey = function () {
		        if (this._property instanceof def.Property) {
		            return this._property.isKey();
		        }
		        return false;
		    };
		    RAMLPropertyService.prototype.isMerged = function () {
		        if (this._property instanceof def.Property) {
		            return this._property.isMerged();
		        }
		        return false;
		    };
		    RAMLPropertyService.prototype.isTypeExpr = function () {
		        if (this.teDef && false) {
		            return this.texpr;
		        }
		        if (this.domain()) {
		            var dc = this.domain().key();
		            this.texpr = ((this.nameId() == universes.Universe10.TypeDeclaration.properties.type.name || this.nameId() == universes.Universe10.TypeDeclaration.properties.schema.name) && dc == universes.Universe10.TypeDeclaration) || (this.nameId() == universes.Universe08.BodyLike.properties.schema.name && dc === universes.Universe08.BodyLike);
		        }
		        if (!this.texpr) {
		            if (this.range().key() === universes.Universe08.SchemaString || this.range().key() === universes.Universe10.SchemaString) {
		                if (this.range().universe().version() == "RAML10") {
		                    if (this.range() instanceof def.ValueType) {
		                        this.texpr = true;
		                    }
		                }
		            }
		        }
		        this.teDef = true;
		        return this.texpr;
		    };
		    RAMLPropertyService.prototype.isExampleProperty = function () {
		        return this.domain() && (!this.domain().getAdapter(RAMLService).isUserDefined()) && ((this.nameId() == universes.Universe10.TypeDeclaration.properties.example.name) || (this.nameId() == universes.Universe10.ExampleSpec.properties.content.name));
		    };
		    RAMLPropertyService.prototype.isDescriminating = function () {
		        return this._property.isDescriminator();
		    };
		    RAMLPropertyService.prototype.referenceTargets = function (c) {
		        if (this.isTypeExpr()) {
		            var definitionNodes = search.globalDeclarations(c).filter(function (node) {
		                var nc = node.definition().key();
		                if (nc === universes.Universe08.GlobalSchema || nc === universes.Universe10.GlobalSchema) {
		                    return true;
		                }
		                return node.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name);
		            });
		            return definitionNodes;
		        }
		        if (this.isDescriminating()) {
		            var subTypes = search.nodesDeclaringType(this.range(), c);
		            return subTypes;
		        }
		        if (this.isReference()) {
		            var rt = this.referencesTo();
		            var subTypes = search.nodesDeclaringType(rt, c);
		            return subTypes;
		        }
		        if (this.range().hasValueTypeInHierarchy()) {
		            var vt = this.range().getAdapter(RAMLService);
		            if (vt.globallyDeclaredBy().length > 0) {
		                var definitionNodes = search.globalDeclarations(c).filter(function (z) { return _.find(vt.globallyDeclaredBy(), function (x) { return x == z.definition(); }) != null; });
		                return definitionNodes;
		            }
		        }
		        return [];
		    };
		    return RAMLPropertyService;
		})(RAMLPropertyParserService);
		exports.RAMLPropertyService = RAMLPropertyService;
		var RAMLService = (function () {
		    function RAMLService(d) {
		        this._runtime = null;
		        //!!!
		        this._allowsOptionalProperties = false;
		        //!!!
		        this._canInherit = [];
		        this._declaredBy = [];
		        //!!!
		        this._aliases = [];
		        //!!!???
		        this._defining = [];
		        this._runtimeExtenders = [];
		        //!!!???
		        this._declaresType = null;
		        //!!!
		        this._isTemplate = false;
		        //!!!
		        this._contextRequirements = [];
		        this._type = d;
		    }
		    RAMLService.prototype.withAllowQuestion = function () {
		        this._allowsOptionalProperties = true;
		    };
		    RAMLService.prototype.getAllowQuestion = function () {
		        return this._allowsOptionalProperties;
		    };
		    RAMLService.prototype.withCanInherit = function (clazz) {
		        this._canInherit.push(clazz);
		    };
		    RAMLService.prototype.getReferenceIs = function () {
		        return this._referenceIs;
		    };
		    RAMLService.prototype.withReferenceIs = function (fname) {
		        this._referenceIs = fname;
		    };
		    RAMLService.prototype.descriminatorValue = function () {
		        if (this.valueRequirements().length == 0) {
		            return this.nameId();
		        }
		        return this.valueRequirements()[0].value;
		    };
		    RAMLService.prototype.getCanInherit = function () {
		        return this._canInherit;
		    };
		    RAMLService.prototype.withAllowAny = function () {
		        this._allowsAnyChildren = true;
		    };
		    RAMLService.prototype.getAllowAny = function () {
		        return this._allowsAnyChildren || this._type instanceof def.ExternalType;
		    };
		    RAMLService.prototype.globallyDeclaredBy = function () {
		        return this._declaredBy;
		    };
		    RAMLService.prototype.setGloballyDeclaredBy = function (c) {
		        this._declaredBy.push(c);
		    };
		    RAMLService.prototype.setDeclaringNode = function (n) {
		        this._node = n;
		    };
		    RAMLService.prototype.isRuntime = function () {
		        return this._isRuntime;
		    };
		    RAMLService.prototype.nameId = function () {
		        return this._type.nameId();
		    };
		    RAMLService.prototype.universe = function () {
		        return this._type.universe();
		    };
		    RAMLService.prototype.isAssignableFrom = function (name) {
		        return this._type.isAssignableFrom(name);
		    };
		    RAMLService.prototype.isValid = function (h, value, p) {
		        if (this._type.hasArrayInHierarchy()) {
		            return this.isValidArray(h, value, p);
		        }
		        else if (this._type.hasValueTypeInHierarchy()) {
		            return this.isValidValueType(h, value, p);
		        }
		        return true;
		    };
		    RAMLService.prototype.setConsumesRefs = function (b) {
		        this._consumesRef = b;
		    };
		    RAMLService.prototype.definingPropertyIsEnough = function (v) {
		        this._defining.push(v);
		    };
		    RAMLService.prototype.getDefining = function () {
		        return this._defining;
		    };
		    RAMLService.prototype.getConsumesRefs = function () {
		        return this._consumesRef;
		    };
		    RAMLService.prototype.addAlias = function (al) {
		        this._aliases.push(al);
		    };
		    RAMLService.prototype.getAliases = function () {
		        return this._aliases;
		    };
		    RAMLService.prototype.valueRequirements = function () {
		        return this._type.valueRequirements();
		    };
		    RAMLService.prototype.isAnnotation = function () {
		        if (this._annotationChecked) {
		            return this._isAnnotation;
		        }
		        this._annotationChecked = true;
		        this._isAnnotation = (_.find(this._type.allSuperTypes(), function (x) { return x.key() == universes.Universe10.AnnotationRef; }) != null);
		        return this._isAnnotation;
		    };
		    RAMLService.prototype.allowValue = function () {
		        if (this._allowsValueSet) {
		            return this._allowsValue;
		        }
		        if (_.find(this._type.allProperties(), function (x) { return x.isFromParentValue() || x.canBeValue(); })) {
		            this._allowsValue = true;
		            this._allowsValueSet = true;
		            return true;
		        }
		        this._allowsValueSet = true;
		        return false;
		    };
		    RAMLService.prototype.match = function (r, alreadyFound) {
		        var _this = this;
		        //this.vReqInitied=true;
		        if (r.isAttr() || r.isUnknown()) {
		            return false;
		        }
		        var el = r;
		        //if (this.name()=="ObjectField"){
		        //   var tp= el.attr("type");
		        //    if (tp&&tp.value()) {
		        //        //FIXME
		        //        if (!_.find(["string","boolean","file","number","integer","date","pointer","script"], x=>x==tp.value())) {
		        //            return true;
		        //        }
		        //    }
		        //}
		        var hasSuperType = _.find(this._type.superTypes(), function (x) {
		            var dp = _.find(x.allProperties(), function (x) { return (x).isDescriminator(); });
		            if (dp) {
		                var a = el.attr(dp.nameId());
		                if (a) {
		                    if (a.value() == _this.nameId()) {
		                        return true;
		                    }
		                }
		            }
		            return false;
		        });
		        if (hasSuperType) {
		            return true;
		        }
		        if (this.valueRequirements().length == 0) {
		            return false;
		        }
		        var matches = true;
		        //descriminating constraint
		        this.valueRequirements().forEach(function (x) {
		            var a = el.attr(x.name);
		            if (a) {
		                if (a.value() == x.value) {
		                }
		                else {
		                    if (_this.getConsumesRefs()) {
		                        var vl = a.value();
		                        var allSubs = [];
		                        _this._type.superTypes().forEach(function (x) { return x.allSubTypes().forEach(function (y) {
		                            allSubs.push(y);
		                        }); });
		                        var allSubNames = [];
		                        _.unique(allSubs).forEach(function (x) {
		                            allSubNames.push(x.nameId());
		                            x.valueRequirements().forEach(function (y) {
		                                allSubNames.push(y.value);
		                            });
		                            x.getAdapter(RAMLService).getAliases().forEach(function (y) { return allSubNames.push(y); });
		                        });
		                        if (_.find(allSubNames, function (x) { return x == vl; })) {
		                            matches = false;
		                        }
		                    }
		                    else {
		                        matches = false;
		                    }
		                }
		            }
		            else {
		                var m = _this.getDefining();
		                var ms = false;
		                m.forEach(function (x) {
		                    el.lowLevel().children().forEach(function (y) {
		                        if (y.key() == x) {
		                            ms = true;
		                        }
		                    });
		                });
		                if (ms) {
		                    matches = true;
		                    return;
		                }
		                if (!alreadyFound) {
		                    var pr = _this._type.property(x.name);
		                    if (pr && pr.defaultValue() == x.value) {
		                    }
		                    else {
		                        matches = false;
		                    }
		                }
		                else {
		                    matches = false;
		                }
		            }
		        });
		        return matches;
		    };
		    RAMLService.prototype.createStubNode = function (p, key, unit) {
		        if (key === void 0) { key = null; }
		        var lowLevel = jsyaml.createNode(key ? key : "key");
		        var nm = new hlImpl.ASTNodeImpl(lowLevel, null, this._type, p);
		        if (!lowLevel.unit()) {
		            lowLevel._unit = unit;
		        }
		        //this._type.allProperties().forEach(x=>{
		        //    if(x.range().isValueType()&&!x.getAdapter(RAMLPropertyParserService).isSystem()){
		        //        var a = nm.attr(x.nameId());
		        //        if (!a){
		        //            //nm.createAttr(x.name(),"")
		        //        }
		        //    }
		        //})
		        nm.children();
		        return nm;
		    };
		    RAMLService.prototype.key = function () {
		        return this._type.key();
		    };
		    RAMLService.prototype.isValidArray = function (h, v, p) {
		        if (this._type.arrayInHierarchy().componentType()) {
		            return this._type.arrayInHierarchy().componentType().getAdapter(RAMLService).isValid(h, v, p);
		        }
		        return true;
		    };
		    RAMLService.prototype.isValidValueType = function (h, v, p) {
		        try {
		            if (this.key() == universes.Universe10.AnnotationRef) {
		                var targets = p.getAdapter(RAMLPropertyService).referenceTargets(h);
		                var actualAnnotation = _.find(targets, function (x) { return hlImpl.qName(x, h) == v; });
		                if (actualAnnotation != null) {
		                    var attrs = actualAnnotation.attributes("allowedTargets");
		                    if (attrs) {
		                        var aVals = attrs.map(function (x) { return x.value(); });
		                        if (aVals.length > 0) {
		                            var found = false;
		                            //no we should actually check that we are applying annotation properly
		                            var tps = h.definition().allSuperTypes();
		                            tps = tps.concat([h.definition()]);
		                            var tpNames = tps.map(function (x) { return x.nameId(); });
		                            aVals.forEach(function (x) {
		                                //FIXME this is deeply wrong code
		                                if (x == "API") {
		                                    x = "Api";
		                                }
		                                if (x == "NamedExample") {
		                                    x = "ExampleSpec";
		                                }
		                                if (x == "SecurityScheme") {
		                                    x = "AbstractSecurityScheme";
		                                }
		                                if (x == "SecuritySchemeSettings") {
		                                    x = "SecuritySchemeSettings";
		                                }
		                                if (_.find(tpNames, function (y) { return y == x; })) {
		                                    found = true;
		                                }
		                                else {
		                                    if (x == "Parameter") {
		                                        if (h.computedValue("location")) {
		                                            found = true;
		                                        }
		                                    }
		                                    if (x == "Field") {
		                                        if (h.computedValue("field")) {
		                                            found = true;
		                                        }
		                                    }
		                                }
		                            });
		                            if (!found) {
		                                return new Error("annotation " + v + " can not be placed at this location, allowed targets are:" + aVals);
		                            }
		                        }
		                    }
		                }
		                return tm;
		            }
		            if (this.key() == universes.Universe08.SchemaString || this.key() == universes.Universe10.SchemaString) {
		                var tm = su.createSchema(v);
		                if (tm instanceof Error) {
		                    tm.canBeRef = true;
		                }
		                return tm;
		            }
		            if (this.key() == universes.Universe08.StatusCodeString || this.key() == universes.Universe10.StatusCodeString) {
		                var err = validateResponseString(v);
		                if (err != null) {
		                    return err;
		                }
		            }
		            if (this.key() == universes.Universe08.JSonSchemaString || this.key() == universes.Universe10.JSonSchemaString) {
		                var jsshema = su.getJSONSchema(v);
		                if (jsshema instanceof Error) {
		                    jsshema.canBeRef = true;
		                }
		                return jsshema;
		            }
		            if (this.key() == universes.Universe08.XMLSchemaString || this.key() == universes.Universe10.XMLSchemaString) {
		                var xmlschema = su.getXMLSchema(v);
		                if (xmlschema instanceof Error) {
		                    xmlschema.canBeRef = true;
		                }
		                return xmlschema;
		            }
		            if (this.key() == universes.Universe08.BooleanType || this.isAssignableFrom(universes.Universe10.BooleanType.name)) {
		                if (!(v == 'true' || v == 'false')) {
		                    return new Error("'true' or 'false' is expected here");
		                }
		            }
		            if (this.key() == universes.Universe08.NumberType || this.isAssignableFrom(universes.Universe10.NumberType.name)) {
		                var q = parseFloat(v);
		                if (isNaN(q)) {
		                    return new Error("the value of " + p.nameId() + " must be a number");
		                }
		            }
		            if (this.key() == universes.Universe08.StringType || this.isAssignableFrom(universes.Universe10.StringType.name)) {
		                if (v === null) {
		                    //checking if there is at least something in the node.
		                    //We have many tests and APIs with the text like 'propertyName:' without a value. I do not know if such cases are
		                    //actually valid, but not reporting this for now.
		                    if (h && p) {
		                        var highLevelProperty = h.attr(p.nameId());
		                        if (highLevelProperty) {
		                            var lowLevelChildren = highLevelProperty.lowLevel().children();
		                            if (lowLevelChildren && lowLevelChildren.length > 0) {
		                                return new Error(p.nameId() + " must be a string");
		                            }
		                        }
		                    }
		                }
		            }
		            //if (this.name()=='ramlexpression'){
		            //    try {
		            //        if (p.name()=='condition'){
		            //            if (h.computedValue("response")) {
		            //                h = h.parent().parent().parent();
		            //            }
		            //            else{
		            //                h=h.parent().parent();
		            //            }
		            //        }
		            //        if (p.name()=='validWhen'||p.name()=='requiredWhen'){
		            //            h=h.parent();
		            //        }
		            //        ramlexp.validate(v, h);
		            //    } catch (e){
		            //        return e;
		            //    }
		            //}
		            //if (this.name()=="pointer") {
		            //    var pointer = search.resolveRamlPointer(h, v);
		            //    if (!pointer) {
		            //        return new Error("Unable to resolve raml pointer:" + v);
		            //    }
		            //    else{
		            //        var dp=<defs.Property>p;
		            //        var sl=dp.getSelector(h);
		            //        if (sl){
		            //            var pp=h;
		            //            if (pp.definition().isAnnotation()){
		            //                pp=pp.parent();
		            //            }
		            //            var options=sl.apply(pp);
		            //            if (!_.find(options,x=>x==pointer)){
		            //                return new Error("Pointer does not fits to scope " + v);
		            //            }
		            //        }
		            //    }
		            //}
		            //if (this.name()=="RAMLSelector") {
		            //    try {
		            //        var sl = selector.parse(h,v);
		            //        return sl;
		            //    } catch(e){
		            //        return new Error("Unable to parse RAML selector :"+e.message);
		            //    }
		            //}
		            return true;
		        }
		        catch (e) {
		            e.canBeRef = true; //FIXME
		            return e;
		        }
		    };
		    RAMLService.prototype.getRepresentationOf = function () {
		        return this._representationOf;
		    };
		    RAMLService.prototype.addRuntimeProperty = function (p) {
		        this._runtimeProperties.push(p);
		    };
		    RAMLService.prototype.initRuntime = function () {
		        var _this = this;
		        this._runtimeProperties = [];
		        var node = this.getDeclaringNode();
		        if (node) {
		            var el = node.elementsOfKind("properties");
		            el.forEach(function (x) {
		                var prop = typeBuilder.elementToProp(x, true);
		                _this.addRuntimeProperty(prop);
		            });
		        }
		    };
		    RAMLService.prototype.allRuntimeProperties = function (ps) {
		        if (ps === void 0) { ps = {}; }
		        if (!this._runtimeProperties) {
		            this.initRuntime();
		            this._rprops = null;
		        }
		        if (this._rprops) {
		            return this._rprops;
		        }
		        if (ps[this.nameId()]) {
		            return [];
		        }
		        ps[this.nameId()] = this._type;
		        var n = {};
		        if (this._type.superTypes().length > 0) {
		            this._type.superTypes().forEach(function (x) {
		                if (x instanceof def.NodeClass) {
		                    x.getAdapter(RAMLService).allRuntimeProperties(ps).forEach(function (y) { return n[y.nameId()] = y; });
		                }
		            });
		        }
		        this._runtimeProperties.forEach(function (x) { return n[x.nameId()] = x; });
		        this._rprops = Object.keys(n).map(function (x) { return n[x]; });
		        return this._rprops;
		    };
		    RAMLService.prototype.getRuntimeProperties = function () {
		        if (!this._runtimeProperties) {
		            this.initRuntime();
		        }
		        return this._runtimeProperties;
		    };
		    RAMLService.prototype.getPath = function () {
		        return "";
		    };
		    RAMLService.prototype.isDeclaration = function () {
		        if (this._isTemplate) {
		            return true;
		        }
		        if (this._convertsToGlobal) {
		            return true;
		        }
		        if (this._declaresType) {
		            return true;
		        }
		        if (this.key() === universes.Universe10.Library) {
		            return true;
		        }
		        return false;
		    };
		    RAMLService.prototype.isGlobalDeclaration = function () {
		        if (this._actuallyExports) {
		            return true;
		        }
		        if (this._isTemplate) {
		            return true;
		        }
		        if (this._declaresType) {
		            return true;
		        }
		        return false;
		    };
		    RAMLService.prototype.isTypeSystemMember = function () {
		        return this._declaresType != null;
		    };
		    RAMLService.prototype.getExtendedType = function () {
		        return this.universe().type(this._declaresType);
		    };
		    RAMLService.prototype.setInlinedTemplates = function (b) {
		        this._isTemplate = b;
		        return this;
		    };
		    RAMLService.prototype.getRuntimeExtenders = function () {
		        return this._runtimeExtenders;
		    };
		    RAMLService.prototype.isInlinedTemplates = function () {
		        return this._isTemplate;
		    };
		    RAMLService.prototype.setExtendedTypeName = function (name) {
		        this._declaresType = name;
		        var tp = this.universe().type(name);
		        if (tp instanceof def.NodeClass) {
		            var nc = tp;
		            nc.getAdapter(RAMLService)._runtimeExtenders.push(this._type);
		        }
		    };
		    RAMLService.prototype.getKeyProp = function () {
		        return _.find(this._type.allProperties(), function (x) { return x.getAdapter(RAMLPropertyService).isKey(); });
		    };
		    RAMLService.prototype.withActuallyExports = function (pname) {
		        this._actuallyExports = pname;
		    };
		    RAMLService.prototype.withConvertsToGlobal = function (pname) {
		        this._convertsToGlobal = pname;
		    };
		    RAMLService.prototype.getConvertsToGlobal = function () {
		        return this._convertsToGlobal;
		    };
		    RAMLService.prototype.getActuallyExports = function () {
		        return this._actuallyExports;
		    };
		    RAMLService.prototype.isUserDefined = function () {
		        if (this._type instanceof def.NodeClass) {
		            return this._type.isUserDefined();
		        }
		        if (this._type instanceof def.Array) {
		            return this._type.isUserDefined();
		        }
		        if (this._type instanceof def.Union) {
		            return this._type.isUserDefined();
		        }
		        return false;
		    };
		    RAMLService.prototype.withContextRequirement = function (name, value) {
		        this._contextRequirements.push({ name: name, value: value });
		    };
		    RAMLService.prototype.getContextRequirements = function () {
		        return this._contextRequirements;
		    };
		    RAMLService.prototype.findMembersDeterminer = function () {
		        return _.find(this._type.allProperties(), function (x) { return x.isThisPropertyDeclaresTypeFields(); });
		    };
		    RAMLService.prototype.nameAtRuntime = function () {
		        if (this._type.valueRequirements().length > 0) {
		            return this.valueRequirements()[0].value;
		        }
		        if (this._type instanceof def.ValueType) {
		            var nr = this._type.getNameAtRuntime();
		            if (nr) {
		                return nr;
		            }
		        }
		        return this._type.nameId();
		    };
		    RAMLService.prototype.toRuntime = function () {
		        if (this._runtime) {
		            return this._runtime;
		        }
		        if (this._type.hasExternalInHierarchy()) {
		            return this._type;
		        }
		        if (this._type instanceof typeSystem.ValueType) {
		            //build in value type always runtime;
		            return this._type;
		        }
		        if (this.key() == universes.Universe10.NumberTypeDeclaration) {
		            return this.universe().type(universes.Universe10.NumberType.name);
		        }
		        if (this.key() == universes.Universe10.StringTypeDeclaration) {
		            return this.universe().type(universes.Universe10.StringType.name);
		        }
		        if (this.key() == universes.Universe10.BooleanTypeDeclaration) {
		            return this.universe().type(universes.Universe10.BooleanType.name);
		        }
		        if (this.key() == universes.Universe10.IntegerTypeDeclaration) {
		            return this.universe().type(universes.Universe10.NumberType.name);
		        }
		        if (this._isRuntime) {
		            return this._type;
		        }
		        var c = new def.UserDefinedClass(this.nameId(), this.universe(), null, this.getPath(), "");
		        if (!this._type.getAdapter(RAMLService).isUserDefined()) {
		            if (this.key() == universes.Universe10.ObjectTypeDeclaration) {
		                c.getAdapter(RAMLService).withAllowAny();
		            }
		            return c;
		        }
		        this._runtime = c;
		        c.getAdapter(RAMLService)._isRuntime = true;
		        c.getAdapter(RAMLService)._representationOf = this._type;
		        var foundRuntimeProperties = this.getRuntimeProperties();
		        if (foundRuntimeProperties) {
		            foundRuntimeProperties.forEach(function (runtimeProperty) { return runtimeProperty.withDomain(c); });
		            c._properties = foundRuntimeProperties;
		        }
		        else {
		            c._properties = [];
		        }
		        c.getAdapter(RAMLService).setDeclaringNode(this.getDeclaringNode());
		        if (this.isAssignableFrom("ObjectTypeDeclaration")) {
		            c._value = false;
		            if (c._properties.length == 0) {
		                c.getAdapter(RAMLService).withAllowAny();
		            }
		            this._type.superTypes().forEach(function (t) {
		                var s = t.getAdapter(RAMLService).toRuntime();
		                if (t.key() == universes.Universe10.TypeDeclaration) {
		                    return;
		                }
		                if (t.key() == universes.Universe10.ObjectTypeDeclaration) {
		                    return;
		                }
		                if (t.key() == universes.Universe10.RAMLLanguageElement) {
		                    return;
		                }
		                c._superTypes.push(s);
		            });
		        }
		        else {
		            c._value = true;
		            var sm = this._type.superTypes();
		            c._superTypes = sm.map(function (x) { return x.getAdapter(RAMLService).toRuntime(); }).filter(function (x) { return x && x.hasValueTypeInHierarchy(); });
		        }
		        if (this._type.hasUnionInHierarchy()) {
		            var ut = new def.Union(this.nameId(), this.universe(), this.getPath());
		            ut.getAdapter(RAMLService)._representationOf = this._type;
		            ut._isRuntime = true;
		            ut.getAdapter(RAMLService).setDeclaringNode(this.getDeclaringNode());
		            var cm = this._type.unionInHierarchy();
		            if (cm) {
		                if (cm.leftType()) {
		                    ut.left = cm.leftType().getAdapter(RAMLService).toRuntime();
		                }
		                if (cm.rightType()) {
		                    ut.right = cm.rightType().getAdapter(RAMLService).toRuntime();
		                }
		                this._runtime = ut;
		                return ut;
		            }
		            this._runtime = ut;
		            //at.component=this.component.toRuntime();
		            return ut;
		        }
		        if (this._type.hasArrayInHierarchy()) {
		            var at = new def.Array(this.nameId(), this.universe(), this.getPath());
		            this._runtime = at;
		            at._af = {};
		            var fs = this._type.getFixedFacets();
		            for (var i in fs) {
		                at._af[i] = fs[i];
		            }
		            at.getAdapter(RAMLService)._representationOf = this._type;
		            at.getAdapter(RAMLService).setDeclaringNode(this.getDeclaringNode());
		            var at1 = this._type.arrayInHierarchy();
		            if (at1) {
		                var comp = at1.componentType();
		                if (comp) {
		                    at.component = comp.getAdapter(RAMLService).toRuntime();
		                }
		            }
		            //at.component=this.component.toRuntime();
		            return at;
		        }
		        return c;
		    };
		    RAMLService.prototype.getDeclaringNode = function () {
		        return this._node;
		    };
		    return RAMLService;
		})();
		exports.RAMLService = RAMLService;
		function validateResponseString(v) {
		    if (v.length != 3) {
		        return new Error("Status code should be 3 digits number with optional 'x' as wildcards");
		    }
		    for (var i = 0; i < v.length; i++) {
		        var c = v[i];
		        if (!_.find(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'x', 'X'], function (x) { return x == c; })) {
		            return new Error("Status code should be 3 digits number with optional 'x' as wildcards");
		        }
		    }
		    return null;
		}
		exports.validateResponseString = validateResponseString;


	/***/ },
	/* 50 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var defs = __webpack_require__(3);
		var _ = __webpack_require__(4);
		var typeExpression = __webpack_require__(51);
		var universes = __webpack_require__(54);
		var hlimpl = __webpack_require__(5);
		var annotationHandlers = __webpack_require__(84);
		var services = __webpack_require__(49);
		var linter = __webpack_require__(55);
		function templateFields(node, d) {
		    var u = node.root().definition().universe();
		    node.children().forEach(function (x) { return templateFields(x, d); });
		    if (node instanceof hlimpl.ASTPropImpl) {
		        var prop = node;
		        //TODO RECURSIVE PARAMETERS
		        var v = prop.value();
		        if (typeof v == 'string') {
		            var strV = v;
		            handleValue(strV, d, prop, false, u);
		        }
		        else {
		            node.lowLevel().visit(function (x) {
		                if (x.value()) {
		                    var strV = x.value() + "";
		                    handleValue(strV, d, prop, true, u);
		                }
		                return true;
		            });
		        }
		    }
		    else if (node instanceof hlimpl.BasicASTNode) {
		        var v = node.lowLevel().value();
		        if (typeof v == 'string') {
		            var strV = v;
		            handleValue(strV, d, null, false, u);
		        }
		        else {
		            node.lowLevel().visit(function (x) {
		                if (x.value()) {
		                    var strV = x.value() + "";
		                    handleValue(strV, d, null, true, u);
		                }
		                return true;
		            });
		        }
		    }
		}
		var handleValue = function (strV, d, prop, allwaysString, u) {
		    var ps = 0;
		    while (true) {
		        var pos = strV.indexOf("<<", ps);
		        if (pos != -1) {
		            var end = strV.indexOf(">>", pos);
		            var isFull = pos == 0 && end == strV.length - 2;
		            var parameterUsage = strV.substring(pos + 2, end);
		            ps = pos + 2;
		            var directiveIndex = parameterUsage.indexOf("|");
		            if (directiveIndex != -1) {
		                parameterUsage = parameterUsage.substring(0, directiveIndex);
		            }
		            parameterUsage = parameterUsage.trim();
		            if (parameterUsage == "resourcePathName" || parameterUsage == "methodName" || parameterUsage == "resourcePath") {
		                continue;
		            }
		            var q = d[parameterUsage];
		            var r = (prop) ? prop.property().range() : null;
		            if (prop) {
		                if (prop.property().nameId() == universes.Universe10.TypeDeclaration.properties.type.name || prop.property().nameId() == universes.Universe10.TypeDeclaration.properties.schema.name) {
		                    if (prop.property().domain().key() == universes.Universe10.TypeDeclaration) {
		                        r = u.type(universes.Universe10.SchemaString.name);
		                    }
		                }
		            }
		            if (!isFull || allwaysString) {
		                r = u.type(universes.Universe10.StringType.name);
		            }
		            //FIX ME NOT WHOLE TEMPLATES
		            if (q) {
		                q.push({
		                    tp: r,
		                    attr: prop
		                });
		            }
		            else {
		                d[parameterUsage] = [{
		                    tp: r,
		                    attr: prop
		                }];
		            }
		        }
		        else
		            break;
		    }
		};
		function ObjectTypeDeclaration(node) {
		    var de = node.definition().universe().type(universes.Universe10.ObjectTypeDeclaration.name);
		    return de;
		}
		function TypeDeclaration(node) {
		    var de = node.definition().universe().type(universes.Universe10.TypeDeclaration.name);
		    return de;
		}
		var ann = 0;
		function typeFromNode(node) {
		    if (!node) {
		        return null;
		    }
		    if (node.associatedType()) {
		        return node.associatedType();
		    }
		    var u = node.lowLevel().unit();
		    var upath = u ? u.path() : "";
		    if (node.property() && node.property().nameId() == universes.Universe10.LibraryBase.properties.annotationTypes.name) {
		        var st = node.definition().getAdapter(services.RAMLService).toRuntime();
		        var result = new defs.AnnotationType(node.name(), node.definition().universe(), node, upath, "");
		        result._superTypes.push(st);
		        return result;
		    }
		    else {
		        var result = new defs.UserDefinedClass(node.name(), node.definition().universe(), node, upath, "");
		    }
		    node.setAssociatedType(result);
		    //result.setDeclaringNode(node);
		    var def = node.definition();
		    if (def.getAdapter(services.RAMLService).isInlinedTemplates()) {
		        var usages = {};
		        templateFields(node, usages);
		        result.getAdapter(services.RAMLService).setInlinedTemplates(true);
		        Object.keys(usages).forEach(function (x) {
		            var prop = new defs.UserDefinedProp(x);
		            //prop._node=node;
		            prop.withDomain(result);
		            var tp = _.unique(usages[x]).map(function (x) { return x.tp; }).filter(function (x) { return x && x.nameId() != universes.Universe08.StringType.name; });
		            prop.withRange(tp.length == 1 ? tp[0] : node.definition().universe().type(universes.Universe08.StringType.name));
		            prop.withRequired(true);
		            if (usages[x].length > 0) {
		                prop._node = usages[x][0].attr;
		            }
		            prop.unmerge();
		        });
		        var keyProp = new defs.UserDefinedProp("key");
		        //prop._node=node;
		        keyProp.withDomain(result);
		        keyProp.withKey(true);
		        keyProp._node = node;
		        keyProp.withFromParentKey(true);
		        keyProp.withRange(node.definition().universe().type(universes.Universe08.StringType.name));
		    }
		    else if (def.getAdapter(services.RAMLService).getReferenceIs()) {
		        if (def.universe().version() == "RAML08") {
		            result.getAdapter(services.RAMLService).withAllowAny();
		        }
		        var p = def.property(def.getAdapter(services.RAMLService).getReferenceIs());
		        if (p) {
		            p.range().properties().forEach(function (x) {
		                var prop = new defs.Property(x.nameId());
		                prop.unmerge();
		                prop.withDomain(result);
		                prop.withRange(x.range());
		                prop.withMultiValue(x.isMultiValue());
		            });
		        }
		    }
		    else {
		        var rp = def.getAdapter(services.RAMLService).findMembersDeterminer();
		        if (rp) {
		            var elements = node.elementsOfKind(rp.nameId());
		            elements.forEach(function (x) {
		                var prop = elementToProp(x);
		                prop.withDomain(result);
		            });
		        }
		        //here we should found correct inheritance chain
		        var types = node.attributes("type");
		        var schema = node.attributes("schema");
		        types = types.concat(schema);
		        if (node.definition().key() === universes.Universe08.GlobalSchema || node.definition().key() === universes.Universe10.GlobalSchema) {
		            var vl = node.attributes("value");
		            types = types.concat(vl);
		        }
		        var tp = types.length != 0;
		        types.forEach(function (tp) {
		            var vl = tp.value();
		            if (typeof vl == 'string' && vl) {
		                vl = vl.trim();
		                if (vl.charAt(0) == '{') {
		                    var et = new defs.ExternalType(node.name(), node.definition().universe(), upath);
		                    et.schemaString = vl;
		                    et.node = node;
		                    var de = TypeDeclaration(node);
		                    if (de) {
		                        result._superTypes.push(de);
		                    }
		                    result._superTypes.push(et);
		                }
		                if (vl.charAt(0) == '<') {
		                    var et = new defs.ExternalType(node.name(), node.definition().universe(), upath);
		                    et.schemaString = vl;
		                    et.node = node;
		                    var de = TypeDeclaration(node);
		                    if (de) {
		                        result._superTypes.push(de);
		                    }
		                    result._superTypes.push(et);
		                }
		            }
		            var types = {};
		            types[result.nameId()] = result;
		            var at = null;
		            if (vl != result.nameId()) {
		                at = typeExpression.getType(node.parent() || node, vl, types);
		            }
		            else {
		            }
		            if (at) {
		                result._superTypes.push(at);
		            }
		        });
		        result.addRequirement("type", node.name());
		        var extType = def.getAdapter(services.RAMLService).getExtendedType();
		        if (extType) {
		            result._superTypes.push(extType);
		        }
		        {
		            //Adding runtime properties for object types TODO it should be done in more elegant way
		            var prop = _.find(node.lowLevel().children(), function (x) { return x.key() == "properties"; });
		            if (prop) {
		                var de = ObjectTypeDeclaration(node);
		                if (de) {
		                    result._superTypes.push(de);
		                }
		            }
		            else {
		                if (node.property() && node.property().nameId() == universes.Universe10.Method.properties.body.name) {
		                    var de = ObjectTypeDeclaration(node);
		                    if (de) {
		                        result._superTypes.push(de);
		                    }
		                }
		                else if (!tp) {
		                    var de = node.definition().universe().type(universes.Universe10.StringTypeDeclaration.name);
		                    if (de && node.definition().key() != universes.Universe08.BodyLike && node.definition().key() != universes.Universe10.AnnotationTypeDeclaration) {
		                        result._superTypes.push(de);
		                    }
		                }
		                if (result._superTypes.length == 0) {
		                    var de = node.definition().universe().type(universes.Universe10.TypeDeclaration.name);
		                    if (de) {
		                        result._superTypes.push(de);
		                    }
		                }
		            }
		            var pn = ObjectTypeDeclaration(node);
		            if (pn) {
		                node.lowLevel().children().forEach(function (x) {
		                    if (x.key() == "facets") {
		                        return;
		                    }
		                    if (x.key() == "annotations") {
		                        return;
		                    }
		                    if (x.key() == "parameters") {
		                        return;
		                    }
		                    if (!pn.property(x.key())) {
		                        result.fixFacet(x.key(), x);
		                    }
		                });
		            }
		        }
		    }
		    return result;
		}
		exports.typeFromNode = typeFromNode;
		function parsePropertyName(name) {
		    var v = { name: "", regexp: null };
		    if (name.length > 2) {
		        name = name.substr(1, name.length - 2);
		        var pos = name.lastIndexOf("#");
		        if (pos != -1) {
		            v.name = name.substr(pos + 1);
		            v.regexp = name.substr(0, pos);
		        }
		        else {
		            v.regexp = name;
		        }
		    }
		    return v;
		}
		exports.parsePropertyName = parsePropertyName;
		function libraryLocation(definition) {
		    var node = definition.getAdapter(services.RAMLService).getDeclaringNode();
		    var result = null;
		    if (node != null) {
		        var library = node.parent();
		        if (library) {
		            var libraryAnnotations = library.attributes("annotations");
		            libraryAnnotations.forEach(function (x) {
		                var value = x.value();
		                if (value instanceof hlimpl.StructuredValue) {
		                    if (value.lowLevel().key() == "(LibraryLocation)") {
		                        var hlv = value.toHighLevel(library);
		                        if (hlv) {
		                            result = valueOf(hlv);
		                        }
		                    }
		                }
		            });
		        }
		    }
		    return result;
		}
		exports.libraryLocation = libraryLocation;
		function valueOf(hl) {
		    if (hl) {
		        var vl = hl.attr("value");
		        if (vl) {
		            return vl.value();
		        }
		    }
		    return null;
		}
		exports.valueOf = valueOf;
		var scriptToValidator = {};
		var loophole = __webpack_require__(112);
		function evalInSandbox(code, thisArg, args) {
		    return new loophole.Function(code).call(thisArg, args);
		}
		var ValidatorHolder = (function () {
		    function ValidatorHolder() {
		    }
		    ValidatorHolder.prototype.register = function (mm) {
		        this._result = mm;
		    };
		    return ValidatorHolder;
		})();
		function aquireValidator(value) {
		    if (value) {
		        var nm = scriptToValidator[value];
		        if (nm) {
		            if (nm == aquireValidator) {
		                return null;
		            }
		            return nm;
		        }
		        try {
		            var holder = new ValidatorHolder();
		            evalInSandbox(value, holder, []);
		            if (holder._result) {
		                scriptToValidator[value] = holder._result;
		                return holder._result;
		            }
		            else {
		                scriptToValidator[value] = aquireValidator;
		            }
		        }
		        catch (e) {
		            scriptToValidator[value] = aquireValidator;
		        }
		    }
		    return null;
		}
		exports.aquireValidator = aquireValidator;
		function elementToProp(e, toRuntime) {
		    if (toRuntime === void 0) { toRuntime = false; }
		    var nm = e.name();
		    var optional = e.optional();
		    var result = new defs.UserDefinedProp(nm);
		    result._node = e;
		    try {
		        var description = e.attr("description");
		        if (description) {
		            var dsv = "" + description.value();
		            result.withDescription(dsv);
		        }
		        var dn = e.attr("displayName");
		        if (dn) {
		            var dsv = "" + dn.value();
		            result.withDisplayName(dsv);
		        }
		        var example = e.attr("example");
		        if (example) {
		            var obj = new linter.ExampleValidator().parseObject(example, {
		                begin: function () {
		                },
		                end: function () {
		                },
		                accept: function (f) {
		                }
		            }, false);
		            result.setDefaultVal(obj);
		        }
		        else {
		            var exampleElements = e.elementsOfKind("examples");
		            exampleElements.forEach(function (x) {
		                var cnt = x.attr("content");
		                if (cnt) {
		                    var obj = new linter.ExampleValidator().parseObject(cnt, {
		                        begin: function () {
		                        },
		                        end: function () {
		                        },
		                        accept: function (f) {
		                        }
		                    }, false);
		                    result.setDefaultVal(obj);
		                }
		            });
		        }
		    }
		    catch (e) {
		        console.log(e); //TODO remove me
		    }
		    var annotations = e.attributes("annotations");
		    annotations.forEach(function (annotation) {
		        var value = annotation.value();
		        if (value instanceof hlimpl.StructuredValue) {
		            var highLevel = value.toHighLevel(e);
		            if (highLevel) {
		                var definition = highLevel.definition();
		                if (definition.nameId() == "FacetInstanceValidator") {
		                    var node = definition.getAdapter(services.RAMLService).getDeclaringNode();
		                    var ll = libraryLocation(definition);
		                    if (ll == "http://raml.org/library/common.raml") {
		                        var value = valueOf(highLevel);
		                        var facetValidator = aquireValidator(value);
		                        if (facetValidator) {
		                            result.setFacetValidator(facetValidator);
		                        }
		                    }
		                }
		            }
		        }
		    });
		    if (nm.length > 0) {
		        if (nm[0] == '[') {
		            optional = true;
		            var info = parsePropertyName(nm);
		            if (info.regexp) {
		                result.withKeyRegexp(info.regexp);
		            }
		            else {
		                result.withKeyRestriction("");
		            }
		            if (info.name) {
		                result.withDescription(info.name);
		            }
		            result.withMultiValue();
		        }
		        else {
		            result.unmerge();
		        }
		    }
		    var props = e.definition().properties();
		    var tp = e.attr("type");
		    if (tp) {
		        var typeName = tp.value();
		        if (typeName == "any") {
		            result.withMultiValue(true);
		            var rm = new defs.NodeClass("ObjectTypeDeclaration", e.definition().universe(), "", "");
		            rm.getAdapter(services.RAMLService).withAllowAny();
		            result.withRange(rm);
		        }
		        else {
		            var tpv = typeExpression.getType(e, typeName, {}, true);
		            if (tpv) {
		                tpv = tpv.getAdapter(services.RAMLService).toRuntime();
		                if (tpv instanceof defs.Array) {
		                    var at = tpv;
		                    //FIXME
		                    at._af = {};
		                    //var fs=tpv.getFixedFacets();
		                    //for (var i in fs){
		                    //    at._af[i]=fs[i];
		                    //}
		                    at.findFacets(e, at._af);
		                }
		            }
		            result.withRange(tpv);
		        }
		    }
		    //FIXME Literals
		    if (nm == "value" && e.parent() && e.parent().definition().isAssignableFrom(universes.Universe10.AnnotationTypeDeclaration.name)) {
		        result.withCanBeValue();
		    }
		    e.definition().allProperties().forEach(function (p) {
		        if (p.nameId() != universes.Universe10.TypeDeclaration.properties.type.name) {
		            if (p.describesAnnotation()) {
		                var annotationName = p.describedAnnotation();
		                var args = [];
		                var vl = e.attributes(p.nameId()).map(function (a) { return a.value(); });
		                if (vl.length == 1) {
		                    args.push(vl[0]);
		                }
		                else {
		                    args.push(vl);
		                }
		                //TODO ANNOTATIONS WITH MULTIPLE ARGUMENTS
		                var an = {
		                    name: annotationName,
		                    arguments: args
		                };
		                annotationHandlers.recordAnnotation(result, an);
		            }
		        }
		    });
		    if (optional) {
		        result.withRequired(false);
		    }
		    var vn = _.find(e.lowLevel().children(), function (x) { return x.key() == "properties"; });
		    if (vn) {
		        var of = e.definition().universe().type(universes.Universe10.ObjectTypeDeclaration.name);
		        var node = new hlimpl.ASTNodeImpl(e.lowLevel(), e.parent(), of, result);
		        var epath = e.lowLevel().unit();
		        var nc = new defs.UserDefinedClass("", of.universe(), node, epath ? epath.path() : "", "");
		        nc._superTypes.push(of);
		        result.withRange(nc.getAdapter(services.RAMLService).toRuntime());
		    }
		    if (result.range() == null) {
		        result.withRange(e.definition().universe().type(universes.Universe10.StringType.name));
		    }
		    if (result.range().key() == universes.Universe10.ObjectTypeDeclaration) {
		        var rm = new defs.NodeClass(universes.Universe10.ObjectTypeDeclaration.name, result.range().universe(), "", "");
		        rm.getAdapter(services.RAMLService).withAllowAny();
		        result.withRange(rm);
		    }
		    return result;
		}
		exports.elementToProp = elementToProp;


	/***/ },
	/* 51 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var defs = __webpack_require__(3);
		var hl = __webpack_require__(2);
		var _ = __webpack_require__(4);
		var typeExpression = __webpack_require__(52);
		var search = __webpack_require__(53);
		var linter = __webpack_require__(55);
		var schema = __webpack_require__(56);
		var services = __webpack_require__(49);
		var universes = __webpack_require__(54);
		function validate(str, node, cb) {
		    var x = str.trim();
		    if (x.length > 0) {
		        try {
		            if (x.charAt(0) == "{") {
		                schema.getJSONSchema(str);
		                //this is json schema
		                return;
		            }
		            if (x.charAt(0) == "<") {
		                schema.getXMLSchema(str);
		                //this is xsd schema
		                return;
		            }
		        }
		        catch (e) {
		            cb.accept(linter.createIssue(7 /* INVALID_VALUE_SCHEMA */, e.message, node));
		        }
		    }
		    var result = typeExpression.parse(str);
		    validateNode(result, node, cb);
		}
		exports.validate = validate;
		function getType(node, expression, defined, toRuntime) {
		    if (toRuntime === void 0) { toRuntime = false; }
		    if (!expression) {
		        return node.definition().universe().type("StringTypeDeclaration");
		    }
		    if (toRuntime) {
		        if (buildInsRuntime[expression]) {
		            var sm = node.definition().universe().type(buildInsRuntime[expression]);
		            return sm;
		        }
		    }
		    if (buildIns[expression]) {
		        var qm = node.definition().universe().type(buildIns[expression]);
		        return qm;
		    }
		    try {
		        var vl = expression;
		        vl = vl.trim();
		        if (vl.charAt(0) == '{') {
		            return null;
		        }
		        if (vl.charAt(0) == '<') {
		            return null;
		        }
		        var result = typeExpression.parse(expression);
		    }
		    catch (e) {
		        return null;
		    }
		    return deriveType(node, result, toRuntime, defined);
		}
		exports.getType = getType;
		/**
		 * Only use it for example validaation at this point, lets think about it after release.
		 * @param node
		 * @param expression
		 * @param defined
		 * @param toRuntime
		 * @returns {any}
		 */
		function getType2(node, expression, defined, toRuntime) {
		    if (toRuntime === void 0) { toRuntime = false; }
		    if (!expression) {
		        return node.definition().universe().type("StringTypeDeclaration");
		    }
		    if (toRuntime) {
		        if (buildInsRuntime[expression]) {
		            var sm = node.definition().universe().type(buildInsRuntime[expression]);
		            if (sm) {
		                var ret = new defs.UserDefinedClass(node.name(), node.definition().universe(), node, "", "");
		                ret._superTypes.push(sm);
		                return ret;
		            }
		        }
		    }
		    if (buildIns[expression]) {
		        var qm = node.definition().universe().type(buildIns[expression]);
		        if (qm) {
		            var ret = new defs.UserDefinedClass(node.name(), node.definition().universe(), node, "", "");
		            ret._superTypes.push(qm);
		            return ret;
		        }
		    }
		    try {
		        var vl = expression;
		        vl = vl.trim();
		        if (vl.charAt(0) == '{') {
		            return null;
		        }
		        if (vl.charAt(0) == '<') {
		            return null;
		        }
		        var result = typeExpression.parse(expression);
		    }
		    catch (e) {
		        return null;
		    }
		    return deriveType(node, result, toRuntime, defined);
		}
		exports.getType2 = getType2;
		var buildIns = {
		    string: "StringTypeDeclaration",
		    number: "NumberTypeDeclaration",
		    integer: "IntegerTypeDeclaration",
		    date: "DateTypeDeclaration",
		    object: "ObjectTypeDeclaration",
		    boolean: "BooleanTypeDeclaration",
		    value: "ValueTypeDeclaration",
		    file: "FileTypeDeclaration"
		};
		var buildInsRuntime = {
		    string: "string",
		    number: "number",
		    integer: "integer",
		    date: "date",
		    object: "ObjectTypeDeclaration",
		    boolean: "boolean",
		    value: "string",
		    file: "file"
		};
		var counter = 0;
		function deriveType(node, r, toRuntime, defining) {
		    if (toRuntime === void 0) { toRuntime = false; }
		    if (defining === void 0) { defining = {}; }
		    if (r.type == "union") {
		        var u = r;
		        var left = deriveType(node, u.first, toRuntime, defining);
		        var right = deriveType(node, u.rest, toRuntime, defining);
		        var ut = node.definition().universe().type(universes.Universe10.UnionTypeDeclaration.name);
		        var union = new defs.Union("Union" + (counter++), node.definition().universe(), "");
		        union._superTypes.push(ut);
		        union.left = left;
		        union.right = right;
		        return union;
		    }
		    if (r.type == 'responses') {
		        var res = r;
		        var result = null;
		        res.codes.forEach(function (t) {
		            var tp = deriveType(node, t.expr, toRuntime, defining);
		            if (tp) {
		                if (!result) {
		                    result = tp;
		                }
		                else {
		                    var union = new defs.Union("Union" + (counter++), node.definition().universe(), "");
		                    union.left = result;
		                    union.right = tp;
		                    result = tp;
		                }
		            }
		        });
		        return result;
		    }
		    if (r.type == 'parens') {
		        var ex = r;
		        return deriveType(node, ex.expr, toRuntime, defining);
		    }
		    if (r.type == 'name') {
		        var l = r;
		        var val = l.value;
		        var ind = val.lastIndexOf("[]");
		        if (ind != -1 && ind == val.length - 2) {
		            val = val.substr(0, val.length - 2); //FIXME Should be in PEG
		        }
		        if (l.arr > 0) {
		            var types = search.subTypesWithLocals(node.definition().universe().type(universes.Universe10.TypeDeclaration.name), node);
		            var tp = _.find(types, function (x) {
		                var c = x.nameId() == val;
		                if (!c) {
		                    if (x instanceof defs.AbstractType) {
		                        var at = x;
		                        at.getAdapter(services.RAMLService).getAliases().forEach(function (y) {
		                            if (y == val) {
		                                c = true;
		                            }
		                        });
		                    }
		                }
		                return c;
		            });
		            if (!tp) {
		                //TOD make it simpler
		                if (toRuntime || true) {
		                    //it is always runtime model when we are here
		                    if (buildInsRuntime[val]) {
		                        tp = node.definition().universe().type(buildInsRuntime[val]);
		                    }
		                }
		                else if (buildIns[val]) {
		                    tp = node.definition().universe().type(buildIns[val]);
		                }
		            }
		            if (!tp) {
		                tp = node.definition().universe().type(universes.Universe10.StringType.name);
		            }
		            var at = node.definition().universe().type(universes.Universe10.ArrayTypeDeclaration.name);
		            var arr = new defs.Array(tp.nameId() + "[]", node.definition().universe(), "");
		            arr._superTypes.push(at);
		            arr.component = tp;
		            arr.dimensions = l.arr;
		            return arr;
		        }
		        if (toRuntime) {
		            if (buildInsRuntime[val]) {
		                return node.definition().universe().type(buildInsRuntime[val]);
		            }
		        }
		        if (buildIns[val]) {
		            return node.definition().universe().type(buildIns[val]);
		        }
		        var de = node.definition().universe().type(universes.Universe10.TypeDeclaration.name);
		        if (!de) {
		            de = node.definition().universe().type(universes.Universe10.GlobalSchema.name);
		        }
		        //if (defining[val]){
		        //    return defining[val];
		        //}
		        var qm = search.subTypesWithName(val, node, defining);
		        if (qm) {
		            return qm;
		        }
		        //return null;
		        de = node.definition().universe().type(universes.Universe10.GlobalSchema.name);
		        return search.schemasWithName(val, node, defining);
		    }
		    return null;
		}
		exports.deriveType = deriveType;
		function nodeToString(r) {
		    if (r.type == "union") {
		        var u = r;
		        return nodeToString(u.first) + "|" + nodeToString(u.rest);
		    }
		    if (r.type == "responses") {
		        var res = r;
		        var rs = "{";
		        for (var i = 0; i < res.codes.length; i++) {
		            rs += res.codes[i].code;
		            rs += ":";
		            rs += nodeToString(res.codes[i].expr);
		            if (i != res.codes.length - 1) {
		                rs += ",";
		            }
		        }
		        rs += '}';
		        return rs;
		    }
		    if (r.type == 'parens') {
		        var ex = r;
		        var pr = "(" + nodeToString(ex.expr) + ")";
		        if (ex.arr) {
		            pr += "[]";
		        }
		        return pr;
		    }
		    if (r.type == 'name') {
		        var l = r;
		        var val = l.value;
		        var pr = val;
		        if (l.arr) {
		            pr += "[]";
		        }
		        return pr;
		    }
		}
		exports.nodeToString = nodeToString;
		function validateNode(r, node, cb) {
		    if (r.type == "union") {
		        var u = r;
		        validateNode(u.first, node, cb);
		        validateNode(u.rest, node, cb);
		    }
		    if (r.type == "responses") {
		        var res = r;
		        res.codes.forEach(function (x) {
		            var v = x.code;
		            for (var i = 0; i < v.length; i++) {
		                var c = v[i];
		                if (!_.find(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'x', 'X'], function (x) { return x == c; })) {
		                    cb.accept(linter.createIssue(7 /* INVALID_VALUE_SCHEMA */, "Status code should be 3 digits number with optional 'x' as wildcards", node));
		                    return;
		                }
		            }
		            validateNode(x.expr, node, cb);
		        });
		    }
		    if (r.type == 'parens') {
		        var ex = r;
		        validateNode(ex.expr, node, cb);
		    }
		    if (r.type == 'name') {
		        var l = r;
		        var val = l.value;
		        if (val.lastIndexOf("[]") != -1) {
		            val = val.substr(0, val.length - 2); //FIXME Should be in PEG
		        }
		        var pr = node.property();
		        if (pr.getAdapter(services.RAMLPropertyService).isValidValue(val, node.parent())) {
		            return;
		        }
		        var values = pr.getAdapter(services.RAMLPropertyService).enumValues(node.parent());
		        values = values.map(function (x) {
		            var tp = x.indexOf("<");
		            if (tp != -1) {
		                return x.substring(0, tp);
		            }
		            return x;
		        });
		        if (l.params) {
		            l.params.forEach(function (x) {
		                validateNode(x, node, cb);
		            });
		        }
		        values.push("number");
		        values.push("integer");
		        values.push("file");
		        values.push("boolean");
		        values.push("any");
		        values.push("date");
		        values.push("void");
		        values.push("string");
		        values.push("value");
		        if (!_.find(values, function (x) { return x == val; })) {
		            var message = "Unrecognized type '" + val + "'.";
		            cb.accept(linter.createIssue(0 /* UNRESOLVED_REFERENCE */, message, node));
		            return true;
		        }
		    }
		}
		exports.validateNode = validateNode;


	/***/ },
	/* 52 */
	/***/ function(module, exports) {

		var parser = (function () {
		    "use strict";
		    /*
		     * Generated by PEG.js 0.9.0.
		     *
		     * http://pegjs.org/
		     */
		    function peg$subclass(child, parent) {
		        function ctor() {
		            this.constructor = child;
		        }
		        ctor.prototype = parent.prototype;
		        child.prototype = new ctor();
		    }
		    function peg$SyntaxError(message, expected, found, location) {
		        this.message = message;
		        this.expected = expected;
		        this.found = found;
		        this.location = location;
		        this.name = "SyntaxError";
		        if (typeof Error.captureStackTrace === "function") {
		            Error.captureStackTrace(this, peg$SyntaxError);
		        }
		    }
		    peg$subclass(peg$SyntaxError, Error);
		    function peg$parse(input) {
		        var options = arguments.length > 1 ? arguments[1] : {}, parser = this, peg$FAILED = {}, peg$startRuleFunctions = { Term: peg$parseTerm }, peg$startRuleFunction = peg$parseTerm, peg$c0 = "|", peg$c1 = { type: "literal", value: "|", description: "\"|\"" }, peg$c2 = function (first, rest) {
		            return rest ? { "type": "union", "first": first, "rest": rest[3] } : first;
		        }, peg$c3 = "(", peg$c4 = { type: "literal", value: "(", description: "\"(\"" }, peg$c5 = ")", peg$c6 = { type: "literal", value: ")", description: "\")\"" }, peg$c7 = "[]", peg$c8 = { type: "literal", value: "[]", description: "\"[]\"" }, peg$c9 = function (expr, arr) {
		            return { "type": "parens", "expr": expr, "arr": arr.length };
		        }, peg$c10 = "<", peg$c11 = { type: "literal", value: "<", description: "\"<\"" }, peg$c12 = ">", peg$c13 = { type: "literal", value: ">", description: "\">\"" }, peg$c14 = function (first, other) {
		            return [first].concat(other);
		        }, peg$c15 = ",", peg$c16 = { type: "literal", value: ",", description: "\",\"" }, peg$c17 = function (r) {
		            return r;
		        }, peg$c18 = { type: "other", description: "name" }, peg$c19 = function (r, tp, c) {
		            return { "type": "name", "params": tp, "value": r.join(""), "arr": (c.length) };
		        }, peg$c20 = { type: "other", description: "whitespace" }, peg$c21 = /^[ \t\n\r]/, peg$c22 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, peg$c23 = /^[A-Z]/, peg$c24 = { type: "class", value: "[A-Z]", description: "[A-Z]" }, peg$c25 = "_", peg$c26 = { type: "literal", value: "_", description: "\"_\"" }, peg$c27 = "-", peg$c28 = { type: "literal", value: "-", description: "\"-\"" }, peg$c29 = ".", peg$c30 = { type: "literal", value: ".", description: "\".\"" }, peg$c31 = /^[a-z]/, peg$c32 = { type: "class", value: "[a-z]", description: "[a-z]" }, peg$c33 = /^[0-9]/, peg$c34 = { type: "class", value: "[0-9]", description: "[0-9]" }, peg$currPos = 0, peg$savedPos = 0, peg$posDetailsCache = [{ line: 1, column: 1, seenCR: false }], peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, peg$result;
		        if ("startRule" in options) {
		            if (!(options.startRule in peg$startRuleFunctions)) {
		                throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
		            }
		            peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
		        }
		        function text() {
		            return input.substring(peg$savedPos, peg$currPos);
		        }
		        function location() {
		            return peg$computeLocation(peg$savedPos, peg$currPos);
		        }
		        function expected(description) {
		            throw peg$buildException(null, [{ type: "other", description: description }], input.substring(peg$savedPos, peg$currPos), peg$computeLocation(peg$savedPos, peg$currPos));
		        }
		        function error(message) {
		            throw peg$buildException(message, null, input.substring(peg$savedPos, peg$currPos), peg$computeLocation(peg$savedPos, peg$currPos));
		        }
		        function peg$computePosDetails(pos) {
		            var details = peg$posDetailsCache[pos], p, ch;
		            if (details) {
		                return details;
		            }
		            else {
		                p = pos - 1;
		                while (!peg$posDetailsCache[p]) {
		                    p--;
		                }
		                details = peg$posDetailsCache[p];
		                details = {
		                    line: details.line,
		                    column: details.column,
		                    seenCR: details.seenCR
		                };
		                while (p < pos) {
		                    ch = input.charAt(p);
		                    if (ch === "\n") {
		                        if (!details.seenCR) {
		                            details.line++;
		                        }
		                        details.column = 1;
		                        details.seenCR = false;
		                    }
		                    else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
		                        details.line++;
		                        details.column = 1;
		                        details.seenCR = true;
		                    }
		                    else {
		                        details.column++;
		                        details.seenCR = false;
		                    }
		                    p++;
		                }
		                peg$posDetailsCache[pos] = details;
		                return details;
		            }
		        }
		        function peg$computeLocation(startPos, endPos) {
		            var startPosDetails = peg$computePosDetails(startPos), endPosDetails = peg$computePosDetails(endPos);
		            return {
		                start: {
		                    offset: startPos,
		                    line: startPosDetails.line,
		                    column: startPosDetails.column
		                },
		                end: {
		                    offset: endPos,
		                    line: endPosDetails.line,
		                    column: endPosDetails.column
		                }
		            };
		        }
		        function peg$fail(expected) {
		            if (peg$currPos < peg$maxFailPos) {
		                return;
		            }
		            if (peg$currPos > peg$maxFailPos) {
		                peg$maxFailPos = peg$currPos;
		                peg$maxFailExpected = [];
		            }
		            peg$maxFailExpected.push(expected);
		        }
		        function peg$buildException(message, expected, found, location) {
		            function cleanupExpected(expected) {
		                var i = 1;
		                expected.sort(function (a, b) {
		                    if (a.description < b.description) {
		                        return -1;
		                    }
		                    else if (a.description > b.description) {
		                        return 1;
		                    }
		                    else {
		                        return 0;
		                    }
		                });
		                while (i < expected.length) {
		                    if (expected[i - 1] === expected[i]) {
		                        expected.splice(i, 1);
		                    }
		                    else {
		                        i++;
		                    }
		                }
		            }
		            function buildMessage(expected, found) {
		                function stringEscape(s) {
		                    function hex(ch) {
		                        return ch.charCodeAt(0).toString(16).toUpperCase();
		                    }
		                    return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\x08/g, '\\b').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\f/g, '\\f').replace(/\r/g, '\\r').replace(/[\x00-\x07\x0B\x0E\x0F]/g, function (ch) {
		                        return '\\x0' + hex(ch);
		                    }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) {
		                        return '\\x' + hex(ch);
		                    }).replace(/[\u0100-\u0FFF]/g, function (ch) {
		                        return '\\u0' + hex(ch);
		                    }).replace(/[\u1000-\uFFFF]/g, function (ch) {
		                        return '\\u' + hex(ch);
		                    });
		                }
		                var expectedDescs = new Array(expected.length), expectedDesc, foundDesc, i;
		                for (i = 0; i < expected.length; i++) {
		                    expectedDescs[i] = expected[i].description;
		                }
		                expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(", ") + " or " + expectedDescs[expected.length - 1] : expectedDescs[0];
		                foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
		                return "Expected " + expectedDesc + " but " + foundDesc + " found.";
		            }
		            if (expected !== null) {
		                cleanupExpected(expected);
		            }
		            return new peg$SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, location);
		        }
		        function peg$parseTerm() {
		            var s0, s1, s2, s3, s4, s5, s6, s7;
		            s0 = peg$currPos;
		            s1 = peg$parse_();
		            if (s1 !== peg$FAILED) {
		                s2 = peg$parseFactor();
		                if (s2 !== peg$FAILED) {
		                    s3 = peg$currPos;
		                    s4 = peg$parse_();
		                    if (s4 !== peg$FAILED) {
		                        if (input.charCodeAt(peg$currPos) === 124) {
		                            s5 = peg$c0;
		                            peg$currPos++;
		                        }
		                        else {
		                            s5 = peg$FAILED;
		                            if (peg$silentFails === 0) {
		                                peg$fail(peg$c1);
		                            }
		                        }
		                        if (s5 !== peg$FAILED) {
		                            s6 = peg$parse_();
		                            if (s6 !== peg$FAILED) {
		                                s7 = peg$parseTerm();
		                                if (s7 !== peg$FAILED) {
		                                    s4 = [s4, s5, s6, s7];
		                                    s3 = s4;
		                                }
		                                else {
		                                    peg$currPos = s3;
		                                    s3 = peg$FAILED;
		                                }
		                            }
		                            else {
		                                peg$currPos = s3;
		                                s3 = peg$FAILED;
		                            }
		                        }
		                        else {
		                            peg$currPos = s3;
		                            s3 = peg$FAILED;
		                        }
		                    }
		                    else {
		                        peg$currPos = s3;
		                        s3 = peg$FAILED;
		                    }
		                    if (s3 === peg$FAILED) {
		                        s3 = null;
		                    }
		                    if (s3 !== peg$FAILED) {
		                        peg$savedPos = s0;
		                        s1 = peg$c2(s2, s3);
		                        s0 = s1;
		                    }
		                    else {
		                        peg$currPos = s0;
		                        s0 = peg$FAILED;
		                    }
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$FAILED;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$FAILED;
		            }
		            return s0;
		        }
		        function peg$parseFactor() {
		            var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
		            s0 = peg$currPos;
		            if (input.charCodeAt(peg$currPos) === 40) {
		                s1 = peg$c3;
		                peg$currPos++;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c4);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                s2 = peg$parse_();
		                if (s2 !== peg$FAILED) {
		                    s3 = peg$parseTerm();
		                    if (s3 !== peg$FAILED) {
		                        s4 = peg$parse_();
		                        if (s4 !== peg$FAILED) {
		                            if (input.charCodeAt(peg$currPos) === 41) {
		                                s5 = peg$c5;
		                                peg$currPos++;
		                            }
		                            else {
		                                s5 = peg$FAILED;
		                                if (peg$silentFails === 0) {
		                                    peg$fail(peg$c6);
		                                }
		                            }
		                            if (s5 !== peg$FAILED) {
		                                s6 = [];
		                                s7 = peg$currPos;
		                                s8 = peg$parse_();
		                                if (s8 !== peg$FAILED) {
		                                    if (input.substr(peg$currPos, 2) === peg$c7) {
		                                        s9 = peg$c7;
		                                        peg$currPos += 2;
		                                    }
		                                    else {
		                                        s9 = peg$FAILED;
		                                        if (peg$silentFails === 0) {
		                                            peg$fail(peg$c8);
		                                        }
		                                    }
		                                    if (s9 !== peg$FAILED) {
		                                        s8 = [s8, s9];
		                                        s7 = s8;
		                                    }
		                                    else {
		                                        peg$currPos = s7;
		                                        s7 = peg$FAILED;
		                                    }
		                                }
		                                else {
		                                    peg$currPos = s7;
		                                    s7 = peg$FAILED;
		                                }
		                                while (s7 !== peg$FAILED) {
		                                    s6.push(s7);
		                                    s7 = peg$currPos;
		                                    s8 = peg$parse_();
		                                    if (s8 !== peg$FAILED) {
		                                        if (input.substr(peg$currPos, 2) === peg$c7) {
		                                            s9 = peg$c7;
		                                            peg$currPos += 2;
		                                        }
		                                        else {
		                                            s9 = peg$FAILED;
		                                            if (peg$silentFails === 0) {
		                                                peg$fail(peg$c8);
		                                            }
		                                        }
		                                        if (s9 !== peg$FAILED) {
		                                            s8 = [s8, s9];
		                                            s7 = s8;
		                                        }
		                                        else {
		                                            peg$currPos = s7;
		                                            s7 = peg$FAILED;
		                                        }
		                                    }
		                                    else {
		                                        peg$currPos = s7;
		                                        s7 = peg$FAILED;
		                                    }
		                                }
		                                if (s6 !== peg$FAILED) {
		                                    peg$savedPos = s0;
		                                    s1 = peg$c9(s3, s6);
		                                    s0 = s1;
		                                }
		                                else {
		                                    peg$currPos = s0;
		                                    s0 = peg$FAILED;
		                                }
		                            }
		                            else {
		                                peg$currPos = s0;
		                                s0 = peg$FAILED;
		                            }
		                        }
		                        else {
		                            peg$currPos = s0;
		                            s0 = peg$FAILED;
		                        }
		                    }
		                    else {
		                        peg$currPos = s0;
		                        s0 = peg$FAILED;
		                    }
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$FAILED;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$FAILED;
		            }
		            if (s0 === peg$FAILED) {
		                s0 = peg$parseLiteral();
		            }
		            return s0;
		        }
		        function peg$parseTypeParams() {
		            var s0, s1, s2, s3, s4;
		            s0 = peg$currPos;
		            if (input.charCodeAt(peg$currPos) === 60) {
		                s1 = peg$c10;
		                peg$currPos++;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c11);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                s2 = peg$parseTerm();
		                if (s2 !== peg$FAILED) {
		                    s3 = [];
		                    s4 = peg$parseExtraParam();
		                    while (s4 !== peg$FAILED) {
		                        s3.push(s4);
		                        s4 = peg$parseExtraParam();
		                    }
		                    if (s3 !== peg$FAILED) {
		                        if (input.charCodeAt(peg$currPos) === 62) {
		                            s4 = peg$c12;
		                            peg$currPos++;
		                        }
		                        else {
		                            s4 = peg$FAILED;
		                            if (peg$silentFails === 0) {
		                                peg$fail(peg$c13);
		                            }
		                        }
		                        if (s4 !== peg$FAILED) {
		                            peg$savedPos = s0;
		                            s1 = peg$c14(s2, s3);
		                            s0 = s1;
		                        }
		                        else {
		                            peg$currPos = s0;
		                            s0 = peg$FAILED;
		                        }
		                    }
		                    else {
		                        peg$currPos = s0;
		                        s0 = peg$FAILED;
		                    }
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$FAILED;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$FAILED;
		            }
		            return s0;
		        }
		        function peg$parseExtraParam() {
		            var s0, s1, s2;
		            s0 = peg$currPos;
		            if (input.charCodeAt(peg$currPos) === 44) {
		                s1 = peg$c15;
		                peg$currPos++;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c16);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                s2 = peg$parseTerm();
		                if (s2 !== peg$FAILED) {
		                    peg$savedPos = s0;
		                    s1 = peg$c17(s2);
		                    s0 = s1;
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$FAILED;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$FAILED;
		            }
		            return s0;
		        }
		        function peg$parseLiteral() {
		            var s0, s1, s2, s3, s4, s5, s6;
		            peg$silentFails++;
		            s0 = peg$currPos;
		            s1 = [];
		            s2 = peg$parsechar();
		            if (s2 !== peg$FAILED) {
		                while (s2 !== peg$FAILED) {
		                    s1.push(s2);
		                    s2 = peg$parsechar();
		                }
		            }
		            else {
		                s1 = peg$FAILED;
		            }
		            if (s1 !== peg$FAILED) {
		                s2 = peg$parseTypeParams();
		                if (s2 === peg$FAILED) {
		                    s2 = null;
		                }
		                if (s2 !== peg$FAILED) {
		                    s3 = [];
		                    s4 = peg$currPos;
		                    s5 = peg$parse_();
		                    if (s5 !== peg$FAILED) {
		                        if (input.substr(peg$currPos, 2) === peg$c7) {
		                            s6 = peg$c7;
		                            peg$currPos += 2;
		                        }
		                        else {
		                            s6 = peg$FAILED;
		                            if (peg$silentFails === 0) {
		                                peg$fail(peg$c8);
		                            }
		                        }
		                        if (s6 !== peg$FAILED) {
		                            s5 = [s5, s6];
		                            s4 = s5;
		                        }
		                        else {
		                            peg$currPos = s4;
		                            s4 = peg$FAILED;
		                        }
		                    }
		                    else {
		                        peg$currPos = s4;
		                        s4 = peg$FAILED;
		                    }
		                    while (s4 !== peg$FAILED) {
		                        s3.push(s4);
		                        s4 = peg$currPos;
		                        s5 = peg$parse_();
		                        if (s5 !== peg$FAILED) {
		                            if (input.substr(peg$currPos, 2) === peg$c7) {
		                                s6 = peg$c7;
		                                peg$currPos += 2;
		                            }
		                            else {
		                                s6 = peg$FAILED;
		                                if (peg$silentFails === 0) {
		                                    peg$fail(peg$c8);
		                                }
		                            }
		                            if (s6 !== peg$FAILED) {
		                                s5 = [s5, s6];
		                                s4 = s5;
		                            }
		                            else {
		                                peg$currPos = s4;
		                                s4 = peg$FAILED;
		                            }
		                        }
		                        else {
		                            peg$currPos = s4;
		                            s4 = peg$FAILED;
		                        }
		                    }
		                    if (s3 !== peg$FAILED) {
		                        peg$savedPos = s0;
		                        s1 = peg$c19(s1, s2, s3);
		                        s0 = s1;
		                    }
		                    else {
		                        peg$currPos = s0;
		                        s0 = peg$FAILED;
		                    }
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$FAILED;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$FAILED;
		            }
		            peg$silentFails--;
		            if (s0 === peg$FAILED) {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c18);
		                }
		            }
		            return s0;
		        }
		        function peg$parse_() {
		            var s0, s1;
		            peg$silentFails++;
		            s0 = [];
		            if (peg$c21.test(input.charAt(peg$currPos))) {
		                s1 = input.charAt(peg$currPos);
		                peg$currPos++;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c22);
		                }
		            }
		            while (s1 !== peg$FAILED) {
		                s0.push(s1);
		                if (peg$c21.test(input.charAt(peg$currPos))) {
		                    s1 = input.charAt(peg$currPos);
		                    peg$currPos++;
		                }
		                else {
		                    s1 = peg$FAILED;
		                    if (peg$silentFails === 0) {
		                        peg$fail(peg$c22);
		                    }
		                }
		            }
		            peg$silentFails--;
		            if (s0 === peg$FAILED) {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c20);
		                }
		            }
		            return s0;
		        }
		        function peg$parsechar() {
		            var s0;
		            if (peg$c23.test(input.charAt(peg$currPos))) {
		                s0 = input.charAt(peg$currPos);
		                peg$currPos++;
		            }
		            else {
		                s0 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c24);
		                }
		            }
		            if (s0 === peg$FAILED) {
		                if (input.charCodeAt(peg$currPos) === 95) {
		                    s0 = peg$c25;
		                    peg$currPos++;
		                }
		                else {
		                    s0 = peg$FAILED;
		                    if (peg$silentFails === 0) {
		                        peg$fail(peg$c26);
		                    }
		                }
		                if (s0 === peg$FAILED) {
		                    if (input.charCodeAt(peg$currPos) === 45) {
		                        s0 = peg$c27;
		                        peg$currPos++;
		                    }
		                    else {
		                        s0 = peg$FAILED;
		                        if (peg$silentFails === 0) {
		                            peg$fail(peg$c28);
		                        }
		                    }
		                    if (s0 === peg$FAILED) {
		                        if (input.charCodeAt(peg$currPos) === 46) {
		                            s0 = peg$c29;
		                            peg$currPos++;
		                        }
		                        else {
		                            s0 = peg$FAILED;
		                            if (peg$silentFails === 0) {
		                                peg$fail(peg$c30);
		                            }
		                        }
		                        if (s0 === peg$FAILED) {
		                            if (peg$c31.test(input.charAt(peg$currPos))) {
		                                s0 = input.charAt(peg$currPos);
		                                peg$currPos++;
		                            }
		                            else {
		                                s0 = peg$FAILED;
		                                if (peg$silentFails === 0) {
		                                    peg$fail(peg$c32);
		                                }
		                            }
		                            if (s0 === peg$FAILED) {
		                                if (peg$c33.test(input.charAt(peg$currPos))) {
		                                    s0 = input.charAt(peg$currPos);
		                                    peg$currPos++;
		                                }
		                                else {
		                                    s0 = peg$FAILED;
		                                    if (peg$silentFails === 0) {
		                                        peg$fail(peg$c34);
		                                    }
		                                }
		                            }
		                        }
		                    }
		                }
		            }
		            return s0;
		        }
		        peg$result = peg$startRuleFunction();
		        if (peg$result !== peg$FAILED && peg$currPos === input.length) {
		            return peg$result;
		        }
		        else {
		            if (peg$result !== peg$FAILED && peg$currPos < input.length) {
		                peg$fail({ type: "end", description: "end of input" });
		            }
		            throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) : peg$computeLocation(peg$maxFailPos, peg$maxFailPos));
		        }
		    }
		    return {
		        SyntaxError: peg$SyntaxError,
		        parse: peg$parse
		    };
		})();
		module.exports = parser;


	/***/ },
	/* 53 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var defs = __webpack_require__(3);
		var hl = __webpack_require__(2);
		var _ = __webpack_require__(4);
		var typeExpression = __webpack_require__(51);
		var hlimpl = __webpack_require__(5);
		var universes = __webpack_require__(54);
		var typeBuilder = __webpack_require__(50);
		var ramlServices = __webpack_require__(49);
		//FIXME CORRECTLY STRUCTURE IT
		function resolveRamlPointer(point, path) {
		    var components = path.split(".");
		    var currentNode = point;
		    if (currentNode.definition().getAdapter(ramlServices.RAMLService).isAnnotation()) {
		        currentNode = currentNode.parent();
		    }
		    components.forEach(function (x) {
		        if (currentNode == null) {
		            return;
		        }
		        if (x == '$parent') {
		            currentNode = currentNode.parent();
		            return;
		        }
		        if (x == '$root') {
		            currentNode = currentNode.root();
		            return;
		        }
		        if (x == '$top') {
		            currentNode = exports.declRoot(currentNode);
		            return;
		        }
		        var newEl = _.find(currentNode.elements(), function (y) { return y.name() == x; });
		        currentNode = newEl;
		    });
		    return currentNode;
		}
		exports.resolveRamlPointer = resolveRamlPointer;
		exports.declRoot = function (h) {
		    var declRoot = h;
		    while (true) {
		        if (declRoot.definition().key() == universes.Universe10.Library) {
		            break;
		        }
		        var np = declRoot.parent();
		        if (!np) {
		            break;
		        }
		        declRoot = np;
		    }
		    return declRoot;
		};
		function globalDeclarations(h) {
		    var decl = exports.declRoot(h);
		    return findDeclarations(decl);
		}
		exports.globalDeclarations = globalDeclarations;
		function mark(h, rs) {
		    var n = h.lowLevel();
		    n = n._node ? n._node : n;
		    if (n['mark']) {
		        return rs;
		    }
		    n['mark'] = rs;
		    return null;
		}
		function unmark(h) {
		    var n = h.lowLevel();
		    n = n._node ? n._node : n;
		    delete n['mark'];
		}
		function findDeclarations(h) {
		    var rs = [];
		    var q = mark(h, rs);
		    if (q) {
		    }
		    try {
		        h.elements().forEach(function (x) {
		            if (x.definition().key() == universes.Universe10.Library) {
		                rs = rs.concat(findDeclarations(x));
		            }
		            rs.push(x);
		        });
		        return rs;
		    }
		    finally {
		        unmark(h);
		    }
		}
		exports.findDeclarations = findDeclarations;
		function getIndent2(offset, text) {
		    var spaces = "";
		    for (var i = offset - 1; i >= 0; i--) {
		        var c = text.charAt(i);
		        if (c == ' ' || c == '\t') {
		            if (spaces) {
		                spaces += c;
		            }
		            else {
		                spaces = c;
		            }
		        }
		        else if (c == '\r' || c == '\n') {
		            return spaces;
		        }
		    }
		}
		function deepFindNode(n, offset, end, goToOtherUnits) {
		    if (goToOtherUnits === void 0) { goToOtherUnits = true; }
		    if (n == null) {
		        return null;
		    }
		    if (n.lowLevel()) {
		        //var node:ASTNode=<ASTNode>n;
		        if (n.lowLevel().start() <= offset && n.lowLevel().end() >= end) {
		            if (n instanceof hlimpl.ASTNodeImpl) {
		                var hn = n;
		                var all = goToOtherUnits ? hn.children() : hn.directChildren();
		                for (var i = 0; i < all.length; i++) {
		                    if (!goToOtherUnits && all[i].lowLevel().unit() != n.lowLevel().unit()) {
		                        continue;
		                    }
		                    var node = deepFindNode(all[i], offset, end, goToOtherUnits);
		                    if (node) {
		                        return node;
		                    }
		                }
		                return n;
		            }
		            else if (n instanceof hlimpl.ASTPropImpl) {
		                var attr = n;
		                if (!attr.property().isKey()) {
		                    var vl = attr.value();
		                    if (vl instanceof hlimpl.StructuredValue) {
		                        var st = vl;
		                        var hl = st.toHighLevel();
		                        if (hl) {
		                            if (!goToOtherUnits && hl.lowLevel().unit() != n.lowLevel().unit()) {
		                                return null;
		                            }
		                        }
		                        var node = deepFindNode(hl, offset, end, goToOtherUnits);
		                        if (node) {
		                            return node;
		                        }
		                    }
		                    return attr;
		                }
		                return null;
		            }
		            return null;
		        }
		    }
		    return null;
		}
		function getValueAt(text, offset) {
		    var sp = -1;
		    for (var i = offset - 1; i >= 0; i--) {
		        var c = text.charAt(i);
		        if (c == '\r' || c == '\n' || c == ' ' || c == '\t' || c == '"' || c == '\'' || c == ':') {
		            sp = i + 1;
		            break;
		        }
		    }
		    var ep = -1;
		    for (var i = offset; i < text.length; i++) {
		        var c = text.charAt(i);
		        if (c == '\r' || c == '\n' || c == ' ' || c == '\t' || c == '"' || c == '\'' || c == ':') {
		            ep = i;
		            break;
		        }
		    }
		    if (sp != -1 && ep != -1) {
		        return text.substring(sp, ep);
		    }
		    return "";
		}
		function extractName(cleaned, offset) {
		    var txt = "";
		    for (var i = offset; i >= 0; i--) {
		        var c = cleaned[i];
		        if (c == ' ' || c == '\r' || c == '\n' || c == '|' || c == '[' || c == ']' || c == ':' || c == '(' || c == ')') {
		            break;
		        }
		        txt = c + txt;
		    }
		    for (var i = offset + 1; i < cleaned.length; i++) {
		        var c = cleaned[i];
		        if (c == ' ' || c == '\r' || c == '\n' || c == '|' || c == '[' || c == ']' || c == ':' || c == '(' || c == ')') {
		            break;
		        }
		        txt = txt + c;
		    }
		    return txt;
		}
		exports.extractName = extractName;
		var searchInTheValue = function (offset, content, attr, hlnode, p) {
		    if (p === void 0) { p = attr.property(); }
		    var targets = p.getAdapter(ramlServices.RAMLPropertyService).referenceTargets(hlnode);
		    var txt = extractName(content, offset);
		    var t = _.find(targets, function (x) { return hlimpl.qName(x, hlnode) == txt; });
		    if (t) {
		        //TODO EXTRACT COMMON OPEN NODE FUNC
		        return t;
		    }
		    if (p instanceof defs.UserDefinedProp) {
		        var up = p;
		        return up._node;
		    }
		    return null;
		};
		function findUsages(unit, offset) {
		    var decl = findDeclaration(unit, offset);
		    if (decl) {
		        if (decl instanceof hlimpl.ASTNodeImpl) {
		            var hnode = decl;
		            return { node: hnode, results: hnode.findReferences() };
		        }
		        if (decl instanceof hlimpl.ASTPropImpl) {
		        }
		    }
		    var node = deepFindNode(hl.fromUnit(unit), offset, offset, false);
		    if (node instanceof hlimpl.ASTNodeImpl) {
		        return { node: node, results: node.findReferences() };
		    }
		    if (node instanceof hlimpl.ASTPropImpl) {
		        var prop = node;
		        if (prop.property().canBeValue()) {
		            return { node: prop.parent(), results: prop.parent().findReferences() };
		        }
		    }
		    return { node: null, results: [] };
		}
		exports.findUsages = findUsages;
		function getLibraryName(node) {
		    if (node.isElement() && node.asElement().definition().key() != universes.Universe10.Library) {
		        return null;
		    }
		    return node.asElement().attrValue("name");
		}
		function findDeclarationByNode(node, nodePart) {
		    var unit = node.lowLevel().unit();
		    if (!unit) {
		        return null;
		    }
		    var start = node.lowLevel().start();
		    var end = node.lowLevel().end();
		    if (nodePart && nodePart == 1 /* KEY_COMPLETION */) {
		        start = node.lowLevel().keyStart();
		        end = node.lowLevel().keyEnd();
		    }
		    else if (nodePart && nodePart == 0 /* VALUE_COMPLETION */) {
		        start = node.lowLevel().valueStart();
		        end = node.lowLevel().valueEnd();
		    }
		    if (start == -1 || end == -1) {
		        return null;
		    }
		    var offset = Math.floor((start + end) / 2);
		    return findDeclaration(unit, offset, nodePart);
		}
		exports.findDeclarationByNode = findDeclarationByNode;
		function findDeclaration(unit, offset, nodePart) {
		    var node = deepFindNode(hl.fromUnit(unit), offset, offset, false);
		    var kind = nodePart ? nodePart : determineCompletionKind(unit.contents(), offset);
		    if (kind == 0 /* VALUE_COMPLETION */) {
		        var hlnode = node;
		        if (node instanceof hlimpl.ASTPropImpl) {
		            var attr = node;
		            if (attr) {
		                if (attr.value()) {
		                    if (attr.value() instanceof hlimpl.StructuredValue) {
		                        var sval = attr.value();
		                        var hlvalue = sval.toHighLevel();
		                        if (hlvalue) {
		                            var newAttr = _.find(hlvalue.attrs(), function (x) { return x.lowLevel().start() < offset && x.lowLevel().end() >= offset; });
		                            if (newAttr) {
		                                return searchInTheValue(offset, unit.contents(), newAttr, hlvalue, attr.property());
		                            }
		                        }
		                    }
		                    else {
		                        return searchInTheValue(offset, unit.contents(), attr, hlnode);
		                    }
		                }
		            }
		        }
		        else {
		            return searchInTheValue(offset, unit.contents(), null, hlnode, hlnode.property());
		        }
		    }
		    if (kind == 1 /* KEY_COMPLETION */ || kind == 6 /* SEQUENCE_KEY_COPLETION */) {
		        var hlnode = node;
		        var pp = node.property();
		        if (pp instanceof defs.UserDefinedProp) {
		            var up = pp;
		            return up.node();
		        }
		        if (node instanceof hlimpl.ASTNodeImpl) {
		            if (hlnode.definition() instanceof defs.UserDefinedClass) {
		                var uc = hlnode.definition();
		                if (uc.isAssignableFrom("TypeDeclaration")) {
		                    return node;
		                }
		                return uc.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		            }
		        }
		        if (node instanceof hlimpl.ASTPropImpl) {
		            var pr = node;
		            if (isExampleNodeContent(pr)) {
		                var contentType = findExampleContentType(pr);
		                if (contentType) {
		                    var documentationRoot = parseDocumentationContent(pr, contentType.getAdapter(ramlServices.RAMLService).toRuntime());
		                    if (documentationRoot) {
		                        var node = deepFindNode(documentationRoot, offset, offset);
		                        pp = node.property();
		                        if (pp instanceof defs.UserDefinedProp) {
		                            var up = pp;
		                            return up.node();
		                        }
		                        if (node instanceof hlimpl.ASTNodeImpl) {
		                            if (hlnode.definition() instanceof defs.UserDefinedClass) {
		                                var uc = hlnode.definition();
		                                return uc.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		                            }
		                        }
		                    }
		                }
		            }
		        }
		    }
		    if (kind == 2 /* PATH_COMPLETION */) {
		        var inclpath = getValueAt(unit.contents(), offset);
		        if (inclpath) {
		            var ap = unit.resolve(inclpath);
		            return ap;
		        }
		    }
		}
		exports.findDeclaration = findDeclaration;
		function findExampleContentType(node) {
		    var p = node.parent();
		    if (node.property().nameId() == universes.Universe10.ExampleSpec.properties.content.name) {
		        p = p.parent();
		    }
		    return typeBuilder.typeFromNode(p);
		}
		exports.findExampleContentType = findExampleContentType;
		function parseDocumentationContent(attribute, type) {
		    if (!(attribute.value() instanceof hlimpl.StructuredValue)) {
		        return null;
		    }
		    return new hlimpl.ASTNodeImpl(attribute.value().lowLevel(), attribute.parent(), type, attribute.property());
		}
		exports.parseDocumentationContent = parseDocumentationContent;
		function isExampleNodeContent(node) {
		    var typeExampleName10 = universes.Universe10.TypeDeclaration.properties.example.name;
		    var typeExamplesName10 = universes.Universe10.TypeDeclaration.properties.examples.name;
		    var contentName10 = universes.Universe10.ExampleSpec.properties.content.name;
		    var objectName10 = universes.Universe10.ObjectTypeDeclaration.name;
		    if (!(node instanceof hlimpl.ASTPropImpl)) {
		        return false;
		    }
		    var property = node;
		    var parent = property.parent();
		    var parentProperty = parent && parent.property();
		    var parentPropertyName = parentProperty && parentProperty.nameId();
		    if (contentName10 === property.name() && property.isString()) {
		        if (parent instanceof hlimpl.ASTNodeImpl && (typeExamplesName10 === parentPropertyName || typeExampleName10 === parentPropertyName)) {
		            if (parent.parent() instanceof hlimpl.ASTNodeImpl && parent.parent().definition().isAssignableFrom(objectName10)) {
		                return true;
		            }
		        }
		    }
		    else if (typeExampleName10 === property.name() && property.isString()) {
		        if (parent instanceof hlimpl.ASTNodeImpl && parent.definition().isAssignableFrom(objectName10)) {
		            return true;
		        }
		    }
		    return false;
		}
		exports.isExampleNodeContent = isExampleNodeContent;
		function determineCompletionKind(text, offset) {
		    var hasIn = false;
		    var hasSeq = false;
		    var canBeInComment = false;
		    var canBeAnnotation = false;
		    for (var i = offset - 1; i >= 0; i--) {
		        var c = text.charAt(i);
		        if (c == '(') {
		            canBeAnnotation = true;
		        }
		        else if (canBeAnnotation) {
		            if (c == '\r' || c == '\n') {
		                var hasClosing = false;
		                for (var j = offset - 1; j < text.length; j++) {
		                    var ch = text[j];
		                    if (ch == ')') {
		                        hasClosing = true;
		                    }
		                    if (ch == '\r' || ch == "\n") {
		                        break;
		                    }
		                    if (ch == ':') {
		                        canBeAnnotation = false;
		                        break;
		                    }
		                }
		                if (canBeAnnotation && hasClosing) {
		                    return 5 /* ANNOTATION_COMPLETION */;
		                }
		                else {
		                    break;
		                }
		            }
		            if (c == ' ' || c == '\t') {
		                continue;
		            }
		            else {
		                break;
		            }
		        }
		        else {
		            if (c == '\r' || c == '\n') {
		                break;
		            }
		            if (c == ':') {
		                break;
		            }
		        }
		    }
		    for (var i = offset - 1; i >= 0; i--) {
		        var c = text.charAt(i);
		        if (c == '#') {
		            if (i == 0) {
		                return 4 /* VERSION_COMPLETION */;
		            }
		            for (var j = i - 1; j >= 0; j--) {
		                var currentChar = text.charAt(j);
		                if (currentChar == '\r' || currentChar == '\n') {
		                    break;
		                }
		                else if (currentChar == '!') {
		                    if (text.indexOf("!include", j) == j) {
		                        return 2 /* PATH_COMPLETION */;
		                    }
		                }
		            }
		            return 7 /* INCOMMENT */;
		        }
		        if (c == ':') {
		            if (hasIn) {
		                return 3 /* DIRECTIVE_COMPLETION */;
		            }
		            return 0 /* VALUE_COMPLETION */;
		        }
		        if (c == '\r' || c == '\n') {
		            //check for multiline literal
		            var insideOfMultiline = false;
		            var ind = getIndent2(offset, text);
		            for (var a = i; a > 0; a--) {
		                c = text.charAt(a);
		                //TODO this can be further improved
		                if (c == ':') {
		                    if (insideOfMultiline) {
		                        var ll = getIndent2(a, text);
		                        if (ll.length < ind.length) {
		                            return 0 /* VALUE_COMPLETION */;
		                        }
		                    }
		                    break;
		                }
		                if (c == '|') {
		                    insideOfMultiline = true;
		                    continue;
		                }
		                if (c == '\r' || c == '\n') {
		                    insideOfMultiline = false;
		                }
		                if (c != ' ' && c != '\t') {
		                    insideOfMultiline = false;
		                }
		            }
		            if (hasSeq) {
		                return 6 /* SEQUENCE_KEY_COPLETION */;
		            }
		            return 1 /* KEY_COMPLETION */;
		        }
		        if (c == '-') {
		            hasSeq = true;
		        }
		        if (c == '!') {
		            if (text.indexOf("!include", i) == i) {
		                return 2 /* PATH_COMPLETION */;
		            }
		            if (text.indexOf("!i", i) == i) {
		                hasIn = true;
		            }
		        }
		    }
		}
		exports.determineCompletionKind = determineCompletionKind;
		(function (LocationKind) {
		    LocationKind[LocationKind["VALUE_COMPLETION"] = 0] = "VALUE_COMPLETION";
		    LocationKind[LocationKind["KEY_COMPLETION"] = 1] = "KEY_COMPLETION";
		    LocationKind[LocationKind["PATH_COMPLETION"] = 2] = "PATH_COMPLETION";
		    LocationKind[LocationKind["DIRECTIVE_COMPLETION"] = 3] = "DIRECTIVE_COMPLETION";
		    LocationKind[LocationKind["VERSION_COMPLETION"] = 4] = "VERSION_COMPLETION";
		    LocationKind[LocationKind["ANNOTATION_COMPLETION"] = 5] = "ANNOTATION_COMPLETION";
		    LocationKind[LocationKind["SEQUENCE_KEY_COPLETION"] = 6] = "SEQUENCE_KEY_COPLETION";
		    LocationKind[LocationKind["INCOMMENT"] = 7] = "INCOMMENT";
		})(exports.LocationKind || (exports.LocationKind = {}));
		var LocationKind = exports.LocationKind;
		function resolveReference(point, path) {
		    if (!path) {
		        return null;
		    }
		    var sp = path.split("/");
		    var result = point;
		    for (var i = 0; i < sp.length; i++) {
		        if (sp[i] == '#') {
		            result = point.unit().ast();
		            continue;
		        }
		        result = _.find(result.children(), function (x) { return x.key() == sp[i]; });
		        if (!result) {
		            return null;
		        }
		    }
		    return result;
		}
		exports.resolveReference = resolveReference;
		/**
		 * return all sub types of given type visible from parent node
		 * @param range
		 * @param parentNode
		 * @returns ITypeDefinition[]
		 */
		exports.subTypesWithLocals = function (range, parentNode) {
		    if (range == null) {
		        return [];
		    }
		    var name = range.nameId();
		    parentNode = exports.declRoot(parentNode);
		    var actual = parentNode;
		    if (actual._subTypesCache) {
		        var cached = actual._subTypesCache[name];
		        if (cached) {
		            return cached;
		        }
		    }
		    else {
		        actual._subTypesCache = {};
		    }
		    var result = range.allSubTypes();
		    if (range.getAdapter(ramlServices.RAMLService).getRuntimeExtenders().length > 0 && parentNode) {
		        var decls = globalDeclarations(parentNode);
		        var extenders = range.getAdapter(ramlServices.RAMLService).getRuntimeExtenders();
		        var root = parentNode.root();
		        extenders.forEach(function (x) {
		            var definitionNodes = decls.filter(function (z) {
		                var def = z.definition().allSuperTypes();
		                def.push(z.definition());
		                var rr = (z.definition() == x) || (_.find(def, function (d) { return d == x; }) != null) || (_.find(def, function (d) { return d == range; }) != null);
		                return rr;
		            });
		            result = result.concat(definitionNodes.map(function (x) { return typeBuilder.typeFromNode(x); }));
		        });
		    }
		    result = _.unique(result);
		    actual._subTypesCache[name] = result;
		    return result;
		};
		exports.subTypesWithName = function (tname, parentNode, backup) {
		    parentNode = exports.declRoot(parentNode);
		    var decls = globalDeclarations(parentNode);
		    var declNode = _.find(decls, function (x) { return hlimpl.qName(x, parentNode) == tname && x.property() && (x.property().nameId() == universes.Universe10.LibraryBase.properties.types.name); });
		    var result = typeBuilder.typeFromNode(declNode);
		    return result;
		};
		exports.schemasWithName = function (tname, parentNode, backup) {
		    parentNode = exports.declRoot(parentNode);
		    var decls = globalDeclarations(parentNode);
		    var declNode = _.find(decls, function (x) { return hlimpl.qName(x, parentNode) == tname && x.property() && (x.property().nameId() == universes.Universe10.LibraryBase.properties.schemas.name); });
		    var result = typeBuilder.typeFromNode(declNode);
		    return result;
		};
		exports.nodesDeclaringType = function (range, n) {
		    var result = [];
		    var extenders = range.getAdapter(ramlServices.RAMLService).getRuntimeExtenders();
		    if (extenders.length > 0 && n) {
		        var root = n;
		        extenders.forEach(function (x) {
		            var definitionNodes = globalDeclarations(root).filter(function (z) { return z.definition().isAssignableFrom(x.nameId()); });
		            result = result.concat(definitionNodes);
		        });
		    }
		    var isElementType = !range.hasValueTypeInHierarchy();
		    if (isElementType && range.getAdapter(ramlServices.RAMLService).isInlinedTemplates() && n) {
		        var root = n;
		        //TODO I did not like it it might be written much better
		        var definitionNodes = globalDeclarations(root).filter(function (z) { return z.definition() == range; });
		        result = result.concat(definitionNodes);
		    }
		    else {
		        var root = n;
		        var q = {};
		        range.allSubTypes().forEach(function (x) { return q[x.nameId()] = true; });
		        q[range.nameId()] = true;
		        var definitionNodes = globalDeclarations(root).filter(function (z) { return q[z.definition().nameId()]; });
		        result = result.concat(definitionNodes);
		    }
		    return result;
		};
		function findAllSubTypes(p, n) {
		    var range = p.range();
		    return exports.subTypesWithLocals(range, n);
		}
		exports.findAllSubTypes = findAllSubTypes;
		;
		function possibleNodes(p, c) {
		    if (c) {
		        if (p.isDescriminator()) {
		            var range = p.range();
		            var extenders = range.getAdapter(ramlServices.RAMLService).getRuntimeExtenders();
		            if (extenders.length > 0 && c) {
		                var result = [];
		                extenders.forEach(function (x) {
		                    var definitionNodes = globalDeclarations(c).filter(function (z) { return z.definition() == x; });
		                    result = result.concat(definitionNodes);
		                });
		                return result;
		            }
		            return [];
		        }
		        if (p.isReference()) {
		            return exports.nodesDeclaringType(p.referencesTo(), c);
		        }
		        if (p.range().hasValueTypeInHierarchy()) {
		            var vt = p.range().getAdapter(ramlServices.RAMLService);
		            if (vt.globallyDeclaredBy && vt.globallyDeclaredBy().length > 0) {
		                var definitionNodes = globalDeclarations(c).filter(function (z) { return _.find(vt.globallyDeclaredBy(), function (x) { return x == z.definition(); }) != null; });
		                return definitionNodes;
		            }
		        }
		    }
		    return this._enumOptions;
		}
		function allChildren(node) {
		    var res = [];
		    gather(node, res);
		    return res;
		}
		exports.allChildren = allChildren;
		function gather(node, result) {
		    node.children().forEach(function (x) {
		        result.push(x);
		        gather(x, result);
		    });
		}
		var testUsage = function (ck, x, node, result) {
		    if (ck instanceof defs.UserDefinedClass) {
		        var ud = ck;
		        if (node.isSameNode(ud.getAdapter(ramlServices.RAMLService).getDeclaringNode())) {
		            result.push(x);
		        }
		    }
		    if (ck instanceof defs.Array) {
		        var cmp = ck;
		        testUsage(cmp.component, x, node, result);
		    }
		    if (ck instanceof defs.Union) {
		        var uni = ck;
		        testUsage(uni.left, x, node, result);
		        testUsage(uni.right, x, node, result);
		    }
		};
		function refFinder(root, node, result) {
		    root.elements().forEach(function (x) {
		        refFinder(x, node, result);
		        //console.log(x.name())
		        var ck = x.definition();
		        //testUsage(ck, x, node, result);
		    });
		    root.attrs().forEach(function (a) {
		        var pr = a.property();
		        var vl = a.value();
		        //if (pr.isTypeExpr()){
		        //    typeExpression.
		        //}
		        if (pr instanceof defs.UserDefinedProp) {
		            var up = pr.node();
		            if (up == node) {
		                result.push(a);
		            }
		            else if (up.lowLevel().start() == node.lowLevel().start()) {
		                if (up.lowLevel().unit() == node.lowLevel().unit()) {
		                    result.push(a);
		                }
		            }
		        }
		        if (isExampleNodeContent(a)) {
		            var contentType = findExampleContentType(a);
		            if (contentType) {
		                var documentationRoot = parseDocumentationContent(a, contentType.getAdapter(ramlServices.RAMLService).toRuntime());
		                if (documentationRoot) {
		                    refFinder(documentationRoot, node, result);
		                }
		            }
		        }
		        else if (pr.getAdapter(ramlServices.RAMLPropertyService).isTypeExpr() && typeof vl == "string") {
		            var tpa = typeExpression.getType(root, "" + vl, {});
		            testUsage(tpa, a, node, result);
		            var libraryName = getLibraryName(node);
		            if (libraryName && vl.indexOf(libraryName) != -1) {
		                var referencingLibrary = getLibraryDefiningNode(a);
		                if (referencingLibrary && referencingLibrary.lowLevel().start() == node.lowLevel().start()) {
		                    result.push(a);
		                }
		            }
		        }
		        if (pr.isReference() || pr.isDescriminator()) {
		            if (typeof vl == 'string') {
		                var pn = possibleNodes(pr, root);
		                if (_.find(pn, function (x) { return x.name() == vl && x == node; })) {
		                    result.push(a);
		                }
		                var libraryName = getLibraryName(node);
		                if (libraryName && vl.indexOf(libraryName) != -1) {
		                    var referencingLibrary = getLibraryDefiningNode(a);
		                    if (referencingLibrary && referencingLibrary.lowLevel().start() == node.lowLevel().start()) {
		                        result.push(a);
		                    }
		                }
		            }
		            else {
		                var st = vl;
		                if (st) {
		                    var vn = st.valueName();
		                    var pn = possibleNodes(pr, root);
		                    if (_.find(pn, function (x) { return x.name() == vn && x == node; })) {
		                        result.push(a);
		                    }
		                    var hnode = st.toHighLevel();
		                    if (hnode) {
		                        refFinder(hnode, node, result);
		                    }
		                    var libraryName = getLibraryName(node);
		                    if (libraryName && vn.indexOf(libraryName) != -1) {
		                        var referencingLibrary = getLibraryDefiningNode(hnode);
		                        if (referencingLibrary && referencingLibrary.lowLevel().start() == node.lowLevel().start()) {
		                            result.push(a);
		                        }
		                    }
		                }
		            }
		        }
		        else {
		            var pn = possibleNodes(pr, root);
		            if (_.find(pn, function (x) { return x.name() == vl && x == node; })) {
		                result.push(a);
		            }
		        }
		    });
		}
		exports.refFinder = refFinder;
		/**
		 * Returns library node that definition of the current node is located in, or null
		 * if current node is not defined in a library.
		 */
		function getLibraryDefiningNode(nodeToCheck) {
		    if (!nodeToCheck.lowLevel) {
		        return null;
		    }
		    var lowLevelNode = nodeToCheck.lowLevel();
		    if (!lowLevelNode) {
		        return null;
		    }
		    if (lowLevelNode.key()) {
		        var offset = Math.floor((lowLevelNode.keyEnd() + lowLevelNode.keyStart()) / 2);
		        var result = getLibraryDefiningNodeByOffset(lowLevelNode.unit(), offset);
		        if (result)
		            return result;
		    }
		    if (lowLevelNode.value()) {
		        var offset = Math.floor((lowLevelNode.valueEnd() + lowLevelNode.valueStart()) / 2);
		        var result = getLibraryDefiningNodeByOffset(lowLevelNode.unit(), offset);
		        if (result)
		            return result;
		    }
		    return null;
		}
		function getLibraryDefiningNodeByOffset(unit, offset) {
		    var declaration = findDeclaration(unit, offset);
		    if (declaration && declaration.isElement && declaration.isElement()) {
		        var declarationNode = declaration.asElement();
		        var parent = declarationNode;
		        while (parent) {
		            if (parent.definition().key() == universes.Universe10.Library) {
		                return parent;
		            }
		            parent = parent.parent();
		        }
		    }
		    return null;
		}


	/***/ },
	/* 54 */
	/***/ function(module, exports) {

		var Universes = {
		    "Universe08": {
		        "GlobalSchema": {
		            "name": "GlobalSchema",
		            "properties": {
		                "key": {
		                    "name": "key"
		                },
		                "value": {
		                    "name": "value"
		                }
		            }
		        },
		        "Api": {
		            "name": "Api",
		            "properties": {
		                "title": {
		                    "name": "title"
		                },
		                "version": {
		                    "name": "version"
		                },
		                "baseUri": {
		                    "name": "baseUri"
		                },
		                "baseUriParameters": {
		                    "name": "baseUriParameters"
		                },
		                "uriParameters": {
		                    "name": "uriParameters"
		                },
		                "protocols": {
		                    "name": "protocols"
		                },
		                "mediaType": {
		                    "name": "mediaType"
		                },
		                "schemas": {
		                    "name": "schemas"
		                },
		                "traits": {
		                    "name": "traits"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "securitySchemes": {
		                    "name": "securitySchemes"
		                },
		                "resourceTypes": {
		                    "name": "resourceTypes"
		                },
		                "resources": {
		                    "name": "resources"
		                },
		                "documentation": {
		                    "name": "documentation"
		                }
		            }
		        },
		        "DocumentationItem": {
		            "name": "DocumentationItem",
		            "properties": {
		                "title": {
		                    "name": "title"
		                },
		                "content": {
		                    "name": "content"
		                }
		            }
		        },
		        "ValueType": {
		            "name": "ValueType",
		            "properties": {}
		        },
		        "StringType": {
		            "name": "StringType",
		            "properties": {}
		        },
		        "NumberType": {
		            "name": "NumberType",
		            "properties": {}
		        },
		        "BooleanType": {
		            "name": "BooleanType",
		            "properties": {}
		        },
		        "Referencable": {
		            "name": "Referencable",
		            "properties": {}
		        },
		        "Reference": {
		            "name": "Reference",
		            "properties": {}
		        },
		        "DeclaresDynamicType": {
		            "name": "DeclaresDynamicType",
		            "properties": {}
		        },
		        "UriTemplate": {
		            "name": "UriTemplate",
		            "properties": {}
		        },
		        "RelativeUriString": {
		            "name": "RelativeUriString",
		            "properties": {}
		        },
		        "FullUriTemplateString": {
		            "name": "FullUriTemplateString",
		            "properties": {}
		        },
		        "FixedUri": {
		            "name": "FixedUri",
		            "properties": {}
		        },
		        "MarkdownString": {
		            "name": "MarkdownString",
		            "properties": {}
		        },
		        "SchemaString": {
		            "name": "SchemaString",
		            "properties": {}
		        },
		        "JSonSchemaString": {
		            "name": "JSonSchemaString",
		            "properties": {}
		        },
		        "XMLSchemaString": {
		            "name": "XMLSchemaString",
		            "properties": {}
		        },
		        "ExampleString": {
		            "name": "ExampleString",
		            "properties": {}
		        },
		        "StatusCodeString": {
		            "name": "StatusCodeString",
		            "properties": {}
		        },
		        "JSONExample": {
		            "name": "JSONExample",
		            "properties": {}
		        },
		        "XMLExample": {
		            "name": "XMLExample",
		            "properties": {}
		        },
		        "ResourceTypeRef": {
		            "name": "ResourceTypeRef",
		            "properties": {}
		        },
		        "TraitRef": {
		            "name": "TraitRef",
		            "properties": {}
		        },
		        "MethodBase": {
		            "name": "MethodBase",
		            "properties": {
		                "responses": {
		                    "name": "responses"
		                },
		                "body": {
		                    "name": "body"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                }
		            }
		        },
		        "Trait": {
		            "name": "Trait",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "usage": {
		                    "name": "usage"
		                }
		            }
		        },
		        "ResourceType": {
		            "name": "ResourceType",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "usage": {
		                    "name": "usage"
		                },
		                "methods": {
		                    "name": "methods"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "uriParameters": {
		                    "name": "uriParameters"
		                },
		                "displayName": {
		                    "name": "displayName"
		                }
		            }
		        },
		        "Method": {
		            "name": "Method",
		            "properties": {
		                "method": {
		                    "name": "method"
		                },
		                "protocols": {
		                    "name": "protocols"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                }
		            }
		        },
		        "Resource": {
		            "name": "Resource",
		            "properties": {
		                "relativeUri": {
		                    "name": "relativeUri"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "uriParameters": {
		                    "name": "uriParameters"
		                },
		                "methods": {
		                    "name": "methods"
		                },
		                "resources": {
		                    "name": "resources"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "baseUriParameters": {
		                    "name": "baseUriParameters"
		                }
		            }
		        },
		        "SecuritySchemePart": {
		            "name": "SecuritySchemePart",
		            "properties": {
		                "headers": {
		                    "name": "headers"
		                },
		                "queryParameters": {
		                    "name": "queryParameters"
		                },
		                "responses": {
		                    "name": "responses"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                }
		            }
		        },
		        "SecuritySchemeSettings": {
		            "name": "SecuritySchemeSettings",
		            "properties": {}
		        },
		        "AbstractSecurityScheme": {
		            "name": "AbstractSecurityScheme",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "describedBy": {
		                    "name": "describedBy"
		                },
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "SecuritySchemeRef": {
		            "name": "SecuritySchemeRef",
		            "properties": {}
		        },
		        "OAuth1SecuritySchemeSettings": {
		            "name": "OAuth1SecuritySchemeSettings",
		            "properties": {
		                "requestTokenUri": {
		                    "name": "requestTokenUri"
		                },
		                "authorizationUri": {
		                    "name": "authorizationUri"
		                },
		                "tokenCredentialsUri": {
		                    "name": "tokenCredentialsUri"
		                },
		                "signatures": {
		                    "name": "signatures"
		                }
		            }
		        },
		        "OAuth2SecuritySchemeSettings": {
		            "name": "OAuth2SecuritySchemeSettings",
		            "properties": {
		                "accessTokenUri": {
		                    "name": "accessTokenUri"
		                },
		                "authorizationUri": {
		                    "name": "authorizationUri"
		                },
		                "authorizationGrants": {
		                    "name": "authorizationGrants"
		                },
		                "scopes": {
		                    "name": "scopes"
		                }
		            }
		        },
		        "PassThroughSecuritySchemeSettings": {
		            "name": "PassThroughSecuritySchemeSettings",
		            "properties": {
		                "queryParameterName": {
		                    "name": "queryParameterName"
		                },
		                "headerName": {
		                    "name": "headerName"
		                }
		            }
		        },
		        "OAuth2SecurityScheme": {
		            "name": "OAuth2SecurityScheme",
		            "properties": {
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "OAuth1SecurityScheme": {
		            "name": "OAuth1SecurityScheme",
		            "properties": {
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "BasicSecurityScheme": {
		            "name": "BasicSecurityScheme",
		            "properties": {}
		        },
		        "DigestSecurityScheme": {
		            "name": "DigestSecurityScheme",
		            "properties": {}
		        },
		        "CustomSecurityScheme": {
		            "name": "CustomSecurityScheme",
		            "properties": {}
		        },
		        "Parameter": {
		            "name": "Parameter",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "location": {
		                    "name": "location"
		                },
		                "required": {
		                    "name": "required"
		                },
		                "default": {
		                    "name": "default"
		                },
		                "example": {
		                    "name": "example"
		                },
		                "repeat": {
		                    "name": "repeat"
		                }
		            }
		        },
		        "StringTypeDeclaration": {
		            "name": "StringTypeDeclaration",
		            "properties": {
		                "pattern": {
		                    "name": "pattern"
		                },
		                "enum": {
		                    "name": "enum"
		                },
		                "minLength": {
		                    "name": "minLength"
		                },
		                "maxLength": {
		                    "name": "maxLength"
		                }
		            }
		        },
		        "BooleanTypeDeclaration": {
		            "name": "BooleanTypeDeclaration",
		            "properties": {}
		        },
		        "NumberTypeDeclaration": {
		            "name": "NumberTypeDeclaration",
		            "properties": {
		                "minimum": {
		                    "name": "minimum"
		                },
		                "maximum": {
		                    "name": "maximum"
		                }
		            }
		        },
		        "IntegerTypeDeclaration": {
		            "name": "IntegerTypeDeclaration",
		            "properties": {}
		        },
		        "DateTypeDeclaration": {
		            "name": "DateTypeDeclaration",
		            "properties": {}
		        },
		        "FileTypeDeclaration": {
		            "name": "FileTypeDeclaration",
		            "properties": {}
		        },
		        "HasNormalParameters": {
		            "name": "HasNormalParameters",
		            "properties": {
		                "queryParameters": {
		                    "name": "queryParameters"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "headers": {
		                    "name": "headers"
		                }
		            }
		        },
		        "ParameterLocation": {
		            "name": "ParameterLocation",
		            "properties": {}
		        },
		        "RAMLLanguageElement": {
		            "name": "RAMLLanguageElement",
		            "properties": {
		                "description": {
		                    "name": "description"
		                }
		            }
		        },
		        "RAMLSimpleElement": {
		            "name": "RAMLSimpleElement",
		            "properties": {}
		        },
		        "MimeTypeModel": {
		            "name": "MimeTypeModel",
		            "properties": {
		                "type": {
		                    "name": "type"
		                },
		                "tree": {
		                    "name": "tree"
		                },
		                "subtype": {
		                    "name": "subtype"
		                },
		                "suffix": {
		                    "name": "suffix"
		                },
		                "parameters": {
		                    "name": "parameters"
		                }
		            }
		        },
		        "MimeType": {
		            "name": "MimeType",
		            "properties": {}
		        },
		        "BodyLike": {
		            "name": "BodyLike",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "schema": {
		                    "name": "schema"
		                },
		                "example": {
		                    "name": "example"
		                },
		                "formParameters": {
		                    "name": "formParameters"
		                }
		            }
		        },
		        "XMLBody": {
		            "name": "XMLBody",
		            "properties": {
		                "schema": {
		                    "name": "schema"
		                }
		            }
		        },
		        "JSONBody": {
		            "name": "JSONBody",
		            "properties": {
		                "schema": {
		                    "name": "schema"
		                }
		            }
		        },
		        "Response": {
		            "name": "Response",
		            "properties": {
		                "code": {
		                    "name": "code"
		                },
		                "headers": {
		                    "name": "headers"
		                },
		                "body": {
		                    "name": "body"
		                }
		            }
		        }
		    },
		    "Universe10": {
		        "GlobalSchema": {
		            "name": "GlobalSchema",
		            "properties": {
		                "key": {
		                    "name": "key"
		                },
		                "value": {
		                    "name": "value"
		                }
		            }
		        },
		        "ImportDeclaration": {
		            "name": "ImportDeclaration",
		            "properties": {
		                "key": {
		                    "name": "key"
		                },
		                "value": {
		                    "name": "value"
		                }
		            }
		        },
		        "Library": {
		            "name": "Library",
		            "properties": {
		                "usage": {
		                    "name": "usage"
		                }
		            }
		        },
		        "LibraryBase": {
		            "name": "LibraryBase",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "schemas": {
		                    "name": "schemas"
		                },
		                "types": {
		                    "name": "types"
		                },
		                "traits": {
		                    "name": "traits"
		                },
		                "resourceTypes": {
		                    "name": "resourceTypes"
		                },
		                "annotationTypes": {
		                    "name": "annotationTypes"
		                },
		                "securitySchemes": {
		                    "name": "securitySchemes"
		                },
		                "uses": {
		                    "name": "uses"
		                }
		            }
		        },
		        "Overlay": {
		            "name": "Overlay",
		            "properties": {
		                "usage": {
		                    "name": "usage"
		                },
		                "masterRef": {
		                    "name": "masterRef"
		                },
		                "title": {
		                    "name": "title"
		                }
		            }
		        },
		        "Extension": {
		            "name": "Extension",
		            "properties": {
		                "usage": {
		                    "name": "usage"
		                },
		                "masterRef": {
		                    "name": "masterRef"
		                },
		                "title": {
		                    "name": "title"
		                }
		            }
		        },
		        "Api": {
		            "name": "Api",
		            "properties": {
		                "title": {
		                    "name": "title"
		                },
		                "version": {
		                    "name": "version"
		                },
		                "baseUri": {
		                    "name": "baseUri"
		                },
		                "baseUriParameters": {
		                    "name": "baseUriParameters"
		                },
		                "protocols": {
		                    "name": "protocols"
		                },
		                "mediaType": {
		                    "name": "mediaType"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "resources": {
		                    "name": "resources"
		                },
		                "documentation": {
		                    "name": "documentation"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "name": {
		                    "name": "name"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "DocumentationItem": {
		            "name": "DocumentationItem",
		            "properties": {
		                "title": {
		                    "name": "title"
		                },
		                "content": {
		                    "name": "content"
		                }
		            }
		        },
		        "ScriptSpec": {
		            "name": "ScriptSpec",
		            "properties": {
		                "language": {
		                    "name": "language"
		                },
		                "content": {
		                    "name": "content"
		                }
		            }
		        },
		        "ApiDescription": {
		            "name": "ApiDescription",
		            "properties": {
		                "apiFiles": {
		                    "name": "apiFiles"
		                },
		                "script": {
		                    "name": "script"
		                },
		                "type": {
		                    "name": "type"
		                }
		            }
		        },
		        "CallbackAPIDescription": {
		            "name": "CallbackAPIDescription",
		            "properties": {
		                "callbackFor": {
		                    "name": "callbackFor"
		                }
		            }
		        },
		        "RAMLProject": {
		            "name": "RAMLProject",
		            "properties": {
		                "relatedProjects": {
		                    "name": "relatedProjects"
		                },
		                "declaredApis": {
		                    "name": "declaredApis"
		                },
		                "license": {
		                    "name": "license"
		                },
		                "overview": {
		                    "name": "overview"
		                },
		                "url": {
		                    "name": "url"
		                }
		            }
		        },
		        "ValueType": {
		            "name": "ValueType",
		            "properties": {}
		        },
		        "StringType": {
		            "name": "StringType",
		            "properties": {}
		        },
		        "NumberType": {
		            "name": "NumberType",
		            "properties": {}
		        },
		        "BooleanType": {
		            "name": "BooleanType",
		            "properties": {}
		        },
		        "Referencable": {
		            "name": "Referencable",
		            "properties": {}
		        },
		        "Reference": {
		            "name": "Reference",
		            "properties": {}
		        },
		        "DeclaresDynamicType": {
		            "name": "DeclaresDynamicType",
		            "properties": {}
		        },
		        "UriTemplate": {
		            "name": "UriTemplate",
		            "properties": {}
		        },
		        "StatusCodeString": {
		            "name": "StatusCodeString",
		            "properties": {}
		        },
		        "RelativeUriString": {
		            "name": "RelativeUriString",
		            "properties": {}
		        },
		        "FullUriTemplateString": {
		            "name": "FullUriTemplateString",
		            "properties": {}
		        },
		        "FixedUriString": {
		            "name": "FixedUriString",
		            "properties": {}
		        },
		        "ContentType": {
		            "name": "ContentType",
		            "properties": {}
		        },
		        "ValidityExpression": {
		            "name": "ValidityExpression",
		            "properties": {}
		        },
		        "MarkdownString": {
		            "name": "MarkdownString",
		            "properties": {}
		        },
		        "DateFormatSpec": {
		            "name": "DateFormatSpec",
		            "properties": {}
		        },
		        "FunctionalInterface": {
		            "name": "FunctionalInterface",
		            "properties": {}
		        },
		        "SchemaString": {
		            "name": "SchemaString",
		            "properties": {}
		        },
		        "ExampleString": {
		            "name": "ExampleString",
		            "properties": {}
		        },
		        "JSonSchemaString": {
		            "name": "JSonSchemaString",
		            "properties": {}
		        },
		        "XMLSchemaString": {
		            "name": "XMLSchemaString",
		            "properties": {}
		        },
		        "RAMLPointer": {
		            "name": "RAMLPointer",
		            "properties": {}
		        },
		        "RAMLSelector": {
		            "name": "RAMLSelector",
		            "properties": {}
		        },
		        "ResourceTypeRef": {
		            "name": "ResourceTypeRef",
		            "properties": {}
		        },
		        "TraitRef": {
		            "name": "TraitRef",
		            "properties": {}
		        },
		        "SecuritySchemePart": {
		            "name": "SecuritySchemePart",
		            "properties": {
		                "headers": {
		                    "name": "headers"
		                },
		                "queryParameters": {
		                    "name": "queryParameters"
		                },
		                "queryString": {
		                    "name": "queryString"
		                },
		                "responses": {
		                    "name": "responses"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "SecuritySchemeSettings": {
		            "name": "SecuritySchemeSettings",
		            "properties": {}
		        },
		        "OAuth1SecuritySchemeSettings": {
		            "name": "OAuth1SecuritySchemeSettings",
		            "properties": {
		                "requestTokenUri": {
		                    "name": "requestTokenUri"
		                },
		                "authorizationUri": {
		                    "name": "authorizationUri"
		                },
		                "tokenCredentialsUri": {
		                    "name": "tokenCredentialsUri"
		                },
		                "signatures": {
		                    "name": "signatures"
		                }
		            }
		        },
		        "OAuth2SecuritySchemeSettings": {
		            "name": "OAuth2SecuritySchemeSettings",
		            "properties": {
		                "accessTokenUri": {
		                    "name": "accessTokenUri"
		                },
		                "authorizationUri": {
		                    "name": "authorizationUri"
		                },
		                "authorizationGrants": {
		                    "name": "authorizationGrants"
		                },
		                "scopes": {
		                    "name": "scopes"
		                }
		            }
		        },
		        "PassThroughSecuritySchemeSettings": {
		            "name": "PassThroughSecuritySchemeSettings",
		            "properties": {
		                "queryParameterName": {
		                    "name": "queryParameterName"
		                },
		                "headerName": {
		                    "name": "headerName"
		                }
		            }
		        },
		        "SecuritySchemeRef": {
		            "name": "SecuritySchemeRef",
		            "properties": {}
		        },
		        "AbstractSecurityScheme": {
		            "name": "AbstractSecurityScheme",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "describedBy": {
		                    "name": "describedBy"
		                },
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "OAuth2SecurityScheme": {
		            "name": "OAuth2SecurityScheme",
		            "properties": {
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "OAuth1SecurityScheme": {
		            "name": "OAuth1SecurityScheme",
		            "properties": {
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "PassThroughSecurityScheme": {
		            "name": "PassThroughSecurityScheme",
		            "properties": {
		                "settings": {
		                    "name": "settings"
		                }
		            }
		        },
		        "BasicSecurityScheme": {
		            "name": "BasicSecurityScheme",
		            "properties": {}
		        },
		        "DigestSecurityScheme": {
		            "name": "DigestSecurityScheme",
		            "properties": {}
		        },
		        "CustomSecurityScheme": {
		            "name": "CustomSecurityScheme",
		            "properties": {}
		        },
		        "MethodBase": {
		            "name": "MethodBase",
		            "properties": {
		                "responses": {
		                    "name": "responses"
		                },
		                "body": {
		                    "name": "body"
		                },
		                "protocols": {
		                    "name": "protocols"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                }
		            }
		        },
		        "Trait": {
		            "name": "Trait",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "usage": {
		                    "name": "usage"
		                },
		                "uses": {
		                    "name": "uses"
		                }
		            }
		        },
		        "ResourceBase": {
		            "name": "ResourceBase",
		            "properties": {
		                "methods": {
		                    "name": "methods"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                },
		                "uriParameters": {
		                    "name": "uriParameters"
		                }
		            }
		        },
		        "ResourceType": {
		            "name": "ResourceType",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "usage": {
		                    "name": "usage"
		                },
		                "uses": {
		                    "name": "uses"
		                }
		            }
		        },
		        "ResourceTypeOrTrait": {
		            "name": "ResourceTypeOrTrait",
		            "properties": {
		                "usage": {
		                    "name": "usage"
		                },
		                "uses": {
		                    "name": "uses"
		                },
		                "parameters": {
		                    "name": "parameters"
		                }
		            }
		        },
		        "Method": {
		            "name": "Method",
		            "properties": {
		                "method": {
		                    "name": "method"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "queryString": {
		                    "name": "queryString"
		                },
		                "queryParameters": {
		                    "name": "queryParameters"
		                },
		                "headers": {
		                    "name": "headers"
		                },
		                "body": {
		                    "name": "body"
		                },
		                "is": {
		                    "name": "is"
		                },
		                "annotations": {
		                    "name": "annotations"
		                },
		                "securedBy": {
		                    "name": "securedBy"
		                }
		            }
		        },
		        "Resource": {
		            "name": "Resource",
		            "properties": {
		                "relativeUri": {
		                    "name": "relativeUri"
		                },
		                "resources": {
		                    "name": "resources"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "FileTypeDeclaration": {
		            "name": "FileTypeDeclaration",
		            "properties": {
		                "fileTypes": {
		                    "name": "fileTypes"
		                },
		                "minLength": {
		                    "name": "minLength"
		                },
		                "maxLength": {
		                    "name": "maxLength"
		                }
		            }
		        },
		        "HasNormalParameters": {
		            "name": "HasNormalParameters",
		            "properties": {
		                "queryParameters": {
		                    "name": "queryParameters"
		                },
		                "headers": {
		                    "name": "headers"
		                },
		                "queryString": {
		                    "name": "queryString"
		                }
		            }
		        },
		        "RAMLLanguageElement": {
		            "name": "RAMLLanguageElement",
		            "properties": {
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "RAMLSimpleElement": {
		            "name": "RAMLSimpleElement",
		            "properties": {}
		        },
		        "AnnotationTypeDeclaration": {
		            "name": "AnnotationTypeDeclaration",
		            "properties": {
		                "allowMultiple": {
		                    "name": "allowMultiple"
		                },
		                "allowedTargets": {
		                    "name": "allowedTargets"
		                }
		            }
		        },
		        "AnnotationRef": {
		            "name": "AnnotationRef",
		            "properties": {}
		        },
		        "AnnotationTarget": {
		            "name": "AnnotationTarget",
		            "properties": {}
		        },
		        "Annotation": {
		            "name": "Annotation",
		            "properties": {
		                "name": {
		                    "name": "name"
		                }
		            }
		        },
		        "ExampleSpec": {
		            "name": "ExampleSpec",
		            "properties": {
		                "content": {
		                    "name": "content"
		                },
		                "strict": {
		                    "name": "strict"
		                },
		                "name": {
		                    "name": "name"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "DataElementProperty": {
		            "name": "DataElementProperty",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "location": {
		                    "name": "location"
		                },
		                "locationKind": {
		                    "name": "locationKind"
		                },
		                "default": {
		                    "name": "default"
		                },
		                "required": {
		                    "name": "required"
		                }
		            }
		        },
		        "TypeDeclaration": {
		            "name": "TypeDeclaration",
		            "properties": {
		                "name": {
		                    "name": "name"
		                },
		                "facets": {
		                    "name": "facets"
		                },
		                "schema": {
		                    "name": "schema"
		                },
		                "usage": {
		                    "name": "usage"
		                },
		                "type": {
		                    "name": "type"
		                },
		                "location": {
		                    "name": "location"
		                },
		                "locationKind": {
		                    "name": "locationKind"
		                },
		                "default": {
		                    "name": "default"
		                },
		                "example": {
		                    "name": "example"
		                },
		                "examples": {
		                    "name": "examples"
		                },
		                "repeat": {
		                    "name": "repeat"
		                },
		                "required": {
		                    "name": "required"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "ScalarElement": {
		            "name": "ScalarElement",
		            "properties": {
		                "facets": {
		                    "name": "facets"
		                },
		                "enum": {
		                    "name": "enum"
		                }
		            }
		        },
		        "ArrayTypeDeclaration": {
		            "name": "ArrayTypeDeclaration",
		            "properties": {
		                "uniqueItems": {
		                    "name": "uniqueItems"
		                },
		                "items": {
		                    "name": "items"
		                },
		                "minItems": {
		                    "name": "minItems"
		                },
		                "maxItems": {
		                    "name": "maxItems"
		                }
		            }
		        },
		        "UnionTypeDeclaration": {
		            "name": "UnionTypeDeclaration",
		            "properties": {
		                "discriminator": {
		                    "name": "discriminator"
		                }
		            }
		        },
		        "DataElementRef": {
		            "name": "DataElementRef",
		            "properties": {}
		        },
		        "ObjectTypeDeclaration": {
		            "name": "ObjectTypeDeclaration",
		            "properties": {
		                "properties": {
		                    "name": "properties"
		                },
		                "minProperties": {
		                    "name": "minProperties"
		                },
		                "maxProperties": {
		                    "name": "maxProperties"
		                },
		                "additionalProperties": {
		                    "name": "additionalProperties"
		                },
		                "patternProperties": {
		                    "name": "patternProperties"
		                },
		                "discriminator": {
		                    "name": "discriminator"
		                },
		                "discriminatorValue": {
		                    "name": "discriminatorValue"
		                }
		            }
		        },
		        "StringTypeDeclaration": {
		            "name": "StringTypeDeclaration",
		            "properties": {
		                "pattern": {
		                    "name": "pattern"
		                },
		                "minLength": {
		                    "name": "minLength"
		                },
		                "maxLength": {
		                    "name": "maxLength"
		                },
		                "enum": {
		                    "name": "enum"
		                }
		            }
		        },
		        "BooleanTypeDeclaration": {
		            "name": "BooleanTypeDeclaration",
		            "properties": {}
		        },
		        "ValueTypeDeclaration": {
		            "name": "ValueTypeDeclaration",
		            "properties": {}
		        },
		        "NumberTypeDeclaration": {
		            "name": "NumberTypeDeclaration",
		            "properties": {
		                "minimum": {
		                    "name": "minimum"
		                },
		                "maximum": {
		                    "name": "maximum"
		                },
		                "enum": {
		                    "name": "enum"
		                },
		                "format": {
		                    "name": "format"
		                },
		                "multipleOf": {
		                    "name": "multipleOf"
		                }
		            }
		        },
		        "IntegerTypeDeclaration": {
		            "name": "IntegerTypeDeclaration",
		            "properties": {
		                "format": {
		                    "name": "format"
		                }
		            }
		        },
		        "RAMLPointerElement": {
		            "name": "RAMLPointerElement",
		            "properties": {
		                "target": {
		                    "name": "target"
		                }
		            }
		        },
		        "pointer": {
		            "name": "pointer",
		            "properties": {}
		        },
		        "RAMLExpression": {
		            "name": "RAMLExpression",
		            "properties": {}
		        },
		        "ScriptHookElement": {
		            "name": "ScriptHookElement",
		            "properties": {
		                "declaredIn": {
		                    "name": "declaredIn"
		                },
		                "interfaceName": {
		                    "name": "interfaceName"
		                }
		            }
		        },
		        "SchemaElement": {
		            "name": "SchemaElement",
		            "properties": {}
		        },
		        "DateTypeDeclaration": {
		            "name": "DateTypeDeclaration",
		            "properties": {
		                "dateFormat": {
		                    "name": "dateFormat"
		                }
		            }
		        },
		        "ModelLocation": {
		            "name": "ModelLocation",
		            "properties": {}
		        },
		        "LocationKind": {
		            "name": "LocationKind",
		            "properties": {}
		        },
		        "MimeTypeModel": {
		            "name": "MimeTypeModel",
		            "properties": {
		                "type": {
		                    "name": "type"
		                },
		                "tree": {
		                    "name": "tree"
		                },
		                "subtype": {
		                    "name": "subtype"
		                },
		                "suffix": {
		                    "name": "suffix"
		                },
		                "parameters": {
		                    "name": "parameters"
		                }
		            }
		        },
		        "MimeType": {
		            "name": "MimeType",
		            "properties": {}
		        },
		        "Response": {
		            "name": "Response",
		            "properties": {
		                "code": {
		                    "name": "code"
		                },
		                "headers": {
		                    "name": "headers"
		                },
		                "body": {
		                    "name": "body"
		                },
		                "displayName": {
		                    "name": "displayName"
		                },
		                "description": {
		                    "name": "description"
		                },
		                "annotations": {
		                    "name": "annotations"
		                }
		            }
		        },
		        "Status": {
		            "name": "Status",
		            "properties": {
		                "code": {
		                    "name": "code"
		                },
		                "message": {
		                    "name": "message"
		                }
		            }
		        },
		        "AuthentificationState": {
		            "name": "AuthentificationState",
		            "properties": {}
		        },
		        "AuthentificationParameters": {
		            "name": "AuthentificationParameters",
		            "properties": {}
		        },
		        "AuthData": {
		            "name": "AuthData",
		            "properties": {
		                "authentificationParameters": {
		                    "name": "authentificationParameters"
		                }
		            }
		        },
		        "ParameterSpec": {
		            "name": "ParameterSpec",
		            "properties": {}
		        },
		        "PromptSpec": {
		            "name": "PromptSpec",
		            "properties": {}
		        },
		        "UserResponse": {
		            "name": "UserResponse",
		            "properties": {}
		        },
		        "QueryListener": {
		            "name": "QueryListener",
		            "properties": {}
		        },
		        "EndPoint": {
		            "name": "EndPoint",
		            "properties": {}
		        },
		        "EndPointSpec": {
		            "name": "EndPointSpec",
		            "properties": {
		                "url": {
		                    "name": "url"
		                },
		                "needToSendResponse": {
		                    "name": "needToSendResponse"
		                }
		            }
		        },
		        "SecurityEnvironment": {
		            "name": "SecurityEnvironment",
		            "properties": {}
		        },
		        "AuthentificationManager": {
		            "name": "AuthentificationManager",
		            "properties": {}
		        },
		        "SchemeInfo": {
		            "name": "SchemeInfo",
		            "properties": {
		                "parameterSpec": {
		                    "name": "parameterSpec"
		                }
		            }
		        },
		        "SecurityScheme": {
		            "name": "SecurityScheme",
		            "properties": {}
		        },
		        "SecurityAwareApiClient": {
		            "name": "SecurityAwareApiClient",
		            "properties": {}
		        },
		        "SecuritySchemeHook": {
		            "name": "SecuritySchemeHook",
		            "properties": {}
		        },
		        "StatusCode": {
		            "name": "StatusCode",
		            "properties": {}
		        }
		    }
		};
		module.exports = Universes;


	/***/ },
	/* 55 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var jsyaml = __webpack_require__(15);
		var defs = __webpack_require__(3);
		var hl = __webpack_require__(2);
		var _ = __webpack_require__(4);
		var yaml = __webpack_require__(7);
		var typeExpression = __webpack_require__(51);
		var def = __webpack_require__(3);
		var hlimpl = __webpack_require__(5);
		var su = __webpack_require__(56);
		var path = __webpack_require__(16);
		var fs = __webpack_require__(17);
		var universes = __webpack_require__(54);
		var universeHelpers = __webpack_require__(62);
		var services = __webpack_require__(49);
		var typeSystem = __webpack_require__(63);
		var typeBuilder = __webpack_require__(50);
		var OverloadingValidator = __webpack_require__(64);
		var OverloadingValidator08 = __webpack_require__(111);
		var expander = __webpack_require__(73);
		var util = __webpack_require__(48);
		var mediaTypeParser = __webpack_require__(88);
		var xmlutil = __webpack_require__(57);
		var LinterSettings = (function () {
		    function LinterSettings() {
		        this.validateNotStrictExamples = true;
		    }
		    return LinterSettings;
		})();
		var settings = new LinterSettings();
		var loophole = __webpack_require__(112);
		function evalInSandbox(code, thisArg, args) {
		    return new loophole.Function(code).call(thisArg, args);
		}
		var MAX_RECURSION_LEVEL = 400;
		var lintWithFile = function (customLinter, acceptor, astNode) {
		    if (fs.existsSync(customLinter)) {
		        try {
		            var content = fs.readFileSync(customLinter).toString();
		            var factr = new LinterExtensionsImpl(acceptor);
		            evalInSandbox(content, factr, null);
		            factr.visit(astNode);
		        }
		        catch (e) {
		            console.log("Error in custom linter");
		            console.log(e);
		        }
		    }
		};
		function checkPropertyQuard(n, v) {
		    var pr = n.property();
		    if (pr) {
		        pr.getContextRequirements().forEach(function (x) {
		            if (!n.checkContextValue(x.name, x.value, x.value)) {
		                v.accept(createIssue(8 /* MISSED_CONTEXT_REQUIREMENT */, x.name + " should be " + x.value + " to use property " + pr.nameId(), n));
		            }
		        });
		    }
		    return pr;
		}
		;
		function lintNode(astNode, acceptor) {
		    if (typeof fs === "undefined") {
		        return;
		    }
		    if (!fs) {
		        return;
		    }
		    var fsMethods = ['exists', 'readFile', 'writeFile', 'readdir', 'existsSync', 'readFileSync', 'writeFileSync', 'readdirSync'];
		    var existingFsFields = Object.keys(fs);
		    for (var i = 0; i < fsMethods.length; i++) {
		        if (!fs[fsMethods[i]]) {
		            return;
		        }
		    }
		    var ps = astNode.lowLevel().unit().absolutePath();
		    var dr = path.dirname(ps);
		    var customLinter = path.resolve(dr, "raml-lint.js");
		    lintWithFile(customLinter, acceptor, astNode);
		    var dir = path.resolve(dr, ".raml");
		    if (fs.existsSync(dir)) {
		        var st = fs.statSync(dir);
		        if (st.isDirectory()) {
		            var files = fs.readdirSync(dir);
		            files.forEach(function (x) {
		                if (x.indexOf("-lint.js") != -1) {
		                    lintWithFile(path.resolve(dir, x), acceptor, astNode);
		                }
		                //console.log(x);
		            });
		        }
		    }
		}
		;
		var LinterExtensionsImpl = (function () {
		    function LinterExtensionsImpl(acceptor) {
		        this.acceptor = acceptor;
		        this.nodes = {};
		    }
		    LinterExtensionsImpl.prototype.error = function (w, message) {
		        this.acceptor.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, message, w.highLevel()));
		    };
		    LinterExtensionsImpl.prototype.errorOnProperty = function (w, property, message) {
		        var pr = w.highLevel().attr(property);
		        this.acceptor.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, message, pr));
		    };
		    LinterExtensionsImpl.prototype.warningOnProperty = function (w, property, message) {
		        var pr = w.highLevel().attr(property);
		        this.acceptor.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, message, pr, true));
		    };
		    LinterExtensionsImpl.prototype.warning = function (w, message) {
		        this.acceptor.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, message, w.highLevel(), true));
		    };
		    LinterExtensionsImpl.prototype.registerRule = function (nodeType, rule) {
		        var q = this.nodes[nodeType];
		        if (!q) {
		            q = [];
		            this.nodes[nodeType] = q;
		        }
		        q.push(rule);
		    };
		    LinterExtensionsImpl.prototype.visit = function (h) {
		        var _this = this;
		        var nd = h.definition();
		        this.process(nd, h);
		        nd.allSuperTypes().forEach(function (x) { return _this.process(x, h); });
		        h.elements().forEach(function (y) { return _this.visit(y); });
		    };
		    LinterExtensionsImpl.prototype.process = function (d, h) {
		        var _this = this;
		        if (d instanceof def.NodeClass) {
		            if (!d.getAdapter(services.RAMLService).getDeclaringNode()) {
		                var rules = this.nodes[d.nameId()];
		                if (rules) {
		                    rules.forEach(function (x) { return x(h.wrapperNode(), _this); });
		                }
		            }
		        }
		    };
		    return LinterExtensionsImpl;
		})();
		var StackNode = (function () {
		    function StackNode() {
		    }
		    StackNode.prototype.toString = function () {
		        if (this.prev) {
		            return this.value + "." + this.prev.toString();
		        }
		        return this.value;
		    };
		    StackNode.prototype.last = function () {
		        if (this.prev) {
		            return this.prev.last();
		        }
		        return this;
		    };
		    return StackNode;
		})();
		var TypeValidator = (function () {
		    function TypeValidator(node) {
		        this.node = node;
		    }
		    TypeValidator.prototype.validate = function (obj, t, cb, strict, recursionLevel) {
		        if (recursionLevel === void 0) { recursionLevel = 0; }
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        if (t.hasExternalInHierarchy()) {
		            var so = null;
		            var strVal = t.externalInHierarchy().schema();
		            if (strVal.charAt(0) == "{") {
		                try {
		                    so = su.getJSONSchema(strVal);
		                }
		                catch (e) {
		                    return null;
		                }
		            }
		            if (strVal.charAt(0) == "<") {
		                try {
		                    so = su.getXMLSchema(strVal);
		                }
		                catch (e) {
		                    return null;
		                }
		            }
		            if (so) {
		                try {
		                    so.validateObject(obj);
		                }
		                catch (e) {
		                    if (e.message == "Cannot assign to read only property '__$validated' of object") {
		                        return;
		                    }
		                    if (e.message == "Object.keys called on non-object") {
		                        return;
		                    }
		                    cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "Example does not conforms to schema:" + e.message, this.node, !strict));
		                    return;
		                }
		            }
		            return;
		        }
		        if (t.hasArrayInHierarchy()) {
		            this.validateArray(obj, t.arrayInHierarchy(), cb, strict, recursionLevel);
		        }
		        else if (t.hasUnionInHierarchy()) {
		            this.validateUnion(obj, t.unionInHierarchy(), cb, strict, recursionLevel);
		        }
		        else if (t.hasStructure()) {
		            this.validateClass(obj, t, cb, strict, recursionLevel);
		        }
		        else if (t.hasValueTypeInHierarchy()) {
		            this.validateValue(obj, t, cb, strict, recursionLevel);
		        }
		        else {
		            throw new Error("Not supported case");
		        }
		    };
		    TypeValidator.prototype.createIssue = function (c, message, node, w) {
		        if (w === void 0) { w = false; }
		        var result = createIssue(c, message, node, w);
		        if (this.stack) {
		            var ll = this.findNode(this.stack.last(), this.node.lowLevel());
		            if (ll && ll != node.lowLevel()) {
		                if (ll.unit() == node.root().lowLevel().unit()) {
		                    if (ll.keyStart() > 0 && ll.keyEnd() > 0) {
		                        result.start = ll.keyStart();
		                        result.end = ll.keyEnd();
		                    }
		                }
		            }
		        }
		        return result;
		    };
		    TypeValidator.prototype.findNode = function (c, q) {
		        var key = "" + c.value;
		        if (typeof c.value == 'number') {
		            var m = q.children();
		            if (m[c.value]) {
		                var node = m[c.value];
		                if (c.next) {
		                    return this.findNode(c.next, node);
		                }
		            }
		            return q;
		        }
		        var node = _.find(q.children(), function (x) { return x.key() == key; });
		        if (node) {
		            if (c.next) {
		                return this.findNode(c.next, node);
		            }
		            return node;
		        }
		        else {
		            return q;
		        }
		    };
		    TypeValidator.prototype.validateClass = function (obj, t, cb, strict, recursionLevel) {
		        var _this = this;
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        var supers = t.allSuperTypes();
		        supers.push(t);
		        this.validateFacets(t.getAdapter(services.RAMLService).isRuntime() ? t : t.getAdapter(services.RAMLService).toRuntime(), obj, cb, strict, recursionLevel);
		        supers.forEach(function (s) {
		            if (s.key() == universes.Universe10.StringTypeDeclaration || s.key() == universes.Universe08.StringTypeDeclaration) {
		                if (typeof obj != 'string' && typeof obj != 'number' && typeof obj != 'boolean') {
		                    cb.accept(_this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "String is expected", _this.node, !strict));
		                }
		            }
		            if (s.key() == universes.Universe10.NumberTypeDeclaration || s.key() == universes.Universe08.NumberTypeDeclaration) {
		                if (typeof obj != 'number') {
		                    cb.accept(_this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "Number is expected", _this.node, !strict));
		                }
		            }
		            if (s.key() == universes.Universe10.BooleanTypeDeclaration || s.key() == universes.Universe08.BooleanTypeDeclaration) {
		                var isOk = obj == true || obj == false;
		                if (!isOk) {
		                    cb.accept(_this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "boolean is expected", _this.node, !strict));
		                }
		            }
		            if (s instanceof def.Array) {
		                _this.validate(obj, s, cb, strict, recursionLevel + 1);
		            }
		            if (s instanceof def.Union) {
		                _this.validate(obj, s, cb, strict, recursionLevel + 1);
		            }
		        });
		        var props = t.getAdapter(services.RAMLService).isRuntime() ? t.allProperties() : t.getAdapter(services.RAMLService).toRuntime().allProperties();
		        if (!obj) {
		            obj = {};
		        }
		        var handled = {};
		        props.forEach(function (p) {
		            if (!p.getAdapter(services.RAMLPropertyService).isMerged()) {
		                var value = obj[p.nameId()];
		                handled[p.nameId()] = 1;
		                if (value == null) {
		                    if (p.isRequired()) {
		                        cb.accept(_this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "Required property:" + p.nameId() + " is missed", _this.node, !strict));
		                    }
		                }
		                else {
		                    _this.validatePropValue(value, p, cb, strict, p.nameId(), recursionLevel + 1);
		                }
		            }
		        });
		        props.forEach(function (p) {
		            if (p.getAdapter(services.RAMLPropertyService).isMerged()) {
		                if (p.getKeyRegexp() != null) {
		                    Object.keys(obj).forEach(function (x) {
		                        if (!handled[x]) {
		                            try {
		                                var re = new RegExp(p.getKeyRegexp());
		                                if (re.test(x)) {
		                                    var n = _this.node;
		                                    _this.validatePropValue(obj[x], p, cb, strict, x, recursionLevel + 1);
		                                    handled[x] = 1;
		                                }
		                            }
		                            catch (e) {
		                            }
		                        }
		                    });
		                }
		            }
		        });
		        props.forEach(function (p) {
		            if (p.getAdapter(services.RAMLPropertyService).isMerged()) {
		                if (p.keyPrefix() != null) {
		                    Object.keys(obj).forEach(function (x) {
		                        if (!handled[x]) {
		                            _this.validatePropValue(obj[x], p, cb, strict, x, recursionLevel + 1);
		                            handled[x] = 1;
		                        }
		                    });
		                }
		            }
		        });
		        if (typeof obj == 'object' && props.length > 0) {
		            Object.keys(obj).forEach(function (x) {
		                if (!handled[x]) {
		                    try {
		                        _this.pushStack(x);
		                        cb.accept(_this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "Unknown property:" + x, _this.node, !strict));
		                    }
		                    finally {
		                        if (_this.stack) {
		                            _this.stack = _this.stack.prev;
		                        }
		                    }
		                }
		            });
		        }
		    };
		    TypeValidator.prototype.validateFacets = function (t, obj, cb, strict, recursionLevel) {
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        var rof = t.getAdapter(services.RAMLService).getRepresentationOf();
		        var fixedFacets = t.getFixedFacets();
		        if (rof) {
		            t = rof;
		            if (t instanceof def.UserDefinedClass) {
		                fixedFacets = t.getFixedFacets();
		            }
		        }
		        for (var facetKey in fixedFacets) {
		            var facet = t.facet(facetKey);
		            if (facet) {
		                var facetValue = fixedFacets[facetKey];
		                var facetValidator = facet.getFacetValidator();
		                if (facetValidator) {
		                    try {
		                        var result = facetValidator(obj, facetValue);
		                        if (typeof result == "string") {
		                            cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "" + result, this.node, !strict));
		                        }
		                    }
		                    catch (e) {
		                        cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, e.message, this.node, !strict));
		                    }
		                }
		            }
		        }
		    };
		    TypeValidator.prototype.validatePropValue = function (value, p, cb, strict, key, recursionLevel) {
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        this.pushStack(key);
		        try {
		            this.validate(value, p.range(), cb, strict, recursionLevel);
		            var enumValues = p.getAdapter(services.RAMLPropertyService).enumValues(null);
		            if (enumValues) {
		                if (typeof enumValues == 'string') {
		                    if (enumValues != value) {
		                        cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "" + p.nameId() + " should be one of " + enumValues, this.node, !strict));
		                    }
		                }
		                else if (enumValues.length > 0) {
		                    if (!_.find(enumValues, function (x) { return x == value; })) {
		                        cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "" + p.nameId() + " should be one of " + enumValues, this.node, !strict));
		                    }
		                }
		            }
		        }
		        finally {
		            if (this.stack) {
		                this.stack = this.stack.prev;
		            }
		        }
		    };
		    TypeValidator.prototype.pushStack = function (key) {
		        if (!this.stack) {
		            this.stack = new StackNode();
		            this.stack.value = key;
		        }
		        else {
		            var pn = new StackNode();
		            pn.prev = this.stack;
		            this.stack.next = pn;
		            this.stack = pn;
		            this.stack.value = key;
		        }
		    };
		    TypeValidator.prototype.validateArray = function (obj, t, cb, strict, recursionLevel) {
		        var _this = this;
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        if (!(obj instanceof Array)) {
		            obj = [obj];
		        }
		        if (obj instanceof Array) {
		            var arr = obj;
		            this.validateFacets(t, obj, cb, strict, recursionLevel);
		            var num = 0;
		            arr.forEach(function (x) {
		                try {
		                    _this.pushStack(num++);
		                    _this.validate(x, t.component, cb, strict, recursionLevel + 1);
		                }
		                finally {
		                    if (_this.stack) {
		                        _this.stack = _this.stack.prev;
		                    }
		                }
		            });
		        }
		    };
		    TypeValidator.prototype.validateUnion = function (obj, t, cb, strict, recursionLevel) {
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        //FIXME
		    };
		    TypeValidator.prototype.validateValue = function (obj, t, cb, strict, recursionLevel) {
		        if (recursionLevel >= MAX_RECURSION_LEVEL) {
		            return;
		        }
		        //FIXME
		        if (t.key() == universes.Universe08.NumberType || t.key() == universes.Universe10.NumberType) {
		            if (typeof obj != 'number') {
		                var qqq = parseFloat(obj);
		                if (!qqq) {
		                    if (isNaN(qqq)) {
		                        cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "Number is expected", this.node, !strict));
		                    }
		                }
		            }
		        }
		        if (t.key() == universes.Universe08.BooleanType || t.key() == universes.Universe10.BooleanType) {
		            if (typeof obj != 'boolean') {
		                if (obj != 'true' && obj != 'false') {
		                    cb.accept(this.createIssue(7 /* INVALID_VALUE_SCHEMA */, "boolean is expected", this.node, !strict));
		                }
		            }
		        }
		    };
		    return TypeValidator;
		})();
		exports.TypeValidator = TypeValidator;
		function isTypeOrSchema(d) {
		    return d.nameId() == universes.Universe10.TypeDeclaration.properties.type.name || d.nameId() == universes.Universe10.TypeDeclaration.properties.schema.name;
		}
		function isExampleProp(d) {
		    if (!d.domain()) {
		        return;
		    }
		    if (d.domain().getAdapter(services.RAMLService).isUserDefined()) {
		        return false;
		    }
		    return d.nameId() == universes.Universe10.TypeDeclaration.properties.example.name || d.nameId() == universes.Universe10.ExampleSpec.properties.content.name;
		}
		function insideResourceTypeOrTrait(h) {
		    var declRoot = h;
		    while (true) {
		        if (declRoot.definition().getAdapter(services.RAMLService).isInlinedTemplates()) {
		            return true;
		        }
		        var np = declRoot.parent();
		        if (!np) {
		            break;
		        }
		        else {
		            declRoot = np;
		        }
		    }
		    return false;
		}
		function validateBasic(node, v, requiredOnly) {
		    if (requiredOnly === void 0) { requiredOnly = false; }
		    if (node.lowLevel()) {
		        if (node.lowLevel().keyKind() == 2 /* MAP */) {
		            v.accept(createIssue(2 /* UNKNOWN_NODE */, "Node key can not be map", node));
		        }
		        if (node.lowLevel().keyKind() == 3 /* SEQ */) {
		            if (node.lowLevel().value() == null) {
		                var isPattern = false;
		                if (node.isElement()) {
		                    if (node.asElement().definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		                        isPattern = true;
		                    }
		                }
		                if (!isPattern) {
		                    v.accept(createIssue(2 /* UNKNOWN_NODE */, "Node key can not be sequence", node));
		                }
		            }
		        }
		        if (node.parent() == null) {
		            node.lowLevel().errors().forEach(function (x) {
		                var em = {
		                    code: 1 /* YAML_ERROR */,
		                    message: x.message,
		                    node: null,
		                    start: x.mark.position,
		                    end: x.mark.position + 1,
		                    isWarning: false,
		                    path: node.lowLevel().unit() == node.root().lowLevel().unit() ? null : node.lowLevel().unit().path(),
		                    unit: node.lowLevel().unit()
		                };
		                v.accept(em);
		            });
		        }
		    }
		    validateIncludes(node, v);
		    if (node.errorMessage) {
		        v.accept(createIssue(2 /* UNKNOWN_NODE */, node.errorMessage, node));
		        return;
		    }
		    if (node.isUnknown()) {
		        if (node.name().indexOf("<<") != -1) {
		            if (insideResourceTypeOrTrait(node.parent())) {
		                var error = new TraitVariablesValidator().check(node.name());
		                if (error) {
		                    v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "unknown function applied to property name", node));
		                }
		                return;
		            }
		        }
		        if (node.needSequence) {
		            v.accept(createIssue(2 /* UNKNOWN_NODE */, "node: " + node.name() + " should be wrapped in sequence", node));
		        }
		        if (node.unresolvedRef) {
		            v.accept(createIssue(2 /* UNKNOWN_NODE */, "reference: " + node.lowLevel().value() + " can not be resolved", node));
		        }
		        if (node.knownProperty && node.lowLevel().value()) {
		            //if (!node.lowLevel().)
		            if (node.lowLevel().includeErrors().length == 0) {
		                v.accept(createIssue(2 /* UNKNOWN_NODE */, "property " + node.name() + " can not have scalar value", node));
		            }
		        }
		        else {
		            v.accept(createIssue(2 /* UNKNOWN_NODE */, "Unknown node: " + node.name(), node));
		        }
		    }
		    if (node.markCh() && !node.allowRecursive()) {
		        v.accept(createIssue(2 /* UNKNOWN_NODE */, "Recursive definition: " + node.name(), node));
		        return;
		    }
		    try {
		        node.directChildren().filter(function (child) {
		            return !requiredOnly || (child.property && child.property() && child.property().isRequired());
		        }).forEach(function (x) {
		            if (x.errorMessage) {
		                v.accept(createIssue(2 /* UNKNOWN_NODE */, x.errorMessage, node));
		            }
		            x.validate(v);
		        });
		    }
		    finally {
		        node.unmarkCh();
		    }
		}
		exports.validateBasic = validateBasic;
		function validate(node, v) {
		    if (!node.parent()) {
		        try {
		            validateIncludes(node, v);
		        }
		        finally {
		            cleanupIncludesFlag(node, v);
		        }
		    }
		    if (node.isAttr()) {
		        new CompositePropertyValidator().validate(node, v);
		    }
		    else if (node.isElement()) {
		        var highLevelNode = node;
		        var hasRequireds = highLevelNode.definition().requiredProperties() && highLevelNode.definition().requiredProperties().length > 0;
		        var isAllowAny = highLevelNode.definition().getAdapter(services.RAMLService).getAllowAny();
		        if (isAllowAny) {
		            if (hasRequireds) {
		                validateBasic(node, v, true);
		            }
		        }
		        else {
		            validateBasic(node, v);
		        }
		        new CompositeNodeValidator().validate(node, v);
		    }
		    else {
		        validateBasic(node, v);
		    }
		}
		exports.validate = validate;
		function cleanupIncludesFlag(node, v) {
		    var val = node.lowLevel().actual();
		    delete val._inc;
		    node.children().forEach(function (x) { return cleanupIncludesFlag(x, v); });
		}
		function validateIncludes(node, v) {
		    var val = node.lowLevel().actual();
		    if (val._inc) {
		        return;
		    }
		    val._inc = true;
		    if (node.lowLevel()) {
		        node.lowLevel().includeErrors().forEach(function (x) {
		            var em = createIssue(6 /* UNABLE_TO_RESOLVE_INCLUDE_FILE */, x, node);
		            v.accept(em);
		        });
		    }
		    node.children().forEach(function (x) { return validateIncludes(node, v); });
		}
		var validateRegexp = function (cleanedValue, v, node) {
		    try {
		        new RegExp(cleanedValue);
		    }
		    catch (Error) {
		        v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Illegal pattern " + cleanedValue, node));
		    }
		};
		var TraitVariablesValidator = (function () {
		    function TraitVariablesValidator() {
		    }
		    TraitVariablesValidator.prototype.check = function (obj) {
		        var errors = [];
		        if (typeof (obj) === 'string') {
		            var str = obj;
		            var prev = 0;
		            for (var i = str.indexOf('<<'); i >= 0; i = str.indexOf('<<', prev)) {
		                var i0 = i;
		                i += '<<'.length;
		                prev = str.indexOf('>>', i);
		                var paramOccurence = str.substring(i, prev);
		                prev += '>>'.length;
		                var originalString = str.substring(i0, prev);
		                var val;
		                var paramName;
		                var ind = paramOccurence.lastIndexOf('|');
		                paramName = paramOccurence.substring(0, ind).trim();
		                var transformerName = paramOccurence.substring(ind + 1).trim();
		                if (ind != -1) {
		                    var functionNames = expander.getTransformNames();
		                    if (_.find(functionNames, function (functionName) { return transformerName === functionName || transformerName === ('!' + functionName); })) {
		                        return;
		                    }
		                    return "unknown function " + transformerName;
		                }
		            }
		        }
		    };
		    return TraitVariablesValidator;
		})();
		var MethodBodyValidator = (function () {
		    function MethodBodyValidator() {
		    }
		    MethodBodyValidator.prototype.validate = function (node, validationAcceptor) {
		        var methodNode = node.parent();
		        if (!methodNode) {
		            return;
		        }
		        if (!(methodNode.definition().isAssignableFrom(universes.Universe08.Method.name) || methodNode.definition().isAssignableFrom(universes.Universe10.Method.name))) {
		            return;
		        }
		        var hasBody = _.find(methodNode.lowLevel() && methodNode.lowLevel().children() || [], function (child) {
		            var keyValue = child.key();
		            return keyValue && (universes.Universe08.MethodBase.properties.body.name === keyValue || universes.Universe10.MethodBase.properties.body.name === keyValue);
		        });
		        if (hasBody && _.find(MethodBodyValidator.methodsWithoutRequestBody, function (methodDisabled) { return methodNode.name() === methodDisabled; })) {
		            validationAcceptor.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, 'Request body is disabled for "' + methodNode.name() + '" method.', methodNode));
		        }
		    };
		    MethodBodyValidator.methodsWithoutRequestBody = ['trace'];
		    return MethodBodyValidator;
		})();
		var CompositePropertyValidator = (function () {
		    function CompositePropertyValidator() {
		    }
		    CompositePropertyValidator.prototype.validate = function (node, v) {
		        var pr = checkPropertyQuard(node, v);
		        var vl = node.value();
		        if (!node.property().range().hasStructure()) {
		            if (vl instanceof hlimpl.StructuredValue && !node.property().isSelfNode()) {
		                //TODO THIS SHOULD BE MOVED TO TYPESYSTEM FOR STS AT SOME MOMENT
		                if (isTypeOrSchema(node.property())) {
		                    if (node.property().domain().key() == universes.Universe08.BodyLike) {
		                        var structValue = vl;
		                        var newNode = new hlimpl.ASTNodeImpl(node.lowLevel(), node.parent(), node.parent().definition().universe().type("ObjectTypeDeclaration"), node.property());
		                        newNode.validate(v);
		                        return;
		                    }
		                }
		                v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Scalar is expected here", node));
		            }
		            else {
		                if (node.lowLevel().valueKind() != 0 /* SCALAR */ && node.lowLevel().valueKind() != 5 /* INCLUDE_REF */ && !node.property().getAdapter(services.RAMLPropertyService).isKey()) {
		                    if ((!node.property().isMultiValue())) {
		                        var k = node.property().range().key();
		                        if (k == universes.Universe08.StringType || k == universes.Universe08.MarkdownString || k == universes.Universe08.MimeType) {
		                            v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "property '" + node.name() + "' must be a string", node));
		                        }
		                    }
		                }
		            }
		        }
		        if (node.property().getAdapter(services.RAMLPropertyService).isKey()) {
		            if (vl != null && vl.indexOf(" ") != -1) {
		                v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Keys should not have spaces '" + node.value() + "'", node));
		            }
		        }
		        if (typeof vl == 'string' && vl.indexOf("<<") != -1) {
		            if (vl.indexOf(">>") > vl.indexOf("<<")) {
		                var error = new TraitVariablesValidator().check(vl);
		                if (error) {
		                    v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "unknown function applied to parameter", node));
		                }
		                if (insideResourceTypeOrTrait(node.parent())) {
		                    return;
		                }
		            }
		        }
		        new MethodBodyValidator().validate(node, v);
		        if ((node.property().range().key() == universes.Universe08.MimeType || node.property().range().key() == universes.Universe10.MimeType) || (node.property().nameId() == universes.Universe10.TypeDeclaration.properties.name.name && node.parent().property().nameId() == universes.Universe10.Method.properties.body.name)) {
		            new MediaTypeValidator().validate(node, v);
		            return;
		        }
		        if (isExampleProp(node.property())) {
		            new ExampleValidator().validate(node, v);
		        }
		        if (node.property().nameId() == universes.Universe10.TypeDeclaration.properties.name.name) {
		            //TODO MOVE TO DEF SYSTEM
		            var nameId = node.parent().property() && node.parent().property().nameId();
		            if (nameId == universes.Universe08.Resource.properties.uriParameters.name || nameId == universes.Universe08.Resource.properties.baseUriParameters.name) {
		                new UrlParameterNameValidator().validate(node, v);
		                return;
		            }
		        }
		        var range = node.property().range().key();
		        if (range == universes.Universe08.RelativeUriString || range == universes.Universe10.RelativeUriString) {
		            new UriValidator().validate(node, v);
		            return;
		        }
		        if (range == universes.Universe08.FullUriTemplateString || range == universes.Universe10.FullUriTemplateString) {
		            new UriValidator().validate(node, v);
		            return;
		        }
		        if ("pattern" == node.name() && universes.Universe10.StringType == node.definition().key() && node.parent().definition().isAssignableFrom("StringTypeDeclaration")) {
		            validateRegexp(node.value(), v, node);
		        }
		        if ("name" == node.name() && universes.Universe10.StringType == node.definition().key() && (typeof node.value() == "string") && node.value().indexOf("[") == 0 && node.value().lastIndexOf("]") == node.value().length - 1) {
		            if (node.parent() instanceof hlimpl.ASTNodeImpl && universes.Universe10.ObjectTypeDeclaration.properties.properties.name == node.parent().property().nameId()) {
		                if (node.parent().parent() instanceof hlimpl.ASTNodeImpl && universes.Universe10.ObjectTypeDeclaration == node.parent().parent().definition().key()) {
		                    var cleanedValue = node.value().substr(1, node.value().length - 2);
		                    validateRegexp(cleanedValue, v, node);
		                }
		            }
		        }
		        if (pr.getAdapter(services.RAMLPropertyService).isTypeExpr()) {
		            new SchemaOrTypeValidator().validate(node, v);
		            return;
		        }
		        if (pr.isReference() || pr.isDescriminator()) {
		            new DescriminatorOrReferenceValidator().validate(node, v);
		        }
		        else {
		            new NormalValidator().validate(node, v);
		        }
		    };
		    return CompositePropertyValidator;
		})();
		var NormalValidator = (function () {
		    function NormalValidator() {
		    }
		    NormalValidator.prototype.validate = function (node, cb) {
		        var vl = node.value();
		        var pr = node.property();
		        var range = pr.range();
		        if (range instanceof typeSystem.AbstractType) {
		            var nc = range;
		            var rof = nc.getAdapter(services.RAMLService).getRepresentationOf();
		            if (rof) {
		                nc = rof;
		            }
		            var ff = nc.getFixedFacets();
		            for (var fc in ff) {
		                var facet = nc.facet(fc);
		                if (facet) {
		                    var val = facet.getFacetValidator();
		                    if (val) {
		                        try {
		                            var qq = vl;
		                            if (pr.range().hasArrayInHierarchy()) {
		                                try {
		                                    qq = node.parent().lowLevel().dumpToObject()[node.parent().name()][pr.nameId()];
		                                }
		                                catch (e) {
		                                }
		                            }
		                            var res = val(qq, ff[fc]);
		                            if (typeof res == 'string') {
		                                cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "" + res, node));
		                            }
		                        }
		                        catch (e) {
		                            cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, e.message, node));
		                        }
		                    }
		                }
		            }
		        }
		        var v = cb;
		        if (node.lowLevel().keyKind() != 3 /* SEQ */) {
		            var validation = pr.range().getAdapter(services.RAMLService).isValid(node.parent(), vl, pr);
		        }
		        else {
		            validation = true;
		        }
		        if (validation instanceof Error) {
		            if (!validation.canBeRef) {
		                v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, validation.message, node));
		                validation = null;
		                return;
		            }
		        }
		        if (!validation || validation instanceof Error) {
		            if (pr.nameId() != 'value') {
		                if (!checkReference(pr, node, vl, v)) {
		                    if (pr.nameId() == universes.Universe10.TypeDeclaration.properties.schema.name || universes.Universe10.TypeDeclaration.properties.type.name) {
		                        if (vl && vl.trim() && (pr.domain().key() == universes.Universe08.BodyLike || pr.domain().key() == universes.Universe10.TypeDeclaration)) {
		                            var testSchema = vl.trim().charAt(0); //FIXME
		                            if (testSchema != '{' && testSchema != '<') {
		                                return;
		                            }
		                        }
		                    }
		                    var decl = node.findReferencedValue();
		                    if (decl instanceof Error) {
		                        v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, decl.message, node));
		                    }
		                    if (!decl) {
		                        if (vl) {
		                            if (pr.nameId() == universes.Universe10.TypeDeclaration.properties.schema.name) {
		                                var z = vl.trim();
		                                if (z.charAt(0) != '{' && z.charAt(0) != '<') {
		                                    if (vl.indexOf('|') != -1 || vl.indexOf('[]') != -1 || vl.indexOf("(") != -1) {
		                                        return;
		                                    }
		                                }
		                            }
		                        }
		                        if (validation instanceof Error && vl) {
		                            v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, validation.message, node));
		                            validation = null;
		                            return;
		                        }
		                        v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Empty value is not allowed here", node));
		                    }
		                }
		            }
		            else {
		                var vl = node.value();
		                var message = "Invalid value schema:" + vl;
		                if (validation instanceof Error) {
		                    message = validation.message;
		                }
		                v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, message, node));
		            }
		        }
		        var values = pr.enumOptions();
		        if (values) {
		            if (typeof values == 'string') {
		                if (values != vl) {
		                    if (vl && (vl.indexOf("x-") == 0) && pr.nameId() == universes.Universe08.AbstractSecurityScheme.properties.type.name) {
		                    }
		                    else {
		                        v.accept(createIssue(0 /* UNRESOLVED_REFERENCE */, "Invalid value:" + vl + " allowed values are:" + values, node));
		                    }
		                }
		            }
		            else if (values.length > 0) {
		                if (!_.find(values, function (x) { return x == vl; })) {
		                    if (vl && (vl.indexOf("x-") == 0) && pr.nameId() == universes.Universe08.AbstractSecurityScheme.properties.type.name) {
		                    }
		                    else {
		                        v.accept(createIssue(0 /* UNRESOLVED_REFERENCE */, "Invalid value:" + vl + " allowed values are:" + values.join(","), node));
		                    }
		                }
		            }
		        }
		    };
		    return NormalValidator;
		})();
		var UriValidator = (function () {
		    function UriValidator() {
		    }
		    UriValidator.prototype.validate = function (node, cb) {
		        try {
		            var values = new UrlParameterNameValidator().parseUrl(node.value());
		            if (values.some(function (x) { return x == "version"; }) && node.property().nameId() == "baseUri") {
		                var version = node.root().attr("version");
		                if (!version) {
		                    cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "missing version", node, false));
		                }
		            }
		        }
		        catch (e) {
		            cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, e.message, node, false));
		        }
		    };
		    return UriValidator;
		})();
		var MediaTypeValidator = (function () {
		    function MediaTypeValidator() {
		    }
		    MediaTypeValidator.prototype.validate = function (node, cb) {
		        try {
		            var v = node.value();
		            if (!v) {
		                return;
		            }
		            if (v == "*/*") {
		                return;
		            }
		            if (v.indexOf("/*") == v.length - 2) {
		                v = v.substring(0, v.length - 2) + "/xxx";
		            }
		            if (v == "body") {
		                if (node.parent().parent()) {
		                    var ppc = node.parent().parent().definition().key();
		                    if (ppc === universes.Universe08.Response || ppc === universes.Universe10.Response || node.parent().parent().definition().isAssignableFrom(universes.Universe10.MethodBase.name)) {
		                        v = node.parent().computedValue("mediaType");
		                    }
		                }
		            }
		            var res = mediaTypeParser.parse(v);
		            var types = {
		                application: 1,
		                audio: 1,
		                example: 1,
		                image: 1,
		                message: 1,
		                model: 1,
		                multipart: 1,
		                text: 1,
		                video: 1
		            };
		            if (!types[res.type]) {
		                cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Unknown media type 'type'", node));
		            }
		        }
		        catch (e) {
		            cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "" + e.message, node));
		        }
		        if (node.value() && node.value() == ("multipart/form-data") || node.value() == ("application/x-www-form-urlencoded")) {
		            if (node.parent() && node.parent().parent() && node.parent().parent().property()) {
		                if (node.parent().parent().property().nameId() == universes.Universe10.MethodBase.properties.responses.name) {
		                    cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Form related media types can not be used in responses", node));
		                }
		            }
		        }
		        return;
		    };
		    return MediaTypeValidator;
		})();
		//class SignatureValidator implements PropertyValidator{
		//    validate(node:hl.IAttribute,cb:hl.ValidationAcceptor){
		//        var vl=node.value();
		//        var q = vl?vl.trim():"";
		//        if (q.length > 0 ) {
		//            try {
		//                //ramlSignature.validate(vl, node, cb);
		//            }catch (e){
		//                cb.accept(createIssue(hl.IssueCode.INVALID_VALUE_SCHEMA,"Error during signature parse:"+e.message,node))
		//            }
		//            return;
		//        }
		//        return;
		//    }
		//}
		var UrlParameterNameValidator = (function () {
		    function UrlParameterNameValidator() {
		    }
		    UrlParameterNameValidator.prototype.checkBaseUri = function (node, c, vl, v) {
		        var bu = c.root().attr("baseUri");
		        if (bu) {
		            var tnv = bu.value();
		            try {
		                var pNames = this.parseUrl(tnv);
		                if (!_.find(pNames, function (x) { return x == vl; })) {
		                    v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Unused url parameter", node));
		                }
		            }
		            catch (e) {
		            }
		        }
		        else {
		            v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Unused url parameter", node));
		        }
		    };
		    UrlParameterNameValidator.prototype.parseUrl = function (value) {
		        var result = [];
		        var temp = "";
		        var inPar = false;
		        var count = 0;
		        for (var a = 0; a < value.length; a++) {
		            var c = value[a];
		            if (c == '{') {
		                count++;
		                inPar = true;
		                continue;
		            }
		            if (c == '}') {
		                count--;
		                inPar = false;
		                result.push(temp);
		                temp = "";
		                continue;
		            }
		            if (inPar) {
		                temp += c;
		            }
		        }
		        if (count > 0) {
		            throw new Error("Unmatched '{'");
		        }
		        if (count < 0) {
		            throw new Error("Unmatched '}'");
		        }
		        return result;
		    };
		    UrlParameterNameValidator.prototype.validate = function (node, cb) {
		        var vl = node.value();
		        if (node.parent().property().nameId() == universes.Universe10.Api.properties.baseUri.name) {
		            var c = node.parent().parent();
		            this.checkBaseUri(node, c, vl, cb);
		            return;
		        }
		        var c = node.parent().parent();
		        var tn = c.name();
		        if (c.definition().key() === universes.Universe10.Api || c.definition().key() === universes.Universe08.Api) {
		            this.checkBaseUri(node, c, vl, cb);
		            return;
		        }
		        if (c.definition().key() == universes.Universe10.ResourceType || c.definition().key() == universes.Universe08.ResourceType) {
		            return;
		        }
		        try {
		            var pNames = this.parseUrl(tn);
		            var foundInLocalParameters = _.find(pNames, function (x) { return x == vl; });
		            if (!foundInLocalParameters) {
		                var baseUri = node.root().attr(universes.Universe10.Api.properties.baseUri.name);
		                if (baseUri && node.name() === universes.Universe08.Api.properties.baseUriParameters.name) {
		                    var baseUriValue = baseUri.value();
		                    if (baseUriValue) {
		                        pNames = this.parseUrl(baseUriValue);
		                        if (pNames && pNames.length > 0) {
		                            if (_.find(pNames, function (x) { return x == vl; }))
		                                return;
		                        }
		                    }
		                }
		                cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Unused url parameter '" + vl + "'", node));
		            }
		        }
		        catch (e) {
		        }
		    };
		    return UrlParameterNameValidator;
		})();
		exports.UrlParameterNameValidator = UrlParameterNameValidator;
		exports.typeToName = {};
		exports.typeToName[universes.Universe08.Trait.name] = "trait";
		exports.typeToName[universes.Universe08.ResourceType.name] = "resource type";
		exports.typeToName[universes.Universe10.Trait.name] = "trait";
		exports.typeToName[universes.Universe10.AnnotationTypeDeclaration.name] = "annotation type";
		exports.typeToName[universes.Universe10.ResourceType.name] = "resource type";
		exports.typeToName[universes.Universe10.AbstractSecurityScheme.name] = "security scheme";
		function checkReference(pr, astNode, vl, cb) {
		    if (!vl) {
		        return;
		    }
		    if (vl == 'null') {
		        if (pr.isAllowNull()) {
		            return;
		        }
		    }
		    try {
		        if (typeof vl == 'string') {
		            if (pr.domain().key() == universes.Universe10.TypeDeclaration) {
		                if (pr.nameId() == universes.Universe10.TypeDeclaration.properties.type.name || pr.nameId() == universes.Universe10.ArrayTypeDeclaration.properties.items.name) {
		                    typeExpression.validate(vl, astNode, cb);
		                    return false;
		                }
		            }
		            if (pr.range().key() == universes.Universe08.SchemaString || pr.range().key() == universes.Universe10.SchemaString) {
		                if (pr.range().universe().version() == "RAML10") {
		                    if (pr.range() instanceof defs.ValueType) {
		                        typeExpression.validate(vl, astNode, cb);
		                        return false;
		                    }
		                }
		            }
		            if (pr.nameId() == universes.Universe10.TypeDeclaration.properties.schema.name || pr.nameId() == universes.Universe10.TypeDeclaration.properties.type.name) {
		                if (pr.domain().key() == universes.Universe08.BodyLike || pr.domain().key() == universes.Universe10.TypeDeclaration) {
		                    var q = vl.trim();
		                    if (q.length > 0 && q.charAt(0) != '{' && q.charAt(0) != '<') {
		                        typeExpression.validate(vl, astNode, cb);
		                        return false;
		                    }
		                    return;
		                }
		            }
		        }
		    }
		    catch (e) {
		        cb.accept(createIssue(0 /* UNRESOLVED_REFERENCE */, "Syntax error:" + e.message, astNode));
		    }
		    var adapter = pr.getAdapter(services.RAMLPropertyService);
		    var valid = adapter.isValidValue(vl, astNode.parent());
		    if (!valid && astNode.lowLevel().unit().absolutePath() !== astNode.parent().lowLevel().unit().absolutePath()) {
		        valid = adapter.isValidValue(vl, hl.fromUnit(astNode.lowLevel().unit()));
		    }
		    if (!valid) {
		        if (typeof vl == 'string') {
		            if ((vl.indexOf("x-") == 0) && pr.nameId() == universes.Universe10.TypeDeclaration.properties.type.name) {
		                return true;
		            }
		        }
		        var expected = (adapter.isReference && adapter.isReference() && adapter.referencesTo && adapter.referencesTo() && adapter.referencesTo().nameId && adapter.referencesTo().nameId());
		        var referencedToName = exports.typeToName[expected] || nameForNonReference(astNode);
		        var message = referencedToName ? ("Unrecognized " + referencedToName + " '" + vl + "'.") : ("Unresolved reference: " + vl);
		        if (pr.nameId() == "type" && pr.domain().universe().version() == "RAML08") {
		            if (pr.domain().isAssignableFrom(universes.Universe08.Parameter.name)) {
		                message = "type can be either of: string, number, integer, file, date or boolean";
		            }
		        }
		        cb.accept(createIssue(0 /* UNRESOLVED_REFERENCE */, message, astNode));
		        return true;
		    }
		    return false;
		}
		function nameForNonReference(astNode) {
		    var propertyName = astNode && astNode.lowLevel() && astNode.lowLevel().key();
		    if (propertyName === universes.Universe10.AbstractSecurityScheme.properties.type.name) {
		        var domain = astNode.parent() && astNode.parent().definition() && astNode.parent().definition().nameId();
		        if (domain === universes.Universe10.AbstractSecurityScheme.name) {
		            return "security scheme type";
		        }
		    }
		}
		var SchemaOrTypeValidator = (function () {
		    function SchemaOrTypeValidator() {
		    }
		    SchemaOrTypeValidator.prototype.validate = function (node, cb) {
		        var vl = node.value();
		        if (vl instanceof hlimpl.StructuredValue) {
		            //already validated in scalar
		            //cb.accept(createIssue(hl.IssueCode.UNRESOLVED_REFERENCE,"Type expression is expected here",node));
		            return;
		        }
		        if (!vl) {
		            vl = "";
		        }
		        try {
		            typeExpression.validate(vl, node, cb);
		        }
		        catch (e) {
		            cb.accept(createIssue(0 /* UNRESOLVED_REFERENCE */, "Syntax error:" + e.message, node));
		        }
		    };
		    return SchemaOrTypeValidator;
		})();
		var DescriminatorOrReferenceValidator = (function () {
		    function DescriminatorOrReferenceValidator() {
		    }
		    DescriminatorOrReferenceValidator.prototype.validate = function (node, cb) {
		        var vl = node.value();
		        var valueKey = vl;
		        var pr = node.property();
		        if (typeof vl == 'string') {
		            checkReference(pr, node, vl, cb);
		            if (pr.range() instanceof defs.ReferenceType) {
		                var t = pr.range();
		                if (true) {
		                    var mockNode = jsyaml.createNode("" + vl);
		                    mockNode._actualNode().startPosition = node.lowLevel().valueStart();
		                    mockNode._actualNode().endPosition = node.lowLevel().valueEnd();
		                    var stv = new hlimpl.StructuredValue(mockNode, node.parent(), node.property());
		                    var hn = stv.toHighLevel();
		                    if (hn) {
		                        hn.validate(cb);
		                    }
		                }
		            }
		        }
		        else {
		            var st = vl;
		            if (st) {
		                valueKey = st.valueName();
		                var vn = st.valueName();
		                if (!checkReference(pr, node, vn, cb)) {
		                    var hnode = st.toHighLevel();
		                    if (hnode)
		                        hnode.validate(cb);
		                }
		            }
		            else {
		                valueKey = null;
		            }
		        }
		        if (valueKey) {
		            var validation = pr.range().getAdapter(services.RAMLService).isValid(node.parent(), valueKey, pr);
		            if (validation instanceof Error) {
		                cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, validation.message, node));
		                validation = null;
		            }
		        }
		    };
		    return DescriminatorOrReferenceValidator;
		})();
		var allowOverride = { resources: 1, queryParameters: 1, headers: 1, body: 1, methods: 1, responses: 1 };
		var RAMLVersionAndFragmentValidator = (function () {
		    function RAMLVersionAndFragmentValidator() {
		    }
		    RAMLVersionAndFragmentValidator.prototype.validate = function (node, v) {
		        var u = node.universe();
		        var tv = u.getTypedVersion();
		        if (tv) {
		            if (util.startsWith(tv, "#%")) {
		                if (tv !== "#%RAML 0.8" && tv !== "#%RAML 1.0") {
		                    var i = createIssue(9 /* NODE_HAS_VALUE */, "Unknown version of RAML expected to see one of '#%RAML 0.8' or '#%RAML 1.0'", node);
		                    v.accept(i);
		                }
		                var tl = u.getTopLevel();
		                if (tl) {
		                    if (tl != node.definition().nameId()) {
		                        if (node.definition().nameId() == "Api") {
		                            var i = createIssue(9 /* NODE_HAS_VALUE */, "Unknown top level type:" + tl, node);
		                            v.accept(i);
		                        }
		                    }
		                }
		            }
		        }
		    };
		    return RAMLVersionAndFragmentValidator;
		})();
		var RequiredPropertiesAndContextRequirementsValidator = (function () {
		    function RequiredPropertiesAndContextRequirementsValidator() {
		    }
		    RequiredPropertiesAndContextRequirementsValidator.prototype.validate = function (node, v) {
		        (node.definition()).getAdapter(services.RAMLService).getContextRequirements().forEach(function (x) {
		            if (!node.checkContextValue(x.name, x.value, x.value)) {
		                var message = x.name + (" should be " + x.value + " to use type " + node.definition().nameId());
		                if (x.name == 'location' && x.value == "ParameterLocation.FORM") {
		                    message = "file type can be only used in web forms";
		                }
		                v.accept(createIssue(8 /* MISSED_CONTEXT_REQUIREMENT */, message, node));
		            }
		        });
		        node.definition().requiredProperties().forEach(function (x) {
		            var r = x.range();
		            if (r.hasArrayInHierarchy()) {
		                r = r.arrayInHierarchy().componentType();
		            }
		            if (r.hasValueTypeInHierarchy()) {
		                var nm = node.attr(x.nameId());
		                if (!nm) {
		                    var msg = "Missing required property " + x.nameId();
		                    if (node.definition().getAdapter(services.RAMLService).isInlinedTemplates()) {
		                        msg = "value was not provided for parameter: " + x.nameId();
		                    }
		                    var i = createIssue(3 /* MISSING_REQUIRED_PROPERTY */, msg, node);
		                    v.accept(i);
		                }
		            }
		            else {
		                var el = node.elementsOfKind(x.nameId());
		                if (!el || el.length == 0) {
		                    var i = createIssue(3 /* MISSING_REQUIRED_PROPERTY */, "Missing required property " + x.nameId(), node);
		                    v.accept(i);
		                }
		            }
		        });
		    };
		    return RequiredPropertiesAndContextRequirementsValidator;
		})();
		var ScalarQuoteValidator = (function () {
		    function ScalarQuoteValidator() {
		    }
		    ScalarQuoteValidator.prototype.validate = function (node, v) {
		        var r = node.lowLevel().unit();
		        node.lowLevel().visit(function (x) {
		            if (x.unit() != r) {
		                return false;
		            }
		            if (x.value() && x._node && x._node.value) {
		                if (x._node.value.doubleQuoted) {
		                    var ind = (x.value() + "").indexOf(":");
		                    var nl = (x.value() + "").indexOf("\n");
		                    if (ind != -1 && nl != -1 && (!x.includePath() || x.includePath().length == 0)) {
		                        var i = createIssue(9 /* NODE_HAS_VALUE */, "Suspicious double quoted multiline scalar, it is likely that you forgot closing \" " + x.value(), node, true);
		                        i.start = x._node.value.startPosition;
		                        i.end = x._node.value.endPosition;
		                        if (i.start == i.end) {
		                            i.end++;
		                        }
		                        v.accept(i);
		                    }
		                }
		            }
		            return true;
		        });
		    };
		    return ScalarQuoteValidator;
		})();
		//TODO to typesystem
		var FixedFacetsValidator = (function () {
		    function FixedFacetsValidator() {
		    }
		    FixedFacetsValidator.prototype.validate = function (node, v) {
		        var nc = node.definition();
		        var facets = nc.getFixedFacets();
		        Object.keys(facets).forEach(function (fk) {
		            var facet = nc.getAdapter(services.RAMLService).getRepresentationOf().facet(fk);
		            if (facet) {
		                var facetValidator = facet.getFacetValidator();
		                if (facetValidator) {
		                    var obj = node.lowLevel().dumpToObject();
		                    obj = obj[node.lowLevel().key()];
		                    try {
		                        var message = facetValidator(obj, facets[fk]);
		                        if (typeof message == 'string') {
		                            var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "" + message, node);
		                            v.accept(i);
		                        }
		                    }
		                    catch (e) {
		                        var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, e.message, node);
		                        v.accept(i);
		                    }
		                }
		            }
		        });
		    };
		    return FixedFacetsValidator;
		})();
		var OverridePropertyValidator = (function () {
		    function OverridePropertyValidator() {
		    }
		    OverridePropertyValidator.prototype.validate = function (node, v) {
		        var props = node.elementsOfKind("properties");
		        this.checkOverride(props, node, v, false);
		        var faceted = node.elementsOfKind("facets");
		        this.checkOverride(faceted, node, v, true);
		    };
		    OverridePropertyValidator.prototype.checkOverride = function (props, node, v, facets) {
		        var _this = this;
		        var name = facets ? "facet" : "property";
		        if (props.length > 0) {
		            var types = node.attributes("type");
		            types.forEach(function (t) {
		                var tp = typeExpression.getType(node, t.value(), {});
		                if (tp instanceof def.NodeClass) {
		                    var xnc = tp;
		                    var serv = xnc.getAdapter(services.RAMLService);
		                    var rps = facets ? xnc.allFacets() : serv.allRuntimeProperties();
		                    rps.forEach(function (rp) {
		                        var override = _.find(props, function (x) { return x.name() == rp.nameId(); });
		                        if (override) {
		                            if (facets) {
		                                //not allowing to override facets at all
		                                var i = createIssue(10 /* ONLY_OVERRIDE_ALLOWED */, ("Illegal override of " + name + " " + override.name() + " inherited from ") + t.value(), override);
		                                v.accept(i);
		                            }
		                            else if (override.optional()) {
		                                //we are not allowing to override required properties with optional properties
		                                var i = createIssue(10 /* ONLY_OVERRIDE_ALLOWED */, ("Illegal override of " + name + " " + override.name() + " inherited from ") + t.value() + ', required ' + name + ' can not be made optional ', override);
		                                v.accept(i);
		                            }
		                            else if (!_this.overrideAllowed(override, rp)) {
		                                var i = createIssue(10 /* ONLY_OVERRIDE_ALLOWED */, ("Illegal override of " + name + " " + override.name() + " inherited from ") + t.value(), override);
		                                v.accept(i);
		                            }
		                        }
		                    });
		                }
		            });
		        }
		    };
		    OverridePropertyValidator.prototype.overrideAllowed = function (propertyNode, runtimeProperty) {
		        if (!propertyNode.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		            return false;
		        }
		        //check for user-defined classes
		        if (propertyNode.definition().isAssignableFrom(runtimeProperty.range().nameId())) {
		            return true;
		        }
		        //checking runtime hierarchy for value types
		        var propertyDefinitionRuntime = propertyNode.definition().getAdapter(services.RAMLService).toRuntime();
		        if (propertyDefinitionRuntime) {
		            if (propertyDefinitionRuntime.isAssignableFrom(runtimeProperty.range().nameId())) {
		                return true;
		            }
		        }
		        return false;
		    };
		    return OverridePropertyValidator;
		})();
		var CompositeNodeValidator = (function () {
		    function CompositeNodeValidator() {
		    }
		    CompositeNodeValidator.prototype.validate = function (node, v) {
		        if (node.lowLevel().keyKind() == 3 /* SEQ */) {
		            var isPattern = node.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name);
		            if (!isPattern) {
		                v.accept(createIssue(2 /* UNKNOWN_NODE */, "Node key can not be sequence", node));
		            }
		        }
		        if (node.definition().key() == universes.Universe08.GlobalSchema) {
		            if (node.lowLevel().valueKind() != 0 /* SCALAR */ && node.lowLevel().valueKind() != 5 /* INCLUDE_REF */) {
		                v.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "schema " + node.name() + " must be a string", node));
		            }
		        }
		        if (!node.parent()) {
		            new RAMLVersionAndFragmentValidator().validate(node, v);
		            if (node.definition().key() == universes.Universe08.Api || node.definition().key() == universes.Universe10.Api) {
		                if (node.definition().universe().version() != "RAML08") {
		                    new OverloadingValidator().validateApi(node.wrapperNode(), v);
		                }
		                else {
		                    new OverloadingValidator08().validateApi(node.wrapperNode(), v);
		                }
		            }
		            new ScalarQuoteValidator().validate(node, v);
		            lintNode(node, v);
		        }
		        new OverlayNodesValidator().validate(node, v);
		        var nc = node.definition();
		        if (nc instanceof typeSystem.AbstractType) {
		            var anc = nc;
		            if (nc.isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		                //var tpes=anc.allSuperTypes();
		                new OverridePropertyValidator().validate(node, v);
		            }
		            if (anc.getAdapter(services.RAMLService).isRuntime()) {
		                new FixedFacetsValidator().validate(node, v);
		            }
		        }
		        if (nc.key() == universes.Universe08.BodyLike) {
		            if (node.lowLevel().children().map(function (x) { return x.key(); }).some(function (x) { return x === "formParameters"; })) {
		                if (node.parent() && node.parent().definition().key() == universes.Universe08.Response) {
		                    var i = createIssue(9 /* NODE_HAS_VALUE */, "form parameters can not be used in response", node);
		                    v.accept(i);
		                }
		                else if (node.lowLevel().children().map(function (x) { return x.key(); }).some(function (x) { return x === "schema" || x === "example"; })) {
		                    var i = createIssue(9 /* NODE_HAS_VALUE */, "formParameters cannot be used together with the example or schema properties", node);
		                    v.accept(i);
		                }
		            }
		        }
		        //validation of enum values;
		        if (node.definition().isAssignableFrom(universes.Universe08.Parameter.name) || node.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		            var vls = node.attributes("enum").map(function (x) { return x.value(); });
		            if (vls.length != _.uniq(vls).length) {
		                var i = createIssue(9 /* NODE_HAS_VALUE */, "enum contains duplicated values", node);
		                v.accept(i);
		            }
		            if (node.definition().isAssignableFrom(universes.Universe08.NumberTypeDeclaration.name) || node.definition().isAssignableFrom(universes.Universe10.NumberTypeDeclaration.name)) {
		                var isInteger = node.definition().isAssignableFrom(universes.Universe08.IntegerTypeDeclaration.name) || node.definition().isAssignableFrom(universes.Universe10.IntegerTypeDeclaration.name);
		                node.attributes("enum").forEach(function (attribute) {
		                    var value = isInteger ? parseInt(attribute.value()) : parseFloat(attribute.value());
		                    var isValid = isInteger ? !isNaN(value) && attribute.value().indexOf('.') === -1 : !isNaN(value);
		                    if (!isValid) {
		                        var issue = createIssue(9 /* NODE_HAS_VALUE */, (isInteger ? "Integer" : "Number") + " is expected", attribute);
		                        v.accept(issue);
		                    }
		                });
		            }
		        }
		        checkPropertyQuard(node, v);
		        if (typeof node.value() == 'string' && !node.definition().getAdapter(services.RAMLService).allowValue()) {
		            if (node.parent()) {
		                var i = createIssue(9 /* NODE_HAS_VALUE */, "node " + node.name() + " can not be a scalar", node);
		                v.accept(i);
		            }
		        }
		        new RequiredPropertiesAndContextRequirementsValidator().validate(node, v);
		        new ValidateChildrenKeys().validate(node, v);
		        if (node.definition() && node.property() && node.property().nameId() == "types") {
		            new TypeExressionHierarchyValidator().validate(node, v);
		            new InheritanceRulesValidator().validate(node, v);
		        }
		    };
		    return CompositeNodeValidator;
		})();
		var OverlayNodesValidator = (function () {
		    function OverlayNodesValidator() {
		    }
		    /**
		     * Checks that this node is in white list and
		     * makes itself and all of its children allowed to exist in overlay even
		     * if there is no master counterpart
		     * @param node
		     * @param root
		     * @returns {boolean}
		     */
		    OverlayNodesValidator.prototype.allowsAnyChildren = function (node, root) {
		        var property = node.property();
		        var definition = node.definition();
		        //accepting new annotation types
		        if ((universeHelpers.isAnnotationTypeType(definition) || universeHelpers.isTypeDeclarationTypeOrDescendant(definition)) && universeHelpers.isAnnotationTypesProperty(property))
		            return true;
		        //accepting new top-level type declarations
		        if (node.parent() == root && universeHelpers.isTypesProperty(property) && universeHelpers.isTypeDeclarationTypeOrDescendant(definition))
		            return true;
		        //as we allow types, it is logical to also allow schemas as "schemas are only aliases for types"
		        if (universeHelpers.isSchemasProperty(property) && universeHelpers.isGlobalSchemaType(definition))
		            return true;
		        //accepting documentation
		        if (node.parent() == root && universeHelpers.isDocumentationProperty(property) && universeHelpers.isDocumentationType(definition))
		            return true;
		        //accepting annotations
		        if (universeHelpers.isAnnotationsProperty(property))
		            return true;
		        //uses allowed
		        if (universeHelpers.isUsesProperty(property))
		            return true;
		        //examples allowed
		        if (universeHelpers.isExamplesProperty(property))
		            return true;
		        return false;
		    };
		    /**
		     * Checks that this node is allowed to exist in overlay even if there is no master counterpart
		     * due to it or its parent being in the white list.
		     * @param node
		     * @param root
		     */
		    OverlayNodesValidator.prototype.nodeAllowedDueToParent = function (node, root) {
		        var currentNode = node;
		        while (currentNode != root && currentNode != null) {
		            if (this.allowsAnyChildren(currentNode, root)) {
		                return true;
		            }
		            currentNode = currentNode.parent();
		        }
		        return false;
		    };
		    OverlayNodesValidator.prototype.validate = function (node, v) {
		        var root = node.root();
		        var property = node.property();
		        var definition = node.definition();
		        //we are only validating overlays
		        if (!universeHelpers.isOverlayType(root.definition()))
		            return;
		        //for root only validate properties
		        if (node == root) {
		            this.validateProperties(node, v);
		            return;
		        }
		        //we have a whitelist of IHighLevelNodes allowed to be added in an overlay like new types, annotation types,
		        //annotation etc. The contents of such nodes is checked here.
		        if (this.nodeAllowedDueToParent(node, root))
		            return;
		        //checking for a node, this node overrides
		        var overrides = root.knownIds();
		        if (!overrides) {
		            //should never happen
		            return;
		        }
		        var override = overrides.hasOwnProperty(node.id());
		        if (override) {
		            //overrides are allowed, but we need to check properties, this override potentially brings in or changes:
		            this.validateProperties(node, v);
		            return;
		        }
		        //otherwise reporting an illegal node:
		        v.accept(createIssue(10 /* ONLY_OVERRIDE_ALLOWED */, "This node does not override any node from master api:" + node.id(), node));
		    };
		    OverlayNodesValidator.prototype.validateProperties = function (node, acceptor) {
		        node.attrs().forEach(function (attribute) {
		            //ignoring key properties as they are not overriding anything
		            if (attribute.property().getAdapter(services.RAMLPropertyService).isKey()) {
		                return;
		            }
		            //ignoring nodes, which are not coming from this node, but from is master chain
		            if (attribute.parent() != node) {
		                return;
		            }
		            //yes, that also happens!
		            if (attribute.isElement()) {
		                return;
		            }
		            //title allowed
		            if (universeHelpers.isTitlePropertyName(attribute.name()))
		                return;
		            //description allowed
		            if (universeHelpers.isDescriptionPropertyName(attribute.name()))
		                return;
		            //displayName allowed
		            if (universeHelpers.isDisplayNamePropertyName(attribute.name()))
		                return;
		            //usage allowed
		            if (universeHelpers.isUsagePropertyName(attribute.name()))
		                return;
		            //example allowed
		            if (universeHelpers.isExampleProperty(attribute.property()))
		                return;
		            //masterRef allowed
		            if (universeHelpers.isMasterRefProperty(attribute.property()))
		                return;
		            //annotations allowed
		            if (universeHelpers.isAnnotationsProperty(attribute.property()))
		                return;
		            //uses allowed
		            if (universeHelpers.isUsesProperty(attribute.property()))
		                return;
		            //reporting the error
		            var message = "Property " + attribute.name() + " is not allowed to be overriden or added in overlays";
		            acceptor.accept(createIssue(10 /* ONLY_OVERRIDE_ALLOWED */, message, attribute));
		        });
		    };
		    return OverlayNodesValidator;
		})();
		var ValidateChildrenKeys = (function () {
		    function ValidateChildrenKeys() {
		    }
		    ValidateChildrenKeys.prototype.validate = function (node, v) {
		        if (node.definition().universe().version() == "RAML08") {
		            var m = {};
		            var els = node.directChildren().filter(function (x) { return x.isElement(); });
		            els.forEach(function (x) {
		                if (x["_computed"]) {
		                    return;
		                }
		                if (!x.name()) {
		                    return; //handling nodes with no key (documentation)
		                }
		                var rm = x.lowLevel().parent() ? x.lowLevel().parent().end() : "";
		                var k = x.name() + rm;
		                if (m.hasOwnProperty(k)) {
		                    if (!x.isNamePatch()) {
		                        var i = createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, x.name() + " already exists in this context", x);
		                        v.accept(i);
		                    }
		                }
		                else {
		                    m[k] = 1;
		                }
		            });
		        }
		        else {
		            var m = {};
		            var els = node.directChildren().filter(function (x) { return x.isElement(); });
		            els.forEach(function (x) {
		                if (x["_computed"]) {
		                    return;
		                }
		                if (!x.name()) {
		                    return; //handling nodes with no key (documentation)
		                }
		                if (allowOverride[x.property().nameId()]) {
		                    return;
		                }
		                var k = x.name() + x.property().nameId();
		                if (m.hasOwnProperty(k)) {
		                    var i = createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, x.name() + " already exists in this context", x);
		                    v.accept(i);
		                }
		                else {
		                    m[k] = 1;
		                }
		            });
		        }
		        var requireds = node.definition().requiredProperties();
		        var hasRequireds = requireds && requireds.length > 0;
		        var adapter = node.definition().getAdapter(services.RAMLService);
		        var isAllowAny = adapter && adapter.getAllowAny();
		        var anyExceptRequireds = isAllowAny && hasRequireds;
		        var allLowlevel = node.lowLevel().children();
		        var mm = _.groupBy(allLowlevel, function (x) { return x.key(); });
		        var pr = node.directChildren().filter(function (x) { return x.isAttr() || anyExceptRequireds; });
		        var gr = _.groupBy(pr, function (x) { return x.name(); });
		        var all = node.directChildren();
		        var allG = _.groupBy(all, function (x) { return x.name(); });
		        var computedAnnotationsMultiplValues = false;
		        Object.keys(mm).forEach(function (x) {
		            if (x.charAt(0) !== '(' || mm[x].length < 2) {
		                return;
		            }
		            if (!computedAnnotationsMultiplValues) {
		                computedAnnotationsMultiplValues = true;
		                pr.forEach(function (z) {
		                    if (z.property().isAnnotation()) {
		                        var annotationRange = z.property().range();
		                        var attr = z;
		                        var refsTo = attr.findReferenceDeclaration();
		                        if (refsTo != null) {
		                            var refNode = refsTo;
		                            var multiple = refNode.attr("allowMultiple");
		                            if (multiple) {
		                                var mv = multiple.value();
		                                if (mv == 'true') {
		                                    delete mm[attr.lowLevel().key()];
		                                }
		                            }
		                        }
		                    }
		                });
		            }
		        });
		        Object.keys(mm).forEach(function (x) {
		            if (x) {
		                if (mm[x].length > 1 && !allG[x]) {
		                    var i = createIssue(4 /* PROPERTY_EXPECT_TO_HAVE_SINGLE_VALUE */, x + " should have a single value", node);
		                    i.start = mm[x][0].keyStart();
		                    i.end = mm[x][0].keyEnd();
		                    v.accept(i);
		                }
		            }
		        });
		        Object.keys(gr).forEach(function (x) {
		            if (gr[x].length < 2) {
		                return;
		            }
		            var isUnknown = gr[x][0].isUnknown();
		            var isMultiValue = !isUnknown && gr[x][0].property().isMultiValue();
		            if (isMultiValue && (node.definition().isAssignableFrom(universes.Universe08.SecuritySchemeSettings.name) || node.definition().isAssignableFrom(universes.Universe10.SecuritySchemeSettings.name))) {
		                isMultiValue = mm[x] && mm[x].length === 1;
		            }
		            if ((isUnknown && anyExceptRequireds) || !isMultiValue) {
		                gr[x].forEach(function (y) {
		                    var i = createIssue(4 /* PROPERTY_EXPECT_TO_HAVE_SINGLE_VALUE */, (y.property() ? y.property().nameId() : y.name()) + " should have a single value", y);
		                    v.accept(i);
		                });
		            }
		        });
		    };
		    return ValidateChildrenKeys;
		})();
		var InheritanceRulesValidator = (function () {
		    function InheritanceRulesValidator() {
		    }
		    InheritanceRulesValidator.prototype.isPrimitive = function (q) {
		        return !q.hasArrayInHierarchy() && !this.isObject(q) && !q.hasUnionInHierarchy() && q.key() != universes.Universe10.TypeDeclaration;
		    };
		    InheritanceRulesValidator.prototype.isObject = function (q) {
		        return q.isAssignableFrom(universes.Universe10.ObjectTypeDeclaration.name);
		    };
		    InheritanceRulesValidator.prototype.validate = function (node, v) {
		        var _this = this;
		        var associatedType = node.associatedType();
		        if (!associatedType) {
		            if (_.find(node.definition().allSuperTypes(), function (x) { return x.key() == universes.Universe10.TypeDeclaration; })) {
		                associatedType = typeBuilder.typeFromNode(node);
		            }
		        }
		        if (associatedType) {
		            var st = associatedType.superTypes();
		            if (st.length > 1) {
		                if (_.find(st, function (x) { return _this.isPrimitive(x); })) {
		                    if (_.find(st, function (x) { return _this.isObject(x); })) {
		                        var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "You can not inherit both from types of different kind", node.attr("type") ? node.attr("type") : node);
		                        v.accept(i);
		                        return;
		                    }
		                }
		                if (_.find(st, function (x) { return x.hasArrayInHierarchy(); })) {
		                    if (_.find(st, function (x) { return !x.hasArrayInHierarchy(); })) {
		                        var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "You can not inherit both from types of different kind", node.attr("type") ? node.attr("type") : node);
		                        v.accept(i);
		                        return;
		                    }
		                }
		                if (_.filter(st, function (x) { return _this.isPrimitive(x); }).length > 1) {
		                    var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "You can not inherit from two primitive types", node.attr("type") ? node.attr("type") : node);
		                    v.accept(i);
		                    return;
		                }
		                if (_.filter(st, function (x) { return x.hasArrayInHierarchy(); }).length > 1) {
		                    var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "You can not inherit from two array types", node.attr("type") ? node.attr("type") : node);
		                    v.accept(i);
		                    return;
		                }
		            }
		        }
		    };
		    return InheritanceRulesValidator;
		})();
		//TODO REMOVE IT
		var buildIns = {
		    string: 1,
		    date: 1,
		    boolean: 1,
		    number: 1,
		    integer: 1,
		    object: 1,
		    array: 1,
		    union: 1,
		    file: 1,
		    value: 1,
		    any: 1,
		    scalar: 1
		};
		var TypeVisited = (function () {
		    function TypeVisited(name, path) {
		        this.name = name;
		        this.path = path;
		    }
		    TypeVisited.prototype.isType = function (definition) {
		        if (this.name !== (definition && definition.nameId())) {
		            return false;
		        }
		        if (this.path !== (definition && definition._path)) {
		            return false;
		        }
		        return true;
		    };
		    return TypeVisited;
		})();
		var TypeExressionHierarchyValidator = (function () {
		    function TypeExressionHierarchyValidator() {
		        this.visited = [];
		    }
		    TypeExressionHierarchyValidator.prototype.validate = function (node, cb) {
		        this._node = node;
		        try {
		            if (buildIns[node.name()]) {
		                var issue = createIssue(7 /* INVALID_VALUE_SCHEMA */, "You can not redeclare build in types", node);
		                cb.accept(issue);
		            }
		            var at = node.attributes("type");
		            if (at) {
		                var found = false;
		                at.forEach(function (x) {
		                    if (x.value() == node.name()) {
		                        var issue = createIssue(7 /* INVALID_VALUE_SCHEMA */, "Recurrent type definition", node.attr("type") ? node.attr("type") : node);
		                        cb.accept(issue);
		                        found = true;
		                    }
		                });
		                if (found) {
		                    return;
		                }
		            }
		            this.visited.push(new TypeVisited(this._node.name(), this.path()));
		            this.traverseDec(this.definition(), cb, 0);
		        }
		        catch (e) {
		        }
		    };
		    TypeExressionHierarchyValidator.prototype.path = function () {
		        return this._node && this._node.lowLevel() && this._node.lowLevel().unit() && this._node.lowLevel().unit().path();
		    };
		    TypeExressionHierarchyValidator.prototype.attr = function (name) {
		        return this._node.attr(name);
		    };
		    TypeExressionHierarchyValidator.prototype.definition = function () {
		        return this._node.definition();
		    };
		    /**
		     * !!!You cannot inherit from types of different kind at the same moment ( kinds are: union types, array types, object types, scalar types )
		     * !!!You cannot inherit from types extending union types ( ex: you cannot extend from Pet if Pet = Dog | Cat )
		     * You cannot inherit from multiple primitive types
		     * !!! You cannot inherit from a type that extends Array type
		     * Facets are always inherited
		     * You can fix a previously defined facet to a value if the facet is defined on a superclass
		     * Properties are only allowed on object types
		     * You cannot create cyclic dependencies when inheriting
		     * @param d
		     * @param v
		     * @param level
		     * @param visited
		     */
		    TypeExressionHierarchyValidator.prototype.traverseDec = function (d, v, level) {
		        var _this = this;
		        if (!d) {
		            return;
		        }
		        if (d instanceof def.Array && level > 0) {
		            var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "Extending from types extending array types is not allowed", this.attr("type") ? this.attr("type") : this._node);
		            v.accept(i);
		            return;
		        }
		        if (d instanceof def.Union && level > 0) {
		            var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "Extending from types extending union types is not allowed", this.attr("type") ? this.attr("type") : this._node);
		            v.accept(i);
		            return;
		        }
		        if (_.find(this.visited, function (mayBeVisited) { return mayBeVisited.isType(d); })) {
		            var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "Recurrent type definition", this.attr("type") ? this.attr("type") : this._node);
		            v.accept(i);
		            throw new Error();
		        }
		        this.visited.push(new TypeVisited(d.nameId(), d._path));
		        try {
		            if (d.nameId() == this._node.name() && level > 0) {
		                var i = createIssue(7 /* INVALID_VALUE_SCHEMA */, "Recurrent type definition", this.attr("type") ? this.attr("type") : this._node);
		                v.accept(i);
		                throw new Error();
		            }
		            if (d.hasArrayInHierarchy()) {
		                this.traverseDec(d.arrayInHierarchy().componentType(), v, level + 1);
		                return;
		            }
		            if (d.hasUnionInHierarchy()) {
		                var lleft = level + 1;
		                var lright = level + 1;
		                var union = d.unionInHierarchy();
		                if (union.leftType()) {
		                    if (union.leftType().hasUnionInHierarchy()) {
		                        var ul = union.leftType().unionInHierarchy();
		                        if (union.getAdapter(services.RAMLService).getDeclaringNode() == ul.getAdapter(services.RAMLService).getDeclaringNode()) {
		                        }
		                    }
		                }
		                if (union.rightType()) {
		                    if (union.rightType().hasUnionInHierarchy()) {
		                        var ul = union.rightType().unionInHierarchy();
		                        if (union.getAdapter(services.RAMLService).getDeclaringNode() == ul.getAdapter(services.RAMLService).getDeclaringNode()) {
		                            lright = level;
		                        }
		                    }
		                }
		                if (lleft == level + 1) {
		                    this.traverseDec(union.leftType(), v, lleft);
		                }
		                if (lright == level + 1) {
		                    this.traverseDec(union.rightType(), v, lright);
		                }
		                return;
		            }
		            var mn = d.allSuperTypes();
		            mn.forEach(function (yy) {
		                if (yy instanceof defs.AbstractType) {
		                    var node = (yy).getAdapter(services.RAMLService).getDeclaringNode();
		                    if (node || yy instanceof defs.Array || yy instanceof defs.Union) {
		                        _this.traverseDec(yy, v, level + 1);
		                    }
		                }
		            });
		        }
		        finally {
		            this.visited = this.visited.filter(function (toRemove) { return !toRemove.isType(d); });
		        }
		    };
		    return TypeExressionHierarchyValidator;
		})();
		/**
		 * validates examples
		 */
		var ExampleValidator = (function () {
		    function ExampleValidator() {
		    }
		    ExampleValidator.prototype.validate = function (node, cb) {
		        //check if we expect to do strict validation
		        var strictValidation = this.isStrict(node);
		        if (!strictValidation) {
		            if (!settings.validateNotStrictExamples) {
		                return;
		            }
		        }
		        var pObj = this.parseObject(node, cb, strictValidation);
		        if (!pObj) {
		            return;
		        }
		        var schema = this.aquireSchema(node);
		        if (schema) {
		            schema.validate(pObj, cb, strictValidation);
		        }
		    };
		    ExampleValidator.prototype.isExampleNode = function (node) {
		        return this.isSingleExampleNode(node) || this.isExampleNodeInMultipleDecl(node);
		    };
		    ExampleValidator.prototype.isSingleExampleNode = function (node) {
		        return node.name() == universes.Universe10.TypeDeclaration.properties.example.name;
		    };
		    ExampleValidator.prototype.isExampleNodeInMultipleDecl = function (node) {
		        var parent = node.parent();
		        if (parent) {
		            return universeHelpers.isExampleSpecType(parent.definition());
		        }
		        return false;
		    };
		    ExampleValidator.prototype.findParentSchemaOrTypeAttribute = function (node) {
		        var attribute = node.parent().attr(universes.Universe10.TypeDeclaration.properties.schema.name);
		        if (attribute) {
		            return attribute;
		        }
		        attribute = node.parent().attr(universes.Universe10.TypeDeclaration.properties.type.name);
		        if (attribute) {
		            return attribute;
		        }
		        if (!node.parent()) {
		            return null;
		        }
		        attribute = node.parent().parent().attr(universes.Universe10.TypeDeclaration.properties.schema.name);
		        if (attribute) {
		            return attribute;
		        }
		        attribute = node.parent().parent().attr(universes.Universe10.TypeDeclaration.properties.type.name);
		        if (attribute) {
		            return attribute;
		        }
		        return null;
		    };
		    ExampleValidator.prototype.aquireSchema = function (node) {
		        var sp = node.parent().definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name);
		        if (this.isExampleNode(node)) {
		            var sampleRoot = node;
		            if (this.isExampleNodeInMultipleDecl(node)) {
		                sampleRoot = node.parent();
		            }
		            if (sampleRoot.parent()) {
		                if (sampleRoot.parent().definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name) && sampleRoot.parent().parent() === null) {
		                    sp = false;
		                }
		                else if (sampleRoot.parent().property().nameId() == universes.Universe10.LibraryBase.properties.types.name) {
		                    sp = false;
		                }
		                if (sampleRoot.parent().parent()) {
		                    var ppc = sampleRoot.parent().parent().definition().key();
		                    if (ppc == universes.Universe08.Method || ppc == universes.Universe10.Method) {
		                        if (sampleRoot.parent().property().nameId() == universes.Universe10.Method.properties.queryParameters.name) {
		                        }
		                        else {
		                            sp = true;
		                        }
		                    }
		                    if (ppc == universes.Universe08.Response || ppc == universes.Universe10.Response) {
		                        sp = true;
		                    }
		                }
		            }
		        }
		        if (node.parent().definition().key() == universes.Universe08.BodyLike || sp) {
		            //FIXME MULTIPLE INHERITANCE
		            var sa = this.findParentSchemaOrTypeAttribute(node);
		            if (sa) {
		                var val = sa.value();
		                if (val instanceof hlimpl.StructuredValue) {
		                    return null;
		                }
		                var strVal = ("" + val).trim();
		                var so = null;
		                if (strVal.charAt(0) == "{") {
		                    try {
		                        so = su.getJSONSchema(strVal);
		                    }
		                    catch (e) {
		                        return null;
		                    }
		                }
		                if (strVal.charAt(0) == "<") {
		                    try {
		                        so = su.getXMLSchema(strVal);
		                    }
		                    catch (e) {
		                        return null;
		                    }
		                }
		                if (so) {
		                    return {
		                        validate: function (pObje, cb, strict) {
		                            try {
		                                if (pObje.__$validated) {
		                                    return;
		                                }
		                                so.validateObject(pObje);
		                            }
		                            catch (e) {
		                                if (e.message == "Cannot assign to read only property '__$validated' of object") {
		                                    return;
		                                }
		                                if (e.message == "Object.keys called on non-object") {
		                                    return;
		                                }
		                                cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Example does not conforms to schema:" + e.message, node, !strict));
		                                return;
		                            }
		                            //validate using classical schema;
		                        }
		                    };
		                }
		                else {
		                    if (strVal.length > 0) {
		                        var nodeParent = node.parent();
		                        var grandParent = nodeParent && nodeParent.parent();
		                        var owner = nodeParent && nodeParent.definition() && nodeParent.definition().isAssignableFrom(universes.Universe10.ObjectTypeDeclaration.name) && nodeParent;
		                        owner = owner || (grandParent && grandParent.definition() && grandParent.definition().isAssignableFrom(universes.Universe10.ObjectTypeDeclaration.name) && grandParent);
		                        var tp = owner ? typeBuilder.typeFromNode(owner) : typeExpression.getType2(node.parent(), strVal, {});
		                        if (tp) {
		                            return {
		                                validate: function (pObje, cb, strict) {
		                                    new TypeValidator(node).validate(pObje, tp, cb, strict);
		                                }
		                            };
		                        }
		                    }
		                }
		            }
		        }
		        return this.getSchemaFromModel(node);
		    };
		    ExampleValidator.prototype.getSchemaFromModel = function (node) {
		        var p = node.parent();
		        if (node.property().nameId() == universes.Universe10.ExampleSpec.properties.content.name) {
		            p = p.parent();
		        }
		        var tp = typeBuilder.typeFromNode(p);
		        if (tp) {
		            return {
		                validate: function (pObje, cb, strict) {
		                    new TypeValidator(node).validate(pObje, tp, cb, strict);
		                    //validate using typeExpression;
		                }
		            };
		        }
		        return null;
		    };
		    ExampleValidator.prototype.toObject = function (h, v, cb) {
		        var res = v.lowLevel().dumpToObject(true);
		        this.testDublication(h, v.lowLevel(), cb);
		        if (res["example"]) {
		            return res["example"];
		        }
		        if (res["content"]) {
		            return res["content"];
		        }
		    };
		    ExampleValidator.prototype.testDublication = function (h, v, cb) {
		        var _this = this;
		        var map = {};
		        v.children().forEach(function (x) {
		            if (x.key()) {
		                if (map[x.key()]) {
		                    cb.accept(createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, "Keys should be unique", new hlimpl.BasicASTNode(x, h.parent())));
		                }
		                map[x.key()] = x;
		            }
		            _this.testDublication(h, x, cb);
		        });
		    };
		    ExampleValidator.prototype.parseObject = function (node, cb, strictValidation) {
		        var pObj = null;
		        var vl = node.value();
		        var mediaType = getMediaType(node);
		        if (vl instanceof hlimpl.StructuredValue) {
		            //validate in context of type/schema
		            pObj = this.toObject(node, vl, cb);
		        }
		        else {
		            if (mediaType) {
		                if (isJson(mediaType)) {
		                    try {
		                        pObj = JSON.parse(vl);
		                    }
		                    catch (e) {
		                        cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Can not parse JSON:" + e.message, node, !strictValidation));
		                        return;
		                    }
		                }
		                if (isXML(mediaType)) {
		                    try {
		                        pObj = xmlutil(vl);
		                    }
		                    catch (e) {
		                        cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Can not parse XML:" + e.message, node, !strictValidation));
		                        return;
		                    }
		                }
		            }
		            else {
		                try {
		                    pObj = JSON.parse(vl);
		                }
		                catch (e) {
		                    if (vl.trim().indexOf("<") == 0) {
		                        try {
		                            pObj = xmlutil(vl);
		                        }
		                        catch (e) {
		                            cb.accept(createIssue(7 /* INVALID_VALUE_SCHEMA */, "Can not parse XML:" + e.message, node, !strictValidation));
		                            return;
		                        }
		                    }
		                    else {
		                        //cb.accept(createIssue(hl.IssueCode.INVALID_VALUE_SCHEMA, "Can not parse JSON:" + e.message, node, !strictValidation));
		                        return vl;
		                    }
		                }
		            }
		        }
		        return pObj;
		    };
		    ExampleValidator.prototype.isStrict = function (node) {
		        var strictValidation = false;
		        var strict = node.parent().attr("strict");
		        if (strict) {
		            if (strict.value() == 'true') {
		                strictValidation = true;
		            }
		        }
		        return strictValidation;
		    };
		    return ExampleValidator;
		})();
		exports.ExampleValidator = ExampleValidator;
		function isJson(s) {
		    return s.indexOf("json") != -1;
		}
		exports.isJson = isJson;
		function isXML(s) {
		    return s.indexOf("xml") != -1;
		}
		exports.isXML = isXML;
		function getMediaType(node) {
		    var vl = getMediaType2(node);
		    if (vl == 'body') {
		        var rootMedia = node.root().attr("mediaType");
		        if (rootMedia) {
		            return rootMedia.value();
		        }
		        return null;
		    }
		    return vl;
		}
		exports.getMediaType = getMediaType;
		function getMediaType2(node) {
		    if (node.parent()) {
		        var pc = node.parent().definition();
		        if (pc.key() == universes.Universe08.BodyLike) {
		            return node.parent().name();
		        }
		        if (node.parent().parent()) {
		            var ppc = node.parent().parent().definition().key();
		            if (ppc == universes.Universe08.Response || ppc == universes.Universe10.Response) {
		                if (node.parent().property().nameId() == universes.Universe08.Response.properties.headers.name) {
		                    return null;
		                }
		                return node.parent().name();
		            }
		            if (ppc == universes.Universe08.Method || ppc == universes.Universe10.Method) {
		                if (node.parent().property().nameId() == universes.Universe10.Method.properties.queryParameters.name || node.parent().property().nameId() == universes.Universe10.Method.properties.headers.name) {
		                    return null;
		                }
		                return node.parent().name();
		            }
		        }
		    }
		    return null;
		}
		var localError = function (node, c, w, message, p, prop) {
		    var st = node.lowLevel().start();
		    var et = node.lowLevel().end();
		    if (node.lowLevel().key() && node.lowLevel().keyStart()) {
		        var ks = node.lowLevel().keyStart();
		        if (ks > 0) {
		            st = ks;
		        }
		        var ke = node.lowLevel().keyEnd();
		        if (ke > 0) {
		            et = ke;
		        }
		    }
		    if (et < st) {
		        et = st + 1; //FIXME
		    }
		    if (prop && !prop.getAdapter(services.RAMLPropertyService).isMerged() && node.parent() == null) {
		        var nm = _.find(node.lowLevel().children(), function (x) { return x.key() == prop.nameId(); });
		        if (nm) {
		            var ks = nm.keyStart();
		            var ke = nm.keyEnd();
		            if (ks > 0 && ke > ks) {
		                st = ks;
		                et = ke;
		            }
		        }
		    }
		    return {
		        code: c,
		        isWarning: w,
		        message: message,
		        node: node,
		        start: st,
		        end: et,
		        path: p ? (node.lowLevel().unit() ? node.lowLevel().unit().path() : "") : null,
		        extras: [],
		        unit: node ? node.lowLevel().unit() : null
		    };
		};
		function createIssue(c, message, node, w) {
		    if (w === void 0) { w = false; }
		    //console.log(node.name()+node.lowLevel().start()+":"+node.id());
		    var original = null;
		    var pr = null;
		    if (node) {
		        pr = node.property();
		        if (node.lowLevel().unit() != node.root().lowLevel().unit()) {
		            original = localError(node, c, w, message, true, pr);
		            var v = node.lowLevel().unit();
		            if (v) {
		                message = message + " " + v.path();
		            }
		            while (node.lowLevel().unit() != node.root().lowLevel().unit()) {
		                pr = node.property();
		                node = node.parent();
		            }
		        }
		    }
		    if (original) {
		        if (node.property() && node.property().nameId() == universes.Universe10.LibraryBase.properties.uses.name && node.parent() != null) {
		            pr = node.property(); //FIXME there should be other cases
		            node = node.parent();
		        }
		    }
		    var error = localError(node, c, w, message, false, pr);
		    if (original) {
		        error.extras.push(original);
		    }
		    //console.log(error.start+":"+error.end)
		    return error;
		}
		exports.createIssue = createIssue;


	/***/ },
	/* 56 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var xmlutil = __webpack_require__(57);
		var lru = __webpack_require__(59);
		var ZSchema = __webpack_require__(60);
		var ValidationResult = (function () {
		    function ValidationResult() {
		    }
		    return ValidationResult;
		})();
		exports.ValidationResult = ValidationResult;
		var globalCache = lru(400);
		var useLint = true;
		var JSONSchemaObject = (function () {
		    function JSONSchemaObject(schema) {
		        this.schema = schema;
		        if (!schema || schema.trim().length == 0 || schema.trim().charAt(0) != '{') {
		            throw new Error("Invalid JSON schema content");
		        }
		        var jsonSchemaObject;
		        try {
		            var jsonSchemaObject = JSON.parse(schema);
		        }
		        catch (err) {
		            throw new Error("It is not JSON schema");
		        }
		        if (!jsonSchemaObject) {
		            return;
		        }
		        try {
		            var api = __webpack_require__(61);
		            jsonSchemaObject = api.v4(jsonSchemaObject);
		        }
		        catch (e) {
		            throw new Error('Can not parse schema' + schema);
		        }
		        delete jsonSchemaObject['$schema'];
		        //delete jsonSchemaObject['required']
		        this.jsonSchema = jsonSchemaObject;
		    }
		    JSONSchemaObject.prototype.getType = function () {
		        return "source.json";
		    };
		    JSONSchemaObject.prototype.validateObject = function (object) {
		        //TODO Validation of objects
		        //xmlutil(content);
		        this.validate(JSON.stringify(object));
		    };
		    JSONSchemaObject.prototype.validate = function (content) {
		        var key = content + this.schema;
		        var c = globalCache.get(key);
		        if (c) {
		            if (c instanceof Error) {
		                throw c;
		            }
		            return;
		        }
		        var validator = new ZSchema();
		        var valid = validator.validate(JSON.parse(content), this.jsonSchema);
		        var errors = validator.getLastErrors();
		        if (errors && errors.length > 0) {
		            var res = new Error("Content is not valid according to schema:" + errors.map(function (x) { return x.message + " " + x.params; }).join(", "));
		            res.errors = errors;
		            globalCache.set(key, res);
		            throw res;
		        }
		        globalCache.set(key, 1);
		    };
		    return JSONSchemaObject;
		})();
		exports.JSONSchemaObject = JSONSchemaObject;
		var XMLSchemaObject = (function () {
		    function XMLSchemaObject(schema) {
		        this.schema = schema;
		        if (schema.charAt(0) != '<') {
		            throw new Error("Invalid JSON schema");
		        }
		        xmlutil(schema);
		    }
		    XMLSchemaObject.prototype.getType = function () {
		        return "text.xml";
		    };
		    XMLSchemaObject.prototype.validate = function (content) {
		        xmlutil(content);
		    };
		    XMLSchemaObject.prototype.validateObject = function (object) {
		        //TODO Validation of objects
		        //xmlutil(content);
		    };
		    return XMLSchemaObject;
		})();
		exports.XMLSchemaObject = XMLSchemaObject;
		function getJSONSchema(content) {
		    var rs = useLint ? globalCache.get(content) : false;
		    if (rs) {
		        return rs;
		    }
		    var res = new JSONSchemaObject(content);
		    globalCache.set(content, res);
		    return res;
		}
		exports.getJSONSchema = getJSONSchema;
		function getXMLSchema(content) {
		    var rs = useLint ? globalCache.get(content) : false;
		    if (rs) {
		        return rs;
		    }
		    var res = new XMLSchemaObject(content);
		    if (useLint) {
		        globalCache.set(content, res);
		    }
		}
		exports.getXMLSchema = getXMLSchema;
		function createSchema(content) {
		    var rs = useLint ? globalCache.get(content) : false;
		    if (rs) {
		        return rs;
		    }
		    try {
		        var res = new JSONSchemaObject(content);
		        if (useLint) {
		            globalCache.set(content, res);
		        }
		        return res;
		    }
		    catch (e) {
		        try {
		            var res = new XMLSchemaObject(content);
		            if (useLint) {
		                globalCache.set(content, res);
		            }
		            return res;
		        }
		        catch (e) {
		            if (useLint) {
		                globalCache.set(content, new Error("Can not parse schema"));
		            }
		            return null;
		        }
		    }
		}
		exports.createSchema = createSchema;


	/***/ },
	/* 57 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var DomParser = __webpack_require__(58);
		function xmlToJson(xml) {
		    // Create the return object
		    var obj = {};
		    if (xml.nodeType == 1) {
		        // do attributes
		        if (xml.attributes.length > 0) {
		            for (var j = 0; j < xml.attributes.length; j++) {
		                var attribute = xml.attributes.item(j);
		                obj["@" + attribute.nodeName] = attribute.nodeValue;
		            }
		        }
		    }
		    else if (xml.nodeType == 3) {
		        obj = xml.nodeValue;
		    }
		    // do children
		    if (xml.hasChildNodes()) {
		        for (var i = 0; i < xml.childNodes.length; i++) {
		            var item = xml.childNodes.item(i);
		            var nodeName = item.nodeName;
		            if (nodeName == undefined) {
		                continue;
		            }
		            if (typeof (obj[nodeName]) == "undefined") {
		                obj[nodeName] = xmlToJson(item);
		            }
		            else {
		                if (typeof (obj[nodeName].push) == "undefined") {
		                    var old = obj[nodeName];
		                    obj[nodeName] = [];
		                    obj[nodeName].push(old);
		                }
		                obj[nodeName].push(xmlToJson(item));
		            }
		        }
		    }
		    return obj;
		}
		;
		function cleanupText(j) {
		    for (var p in j) {
		        if (typeof (j[p]) == "object") {
		            for (var k in j[p]) {
		                if (k == '#text') {
		                    var txt = j[p]['#text'];
		                    if (typeof (txt) != 'string') {
		                        txt = txt.join("");
		                    }
		                    txt = txt.trim();
		                    if (txt.length == 0) {
		                        delete j[p]['#text'];
		                    }
		                }
		            }
		            cleanupText(j[p]);
		        }
		    }
		    return j;
		}
		function cleanupJson(j) {
		    for (var p in j) {
		        if (typeof (j[p]) == "object") {
		            var keys = Object.keys(j[p]);
		            if (keys.length == 1) {
		                if (keys[0] == '#text') {
		                    j[p] = j[p]['#text'];
		                }
		            }
		            cleanupJson(j[p]);
		        }
		    }
		    return j;
		}
		function parseXML(value) {
		    var v = new DomParser.DOMParser();
		    var parsed = v.parseFromString(value);
		    return cleanupJson(cleanupText(xmlToJson(parsed)));
		}
		module.exports = parseXML;


	/***/ },
	/* 58 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(10);

	/***/ },
	/* 59 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(13);

	/***/ },
	/* 60 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(14);

	/***/ },
	/* 61 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(31);

	/***/ },
	/* 62 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var universe = __webpack_require__(54);
		/////////////////////// properties
		function isDocumentationProperty(p) {
		    return p.nameId() === universe.Universe10.Api.properties.documentation.name || p.nameId() === universe.Universe08.Api.properties.documentation.name;
		}
		exports.isDocumentationProperty = isDocumentationProperty;
		function isUsagePropertyName(name) {
		    return name === universe.Universe10.Trait.properties.usage.name || name === universe.Universe08.Trait.properties.usage.name || name === universe.Universe10.ResourceType.properties.usage.name || name === universe.Universe08.ResourceType.properties.usage.name || name === universe.Universe10.Library.properties.usage.name || name === universe.Universe10.Overlay.properties.usage.name || name === universe.Universe10.Extension.properties.usage.name;
		}
		exports.isUsagePropertyName = isUsagePropertyName;
		function isUsageProperty(p) {
		    return isUsagePropertyName(p.nameId());
		}
		exports.isUsageProperty = isUsageProperty;
		function isMasterRefProperty(p) {
		    return p.nameId() == universe.Universe10.Overlay.properties.masterRef.name || p.nameId() == universe.Universe10.Extension.properties.masterRef.name;
		}
		exports.isMasterRefProperty = isMasterRefProperty;
		function isDescriptionPropertyName(name) {
		    return name === universe.Universe10.TypeDeclaration.properties.description.name || name === universe.Universe10.RAMLLanguageElement.properties.description.name || name === universe.Universe08.RAMLLanguageElement.properties.description.name || name === "description";
		    //TODO too long to actually list every element having a description, so a couple of checks to cause compile error, and a simple equals check. Also we do not want to affect performance that much.
		}
		exports.isDescriptionPropertyName = isDescriptionPropertyName;
		function isDescriptionProperty(p) {
		    return isDescriptionPropertyName(p.nameId());
		}
		exports.isDescriptionProperty = isDescriptionProperty;
		function isDisplayNamePropertyName(name) {
		    return name === universe.Universe10.TypeDeclaration.properties.displayName.name || name === universe.Universe10.RAMLLanguageElement.properties.displayName.name || name === "displayName";
		    //TODO too long to actually list every element having displayname, so a couple of checks to cause compile error, and a simple equals check. Also we do not want to affect performance that much.
		}
		exports.isDisplayNamePropertyName = isDisplayNamePropertyName;
		function isDisplayNameProperty(p) {
		    return isDisplayNamePropertyName(p.nameId());
		}
		exports.isDisplayNameProperty = isDisplayNameProperty;
		function isTitlePropertyName(name) {
		    return name === universe.Universe10.Api.properties.title.name || name === universe.Universe08.Api.properties.title.name || name === universe.Universe10.DocumentationItem.properties.title.name || name === universe.Universe08.DocumentationItem.properties.title.name || name === universe.Universe10.Overlay.properties.title.name || name === universe.Universe10.Extension.properties.title.name;
		}
		exports.isTitlePropertyName = isTitlePropertyName;
		function isTitleProperty(p) {
		    return isTitlePropertyName(p.nameId());
		}
		exports.isTitleProperty = isTitleProperty;
		function isAnnotationsProperty(p) {
		    return p.nameId() === universe.Universe10.Api.properties.annotations.name || p.nameId() === universe.Universe10.Method.properties.annotations.name || p.nameId() === universe.Universe10.Resource.properties.annotations.name || p.nameId() === universe.Universe10.RAMLLanguageElement.properties.annotations.name || p.nameId() === universe.Universe10.ExampleSpec.properties.annotations.name || p.nameId() === universe.Universe10.TypeDeclaration.properties.annotations.name || p.nameId() === universe.Universe10.Response.properties.annotations.name;
		}
		exports.isAnnotationsProperty = isAnnotationsProperty;
		function isIsProperty(p) {
		    return p.nameId() === universe.Universe10.MethodBase.properties.is.name || p.nameId() === universe.Universe08.MethodBase.properties.is.name || p.nameId() === universe.Universe10.ResourceBase.properties.is.name || p.nameId() === universe.Universe08.ResourceType.properties.is.name || p.nameId() === universe.Universe08.Resource.properties.is.name;
		}
		exports.isIsProperty = isIsProperty;
		function isSecuredByProperty(p) {
		    return p.nameId() === universe.Universe10.Api.properties.securedBy.name || p.nameId() === universe.Universe08.Api.properties.securedBy.name || p.nameId() === universe.Universe10.MethodBase.properties.securedBy.name || p.nameId() === universe.Universe08.MethodBase.properties.securedBy.name || p.nameId() === universe.Universe08.ResourceType.properties.securedBy.name || p.nameId() === universe.Universe10.Method.properties.securedBy.name || p.nameId() === universe.Universe08.Method.properties.securedBy.name || p.nameId() === universe.Universe08.Resource.properties.securedBy.name || p.nameId() === universe.Universe10.ResourceBase.properties.securedBy.name;
		}
		exports.isSecuredByProperty = isSecuredByProperty;
		function isTypeProperty(p) {
		    return p.nameId() === universe.Universe10.AbstractSecurityScheme.properties.type.name || p.nameId() === universe.Universe08.AbstractSecurityScheme.properties.type.name || p.nameId() === universe.Universe08.ResourceType.properties.type.name || p.nameId() === universe.Universe08.Resource.properties.type.name || p.nameId() === universe.Universe08.Parameter.properties.type.name || p.nameId() === universe.Universe10.MimeTypeModel.properties.type.name || p.nameId() === universe.Universe08.MimeTypeModel.properties.type.name || p.nameId() === universe.Universe10.ApiDescription.properties.type.name || p.nameId() === universe.Universe10.ResourceBase.properties.type.name || p.nameId() === universe.Universe10.TypeDeclaration.properties.type.name;
		}
		exports.isTypeProperty = isTypeProperty;
		function isProtocolsProperty(p) {
		    return p.nameId() === universe.Universe10.Api.properties.protocols.name || p.nameId() === universe.Universe08.Api.properties.protocols.name || p.nameId() === universe.Universe08.Method.properties.protocols.name || p.nameId() === universe.Universe10.MethodBase.properties.protocols.name;
		}
		exports.isProtocolsProperty = isProtocolsProperty;
		function isNameProperty(p) {
		    return p.nameId() === universe.Universe10.TypeDeclaration.properties.name.name || p.nameId() === universe.Universe10.TypeDeclaration.properties.name.name || p.nameId() === universe.Universe08.AbstractSecurityScheme.properties.name.name || p.nameId() === universe.Universe10.AbstractSecurityScheme.properties.name.name || p.nameId() === universe.Universe08.Trait.properties.name.name || p.nameId() === universe.Universe10.Trait.properties.name.name || p.nameId() === "name";
		    //TODO too long to actually list every element having a name, so a couple of checks to cause compile error, and a simple equals check. Also we do not want to affect performance that much.
		}
		exports.isNameProperty = isNameProperty;
		function isBodyProperty(p) {
		    return p.nameId() === universe.Universe10.MethodBase.properties.body.name || p.nameId() === universe.Universe08.MethodBase.properties.body.name || p.nameId() === universe.Universe10.Response.properties.body.name || p.nameId() === universe.Universe08.Response.properties.body.name || p.nameId() === universe.Universe10.Method.properties.body.name;
		}
		exports.isBodyProperty = isBodyProperty;
		function isSchemaProperty(p) {
		    return p.nameId() === universe.Universe08.BodyLike.properties.schema.name || p.nameId() === universe.Universe08.XMLBody.properties.schema.name || p.nameId() === universe.Universe08.JSONBody.properties.schema.name || p.nameId() === universe.Universe10.TypeDeclaration.properties.schema.name;
		}
		exports.isSchemaProperty = isSchemaProperty;
		function isSchemasProperty(p) {
		    return p.nameId() === universe.Universe08.Api.properties.schemas.name || p.nameId() === universe.Universe10.LibraryBase.properties.schemas.name;
		}
		exports.isSchemasProperty = isSchemasProperty;
		//export function isSignatureProperty(p:hl.IProperty) : boolean {
		//    return p.nameId() === universe.Universe10.Method.properties.signature.name ||
		//    p.nameId() === universe.Universe10.Resource.properties.signature.name;
		//}
		function isResourcesProperty(p) {
		    return p.nameId() === universe.Universe10.Api.properties.resources.name || p.nameId() === universe.Universe08.Api.properties.resources.name || p.nameId() === universe.Universe10.Resource.properties.resources.name || p.nameId() === universe.Universe08.Resource.properties.resources.name;
		}
		exports.isResourcesProperty = isResourcesProperty;
		function isTypesProperty(p) {
		    return p.nameId() === universe.Universe10.LibraryBase.properties.types.name;
		}
		exports.isTypesProperty = isTypesProperty;
		function isExampleProperty(p) {
		    return p.nameId() === universe.Universe10.TypeDeclaration.properties.example.name || p.nameId() === "example";
		    //TODO too long to actually list every element having an example, so a couple of checks to cause compile error, and a simple equals check. Also we do not want to affect performance that much.
		}
		exports.isExampleProperty = isExampleProperty;
		function isExamplesProperty(p) {
		    return p.nameId() === universe.Universe10.TypeDeclaration.properties.examples.name || p.nameId() === "examples";
		    //TODO too long to actually list every element having an example, so a couple of checks to cause compile error, and a simple equals check. Also we do not want to affect performance that much.
		}
		exports.isExamplesProperty = isExamplesProperty;
		function isValueProperty(p) {
		    return p.nameId() === universe.Universe10.GlobalSchema.properties.value.name || p.nameId() === universe.Universe08.GlobalSchema.properties.value.name || p.nameId() === universe.Universe10.ImportDeclaration.properties.value.name;
		}
		exports.isValueProperty = isValueProperty;
		function isUriParametersProperty(p) {
		    return p.nameId() === universe.Universe08.Api.properties.uriParameters.name || p.nameId() === universe.Universe08.ResourceType.properties.uriParameters.name || p.nameId() === universe.Universe08.Resource.properties.uriParameters.name || p.nameId() === universe.Universe10.ResourceBase.properties.uriParameters.name;
		}
		exports.isUriParametersProperty = isUriParametersProperty;
		function isBaseUriParametersProperty(p) {
		    return p.nameId() === universe.Universe08.Resource.properties.baseUriParameters.name || p.nameId() === universe.Universe08.Api.properties.baseUriParameters.name || p.nameId() === universe.Universe10.Api.properties.baseUriParameters.name;
		}
		exports.isBaseUriParametersProperty = isBaseUriParametersProperty;
		function isUsesProperty(p) {
		    return p.nameId() === universe.Universe10.LibraryBase.properties.uses.name || p.nameId() === universe.Universe10.Trait.properties.uses.name || p.nameId() === universe.Universe10.ResourceType.properties.uses.name || p.nameId() === universe.Universe10.ResourceTypeOrTrait.properties.uses.name;
		}
		exports.isUsesProperty = isUsesProperty;
		function isAnnotationTypesProperty(p) {
		    return p.nameId() === universe.Universe10.LibraryBase.properties.annotationTypes.name;
		}
		exports.isAnnotationTypesProperty = isAnnotationTypesProperty;
		function isRepeatProperty(p) {
		    return p.nameId() === universe.Universe08.Parameter.properties.repeat.name || p.nameId() === universe.Universe10.TypeDeclaration.properties.repeat.name;
		}
		exports.isRepeatProperty = isRepeatProperty;
		/////////////////////// types
		function isMethodType(type) {
		    return type.key() == universe.Universe10.Method || type.key() == universe.Universe08.Method;
		}
		exports.isMethodType = isMethodType;
		function isApiType(type) {
		    return type.key() == universe.Universe10.Api || type.key() == universe.Universe08.Api;
		}
		exports.isApiType = isApiType;
		function isBooleanTypeType(type) {
		    return type.key() == universe.Universe10.BooleanType || type.key() == universe.Universe08.BooleanType;
		}
		exports.isBooleanTypeType = isBooleanTypeType;
		function isMarkdownStringType(type) {
		    return type.key() == universe.Universe10.MarkdownString || type.key() == universe.Universe08.MarkdownString;
		}
		exports.isMarkdownStringType = isMarkdownStringType;
		function isResourceType(type) {
		    return type.key() == universe.Universe10.Resource || type.key() == universe.Universe08.Resource;
		}
		exports.isResourceType = isResourceType;
		function isTraitType(type) {
		    return type.key() == universe.Universe10.Trait || type.key() == universe.Universe08.Trait;
		}
		exports.isTraitType = isTraitType;
		function isGlobalSchemaType(type) {
		    return type.key() == universe.Universe10.GlobalSchema || type.key() == universe.Universe08.GlobalSchema;
		}
		exports.isGlobalSchemaType = isGlobalSchemaType;
		function isSecuritySchemaType(type) {
		    return type.key() == universe.Universe10.AbstractSecurityScheme || type.key() == universe.Universe08.AbstractSecurityScheme;
		}
		exports.isSecuritySchemaType = isSecuritySchemaType;
		function isTypeDeclarationType(type) {
		    return type.key() == universe.Universe10.TypeDeclaration;
		}
		exports.isTypeDeclarationType = isTypeDeclarationType;
		function isResponseType(type) {
		    return type.key() == universe.Universe10.Response || type.key() == universe.Universe08.Response;
		}
		exports.isResponseType = isResponseType;
		function isBodyLikeType(type) {
		    return type.key() == universe.Universe08.BodyLike;
		}
		exports.isBodyLikeType = isBodyLikeType;
		function isOverlayType(type) {
		    return type.key() == universe.Universe10.Overlay;
		}
		exports.isOverlayType = isOverlayType;
		function isAnnotationTypeType(type) {
		    return type.key() == universe.Universe10.AnnotationTypeDeclaration;
		}
		exports.isAnnotationTypeType = isAnnotationTypeType;
		function isResourceTypeType(type) {
		    return type.key() == universe.Universe10.ResourceType || type.key() == universe.Universe08.ResourceType;
		}
		exports.isResourceTypeType = isResourceTypeType;
		function isSchemaStringType(type) {
		    return type.key() == universe.Universe10.SchemaString || type.key() == universe.Universe08.SchemaString;
		}
		exports.isSchemaStringType = isSchemaStringType;
		function isMethodBaseType(type) {
		    return type.key() == universe.Universe10.MethodBase || type.key() == universe.Universe08.MethodBase;
		}
		exports.isMethodBaseType = isMethodBaseType;
		function isPointerType(type) {
		    return type.key() == universe.Universe10.pointer;
		}
		exports.isPointerType = isPointerType;
		function isRamlExpressionType(type) {
		    return false;
		}
		exports.isRamlExpressionType = isRamlExpressionType;
		function isRamlSelectorType(type) {
		    return type.key() == universe.Universe10.RAMLSelector;
		}
		exports.isRamlSelectorType = isRamlSelectorType;
		function isLibraryType(type) {
		    return type.key() == universe.Universe10.Library;
		}
		exports.isLibraryType = isLibraryType;
		function isStringTypeType(type) {
		    return type.key() == universe.Universe10.StringType || type.key() == universe.Universe08.StringType;
		}
		exports.isStringTypeType = isStringTypeType;
		function isExampleSpecType(type) {
		    return type.key() == universe.Universe10.ExampleSpec;
		}
		exports.isExampleSpecType = isExampleSpecType;
		function isExtensionType(type) {
		    return type.key() == universe.Universe10.Extension;
		}
		exports.isExtensionType = isExtensionType;
		function isTypeDeclarationTypeOrDescendant(type) {
		    return type.isAssignableFrom(universe.Universe10.TypeDeclaration.name);
		}
		exports.isTypeDeclarationTypeOrDescendant = isTypeDeclarationTypeOrDescendant;
		function isDocumentationType(type) {
		    return type.key() == universe.Universe10.DocumentationItem || type.key() == universe.Universe08.DocumentationItem;
		}
		exports.isDocumentationType = isDocumentationType;
		function isAnnotationRefTypeOrDescendant(type) {
		    return type.isAssignableFrom(universe.Universe10.AnnotationRef.name);
		}
		exports.isAnnotationRefTypeOrDescendant = isAnnotationRefTypeOrDescendant;


	/***/ },
	/* 63 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var _ = __webpack_require__(4);
		var extraInjections = [];
		function registerInjector(i) {
		    extraInjections.push(i);
		}
		exports.registerInjector = registerInjector;
		var Adaptable = (function () {
		    function Adaptable() {
		        var _this = this;
		        this.adapters = [];
		        extraInjections.forEach(function (x) { return x.inject(_this); });
		    }
		    Adaptable.prototype.addAdapter = function (q) {
		        this.adapters.push(q);
		    };
		    Adaptable.prototype.getAdapter = function (adapterType) {
		        var result = null;
		        this.adapters.forEach(function (x) {
		            if (x instanceof adapterType) {
		                result = x;
		            }
		        });
		        return result;
		    };
		    return Adaptable;
		})();
		exports.Adaptable = Adaptable;
		var Described = (function (_super) {
		    __extends(Described, _super);
		    function Described(_name, _description) {
		        if (_description === void 0) { _description = ""; }
		        _super.call(this);
		        this._name = _name;
		        this._description = _description;
		        this._tags = [];
		        this._annotations = [];
		    }
		    Described.prototype.nameId = function () {
		        return this._name;
		    };
		    Described.prototype.description = function () {
		        return this._description;
		    };
		    Described.prototype.addAnnotation = function (a) {
		        this._annotations.push(a);
		    };
		    Described.prototype.removeAnnotation = function (a) {
		        this._annotations = this._annotations.filter(function (x) { return x != a; });
		    };
		    Described.prototype.annotations = function () {
		        return [].concat(this._annotations);
		    };
		    Described.prototype.tags = function () {
		        return this._tags;
		    };
		    Described.prototype.withDescription = function (d) {
		        this._description = d;
		        return this;
		    };
		    return Described;
		})(Adaptable);
		exports.Described = Described;
		var ValueRequirement = (function () {
		    /**
		     *
		     * @param name name of the property to discriminate
		     * @param value expected value of discriminating property
		     */
		    function ValueRequirement(name, value) {
		        this.name = name;
		        this.value = value;
		    }
		    return ValueRequirement;
		})();
		exports.ValueRequirement = ValueRequirement;
		var Annotation = (function (_super) {
		    __extends(Annotation, _super);
		    function Annotation(type, parameters) {
		        _super.call(this, type.nameId());
		        this.type = type;
		        this.parameters = parameters;
		    }
		    Annotation.prototype.parameterNames = function () {
		        return Object.keys(this.parameters);
		    };
		    Annotation.prototype.parameter = function (name) {
		        return this.parameters[name];
		    };
		    Annotation.prototype.getType = function () {
		        return this.type;
		    };
		    return Annotation;
		})(Described);
		exports.Annotation = Annotation;
		var AbstractType = (function (_super) {
		    __extends(AbstractType, _super);
		    function AbstractType(_name, _universe, _path) {
		        if (_universe === void 0) { _universe = null; }
		        if (_path === void 0) { _path = ""; }
		        _super.call(this, _name);
		        this._universe = _universe;
		        this._path = _path;
		        this._superTypes = [];
		        this._subTypes = [];
		        this._requirements = [];
		        this.fixedFacets = {};
		        this.uc = false;
		    }
		    AbstractType.prototype.properties = function () {
		        return [];
		    };
		    AbstractType.prototype.externalInHierarchy = function () {
		        var x = this.allSuperTypes();
		        var res = null;
		        x.forEach(function (y) {
		            if (y instanceof ExternalType) {
		                res = y;
		            }
		        });
		        return res;
		    };
		    AbstractType.prototype.allFacets = function (ps) {
		        if (ps === void 0) { ps = {}; }
		        if (this._allFacets) {
		            return this._allFacets;
		        }
		        if (ps[this.nameId()]) {
		            return [];
		        }
		        ps[this.typeId()] = this;
		        var n = {};
		        if (this.superTypes().length > 0) {
		            this.superTypes().forEach(function (x) {
		                if (x instanceof AbstractType) {
		                    x.allFacets(ps).forEach(function (y) { return n[y.nameId()] = y; });
		                }
		            });
		        }
		        this.properties().forEach(function (x) { return n[x.nameId()] = x; });
		        this._allFacets = Object.keys(n).map(function (x) { return n[x]; });
		        return this._allFacets;
		    };
		    AbstractType.prototype.facet = function (name) {
		        return _.find(this.allFacets(), function (x) { return x.nameId() == name; });
		    };
		    AbstractType.prototype.typeId = function () {
		        return this.nameId();
		    };
		    AbstractType.prototype.allProperties = function (ps) {
		        if (ps === void 0) { ps = {}; }
		        if (this._props) {
		            return this._props;
		        }
		        if (ps[this.typeId()]) {
		            return [];
		        }
		        ps[this.typeId()] = this;
		        var n = {};
		        if (this.superTypes().length > 0) {
		            this.superTypes().forEach(function (x) {
		                if (x instanceof AbstractType) {
		                    x.allProperties(ps).forEach(function (y) { return n[y.nameId()] = y; });
		                }
		                else {
		                    x.allProperties().forEach(function (y) { return n[y.nameId()] = y; });
		                }
		            });
		        }
		        for (var x in this.getFixedFacets()) {
		            delete n[x];
		        }
		        this.properties().forEach(function (x) { return n[x.nameId()] = x; });
		        this._props = Object.keys(n).map(function (x) { return n[x]; });
		        return this._props;
		    };
		    AbstractType.prototype.property = function (propName) {
		        return _.find(this.allProperties(), function (x) { return x.nameId() == propName; });
		    };
		    AbstractType.prototype.hasValueTypeInHierarchy = function () {
		        return _.find(this.allSuperTypes(), function (x) {
		            var mm = x;
		            if (mm.uc) {
		                return false;
		            }
		            mm.uc = true;
		            try {
		                return x.hasValueTypeInHierarchy();
		            }
		            finally {
		                mm.uc = false;
		            }
		        }) != null;
		    };
		    AbstractType.prototype.isAnnotationType = function () {
		        return false;
		    };
		    AbstractType.prototype.hasStructure = function () {
		        return false;
		    };
		    AbstractType.prototype.key = function () {
		        if (this._key) {
		            return this._key;
		        }
		        if (this._universe) {
		            this._key = this.universe().matched()[this.nameId()];
		            if (!this._key) {
		                return null;
		            }
		        }
		        return this._key;
		    };
		    AbstractType.prototype.isUserDefined = function () {
		        return false;
		    };
		    AbstractType.prototype.hasArrayInHierarchy = function () {
		        var arr = _.find(this.allSuperTypes(), function (x) { return x instanceof Array; }) != null;
		        return arr;
		    };
		    AbstractType.prototype.arrayInHierarchy = function () {
		        var x = this.allSuperTypes();
		        var res = null;
		        x.forEach(function (y) {
		            if (y instanceof Array) {
		                res = y;
		            }
		        });
		        return res;
		    };
		    AbstractType.prototype.unionInHierarchy = function () {
		        var x = this.allSuperTypes();
		        var res = null;
		        x.forEach(function (y) {
		            if (y instanceof Union) {
		                res = y;
		            }
		        });
		        return res;
		    };
		    AbstractType.prototype.hasExternalInHierarchy = function () {
		        return _.find(this.allSuperTypes(), function (x) {
		            var mm = x;
		            if (mm.uc) {
		                return false;
		            }
		            mm.uc = true;
		            try {
		                return x instanceof ExternalType;
		            }
		            finally {
		                mm.uc = false;
		            }
		        }) != null;
		    };
		    AbstractType.prototype.hasUnionInHierarchy = function () {
		        return _.find(this.allSuperTypes(), function (x) {
		            var mm = x;
		            if (mm.uc) {
		                return false;
		            }
		            mm.uc = true;
		            try {
		                return x.hasUnionInHierarchy();
		            }
		            finally {
		                mm.uc = false;
		            }
		        }) != null;
		    };
		    AbstractType.prototype.fixFacet = function (name, v) {
		        this.fixedFacets[name] = v;
		    };
		    AbstractType.prototype.getFixedFacets = function () {
		        if (this._af) {
		            return this._af;
		        }
		        var sp = this.allSuperTypes();
		        var mm = {};
		        for (var q in this.fixedFacets) {
		            mm[q] = this.fixedFacets[q];
		        }
		        sp.forEach(function (x) {
		            if (x instanceof AbstractType) {
		                x.contributeFacets(mm);
		                var ff = x.fixedFacets;
		                for (var q in ff) {
		                    mm[q] = ff[q];
		                }
		            }
		        });
		        this.contributeFacets(mm);
		        this._af = mm;
		        return mm;
		    };
		    AbstractType.prototype.contributeFacets = function (x) {
		    };
		    AbstractType.prototype.getPath = function () {
		        return this._path;
		    };
		    AbstractType.prototype.setNameAtRuntime = function (name) {
		        this._nameAtRuntime = name;
		    };
		    AbstractType.prototype.getNameAtRuntime = function () {
		        return this._nameAtRuntime;
		    };
		    AbstractType.prototype.universe = function () {
		        return this._universe;
		    };
		    AbstractType.prototype.superTypes = function () {
		        return [].concat(this._superTypes);
		    };
		    AbstractType.prototype.isAssignableFrom = function (typeName) {
		        if (this.nameId() == typeName) {
		            if (this.isUserDefined()) {
		                return false;
		            }
		            return true;
		        }
		        var currentSuperTypes = this.allSuperTypes();
		        for (var i = 0; i < currentSuperTypes.length; i++) {
		            if (currentSuperTypes[i].nameId() == typeName) {
		                return true;
		            }
		        }
		        return false;
		    };
		    AbstractType.prototype.annotationType = function () {
		        return null;
		    };
		    AbstractType.prototype.subTypes = function () {
		        return [].concat(this._subTypes);
		    };
		    AbstractType.prototype.allSubTypes = function () {
		        var rs = [];
		        this.subTypes().forEach(function (x) {
		            rs.push(x);
		            rs = rs.concat(x.allSubTypes());
		        });
		        return _.unique(rs);
		    };
		    AbstractType.prototype.allSuperTypes = function () {
		        var rs = [];
		        this.allSuperTypesRecurrent(this, {}, rs);
		        return _.unique(rs);
		    };
		    AbstractType.prototype.allSuperTypesRecurrent = function (t, m, result) {
		        var _this = this;
		        t.superTypes().forEach(function (x) {
		            if (!m[x.typeId()]) {
		                result.push(x);
		                m[x.typeId()] = x;
		                _this.allSuperTypesRecurrent(x, m, result);
		            }
		        });
		    };
		    AbstractType.prototype.addSuperType = function (q) {
		        q._subTypes.push(this);
		        this._superTypes.push(q);
		    };
		    AbstractType.prototype.addRequirement = function (name, value) {
		        this._requirements.push(new ValueRequirement(name, value));
		    };
		    //FIXME simplify it
		    AbstractType.prototype.valueRequirements = function () {
		        return this._requirements;
		    };
		    AbstractType.prototype.requiredProperties = function () {
		        return this.allProperties().filter(function (x) { return x.isRequired(); });
		    };
		    AbstractType.prototype.printDetails = function (indent, settings) {
		        var _this = this;
		        if (!indent) {
		            indent = "";
		        }
		        if (!settings) {
		            settings = {
		                hideProperties: false,
		                hideSuperTypeProperties: false,
		                printStandardSuperclasses: false
		            };
		        }
		        var standardIndent = "  ";
		        var result = "";
		        var className = this.getTypeClassName();
		        result += indent + this.nameId() + "[" + className + "]" + "\n";
		        var properties = this.properties();
		        if (properties && properties.length > 0 && !settings.hideProperties) {
		            result += indent + standardIndent + "Properties:\n";
		            properties.forEach(function (property) {
		                var propertyType = "";
		                var propertyRange = property.range();
		                if (propertyRange instanceof Described) {
		                    propertyType += propertyRange.nameId();
		                }
		                if (propertyRange instanceof AbstractType) {
		                    propertyType += "[";
		                    propertyType += propertyRange.getTypeClassName();
		                    propertyType += "]";
		                }
		                result += indent + standardIndent + standardIndent + property.nameId() + " : " + propertyType + "\n";
		            });
		        }
		        var superTypes = this.superTypes();
		        var filteredSuperTypes = superTypes;
		        if (superTypes && !settings.printStandardSuperclasses) {
		            filteredSuperTypes = _.filter(superTypes, function (superType) {
		                var name = superType instanceof Described ? superType.nameId() : "";
		                var type = superType instanceof AbstractType ? superType.getTypeClassName() : "";
		                return !_this.isStandardSuperclass(name, type);
		            });
		        }
		        if (filteredSuperTypes && filteredSuperTypes.length > 0) {
		            result += indent + standardIndent + "Super types:\n";
		            filteredSuperTypes.forEach(function (superType) {
		                result += superType.printDetails(indent + standardIndent + standardIndent, {
		                    hideProperties: settings.hideSuperTypeProperties,
		                    hideSuperTypeProperties: settings.hideSuperTypeProperties,
		                    printStandardSuperclasses: settings.printStandardSuperclasses
		                });
		            });
		        }
		        return result;
		    };
		    AbstractType.prototype.getTypeClassName = function () {
		        return this.constructor.toString().match(/\w+/g)[1];
		    };
		    AbstractType.prototype.isStandardSuperclass = function (nameId, className) {
		        if (nameId === "TypeDeclaration" && className === "NodeClass")
		            return true;
		        if (nameId === "ObjectTypeDeclaration" && className === "NodeClass")
		            return true;
		        if (nameId === "RAMLLanguageElement" && className === "NodeClass")
		            return true;
		        return false;
		    };
		    /**
		     * Returns example for this type.
		     * Returned example should be tested for being empty and being expandable.
		     */
		    AbstractType.prototype.examples = function () {
		        return [new ExpandableExampleStub()];
		    };
		    /**
		     * Returns whether this type contain genuine user defined type in its hierarchy.
		     * Genuine user defined type is a type user intentionally defined and filled with
		     * properties or facets, or having user-defined name as opposed to a synthetic user-defined type.
		     */
		    AbstractType.prototype.isGenuineUserDefinedType = function () {
		        return false;
		    };
		    /**
		     * Returns nearest genuine user-define type in the hierarchy.
		     * Genuine user defined type is a type user intentionally defined and filled with
		     * properties or facets, or having user-defined name as opposed to a synthetic user-defined type.
		     */
		    AbstractType.prototype.genuineUserDefinedType = function () {
		        return null;
		    };
		    AbstractType.prototype.isUnion = function () {
		        return false;
		    };
		    AbstractType.prototype.union = function () {
		        return null;
		    };
		    AbstractType.prototype.isExternal = function () {
		        return false;
		    };
		    AbstractType.prototype.external = function () {
		        return null;
		    };
		    AbstractType.prototype.isArray = function () {
		        return false;
		    };
		    AbstractType.prototype.array = function () {
		        return null;
		    };
		    AbstractType.prototype.isValueType = function () {
		        return false;
		    };
		    return AbstractType;
		})(Described);
		exports.AbstractType = AbstractType;
		var ValueType = (function (_super) {
		    __extends(ValueType, _super);
		    function ValueType(name, _universe, path, description) {
		        if (_universe === void 0) { _universe = null; }
		        if (path === void 0) { path = ""; }
		        if (description === void 0) { description = ""; }
		        _super.call(this, name, _universe, path);
		    }
		    ValueType.prototype.hasStructure = function () {
		        return false;
		    };
		    ValueType.prototype.hasValueTypeInHierarchy = function () {
		        return true;
		    };
		    ValueType.prototype.isValueType = function () {
		        return true;
		    };
		    ValueType.prototype.isUnionType = function () {
		        return false;
		    };
		    return ValueType;
		})(AbstractType);
		exports.ValueType = ValueType;
		var StructuredType = (function (_super) {
		    __extends(StructuredType, _super);
		    function StructuredType() {
		        _super.apply(this, arguments);
		        this._properties = [];
		    }
		    StructuredType.prototype.hasStructure = function () {
		        return true;
		    };
		    StructuredType.prototype.propertyIndex = function (name) {
		        var props = this.properties();
		        for (var i = 0; i < props.length; i++) {
		            if (props[i].nameId() == name)
		                return i;
		        }
		        return -1;
		    };
		    StructuredType.prototype.addProperty = function (name, range) {
		        return new Property(name).withDomain(this).withRange(range);
		    };
		    StructuredType.prototype.allPropertyIndex = function (name) {
		        var props = this.allProperties();
		        for (var i = 0; i < props.length; i++) {
		            if (props[i].nameId() == name)
		                return i;
		        }
		        return -1;
		    };
		    StructuredType.prototype.properties = function () {
		        return [].concat(this._properties);
		    };
		    StructuredType.prototype.registerProperty = function (p) {
		        if (p.domain() != this) {
		            throw new Error("Should be already owned by this");
		        }
		        if (this._properties.indexOf(p) != -1) {
		            throw new Error("Already included");
		        }
		        this._properties.push(p);
		    };
		    return StructuredType;
		})(AbstractType);
		exports.StructuredType = StructuredType;
		var Property = (function (_super) {
		    __extends(Property, _super);
		    function Property() {
		        _super.apply(this, arguments);
		        this._keyShouldStartFrom = null;
		        this._isRequired = false;
		        this._isMultiValue = false;
		        this._descriminates = false;
		        this._defaultBooleanValue = null;
		        this._defaultIntegerValue = null;
		    }
		    Property.prototype.withMultiValue = function (v) {
		        if (v === void 0) { v = true; }
		        this._isMultiValue = v;
		        return this;
		    };
		    Property.prototype.withDescriminating = function (b) {
		        this._descriminates = b;
		        return this;
		    };
		    Property.prototype.withRequired = function (req) {
		        this._isRequired = req;
		        return this;
		    };
		    Property.prototype.isRequired = function () {
		        return this._isRequired;
		    };
		    Property.prototype.withKeyRestriction = function (keyShouldStartFrom) {
		        this._keyShouldStartFrom = keyShouldStartFrom;
		        return this;
		    };
		    Property.prototype.withDomain = function (d) {
		        this._ownerClass = d;
		        d.registerProperty(this);
		        return this;
		    };
		    Property.prototype.setDefaultVal = function (s) {
		        this._defaultValue = s;
		        return this;
		    };
		    Property.prototype.setDefaultBooleanVal = function (s) {
		        this._defaultBooleanValue = s;
		        return this;
		    };
		    Property.prototype.setDefaultIntegerVal = function (s) {
		        this._defaultIntegerValue = s;
		        return this;
		    };
		    Property.prototype.defaultValue = function () {
		        if (this._defaultValue != null) {
		            return this._defaultValue;
		        }
		        else if (this._defaultBooleanValue != null) {
		            return this._defaultBooleanValue;
		        }
		        else if (this._defaultIntegerValue != null) {
		            return this._defaultIntegerValue;
		        }
		        return null;
		    };
		    Property.prototype.isPrimitive = function () {
		        return false;
		    };
		    Property.prototype.withRange = function (t) {
		        this._nodeRange = t;
		        return this;
		    };
		    Property.prototype.isValueProperty = function () {
		        return this._nodeRange.hasValueTypeInHierarchy();
		    };
		    Property.prototype.enumOptions = function () {
		        if (this._enumOptions && typeof this._enumOptions == 'string') {
		            return [this._enumOptions + ""];
		        }
		        return this._enumOptions;
		    };
		    Property.prototype.keyPrefix = function () {
		        return this._keyShouldStartFrom;
		    };
		    Property.prototype.withEnumOptions = function (op) {
		        this._enumOptions = op;
		        return this;
		    };
		    Property.prototype.withKeyRegexp = function (regexp) {
		        this._keyRegexp = regexp;
		        return this;
		    };
		    Property.prototype.getKeyRegexp = function () {
		        return this._keyRegexp;
		    };
		    Property.prototype.matchKey = function (k) {
		        if (k == null) {
		            return false;
		        }
		        if (this._groupName != null) {
		            return this._groupName == k;
		        }
		        else {
		            if (this._keyShouldStartFrom != null) {
		                if (k.indexOf(this._keyShouldStartFrom) == 0) {
		                    return true;
		                }
		            }
		            if (this._enumOptions) {
		                if (this._enumOptions.indexOf(k) != -1) {
		                    return true;
		                }
		            }
		            if (this.getKeyRegexp()) {
		                try {
		                    if (new RegExp(this.getKeyRegexp()).test(k)) {
		                        return true;
		                    }
		                }
		                catch (Error) {
		                }
		            }
		            return false;
		        }
		    };
		    Property.prototype.getFacetValidator = function () {
		        return this.facetValidator;
		    };
		    Property.prototype.setFacetValidator = function (f) {
		        this.facetValidator = f;
		    };
		    Property.prototype.domain = function () {
		        return this._ownerClass;
		    };
		    Property.prototype.range = function () {
		        return this._nodeRange;
		    };
		    Property.prototype.isMultiValue = function () {
		        if (this.range() && this.range().hasArrayInHierarchy()) {
		            return true;
		        }
		        return this._isMultiValue;
		    };
		    Property.prototype.isDescriminator = function () {
		        return this._descriminates;
		    };
		    return Property;
		})(Described);
		exports.Property = Property;
		var Union = (function (_super) {
		    __extends(Union, _super);
		    function Union() {
		        _super.apply(this, arguments);
		    }
		    Union.prototype.key = function () {
		        return null;
		    };
		    Union.prototype.leftType = function () {
		        return this.left;
		    };
		    Union.prototype.rightType = function () {
		        return this.right;
		    };
		    Union.prototype.isUserDefined = function () {
		        return true;
		    };
		    Union.prototype.unionInHierarchy = function () {
		        return this;
		    };
		    Union.prototype.union = function () {
		        return this;
		    };
		    Union.prototype.hasUnionInHierarchy = function () {
		        return true;
		    };
		    Union.prototype.isUnion = function () {
		        return true;
		    };
		    Union.prototype.hasArrayInHierarchy = function () {
		        if (this.left && this.right) {
		            return this.left.hasArrayInHierarchy() || this.right.hasArrayInHierarchy();
		        }
		        if (this.left) {
		            return this.left.hasArrayInHierarchy();
		        }
		        if (this.right) {
		            return this.right.hasArrayInHierarchy();
		        }
		    };
		    return Union;
		})(AbstractType);
		exports.Union = Union;
		var Array = (function (_super) {
		    __extends(Array, _super);
		    function Array() {
		        _super.apply(this, arguments);
		    }
		    Array.prototype.hasArrayInHierarchy = function () {
		        return true;
		    };
		    Array.prototype.isArray = function () {
		        return true;
		    };
		    Array.prototype.arrayInHierarchy = function () {
		        return this;
		    };
		    Array.prototype.array = function () {
		        return this;
		    };
		    Array.prototype.isUserDefined = function () {
		        return true;
		    };
		    Array.prototype.componentType = function () {
		        return this.component;
		    };
		    Array.prototype.key = function () {
		        return null;
		    };
		    return Array;
		})(AbstractType);
		exports.Array = Array;
		var ExternalType = (function (_super) {
		    __extends(ExternalType, _super);
		    function ExternalType() {
		        _super.apply(this, arguments);
		    }
		    ExternalType.prototype.externalInHierarchy = function () {
		        return this;
		    };
		    ExternalType.prototype.typeId = function () {
		        return this.schemaString;
		    };
		    ExternalType.prototype.schema = function () {
		        return this.schemaString;
		    };
		    ExternalType.prototype.isUserDefined = function () {
		        return true;
		    };
		    ExternalType.prototype.hasExternalInHierarchy = function () {
		        return true;
		    };
		    ExternalType.prototype.isExternal = function () {
		        return true;
		    };
		    ExternalType.prototype.external = function () {
		        return this;
		    };
		    return ExternalType;
		})(StructuredType);
		exports.ExternalType = ExternalType;
		var ExpandableExampleStub = (function () {
		    function ExpandableExampleStub() {
		    }
		    ExpandableExampleStub.prototype.isEmpty = function () {
		        return true;
		    };
		    ExpandableExampleStub.prototype.isJSONString = function () {
		        return false;
		    };
		    ExpandableExampleStub.prototype.isXMLString = function () {
		        return false;
		    };
		    ExpandableExampleStub.prototype.isYAML = function () {
		        return false;
		    };
		    ExpandableExampleStub.prototype.asString = function () {
		        return "";
		    };
		    ExpandableExampleStub.prototype.asJSON = function () {
		        return null;
		    };
		    ExpandableExampleStub.prototype.original = function () {
		        return null;
		    };
		    ExpandableExampleStub.prototype.expandAsString = function () {
		        return null;
		    };
		    ExpandableExampleStub.prototype.expandAsJSON = function () {
		        return null;
		    };
		    return ExpandableExampleStub;
		})();
		exports.ExpandableExampleStub = ExpandableExampleStub;


	/***/ },
	/* 64 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var hl = __webpack_require__(2);
		var _ = __webpack_require__(4);
		var linter = __webpack_require__(55);
		var wrapperHelper = __webpack_require__(65);
		function escapeUri(u) {
		    var ss = "";
		    var level = 0;
		    for (var i = 0; i < u.length; i++) {
		        var c = u.charAt(i);
		        if (level == 0) {
		            ss = ss + c;
		        }
		        if (c == '{') {
		            level++;
		        }
		        if (c == '}') {
		            level--;
		        }
		    }
		    return ss;
		}
		var OverloadingValidator = (function () {
		    function OverloadingValidator() {
		        this.holder = {};
		        this.conflicting = {};
		    }
		    OverloadingValidator.prototype.validateApi = function (q, v) {
		        var _this = this;
		        q.resources().forEach(function (x) {
		            _this.acceptResource(x);
		            x.resources().forEach(function (y) { return _this.acceptResource(y); });
		        });
		        for (var c in this.conflicting) {
		            var ms = this.conflicting[c];
		            //now we should layout parameters by items
		            var overmapQuery = {};
		            var overmapHeaders = {};
		            var pushed = [];
		            ms.forEach(function (m) {
		                m.queryParameters().forEach(function (q) {
		                    var key = q.name();
		                    if (!q.required()) {
		                        return;
		                    }
		                    var set = overmapQuery[key];
		                    if (!set) {
		                        set = [];
		                        overmapQuery[key] = set;
		                    }
		                    set.push(m);
		                    pushed.push(m);
		                });
		                m.headers().forEach(function (q) {
		                    var key = q.name();
		                    if (!q.required()) {
		                        return;
		                    }
		                    var set = overmapHeaders[key];
		                    if (!set) {
		                        set = [];
		                        overmapHeaders[key] = set;
		                    }
		                    set.push(m);
		                    pushed.push(m);
		                });
		            });
		            var notPushed = ms.filter(function (x) { return !_.find(pushed, function (y) { return y == x; }); });
		            if (notPushed.length > 0) {
		                notPushed.forEach(function (m) {
		                    v.accept(linter.createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, "method overloading is ambiguous", m.highLevel(), true));
		                });
		            }
		            for (var key in overmapQuery) {
		                var cm = overmapQuery[key];
		                if (cm.length > 1) {
		                    var over = {};
		                    var pushed2 = [];
		                    cm.forEach(function (m) {
		                        var pr = _.find(m.queryParameters(), function (x) { return x.name() == key; });
		                        if (pr['enum']) {
		                            var ev = pr['enum']();
		                            if (ev && ev.length > 0) {
		                                ev.forEach(function (value) {
		                                    var t = over[value];
		                                    if (!t) {
		                                        t = [];
		                                        over[value] = t;
		                                    }
		                                    t.push(m);
		                                    pushed2.push(m);
		                                });
		                            }
		                        }
		                    });
		                    var notPushed2 = cm.filter(function (x) { return !_.find(pushed2, function (y) { return y == x; }); });
		                    if (notPushed2.length > 0) {
		                        notPushed2.forEach(function (m) {
		                            v.accept(linter.createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, "method overloading is ambiguous no domain restrictions", m.highLevel(), true));
		                        });
		                    }
		                    for (var k in over) {
		                        var rs = over[k];
		                        if (rs.length > 1) {
		                            rs.forEach(function (m) { return v.accept(linter.createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, "method overloading is ambiguous ( enum value " + k + ")", m.highLevel(), true)); });
		                        }
		                    }
		                }
		            }
		        }
		    };
		    OverloadingValidator.prototype.acceptResource = function (x) {
		        var _this = this;
		        x.methods().forEach(function (m) {
		            _this.acceptMethod(x, m);
		        });
		    };
		    OverloadingValidator.prototype.acceptMethod = function (x, m) {
		        var uri = escapeUri(wrapperHelper.absoluteUri(x)) + m.method();
		        var pos = this.holder[uri];
		        if (!pos) {
		            pos = [];
		            this.holder[uri] = pos;
		        }
		        pos.push(m);
		        if (pos.length > 1) {
		            this.conflicting[uri] = pos;
		        }
		        //wrapperHelper.absoluteUri(m.parent().)
		    };
		    return OverloadingValidator;
		})();
		module.exports = OverloadingValidator;


	/***/ },
	/* 65 */
	/***/ function(module, exports, __webpack_require__) {

		var RamlWrapper = __webpack_require__(1);
		var ramlPathMatch = __webpack_require__(66);
		var hl = __webpack_require__(2);
		var hlimpl = __webpack_require__(5);
		var linter = __webpack_require__(55);
		var universes = __webpack_require__(54);
		var Opt = __webpack_require__(12);
		var util = __webpack_require__(11);
		var typeexpression = __webpack_require__(50);
		var expander = __webpack_require__(73);
		var lowLevelProxy = __webpack_require__(6);
		var search = __webpack_require__(53);
		var ll = __webpack_require__(15);
		var path = __webpack_require__(16);
		var ramlservices = __webpack_require__(49);
		function resolveType(p) {
		    var tpe = typeexpression.typeFromNode(p.highLevel());
		    return tpe.getAdapter(ramlservices.RAMLService).toRuntime();
		}
		exports.resolveType = resolveType;
		//__$helperMethod__ Runtime representation of type represented by this AST node
		function runtimeType(p) {
		    var tpe = typeexpression.typeFromNode(p.highLevel());
		    return tpe.getAdapter(ramlservices.RAMLService).toRuntime();
		}
		exports.runtimeType = runtimeType;
		function load(pth) {
		    var m = new ll.Project(path.dirname(pth));
		    var unit = m.unit(path.basename(pth));
		    if (unit) {
		        if (unit.isRAMLUnit()) {
		            return hl.fromUnit(unit).wrapperNode();
		        }
		    }
		    return null;
		}
		exports.load = load;
		//__$helperMethod__ Path relative to API root
		function completeRelativeUri(res) {
		    var uri = '';
		    var parent = res;
		    do {
		        res = parent; //(parent instanceof RamlWrapper.ResourceImpl) ? <RamlWrapper.Resource>parent : null;
		        uri = res.relativeUri().value() + uri;
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe10.Resource.name);
		    return uri;
		}
		exports.completeRelativeUri = completeRelativeUri;
		//__$helperMethod__ Equivalent API with traits and resource types expanded __$meta__={"name":"expand"}
		function expandTraitsAndResourceTypes(api) {
		    var lowLevelNode = api.highLevel().lowLevel();
		    if (lowLevelNode instanceof lowLevelProxy.LowLevelProxyNode) {
		        return api;
		    }
		    return expander.expandTraitsAndResourceTypes(api);
		}
		exports.expandTraitsAndResourceTypes = expandTraitsAndResourceTypes;
		//__$helperMethod__ baseUri of owning Api concatenated with completeRelativeUri
		function absoluteUri(res) {
		    var uri = '';
		    var parent = res;
		    do {
		        res = parent; //(parent instanceof RamlWrapper.ResourceImpl) ? <RamlWrapper.Resource>parent : null;
		        uri = res.relativeUri().value() + uri;
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe10.Resource.name);
		    uri = uri.replace(/\/\//g, '/');
		    var buri = parent.baseUri();
		    var base = buri ? buri.value() : "";
		    base = base ? base : '';
		    if (util.stringEndsWith(base, '/')) {
		        uri = uri.substring(1);
		    }
		    uri = base + uri;
		    return uri;
		}
		exports.absoluteUri = absoluteUri;
		//__$helperMethod__ validate an instance against type
		function validateInstance(res, value) {
		    var tv = new linter.TypeValidator(res.highLevel());
		    var errors = [];
		    var vl = {
		        begin: function () {
		        },
		        accept: function (issue) {
		            errors.push(issue.message);
		        },
		        end: function () {
		        }
		    };
		    tv.validate(value, res.runtimeType(), vl, true);
		    return errors;
		}
		exports.validateInstance = validateInstance;
		function qName(c) {
		    return hlimpl.qName(c.highLevel(), c.highLevel().root());
		}
		exports.qName = qName;
		//__$helperMethod__ Retrieve all traits including those defined in libraries
		function allTraits(a) {
		    return search.globalDeclarations(a.highLevel()).filter(function (x) { return x.definition().key() == universes.Universe08.Trait || x.definition().key() == universes.Universe10.Trait; }).map(function (x) { return x.wrapperNode(); });
		}
		exports.allTraits = allTraits;
		//__$helperMethod__ Retrieve all resource types including those defined in libraries
		function allResourceTypes(a) {
		    return search.globalDeclarations(a.highLevel()).filter(function (x) { return x.definition().key() == universes.Universe08.ResourceType || x.definition().key() == universes.Universe10.ResourceType; }).map(function (x) { return x.wrapperNode(); });
		}
		exports.allResourceTypes = allResourceTypes;
		function relativeUriSegments(res) {
		    var result = [];
		    var parent = res;
		    do {
		        res = parent; //(parent instanceof RamlWrapper.ResourceImpl) ? <RamlWrapper.Resource>parent : null;
		        result.push(res.relativeUri().value());
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe10.Resource.name);
		    return result.reverse();
		}
		exports.relativeUriSegments = relativeUriSegments;
		//__$helperMethod__ For methods of Resources returns parent resource. For methods of ResourceTypes returns null.
		function parentResource(method) {
		    if (method.parent() instanceof RamlWrapper.ResourceImpl) {
		        return method.parent();
		    }
		    return null;
		}
		exports.parentResource = parentResource;
		//__$helperMethod__ Parent resource for non top level resources __$meta__={"name":"parentResource"}
		function parent(resource) {
		    var parent = resource.parent();
		    if (parent.definition().key().name == universes.Universe10.Resource.name) {
		        return parent;
		    }
		    return null;
		}
		exports.parent = parent;
		//__$helperMethod__ Get child resource by its relative path
		function childResource(container, relPath) {
		    if (container == null) {
		        return null;
		    }
		    var resources = container.resources();
		    if (!resources) {
		        return null;
		    }
		    resources = resources.filter(function (x) { return x.relativeUri().value() == relPath; });
		    if (resources.length == 0) {
		        return null;
		    }
		    return resources[0];
		}
		exports.childResource = childResource;
		function getResource(container, path) {
		    if (!container) {
		        return null;
		    }
		    var res = null;
		    for (var i = 0; i < path.length; i++) {
		        res = childResource(container, path[i]);
		        if (!res) {
		            return null;
		        }
		        container = res;
		    }
		    return res;
		}
		exports.getResource = getResource;
		//__$helperMethod__ Get child method by its name
		function childMethod(resource, method) {
		    if (!resource) {
		        return null;
		    }
		    return resource.methods().filter(function (x) { return x.method() == method; });
		}
		exports.childMethod = childMethod;
		function getMethod(container, path, method) {
		    var resource = getResource(container, path);
		    if (!resource) {
		        return null;
		    }
		    return childMethod(resource, method);
		}
		exports.getMethod = getMethod;
		function isApi(obj) {
		    return obj.definition().key().name == universes.Universe10.Api.name;
		}
		;
		//__$helperMethod__ Api owning the resource as a sibling
		function ownerApi(method) {
		    var obj = method;
		    while (!isApi(obj)) {
		        obj = obj.parent();
		    }
		    return obj;
		}
		exports.ownerApi = ownerApi;
		//__$helperMethod__
		// For methods of Resources: `{parent Resource relative path} {methodName}`.
		// For methods of ResourceTypes: `{parent ResourceType name} {methodName}`.
		// For other methods throws Exception.
		function methodId(method) {
		    var parent = method.parent();
		    if (parent instanceof RamlWrapper.ResourceImpl) {
		        return completeRelativeUri(parent) + ' ' + method.method().toLowerCase();
		    }
		    else if (parent instanceof RamlWrapper.ResourceTypeImpl) {
		        return parent.name() + ' ' + method.method().toLowerCase();
		    }
		    throw new Error("Method is supposed to be owned by Resource or ResourceType.\nHere the method is owned by " + method.definition().key().name);
		}
		exports.methodId = methodId;
		//__$helperMethod__ true for codes < 400 and false otherwise
		function isOkRange(response) {
		    var str = response.code().value();
		    var err = ramlservices.validateResponseString(str);
		    if (err != null) {
		        return false;
		    }
		    try {
		        if (parseInt(str.charAt(0)) < 4) {
		            return true;
		        }
		    }
		    catch (e) {
		    }
		    return false;
		}
		exports.isOkRange = isOkRange;
		//__$helperMethod__  Retrieve all resources of the Api
		function allResources(api) {
		    var resources = [];
		    var visitor = function (res) {
		        resources.push(res);
		        res.resources().forEach(function (x) { return visitor(x); });
		    };
		    api.resources().forEach(function (x) { return visitor(x); });
		    return resources;
		}
		exports.allResources = allResources;
		function matchUri(apiRootRelativeUri, resource) {
		    var allParameters = {};
		    while (resource != null) {
		        uriParameters(resource).forEach(function (x) { return allParameters[x.name()] = new ParamWrapper(x); });
		        resource = parent(resource);
		    }
		    var result = ramlPathMatch(completeRelativeUri(resource), allParameters, {})(apiRootRelativeUri);
		    if (result) {
		        return new Opt(Object.keys(result.params).map(function (x) { return new ParamValue(x, result['params'][x]); }));
		    }
		    return Opt.empty();
		}
		exports.matchUri = matchUri;
		var schemaContentChars = ['{', '<'];
		function schema(body, api) {
		    var schemaNode = body.schema();
		    if (!schemaNode) {
		        return Opt.empty();
		    }
		    var schemaString = schemaNode;
		    var isContent = false;
		    schemaContentChars.forEach(function (x) {
		        try {
		            isContent = isContent || schemaString.indexOf(x) >= 0;
		        }
		        catch (e) {
		        }
		    });
		    var schDef;
		    if (isContent) {
		        schDef = new SchemaDef(schemaString);
		    }
		    else {
		        var globalSchemes = api.schemas().filter(function (x) { return x.key() == schemaString; });
		        if (globalSchemes.length > 0) {
		            schDef = new SchemaDef(globalSchemes[0].value().value(), globalSchemes[0].key());
		        }
		        else {
		            return Opt.empty();
		        }
		    }
		    return new Opt(schDef);
		}
		exports.schema = schema;
		/**
		 * __$helperMethod__ Retrieve an ordered list of all uri parameters including those which are not described in the `uriParameters` node.
		 * Consider a fragment of RAML specification:
		 * ```yaml
		 * /resource/{objectId}/{propertyId}:
		 *   uriParameters:
		 *     objectId:
		 * ```
		 * Here `propertyId` uri parameter is not described in the `uriParameters` node.
		 * Thus, it is not among Resource.uriParameters(), but it is among Resource.allUriParameters().
		 * __$meta__={"name":"allUriParameters"}
		 **/
		function uriParameters(resource) {
		    var uri = resource.relativeUri().value();
		    var params = resource.uriParameters();
		    var propName = universes.Universe10.ResourceBase.properties.uriParameters.name;
		    return extractParams(params, uri, resource, propName);
		}
		exports.uriParameters = uriParameters;
		/**__$helperMethod__
		 * Retrieve an ordered list of all base uri parameters regardless of whether they are described in `baseUriParameters` or not
		 * Consider a fragment of RAML specification:
		 * ```yaml
		 * version: v1
		 * baseUri: https://{organization}.example.com/{version}/{service}
		 * baseUriParameters:
		 *   service:
		 * ```
		 * Here `version` and `organization` are base uri parameters which are not described in the `baseUriParameters` node.
		 * Thus, they are not among `Api.baseUriParameters()`, but they are among `Api.allBaseUriParameters()`.
		 * __$meta__={"name":"allBaseUriParameters"}
		 **/
		function baseUriParameters(api) {
		    var uri = api.baseUri() ? api.baseUri().value() : '';
		    var params = api.baseUriParameters();
		    var propName = universes.Universe10.Api.properties.baseUriParameters.name;
		    return extractParams(params, uri, api, propName);
		}
		exports.baseUriParameters = baseUriParameters;
		/**__$helperMethod__
		 * Retrieve an ordered list of all absolute uri parameters. Returns a union of `Api.allBaseUriParameters()`
		 * for `Api` owning the `Resource` and `Resource.allUriParameters()`.
		 */
		function absoluteUriParameters(res) {
		    var uriParamsPropName = universes.Universe10.ResourceBase.properties.uriParameters.name;
		    var baseUriParamsPropName = universes.Universe10.Api.properties.baseUriParameters.name;
		    var params = [];
		    var parent = res;
		    do {
		        res = parent;
		        var uri = res.relativeUri().value();
		        var uriParams = res.uriParameters();
		        params = extractParams(uriParams, uri, res, uriParamsPropName).concat(params);
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe10.Resource.name);
		    var api = parent;
		    var baseUri = api.baseUri().value();
		    var baseUriParams = api.baseUriParameters();
		    params = extractParams(baseUriParams, baseUri, api, baseUriParamsPropName).concat(params);
		    return params;
		}
		exports.absoluteUriParameters = absoluteUriParameters;
		/**
		 * __$helperMethod__ Protocols used by the API. Returns the `protocols` property value if it is specified.
		 * Otherwise, returns protocol, specified in the base URI.
		 **/
		function allProtocols(api) {
		    var result = api.protocols();
		    if (result.length != 0) {
		        return result;
		    }
		    var baseUriAttr = api.baseUri();
		    if (baseUriAttr) {
		        var baseUri = baseUriAttr.value();
		        if (baseUri) {
		            var ind = baseUri.indexOf('://');
		            if (ind >= 0) {
		                result = [baseUri.substring(0, ind)];
		            }
		        }
		    }
		    return result;
		}
		exports.allProtocols = allProtocols;
		/**
		 * __$helperMethod__ Returns security schemes, resource or method is secured with. If no security schemes are set at resource or method level,
		 * returns schemes defined with `securedBy` at API level.
		 */
		function allSecuredBy(resourceOrMethod) {
		    var currentSecuredBy = resourceOrMethod.securedBy();
		    if (currentSecuredBy && currentSecuredBy.length > 0) {
		        return currentSecuredBy;
		    }
		    //instanceof, but have to avoid direct usage of instanceof in JS.
		    if (resourceOrMethod.highLevel().definition().key() == universes.Universe10.Method) {
		        var resource = resourceOrMethod.parentResource();
		        if (resource && resource.securedBy() && resource.securedBy().length > 0) {
		            return resource.securedBy();
		        }
		    }
		    return resourceOrMethod.ownerApi().securedBy();
		}
		exports.allSecuredBy = allSecuredBy;
		/**
		 * __$helperMethod__ Returns the name of security scheme, this reference refers to.
		 */
		function securitySchemeName(schemeReference) {
		    var highLevel = schemeReference.highLevel();
		    if (!highLevel)
		        return "";
		    var attributeValue = highLevel.value();
		    if (!attributeValue)
		        return "";
		    return attributeValue.toString();
		}
		exports.securitySchemeName = securitySchemeName;
		/**
		 * __$helperMethod__ Returns AST node of security scheme, this reference refers to, or null.
		 */
		function securityScheme(schemeReference) {
		    var highLevel = schemeReference.highLevel();
		    if (!highLevel)
		        return null;
		    var declaration = search.findDeclarationByNode(highLevel, 0 /* VALUE_COMPLETION */);
		    if (!declaration)
		        return null;
		    if (!declaration.getKind || declaration.getKind() != 1 /* NODE */) {
		        return null;
		    }
		    var result = declaration.wrapperNode();
		    if (!(result instanceof RamlWrapper.AbstractSecuritySchemeImpl)) {
		        //I do not see how to avoid instanceof here
		        return null;
		    }
		    return result;
		}
		exports.securityScheme = securityScheme;
		//__$helperMethod__ Returns RAML version. "RAML10" string is returned for RAML 1.0. "RAML08" string is returned for RAML 0.8.
		function RAMLVersion(api) {
		    return api.highLevel().definition().universe().version();
		}
		exports.RAMLVersion = RAMLVersion;
		//__$helperMethod__ Returns schema content for the cases when schema is inlined, when schema is included, and when schema is a reference.
		function schemaContent(typeDeclaration) {
		    var schemaString = typeDeclaration.schema();
		    if (!schemaString) {
		        return null;
		    }
		    var schemaAttribute = typeDeclaration.highLevel().attr(universes.Universe10.TypeDeclaration.properties.schema.name);
		    if (!schemaAttribute) {
		        return schemaString;
		    }
		    var declaration = search.findDeclarationByNode(schemaAttribute, 0 /* VALUE_COMPLETION */);
		    if (!declaration)
		        return schemaString;
		    if (!declaration.getKind || declaration.getKind() != 1 /* NODE */) {
		        return schemaString;
		    }
		    //we found the schema declaration and should get its contents
		    if (declaration.definition().key() != universes.Universe10.GlobalSchema) {
		        return null;
		    }
		    var valueAttribute = declaration.attr(universes.Universe10.GlobalSchema.properties.value.name);
		    if (valueAttribute == null) {
		        return null;
		    }
		    return valueAttribute.value();
		}
		exports.schemaContent = schemaContent;
		function extractParams(params, uri, owner, propName) {
		    var ownerHl = owner.highLevel();
		    var prop = ownerHl.definition().property(propName);
		    if (!uri) {
		        return [];
		    }
		    var describedParams = {};
		    params.forEach(function (x) {
		        var arr = describedParams[x.name()];
		        if (!arr) {
		            arr = [];
		            describedParams[x.name()] = arr;
		        }
		        arr.push(x);
		    });
		    var allParams = [];
		    var prev = 0;
		    var mentionedParams = {};
		    for (var i = uri.indexOf('{'); i >= 0; i = uri.indexOf('{', prev)) {
		        prev = uri.indexOf('}', ++i);
		        var paramName = uri.substring(i, prev);
		        mentionedParams[paramName] = true;
		        if (describedParams[paramName]) {
		            describedParams[paramName].forEach(function (x) { return allParams.push(x); });
		        }
		        else {
		            var uriParameter = new RamlWrapper.TypeDeclarationImpl(paramName);
		            uriParameter.setName(paramName);
		            var hlNode = uriParameter.highLevel();
		            hlNode.setParent(ownerHl);
		            hlNode.patchProp(prop);
		            allParams.push(uriParameter);
		        }
		    }
		    Object.keys(describedParams).filter(function (x) { return !mentionedParams[x]; }).forEach(function (x) { return describedParams[x].forEach(function (y) { return allParams.push(y); }); });
		    return allParams;
		}
		;
		var SchemaDef = (function () {
		    function SchemaDef(_content, _name) {
		        this._content = _content;
		        this._name = _name;
		    }
		    SchemaDef.prototype.name = function () {
		        return this._name;
		    };
		    SchemaDef.prototype.content = function () {
		        return this._content;
		    };
		    return SchemaDef;
		})();
		exports.SchemaDef = SchemaDef;
		var ParamValue = (function () {
		    function ParamValue(key, value) {
		        this.key = key;
		        this.value = value;
		    }
		    return ParamValue;
		})();
		exports.ParamValue = ParamValue;
		var ParamWrapper = (function () {
		    function ParamWrapper(_param) {
		        this._param = _param;
		        this.description = _param.description() ? _param.description().value() : this.description;
		        this.displayName = _param.displayName();
		        //        this.enum = _param.enum();
		        this.type = _param.type().length > 0 ? _param.type()[0] : "string";
		        this.example = _param.example();
		        this.repeat = _param.repeat();
		        this.required = _param.required();
		        this.default = _param.default();
		    }
		    return ParamWrapper;
		})();


	/***/ },
	/* 66 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var ramlSanitize = __webpack_require__(67);
		var ramlValidate = __webpack_require__(68);
		var REGEXP_MATCH = {
		    number: '[-+]?\\d+(?:\\.\\d+)?',
		    integer: '[-+]?\\d+',
		    date: '(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \\d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d{4} (?:[0-1]\\d|2[0-3]):[0-5]\\d:[0-5]\\d GMT',
		    boolean: '(?:true|false)'
		};
		var ESCAPE_CHARACTERS = /([.*+?=^!:${}()|[\]\/\\])/g;
		var REGEXP_REPLACE = new RegExp([
		    '([.\\/])?\\{([^}]+)\\}',
		    ESCAPE_CHARACTERS.source
		].join('|'), 'g');
		function toRegExp(path, parameters, keys, options) {
		    var end = options.end !== false;
		    var strict = options.strict;
		    var flags = '';
		    if (!options.sensitive) {
		        flags += 'i';
		    }
		    var route = path.replace(REGEXP_REPLACE, function (match, prefix, key, escape) {
		        if (escape) {
		            return '\\' + escape;
		        }
		        // Push the current key into the keys array.
		        keys.push({
		            name: key,
		            prefix: prefix || '/'
		        });
		        prefix = prefix ? '\\' + prefix : '';
		        // TODO: Support an array of parameters.
		        var param = parameters[key];
		        var capture = param && REGEXP_MATCH[param.type] || '[^' + (prefix || '\\/') + ']+';
		        var optional = param && param.required === false;
		        if (Array.isArray(param.enum) && param.enum.length) {
		            capture = '(?:' + param.enum.map(function (value) {
		                return String(value).replace(ESCAPE_CHARACTERS, '\\$1');
		            }).join('|') + ')';
		        }
		        return prefix + '(' + capture + ')' + (optional ? '?' : '');
		    });
		    var endsWithSlash = path.charAt(path.length - 1) === '/';
		    // In non-strict mode we allow a slash at the end of match. If the path to
		    // match already ends with a slash, we remove it for consistency. The slash
		    // is valid at the end of a path match, not in the middle. This is important
		    // in non-ending mode, where "/test/" shouldn't match "/test//route".
		    if (!strict) {
		        route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?';
		    }
		    if (end) {
		        route += '$';
		    }
		    else {
		        // In non-ending mode, we need the capturing groups to match as much as
		        // possible by using a positive lookahead to the end or next path segment.
		        route += strict && endsWithSlash ? '' : '(?=\\/|$)';
		    }
		    return new RegExp('^' + route + (end ? '$' : ''), flags);
		}
		function decodeParam(param) {
		    try {
		        return decodeURIComponent(param);
		    }
		    catch (_) {
		        var err = new Error('Failed to decode param "' + param + '"');
		        err.status = 400;
		        throw err;
		    }
		}
		function ramlPathMatch(path, parameters, options) {
		    options = options || {};
		    if (path === '/' && options.end === false) {
		        return truth;
		    }
		    parameters = parameters || {};
		    var keys = [];
		    var re = toRegExp(path, parameters, keys, options);
		    var sanitize = ramlSanitize()(parameters);
		    var validate = ramlValidate()(parameters);
		    return function (pathname) {
		        var m = re.exec(pathname);
		        if (!m) {
		            return false;
		        }
		        if (parameters['mediaTypeExtension']) {
		            if (m.length > 1 && !m[m.length - 1]) {
		                var beforeLast = m[m.length - 2];
		                var ind = beforeLast.lastIndexOf('.');
		                if (ind >= 0) {
		                    m[m.length - 2] = beforeLast.substring(0, ind);
		                    m[m.length - 1] = beforeLast.substring(ind);
		                }
		            }
		        }
		        var path = m[0];
		        var params = {};
		        for (var i = 1; i < m.length; i++) {
		            var key = keys[i - 1];
		            var param = m[i];
		            params[key.name] = param == null ? param : decodeParam(param);
		        }
		        params = sanitize(params);
		        if (!validate(params).valid) {
		            return false;
		        }
		        return {
		            path: path,
		            params: params
		        };
		    };
		}
		function truth(path) {
		    return { path: '', params: {} };
		}
		module.exports = ramlPathMatch;


	/***/ },
	/* 67 */
	/***/ function(module, exports) {

		/// <reference path="../../typings/main.d.ts" />
		function isEmpty(value) {
		    return value == null;
		}
		function toString(value) {
		    return isEmpty(value) ? '' : String(value);
		}
		function toBoolean(value) {
		    return [0, false, '', '0', 'false'].indexOf(value) === -1;
		}
		function toNumber(value) {
		    return isFinite(value) ? Number(value) : null;
		}
		function toInteger(value) {
		    return value % 1 === 0 ? Number(value) : null;
		}
		function toDate(value) {
		    return !isNaN(Date.parse(value)) ? new Date(value) : null;
		}
		function toSanitization(parameter, rules, types) {
		    var parameters = Array.isArray(parameter) ? parameter : [parameter];
		    var sanitizations = parameters.map(function (parameter) {
		        var fns = [];
		        var typeSanitization = types[parameter.type];
		        if (typeof typeSanitization === 'function') {
		            fns.push(typeSanitization);
		        }
		        Object.keys(parameter).filter(function (key) {
		            return key !== 'type' && key !== 'repeat' && key !== 'default';
		        }).forEach(function (key) {
		            var fn = rules[key];
		            if (typeof fn === 'function') {
		                fns.push(fn(parameter[key], key));
		            }
		        });
		        function sanitize(value, key, src) {
		            for (var i = 0; i < fns.length; i++) {
		                var fn = fns[i];
		                var value = fn(value, key, src);
		                if (value != null) {
		                    return value;
		                }
		            }
		            return null;
		        }
		        return function (value, key, src) {
		            if (isEmpty(value)) {
		                if (parameter.default != null) {
		                    return sanitize(parameter.default, key, src);
		                }
		                return parameter.repeat && !parameter.required ? [] : value;
		            }
		            if (parameter.repeat) {
		                var values = Array.isArray(value) ? value : [value];
		                values = values.map(function (value) {
		                    return sanitize(value, key, src);
		                });
		                return values.some(isEmpty) ? null : value;
		            }
		            if (Array.isArray(value)) {
		                if (value.length > 1) {
		                    return null;
		                }
		                value = value[0];
		            }
		            return sanitize(value, key, src);
		        };
		    });
		    return function (value, key, src) {
		        for (var i = 0; i < sanitizations.length; i++) {
		            var sanitization = sanitizations[i];
		            var result = sanitization(value, key, src);
		            if (result != null) {
		                return result;
		            }
		        }
		        return value;
		    };
		}
		function sanitize() {
		    var RULES = {};
		    var TYPES = {
		        string: toString,
		        number: toNumber,
		        integer: toInteger,
		        boolean: toBoolean,
		        date: toDate
		    };
		    function rule(parameter) {
		        return toSanitization(parameter, RULES, TYPES);
		    }
		    var sanitize = function (parameterMap) {
		        if (!parameterMap) {
		            return function () {
		                return {};
		            };
		        }
		        var sanitizations = {};
		        Object.keys(parameterMap).forEach(function (key) {
		            sanitizations[key] = sanitize.rule(parameterMap[key]);
		        });
		        return function (src) {
		            src = src || {};
		            var dest = {};
		            // Iterate the sanitized parameters to get a clean model.
		            Object.keys(sanitizations).forEach(function (key) {
		                var value = src[key];
		                var fn = sanitizations[key];
		                if (Object.prototype.hasOwnProperty.call(src, key)) {
		                    dest[key] = fn(value, key, src);
		                }
		            });
		            return dest;
		        };
		    };
		    var s;
		    s = sanitize;
		    s.rule = rule;
		    s.TYPES = TYPES;
		    s.RULES = RULES;
		    return s;
		}
		module.exports = sanitize;


	/***/ },
	/* 68 */
	/***/ function(module, exports, __webpack_require__) {

		/* WEBPACK VAR INJECTION */(function(Buffer) {/// <reference path="../../typings/main.d.ts" />
		var _toString = Object.prototype.toString;
		function isDateType(check) {
		    return _toString.call(check) === '[object Date]' && !isNaN(check.getTime());
		}
		function isBooleanType(check) {
		    return typeof check === 'boolean';
		}
		function isStringType(check) {
		    return typeof check === 'string';
		}
		function isIntegerType(check) {
		    return typeof check === 'number' && check % 1 === 0;
		}
		function isNumberType(check) {
		    return typeof check === 'number' && isFinite(check);
		}
		function isMinimum(min) {
		    return function (check) {
		        return check >= min;
		    };
		}
		function isMaximum(max) {
		    return function (check) {
		        return check <= max;
		    };
		}
		function isMinimumLength(min) {
		    return function (check) {
		        return Buffer.byteLength(check) >= min;
		    };
		}
		function isMaximumLength(max) {
		    return function (check) {
		        return Buffer.byteLength(check) <= max;
		    };
		}
		function isEnum(values) {
		    if (values && values.length != 0) {
		        return function (check) {
		            return values.indexOf(check) > -1;
		        };
		    }
		    else {
		        return function (check) {
		            return true;
		        };
		    }
		}
		function isPattern(pattern) {
		    var regexp = (typeof pattern === 'string') ? new RegExp(pattern) : pattern;
		    return regexp.test.bind(regexp);
		}
		function toValidationResult(valid, key, value, rule, attr) {
		    return {
		        valid: valid,
		        rule: rule,
		        attr: attr,
		        value: value,
		        key: key
		    };
		}
		function toValidationFunction(parameter, rules) {
		    var validations = [];
		    Object.keys(parameter).forEach(function (name) {
		        var rule = rules[name];
		        if (!rule) {
		            return;
		        }
		        var value = parameter[name];
		        validations.push([name, rule(value, name), value]);
		    });
		    return function (value, key, src) {
		        for (var i = 0; i < validations.length; i++) {
		            var validation = validations[i];
		            var name = validation[0];
		            var fn = validation[1];
		            var attr = validation[2];
		            var valid = fn(value, key, src);
		            if (!valid) {
		                return toValidationResult(false, key, value, name, attr);
		            }
		        }
		        return toValidationResult(true, key, value);
		    };
		}
		function toValidation(parameter, rules, types) {
		    var parameters = Array.isArray(parameter) ? parameter : [parameter];
		    var isOptional = !parameters.length;
		    var simpleValidations = [];
		    var repeatValidations = [];
		    parameters.forEach(function (parameter) {
		        var validation = [parameter.type || 'string', toValidationFunction(parameter, rules)];
		        if (!parameter.required) {
		            isOptional = true;
		        }
		        if (parameter.repeat) {
		            repeatValidations.push(validation);
		        }
		        else {
		            simpleValidations.push(validation);
		        }
		    });
		    return function (value, key, src) {
		        if (value == null) {
		            return toValidationResult(isOptional, key, value, 'required', !isOptional);
		        }
		        var isArray = Array.isArray(value);
		        var values = isArray ? value : [value];
		        var validations = isArray ? repeatValidations : simpleValidations;
		        if (!validations.length) {
		            return toValidationResult(false, key, value, 'repeat', !isArray);
		        }
		        var response = null;
		        var originalValue = value;
		        validations.some(function (validation) {
		            var isValidType = values.every(function (value) {
		                var paramType = validation[0];
		                var isValidType = types[paramType] && types[paramType](value, key, src);
		                if (!isValidType) {
		                    response = toValidationResult(false, key, originalValue, 'type', paramType);
		                }
		                return isValidType;
		            });
		            if (!isValidType) {
		                return false;
		            }
		            values.every(function (value) {
		                var fn = validation[1];
		                response = fn(value, key);
		                return response.valid;
		            });
		            return true;
		        });
		        return response;
		    };
		}
		function validate() {
		    var TYPES = {
		        date: isDateType,
		        number: isNumberType,
		        integer: isIntegerType,
		        boolean: isBooleanType,
		        string: isStringType
		    };
		    var RULES = {
		        minimum: isMinimum,
		        maximum: isMaximum,
		        minLength: isMinimumLength,
		        maxLength: isMaximumLength,
		        'enum': isEnum,
		        pattern: isPattern
		    };
		    function rule(parameter) {
		        return toValidation(parameter, RULES, TYPES);
		    }
		    var v;
		    var validate = function (parameterMap) {
		        if (!parameterMap) {
		            return function (check) {
		                return { valid: true, errors: [] };
		            };
		        }
		        var validations = {};
		        Object.keys(parameterMap).forEach(function (key) {
		            validations[key] = rule(parameterMap[key]);
		        });
		        return function (src) {
		            src = src || {};
		            var errors = Object.keys(validations).map(function (param) {
		                var value = src[param];
		                var fn = validations[param];
		                return fn(value, param, src);
		            }).filter(function (result) {
		                return !result.valid;
		            });
		            return {
		                valid: errors.length === 0,
		                errors: errors
		            };
		        };
		    };
		    v = validate;
		    v.rule = rule;
		    v.TYPES = TYPES;
		    v.RULES = RULES;
		    return v;
		}
		module.exports = validate;

		/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(69).Buffer))

	/***/ },
	/* 69 */
	/***/ function(module, exports, __webpack_require__) {

		/* WEBPACK VAR INJECTION */(function(Buffer, global) {/*!
		 * The buffer module from node.js, for the browser.
		 *
		 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
		 * @license  MIT
		 */
		/* eslint-disable no-proto */

		var base64 = __webpack_require__(70)
		var ieee754 = __webpack_require__(71)
		var isArray = __webpack_require__(72)

		exports.Buffer = Buffer
		exports.SlowBuffer = SlowBuffer
		exports.INSPECT_MAX_BYTES = 50
		Buffer.poolSize = 8192 // not used by this implementation

		var rootParent = {}

		/**
		 * If `Buffer.TYPED_ARRAY_SUPPORT`:
		 *   === true    Use Uint8Array implementation (fastest)
		 *   === false   Use Object implementation (most compatible, even IE6)
		 *
		 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
		 * Opera 11.6+, iOS 4.2+.
		 *
		 * Due to various browser bugs, sometimes the Object implementation will be used even
		 * when the browser supports typed arrays.
		 *
		 * Note:
		 *
		 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
		 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
		 *
		 *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
		 *     on objects.
		 *
		 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
		 *
		 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
		 *     incorrect length in some situations.

		 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
		 * get the Object implementation, which is slower but behaves correctly.
		 */
		Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
		  ? global.TYPED_ARRAY_SUPPORT
		  : typedArraySupport()

		function typedArraySupport () {
		  function Bar () {}
		  try {
		    var arr = new Uint8Array(1)
		    arr.foo = function () { return 42 }
		    arr.constructor = Bar
		    return arr.foo() === 42 && // typed array instances can be augmented
		        arr.constructor === Bar && // constructor can be set
		        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
		        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
		  } catch (e) {
		    return false
		  }
		}

		function kMaxLength () {
		  return Buffer.TYPED_ARRAY_SUPPORT
		    ? 0x7fffffff
		    : 0x3fffffff
		}

		/**
		 * Class: Buffer
		 * =============
		 *
		 * The Buffer constructor returns instances of `Uint8Array` that are augmented
		 * with function properties for all the node `Buffer` API functions. We use
		 * `Uint8Array` so that square bracket notation works as expected -- it returns
		 * a single octet.
		 *
		 * By augmenting the instances, we can avoid modifying the `Uint8Array`
		 * prototype.
		 */
		function Buffer (arg) {
		  if (!(this instanceof Buffer)) {
		    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
		    if (arguments.length > 1) return new Buffer(arg, arguments[1])
		    return new Buffer(arg)
		  }

		  this.length = 0
		  this.parent = undefined

		  // Common case.
		  if (typeof arg === 'number') {
		    return fromNumber(this, arg)
		  }

		  // Slightly less common case.
		  if (typeof arg === 'string') {
		    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
		  }

		  // Unusual.
		  return fromObject(this, arg)
		}

		function fromNumber (that, length) {
		  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
		  if (!Buffer.TYPED_ARRAY_SUPPORT) {
		    for (var i = 0; i < length; i++) {
		      that[i] = 0
		    }
		  }
		  return that
		}

		function fromString (that, string, encoding) {
		  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'

		  // Assumption: byteLength() return value is always < kMaxLength.
		  var length = byteLength(string, encoding) | 0
		  that = allocate(that, length)

		  that.write(string, encoding)
		  return that
		}

		function fromObject (that, object) {
		  if (Buffer.isBuffer(object)) return fromBuffer(that, object)

		  if (isArray(object)) return fromArray(that, object)

		  if (object == null) {
		    throw new TypeError('must start with number, buffer, array or string')
		  }

		  if (typeof ArrayBuffer !== 'undefined') {
		    if (object.buffer instanceof ArrayBuffer) {
		      return fromTypedArray(that, object)
		    }
		    if (object instanceof ArrayBuffer) {
		      return fromArrayBuffer(that, object)
		    }
		  }

		  if (object.length) return fromArrayLike(that, object)

		  return fromJsonObject(that, object)
		}

		function fromBuffer (that, buffer) {
		  var length = checked(buffer.length) | 0
		  that = allocate(that, length)
		  buffer.copy(that, 0, 0, length)
		  return that
		}

		function fromArray (that, array) {
		  var length = checked(array.length) | 0
		  that = allocate(that, length)
		  for (var i = 0; i < length; i += 1) {
		    that[i] = array[i] & 255
		  }
		  return that
		}

		// Duplicate of fromArray() to keep fromArray() monomorphic.
		function fromTypedArray (that, array) {
		  var length = checked(array.length) | 0
		  that = allocate(that, length)
		  // Truncating the elements is probably not what people expect from typed
		  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
		  // of the old Buffer constructor.
		  for (var i = 0; i < length; i += 1) {
		    that[i] = array[i] & 255
		  }
		  return that
		}

		function fromArrayBuffer (that, array) {
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    // Return an augmented `Uint8Array` instance, for best performance
		    array.byteLength
		    that = Buffer._augment(new Uint8Array(array))
		  } else {
		    // Fallback: Return an object instance of the Buffer class
		    that = fromTypedArray(that, new Uint8Array(array))
		  }
		  return that
		}

		function fromArrayLike (that, array) {
		  var length = checked(array.length) | 0
		  that = allocate(that, length)
		  for (var i = 0; i < length; i += 1) {
		    that[i] = array[i] & 255
		  }
		  return that
		}

		// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
		// Returns a zero-length buffer for inputs that don't conform to the spec.
		function fromJsonObject (that, object) {
		  var array
		  var length = 0

		  if (object.type === 'Buffer' && isArray(object.data)) {
		    array = object.data
		    length = checked(array.length) | 0
		  }
		  that = allocate(that, length)

		  for (var i = 0; i < length; i += 1) {
		    that[i] = array[i] & 255
		  }
		  return that
		}

		if (Buffer.TYPED_ARRAY_SUPPORT) {
		  Buffer.prototype.__proto__ = Uint8Array.prototype
		  Buffer.__proto__ = Uint8Array
		}

		function allocate (that, length) {
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    // Return an augmented `Uint8Array` instance, for best performance
		    that = Buffer._augment(new Uint8Array(length))
		    that.__proto__ = Buffer.prototype
		  } else {
		    // Fallback: Return an object instance of the Buffer class
		    that.length = length
		    that._isBuffer = true
		  }

		  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
		  if (fromPool) that.parent = rootParent

		  return that
		}

		function checked (length) {
		  // Note: cannot use `length < kMaxLength` here because that fails when
		  // length is NaN (which is otherwise coerced to zero.)
		  if (length >= kMaxLength()) {
		    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
		                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
		  }
		  return length | 0
		}

		function SlowBuffer (subject, encoding) {
		  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)

		  var buf = new Buffer(subject, encoding)
		  delete buf.parent
		  return buf
		}

		Buffer.isBuffer = function isBuffer (b) {
		  return !!(b != null && b._isBuffer)
		}

		Buffer.compare = function compare (a, b) {
		  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
		    throw new TypeError('Arguments must be Buffers')
		  }

		  if (a === b) return 0

		  var x = a.length
		  var y = b.length

		  var i = 0
		  var len = Math.min(x, y)
		  while (i < len) {
		    if (a[i] !== b[i]) break

		    ++i
		  }

		  if (i !== len) {
		    x = a[i]
		    y = b[i]
		  }

		  if (x < y) return -1
		  if (y < x) return 1
		  return 0
		}

		Buffer.isEncoding = function isEncoding (encoding) {
		  switch (String(encoding).toLowerCase()) {
		    case 'hex':
		    case 'utf8':
		    case 'utf-8':
		    case 'ascii':
		    case 'binary':
		    case 'base64':
		    case 'raw':
		    case 'ucs2':
		    case 'ucs-2':
		    case 'utf16le':
		    case 'utf-16le':
		      return true
		    default:
		      return false
		  }
		}

		Buffer.concat = function concat (list, length) {
		  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')

		  if (list.length === 0) {
		    return new Buffer(0)
		  }

		  var i
		  if (length === undefined) {
		    length = 0
		    for (i = 0; i < list.length; i++) {
		      length += list[i].length
		    }
		  }

		  var buf = new Buffer(length)
		  var pos = 0
		  for (i = 0; i < list.length; i++) {
		    var item = list[i]
		    item.copy(buf, pos)
		    pos += item.length
		  }
		  return buf
		}

		function byteLength (string, encoding) {
		  if (typeof string !== 'string') string = '' + string

		  var len = string.length
		  if (len === 0) return 0

		  // Use a for loop to avoid recursion
		  var loweredCase = false
		  for (;;) {
		    switch (encoding) {
		      case 'ascii':
		      case 'binary':
		      // Deprecated
		      case 'raw':
		      case 'raws':
		        return len
		      case 'utf8':
		      case 'utf-8':
		        return utf8ToBytes(string).length
		      case 'ucs2':
		      case 'ucs-2':
		      case 'utf16le':
		      case 'utf-16le':
		        return len * 2
		      case 'hex':
		        return len >>> 1
		      case 'base64':
		        return base64ToBytes(string).length
		      default:
		        if (loweredCase) return utf8ToBytes(string).length // assume utf8
		        encoding = ('' + encoding).toLowerCase()
		        loweredCase = true
		    }
		  }
		}
		Buffer.byteLength = byteLength

		// pre-set for values that may exist in the future
		Buffer.prototype.length = undefined
		Buffer.prototype.parent = undefined

		function slowToString (encoding, start, end) {
		  var loweredCase = false

		  start = start | 0
		  end = end === undefined || end === Infinity ? this.length : end | 0

		  if (!encoding) encoding = 'utf8'
		  if (start < 0) start = 0
		  if (end > this.length) end = this.length
		  if (end <= start) return ''

		  while (true) {
		    switch (encoding) {
		      case 'hex':
		        return hexSlice(this, start, end)

		      case 'utf8':
		      case 'utf-8':
		        return utf8Slice(this, start, end)

		      case 'ascii':
		        return asciiSlice(this, start, end)

		      case 'binary':
		        return binarySlice(this, start, end)

		      case 'base64':
		        return base64Slice(this, start, end)

		      case 'ucs2':
		      case 'ucs-2':
		      case 'utf16le':
		      case 'utf-16le':
		        return utf16leSlice(this, start, end)

		      default:
		        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
		        encoding = (encoding + '').toLowerCase()
		        loweredCase = true
		    }
		  }
		}

		Buffer.prototype.toString = function toString () {
		  var length = this.length | 0
		  if (length === 0) return ''
		  if (arguments.length === 0) return utf8Slice(this, 0, length)
		  return slowToString.apply(this, arguments)
		}

		Buffer.prototype.equals = function equals (b) {
		  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
		  if (this === b) return true
		  return Buffer.compare(this, b) === 0
		}

		Buffer.prototype.inspect = function inspect () {
		  var str = ''
		  var max = exports.INSPECT_MAX_BYTES
		  if (this.length > 0) {
		    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
		    if (this.length > max) str += ' ... '
		  }
		  return '<Buffer ' + str + '>'
		}

		Buffer.prototype.compare = function compare (b) {
		  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
		  if (this === b) return 0
		  return Buffer.compare(this, b)
		}

		Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
		  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
		  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
		  byteOffset >>= 0

		  if (this.length === 0) return -1
		  if (byteOffset >= this.length) return -1

		  // Negative offsets start from the end of the buffer
		  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)

		  if (typeof val === 'string') {
		    if (val.length === 0) return -1 // special case: looking for empty string always fails
		    return String.prototype.indexOf.call(this, val, byteOffset)
		  }
		  if (Buffer.isBuffer(val)) {
		    return arrayIndexOf(this, val, byteOffset)
		  }
		  if (typeof val === 'number') {
		    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
		      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
		    }
		    return arrayIndexOf(this, [ val ], byteOffset)
		  }

		  function arrayIndexOf (arr, val, byteOffset) {
		    var foundIndex = -1
		    for (var i = 0; byteOffset + i < arr.length; i++) {
		      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
		        if (foundIndex === -1) foundIndex = i
		        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
		      } else {
		        foundIndex = -1
		      }
		    }
		    return -1
		  }

		  throw new TypeError('val must be string, number or Buffer')
		}

		// `get` is deprecated
		Buffer.prototype.get = function get (offset) {
		  console.log('.get() is deprecated. Access using array indexes instead.')
		  return this.readUInt8(offset)
		}

		// `set` is deprecated
		Buffer.prototype.set = function set (v, offset) {
		  console.log('.set() is deprecated. Access using array indexes instead.')
		  return this.writeUInt8(v, offset)
		}

		function hexWrite (buf, string, offset, length) {
		  offset = Number(offset) || 0
		  var remaining = buf.length - offset
		  if (!length) {
		    length = remaining
		  } else {
		    length = Number(length)
		    if (length > remaining) {
		      length = remaining
		    }
		  }

		  // must be an even number of digits
		  var strLen = string.length
		  if (strLen % 2 !== 0) throw new Error('Invalid hex string')

		  if (length > strLen / 2) {
		    length = strLen / 2
		  }
		  for (var i = 0; i < length; i++) {
		    var parsed = parseInt(string.substr(i * 2, 2), 16)
		    if (isNaN(parsed)) throw new Error('Invalid hex string')
		    buf[offset + i] = parsed
		  }
		  return i
		}

		function utf8Write (buf, string, offset, length) {
		  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
		}

		function asciiWrite (buf, string, offset, length) {
		  return blitBuffer(asciiToBytes(string), buf, offset, length)
		}

		function binaryWrite (buf, string, offset, length) {
		  return asciiWrite(buf, string, offset, length)
		}

		function base64Write (buf, string, offset, length) {
		  return blitBuffer(base64ToBytes(string), buf, offset, length)
		}

		function ucs2Write (buf, string, offset, length) {
		  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
		}

		Buffer.prototype.write = function write (string, offset, length, encoding) {
		  // Buffer#write(string)
		  if (offset === undefined) {
		    encoding = 'utf8'
		    length = this.length
		    offset = 0
		  // Buffer#write(string, encoding)
		  } else if (length === undefined && typeof offset === 'string') {
		    encoding = offset
		    length = this.length
		    offset = 0
		  // Buffer#write(string, offset[, length][, encoding])
		  } else if (isFinite(offset)) {
		    offset = offset | 0
		    if (isFinite(length)) {
		      length = length | 0
		      if (encoding === undefined) encoding = 'utf8'
		    } else {
		      encoding = length
		      length = undefined
		    }
		  // legacy write(string, encoding, offset, length) - remove in v0.13
		  } else {
		    var swap = encoding
		    encoding = offset
		    offset = length | 0
		    length = swap
		  }

		  var remaining = this.length - offset
		  if (length === undefined || length > remaining) length = remaining

		  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
		    throw new RangeError('attempt to write outside buffer bounds')
		  }

		  if (!encoding) encoding = 'utf8'

		  var loweredCase = false
		  for (;;) {
		    switch (encoding) {
		      case 'hex':
		        return hexWrite(this, string, offset, length)

		      case 'utf8':
		      case 'utf-8':
		        return utf8Write(this, string, offset, length)

		      case 'ascii':
		        return asciiWrite(this, string, offset, length)

		      case 'binary':
		        return binaryWrite(this, string, offset, length)

		      case 'base64':
		        // Warning: maxLength not taken into account in base64Write
		        return base64Write(this, string, offset, length)

		      case 'ucs2':
		      case 'ucs-2':
		      case 'utf16le':
		      case 'utf-16le':
		        return ucs2Write(this, string, offset, length)

		      default:
		        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
		        encoding = ('' + encoding).toLowerCase()
		        loweredCase = true
		    }
		  }
		}

		Buffer.prototype.toJSON = function toJSON () {
		  return {
		    type: 'Buffer',
		    data: Array.prototype.slice.call(this._arr || this, 0)
		  }
		}

		function base64Slice (buf, start, end) {
		  if (start === 0 && end === buf.length) {
		    return base64.fromByteArray(buf)
		  } else {
		    return base64.fromByteArray(buf.slice(start, end))
		  }
		}

		function utf8Slice (buf, start, end) {
		  end = Math.min(buf.length, end)
		  var res = []

		  var i = start
		  while (i < end) {
		    var firstByte = buf[i]
		    var codePoint = null
		    var bytesPerSequence = (firstByte > 0xEF) ? 4
		      : (firstByte > 0xDF) ? 3
		      : (firstByte > 0xBF) ? 2
		      : 1

		    if (i + bytesPerSequence <= end) {
		      var secondByte, thirdByte, fourthByte, tempCodePoint

		      switch (bytesPerSequence) {
		        case 1:
		          if (firstByte < 0x80) {
		            codePoint = firstByte
		          }
		          break
		        case 2:
		          secondByte = buf[i + 1]
		          if ((secondByte & 0xC0) === 0x80) {
		            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
		            if (tempCodePoint > 0x7F) {
		              codePoint = tempCodePoint
		            }
		          }
		          break
		        case 3:
		          secondByte = buf[i + 1]
		          thirdByte = buf[i + 2]
		          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
		            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
		            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
		              codePoint = tempCodePoint
		            }
		          }
		          break
		        case 4:
		          secondByte = buf[i + 1]
		          thirdByte = buf[i + 2]
		          fourthByte = buf[i + 3]
		          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
		            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
		            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
		              codePoint = tempCodePoint
		            }
		          }
		      }
		    }

		    if (codePoint === null) {
		      // we did not generate a valid codePoint so insert a
		      // replacement char (U+FFFD) and advance only 1 byte
		      codePoint = 0xFFFD
		      bytesPerSequence = 1
		    } else if (codePoint > 0xFFFF) {
		      // encode to utf16 (surrogate pair dance)
		      codePoint -= 0x10000
		      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
		      codePoint = 0xDC00 | codePoint & 0x3FF
		    }

		    res.push(codePoint)
		    i += bytesPerSequence
		  }

		  return decodeCodePointsArray(res)
		}

		// Based on http://stackoverflow.com/a/22747272/680742, the browser with
		// the lowest limit is Chrome, with 0x10000 args.
		// We go 1 magnitude less, for safety
		var MAX_ARGUMENTS_LENGTH = 0x1000

		function decodeCodePointsArray (codePoints) {
		  var len = codePoints.length
		  if (len <= MAX_ARGUMENTS_LENGTH) {
		    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
		  }

		  // Decode in chunks to avoid "call stack size exceeded".
		  var res = ''
		  var i = 0
		  while (i < len) {
		    res += String.fromCharCode.apply(
		      String,
		      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
		    )
		  }
		  return res
		}

		function asciiSlice (buf, start, end) {
		  var ret = ''
		  end = Math.min(buf.length, end)

		  for (var i = start; i < end; i++) {
		    ret += String.fromCharCode(buf[i] & 0x7F)
		  }
		  return ret
		}

		function binarySlice (buf, start, end) {
		  var ret = ''
		  end = Math.min(buf.length, end)

		  for (var i = start; i < end; i++) {
		    ret += String.fromCharCode(buf[i])
		  }
		  return ret
		}

		function hexSlice (buf, start, end) {
		  var len = buf.length

		  if (!start || start < 0) start = 0
		  if (!end || end < 0 || end > len) end = len

		  var out = ''
		  for (var i = start; i < end; i++) {
		    out += toHex(buf[i])
		  }
		  return out
		}

		function utf16leSlice (buf, start, end) {
		  var bytes = buf.slice(start, end)
		  var res = ''
		  for (var i = 0; i < bytes.length; i += 2) {
		    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
		  }
		  return res
		}

		Buffer.prototype.slice = function slice (start, end) {
		  var len = this.length
		  start = ~~start
		  end = end === undefined ? len : ~~end

		  if (start < 0) {
		    start += len
		    if (start < 0) start = 0
		  } else if (start > len) {
		    start = len
		  }

		  if (end < 0) {
		    end += len
		    if (end < 0) end = 0
		  } else if (end > len) {
		    end = len
		  }

		  if (end < start) end = start

		  var newBuf
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    newBuf = Buffer._augment(this.subarray(start, end))
		  } else {
		    var sliceLen = end - start
		    newBuf = new Buffer(sliceLen, undefined)
		    for (var i = 0; i < sliceLen; i++) {
		      newBuf[i] = this[i + start]
		    }
		  }

		  if (newBuf.length) newBuf.parent = this.parent || this

		  return newBuf
		}

		/*
		 * Need to make sure that buffer isn't trying to write out of bounds.
		 */
		function checkOffset (offset, ext, length) {
		  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
		  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
		}

		Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
		  offset = offset | 0
		  byteLength = byteLength | 0
		  if (!noAssert) checkOffset(offset, byteLength, this.length)

		  var val = this[offset]
		  var mul = 1
		  var i = 0
		  while (++i < byteLength && (mul *= 0x100)) {
		    val += this[offset + i] * mul
		  }

		  return val
		}

		Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
		  offset = offset | 0
		  byteLength = byteLength | 0
		  if (!noAssert) {
		    checkOffset(offset, byteLength, this.length)
		  }

		  var val = this[offset + --byteLength]
		  var mul = 1
		  while (byteLength > 0 && (mul *= 0x100)) {
		    val += this[offset + --byteLength] * mul
		  }

		  return val
		}

		Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 1, this.length)
		  return this[offset]
		}

		Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 2, this.length)
		  return this[offset] | (this[offset + 1] << 8)
		}

		Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 2, this.length)
		  return (this[offset] << 8) | this[offset + 1]
		}

		Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 4, this.length)

		  return ((this[offset]) |
		      (this[offset + 1] << 8) |
		      (this[offset + 2] << 16)) +
		      (this[offset + 3] * 0x1000000)
		}

		Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 4, this.length)

		  return (this[offset] * 0x1000000) +
		    ((this[offset + 1] << 16) |
		    (this[offset + 2] << 8) |
		    this[offset + 3])
		}

		Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
		  offset = offset | 0
		  byteLength = byteLength | 0
		  if (!noAssert) checkOffset(offset, byteLength, this.length)

		  var val = this[offset]
		  var mul = 1
		  var i = 0
		  while (++i < byteLength && (mul *= 0x100)) {
		    val += this[offset + i] * mul
		  }
		  mul *= 0x80

		  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

		  return val
		}

		Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
		  offset = offset | 0
		  byteLength = byteLength | 0
		  if (!noAssert) checkOffset(offset, byteLength, this.length)

		  var i = byteLength
		  var mul = 1
		  var val = this[offset + --i]
		  while (i > 0 && (mul *= 0x100)) {
		    val += this[offset + --i] * mul
		  }
		  mul *= 0x80

		  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

		  return val
		}

		Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 1, this.length)
		  if (!(this[offset] & 0x80)) return (this[offset])
		  return ((0xff - this[offset] + 1) * -1)
		}

		Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 2, this.length)
		  var val = this[offset] | (this[offset + 1] << 8)
		  return (val & 0x8000) ? val | 0xFFFF0000 : val
		}

		Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 2, this.length)
		  var val = this[offset + 1] | (this[offset] << 8)
		  return (val & 0x8000) ? val | 0xFFFF0000 : val
		}

		Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 4, this.length)

		  return (this[offset]) |
		    (this[offset + 1] << 8) |
		    (this[offset + 2] << 16) |
		    (this[offset + 3] << 24)
		}

		Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 4, this.length)

		  return (this[offset] << 24) |
		    (this[offset + 1] << 16) |
		    (this[offset + 2] << 8) |
		    (this[offset + 3])
		}

		Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 4, this.length)
		  return ieee754.read(this, offset, true, 23, 4)
		}

		Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 4, this.length)
		  return ieee754.read(this, offset, false, 23, 4)
		}

		Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 8, this.length)
		  return ieee754.read(this, offset, true, 52, 8)
		}

		Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
		  if (!noAssert) checkOffset(offset, 8, this.length)
		  return ieee754.read(this, offset, false, 52, 8)
		}

		function checkInt (buf, value, offset, ext, max, min) {
		  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
		  if (value > max || value < min) throw new RangeError('value is out of bounds')
		  if (offset + ext > buf.length) throw new RangeError('index out of range')
		}

		Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
		  value = +value
		  offset = offset | 0
		  byteLength = byteLength | 0
		  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)

		  var mul = 1
		  var i = 0
		  this[offset] = value & 0xFF
		  while (++i < byteLength && (mul *= 0x100)) {
		    this[offset + i] = (value / mul) & 0xFF
		  }

		  return offset + byteLength
		}

		Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
		  value = +value
		  offset = offset | 0
		  byteLength = byteLength | 0
		  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)

		  var i = byteLength - 1
		  var mul = 1
		  this[offset + i] = value & 0xFF
		  while (--i >= 0 && (mul *= 0x100)) {
		    this[offset + i] = (value / mul) & 0xFF
		  }

		  return offset + byteLength
		}

		Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
		  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
		  this[offset] = (value & 0xff)
		  return offset + 1
		}

		function objectWriteUInt16 (buf, value, offset, littleEndian) {
		  if (value < 0) value = 0xffff + value + 1
		  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
		    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
		      (littleEndian ? i : 1 - i) * 8
		  }
		}

		Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value & 0xff)
		    this[offset + 1] = (value >>> 8)
		  } else {
		    objectWriteUInt16(this, value, offset, true)
		  }
		  return offset + 2
		}

		Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value >>> 8)
		    this[offset + 1] = (value & 0xff)
		  } else {
		    objectWriteUInt16(this, value, offset, false)
		  }
		  return offset + 2
		}

		function objectWriteUInt32 (buf, value, offset, littleEndian) {
		  if (value < 0) value = 0xffffffff + value + 1
		  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
		    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
		  }
		}

		Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset + 3] = (value >>> 24)
		    this[offset + 2] = (value >>> 16)
		    this[offset + 1] = (value >>> 8)
		    this[offset] = (value & 0xff)
		  } else {
		    objectWriteUInt32(this, value, offset, true)
		  }
		  return offset + 4
		}

		Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value >>> 24)
		    this[offset + 1] = (value >>> 16)
		    this[offset + 2] = (value >>> 8)
		    this[offset + 3] = (value & 0xff)
		  } else {
		    objectWriteUInt32(this, value, offset, false)
		  }
		  return offset + 4
		}

		Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) {
		    var limit = Math.pow(2, 8 * byteLength - 1)

		    checkInt(this, value, offset, byteLength, limit - 1, -limit)
		  }

		  var i = 0
		  var mul = 1
		  var sub = value < 0 ? 1 : 0
		  this[offset] = value & 0xFF
		  while (++i < byteLength && (mul *= 0x100)) {
		    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
		  }

		  return offset + byteLength
		}

		Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) {
		    var limit = Math.pow(2, 8 * byteLength - 1)

		    checkInt(this, value, offset, byteLength, limit - 1, -limit)
		  }

		  var i = byteLength - 1
		  var mul = 1
		  var sub = value < 0 ? 1 : 0
		  this[offset + i] = value & 0xFF
		  while (--i >= 0 && (mul *= 0x100)) {
		    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
		  }

		  return offset + byteLength
		}

		Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
		  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
		  if (value < 0) value = 0xff + value + 1
		  this[offset] = (value & 0xff)
		  return offset + 1
		}

		Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value & 0xff)
		    this[offset + 1] = (value >>> 8)
		  } else {
		    objectWriteUInt16(this, value, offset, true)
		  }
		  return offset + 2
		}

		Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value >>> 8)
		    this[offset + 1] = (value & 0xff)
		  } else {
		    objectWriteUInt16(this, value, offset, false)
		  }
		  return offset + 2
		}

		Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value & 0xff)
		    this[offset + 1] = (value >>> 8)
		    this[offset + 2] = (value >>> 16)
		    this[offset + 3] = (value >>> 24)
		  } else {
		    objectWriteUInt32(this, value, offset, true)
		  }
		  return offset + 4
		}

		Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
		  value = +value
		  offset = offset | 0
		  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
		  if (value < 0) value = 0xffffffff + value + 1
		  if (Buffer.TYPED_ARRAY_SUPPORT) {
		    this[offset] = (value >>> 24)
		    this[offset + 1] = (value >>> 16)
		    this[offset + 2] = (value >>> 8)
		    this[offset + 3] = (value & 0xff)
		  } else {
		    objectWriteUInt32(this, value, offset, false)
		  }
		  return offset + 4
		}

		function checkIEEE754 (buf, value, offset, ext, max, min) {
		  if (value > max || value < min) throw new RangeError('value is out of bounds')
		  if (offset + ext > buf.length) throw new RangeError('index out of range')
		  if (offset < 0) throw new RangeError('index out of range')
		}

		function writeFloat (buf, value, offset, littleEndian, noAssert) {
		  if (!noAssert) {
		    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
		  }
		  ieee754.write(buf, value, offset, littleEndian, 23, 4)
		  return offset + 4
		}

		Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
		  return writeFloat(this, value, offset, true, noAssert)
		}

		Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
		  return writeFloat(this, value, offset, false, noAssert)
		}

		function writeDouble (buf, value, offset, littleEndian, noAssert) {
		  if (!noAssert) {
		    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
		  }
		  ieee754.write(buf, value, offset, littleEndian, 52, 8)
		  return offset + 8
		}

		Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
		  return writeDouble(this, value, offset, true, noAssert)
		}

		Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
		  return writeDouble(this, value, offset, false, noAssert)
		}

		// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
		Buffer.prototype.copy = function copy (target, targetStart, start, end) {
		  if (!start) start = 0
		  if (!end && end !== 0) end = this.length
		  if (targetStart >= target.length) targetStart = target.length
		  if (!targetStart) targetStart = 0
		  if (end > 0 && end < start) end = start

		  // Copy 0 bytes; we're done
		  if (end === start) return 0
		  if (target.length === 0 || this.length === 0) return 0

		  // Fatal error conditions
		  if (targetStart < 0) {
		    throw new RangeError('targetStart out of bounds')
		  }
		  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
		  if (end < 0) throw new RangeError('sourceEnd out of bounds')

		  // Are we oob?
		  if (end > this.length) end = this.length
		  if (target.length - targetStart < end - start) {
		    end = target.length - targetStart + start
		  }

		  var len = end - start
		  var i

		  if (this === target && start < targetStart && targetStart < end) {
		    // descending copy from end
		    for (i = len - 1; i >= 0; i--) {
		      target[i + targetStart] = this[i + start]
		    }
		  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
		    // ascending copy from start
		    for (i = 0; i < len; i++) {
		      target[i + targetStart] = this[i + start]
		    }
		  } else {
		    target._set(this.subarray(start, start + len), targetStart)
		  }

		  return len
		}

		// fill(value, start=0, end=buffer.length)
		Buffer.prototype.fill = function fill (value, start, end) {
		  if (!value) value = 0
		  if (!start) start = 0
		  if (!end) end = this.length

		  if (end < start) throw new RangeError('end < start')

		  // Fill 0 bytes; we're done
		  if (end === start) return
		  if (this.length === 0) return

		  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
		  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')

		  var i
		  if (typeof value === 'number') {
		    for (i = start; i < end; i++) {
		      this[i] = value
		    }
		  } else {
		    var bytes = utf8ToBytes(value.toString())
		    var len = bytes.length
		    for (i = start; i < end; i++) {
		      this[i] = bytes[i % len]
		    }
		  }

		  return this
		}

		/**
		 * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
		 * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
		 */
		Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
		  if (typeof Uint8Array !== 'undefined') {
		    if (Buffer.TYPED_ARRAY_SUPPORT) {
		      return (new Buffer(this)).buffer
		    } else {
		      var buf = new Uint8Array(this.length)
		      for (var i = 0, len = buf.length; i < len; i += 1) {
		        buf[i] = this[i]
		      }
		      return buf.buffer
		    }
		  } else {
		    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
		  }
		}

		// HELPER FUNCTIONS
		// ================

		var BP = Buffer.prototype

		/**
		 * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
		 */
		Buffer._augment = function _augment (arr) {
		  arr.constructor = Buffer
		  arr._isBuffer = true

		  // save reference to original Uint8Array set method before overwriting
		  arr._set = arr.set

		  // deprecated
		  arr.get = BP.get
		  arr.set = BP.set

		  arr.write = BP.write
		  arr.toString = BP.toString
		  arr.toLocaleString = BP.toString
		  arr.toJSON = BP.toJSON
		  arr.equals = BP.equals
		  arr.compare = BP.compare
		  arr.indexOf = BP.indexOf
		  arr.copy = BP.copy
		  arr.slice = BP.slice
		  arr.readUIntLE = BP.readUIntLE
		  arr.readUIntBE = BP.readUIntBE
		  arr.readUInt8 = BP.readUInt8
		  arr.readUInt16LE = BP.readUInt16LE
		  arr.readUInt16BE = BP.readUInt16BE
		  arr.readUInt32LE = BP.readUInt32LE
		  arr.readUInt32BE = BP.readUInt32BE
		  arr.readIntLE = BP.readIntLE
		  arr.readIntBE = BP.readIntBE
		  arr.readInt8 = BP.readInt8
		  arr.readInt16LE = BP.readInt16LE
		  arr.readInt16BE = BP.readInt16BE
		  arr.readInt32LE = BP.readInt32LE
		  arr.readInt32BE = BP.readInt32BE
		  arr.readFloatLE = BP.readFloatLE
		  arr.readFloatBE = BP.readFloatBE
		  arr.readDoubleLE = BP.readDoubleLE
		  arr.readDoubleBE = BP.readDoubleBE
		  arr.writeUInt8 = BP.writeUInt8
		  arr.writeUIntLE = BP.writeUIntLE
		  arr.writeUIntBE = BP.writeUIntBE
		  arr.writeUInt16LE = BP.writeUInt16LE
		  arr.writeUInt16BE = BP.writeUInt16BE
		  arr.writeUInt32LE = BP.writeUInt32LE
		  arr.writeUInt32BE = BP.writeUInt32BE
		  arr.writeIntLE = BP.writeIntLE
		  arr.writeIntBE = BP.writeIntBE
		  arr.writeInt8 = BP.writeInt8
		  arr.writeInt16LE = BP.writeInt16LE
		  arr.writeInt16BE = BP.writeInt16BE
		  arr.writeInt32LE = BP.writeInt32LE
		  arr.writeInt32BE = BP.writeInt32BE
		  arr.writeFloatLE = BP.writeFloatLE
		  arr.writeFloatBE = BP.writeFloatBE
		  arr.writeDoubleLE = BP.writeDoubleLE
		  arr.writeDoubleBE = BP.writeDoubleBE
		  arr.fill = BP.fill
		  arr.inspect = BP.inspect
		  arr.toArrayBuffer = BP.toArrayBuffer

		  return arr
		}

		var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g

		function base64clean (str) {
		  // Node strips out invalid characters like \n and \t from the string, base64-js does not
		  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
		  // Node converts strings with length < 2 to ''
		  if (str.length < 2) return ''
		  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
		  while (str.length % 4 !== 0) {
		    str = str + '='
		  }
		  return str
		}

		function stringtrim (str) {
		  if (str.trim) return str.trim()
		  return str.replace(/^\s+|\s+$/g, '')
		}

		function toHex (n) {
		  if (n < 16) return '0' + n.toString(16)
		  return n.toString(16)
		}

		function utf8ToBytes (string, units) {
		  units = units || Infinity
		  var codePoint
		  var length = string.length
		  var leadSurrogate = null
		  var bytes = []

		  for (var i = 0; i < length; i++) {
		    codePoint = string.charCodeAt(i)

		    // is surrogate component
		    if (codePoint > 0xD7FF && codePoint < 0xE000) {
		      // last char was a lead
		      if (!leadSurrogate) {
		        // no lead yet
		        if (codePoint > 0xDBFF) {
		          // unexpected trail
		          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
		          continue
		        } else if (i + 1 === length) {
		          // unpaired lead
		          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
		          continue
		        }

		        // valid lead
		        leadSurrogate = codePoint

		        continue
		      }

		      // 2 leads in a row
		      if (codePoint < 0xDC00) {
		        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
		        leadSurrogate = codePoint
		        continue
		      }

		      // valid surrogate pair
		      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
		    } else if (leadSurrogate) {
		      // valid bmp char, but last char was a lead
		      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
		    }

		    leadSurrogate = null

		    // encode utf8
		    if (codePoint < 0x80) {
		      if ((units -= 1) < 0) break
		      bytes.push(codePoint)
		    } else if (codePoint < 0x800) {
		      if ((units -= 2) < 0) break
		      bytes.push(
		        codePoint >> 0x6 | 0xC0,
		        codePoint & 0x3F | 0x80
		      )
		    } else if (codePoint < 0x10000) {
		      if ((units -= 3) < 0) break
		      bytes.push(
		        codePoint >> 0xC | 0xE0,
		        codePoint >> 0x6 & 0x3F | 0x80,
		        codePoint & 0x3F | 0x80
		      )
		    } else if (codePoint < 0x110000) {
		      if ((units -= 4) < 0) break
		      bytes.push(
		        codePoint >> 0x12 | 0xF0,
		        codePoint >> 0xC & 0x3F | 0x80,
		        codePoint >> 0x6 & 0x3F | 0x80,
		        codePoint & 0x3F | 0x80
		      )
		    } else {
		      throw new Error('Invalid code point')
		    }
		  }

		  return bytes
		}

		function asciiToBytes (str) {
		  var byteArray = []
		  for (var i = 0; i < str.length; i++) {
		    // Node's code seems to be doing this and not & 0x7F..
		    byteArray.push(str.charCodeAt(i) & 0xFF)
		  }
		  return byteArray
		}

		function utf16leToBytes (str, units) {
		  var c, hi, lo
		  var byteArray = []
		  for (var i = 0; i < str.length; i++) {
		    if ((units -= 2) < 0) break

		    c = str.charCodeAt(i)
		    hi = c >> 8
		    lo = c % 256
		    byteArray.push(lo)
		    byteArray.push(hi)
		  }

		  return byteArray
		}

		function base64ToBytes (str) {
		  return base64.toByteArray(base64clean(str))
		}

		function blitBuffer (src, dst, offset, length) {
		  for (var i = 0; i < length; i++) {
		    if ((i + offset >= dst.length) || (i >= src.length)) break
		    dst[i + offset] = src[i]
		  }
		  return i
		}

		/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(69).Buffer, (function() { return this; }())))

	/***/ },
	/* 70 */
	/***/ function(module, exports, __webpack_require__) {

		var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

		;(function (exports) {
			'use strict';

		  var Arr = (typeof Uint8Array !== 'undefined')
		    ? Uint8Array
		    : Array

			var PLUS   = '+'.charCodeAt(0)
			var SLASH  = '/'.charCodeAt(0)
			var NUMBER = '0'.charCodeAt(0)
			var LOWER  = 'a'.charCodeAt(0)
			var UPPER  = 'A'.charCodeAt(0)
			var PLUS_URL_SAFE = '-'.charCodeAt(0)
			var SLASH_URL_SAFE = '_'.charCodeAt(0)

			function decode (elt) {
				var code = elt.charCodeAt(0)
				if (code === PLUS ||
				    code === PLUS_URL_SAFE)
					return 62 // '+'
				if (code === SLASH ||
				    code === SLASH_URL_SAFE)
					return 63 // '/'
				if (code < NUMBER)
					return -1 //no match
				if (code < NUMBER + 10)
					return code - NUMBER + 26 + 26
				if (code < UPPER + 26)
					return code - UPPER
				if (code < LOWER + 26)
					return code - LOWER + 26
			}

			function b64ToByteArray (b64) {
				var i, j, l, tmp, placeHolders, arr

				if (b64.length % 4 > 0) {
					throw new Error('Invalid string. Length must be a multiple of 4')
				}

				// the number of equal signs (place holders)
				// if there are two placeholders, than the two characters before it
				// represent one byte
				// if there is only one, then the three characters before it represent 2 bytes
				// this is just a cheap hack to not do indexOf twice
				var len = b64.length
				placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0

				// base64 is 4/3 + up to two characters of the original data
				arr = new Arr(b64.length * 3 / 4 - placeHolders)

				// if there are placeholders, only get up to the last complete 4 chars
				l = placeHolders > 0 ? b64.length - 4 : b64.length

				var L = 0

				function push (v) {
					arr[L++] = v
				}

				for (i = 0, j = 0; i < l; i += 4, j += 3) {
					tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
					push((tmp & 0xFF0000) >> 16)
					push((tmp & 0xFF00) >> 8)
					push(tmp & 0xFF)
				}

				if (placeHolders === 2) {
					tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
					push(tmp & 0xFF)
				} else if (placeHolders === 1) {
					tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
					push((tmp >> 8) & 0xFF)
					push(tmp & 0xFF)
				}

				return arr
			}

			function uint8ToBase64 (uint8) {
				var i,
					extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
					output = "",
					temp, length

				function encode (num) {
					return lookup.charAt(num)
				}

				function tripletToBase64 (num) {
					return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
				}

				// go through the array every three bytes, we'll deal with trailing stuff later
				for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
					temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
					output += tripletToBase64(temp)
				}

				// pad the end with zeros, but make sure to not forget the extra bytes
				switch (extraBytes) {
					case 1:
						temp = uint8[uint8.length - 1]
						output += encode(temp >> 2)
						output += encode((temp << 4) & 0x3F)
						output += '=='
						break
					case 2:
						temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
						output += encode(temp >> 10)
						output += encode((temp >> 4) & 0x3F)
						output += encode((temp << 2) & 0x3F)
						output += '='
						break
				}

				return output
			}

			exports.toByteArray = b64ToByteArray
			exports.fromByteArray = uint8ToBase64
		}( false ? (this.base64js = {}) : exports))


	/***/ },
	/* 71 */
	/***/ function(module, exports) {

		exports.read = function (buffer, offset, isLE, mLen, nBytes) {
		  var e, m
		  var eLen = nBytes * 8 - mLen - 1
		  var eMax = (1 << eLen) - 1
		  var eBias = eMax >> 1
		  var nBits = -7
		  var i = isLE ? (nBytes - 1) : 0
		  var d = isLE ? -1 : 1
		  var s = buffer[offset + i]

		  i += d

		  e = s & ((1 << (-nBits)) - 1)
		  s >>= (-nBits)
		  nBits += eLen
		  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}

		  m = e & ((1 << (-nBits)) - 1)
		  e >>= (-nBits)
		  nBits += mLen
		  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}

		  if (e === 0) {
		    e = 1 - eBias
		  } else if (e === eMax) {
		    return m ? NaN : ((s ? -1 : 1) * Infinity)
		  } else {
		    m = m + Math.pow(2, mLen)
		    e = e - eBias
		  }
		  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
		}

		exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
		  var e, m, c
		  var eLen = nBytes * 8 - mLen - 1
		  var eMax = (1 << eLen) - 1
		  var eBias = eMax >> 1
		  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
		  var i = isLE ? 0 : (nBytes - 1)
		  var d = isLE ? 1 : -1
		  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0

		  value = Math.abs(value)

		  if (isNaN(value) || value === Infinity) {
		    m = isNaN(value) ? 1 : 0
		    e = eMax
		  } else {
		    e = Math.floor(Math.log(value) / Math.LN2)
		    if (value * (c = Math.pow(2, -e)) < 1) {
		      e--
		      c *= 2
		    }
		    if (e + eBias >= 1) {
		      value += rt / c
		    } else {
		      value += rt * Math.pow(2, 1 - eBias)
		    }
		    if (value * c >= 2) {
		      e++
		      c /= 2
		    }

		    if (e + eBias >= eMax) {
		      m = 0
		      e = eMax
		    } else if (e + eBias >= 1) {
		      m = (value * c - 1) * Math.pow(2, mLen)
		      e = e + eBias
		    } else {
		      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
		      e = 0
		    }
		  }

		  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

		  e = (e << mLen) | m
		  eLen += mLen
		  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

		  buffer[offset + i - d] |= s * 128
		}


	/***/ },
	/* 72 */
	/***/ function(module, exports) {

		
		/**
		 * isArray
		 */

		var isArray = Array.isArray;

		/**
		 * toString
		 */

		var str = Object.prototype.toString;

		/**
		 * Whether or not the given `val`
		 * is an array.
		 *
		 * example:
		 *
		 *        isArray([]);
		 *        // > true
		 *        isArray(arguments);
		 *        // > false
		 *        isArray('');
		 *        // > false
		 *
		 * @param {mixed} val
		 * @return {bool}
		 */

		module.exports = isArray || function (val) {
		  return !! val && '[object Array]' == str.call(val);
		};


	/***/ },
	/* 73 */
	/***/ function(module, exports, __webpack_require__) {

		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var hl = __webpack_require__(2);
		var hlimpl = __webpack_require__(5);
		var Error = __webpack_require__(9);
		var util = __webpack_require__(11);
		var proxy = __webpack_require__(6);
		var RamlWrapper = __webpack_require__(1);
		var RamlWrapper08 = __webpack_require__(74);
		var wrapperHelper = __webpack_require__(65);
		var pluralize = __webpack_require__(90);
		var universeProvider = __webpack_require__(78);
		var changeCase = __webpack_require__(91);
		function expandTraitsAndResourceTypes(api) {
		    if (!(api instanceof RamlWrapper.ApiImpl || api instanceof RamlWrapper08.ApiImpl)) {
		        return null;
		    }
		    return new TraitsAndResourceTypesExpander().expandTraitsAndResourceTypes(api);
		}
		exports.expandTraitsAndResourceTypes = expandTraitsAndResourceTypes;
		function mergeAPIs(masterUnit, extensionsAndOverlays, mergeMode) {
		    var masterApi = hl.fromUnit(masterUnit);
		    if (!masterApi)
		        throw new Error("couldn't load api from " + masterUnit.absolutePath());
		    if (!extensionsAndOverlays || extensionsAndOverlays.length == 0) {
		        return masterApi;
		    }
		    var currentMaster = masterApi;
		    var lastExtensionOrOverlay = null;
		    for (var i = 0; i < extensionsAndOverlays.length; i++) {
		        var currentUnit = extensionsAndOverlays[i];
		        var currentApi = hl.fromUnit(currentUnit);
		        if (!currentApi)
		            throw new Error("couldn't load api from " + currentUnit.absolutePath());
		        currentApi.overrideMaster(currentMaster);
		        currentApi.setMergeMode(mergeMode);
		        currentMaster = currentApi;
		        if (i == extensionsAndOverlays.length - 1) {
		            lastExtensionOrOverlay = currentApi;
		        }
		    }
		    return lastExtensionOrOverlay;
		}
		exports.mergeAPIs = mergeAPIs;
		var TraitsAndResourceTypesExpander = (function () {
		    function TraitsAndResourceTypesExpander() {
		    }
		    TraitsAndResourceTypesExpander.prototype.expandTraitsAndResourceTypes = function (_api) {
		        var _this = this;
		        var isRAML1 = _api instanceof RamlWrapper.ApiImpl;
		        var api = _api;
		        var traits = wrapperHelper.allTraits(api);
		        var resourceTypes = wrapperHelper.allResourceTypes(api);
		        //if ((!traits || traits.length == 0) && (!resourceTypes || resourceTypes.length == 0)) {
		        //    return api;
		        //}
		        if (traits.length == 0 && resourceTypes.length == 0) {
		            return _api;
		        }
		        var llNode = api.highLevel().lowLevel();
		        this.ramlVersion = _api.highLevel().definition().universe().version();
		        var topComposite = new proxy.LowLevelCompositeNode(llNode, null, null, this.ramlVersion);
		        var apiType = isRAML1 ? universeProvider('RAML10').type('Api') : universeProvider('RAML08').type('Api');
		        var hlNode = new hlimpl.ASTNodeImpl(topComposite, null, apiType, null);
		        var result = isRAML1 ? new RamlWrapper.ApiImpl(hlNode) : new RamlWrapper08.ApiImpl(hlNode);
		        this.traitMap = {};
		        this.resourceTypeMap = {};
		        result.highLevel().setMergeMode(_api.highLevel().getMergeMode());
		        if (traits) {
		            traits.forEach(function (x) { return _this.traitMap[wrapperHelper.qName(x)] = x; });
		        }
		        if (resourceTypes) {
		            resourceTypes.forEach(function (x) { return _this.resourceTypeMap[wrapperHelper.qName(x)] = x; });
		        }
		        var resources = result.resources();
		        resources.forEach(function (x) { return _this.processResource(x); });
		        return result;
		    };
		    TraitsAndResourceTypesExpander.prototype.processResource = function (resource) {
		        var _this = this;
		        var resourceData = this.collectResourceData(resource);
		        if (resource instanceof RamlWrapper.ResourceImpl) {
		            var mb = resource;
		        }
		        var resourceLowLevel = resource.highLevel().lowLevel();
		        resourceData.filter(function (x) { return x.resourceType != null; }).forEach(function (x) {
		            var resourceTypeLowLevel = x.resourceType.node.highLevel().lowLevel();
		            var resourceTypeTransformer = new DefaultTransformer(resource, x.resourceType.transformer);
		            resourceLowLevel.adopt(resourceTypeLowLevel, resourceTypeTransformer);
		        });
		        var methods = resource.methods();
		        methods.forEach(function (m) {
		            var methodLowLevel = m.highLevel().lowLevel();
		            var name = m.method();
		            resourceData.forEach(function (x) {
		                var methodTraits = x.methodTraits[name];
		                if (methodTraits) {
		                    methodTraits.forEach(function (x) {
		                        var traitLowLevel = x.node.highLevel().lowLevel();
		                        var traitTransformer = new DefaultTransformer(m, x.transformer);
		                        methodLowLevel.adopt(traitLowLevel, traitTransformer);
		                    });
		                }
		                var resourceTraits = x.traits;
		                if (resourceTraits) {
		                    resourceTraits.forEach(function (x) {
		                        var traitLowLevel = x.node.highLevel().lowLevel();
		                        var traitTransformer = new DefaultTransformer(m, x.transformer);
		                        methodLowLevel.adopt(traitLowLevel, traitTransformer);
		                    });
		                }
		            });
		        });
		        var resources = resource.resources();
		        resources.forEach(function (x) { return _this.processResource(x); });
		    };
		    TraitsAndResourceTypesExpander.prototype.collectResourceData = function (obj, arr, transformer) {
		        var _this = this;
		        if (arr === void 0) { arr = []; }
		        var ownTraits = this.extractTraits(obj);
		        var methodTraitsMap = {};
		        var methods = obj.methods();
		        methods.forEach(function (x) {
		            var methodTraits = _this.extractTraits(x);
		            if (methodTraits && methodTraits.length > 0) {
		                methodTraitsMap[x.method()] = methodTraits;
		            }
		        });
		        var rtData;
		        var rt = obj.type();
		        if (rt) {
		            rtData = this.readGenerictData(rt, this.resourceTypeMap, 'resource type', transformer);
		        }
		        arr.push({
		            resourceType: rtData,
		            traits: ownTraits,
		            methodTraits: methodTraitsMap
		        });
		        if (rtData) {
		            this.collectResourceData(rtData.node, arr, rtData.transformer);
		        }
		        return arr;
		    };
		    TraitsAndResourceTypesExpander.prototype.extractTraits = function (obj, _transformer, map) {
		        var _this = this;
		        if (map === void 0) { map = {}; }
		        var arr = [];
		        for (var i = -1; i < arr.length; i++) {
		            var gd = i < 0 ? null : arr[i];
		            var _obj = gd ? gd.node : obj;
		            var transformer = gd ? gd.transformer : _transformer;
		            _obj.is().forEach(function (x) {
		                var traitData = _this.readGenerictData(x, _this.traitMap, 'trait', transformer);
		                if (traitData) {
		                    var name = traitData.name;
		                    if (!map[name]) {
		                        map[name] = true;
		                        arr.push(traitData);
		                    }
		                }
		            });
		        }
		        if (obj instanceof RamlWrapper.MethodImpl) {
		            var mb = obj;
		        }
		        return arr;
		    };
		    TraitsAndResourceTypesExpander.prototype.readGenerictData = function (obj, globalMap, template, transformer) {
		        var value = obj.value();
		        if (typeof (value) == 'string') {
		            if (transformer) {
		                value = transformer.transform(value).value;
		            }
		            var node = globalMap[value];
		            if (node) {
		                return {
		                    name: value,
		                    transformer: null,
		                    node: node
		                };
		            }
		        }
		        else if (value instanceof hlimpl.StructuredValue) {
		            var sv = value;
		            var name = sv.valueName();
		            var params = {};
		            var node = globalMap[name];
		            //var t = hlimpl.typeFromNode(node.highLevel());
		            if (node) {
		                if (this.ramlVersion == 'RAML08' && transformer) {
		                    sv.children().forEach(function (x) { return params[x.valueName()] = transformer.transform(x.lowLevel().value()).value; });
		                }
		                else {
		                    sv.children().forEach(function (x) { return params[x.valueName()] = x.lowLevel().value(); });
		                }
		                return {
		                    name: name,
		                    transformer: new ValueTransformer(template, name, params),
		                    node: node
		                };
		            }
		        }
		        return null;
		    };
		    return TraitsAndResourceTypesExpander;
		})();
		var TransformMatches = (function () {
		    function TransformMatches(name, transformer) {
		        this.name = name;
		        this.regexp = new RegExp(TransformMatches.leftTransformRegexp.source + name + TransformMatches.rightTransformRegexp.source);
		        this.transformer = transformer;
		    }
		    TransformMatches.leftTransformRegexp = /\|\s*!\s*/;
		    TransformMatches.rightTransformRegexp = /\s*$/;
		    return TransformMatches;
		})();
		var transformers = [
		    new TransformMatches("singularize", function (arg) { return pluralize.singular(arg); }),
		    new TransformMatches("pluralize", function (arg) { return pluralize.plural(arg); }),
		    new TransformMatches("uppercase", function (arg) { return arg ? arg.toUpperCase() : arg; }),
		    new TransformMatches("lowercase", function (arg) { return arg ? arg.toLowerCase() : arg; }),
		    new TransformMatches("lowercamelcase", function (arg) {
		        if (!arg) {
		            return arg;
		        }
		        return changeCase.camelCase(arg);
		    }),
		    new TransformMatches("uppercamelcase", function (arg) {
		        if (!arg) {
		            return arg;
		        }
		        var lowerCamelCase = changeCase.camelCase(arg);
		        return lowerCamelCase[0].toUpperCase() + lowerCamelCase.substring(1, lowerCamelCase.length);
		    }),
		    new TransformMatches("lowerunderscorecase", function (arg) {
		        if (!arg) {
		            return arg;
		        }
		        var snakeCase = changeCase.snake(arg);
		        return snakeCase.toLowerCase();
		    }),
		    new TransformMatches("upperunderscorecase", function (arg) {
		        if (!arg) {
		            return arg;
		        }
		        var snakeCase = changeCase.snake(arg);
		        return snakeCase.toUpperCase();
		    }),
		    new TransformMatches("lowerhyphencase", function (arg) {
		        if (!arg) {
		            return arg;
		        }
		        var paramCase = changeCase.param(arg);
		        return paramCase.toLowerCase();
		    }),
		    new TransformMatches("upperhyphencase", function (arg) {
		        if (!arg) {
		            return arg;
		        }
		        var paramCase = changeCase.param(arg);
		        return paramCase.toUpperCase();
		    })
		];
		function getTransformNames() {
		    return transformers.map(function (transformer) { return transformer.name; });
		}
		exports.getTransformNames = getTransformNames;
		function getTransformerForOccurence(occurence) {
		    var result;
		    for (var i = 0; i < transformers.length; i++) {
		        if (occurence.match(transformers[i].regexp)) {
		            result = transformers[i].transformer;
		            break;
		        }
		    }
		    return result;
		}
		exports.getTransformerForOccurence = getTransformerForOccurence;
		var ValueTransformer = (function () {
		    function ValueTransformer(templateKind, templateName, params) {
		        this.templateKind = templateKind;
		        this.templateName = templateName;
		        this.params = params;
		    }
		    ValueTransformer.prototype.transform = function (obj) {
		        var undefParams = {};
		        var errors = [];
		        if (typeof (obj) === 'string') {
		            var str = obj;
		            var str1 = '';
		            var prev = 0;
		            for (var i = str.indexOf('<<'); i >= 0; i = str.indexOf('<<', prev)) {
		                str1 += str.substring(prev, i);
		                var i0 = i;
		                i += '<<'.length;
		                prev = str.indexOf('>>', i);
		                var paramOccurence = str.substring(i, prev);
		                prev += '>>'.length;
		                var originalString = str.substring(i0, prev);
		                var val;
		                var paramName;
		                var transformer = getTransformerForOccurence(paramOccurence);
		                if (transformer) {
		                    var ind = paramOccurence.lastIndexOf('|');
		                    paramName = paramOccurence.substring(0, ind).trim();
		                    val = this.params[paramName];
		                    if (val) {
		                        val = transformer(val);
		                    }
		                }
		                else {
		                    paramName = paramOccurence.trim();
		                    val = this.params[paramName];
		                }
		                if (!val) {
		                    undefParams[paramName] = true;
		                    val = originalString;
		                }
		                str1 += val;
		            }
		            var upArr = Object.keys(undefParams);
		            if (upArr.length > 0) {
		                var errStr = upArr.join(', ').trim();
		                var message = "Undefined " + this.templateKind + " parameter" + (upArr.length > 1 ? 's' : '') + ": " + errStr;
		                var error = {
		                    code: 3 /* MISSING_REQUIRED_PROPERTY */,
		                    isWarning: false,
		                    message: message,
		                    node: null,
		                    start: -1,
		                    end: -1,
		                    path: null
		                };
		                errors.push(error);
		            }
		            str1 += str.substring(prev, str.length);
		            return { value: str1, errors: errors };
		        }
		        else {
		            return { value: obj, errors: errors };
		        }
		    };
		    return ValueTransformer;
		})();
		var DefaultTransformer = (function (_super) {
		    __extends(DefaultTransformer, _super);
		    function DefaultTransformer(owner, delegate) {
		        _super.call(this, delegate.templateKind, delegate.templateName, null);
		        this.owner = owner;
		        this.delegate = delegate;
		    }
		    DefaultTransformer.prototype.transform = function (obj) {
		        if (obj == null) {
		            return {
		                value: obj,
		                errors: []
		            };
		        }
		        var ownResult = {
		            value: obj,
		            errors: []
		        };
		        var gotDefaultParam = false;
		        defaultParameters.forEach(function (x) { return gotDefaultParam = gotDefaultParam || obj.toString().indexOf('<<' + x) >= 0; });
		        if (gotDefaultParam) {
		            this.initParams();
		            ownResult = _super.prototype.transform.call(this, obj);
		        }
		        var result = this.delegate.transform(ownResult.value);
		        return result;
		    };
		    DefaultTransformer.prototype.initParams = function () {
		        var methodName;
		        var resourcePath = "";
		        var resourcePathName;
		        var node = this.owner.highLevel().lowLevel().originalNode().originalNode();
		        while (node) {
		            var key = node.key();
		            if (key != null) {
		                if (util.stringStartsWith(key, '/')) {
		                    if (!resourcePathName) {
		                        resourcePathName = key.replace(/[\/\{\}]/g, '');
		                    }
		                    resourcePath = key + resourcePath;
		                }
		                else {
		                    methodName = key;
		                }
		            }
		            node = node.parent();
		        }
		        this.params = {
		            resourcePath: resourcePath,
		            resourcePathName: resourcePathName
		        };
		        if (methodName) {
		            this.params['methodName'] = methodName;
		        }
		    };
		    return DefaultTransformer;
		})(ValueTransformer);
		var defaultParameters = ['resourcePath', 'resourcePathName', 'methodName'];


	/***/ },
	/* 74 */
	/***/ function(module, exports, __webpack_require__) {

		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var hl = __webpack_require__(2);
		var services = __webpack_require__(49);
		var core = __webpack_require__(75);
		var apiLoader = __webpack_require__(77);
		var helper = __webpack_require__(89);
		var RAMLLanguageElementImpl = (function (_super) {
		    __extends(RAMLLanguageElementImpl, _super);
		    function RAMLLanguageElementImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLLanguageElementImpl.prototype.wrapperClassName = function () {
		        return "RAMLLanguageElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLLanguageElementImpl.prototype.kind = function () {
		        return "RAMLLanguageElement";
		    };
		    /**
		     * The description attribute describes the intended use or meaning of the $self. This value MAY be formatted using Markdown [MARKDOWN]
		     **/
		    RAMLLanguageElementImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    return RAMLLanguageElementImpl;
		})(core.BasicNodeImpl);
		exports.RAMLLanguageElementImpl = RAMLLanguageElementImpl;
		var ValueTypeImpl = (function (_super) {
		    __extends(ValueTypeImpl, _super);
		    function ValueTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ValueTypeImpl.prototype.wrapperClassName = function () {
		        return "ValueTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ValueTypeImpl.prototype.kind = function () {
		        return "ValueType";
		    };
		    /**
		     * @return String representation of the node value
		     **/
		    ValueTypeImpl.prototype.value = function () {
		        return this.attr.value();
		    };
		    return ValueTypeImpl;
		})(core.AttributeNodeImpl);
		exports.ValueTypeImpl = ValueTypeImpl;
		var NumberTypeImpl = (function (_super) {
		    __extends(NumberTypeImpl, _super);
		    function NumberTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    NumberTypeImpl.prototype.wrapperClassName = function () {
		        return "NumberTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    NumberTypeImpl.prototype.kind = function () {
		        return "NumberType";
		    };
		    return NumberTypeImpl;
		})(ValueTypeImpl);
		exports.NumberTypeImpl = NumberTypeImpl;
		var BooleanTypeImpl = (function (_super) {
		    __extends(BooleanTypeImpl, _super);
		    function BooleanTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BooleanTypeImpl.prototype.wrapperClassName = function () {
		        return "BooleanTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BooleanTypeImpl.prototype.kind = function () {
		        return "BooleanType";
		    };
		    return BooleanTypeImpl;
		})(ValueTypeImpl);
		exports.BooleanTypeImpl = BooleanTypeImpl;
		var ReferenceImpl = (function (_super) {
		    __extends(ReferenceImpl, _super);
		    function ReferenceImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ReferenceImpl.prototype.wrapperClassName = function () {
		        return "ReferenceImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ReferenceImpl.prototype.kind = function () {
		        return "Reference";
		    };
		    /**
		     * @return StructuredValue object representing the node value
		     **/
		    ReferenceImpl.prototype.value = function () {
		        return core.toStructuredValue(this.attr);
		    };
		    return ReferenceImpl;
		})(core.AttributeNodeImpl);
		exports.ReferenceImpl = ReferenceImpl;
		var ResourceTypeRefImpl = (function (_super) {
		    __extends(ResourceTypeRefImpl, _super);
		    function ResourceTypeRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceTypeRefImpl.prototype.wrapperClassName = function () {
		        return "ResourceTypeRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceTypeRefImpl.prototype.kind = function () {
		        return "ResourceTypeRef";
		    };
		    return ResourceTypeRefImpl;
		})(ReferenceImpl);
		exports.ResourceTypeRefImpl = ResourceTypeRefImpl;
		var TraitRefImpl = (function (_super) {
		    __extends(TraitRefImpl, _super);
		    function TraitRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    TraitRefImpl.prototype.wrapperClassName = function () {
		        return "TraitRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    TraitRefImpl.prototype.kind = function () {
		        return "TraitRef";
		    };
		    return TraitRefImpl;
		})(ReferenceImpl);
		exports.TraitRefImpl = TraitRefImpl;
		var SecuritySchemeRefImpl = (function (_super) {
		    __extends(SecuritySchemeRefImpl, _super);
		    function SecuritySchemeRefImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SecuritySchemeRefImpl.prototype.wrapperClassName = function () {
		        return "SecuritySchemeRefImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SecuritySchemeRefImpl.prototype.kind = function () {
		        return "SecuritySchemeRef";
		    };
		    /**
		     * Returns the name of security scheme, this reference refers to.
		     **/
		    SecuritySchemeRefImpl.prototype.securitySchemeName = function () {
		        return helper.securitySchemeName(this);
		    };
		    /**
		     * Returns AST node of security scheme, this reference refers to, or null.
		     **/
		    SecuritySchemeRefImpl.prototype.securityScheme = function () {
		        return helper.securityScheme(this);
		    };
		    return SecuritySchemeRefImpl;
		})(ReferenceImpl);
		exports.SecuritySchemeRefImpl = SecuritySchemeRefImpl;
		var StringTypeImpl = (function (_super) {
		    __extends(StringTypeImpl, _super);
		    function StringTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    StringTypeImpl.prototype.wrapperClassName = function () {
		        return "StringTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    StringTypeImpl.prototype.kind = function () {
		        return "StringType";
		    };
		    return StringTypeImpl;
		})(ValueTypeImpl);
		exports.StringTypeImpl = StringTypeImpl;
		/**
		 * This type currently serves both for absolute and relative urls
		 **/
		var UriTemplateImpl = (function (_super) {
		    __extends(UriTemplateImpl, _super);
		    function UriTemplateImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    UriTemplateImpl.prototype.wrapperClassName = function () {
		        return "UriTemplateImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    UriTemplateImpl.prototype.kind = function () {
		        return "UriTemplate";
		    };
		    return UriTemplateImpl;
		})(StringTypeImpl);
		exports.UriTemplateImpl = UriTemplateImpl;
		/**
		 * This  type describes relative uri templates
		 **/
		var RelativeUriStringImpl = (function (_super) {
		    __extends(RelativeUriStringImpl, _super);
		    function RelativeUriStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RelativeUriStringImpl.prototype.wrapperClassName = function () {
		        return "RelativeUriStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RelativeUriStringImpl.prototype.kind = function () {
		        return "RelativeUriString";
		    };
		    return RelativeUriStringImpl;
		})(UriTemplateImpl);
		exports.RelativeUriStringImpl = RelativeUriStringImpl;
		/**
		 * This  type describes absolute uri templates
		 **/
		var FullUriTemplateStringImpl = (function (_super) {
		    __extends(FullUriTemplateStringImpl, _super);
		    function FullUriTemplateStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FullUriTemplateStringImpl.prototype.wrapperClassName = function () {
		        return "FullUriTemplateStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FullUriTemplateStringImpl.prototype.kind = function () {
		        return "FullUriTemplateString";
		    };
		    return FullUriTemplateStringImpl;
		})(UriTemplateImpl);
		exports.FullUriTemplateStringImpl = FullUriTemplateStringImpl;
		/**
		 * This  type describes fixed uris
		 **/
		var FixedUriImpl = (function (_super) {
		    __extends(FixedUriImpl, _super);
		    function FixedUriImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FixedUriImpl.prototype.wrapperClassName = function () {
		        return "FixedUriImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FixedUriImpl.prototype.kind = function () {
		        return "FixedUri";
		    };
		    return FixedUriImpl;
		})(StringTypeImpl);
		exports.FixedUriImpl = FixedUriImpl;
		/**
		 * Schema at this moment only two subtypes are supported (json schema and xsd)
		 **/
		var SchemaStringImpl = (function (_super) {
		    __extends(SchemaStringImpl, _super);
		    function SchemaStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SchemaStringImpl.prototype.wrapperClassName = function () {
		        return "SchemaStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SchemaStringImpl.prototype.kind = function () {
		        return "SchemaString";
		    };
		    return SchemaStringImpl;
		})(StringTypeImpl);
		exports.SchemaStringImpl = SchemaStringImpl;
		/**
		 * JSON schema
		 **/
		var JSonSchemaStringImpl = (function (_super) {
		    __extends(JSonSchemaStringImpl, _super);
		    function JSonSchemaStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    JSonSchemaStringImpl.prototype.wrapperClassName = function () {
		        return "JSonSchemaStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    JSonSchemaStringImpl.prototype.kind = function () {
		        return "JSonSchemaString";
		    };
		    return JSonSchemaStringImpl;
		})(SchemaStringImpl);
		exports.JSonSchemaStringImpl = JSonSchemaStringImpl;
		/**
		 * XSD schema
		 **/
		var XMLSchemaStringImpl = (function (_super) {
		    __extends(XMLSchemaStringImpl, _super);
		    function XMLSchemaStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    XMLSchemaStringImpl.prototype.wrapperClassName = function () {
		        return "XMLSchemaStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    XMLSchemaStringImpl.prototype.kind = function () {
		        return "XMLSchemaString";
		    };
		    return XMLSchemaStringImpl;
		})(SchemaStringImpl);
		exports.XMLSchemaStringImpl = XMLSchemaStringImpl;
		var ExampleStringImpl = (function (_super) {
		    __extends(ExampleStringImpl, _super);
		    function ExampleStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ExampleStringImpl.prototype.wrapperClassName = function () {
		        return "ExampleStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ExampleStringImpl.prototype.kind = function () {
		        return "ExampleString";
		    };
		    return ExampleStringImpl;
		})(StringTypeImpl);
		exports.ExampleStringImpl = ExampleStringImpl;
		var JSONExampleImpl = (function (_super) {
		    __extends(JSONExampleImpl, _super);
		    function JSONExampleImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    JSONExampleImpl.prototype.wrapperClassName = function () {
		        return "JSONExampleImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    JSONExampleImpl.prototype.kind = function () {
		        return "JSONExample";
		    };
		    return JSONExampleImpl;
		})(ExampleStringImpl);
		exports.JSONExampleImpl = JSONExampleImpl;
		var XMLExampleImpl = (function (_super) {
		    __extends(XMLExampleImpl, _super);
		    function XMLExampleImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    XMLExampleImpl.prototype.wrapperClassName = function () {
		        return "XMLExampleImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    XMLExampleImpl.prototype.kind = function () {
		        return "XMLExample";
		    };
		    return XMLExampleImpl;
		})(ExampleStringImpl);
		exports.XMLExampleImpl = XMLExampleImpl;
		var StatusCodeStringImpl = (function (_super) {
		    __extends(StatusCodeStringImpl, _super);
		    function StatusCodeStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    StatusCodeStringImpl.prototype.wrapperClassName = function () {
		        return "StatusCodeStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    StatusCodeStringImpl.prototype.kind = function () {
		        return "StatusCodeString";
		    };
		    return StatusCodeStringImpl;
		})(StringTypeImpl);
		exports.StatusCodeStringImpl = StatusCodeStringImpl;
		/**
		 * This sub type of the string represents mime types
		 **/
		var MimeTypeImpl = (function (_super) {
		    __extends(MimeTypeImpl, _super);
		    function MimeTypeImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MimeTypeImpl.prototype.wrapperClassName = function () {
		        return "MimeTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MimeTypeImpl.prototype.kind = function () {
		        return "MimeType";
		    };
		    return MimeTypeImpl;
		})(StringTypeImpl);
		exports.MimeTypeImpl = MimeTypeImpl;
		/**
		 * Mardown string is a string which can contain markdown as an extension this markdown should support links with RAML Pointers since 1.0
		 **/
		var MarkdownStringImpl = (function (_super) {
		    __extends(MarkdownStringImpl, _super);
		    function MarkdownStringImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MarkdownStringImpl.prototype.wrapperClassName = function () {
		        return "MarkdownStringImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MarkdownStringImpl.prototype.kind = function () {
		        return "MarkdownString";
		    };
		    return MarkdownStringImpl;
		})(StringTypeImpl);
		exports.MarkdownStringImpl = MarkdownStringImpl;
		var ResourceTypeImpl = (function (_super) {
		    __extends(ResourceTypeImpl, _super);
		    function ResourceTypeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResourceType(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceTypeImpl.prototype.wrapperClassName = function () {
		        return "ResourceTypeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceTypeImpl.prototype.kind = function () {
		        return "ResourceType";
		    };
		    /**
		     * Name of the resource type
		     **/
		    ResourceTypeImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    ResourceTypeImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    ResourceTypeImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    ResourceTypeImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    /**
		     * Methods that are part of this resource type definition
		     **/
		    ResourceTypeImpl.prototype.methods = function () {
		        return _super.prototype.elements.call(this, 'methods');
		    };
		    /**
		     * Instantiation of applyed traits
		     **/
		    ResourceTypeImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * Instantiation of applyed resource type
		     **/
		    ResourceTypeImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', function (attr) { return new ResourceTypeRefImpl(attr); });
		    };
		    /**
		     * securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     **/
		    ResourceTypeImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * Uri parameters of this resource
		     **/
		    ResourceTypeImpl.prototype.uriParameters = function () {
		        return _super.prototype.elements.call(this, 'uriParameters');
		    };
		    ResourceTypeImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ResourceTypeImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    return ResourceTypeImpl;
		})(RAMLLanguageElementImpl);
		exports.ResourceTypeImpl = ResourceTypeImpl;
		var HasNormalParametersImpl = (function (_super) {
		    __extends(HasNormalParametersImpl, _super);
		    function HasNormalParametersImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createHasNormalParameters(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    HasNormalParametersImpl.prototype.wrapperClassName = function () {
		        return "HasNormalParametersImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    HasNormalParametersImpl.prototype.kind = function () {
		        return "HasNormalParameters";
		    };
		    /**
		     * An APIs resources MAY be filtered (to return a subset of results) or altered (such as transforming a response body from JSON to XML format) by the use of query strings. If the resource or its method supports a query string, the query string MUST be defined by the queryParameters property
		     **/
		    HasNormalParametersImpl.prototype.queryParameters = function () {
		        return _super.prototype.elements.call(this, 'queryParameters');
		    };
		    HasNormalParametersImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    HasNormalParametersImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * Headers that allowed at this position
		     **/
		    HasNormalParametersImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    return HasNormalParametersImpl;
		})(RAMLLanguageElementImpl);
		exports.HasNormalParametersImpl = HasNormalParametersImpl;
		var ParameterImpl = (function (_super) {
		    __extends(ParameterImpl, _super);
		    function ParameterImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createParameter(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ParameterImpl.prototype.wrapperClassName = function () {
		        return "ParameterImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ParameterImpl.prototype.kind = function () {
		        return "Parameter";
		    };
		    /**
		     * name of the parameter
		     **/
		    ParameterImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    ParameterImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    ParameterImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ParameterImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * The type attribute specifies the primitive type of the parameter's resolved value. API clients MUST return/throw an error if the parameter's resolved value does not match the specified type. If type is not specified, it defaults to string.
		     **/
		    ParameterImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', this.toString);
		    };
		    /**
		     * @hidden
		     * Set type value
		     **/
		    ParameterImpl.prototype.setType = function (param) {
		        this.highLevel().attrOrCreate("type").setValue("" + param);
		        return this;
		    };
		    /**
		     * Location of the parameter (can not be edited by user)
		     **/
		    ParameterImpl.prototype.location = function () {
		        return _super.prototype.attribute.call(this, 'location', function (attr) { return new ParameterLocationImpl(attr); });
		    };
		    /**
		     * Set to true if parameter is required
		     **/
		    ParameterImpl.prototype.required = function () {
		        return _super.prototype.attribute.call(this, 'required', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set required value
		     **/
		    ParameterImpl.prototype.setRequired = function (param) {
		        this.highLevel().attrOrCreate("required").setValue("" + param);
		        return this;
		    };
		    /**
		     * The default attribute specifies the default value to use for the property if the property is omitted or its value is not specified. This SHOULD NOT be interpreted as a requirement for the client to send the default attribute's value if there is no other value to send. Instead, the default attribute's value is the value the server uses if the client does not send a value.
		     **/
		    ParameterImpl.prototype["default"] = function () {
		        return _super.prototype.attribute.call(this, 'default', this.toString);
		    };
		    /**
		     * @hidden
		     * Set default value
		     **/
		    ParameterImpl.prototype.setDefault = function (param) {
		        this.highLevel().attrOrCreate("default").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional) The example attribute shows an example value for the property. This can be used, e.g., by documentation generators to generate sample values for the property.
		     **/
		    ParameterImpl.prototype.example = function () {
		        return _super.prototype.attribute.call(this, 'example', this.toString);
		    };
		    /**
		     * @hidden
		     * Set example value
		     **/
		    ParameterImpl.prototype.setExample = function (param) {
		        this.highLevel().attrOrCreate("example").setValue("" + param);
		        return this;
		    };
		    /**
		     * The repeat attribute specifies that the parameter can be repeated. If the parameter can be used multiple times, the repeat parameter value MUST be set to 'true'. Otherwise, the default value is 'false' and the parameter may not be repeated.
		     **/
		    ParameterImpl.prototype.repeat = function () {
		        return _super.prototype.attribute.call(this, 'repeat', this.toBoolean);
		    };
		    /**
		     * @hidden
		     * Set repeat value
		     **/
		    ParameterImpl.prototype.setRepeat = function (param) {
		        this.highLevel().attrOrCreate("repeat").setValue("" + param);
		        return this;
		    };
		    return ParameterImpl;
		})(RAMLLanguageElementImpl);
		exports.ParameterImpl = ParameterImpl;
		var ParameterLocationImpl = (function () {
		    function ParameterLocationImpl(attr) {
		        this.attr = attr;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ParameterLocationImpl.prototype.wrapperClassName = function () {
		        return "ParameterLocationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ParameterLocationImpl.prototype.kind = function () {
		        return "ParameterLocation";
		    };
		    return ParameterLocationImpl;
		})();
		exports.ParameterLocationImpl = ParameterLocationImpl;
		/**
		 * Value must be a string
		 **/
		var StringTypeDeclarationImpl = (function (_super) {
		    __extends(StringTypeDeclarationImpl, _super);
		    function StringTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createStringTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    StringTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "StringTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    StringTypeDeclarationImpl.prototype.kind = function () {
		        return "StringTypeDeclaration";
		    };
		    /**
		     * (Optional, applicable only for parameters of type string) The pattern attribute is a regular expression that a parameter of type string MUST match. Regular expressions MUST follow the regular expression specification from ECMA 262/Perl 5. The pattern MAY be enclosed in double quotes for readability and clarity.
		     **/
		    StringTypeDeclarationImpl.prototype.pattern = function () {
		        return _super.prototype.attribute.call(this, 'pattern', this.toString);
		    };
		    /**
		     * @hidden
		     * Set pattern value
		     **/
		    StringTypeDeclarationImpl.prototype.setPattern = function (param) {
		        this.highLevel().attrOrCreate("pattern").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type string) The enum attribute provides an enumeration of the parameter's valid values. This MUST be an array. If the enum attribute is defined, API clients and servers MUST verify that a parameter's value matches a value in the enum array. If there is no matching value, the clients and servers MUST treat this as an error.
		     **/
		    StringTypeDeclarationImpl.prototype.enum = function () {
		        return _super.prototype.attributes.call(this, 'enum', this.toString);
		    };
		    /**
		     * @hidden
		     * Set enum value
		     **/
		    StringTypeDeclarationImpl.prototype.setEnum = function (param) {
		        this.highLevel().attrOrCreate("enum").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type string) The minLength attribute specifies the parameter value's minimum number of characters.
		     **/
		    StringTypeDeclarationImpl.prototype.minLength = function () {
		        return _super.prototype.attribute.call(this, 'minLength', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minLength value
		     **/
		    StringTypeDeclarationImpl.prototype.setMinLength = function (param) {
		        this.highLevel().attrOrCreate("minLength").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type string) The maxLength attribute specifies the parameter value's maximum number of characters.
		     **/
		    StringTypeDeclarationImpl.prototype.maxLength = function () {
		        return _super.prototype.attribute.call(this, 'maxLength', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maxLength value
		     **/
		    StringTypeDeclarationImpl.prototype.setMaxLength = function (param) {
		        this.highLevel().attrOrCreate("maxLength").setValue("" + param);
		        return this;
		    };
		    return StringTypeDeclarationImpl;
		})(ParameterImpl);
		exports.StringTypeDeclarationImpl = StringTypeDeclarationImpl;
		/**
		 * Value must be a boolean
		 **/
		var BooleanTypeDeclarationImpl = (function (_super) {
		    __extends(BooleanTypeDeclarationImpl, _super);
		    function BooleanTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createBooleanTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BooleanTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "BooleanTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BooleanTypeDeclarationImpl.prototype.kind = function () {
		        return "BooleanTypeDeclaration";
		    };
		    return BooleanTypeDeclarationImpl;
		})(ParameterImpl);
		exports.BooleanTypeDeclarationImpl = BooleanTypeDeclarationImpl;
		/**
		 * Value MUST be a number. Indicate floating point numbers as defined by YAML.
		 **/
		var NumberTypeDeclarationImpl = (function (_super) {
		    __extends(NumberTypeDeclarationImpl, _super);
		    function NumberTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createNumberTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    NumberTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "NumberTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    NumberTypeDeclarationImpl.prototype.kind = function () {
		        return "NumberTypeDeclaration";
		    };
		    /**
		     * (Optional, applicable only for parameters of type number or integer) The minimum attribute specifies the parameter's minimum value.
		     **/
		    NumberTypeDeclarationImpl.prototype.minimum = function () {
		        return _super.prototype.attribute.call(this, 'minimum', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set minimum value
		     **/
		    NumberTypeDeclarationImpl.prototype.setMinimum = function (param) {
		        this.highLevel().attrOrCreate("minimum").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional, applicable only for parameters of type number or integer) The maximum attribute specifies the parameter's maximum value.
		     **/
		    NumberTypeDeclarationImpl.prototype.maximum = function () {
		        return _super.prototype.attribute.call(this, 'maximum', this.toNumber);
		    };
		    /**
		     * @hidden
		     * Set maximum value
		     **/
		    NumberTypeDeclarationImpl.prototype.setMaximum = function (param) {
		        this.highLevel().attrOrCreate("maximum").setValue("" + param);
		        return this;
		    };
		    return NumberTypeDeclarationImpl;
		})(ParameterImpl);
		exports.NumberTypeDeclarationImpl = NumberTypeDeclarationImpl;
		/**
		 * Value MUST be a integer.
		 **/
		var IntegerTypeDeclarationImpl = (function (_super) {
		    __extends(IntegerTypeDeclarationImpl, _super);
		    function IntegerTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createIntegerTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    IntegerTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "IntegerTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    IntegerTypeDeclarationImpl.prototype.kind = function () {
		        return "IntegerTypeDeclaration";
		    };
		    return IntegerTypeDeclarationImpl;
		})(NumberTypeDeclarationImpl);
		exports.IntegerTypeDeclarationImpl = IntegerTypeDeclarationImpl;
		/**
		 * Value MUST be a string representation of a date as defined in RFC2616 Section 3.3 [RFC2616].
		 **/
		var DateTypeDeclarationImpl = (function (_super) {
		    __extends(DateTypeDeclarationImpl, _super);
		    function DateTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createDateTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DateTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "DateTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DateTypeDeclarationImpl.prototype.kind = function () {
		        return "DateTypeDeclaration";
		    };
		    return DateTypeDeclarationImpl;
		})(ParameterImpl);
		exports.DateTypeDeclarationImpl = DateTypeDeclarationImpl;
		/**
		 * (Applicable only to Form properties) Value is a file. Client generators SHOULD use this type to handle file uploads correctly.
		 **/
		var FileTypeDeclarationImpl = (function (_super) {
		    __extends(FileTypeDeclarationImpl, _super);
		    function FileTypeDeclarationImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createFileTypeDeclaration(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    FileTypeDeclarationImpl.prototype.wrapperClassName = function () {
		        return "FileTypeDeclarationImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    FileTypeDeclarationImpl.prototype.kind = function () {
		        return "FileTypeDeclaration";
		    };
		    return FileTypeDeclarationImpl;
		})(ParameterImpl);
		exports.FileTypeDeclarationImpl = FileTypeDeclarationImpl;
		var MethodBaseImpl = (function (_super) {
		    __extends(MethodBaseImpl, _super);
		    function MethodBaseImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createMethodBase(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MethodBaseImpl.prototype.wrapperClassName = function () {
		        return "MethodBaseImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MethodBaseImpl.prototype.kind = function () {
		        return "MethodBase";
		    };
		    /**
		     * Resource methods MAY have one or more responses. Responses MAY be described using the description property, and MAY include example attributes or schema properties.
		     **/
		    MethodBaseImpl.prototype.responses = function () {
		        return _super.prototype.elements.call(this, 'responses');
		    };
		    /**
		     * Some method verbs expect the resource to be sent as a request body. For example, to create a resource, the request must include the details of the resource to create.
		     * Resources CAN have alternate representations. For example, an API might support both JSON and XML representations.
		     * A method's body is defined in the body property as a hashmap, in which the key MUST be a valid media type.
		     **/
		    MethodBaseImpl.prototype.body = function () {
		        return _super.prototype.elements.call(this, 'body');
		    };
		    /**
		     * Instantiation of applyed traits
		     **/
		    MethodBaseImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * A list of the security schemas to apply, these must be defined in the securitySchemes declaration.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     * Security schemas may also be applied to a resource with securedBy, which is equivalent to applying the security schemas to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     **/
		    MethodBaseImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    return MethodBaseImpl;
		})(HasNormalParametersImpl);
		exports.MethodBaseImpl = MethodBaseImpl;
		var ResponseImpl = (function (_super) {
		    __extends(ResponseImpl, _super);
		    function ResponseImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResponse(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResponseImpl.prototype.wrapperClassName = function () {
		        return "ResponseImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResponseImpl.prototype.kind = function () {
		        return "Response";
		    };
		    /**
		     * Responses MUST be a map of one or more HTTP status codes, where each status code itself is a map that describes that status code.
		     **/
		    ResponseImpl.prototype.code = function () {
		        return _super.prototype.attribute.call(this, 'code', function (attr) { return new StatusCodeStringImpl(attr); });
		    };
		    /**
		     * An API's methods may support custom header values in responses. The custom, non-standard HTTP headers MUST be specified by the headers property.
		     * API's may include the the placeholder token {?} in a header name to indicate that any number of headers that conform to the specified format can be sent in responses. This is particularly useful for APIs that allow HTTP headers that conform to some naming convention to send arbitrary, custom data.
		     *
		     * In the following example, the header x-metadata-{?} is used to send metadata that has been saved with the media.
		     **/
		    ResponseImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    /**
		     * Each response MAY contain a body property, which conforms to the same structure as request body properties (see Body). Responses that can return more than one response code MAY therefore have multiple bodies defined.
		     * For APIs without a priori knowledge of the response types for their responses, "* /*" MAY be used to indicate that responses that do not matching other defined data types MUST be accepted. Processing applications MUST match the most descriptive media type first if "* /*" is used.
		     **/
		    ResponseImpl.prototype.body = function () {
		        return _super.prototype.elements.call(this, 'body');
		    };
		    /**
		     * true for codes < 400 and false otherwise
		     **/
		    ResponseImpl.prototype.isOkRange = function () {
		        return helper.isOkRange(this);
		    };
		    return ResponseImpl;
		})(RAMLLanguageElementImpl);
		exports.ResponseImpl = ResponseImpl;
		var BodyLikeImpl = (function (_super) {
		    __extends(BodyLikeImpl, _super);
		    function BodyLikeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createBodyLike(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BodyLikeImpl.prototype.wrapperClassName = function () {
		        return "BodyLikeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BodyLikeImpl.prototype.kind = function () {
		        return "BodyLike";
		    };
		    /**
		     * Mime type of the request or response body
		     **/
		    BodyLikeImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    BodyLikeImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * The structure of a request or response body MAY be further specified by the schema property under the appropriate media type.
		     *
		     * The schema key CANNOT be specified if a body's media type is application/x-www-form-urlencoded or multipart/form-data.
		     *
		     * All parsers of RAML MUST be able to interpret JSON Schema [JSON_SCHEMA] and XML Schema [XML_SCHEMA].
		     *
		     * Schema MAY be declared inline or in an external file. However, if the schema is sufficiently large so as to make it difficult for a person to read the API definition, or the schema is reused across multiple APIs or across multiple miles in the same API, the !include user-defined data type SHOULD be used instead of including the content inline.
		     * Alternatively, the value of the schema field MAY be the name of a schema specified in the root-level schemas property (see Named Parameters, or it MAY be declared in an external file and included by using the by using the RAML !include user-defined data type.
		     **/
		    BodyLikeImpl.prototype.schema = function () {
		        return _super.prototype.attribute.call(this, 'schema', function (attr) { return new SchemaStringImpl(attr); });
		    };
		    /**
		     * Documentation generators MUST use body properties' example attributes to generate example invocations.
		     * This example shows example attributes for two body property media types.
		     **/
		    BodyLikeImpl.prototype.example = function () {
		        return _super.prototype.attribute.call(this, 'example', function (attr) { return new ExampleStringImpl(attr); });
		    };
		    /**
		     * Web forms REQUIRE special encoding and custom declaration.
		     * If the API's media type is either application/x-www-form-urlencoded or multipart/form-data, the formParameters property MUST specify the name-value pairs that the API is expecting.
		     * The formParameters property is a map in which the key is the name of the web form parameter, and the value is itself a map the specifies the web form parameter's attributes
		     **/
		    BodyLikeImpl.prototype.formParameters = function () {
		        return _super.prototype.elements.call(this, 'formParameters');
		    };
		    /**
		     * Returns schema content for the cases when schema is inlined, when schema is included, and when schema is a reference.
		     **/
		    BodyLikeImpl.prototype.schemaContent = function () {
		        return helper.schemaContent(this);
		    };
		    return BodyLikeImpl;
		})(RAMLLanguageElementImpl);
		exports.BodyLikeImpl = BodyLikeImpl;
		/**
		 * Needed to set connection between xml related mime types and xsd schema
		 **/
		var XMLBodyImpl = (function (_super) {
		    __extends(XMLBodyImpl, _super);
		    function XMLBodyImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createXMLBody(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    XMLBodyImpl.prototype.wrapperClassName = function () {
		        return "XMLBodyImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    XMLBodyImpl.prototype.kind = function () {
		        return "XMLBody";
		    };
		    /**
		     * XSD Schema
		     **/
		    XMLBodyImpl.prototype.schema = function () {
		        return _super.prototype.attribute.call(this, 'schema', function (attr) { return new XMLSchemaStringImpl(attr); });
		    };
		    return XMLBodyImpl;
		})(BodyLikeImpl);
		exports.XMLBodyImpl = XMLBodyImpl;
		/**
		 * Needed to set connection between json related mime types and json schema
		 **/
		var JSONBodyImpl = (function (_super) {
		    __extends(JSONBodyImpl, _super);
		    function JSONBodyImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createJSONBody(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    JSONBodyImpl.prototype.wrapperClassName = function () {
		        return "JSONBodyImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    JSONBodyImpl.prototype.kind = function () {
		        return "JSONBody";
		    };
		    /**
		     * JSON Schema
		     **/
		    JSONBodyImpl.prototype.schema = function () {
		        return _super.prototype.attribute.call(this, 'schema', function (attr) { return new JSonSchemaStringImpl(attr); });
		    };
		    return JSONBodyImpl;
		})(BodyLikeImpl);
		exports.JSONBodyImpl = JSONBodyImpl;
		var TraitImpl = (function (_super) {
		    __extends(TraitImpl, _super);
		    function TraitImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createTrait(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    TraitImpl.prototype.wrapperClassName = function () {
		        return "TraitImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    TraitImpl.prototype.kind = function () {
		        return "Trait";
		    };
		    /**
		     * Name of the trait
		     **/
		    TraitImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    TraitImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    TraitImpl.prototype.usage = function () {
		        return _super.prototype.attribute.call(this, 'usage', this.toString);
		    };
		    /**
		     * @hidden
		     * Set usage value
		     **/
		    TraitImpl.prototype.setUsage = function (param) {
		        this.highLevel().attrOrCreate("usage").setValue("" + param);
		        return this;
		    };
		    return TraitImpl;
		})(MethodBaseImpl);
		exports.TraitImpl = TraitImpl;
		var SecuritySchemePartImpl = (function (_super) {
		    __extends(SecuritySchemePartImpl, _super);
		    function SecuritySchemePartImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createSecuritySchemePart(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SecuritySchemePartImpl.prototype.wrapperClassName = function () {
		        return "SecuritySchemePartImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SecuritySchemePartImpl.prototype.kind = function () {
		        return "SecuritySchemePart";
		    };
		    /**
		     * Headers that allowed at this position
		     **/
		    SecuritySchemePartImpl.prototype.headers = function () {
		        return _super.prototype.elements.call(this, 'headers');
		    };
		    /**
		     * An APIs resources MAY be filtered (to return a subset of results) or altered (such as transforming a response body from JSON to XML format) by the use of query strings. If the resource or its method supports a query string, the query string MUST be defined by the queryParameters property
		     **/
		    SecuritySchemePartImpl.prototype.queryParameters = function () {
		        return _super.prototype.elements.call(this, 'queryParameters');
		    };
		    /**
		     * Optional array of responses, describing the possible responses that could be sent.
		     **/
		    SecuritySchemePartImpl.prototype.responses = function () {
		        return _super.prototype.elements.call(this, 'responses');
		    };
		    /**
		     * Instantiation of applyed traits
		     **/
		    SecuritySchemePartImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * A list of the security schemas to apply, these must be defined in the securitySchemes declaration.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     * Security schemas may also be applied to a resource with securedBy, which is equivalent to applying the security schemas to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     **/
		    SecuritySchemePartImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * An alternate, human-friendly name for the security scheme part
		     **/
		    SecuritySchemePartImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    SecuritySchemePartImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A longer, human-friendly description of the security scheme part
		     **/
		    SecuritySchemePartImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    return SecuritySchemePartImpl;
		})(MethodBaseImpl);
		exports.SecuritySchemePartImpl = SecuritySchemePartImpl;
		/**
		 * Method object allows description of http methods
		 **/
		var MethodImpl = (function (_super) {
		    __extends(MethodImpl, _super);
		    function MethodImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createMethod(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    MethodImpl.prototype.wrapperClassName = function () {
		        return "MethodImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    MethodImpl.prototype.kind = function () {
		        return "Method";
		    };
		    /**
		     * Method that can be called
		     **/
		    MethodImpl.prototype.method = function () {
		        return _super.prototype.attribute.call(this, 'method', this.toString);
		    };
		    /**
		     * @hidden
		     * Set method value
		     **/
		    MethodImpl.prototype.setMethod = function (param) {
		        this.highLevel().attrOrCreate("method").setValue("" + param);
		        return this;
		    };
		    /**
		     * A method can override an API's protocols value for that single method by setting a different value for the fields.
		     **/
		    MethodImpl.prototype.protocols = function () {
		        return _super.prototype.attributes.call(this, 'protocols', this.toString);
		    };
		    /**
		     * @hidden
		     * Set protocols value
		     **/
		    MethodImpl.prototype.setProtocols = function (param) {
		        this.highLevel().attrOrCreate("protocols").setValue("" + param);
		        return this;
		    };
		    /**
		     * securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     **/
		    MethodImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * For methods of Resources returns parent resource. For methods of ResourceTypes returns null.
		     **/
		    MethodImpl.prototype.parentResource = function () {
		        return helper.parentResource(this);
		    };
		    /**
		     * Api owning the resource as a sibling
		     **/
		    MethodImpl.prototype.ownerApi = function () {
		        return helper.ownerApi(this);
		    };
		    /**
		     * For methods of Resources: `{parent Resource relative path} {methodName}`.
		     * For methods of ResourceTypes: `{parent ResourceType name} {methodName}`.
		     * For other methods throws Exception.
		     **/
		    MethodImpl.prototype.methodId = function () {
		        return helper.methodId(this);
		    };
		    /**
		     * Returns security schemes, resource or method is secured with. If no security schemes are set at resource or method level,
		     * returns schemes defined with `securedBy` at API level.
		     **/
		    MethodImpl.prototype.allSecuredBy = function () {
		        return helper.allSecuredBy(this);
		    };
		    return MethodImpl;
		})(MethodBaseImpl);
		exports.MethodImpl = MethodImpl;
		var ResourceImpl = (function (_super) {
		    __extends(ResourceImpl, _super);
		    function ResourceImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createResource(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ResourceImpl.prototype.wrapperClassName = function () {
		        return "ResourceImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ResourceImpl.prototype.kind = function () {
		        return "Resource";
		    };
		    /**
		     * Relative URL of this resource from the parent resource
		     **/
		    ResourceImpl.prototype.relativeUri = function () {
		        return _super.prototype.attribute.call(this, 'relativeUri', function (attr) { return new RelativeUriStringImpl(attr); });
		    };
		    /**
		     * Instantiation of applyed resource type
		     **/
		    ResourceImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', function (attr) { return new ResourceTypeRefImpl(attr); });
		    };
		    /**
		     * Instantiation of applyed traits
		     **/
		    ResourceImpl.prototype.is = function () {
		        return _super.prototype.attributes.call(this, 'is', function (attr) { return new TraitRefImpl(attr); });
		    };
		    /**
		     * securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.
		     * To indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.
		     **/
		    ResourceImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * Uri parameters of this resource
		     **/
		    ResourceImpl.prototype.uriParameters = function () {
		        return _super.prototype.elements.call(this, 'uriParameters');
		    };
		    /**
		     * Methods that can be called on this resource
		     **/
		    ResourceImpl.prototype.methods = function () {
		        return _super.prototype.elements.call(this, 'methods');
		    };
		    /**
		     * Children resources
		     **/
		    ResourceImpl.prototype.resources = function () {
		        return _super.prototype.elements.call(this, 'resources');
		    };
		    ResourceImpl.prototype.displayName = function () {
		        return _super.prototype.attribute.call(this, 'displayName', this.toString);
		    };
		    /**
		     * @hidden
		     * Set displayName value
		     **/
		    ResourceImpl.prototype.setDisplayName = function (param) {
		        this.highLevel().attrOrCreate("displayName").setValue("" + param);
		        return this;
		    };
		    /**
		     * A resource or a method can override a base URI template's values. This is useful to restrict or change the default or parameter selection in the base URI. The baseUriParameters property MAY be used to override any or all parameters defined at the root level baseUriParameters property, as well as base URI parameters not specified at the root level.
		     **/
		    ResourceImpl.prototype.baseUriParameters = function () {
		        return _super.prototype.elements.call(this, 'baseUriParameters');
		    };
		    /**
		     * Path relative to API root
		     **/
		    ResourceImpl.prototype.completeRelativeUri = function () {
		        return helper.completeRelativeUri(this);
		    };
		    /**
		     * baseUri of owning Api concatenated with completeRelativeUri
		     **/
		    ResourceImpl.prototype.absoluteUri = function () {
		        return helper.absoluteUri(this);
		    };
		    /**
		     * Parent resource for non top level resources
		     **/
		    ResourceImpl.prototype.parentResource = function () {
		        return helper.parent(this);
		    };
		    /**
		     * Get child resource by its relative path
		     **/
		    ResourceImpl.prototype.childResource = function (relPath) {
		        return helper.childResource(this, relPath);
		    };
		    /**
		     * Get child method by its name
		     **/
		    ResourceImpl.prototype.childMethod = function (method) {
		        return helper.childMethod(this, method);
		    };
		    /**
		     * Api owning the resource as a sibling
		     **/
		    ResourceImpl.prototype.ownerApi = function () {
		        return helper.ownerApi(this);
		    };
		    /**
		     * Retrieve an ordered list of all uri parameters including those which are not described in the `uriParameters` node.
		     * Consider a fragment of RAML specification:
		     * ```yaml
		     * /resource/{objectId}/{propertyId}:
		     * uriParameters:
		     * objectId:
		     * ```
		     * Here `propertyId` uri parameter is not described in the `uriParameters` node.
		     * Thus, it is not among Resource.uriParameters(), but it is among Resource.allUriParameters().
		     **/
		    ResourceImpl.prototype.allUriParameters = function () {
		        return helper.uriParameters(this);
		    };
		    /**
		     * Retrieve an ordered list of all absolute uri parameters. Returns a union of `Api.allBaseUriParameters()`
		     * for `Api` owning the `Resource` and `Resource.allUriParameters()`.
		     **/
		    ResourceImpl.prototype.absoluteUriParameters = function () {
		        return helper.absoluteUriParameters(this);
		    };
		    /**
		     * Returns security schemes, resource or method is secured with. If no security schemes are set at resource or method level,
		     * returns schemes defined with `securedBy` at API level.
		     **/
		    ResourceImpl.prototype.allSecuredBy = function () {
		        return helper.allSecuredBy(this);
		    };
		    return ResourceImpl;
		})(RAMLLanguageElementImpl);
		exports.ResourceImpl = ResourceImpl;
		/**
		 * Declares globally referable security schema definition
		 **/
		var AbstractSecuritySchemeImpl = (function (_super) {
		    __extends(AbstractSecuritySchemeImpl, _super);
		    function AbstractSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createAbstractSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    AbstractSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "AbstractSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    AbstractSecuritySchemeImpl.prototype.kind = function () {
		        return "AbstractSecurityScheme";
		    };
		    AbstractSecuritySchemeImpl.prototype.name = function () {
		        return _super.prototype.attribute.call(this, 'name', this.toString);
		    };
		    /**
		     * @hidden
		     * Set name value
		     **/
		    AbstractSecuritySchemeImpl.prototype.setName = function (param) {
		        this.highLevel().attrOrCreate("name").setValue("" + param);
		        return this;
		    };
		    /**
		     * The securitySchemes property MUST be used to specify an API's security mechanisms, including the required settings and the authentication methods that the API supports. one authentication method is allowed if the API supports them.
		     **/
		    AbstractSecuritySchemeImpl.prototype["type"] = function () {
		        return _super.prototype.attribute.call(this, 'type', this.toString);
		    };
		    /**
		     * @hidden
		     * Set type value
		     **/
		    AbstractSecuritySchemeImpl.prototype.setType = function (param) {
		        this.highLevel().attrOrCreate("type").setValue("" + param);
		        return this;
		    };
		    /**
		     * The description MAY be used to describe a securityScheme.
		     **/
		    AbstractSecuritySchemeImpl.prototype.description = function () {
		        return _super.prototype.attribute.call(this, 'description', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    /**
		     * A description of the request components related to Security that are determined by the scheme: the headers, query parameters or responses. As a best practice, even for standard security schemes, API designers SHOULD describe these properties of security schemes.
		     * Including the security scheme description completes an API documentation.
		     **/
		    AbstractSecuritySchemeImpl.prototype.describedBy = function () {
		        return _super.prototype.element.call(this, 'describedBy');
		    };
		    /**
		     * The settings attribute MAY be used to provide security scheme-specific information. The required attributes vary depending on the type of security scheme is being declared.
		     * It describes the minimum set of properties which any processing application MUST provide and validate if it chooses to implement the security scheme. Processing applications MAY choose to recognize other properties for things such as token lifetime, preferred cryptographic algorithms, and more.
		     **/
		    AbstractSecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return AbstractSecuritySchemeImpl;
		})(RAMLLanguageElementImpl);
		exports.AbstractSecuritySchemeImpl = AbstractSecuritySchemeImpl;
		var SecuritySchemeSettingsImpl = (function (_super) {
		    __extends(SecuritySchemeSettingsImpl, _super);
		    function SecuritySchemeSettingsImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    SecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "SecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    SecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "SecuritySchemeSettings";
		    };
		    return SecuritySchemeSettingsImpl;
		})(core.BasicNodeImpl);
		exports.SecuritySchemeSettingsImpl = SecuritySchemeSettingsImpl;
		var OAuth1SecuritySchemeSettingsImpl = (function (_super) {
		    __extends(OAuth1SecuritySchemeSettingsImpl, _super);
		    function OAuth1SecuritySchemeSettingsImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth1SecuritySchemeSettings(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "OAuth1SecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "OAuth1SecuritySchemeSettings";
		    };
		    /**
		     * The URI of the Temporary Credential Request endpoint as defined in RFC5849 Section 2.1
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.requestTokenUri = function () {
		        return _super.prototype.attribute.call(this, 'requestTokenUri', function (attr) { return new FixedUriImpl(attr); });
		    };
		    /**
		     * The URI of the Resource Owner Authorization endpoint as defined in RFC5849 Section 2.2
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.authorizationUri = function () {
		        return _super.prototype.attribute.call(this, 'authorizationUri', function (attr) { return new FixedUriImpl(attr); });
		    };
		    /**
		     * The URI of the Token Request endpoint as defined in RFC5849 Section 2.3
		     **/
		    OAuth1SecuritySchemeSettingsImpl.prototype.tokenCredentialsUri = function () {
		        return _super.prototype.attribute.call(this, 'tokenCredentialsUri', function (attr) { return new FixedUriImpl(attr); });
		    };
		    return OAuth1SecuritySchemeSettingsImpl;
		})(SecuritySchemeSettingsImpl);
		exports.OAuth1SecuritySchemeSettingsImpl = OAuth1SecuritySchemeSettingsImpl;
		var OAuth2SecuritySchemeSettingsImpl = (function (_super) {
		    __extends(OAuth2SecuritySchemeSettingsImpl, _super);
		    function OAuth2SecuritySchemeSettingsImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth2SecuritySchemeSettings(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.wrapperClassName = function () {
		        return "OAuth2SecuritySchemeSettingsImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.kind = function () {
		        return "OAuth2SecuritySchemeSettings";
		    };
		    /**
		     * The URI of the Token Endpoint as defined in RFC6749 [RFC6748] Section 3.2. Not required forby implicit grant type.
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.accessTokenUri = function () {
		        return _super.prototype.attribute.call(this, 'accessTokenUri', function (attr) { return new FixedUriImpl(attr); });
		    };
		    /**
		     * The URI of the Authorization Endpoint as defined in RFC6749 [RFC6748] Section 3.1. Required forby authorization_code and implicit grant types.
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.authorizationUri = function () {
		        return _super.prototype.attribute.call(this, 'authorizationUri', function (attr) { return new FixedUriImpl(attr); });
		    };
		    OAuth2SecuritySchemeSettingsImpl.prototype.authorizationGrants = function () {
		        return _super.prototype.attributes.call(this, 'authorizationGrants', this.toString);
		    };
		    /**
		     * @hidden
		     * Set authorizationGrants value
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.setAuthorizationGrants = function (param) {
		        this.highLevel().attrOrCreate("authorizationGrants").setValue("" + param);
		        return this;
		    };
		    /**
		     * A list of scopes supported by the security scheme as defined in RFC6749 [RFC6749] Section 3.3
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.scopes = function () {
		        return _super.prototype.attributes.call(this, 'scopes', this.toString);
		    };
		    /**
		     * @hidden
		     * Set scopes value
		     **/
		    OAuth2SecuritySchemeSettingsImpl.prototype.setScopes = function (param) {
		        this.highLevel().attrOrCreate("scopes").setValue("" + param);
		        return this;
		    };
		    return OAuth2SecuritySchemeSettingsImpl;
		})(SecuritySchemeSettingsImpl);
		exports.OAuth2SecuritySchemeSettingsImpl = OAuth2SecuritySchemeSettingsImpl;
		/**
		 * Declares globally referable security schema definition
		 **/
		var OAuth2SecuritySchemeImpl = (function (_super) {
		    __extends(OAuth2SecuritySchemeImpl, _super);
		    function OAuth2SecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth2SecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth2SecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "OAuth2SecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth2SecuritySchemeImpl.prototype.kind = function () {
		        return "OAuth2SecurityScheme";
		    };
		    OAuth2SecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return OAuth2SecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.OAuth2SecuritySchemeImpl = OAuth2SecuritySchemeImpl;
		/**
		 * Declares globally referable security schema definition
		 **/
		var OAuth1SecuritySchemeImpl = (function (_super) {
		    __extends(OAuth1SecuritySchemeImpl, _super);
		    function OAuth1SecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createOAuth1SecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    OAuth1SecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "OAuth1SecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    OAuth1SecuritySchemeImpl.prototype.kind = function () {
		        return "OAuth1SecurityScheme";
		    };
		    OAuth1SecuritySchemeImpl.prototype.settings = function () {
		        return _super.prototype.element.call(this, 'settings');
		    };
		    return OAuth1SecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.OAuth1SecuritySchemeImpl = OAuth1SecuritySchemeImpl;
		/**
		 * Declares globally referable security schema definition
		 **/
		var BasicSecuritySchemeImpl = (function (_super) {
		    __extends(BasicSecuritySchemeImpl, _super);
		    function BasicSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createBasicSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    BasicSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "BasicSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    BasicSecuritySchemeImpl.prototype.kind = function () {
		        return "BasicSecurityScheme";
		    };
		    return BasicSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.BasicSecuritySchemeImpl = BasicSecuritySchemeImpl;
		/**
		 * Declares globally referable security schema definition
		 **/
		var DigestSecuritySchemeImpl = (function (_super) {
		    __extends(DigestSecuritySchemeImpl, _super);
		    function DigestSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createDigestSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DigestSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "DigestSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DigestSecuritySchemeImpl.prototype.kind = function () {
		        return "DigestSecurityScheme";
		    };
		    return DigestSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.DigestSecuritySchemeImpl = DigestSecuritySchemeImpl;
		/**
		 * Declares globally referable security schema definition
		 **/
		var CustomSecuritySchemeImpl = (function (_super) {
		    __extends(CustomSecuritySchemeImpl, _super);
		    function CustomSecuritySchemeImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createCustomSecurityScheme(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    CustomSecuritySchemeImpl.prototype.wrapperClassName = function () {
		        return "CustomSecuritySchemeImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    CustomSecuritySchemeImpl.prototype.kind = function () {
		        return "CustomSecurityScheme";
		    };
		    return CustomSecuritySchemeImpl;
		})(AbstractSecuritySchemeImpl);
		exports.CustomSecuritySchemeImpl = CustomSecuritySchemeImpl;
		var ApiImpl = (function (_super) {
		    __extends(ApiImpl, _super);
		    function ApiImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createApi(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    ApiImpl.prototype.wrapperClassName = function () {
		        return "ApiImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    ApiImpl.prototype.kind = function () {
		        return "Api";
		    };
		    /**
		     * The title property is a short plain text description of the RESTful API. The title property's value SHOULD be suitable for use as a title for the contained user documentation.
		     **/
		    ApiImpl.prototype.title = function () {
		        return _super.prototype.attribute.call(this, 'title', this.toString);
		    };
		    /**
		     * @hidden
		     * Set title value
		     **/
		    ApiImpl.prototype.setTitle = function (param) {
		        this.highLevel().attrOrCreate("title").setValue("" + param);
		        return this;
		    };
		    /**
		     * If the RAML API definition is targeted to a specific API version, the API definition MUST contain a version property. The version property is OPTIONAL and should not be used if:
		     * The API itself is not versioned.
		     * The API definition does not change between versions. The API architect can decide whether a change to user documentation elements, but no change to the API's resources, constitutes a version change.
		     * The API architect MAY use any versioning scheme so long as version numbers retain the same format. For example, "v3", "v3.0", and "V3" are all allowed, but are not considered to be equal.
		     **/
		    ApiImpl.prototype.version = function () {
		        return _super.prototype.attribute.call(this, 'version', this.toString);
		    };
		    /**
		     * @hidden
		     * Set version value
		     **/
		    ApiImpl.prototype.setVersion = function (param) {
		        this.highLevel().attrOrCreate("version").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional during development; Required after implementation) A RESTful API's resources are defined relative to the API's base URI. The use of the baseUri field is OPTIONAL to allow describing APIs that have not yet been implemented. After the API is implemented (even a mock implementation) and can be accessed at a service endpoint, the API definition MUST contain a baseUri property. The baseUri property's value MUST conform to the URI specification [RFC2396] or a Level 1 Template URI as defined in RFC 6570 [RFC6570].
		     * The baseUri property SHOULD only be used as a reference value. API client generators MAY make the baseUri configurable by the API client's users.
		     * If the baseUri value is a Level 1 Template URI, the following reserved base URI parameters are available for replacement:
		     **/
		    ApiImpl.prototype.baseUri = function () {
		        return _super.prototype.attribute.call(this, 'baseUri', function (attr) { return new FullUriTemplateStringImpl(attr); });
		    };
		    /**
		     * Base uri parameters are named parameters which described template parameters in the base uri
		     **/
		    ApiImpl.prototype.baseUriParameters = function () {
		        return _super.prototype.elements.call(this, 'baseUriParameters');
		    };
		    /**
		     * URI parameters can be further defined by using the uriParameters property. The use of uriParameters is OPTIONAL. The uriParameters property MUST be a map in which each key MUST be the name of the URI parameter as defined in the baseUri property. The uriParameters CANNOT contain a key named version because it is a reserved URI parameter name. The value of the uriParameters property is itself a map that specifies  the property's attributes as named parameters
		     **/
		    ApiImpl.prototype.uriParameters = function () {
		        return _super.prototype.elements.call(this, 'uriParameters');
		    };
		    /**
		     * A RESTful API can be reached HTTP, HTTPS, or both. The protocols property MAY be used to specify the protocols that an API supports. If the protocols property is not specified, the protocol specified at the baseUri property is used. The protocols property MUST be an array of strings, of values `HTTP` and/or `HTTPS`.
		     **/
		    ApiImpl.prototype.protocols = function () {
		        return _super.prototype.attributes.call(this, 'protocols', this.toString);
		    };
		    /**
		     * @hidden
		     * Set protocols value
		     **/
		    ApiImpl.prototype.setProtocols = function (param) {
		        this.highLevel().attrOrCreate("protocols").setValue("" + param);
		        return this;
		    };
		    /**
		     * (Optional) The media types returned by API responses, and expected from API requests that accept a body, MAY be defaulted by specifying the mediaType property. This property is specified at the root level of the API definition. The property's value MAY be a single string with a valid media type:
		     * One of the following YAML media types:
		     * text/yaml
		     * text/x-yaml
		     * application/yaml
		     * application/x-yaml*
		     * Any type from the list of IANA MIME Media Types, http://www.iana.org/assignments/media-types
		     * A custom type that conforms to the regular expression, "application/[A-Za-z.-0-1]*+?(json|xml)"
		     * For any combination of resource and operation in the API, if a media type is specified as a key of the body property for that resource and operation, or if a media type is specified in the mediaType property, the body MUST be in the specified media types. Moreover, if the client specifies an Accepts header containing multiple media types that are allowed by the specification for the requested resource and operation, the server SHOULD return a body using the media type in the Accepts header's mediaType list.
		     **/
		    ApiImpl.prototype.mediaType = function () {
		        return _super.prototype.attribute.call(this, 'mediaType', function (attr) { return new MimeTypeImpl(attr); });
		    };
		    /**
		     * To better achieve consistency and simplicity, the API definition SHOULD include an OPTIONAL schemas property in the root section. The schemas property specifies collections of schemas that could be used anywhere in the API definition. The value of the schemas property is an array of maps; in each map, the keys are the schema name, and the values are schema definitions. The schema definitions MAY be included inline or by using the RAML !include user-defined data type.
		     **/
		    ApiImpl.prototype.schemas = function () {
		        return _super.prototype.elements.call(this, 'schemas');
		    };
		    /**
		     * Declarations of traits used in this API
		     **/
		    ApiImpl.prototype.traits = function () {
		        return _super.prototype.elements.call(this, 'traits');
		    };
		    /**
		     * A list of the security schemas to apply to all methods, these must be defined in the securitySchemes declaration.
		     **/
		    ApiImpl.prototype.securedBy = function () {
		        return _super.prototype.attributes.call(this, 'securedBy', function (attr) { return new SecuritySchemeRefImpl(attr); });
		    };
		    /**
		     * Security schemas that can be applied with securedBy
		     **/
		    ApiImpl.prototype.securitySchemes = function () {
		        return _super.prototype.elements.call(this, 'securitySchemes');
		    };
		    /**
		     * Declaration of resource types used in this API
		     **/
		    ApiImpl.prototype.resourceTypes = function () {
		        return _super.prototype.elements.call(this, 'resourceTypes');
		    };
		    /**
		     * Resources are identified by their relative URI, which MUST begin with a slash (/).
		     * A resource defined as a root-level property is called a top-level resource. Its property's key is the resource's URI relative to the baseUri.
		     * A resource defined as a child property of another resource is called a nested resource, and its property's key is its URI relative to its parent resource's URI.
		     * Every property whose key begins with a slash (/), and is either at the root of the API definition or is the child property of a resource property, is a resource property. The key of a resource, i.e. its relative URI, MAY consist of multiple URI path fragments separated by slashes; e.g. "/bom/items" may indicate the collection of items in a bill of materials as a single resource. However, if the individual URI path fragments are themselves resources, the API definition SHOULD use nested resources to describe this structure; e.g. if "/bom" is itself a resource then "/items" should be a nested resource of "/bom", while "/bom/items" should not be used.
		     **/
		    ApiImpl.prototype.resources = function () {
		        return _super.prototype.elements.call(this, 'resources');
		    };
		    /**
		     * The API definition can include a variety of documents that serve as a user guides and reference documentation for the API. Such documents can clarify how the API works or provide business context.
		     * Documentation-generators MUST include all the sections in an API definition's documentation property in the documentation output, and they MUST preserve the order in which the documentation is declared.
		     * To add user documentation to the API, include the documentation property at the root of the API definition. The documentation property MUST be an array of documents. Each document MUST contain title and content attributes, both of which are REQUIRED. If the documentation property is specified, it MUST include at least one document.
		     * Documentation-generators MUST process the content field as if it was defined using Markdown [MARKDOWN].
		     *
		     * This example shows an API definition with a single user document.
		     **/
		    ApiImpl.prototype.documentation = function () {
		        return _super.prototype.elements.call(this, 'documentation');
		    };
		    /**
		     * Equivalent API with traits and resource types expanded
		     **/
		    ApiImpl.prototype.expand = function () {
		        return helper.expandTraitsAndResourceTypes(this);
		    };
		    /**
		     * Retrieve all traits including those defined in libraries
		     **/
		    ApiImpl.prototype.allTraits = function () {
		        return helper.allTraits(this);
		    };
		    /**
		     * Retrieve all resource types including those defined in libraries
		     **/
		    ApiImpl.prototype.allResourceTypes = function () {
		        return helper.allResourceTypes(this);
		    };
		    /**
		     * Get child resource by its relative path
		     **/
		    ApiImpl.prototype.childResource = function (relPath) {
		        return helper.childResource(this, relPath);
		    };
		    /**
		     * Retrieve all resources of the Api
		     **/
		    ApiImpl.prototype.allResources = function () {
		        return helper.allResources(this);
		    };
		    /**
		     * Retrieve an ordered list of all base uri parameters regardless of whether they are described in `baseUriParameters` or not
		     * Consider a fragment of RAML specification:
		     * ```yaml
		     * version: v1
		     * baseUri: https://{organization}.example.com/{version}/{service}
		     * baseUriParameters:
		     * service:
		     * ```
		     * Here `version` and `organization` are base uri parameters which are not described in the `baseUriParameters` node.
		     * Thus, they are not among `Api.baseUriParameters()`, but they are among `Api.allBaseUriParameters()`.
		     **/
		    ApiImpl.prototype.allBaseUriParameters = function () {
		        return helper.baseUriParameters(this);
		    };
		    /**
		     * Protocols used by the API. Returns the `protocols` property value if it is specified.
		     * Otherwise, returns protocol, specified in the base URI.
		     **/
		    ApiImpl.prototype.allProtocols = function () {
		        return helper.allProtocols(this);
		    };
		    /**
		     * Returns RAML version. "RAML10" string is returned for RAML 1.0. "RAML08" string is returned for RAML 0.8.
		     **/
		    ApiImpl.prototype.RAMLVersion = function () {
		        return helper.RAMLVersion(this);
		    };
		    return ApiImpl;
		})(RAMLLanguageElementImpl);
		exports.ApiImpl = ApiImpl;
		var RAMLSimpleElementImpl = (function (_super) {
		    __extends(RAMLSimpleElementImpl, _super);
		    function RAMLSimpleElementImpl() {
		        _super.apply(this, arguments);
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    RAMLSimpleElementImpl.prototype.wrapperClassName = function () {
		        return "RAMLSimpleElementImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    RAMLSimpleElementImpl.prototype.kind = function () {
		        return "RAMLSimpleElement";
		    };
		    return RAMLSimpleElementImpl;
		})(core.BasicNodeImpl);
		exports.RAMLSimpleElementImpl = RAMLSimpleElementImpl;
		var DocumentationItemImpl = (function (_super) {
		    __extends(DocumentationItemImpl, _super);
		    function DocumentationItemImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createDocumentationItem(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    DocumentationItemImpl.prototype.wrapperClassName = function () {
		        return "DocumentationItemImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    DocumentationItemImpl.prototype.kind = function () {
		        return "DocumentationItem";
		    };
		    /**
		     * title of documentation section
		     **/
		    DocumentationItemImpl.prototype.title = function () {
		        return _super.prototype.attribute.call(this, 'title', this.toString);
		    };
		    /**
		     * @hidden
		     * Set title value
		     **/
		    DocumentationItemImpl.prototype.setTitle = function (param) {
		        this.highLevel().attrOrCreate("title").setValue("" + param);
		        return this;
		    };
		    /**
		     * Content of documentation section
		     **/
		    DocumentationItemImpl.prototype.content = function () {
		        return _super.prototype.attribute.call(this, 'content', function (attr) { return new MarkdownStringImpl(attr); });
		    };
		    return DocumentationItemImpl;
		})(RAMLSimpleElementImpl);
		exports.DocumentationItemImpl = DocumentationItemImpl;
		/**
		 * Content of the schema
		 **/
		var GlobalSchemaImpl = (function (_super) {
		    __extends(GlobalSchemaImpl, _super);
		    function GlobalSchemaImpl(nodeOrKey) {
		        _super.call(this, (typeof nodeOrKey == "string") ? createGlobalSchema(nodeOrKey) : nodeOrKey);
		        this.nodeOrKey = nodeOrKey;
		    }
		    /**
		     * @hidden
		     * @return Actual name of instance class
		     **/
		    GlobalSchemaImpl.prototype.wrapperClassName = function () {
		        return "GlobalSchemaImpl";
		    };
		    /**
		     * @return Actual name of instance interface
		     **/
		    GlobalSchemaImpl.prototype.kind = function () {
		        return "GlobalSchema";
		    };
		    /**
		     * Name of the global schema, used to refer on schema content
		     **/
		    GlobalSchemaImpl.prototype.key = function () {
		        return _super.prototype.attribute.call(this, 'key', this.toString);
		    };
		    /**
		     * @hidden
		     * Set key value
		     **/
		    GlobalSchemaImpl.prototype.setKey = function (param) {
		        this.highLevel().attrOrCreate("key").setValue("" + param);
		        return this;
		    };
		    /**
		     * Content of the schema
		     **/
		    GlobalSchemaImpl.prototype.value = function () {
		        return _super.prototype.attribute.call(this, 'value', function (attr) { return new SchemaStringImpl(attr); });
		    };
		    return GlobalSchemaImpl;
		})(RAMLSimpleElementImpl);
		exports.GlobalSchemaImpl = GlobalSchemaImpl;
		/**
		 * @hidden
		 **/
		function createApi(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("Api");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLLanguageElement(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("RAMLLanguageElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResourceType(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("ResourceType");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createMethod(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("Method");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createMethodBase(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("MethodBase");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createHasNormalParameters(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("HasNormalParameters");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createParameter(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("Parameter");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createStringTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("StringTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createBooleanTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("BooleanTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createNumberTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("NumberTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createIntegerTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("IntegerTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createDateTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("DateTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createFileTypeDeclaration(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("FileTypeDeclaration");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResponse(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("Response");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createBodyLike(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("BodyLike");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createXMLBody(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("XMLBody");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createJSONBody(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("JSONBody");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createTrait(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("Trait");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createSecuritySchemePart(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("SecuritySchemePart");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createResource(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("Resource");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createAbstractSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("AbstractSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createSecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("SecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth1SecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("OAuth1SecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth2SecuritySchemeSettings(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("OAuth2SecuritySchemeSettings");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth2SecurityScheme(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("OAuth2SecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createOAuth1SecurityScheme(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("OAuth1SecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createBasicSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("BasicSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createDigestSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("DigestSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createCustomSecurityScheme(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("CustomSecurityScheme");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createGlobalSchema(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("GlobalSchema");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createRAMLSimpleElement(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("RAMLSimpleElement");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		/**
		 * @hidden
		 **/
		function createDocumentationItem(key) {
		    var universe = hl.universeProvider("RAML08");
		    var nc = universe.type("DocumentationItem");
		    var node = nc.getAdapter(services.RAMLService).createStubNode(null, key);
		    return node;
		}
		function loadApiSync(apiPath, arg1, arg2) {
		    return apiLoader.loadApi(apiPath, arg1, arg2).getOrElse(null);
		}
		exports.loadApiSync = loadApiSync;
		function loadRAMLSync(ramlPath, arg1, arg2) {
		    return apiLoader.loadApi(ramlPath, arg1, arg2).getOrElse(null);
		}
		exports.loadRAMLSync = loadRAMLSync;
		function loadApi(apiPath, arg1, arg2) {
		    return apiLoader.loadApiAsync(apiPath, arg1, arg2);
		}
		exports.loadApi = loadApi;
		function loadRAML(ramlPath, arg1, arg2) {
		    return apiLoader.loadRAMLAsync(ramlPath, arg1, arg2);
		}
		exports.loadRAML = loadRAML;
		/**
		 * Gets AST node by runtime type, if runtime type matches any.
		 * @param runtimeType - runtime type to find the match for
		 */
		function getLanguageElementByRuntimeType(runtimeType) {
		    return apiLoader.getLanguageElementByRuntimeType(runtimeType);
		}
		exports.getLanguageElementByRuntimeType = getLanguageElementByRuntimeType;


	/***/ },
	/* 75 */
	/***/ function(module, exports, __webpack_require__) {

		var hlImpl = __webpack_require__(5);
		var jsyaml = __webpack_require__(15);
		var ramlService = __webpack_require__(49);
		var json2lowlevel = __webpack_require__(8);
		var defaultCalculator = __webpack_require__(76);
		var BasicNodeImpl = (function () {
		    /**
		     * @hidden
		     **/
		    function BasicNodeImpl(_node) {
		        this._node = _node;
		        _node.setWrapperNode(this);
		    }
		    /**
		     * @hidden
		     **/
		    BasicNodeImpl.prototype.wrapperClassName = function () {
		        return 'BasicNodeImpl';
		    };
		    BasicNodeImpl.prototype.kind = function () {
		        return 'BasicNode';
		    };
		    /**
		     * @return Direct ancestor in RAML hierarchy
		     **/
		    BasicNodeImpl.prototype.parent = function () {
		        var parent = this._node.parent();
		        return parent ? parent.wrapperNode() : null;
		    };
		    /**
		     * @hidden
		     * @return Underlying node of the High Level model
		     **/
		    BasicNodeImpl.prototype.highLevel = function () {
		        return this._node;
		    };
		    /**
		     * @hidden
		     **/
		    BasicNodeImpl.prototype.attributes = function (name, constr) {
		        var attrs = this._node.attributes(name);
		        if (!attrs || attrs.length == 0) {
		            var defaultValue = this.getDefaultsCalculator().attributeDefaultIfEnabled(this._node, this._node.definition().property(name));
		            if (defaultValue == null)
		                return [];
		            if (constr && (constr == this.toString || constr == this.toBoolean || constr == this.toNumber)) {
		                return [constr(defaultValue)];
		            }
		            else if (constr) {
		                return [];
		            }
		            return [defaultValue];
		        }
		        //TODO not sure if we want to artificially create missing attributes having
		        //default values
		        if (constr) {
		            return attrs.map(function (x) { return constr(x); });
		        }
		        else {
		            return attrs.map(function (x) { return x.value(); });
		        }
		    };
		    /**
		     * @hidden
		     **/
		    BasicNodeImpl.prototype.attribute = function (name, constr) {
		        var attr = this._node.attr(name);
		        if (constr && !(constr == this.toString || constr == this.toBoolean || constr == this.toNumber)) {
		            //we're not putting values directly inside anything, besides the default
		            //convertors for default types we support
		            if (attr == null)
		                return null;
		            return constr(attr);
		        }
		        var attributeValue = attr ? attr.value() : null;
		        if (attributeValue == null) {
		            attributeValue = this.getDefaultsCalculator().attributeDefaultIfEnabled(this._node, this._node.definition().property(name));
		        }
		        if (attributeValue == null)
		            return null;
		        if (constr) {
		            return constr(attributeValue);
		        }
		        else {
		            return attributeValue;
		        }
		    };
		    /**
		     * @hidden
		     **/
		    BasicNodeImpl.prototype.elements = function (name) {
		        var elements = this._node.elementsOfKind(name);
		        if (!elements) {
		            return null;
		        }
		        return elements.map(function (x) { return x.wrapperNode(); });
		    };
		    /**
		     * @hidden
		     **/
		    BasicNodeImpl.prototype.element = function (name) {
		        var element = this._node.element(name);
		        if (!element) {
		            return null;
		        }
		        return element.wrapperNode();
		    };
		    /**
		     * Append node as child
		     * @param node node to be appended
		     **/
		    BasicNodeImpl.prototype.add = function (node) {
		        this.highLevel().add(node.highLevel());
		    };
		    /**
		     * Append node as property value
		     * @param node node to be set as property value
		     * @param prop name of property to set value for
		     **/
		    BasicNodeImpl.prototype.addToProp = function (node, prop) {
		        var hl = node.highLevel();
		        var pr = this.highLevel().definition().property(prop);
		        hl._prop = pr;
		        this.highLevel().add(hl);
		    };
		    /**
		     * Remove node from children set
		     * @param node node to be removed
		     **/
		    BasicNodeImpl.prototype.remove = function (node) {
		        this.highLevel().remove(node.highLevel());
		    };
		    /**
		     * @return YAML string representing the node
		     **/
		    BasicNodeImpl.prototype.dump = function () {
		        return this.highLevel().dump("yaml");
		    };
		    BasicNodeImpl.prototype.toString = function (arg) {
		        var obj;
		        //kind of instanceof for hl.IAttribute without actually calling instanceof
		        if (arg.lowLevel && arg.property) {
		            obj = arg.value();
		        }
		        else {
		            obj = arg;
		        }
		        return obj != null ? obj.toString() : obj;
		    };
		    BasicNodeImpl.prototype.toBoolean = function (arg) {
		        var obj;
		        //kind of instanceof for hl.IAttribute without actually calling instanceof
		        if (arg.lowLevel && arg.property) {
		            obj = arg.value();
		        }
		        else {
		            obj = arg;
		        }
		        return obj != null ? obj.toString() == 'true' : obj;
		    };
		    BasicNodeImpl.prototype.toNumber = function (arg) {
		        var obj;
		        //kind of instanceof for hl.IAttribute without actually calling instanceof
		        if (arg.lowLevel && arg.property) {
		            obj = arg.value();
		        }
		        else {
		            obj = arg;
		        }
		        if (!obj) {
		            return obj;
		        }
		        try {
		            var nValue = parseFloat(obj.toString());
		            return nValue;
		        }
		        catch (e) {
		        }
		        return Number.MAX_VALUE;
		    };
		    /**
		     * @return Array of errors
		     **/
		    BasicNodeImpl.prototype.errors = function () {
		        var issues = [];
		        if (this._node.errors() != null) {
		            issues = issues.concat(this._node.errors());
		        }
		        this._node.attrs().filter(function (x) { return x.errors() != null; }).forEach(function (x) { return issues = issues.concat(x.errors()); });
		        var lineMapper = this._node.lowLevel().unit().lineMapper();
		        var result = issues.map(function (x) {
		            var startPoint = null;
		            try {
		                startPoint = lineMapper.position(x.start);
		            }
		            catch (e) {
		                console.warn(e);
		            }
		            var endPoint = null;
		            try {
		                endPoint = lineMapper.position(x.end);
		            }
		            catch (e) {
		                console.warn(e);
		            }
		            return {
		                code: x.code,
		                message: x.message,
		                path: x.path,
		                start: x.start,
		                end: x.end,
		                line: startPoint.errorMessage ? null : startPoint.line,
		                column: startPoint.errorMessage ? null : startPoint.column,
		                range: [startPoint, endPoint],
		                isWarning: x.isWarning
		            };
		        });
		        return result;
		    };
		    /**
		     * @return object representing class of the node
		     **/
		    BasicNodeImpl.prototype.definition = function () {
		        return this.highLevel().definition();
		    };
		    /**
		     * @return for user class instances returns object representing actual user class
		     **/
		    BasicNodeImpl.prototype.runtimeDefinition = function () {
		        return this.highLevel().definition().getAdapter(ramlService.RAMLService).toRuntime();
		    };
		    BasicNodeImpl.prototype.toJSON = function (serializeOptions) {
		        return json2lowlevel.serialize(this.highLevel().lowLevel(), serializeOptions);
		    };
		    /**
		     * @return Whether the element is an optional sibling of trait or resource type
		     **/
		    BasicNodeImpl.prototype.optional = function () {
		        var highLevel = this.highLevel();
		        return highLevel != null ? highLevel.optional() : false;
		    };
		    /**
		     * @return For siblings of traits or resource types returns an array of optional properties names.
		     **/
		    BasicNodeImpl.prototype.optionalProperties = function () {
		        if (!this.highLevel()) {
		            return [];
		        }
		        return this.highLevel().optionalProperties();
		    };
		    BasicNodeImpl.prototype.getDefaultsCalculator = function () {
		        if (this.defaultsCalculator) {
		            return this.defaultsCalculator;
		        }
		        if (this.parent()) {
		            this.defaultsCalculator = this.parent().getDefaultsCalculator();
		        }
		        if (!this.defaultsCalculator) {
		            this.defaultsCalculator = new defaultCalculator.AttributeDefaultsCalculator(false);
		        }
		        return this.defaultsCalculator;
		    };
		    /**
		     * @hidden
		     **/
		    BasicNodeImpl.prototype.setAttributeDefaults = function (attributeDefaults) {
		        this.defaultsCalculator = new defaultCalculator.AttributeDefaultsCalculator(attributeDefaults);
		    };
		    return BasicNodeImpl;
		})();
		exports.BasicNodeImpl = BasicNodeImpl;
		var AttributeNodeImpl = (function () {
		    function AttributeNodeImpl(attr) {
		        this.attr = attr;
		    }
		    /**
		     * @return Underlying High Level attribute node
		     **/
		    AttributeNodeImpl.prototype.highLevel = function () {
		        return this.attr;
		    };
		    /**
		     * @hidden
		     **/
		    AttributeNodeImpl.prototype.wrapperClassName = function () {
		        return 'AttributeNodeImpl';
		    };
		    AttributeNodeImpl.prototype.kind = function () {
		        return 'AttributeNode';
		    };
		    /**
		     * @return Whether the element is an optional sibling of trait or resource type
		     **/
		    AttributeNodeImpl.prototype.optional = function () {
		        var highLevel = this.highLevel();
		        return highLevel != null ? highLevel.optional() : false;
		    };
		    return AttributeNodeImpl;
		})();
		exports.AttributeNodeImpl = AttributeNodeImpl;
		/**
		 * @hidden
		 **/
		function toStructuredValue(node) {
		    var value = node.value();
		    if (typeof value === 'string') {
		        var mockNode = jsyaml.createNode(value.toString());
		        mockNode._actualNode().startPosition = node.lowLevel().valueStart();
		        mockNode._actualNode().endPosition = node.lowLevel().valueEnd();
		        var stv = new hlImpl.StructuredValue(mockNode, node.parent(), node.property());
		        return stv;
		    }
		    else {
		        return value;
		    }
		}
		exports.toStructuredValue = toStructuredValue;


	/***/ },
	/* 76 */
	/***/ function(module, exports, __webpack_require__) {

		var universeHelpers = __webpack_require__(62);
		var services = __webpack_require__(49);
		var AttributeDefaultsCalculator = (function () {
		    /**
		     *
		     * @param enabled - if false, defaults calculator will not return defaults from
		     * attrValueOrDefault method, only original values.
		     * @constructor
		     */
		    function AttributeDefaultsCalculator(enabled) {
		        this.enabled = enabled;
		    }
		    /**
		     * Return attribute default value if defaults calculator is enabled.
		     * If attribute value is null or undefined, returns attribute default.
		     */
		    AttributeDefaultsCalculator.prototype.attributeDefaultIfEnabled = function (node, attributeProperty) {
		        if (!this.enabled)
		            return null;
		        return this.getAttributeDefault(node, attributeProperty);
		    };
		    /**
		     * Returns attribute default.
		     */
		    AttributeDefaultsCalculator.prototype.getAttributeDefault = function (node, attributeProperty) {
		        if (!node || !attributeProperty)
		            return null;
		        try {
		            return this.getAttributeDefault2(attributeProperty, node, node.definition(), node.property(), node.parent(), node.parent() ? node.parent().definition() : null);
		        }
		        catch (Error) {
		            console.log(Error);
		            return null;
		        }
		    };
		    /**
		     * Returns attribute default.
		     * There are so many arguments instead of just providing a single AST node and getting
		     * anything we want from it as sometimes we create fake nodes in helpers and thus
		     * do not have actual high-level nodes at hands.
		     */
		    AttributeDefaultsCalculator.prototype.getAttributeDefault2 = function (attributeProperty, node, nodeDefinition, nodeProperty, parent, parentDefinition) {
		        //static values defined in definition system via defaultValue, defaultIntegerValue
		        // and defaultBooleanValue annotations.
		        if (attributeProperty.defaultValue() != null) {
		            return attributeProperty.defaultValue();
		        }
		        if (universeHelpers.isDisplayNameProperty(attributeProperty)) {
		            var adapter = nodeDefinition.getAdapter(services.RAMLService);
		            var keyProperty = adapter.getKeyProp();
		            if (keyProperty != null) {
		                var attributeValue = node.attrValue(keyProperty.nameId());
		                if (attributeValue != null)
		                    return attributeValue;
		            }
		        }
		        return null;
		    };
		    return AttributeDefaultsCalculator;
		})();
		exports.AttributeDefaultsCalculator = AttributeDefaultsCalculator;


	/***/ },
	/* 77 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var RamlWrapper1 = __webpack_require__(1);
		var path = __webpack_require__(16);
		var Opt = __webpack_require__(12);
		var jsyaml = __webpack_require__(15);
		var hl = __webpack_require__(2);
		var hlimpl = __webpack_require__(5);
		var llimpl = __webpack_require__(15);
		var expander = __webpack_require__(73);
		var universeDef = __webpack_require__(54);
		var ramlServices = __webpack_require__(49);
		var universeProvider = __webpack_require__(78);
		/***
		 * Load API synchronously. Detects RAML version and uses corresponding parser.
		 * @param apiPath Path to API: local file system path or Web URL
		 * @param options Load options
		 * @return Opt&lt;Api&gt;, where Api belongs to RAML 1.0 or RAML 0.8 model.
		 ***/
		function loadApi(apiPath, arg1, arg2) {
		    var api = loadRAMLInternal(apiPath, arg1, arg2);
		    if (false) {
		        throw new Error("Loaded RAML is not API");
		    }
		    else {
		        return new Opt(api);
		    }
		}
		exports.loadApi = loadApi;
		/***
		 * Load RAML synchronously. Detects RAML version and uses corresponding parser.
		 * @param ramlPath Path to RAML: local file system path or Web URL
		 * @param options Load options
		 * @return Opt&lt;RAMLLanguageElement&gt;, where RAMLLanguageElement belongs to RAML 1.0 or RAML 0.8 model.
		 ***/
		function loadRAML(ramlPath, arg1, arg2) {
		    var result = loadRAMLInternal(ramlPath, arg1, arg2);
		    return new Opt(result);
		}
		exports.loadRAML = loadRAML;
		function loadRAMLInternal(apiPath, arg1, arg2) {
		    var gotArray = Array.isArray(arg1);
		    var extensionsAndOverlays = (gotArray ? arg1 : null);
		    var options = (gotArray ? arg2 : arg1);
		    options = options || {};
		    var project = getProject(apiPath, options);
		    var unitName = path.basename(apiPath);
		    var unit = project.unit(unitName);
		    if (arg2 && !extensionsAndOverlays) {
		        throw new Error("Extensions and overlays list should be defined");
		    }
		    var api;
		    if (unit) {
		        if (extensionsAndOverlays && extensionsAndOverlays.length > 0) {
		            var extensionUnits = [];
		            extensionsAndOverlays.forEach(function (currentPath) {
		                if (!currentPath || currentPath.trim().length == 0) {
		                    throw new Error("Extensions and overlays list should contain legal file paths");
		                }
		            });
		            extensionsAndOverlays.forEach(function (unitPath) {
		                extensionUnits.push(project.unit(path.basename(unitPath)));
		            });
		            //calling to perform the checks, we do not actually need the api itself
		            extensionUnits.forEach(function (extensionUnit) { return toApi(extensionUnit, options); });
		            api = toApi(expander.mergeAPIs(unit, extensionUnits, 0 /* MERGE */), options);
		        }
		        else {
		            api = toApi(unit, options);
		            api.highLevel().setMergeMode(0 /* MERGE */);
		        }
		    }
		    if (options.rejectOnErrors && api && api.errors().length) {
		        throw toError(api);
		    }
		    if (options.attributeDefaults != null && api) {
		        api.setAttributeDefaults(options.attributeDefaults);
		    }
		    return api;
		}
		/***
		 * Load API asynchronously. Detects RAML version and uses corresponding parser.
		 * @param apiPath Path to API: local file system path or Web URL
		 * @param options Load options
		 * @return Promise&lt;Api&gt;, where Api belongs to RAML 1.0 or RAML 0.8 model.
		 ***/
		function loadApiAsync(apiPath, arg1, arg2) {
		    var ramlPromise = loadRAMLAsync(apiPath, arg1, arg2);
		    return ramlPromise.then(function (loadedRaml) {
		        if (false) {
		            //TODO check that loaded RAML is API
		            return Promise.reject("Specified RAML is not API");
		        }
		        else {
		            return loadedRaml;
		        }
		    });
		}
		exports.loadApiAsync = loadApiAsync;
		/***
		 * Load API asynchronously. Detects RAML version and uses corresponding parser.
		 * @param ramlPath Path to RAML: local file system path or Web URL
		 * @param options Load options
		 * @return Promise&lt;RAMLLanguageElement&gt;, where RAMLLanguageElement belongs to RAML 1.0 or RAML 0.8 model.
		 ***/
		function loadRAMLAsync(ramlPath, arg1, arg2) {
		    var gotArray = Array.isArray(arg1);
		    var extensionsAndOverlays = (gotArray ? arg1 : null);
		    var options = (gotArray ? arg2 : arg1);
		    options = options || {};
		    var project = getProject(ramlPath, options);
		    var unitName = path.basename(ramlPath);
		    if (arg2 && !extensionsAndOverlays) {
		        throw new Error("Extensions and overlays list should be defined");
		    }
		    if (!extensionsAndOverlays || extensionsAndOverlays.length == 0) {
		        return fetchAndLoadApiAsync(project, unitName, options).then(function (masterApi) {
		            masterApi.highLevel().setMergeMode(0 /* MERGE */);
		            if (options.attributeDefaults != null && masterApi) {
		                masterApi.setAttributeDefaults(options.attributeDefaults);
		            }
		            return masterApi;
		        });
		    }
		    else {
		        extensionsAndOverlays.forEach(function (currentPath) {
		            if (!currentPath || currentPath.trim().length == 0) {
		                throw new Error("Extensions and overlays list should contain legal file paths");
		            }
		        });
		        return fetchAndLoadApiAsync(project, unitName, options).then(function (masterApi) {
		            var apiPromises = [];
		            extensionsAndOverlays.forEach(function (extensionUnitPath) {
		                apiPromises.push(fetchAndLoadApiAsync(project, path.basename(extensionUnitPath), options));
		            });
		            return Promise.all(apiPromises).then(function (apis) {
		                var overlayUnits = [];
		                apis.forEach(function (currentApi) { return overlayUnits.push(currentApi.highLevel().lowLevel().unit()); });
		                var result = expander.mergeAPIs(masterApi.highLevel().lowLevel().unit(), overlayUnits, 0 /* MERGE */);
		                if (options.attributeDefaults != null && result) {
		                    result.setAttributeDefaults(options.attributeDefaults);
		                }
		                return result;
		            }).then(function (mergedHighLevel) {
		                return toApi(mergedHighLevel, options);
		            });
		        });
		    }
		}
		exports.loadRAMLAsync = loadRAMLAsync;
		/**
		 * Gets AST node by runtime type, if runtime type matches any.
		 * @param runtimeType
		 */
		function getLanguageElementByRuntimeType(runtimeType) {
		    if (runtimeType == null) {
		        return null;
		    }
		    var highLevelNode = runtimeType.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		    if (highLevelNode == null) {
		        return null;
		    }
		    return highLevelNode.wrapperNode();
		}
		exports.getLanguageElementByRuntimeType = getLanguageElementByRuntimeType;
		function fetchAndLoadApiAsync(project, unitName, options) {
		    return llimpl.fetchIncludesAsync(project, unitName).then(function (x) {
		        try {
		            var api = toApi(x, options);
		            if (options.rejectOnErrors && api && api.errors().length) {
		                return Promise.reject(toError(api));
		            }
		            return api;
		        }
		        catch (err) {
		            return Promise.reject(err);
		        }
		    });
		}
		function getProject(apiPath, options) {
		    options = options || {};
		    var includeResolver = options.fsResolver;
		    var httpResolver = options.httpResolver;
		    var projectRoot = path.dirname(apiPath);
		    var project = new jsyaml.Project(projectRoot, includeResolver, httpResolver);
		    return project;
		}
		;
		function toApi(unitOrHighlevel, options, checkApisOverlays) {
		    if (checkApisOverlays === void 0) { checkApisOverlays = false; }
		    if (!unitOrHighlevel) {
		        return null;
		    }
		    var unit = null;
		    var highLevel = null;
		    if (unitOrHighlevel.isRAMLUnit) {
		        unit = unitOrHighlevel;
		    }
		    else {
		        highLevel = unitOrHighlevel;
		        unit = highLevel.lowLevel().unit();
		    }
		    var api;
		    var contents = unit.contents();
		    var ramlFirstLine = contents.match(/^\s*#%RAML\s+(\d\.\d)\s*(\w*)\s*$/m);
		    if (!ramlFirstLine) {
		        //TODO throw sensible error
		        return null;
		    }
		    var verStr = ramlFirstLine[1];
		    var ramlFileType = ramlFirstLine[2];
		    var typeName;
		    var apiImpl;
		    var ramlVersion;
		    if (verStr == '0.8') {
		        ramlVersion = 'RAML08';
		    }
		    else if (verStr == '1.0') {
		        ramlVersion = 'RAML10';
		    }
		    if (!ramlVersion) {
		        //TODO throw sensible error
		        return null;
		    }
		    if (ramlVersion == 'RAML08' && checkApisOverlays) {
		        throw new Error('Extensions and overlays are not supported in RAML 0.8.');
		    }
		    //if (!ramlFileType || ramlFileType.trim() === "") {
		    //    if (verStr=='0.8') {
		    //        typeName = universeDef.Universe08.Api.name;
		    //        apiImpl = RamlWrapper08.ApiImpl;
		    //    } else if(verStr=='1.0'){
		    //        typeName = universeDef.Universe10.Api.name;
		    //        apiImpl = RamlWrapper1.ApiImpl;
		    //    }
		    //} else if (ramlFileType === "Overlay") {
		    //    apiImpl = RamlWrapper1.OverlayImpl;
		    //    typeName = universeDef.Universe10.Overlay.name;
		    //} else if (ramlFileType === "Extension") {
		    //    apiImpl = RamlWrapper1.ExtensionImpl;
		    //    typeName = universeDef.Universe10.Extension.name;
		    //}
		    var universe = universeProvider(ramlVersion);
		    var apiType = universe.type(typeName);
		    if (!highLevel) {
		        highLevel = hl.fromUnit(unit);
		    }
		    //api = new apiImpl(highLevel);
		    api = highLevel.wrapperNode();
		    return api;
		}
		;
		function toError(api) {
		    var error = new Error('Api contains errors.');
		    error.parserErrors = api.errors();
		    return error;
		}
		exports.toError = toError;
		function loadApis1(projectRoot, cacheChildren, expandTraitsAndResourceTypes) {
		    if (cacheChildren === void 0) { cacheChildren = false; }
		    if (expandTraitsAndResourceTypes === void 0) { expandTraitsAndResourceTypes = true; }
		    var universe = universeProvider("RAML10");
		    var apiType = universe.type(universeDef.Universe10.Api.name);
		    var p = new jsyaml.Project(projectRoot);
		    var result = [];
		    p.units().forEach(function (x) {
		        var lowLevel = x.ast();
		        if (cacheChildren) {
		            lowLevel = llimpl.toChildCahcingNode(lowLevel);
		        }
		        var api = new RamlWrapper1.ApiImpl(new hlimpl.ASTNodeImpl(lowLevel, null, apiType, null));
		        if (expandTraitsAndResourceTypes) {
		            api = expander.expandTraitsAndResourceTypes(api);
		        }
		        result.push(api);
		    });
		    return result;
		}
		exports.loadApis1 = loadApis1;


	/***/ },
	/* 78 */
	/***/ function(module, exports, __webpack_require__) {

		/* WEBPACK VAR INJECTION */(function(global, __dirname) {var fs = __webpack_require__(17);
		var path = __webpack_require__(16);
		var tsstruct = __webpack_require__(79);
		var ts2def = __webpack_require__(83);
		var universes = {};
		var locations = {
		    "RAML10": "../spec-1.0/api.ts",
		    "RAML08": "../spec-0.8/api.ts"
		};
		var jsonDefinitions = {
		    "RAML10": __webpack_require__(86),
		    "RAML08": __webpack_require__(87)
		};
		var getUniverse = (function () {
		    var x = function (key) {
		        if (universes[key]) {
		            return universes[key];
		        }
		        var src = getDecl(key);
		        var universe = ts2def.toDefSystem(src);
		        if (universe) {
		            universe.setUniverseVersion(key);
		            universes[key] = universe;
		        }
		        var mediaTypeParser = __webpack_require__(88);
		        global.mediaTypeParser = mediaTypeParser;
		        return universe;
		    };
		    x.availableUniverses = function () {
		        return Object.keys(locations);
		    };
		    x.clean = function () {
		        Object.keys(jsonDefinitions).forEach(function (x) {
		            jsonDefinitions[x] = null;
		            universes[x] = null;
		            fs.writeFileSync(path.resolve(__dirname, "../artifacts/" + x + ".json"), 'null');
		        });
		    };
		    return x;
		})();
		function getDecl(key) {
		    if (jsonDefinitions[key]) {
		        return toModule(jsonDefinitions[key]);
		    }
		    var tsPath = path.resolve(__dirname, locations[key]);
		    var decls = fs.readFileSync(tsPath).toString();
		    var src = tsstruct.parseStruct(decls, {}, tsPath);
		    var arr = toModulesCollection(src);
		    var jsonPath = path.resolve(path.resolve(path.dirname(tsPath), '../artifacts'), key + '.json');
		    fs.writeFileSync(jsonPath, JSON.stringify(arr, null, 2));
		    src = toModule(arr);
		    return src;
		}
		function toModulesCollection(mod, map, arr) {
		    if (map === void 0) { map = {}; }
		    if (arr === void 0) { arr = []; }
		    var name = mod['name'];
		    if (map[name]) {
		        return;
		    }
		    map[name] = mod;
		    arr.push(mod);
		    var imports = mod['imports'];
		    Object.keys(imports).forEach(function (x) {
		        var submod = imports[x];
		        var n = submod['name'];
		        imports[x] = n;
		        toModulesCollection(submod, map, arr);
		    });
		    return arr;
		}
		function toModule(arr) {
		    var main = arr[0];
		    var map = {};
		    arr.forEach(function (x) { return map[x['name']] = x; });
		    arr.forEach(function (x) {
		        var imports = x['imports'];
		        Object.keys(imports).forEach(function (y) {
		            var name = imports[y];
		            imports[y] = map[name];
		        });
		    });
		    return main;
		}
		module.exports = getUniverse;

		/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), "../../src/raml1/definition-system"))

	/***/ },
	/* 79 */
	/***/ function(module, exports, __webpack_require__) {

		/**
		 * Created by kor on 08/05/15.
		 */
		/// <reference path="../../../typings/main.d.ts" />
		var ts = __webpack_require__(80);
		var tsm = __webpack_require__(81);
		var pth = __webpack_require__(16);
		var fs = __webpack_require__(17);
		var tsModel = __webpack_require__(82);
		function parse(content) {
		    return ts.createSourceFile("sample.ts", content, 0 /* ES3 */, "1.4.1", true);
		}
		var fld = tsm.Matching.field();
		var clazzMatcher = tsm.Matching.classDeclaration();
		function classDecl(name, isInteface) {
		    return {
		        name: name,
		        methods: [],
		        typeParameters: [],
		        typeParameterConstraint: [],
		        implements: [],
		        fields: [],
		        isInterface: isInteface,
		        annotations: [],
		        extends: [],
		        moduleName: null,
		        annotationOverridings: {}
		    };
		}
		exports.classDecl = classDecl;
		function parseStruct(content, modules, mpth) {
		    var mod = parse(content);
		    var module = { classes: [], aliases: [], enumDeclarations: [], imports: {}, name: mpth };
		    modules[mpth] = module;
		    var currentModule = null;
		    tsm.Matching.visit(mod, function (x) {
		        if (x.kind == 189 /* ModuleDeclaration */) {
		            var cmod = x;
		            currentModule = cmod.name.text;
		        }
		        if (x.kind == 191 /* ImportDeclaration */) {
		            var imp = x;
		            var namespace = imp.name.text;
		            if (namespace == "RamlWrapper") {
		                return;
		            }
		            if (imp.moduleReference.kind != 193 /* ExternalModuleReference */) {
		                throw new Error("Only external module references are supported now");
		            }
		            var path = imp.moduleReference;
		            if (path.expression.kind != 7 /* StringLiteral */) {
		                throw new Error("Only string literals are supported in module references ");
		            }
		            var literal = path.expression;
		            var importPath = literal.text;
		            var absPath = pth.resolve(pth.dirname(mpth) + "/", importPath) + ".ts";
		            if (!fs.existsSync(absPath)) {
		                throw new Error("Path " + importPath + " resolve to " + absPath + "do not exists");
		            }
		            if (!modules[absPath]) {
		                var cnt = fs.readFileSync(absPath).toString();
		                var mod = parseStruct(cnt, modules, absPath);
		            }
		            module.imports[namespace] = modules[absPath];
		        }
		        if (x.kind == 187 /* TypeAliasDeclaration */) {
		            var u = x;
		            var aliasName = u.name.text;
		            var type = buildType(u.type, mpth);
		            module.aliases.push({ name: aliasName, type: type });
		        }
		        if (x.kind == 188 /* EnumDeclaration */) {
		            var e = x;
		            var members = [];
		            e.members.forEach(function (y) {
		                members.push(y['name']['text']);
		            });
		            module.enumDeclarations.push({ name: e.name.text, members: members });
		        }
		        var isInterface = x.kind == 186 /* InterfaceDeclaration */;
		        var isClass = x.kind == 185 /* ClassDeclaration */;
		        if (!isInterface && !isClass) {
		            return;
		        }
		        var c = x;
		        if (c) {
		            var fields = {};
		            var clazz = classDecl(c.name.text, isInterface);
		            clazz.moduleName = currentModule;
		            module.classes.push(clazz);
		            c.members.forEach(function (x) {
		                if (x.kind == 125 /* Method */) {
		                    var md = x;
		                    var aliasName = md.name.text;
		                    var text = content.substring(md.pos, md.end);
		                    clazz.methods.push({ name: aliasName, start: md.pos, end: md.end, text: text });
		                }
		                var field = fld.doMatch(x);
		                if (field) {
		                    var f = buildField(field, mpth);
		                    if (f.name == '$') {
		                        clazz.annotations = f.annotations;
		                    }
		                    else if (f.name.charAt(0) != '$' || f.name == '$ref') {
		                        fields[f.name] = f;
		                        clazz.fields.push(f);
		                    }
		                    else {
		                        var targetField = f.name.substr(1);
		                        var of = fields[targetField];
		                        if (!of) {
		                            if (f.name != '$$') {
		                                //console.log('Overriding annotations for field:'+targetField);
		                                var overridings = clazz.annotationOverridings[targetField];
		                                if (!overridings) {
		                                    overridings = [];
		                                }
		                                clazz.annotationOverridings[targetField] = overridings.concat(f.annotations);
		                            }
		                        }
		                        else {
		                            of.annotations = f.annotations;
		                        }
		                    }
		                }
		            });
		            if (c.typeParameters) {
		                c.typeParameters.forEach(function (x) {
		                    clazz.typeParameters.push(x.name['text']);
		                    if (x.constraint == null) {
		                        clazz.typeParameterConstraint.push(null);
		                    }
		                    else {
		                        clazz.typeParameterConstraint.push(x.constraint['typeName']['text']);
		                    }
		                });
		            }
		            if (c.heritageClauses) {
		                c.heritageClauses.forEach(function (x) {
		                    x.types.forEach(function (y) {
		                        if (x.token == 77 /* ExtendsKeyword */) {
		                            clazz.extends.push(buildType(y, mpth));
		                        }
		                        else if (x.token == 100 /* ImplementsKeyword */) {
		                            clazz.implements.push(buildType(y, mpth));
		                        }
		                        else {
		                            throw new Error("Unknown token class heritage");
		                        }
		                    });
		                });
		            }
		            return tsm.Matching.SKIP;
		        }
		    });
		    return module;
		}
		exports.parseStruct = parseStruct;
		function buildField(f, path) {
		    return {
		        name: f.name['text'],
		        type: buildType(f.type, path),
		        annotations: f.name['text'].charAt(0) == '$' ? buildInitializer(f.initializer) : [],
		        valueConstraint: f.name['text'].charAt(0) != '$' ? buildConstraint(f.initializer) : null,
		        optional: f.questionToken != null
		    };
		}
		function buildConstraint(e) {
		    if (e == null) {
		        return null;
		    }
		    if (e.kind == 145 /* CallExpression */) {
		        return {
		            isCallConstraint: true,
		            value: buildAnnotation(e)
		        };
		    }
		    else {
		        return {
		            isCallConstraint: false,
		            value: parseArg(e)
		        };
		    }
		}
		function buildInitializer(i) {
		    if (i == null) {
		        return [];
		    }
		    if (i.kind == 141 /* ArrayLiteralExpression */) {
		        var arr = i;
		        var annotations = [];
		        arr.elements.forEach(function (x) {
		            annotations.push(buildAnnotation(x));
		        });
		        return annotations;
		    }
		    else {
		        throw new Error("Only Array Literals supported now");
		    }
		}
		function buildAnnotation(e) {
		    if (e.kind == 145 /* CallExpression */) {
		        var call = e;
		        var name = parseName(call.expression);
		        var a = {
		            name: name,
		            arguments: []
		        };
		        call.arguments.forEach(function (x) {
		            a.arguments.push(parseArg(x));
		        });
		        return a;
		    }
		    else {
		        throw new Error("Only call expressions may be annotations");
		    }
		}
		function parseArg(n) {
		    if (n.kind == 7 /* StringLiteral */) {
		        var l = n;
		        return l.text;
		    }
		    if (n.kind == 9 /* NoSubstitutionTemplateLiteral */) {
		        var ls = n;
		        return ls.text;
		    }
		    if (n.kind == 141 /* ArrayLiteralExpression */) {
		        var arr = n;
		        var annotations = [];
		        arr.elements.forEach(function (x) {
		            annotations.push(parseArg(x));
		        });
		        return annotations;
		    }
		    if (n.kind == 93 /* TrueKeyword */) {
		        return true;
		    }
		    if (n.kind == 143 /* PropertyAccessExpression */) {
		        var pa = n;
		        return parseArg(pa.expression) + "." + parseArg(pa.name);
		    }
		    if (n.kind == 63 /* Identifier */) {
		        var ident = n;
		        return ident.text;
		    }
		    if (n.kind == 78 /* FalseKeyword */) {
		        return false;
		    }
		    if (n.kind == 6 /* NumericLiteral */) {
		        var nl = n;
		        return Number(nl.text);
		    }
		    if (n.kind == 157 /* BinaryExpression */) {
		        var bin = n;
		        if (bin.operator = 32 /* PlusToken */) {
		            return parseArg(bin.left) + parseArg(bin.right);
		        }
		    }
		    throw new Error("Unknown value in annotation");
		}
		function parseName(n) {
		    if (n.kind == 63 /* Identifier */) {
		        return n['text'];
		    }
		    if (n.kind == 143 /* PropertyAccessExpression */) {
		        var m = n;
		        return parseName(m.expression) + "." + parseName(m.name);
		    }
		    throw new Error("Only simple identifiers are supported now");
		}
		function basicType(n, path) {
		    var namespaceIndex = n.indexOf(".");
		    var namespace = namespaceIndex != -1 ? n.substring(0, namespaceIndex) : "";
		    var basicName = namespaceIndex != -1 ? n.substring(namespaceIndex + 1) : n;
		    return { typeName: n, nameSpace: namespace, basicName: basicName, typeKind: 0 /* BASIC */, typeArguments: [], modulePath: path };
		}
		function arrayType(b) {
		    return { base: b, typeKind: 1 /* ARRAY */ };
		}
		function unionType(b) {
		    return { options: b, typeKind: 2 /* UNION */ };
		}
		function buildType(t, path) {
		    if (t == null) {
		        return null;
		    }
		    if (t.kind == 118 /* StringKeyword */) {
		        return basicType("string", null);
		    }
		    if (t.kind == 116 /* NumberKeyword */) {
		        return basicType("number", null);
		    }
		    if (t.kind == 110 /* BooleanKeyword */) {
		        return basicType("boolean", null);
		    }
		    if (t.kind == 109 /* AnyKeyword */) {
		        return basicType("any", null);
		    }
		    if (t.kind == 132 /* TypeReference */) {
		        var tr = t;
		        var res = basicType(parseQualified(tr.typeName), path);
		        if (tr.typeArguments) {
		            tr.typeArguments.forEach(function (x) {
		                res.typeArguments.push(buildType(x, path));
		            });
		        }
		        return res;
		    }
		    if (t.kind == 137 /* ArrayType */) {
		        var q = t;
		        return arrayType(buildType(q.elementType, path));
		    }
		    if (t.kind == 139 /* UnionType */) {
		        var ut = t;
		        return unionType(ut.types.map(function (x) { return buildType(x, path); }));
		    }
		    throw new Error("Case not supported" + t.kind);
		}
		exports.buildType = buildType;
		function parseQualified(n) {
		    if (n.kind == 63 /* Identifier */) {
		        return n['text'];
		    }
		    else {
		        var q = n;
		        return parseQualified(q.left) + "." + parseQualified(q.right);
		    }
		}


	/***/ },
	/* 80 */
	/***/ function(module, exports) {

		module.exports = {};

	/***/ },
	/* 81 */
	/***/ function(module, exports, __webpack_require__) {

		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		/// <reference path="../../typings/main.d.ts" />
		var ts = __webpack_require__(80);
		/***
		 * This module is designed to match simple patterns on Typescript AST Tree
		 * it functionality mirrors jsASTMatchers which allows you to match on jsAST
		 */
		//TODO RENAME TO MATCHERS
		var Matching;
		(function (Matching) {
		    /**
		     * do match checks the node type and if node type is ok
		     * calls match function otherwise it returns null
		     */
		    var BasicMatcher = (function () {
		        function BasicMatcher() {
		        }
		        BasicMatcher.prototype.match = function (node) {
		            throw new Error();
		        };
		        BasicMatcher.prototype.nodeType = function () {
		            throw new Error();
		        };
		        BasicMatcher.prototype.doMatch = function (n) {
		            if (!n) {
		                return null;
		            }
		            if (this.nodeType() == n.kind) {
		                return this.match(n);
		            }
		        };
		        return BasicMatcher;
		    })();
		    var ClassDeclarationMatcher = (function (_super) {
		        __extends(ClassDeclarationMatcher, _super);
		        function ClassDeclarationMatcher() {
		            _super.call(this);
		        }
		        ClassDeclarationMatcher.prototype.match = function (node) {
		            return node;
		        };
		        ClassDeclarationMatcher.prototype.nodeType = function () {
		            return 185 /* ClassDeclaration */;
		        };
		        return ClassDeclarationMatcher;
		    })(BasicMatcher);
		    var FieldMatcher = (function (_super) {
		        __extends(FieldMatcher, _super);
		        function FieldMatcher() {
		            _super.apply(this, arguments);
		        }
		        FieldMatcher.prototype.match = function (node) {
		            return node;
		        };
		        FieldMatcher.prototype.nodeType = function () {
		            return 124 /* Property */;
		        };
		        return FieldMatcher;
		    })(BasicMatcher);
		    var AssignmentExpressionMatcher = (function (_super) {
		        __extends(AssignmentExpressionMatcher, _super);
		        function AssignmentExpressionMatcher(left, right, tr) {
		            _super.call(this);
		            this.left = left;
		            this.right = right;
		            this.tr = tr;
		        }
		        AssignmentExpressionMatcher.prototype.match = function (node) {
		            if (node.operator == 51 /* EqualsToken */) {
		                if (this.left.doMatch(node.left) && this.right.doMatch(node.right)) {
		                    return this.tr(node);
		                }
		            }
		            return null;
		        };
		        AssignmentExpressionMatcher.prototype.nodeType = function () {
		            return 157 /* BinaryExpression */;
		        };
		        return AssignmentExpressionMatcher;
		    })(BasicMatcher);
		    var VariableDeclarationMatcher = (function (_super) {
		        __extends(VariableDeclarationMatcher, _super);
		        function VariableDeclarationMatcher(left, right, tr) {
		            _super.call(this);
		            this.left = left;
		            this.right = right;
		            this.tr = tr;
		        }
		        VariableDeclarationMatcher.prototype.match = function (node) {
		            if (this.left.doMatch(node.name) && this.right.doMatch(node.initializer)) {
		                return this.tr(node);
		            }
		        };
		        VariableDeclarationMatcher.prototype.nodeType = function () {
		            return 183 /* VariableDeclaration */;
		        };
		        return VariableDeclarationMatcher;
		    })(BasicMatcher);
		    var ExpressionStatementMatcher = (function (_super) {
		        __extends(ExpressionStatementMatcher, _super);
		        function ExpressionStatementMatcher(expression, tr) {
		            _super.call(this);
		            this.expression = expression;
		            this.tr = tr;
		        }
		        ExpressionStatementMatcher.prototype.match = function (node) {
		            var exp = this.expression.doMatch(node.expression);
		            if (exp) {
		                var v = this.tr(node.expression);
		                if (v == true) {
		                    return exp;
		                }
		                return v;
		            }
		            return null;
		        };
		        ExpressionStatementMatcher.prototype.nodeType = function () {
		            return 166 /* ExpressionStatement */;
		        };
		        return ExpressionStatementMatcher;
		    })(BasicMatcher);
		    var SimpleIdentMatcher = (function (_super) {
		        __extends(SimpleIdentMatcher, _super);
		        function SimpleIdentMatcher(val) {
		            _super.call(this);
		            this.val = val;
		        }
		        SimpleIdentMatcher.prototype.match = function (node) {
		            if (node.text == this.val) {
		                return true;
		            }
		            return null;
		        };
		        SimpleIdentMatcher.prototype.nodeType = function () {
		            return 63 /* Identifier */;
		        };
		        return SimpleIdentMatcher;
		    })(BasicMatcher);
		    var TrueMatcher = (function () {
		        function TrueMatcher() {
		        }
		        TrueMatcher.prototype.doMatch = function (node) {
		            return true;
		        };
		        TrueMatcher.prototype.nodeType = function () {
		            return null;
		        };
		        return TrueMatcher;
		    })();
		    var CallExpressionMatcher = (function (_super) {
		        __extends(CallExpressionMatcher, _super);
		        function CallExpressionMatcher(calleeMatcher, tr) {
		            _super.call(this);
		            this.calleeMatcher = calleeMatcher;
		            this.tr = tr;
		        }
		        CallExpressionMatcher.prototype.match = function (node) {
		            if (this.calleeMatcher.doMatch(node.expression)) {
		                return this.tr(node);
		            }
		            return null;
		        };
		        CallExpressionMatcher.prototype.nodeType = function () {
		            return 145 /* CallExpression */;
		        };
		        return CallExpressionMatcher;
		    })(BasicMatcher);
		    Matching.SKIP = {};
		    function visit(n, cb) {
		        var r0 = cb(n);
		        if (r0) {
		            if (r0 == Matching.SKIP) {
		                return null;
		            }
		            return r0;
		        }
		        var r = ts.forEachChild(n, function (x) {
		            var r = visit(x, cb);
		            if (r) {
		                return r;
		            }
		        });
		        return r;
		    }
		    Matching.visit = visit;
		    var PathNode = (function () {
		        function PathNode(name, _base) {
		            this._base = _base;
		            this.arguments = null;
		            this.name = name;
		        }
		        return PathNode;
		    })();
		    var CallPath = (function () {
		        function CallPath(base, _baseNode) {
		            this._baseNode = _baseNode;
		            this.path = [];
		            this.base = base;
		        }
		        CallPath.prototype.start = function () {
		            return this._baseNode.pos;
		        };
		        CallPath.prototype.startLocation = function () {
		            return this._baseNode.getSourceFile().getLineAndCharacterFromPosition(this.start());
		        };
		        CallPath.prototype.endLocation = function () {
		            return this._baseNode.getSourceFile().getLineAndCharacterFromPosition(this.end());
		        };
		        CallPath.prototype.end = function () {
		            var ce = this.path[this.path.length - 1]._callExpression;
		            if (ce) {
		                return ce.end;
		            }
		            return this.start();
		        };
		        CallPath.prototype.toString = function () {
		            return this.path.map(function (x) { return x.name; }).join(".");
		        };
		        return CallPath;
		    })();
		    Matching.CallPath = CallPath;
		    var MemberExpressionMatcher = (function (_super) {
		        __extends(MemberExpressionMatcher, _super);
		        function MemberExpressionMatcher(objectMatcher, propertyMatcher, tr) {
		            _super.call(this);
		            this.objectMatcher = objectMatcher;
		            this.propertyMatcher = propertyMatcher;
		            this.tr = tr;
		        }
		        MemberExpressionMatcher.prototype.match = function (node) {
		            if (this.objectMatcher.doMatch(node.expression) && this.propertyMatcher.doMatch(node.name)) {
		                return this.tr(node);
		            }
		            return null;
		        };
		        MemberExpressionMatcher.prototype.nodeType = function () {
		            return 143 /* PropertyAccessExpression */;
		        };
		        return MemberExpressionMatcher;
		    })(BasicMatcher);
		    function memberFromExp(objMatcher, tr) {
		        if (tr === void 0) { tr = function (x) { return true; }; }
		        var array = objMatcher.split(".");
		        var result = null;
		        for (var a = 0; a < array.length; a++) {
		            var arg = array[a];
		            var ci = arg.indexOf("(*)");
		            var isCall = false;
		            if (ci != -1) {
		                arg = arg.substr(0, ci);
		                isCall = true;
		            }
		            if (result == null) {
		                result = arg == '*' ? anyNode() : ident(arg);
		            }
		            else {
		                result = new MemberExpressionMatcher(result, arg == '*' ? anyNode() : ident(arg), tr);
		            }
		            if (isCall) {
		                result = new CallExpressionMatcher(result, tr);
		            }
		        }
		        //console.log(result)
		        return result;
		    }
		    Matching.memberFromExp = memberFromExp;
		    var CallBaseMatcher = (function () {
		        function CallBaseMatcher(rootMatcher) {
		            this.rootMatcher = rootMatcher;
		        }
		        CallBaseMatcher.prototype.doMatch = function (node) {
		            var original = node;
		            if (node.kind == 145 /* CallExpression */) {
		                var call = node;
		                var res = this.doMatch(call.expression);
		                if (res) {
		                    if (res.path.length > 0 && res.path[res.path.length - 1].arguments == null) {
		                        res.path[res.path.length - 1].arguments = call.arguments;
		                        res.path[res.path.length - 1]._callExpression = call;
		                        return res;
		                    }
		                    //This case should not exist in type script clients now
		                    //but leaving it here for possible future use at the moment;
		                    //if (res.path.length==0&&call.arguments.length==1){
		                    //    //this is not resource based call!!!
		                    //    if (call.arguments[0].kind==ts.SyntaxKind.StringLiteral){
		                    //        var l:ts.LiteralExpression=<ts.LiteralExpression>call.arguments[0];
		                    //        var url=l.text;
		                    //        var uriPath=url.toString().split("/");
		                    //        uriPath.forEach(x=>res.path.push(
		                    //            new PathNode(x)
		                    //        ))
		                    //        return res;
		                    //    }
		                    //}
		                    return null;
		                }
		            }
		            else if (node.kind == 143 /* PropertyAccessExpression */) {
		                var me = node;
		                var v = this.doMatch(me.expression);
		                if (v) {
		                    if (me.name.kind == 63 /* Identifier */) {
		                        v.path.push(new PathNode(me.name.text, me.name));
		                        return v;
		                    }
		                    return null;
		                }
		            }
		            else if (node.kind == 63 /* Identifier */) {
		                var id = node;
		                if (this.rootMatcher.doMatch(id)) {
		                    return new CallPath(id.text, id);
		                }
		            }
		            return null;
		        };
		        CallBaseMatcher.prototype.nodeType = function () {
		            return null;
		        };
		        return CallBaseMatcher;
		    })();
		    Matching.CallBaseMatcher = CallBaseMatcher;
		    function ident(name) {
		        return new SimpleIdentMatcher(name);
		    }
		    Matching.ident = ident;
		    function anyNode() {
		        return new TrueMatcher();
		    }
		    Matching.anyNode = anyNode;
		    function call(calleeMatcher, tr) {
		        if (tr === void 0) { tr = function (x) { return true; }; }
		        return new CallExpressionMatcher(calleeMatcher, tr);
		    }
		    Matching.call = call;
		    function exprStmt(eM, tr) {
		        if (tr === void 0) { tr = function (x) { return true; }; }
		        return new ExpressionStatementMatcher(eM, tr);
		    }
		    Matching.exprStmt = exprStmt;
		    function assign(left, right, tr) {
		        if (tr === void 0) { tr = function (x) { return true; }; }
		        return new AssignmentExpressionMatcher(left, right, tr);
		    }
		    Matching.assign = assign;
		    function varDecl(left, right, tr) {
		        if (tr === void 0) { tr = function (x) { return true; }; }
		        return new VariableDeclarationMatcher(left, right, tr);
		    }
		    Matching.varDecl = varDecl;
		    function field() {
		        return new FieldMatcher();
		    }
		    Matching.field = field;
		    function classDeclaration() {
		        return new ClassDeclarationMatcher();
		    }
		    Matching.classDeclaration = classDeclaration;
		})(Matching = exports.Matching || (exports.Matching = {}));


	/***/ },
	/* 82 */
	/***/ function(module, exports) {

		var EnumDeclaration = (function () {
		    function EnumDeclaration() {
		    }
		    return EnumDeclaration;
		})();
		exports.EnumDeclaration = EnumDeclaration;
		(function (TypeKind) {
		    TypeKind[TypeKind["BASIC"] = 0] = "BASIC";
		    TypeKind[TypeKind["ARRAY"] = 1] = "ARRAY";
		    TypeKind[TypeKind["UNION"] = 2] = "UNION";
		})(exports.TypeKind || (exports.TypeKind = {}));
		var TypeKind = exports.TypeKind;


	/***/ },
	/* 83 */
	/***/ function(module, exports, __webpack_require__) {

		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		/// <reference path="../../../typings/main.d.ts" />
		var tsModel = __webpack_require__(82);
		var def = __webpack_require__(3);
		var _ = __webpack_require__(4);
		var aHandlers = __webpack_require__(84);
		var services = __webpack_require__(49);
		var FieldWrapper = (function () {
		    function FieldWrapper(_field, _clazz) {
		        this._field = _field;
		        this._clazz = _clazz;
		    }
		    FieldWrapper.prototype.name = function () {
		        return this._field.name;
		    };
		    FieldWrapper.prototype.range = function () {
		        return this._clazz.getModule().typeFor(this._field.type, this._clazz);
		    };
		    FieldWrapper.prototype.isMultiValue = function () {
		        return this._field.type.typeKind == 1 /* ARRAY */;
		    };
		    FieldWrapper.prototype.isKey = function () {
		        return _.find(this._field.annotations, function (x) { return x.name == "MetaModel.key"; }) != null;
		    };
		    FieldWrapper.prototype.isSimpleValue = function () {
		        return _.find(this._field.annotations, function (x) { return x.name == "MetaModel.value"; }) != null;
		    };
		    FieldWrapper.prototype.annotations = function () {
		        return this._field.annotations;
		    };
		    return FieldWrapper;
		})();
		var FieldConstraint = (function () {
		    function FieldConstraint(_field, _clazz) {
		        this._field = _field;
		        this._clazz = _clazz;
		    }
		    FieldConstraint.prototype.name = function () {
		        return this._field.name;
		    };
		    FieldConstraint.prototype.value = function () {
		        return this._field.valueConstraint;
		    };
		    return FieldConstraint;
		})();
		var ClassWrapper = (function () {
		    function ClassWrapper(_clazz, mw) {
		        this._clazz = _clazz;
		        this.mw = mw;
		    }
		    ClassWrapper.prototype.typeMeta = function () {
		        return this._clazz.annotations;
		    };
		    ClassWrapper.prototype.path = function () {
		        return this.mw.path();
		    };
		    ClassWrapper.prototype.getModule = function () {
		        return this.mw;
		    };
		    ClassWrapper.prototype.typeArgs = function () {
		        return this._clazz.typeParameters;
		    };
		    ClassWrapper.prototype.typConstraints = function () {
		        var _this = this;
		        return this._clazz.typeParameterConstraint.map(function (x) {
		            if (x) {
		                return _this.mw.classForName(x);
		            }
		            return null;
		        });
		    };
		    ClassWrapper.prototype.methods = function () {
		        return this._clazz.methods;
		    };
		    ClassWrapper.prototype.name = function () {
		        return this._clazz.name;
		    };
		    ClassWrapper.prototype.members = function () {
		        var _this = this;
		        return this._clazz.fields.filter(function (x) { return x.valueConstraint == null; }).map(function (x) { return new FieldWrapper(x, _this); });
		    };
		    ClassWrapper.prototype.constraints = function () {
		        var _this = this;
		        return this._clazz.fields.filter(function (x) { return x.valueConstraint != null; }).map(function (x) { return new FieldConstraint(x, _this); });
		    };
		    ClassWrapper.prototype.isSubTypeOf = function (of) {
		        if (this == of) {
		            return true;
		        }
		        var _res = false;
		        this.getAllSuperTypes().forEach(function (x) {
		            if (!_res) {
		                _res = _res || x.isSubTypeOf(of);
		            }
		        });
		        return _res;
		    };
		    ClassWrapper.prototype.getExtendsClauses = function () {
		        return this._clazz.extends;
		    };
		    ClassWrapper.prototype.getSuperTypes = function () {
		        var _this = this;
		        var result = [];
		        this._clazz.extends.forEach(function (x) {
		            var tp = _this.mw.classForName(x.typeName);
		            if (tp) {
		                result.push(tp);
		            }
		        });
		        return result;
		    };
		    ClassWrapper.prototype.getAllSuperTypes = function () {
		        var _this = this;
		        var result = [];
		        this._clazz.extends.forEach(function (x) {
		            var tp = _this.mw.classForName(x.typeName);
		            if (tp) {
		                var mm = tp.getAllSuperTypes();
		                result.push(tp);
		                result.concat(mm);
		            }
		        });
		        return _.unique(result);
		    };
		    ClassWrapper.prototype.annotationOverridings = function () {
		        return this._clazz.annotationOverridings;
		    };
		    return ClassWrapper;
		})();
		var AbstractSimpleWrapper = (function () {
		    function AbstractSimpleWrapper() {
		    }
		    AbstractSimpleWrapper.prototype.members = function () {
		        return []; //this._clazz.members.map(x=>new FieldWrapper(x,this))
		    };
		    AbstractSimpleWrapper.prototype.methods = function () {
		        return [];
		    };
		    AbstractSimpleWrapper.prototype.isSubTypeOf = function (of) {
		        return false;
		    };
		    AbstractSimpleWrapper.prototype.getSuperTypes = function () {
		        return [];
		    };
		    AbstractSimpleWrapper.prototype.getAllSuperTypes = function () {
		        return [];
		    };
		    AbstractSimpleWrapper.prototype.name = function () {
		        return null;
		    };
		    AbstractSimpleWrapper.prototype.constraints = function () {
		        return [];
		    };
		    AbstractSimpleWrapper.prototype.typeMeta = function () {
		        return [];
		    };
		    AbstractSimpleWrapper.prototype.getModule = function () {
		        throw new Error("Not implemented");
		    };
		    AbstractSimpleWrapper.prototype.annotationOverridings = function () {
		        return {};
		    };
		    return AbstractSimpleWrapper;
		})();
		var EnumWrapper = (function (_super) {
		    __extends(EnumWrapper, _super);
		    function EnumWrapper(_clazz, mw) {
		        _super.call(this);
		        this._clazz = _clazz;
		        this.mw = mw;
		    }
		    EnumWrapper.prototype.getModule = function () {
		        return this.mw;
		    };
		    EnumWrapper.prototype.values = function () {
		        return this._clazz.members;
		    };
		    EnumWrapper.prototype.name = function () {
		        return this._clazz.name;
		    };
		    return EnumWrapper;
		})(AbstractSimpleWrapper);
		var UnionWrapper = (function (_super) {
		    __extends(UnionWrapper, _super);
		    function UnionWrapper(_clazz, mw) {
		        _super.call(this);
		        this._clazz = _clazz;
		        this.mw = mw;
		    }
		    UnionWrapper.prototype.elements = function () {
		        return this._clazz;
		    };
		    UnionWrapper.prototype.name = function () {
		        return this._clazz.map(function (x) { return x.name(); }).join("|");
		    };
		    return UnionWrapper;
		})(AbstractSimpleWrapper);
		var ModuleWrapper = (function () {
		    function ModuleWrapper(_univers) {
		        var _this = this;
		        this._univers = _univers;
		        this.name2Class = {};
		        this.namespaceToMod = {};
		        this._classes = [];
		        _univers.classes.forEach(function (x) {
		            var c = new ClassWrapper(x, _this);
		            _this._classes.push(c);
		            _this.name2Class[x.name] = c;
		            if (x.moduleName) {
		                //FIXME
		                _this.name2Class[x.moduleName + "." + x.name] = c;
		            }
		        });
		        _univers.enumDeclarations.forEach(function (x) {
		            var c = new EnumWrapper(x, _this);
		            _this._classes.push(c);
		            _this.name2Class[x.name] = c;
		        });
		    }
		    ModuleWrapper.prototype.typeFor = function (t, ow) {
		        var _this = this;
		        switch (t.typeKind) {
		            case 0 /* BASIC */:
		                var bt = t;
		                var typeName = bt.typeName;
		                if (typeName == "string") {
		                    typeName = "StringType";
		                }
		                if (typeName == "number") {
		                    typeName = "NumberType";
		                }
		                if (typeName == "boolean") {
		                    typeName = "BooleanType";
		                }
		                var ti = _.indexOf(ow.typeArgs(), typeName);
		                if (ti != -1) {
		                    var cnst = ow.typConstraints()[ti];
		                    if (!cnst) {
		                        return this.classForName("ValueType");
		                    }
		                    return cnst;
		                }
		                return this.classForName(typeName);
		            case 2 /* UNION */:
		                var ut = t;
		                return new UnionWrapper(ut.options.map(function (x) { return _this.typeFor(x, ow); }), this);
		            case 1 /* ARRAY */:
		                var at = t;
		                return this.typeFor(at.base, ow);
		        }
		        return null;
		    };
		    ModuleWrapper.prototype.path = function () {
		        return this._univers.name;
		    };
		    ModuleWrapper.prototype.classForName = function (name, stack) {
		        var _this = this;
		        if (stack === void 0) { stack = {}; }
		        if (!name) {
		            return null;
		        }
		        var result = this.name2Class[name];
		        if (!result && !stack[this.path()]) {
		            stack[this.path()] = this;
		            var nmsp = name.indexOf(".");
		            if (nmsp != -1) {
		                var actualMod = this.namespaceToMod[name.substring(0, nmsp)];
		                if (!actualMod) {
		                    throw new Error();
		                }
		                return actualMod.classForName(name.substring(nmsp + 1), stack);
		            }
		            Object.keys(this.namespaceToMod).forEach(function (x) {
		                if (x != "MetaModel") {
		                    var nm = _this.namespaceToMod[x].classForName(name, stack);
		                    if (nm) {
		                        result = nm;
		                    }
		                }
		            });
		        }
		        return result;
		    };
		    ModuleWrapper.prototype.classes = function () {
		        return this._classes;
		    };
		    return ModuleWrapper;
		})();
		var wrapperToType = function (range, u) {
		    if (range) {
		        var rangeType;
		        if (range instanceof UnionWrapper) {
		            var uw = range;
		            throw new Error("Union type support was removed from definition system");
		        }
		        else {
		            rangeType = u.type(range.name());
		        }
		        return rangeType;
		    }
		    else {
		        return;
		    }
		};
		var registerClasses = function (m, u) {
		    var valueType = m.classForName("ValueType");
		    m.classes().forEach(function (x) {
		        if (x instanceof EnumWrapper) {
		            var et = new def.EnumType(x.name(), u, x.getModule().path());
		            et.values = x.values();
		            u.register(et);
		            return;
		        }
		        if (x.isSubTypeOf(valueType)) {
		            var st = x.getAllSuperTypes();
		            st.push(x);
		            var refTo = null;
		            st.forEach(function (t) {
		                var cs = t.getExtendsClauses();
		                cs.forEach(function (z) {
		                    if (z.typeKind == 0 /* BASIC */) {
		                        var bas = z;
		                        if (bas.basicName == 'Reference') {
		                            var of = bas.typeArguments[0];
		                            refTo = of.typeName;
		                        }
		                    }
		                });
		            });
		            if (refTo) {
		                //console.log("New reference type" + x.name())
		                var ref = new def.ReferenceType(x.name(), x.getModule().path(), refTo, u);
		                u.register(ref);
		            }
		            var vt = new def.ValueType(x.name(), u, x.getModule().path());
		            u.register(vt);
		        }
		        else {
		            var gt = new def.NodeClass(x.name(), u, x.getModule().path());
		            u.register(gt);
		        }
		    });
		};
		var registerHierarchy = function (m, u) {
		    m.classes().forEach(function (x) {
		        x.getSuperTypes().forEach(function (y) {
		            var tp0 = u.type(x.name());
		            var tp1 = u.type(y.name());
		            if (!tp0 || !tp1) {
		                var tp0 = u.type(x.name());
		                var tp1 = u.type(y.name());
		                throw new Error();
		            }
		            u.registerSuperClass(tp0, tp1);
		        });
		    });
		};
		var registerEverything = function (m, u) {
		    m.classes().forEach(function (x) {
		        var tp = u.type(x.name());
		        x.typeMeta().forEach(function (a) {
		            var rangeType = wrapperToType(x, u);
		            aHandlers.handleTypeAnnotation(a, rangeType);
		        });
		        x.members().forEach(function (x) {
		            var range = x.range();
		            var rangeType = wrapperToType(range, u);
		            if (rangeType == null) {
		                console.log(range + ":" + x.name());
		            }
		            createProp(x, tp, rangeType);
		        });
		        Object.keys(x.annotationOverridings()).forEach(function (fName) {
		            var arr = [].concat(x.annotationOverridings()[fName]);
		            var map = {};
		            arr.forEach(function (ann) { return map[ann.name] = true; });
		            var targetField;
		            var stArr = x.getSuperTypes();
		            var stMap = {};
		            for (var i = 0; i < stArr.length; i++) {
		                var st = stArr[i];
		                if (stMap[st.name()]) {
		                    continue;
		                }
		                stMap[st.name()] = true;
		                st.getSuperTypes().forEach(function (sst) { return stArr.push(sst); });
		                var arr1 = st.annotationOverridings()[fName];
		                if (arr1) {
		                    arr1.filter(function (ann) { return !map[ann.name]; }).forEach(function (ann) {
		                        map[ann.name] = true;
		                        arr.push(ann);
		                    });
		                }
		                else {
		                    var stFields = st.members();
		                    for (var j = 0; j < stFields.length; j++) {
		                        var stField = stFields[j];
		                        if (stField.name() == fName) {
		                            targetField = stField;
		                            break;
		                        }
		                    }
		                }
		                if (targetField) {
		                    var arr2 = targetField.annotations();
		                    arr2.filter(function (ann) { return !map[ann.name]; }).forEach(function (ann) {
		                        map[ann.name] = true;
		                        arr.push(ann);
		                    });
		                    break;
		                }
		            }
		            if (!targetField) {
		                return;
		            }
		            var range = targetField.range();
		            var rangeType = wrapperToType(range, u);
		            if (rangeType == null) {
		                console.log(range + ":" + x.name());
		            }
		            createProp(targetField, tp, rangeType, arr);
		        });
		        x.methods().forEach(function (x) {
		            var at = tp;
		            //at.addMethod(x.name, x.text);
		            //console.log(x.name);
		            //createMember(x, <def.AbstractType>tp, rangeType)
		        });
		        x.constraints().forEach(function (x) {
		            if (x.value().isCallConstraint) {
		                throw new Error();
		            }
		            var mm = x.value();
		            tp.addRequirement(x.name(), "" + mm.value);
		        });
		    });
		    u.types().forEach(function (x) {
		        var at = x;
		        at.getAdapter(services.RAMLService).getAliases().forEach(function (y) { return u.registerAlias(y, at); });
		    });
		};
		var processModule = function (ts, u, used, declared) {
		    if (ts.name.indexOf("metamodel.ts") != -1) {
		        return; //FIXME
		    }
		    if (declared[ts.name]) {
		        return declared[ts.name];
		    }
		    var m = new ModuleWrapper(ts);
		    used[ts.name] = m;
		    declared[ts.name] = m;
		    Object.keys(ts.imports).forEach(function (x) {
		        var pMod = ts.imports[x];
		        if (used[pMod.name]) {
		            m.namespaceToMod[x] = used[pMod.name];
		            return;
		        }
		        var vMod = processModule(pMod, u, used, declared);
		        m.namespaceToMod[x] = vMod;
		    });
		    used[ts.name] = null;
		    return m;
		};
		function toDefSystem(ts) {
		    var u = new def.Universe("");
		    var c = {};
		    processModule(ts, u, {}, c);
		    Object.keys(c).forEach(function (x) {
		        registerClasses(c[x], u);
		    });
		    Object.keys(c).forEach(function (x) {
		        registerHierarchy(c[x], u);
		    });
		    Object.keys(c).forEach(function (x) {
		        registerEverything(c[x], u);
		    });
		    u.types().forEach(function (x) {
		        if (x instanceof def.NodeClass) {
		            var cl = x;
		            cl.properties().forEach(function (y) {
		                var t = y.range();
		                var ap = y;
		                if (!t.hasValueTypeInHierarchy()) {
		                    t.properties().forEach(function (p0) {
		                        if (p0.getAdapter(services.RAMLPropertyService).isKey()) {
		                            var kp = p0.keyPrefix();
		                            if (kp) {
		                                ap.withKeyRestriction(kp);
		                                ap.merge();
		                            }
		                            var eo = p0.enumOptions();
		                            if (eo) {
		                                ap.withEnumOptions(eo);
		                                ap.merge();
		                            }
		                        }
		                    });
		                }
		            });
		            if (cl.getAdapter(services.RAMLService).isGlobalDeclaration()) {
		                if (cl.getAdapter(services.RAMLService).getActuallyExports() && cl.getAdapter(services.RAMLService).getActuallyExports() != "$self") {
		                    var tp = cl.property(cl.getAdapter(services.RAMLService).getActuallyExports()).range();
		                    if (tp.hasValueTypeInHierarchy()) {
		                        var vt = tp.getAdapter(services.RAMLService);
		                        vt.setGloballyDeclaredBy(cl);
		                    }
		                }
		                if (cl.getAdapter(services.RAMLService).getConvertsToGlobal()) {
		                    var tp = u.type(cl.getAdapter(services.RAMLService).getConvertsToGlobal());
		                    if (tp.hasValueTypeInHierarchy()) {
		                        var vt = tp.getAdapter(services.RAMLService);
		                        vt.setGloballyDeclaredBy(cl);
		                    }
		                }
		            }
		        }
		    });
		    return u;
		}
		exports.toDefSystem = toDefSystem;
		var processAnnotations = function (x, p, annotations) {
		    if (!annotations) {
		        annotations = x.annotations();
		    }
		    annotations.forEach(function (x) {
		        var nm = x.name.substring(x.name.lastIndexOf(".") + 1);
		        if (!aHandlers.annotationHandlers[nm]) {
		            console.log("Can not find handler for:");
		        }
		        aHandlers.annotationHandlers[nm](x, p);
		    });
		};
		function createProp(x, clazz, t, annotations) {
		    var p = def.prop(x.name(), "", clazz, t);
		    if (x.isMultiValue()) {
		        p.withMultiValue(true);
		    }
		    p.unmerge();
		    if (!t.hasValueTypeInHierarchy()) {
		        t.properties().forEach(function (p0) {
		            if (p0.getAdapter(services.RAMLPropertyService).isKey()) {
		                var kp = p0.keyPrefix();
		                if (kp) {
		                    p.withKeyRestriction(kp);
		                    p.merge();
		                }
		                var eo = p0.enumOptions();
		                if (eo) {
		                    p.withEnumOptions(eo);
		                    p.merge();
		                }
		            }
		        });
		    }
		    processAnnotations(x, p, annotations);
		}


	/***/ },
	/* 84 */
	/***/ function(module, exports, __webpack_require__) {

		var def = __webpack_require__(3);
		var khttp = __webpack_require__(85);
		var _ = __webpack_require__(4);
		var services = __webpack_require__(49);
		function handleTypeAnnotation(a, rangeType) {
		    if (a.name == 'MetaModel.declaresSubTypeOf') {
		        rangeType.getAdapter(services.RAMLService).setExtendedTypeName(a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.nameAtRuntime') {
		        rangeType.setNameAtRuntime(a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.description') {
		        rangeType.withDescription(a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.inlinedTemplates') {
		        rangeType.getAdapter(services.RAMLService).setInlinedTemplates(true);
		    }
		    if (a.name == 'MetaModel.requireValue') {
		        rangeType.getAdapter(services.RAMLService).withContextRequirement("" + a.arguments[0], "" + a.arguments[1]);
		    }
		    if (a.name == 'MetaModel.referenceIs') {
		        rangeType.getAdapter(services.RAMLService).withReferenceIs("" + a.arguments[0]);
		    }
		    //MetaModel.referenceIs
		    if (a.name == 'MetaModel.actuallyExports') {
		        rangeType.getAdapter(services.RAMLService).withActuallyExports("" + a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.convertsToGlobalOfType') {
		        rangeType.getAdapter(services.RAMLService).withConvertsToGlobal("" + a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.allowAny') {
		        rangeType.getAdapter(services.RAMLService).withAllowAny();
		    }
		    if (a.name == 'MetaModel.allowQuestion') {
		        rangeType.getAdapter(services.RAMLService).withAllowQuestion();
		    }
		    if (a.name == 'MetaModel.alias') {
		        rangeType.getAdapter(services.RAMLService).addAlias("" + a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.consumesRefs') {
		        rangeType.getAdapter(services.RAMLService).setConsumesRefs(true);
		    }
		    if (a.name == 'MetaModel.canInherit') {
		        rangeType.getAdapter(services.RAMLService).withCanInherit("" + a.arguments[0]);
		    }
		    if (a.name == 'MetaModel.definingPropertyIsEnough') {
		        rangeType.getAdapter(services.RAMLService).definingPropertyIsEnough("" + a.arguments[0]);
		    }
		}
		exports.handleTypeAnnotation = handleTypeAnnotation;
		exports.annotationHandlers = {
		    key: function (a, f) {
		        f.withFromParentKey();
		        f.withKey(true);
		    },
		    value: function (a, f) {
		        f.withFromParentValue();
		    },
		    canBeValue: function (a, f) {
		        f.withCanBeValue();
		    },
		    unmerged: function (a, f) {
		        f.unmerge();
		    },
		    startFrom: function (a, f) {
		        f.withKeyRestriction(a.arguments[0]);
		        f.merge();
		    },
		    oneOf: function (a, f) {
		        f.withEnumOptions(a.arguments[0]);
		    },
		    oftenKeys: function (a, f) {
		        f.withOftenKeys(a.arguments[0]);
		    },
		    embeddedInMaps: function (a, f) {
		        f.getAdapter(services.RAMLPropertyParserService).withEmbedMap();
		    },
		    system: function (a, f) {
		        f.getAdapter(services.RAMLPropertyParserService).withSystem(true);
		    },
		    required: function (a, f) {
		        if (a.arguments[0] != 'false') {
		            f.withRequired(true);
		        }
		    },
		    noDirectParse: function (a, f) {
		        if (a.arguments[0] != 'false') {
		            f.withNoDirectParse();
		        }
		    },
		    setsContextValue: function (a, f) {
		        f.addChildValueConstraint(new def.ChildValueConstraint("" + a.arguments[0], "" + a.arguments[1]));
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    defaultValue: function (a, f) {
		        f.setDefaultVal("" + a.arguments[0]);
		    },
		    defaultIntegerValue: function (a, f) {
		        f.setDefaultIntegerVal(a.arguments[0]);
		    },
		    defaultBooleanValue: function (a, f) {
		        f.setDefaultBooleanVal(a.arguments[0]);
		    },
		    facetId: function (a, f) {
		        if (a.arguments[0] == "minItems") {
		            f.setFacetValidator(function (x, f) {
		                if (x instanceof Array) {
		                    var length = Number.parseInt("" + f.value());
		                    if (length > x.length) {
		                        return "array should contain at least " + f.value() + " items";
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "enum") {
		            f.setFacetValidator(function (x, f) {
		                var validateAgainst = x + "";
		                var array = f.children().map(function (x) { return x.value(); });
		                if (!array.some(function (x) { return x == validateAgainst; })) {
		                    return "value should be one of :" + array.join(",");
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "maxItems") {
		            f.setFacetValidator(function (x, f) {
		                if (x instanceof Array) {
		                    var length = Number.parseInt("" + f.value());
		                    if (length < x.length) {
		                        return "array should contain not more then " + f.value() + " items";
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "minProperties") {
		            f.setFacetValidator(function (x, f) {
		                if (x instanceof Object) {
		                    var length = Number.parseInt("" + f.value());
		                    if (length > Object.keys(x).length) {
		                        return "object should contain at least " + f.value() + " properties";
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "maxProperties") {
		            f.setFacetValidator(function (x, f) {
		                if (x instanceof Object) {
		                    var length = Number.parseInt("" + f.value());
		                    if (length < Object.keys(x).length) {
		                        return "object should contain not more then " + f.value() + " properties";
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "uniqueItems") {
		            f.setFacetValidator(function (x, f) {
		                if (x instanceof Array) {
		                    var length = _.unique(x).length;
		                    if (length < x.length) {
		                        return "array should contain only unique items";
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "minLength") {
		            f.setFacetValidator(function (x, f) {
		                if (typeof x == 'number' || typeof x == 'boolean') {
		                    x = "" + x;
		                }
		                if (typeof x == 'string') {
		                    var length = Number.parseInt("" + f.value());
		                    if (length > x.length) {
		                        return "string length should be at least " + length;
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "maxLength") {
		            f.setFacetValidator(function (x, f) {
		                if (typeof x == 'number' || typeof x == 'boolean') {
		                    x = "" + x;
		                }
		                if (typeof x == 'string') {
		                    var length = Number.parseInt("" + f.value());
		                    if (length < x.length) {
		                        return "string length should be not more then " + length;
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "minimum") {
		            f.setFacetValidator(function (x, f) {
		                if (typeof x == 'string') {
		                    x = parseFloat(x);
		                }
		                if (typeof x == 'number') {
		                    var length = parseFloat(f.value());
		                    if (length > x) {
		                        return "value should be not less then " + length;
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "maximum") {
		            f.setFacetValidator(function (x, f) {
		                if (typeof x == 'string') {
		                    x = parseFloat(x);
		                }
		                if (typeof x == 'number') {
		                    var length = parseFloat(f.value());
		                    if (length < x) {
		                        return "value should be not more then " + length;
		                    }
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "pattern") {
		            f.setFacetValidator(function (x, f) {
		                if (typeof x == 'number' || typeof x == 'boolean') {
		                    x = "" + x;
		                }
		                if (typeof x == 'string') {
		                    var regExp = new RegExp(f.value());
		                    if (!regExp.test(x)) {
		                        return "string should match to " + f.value();
		                    }
		                }
		                return null;
		            });
		        }
		    },
		    extraMetaKey: function (a, f) {
		        if (a.arguments[0] == "statusCodes") {
		            f.withOftenKeys(khttp.statusCodes.map(function (x) { return x.code; }));
		            f.setValueDocProvider(function (name) {
		                var s = _.find(khttp.statusCodes, function (x) { return x.code == name; });
		                if (s) {
		                    return (name + ":" + s.description);
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "headers") {
		            f.setValueSuggester(function (x) {
		                if (x.property()) {
		                    var c = x.property().getChildValueConstraints();
		                    if (_.find(c, function (x) {
		                        return x.name == "location" && x.value == "Params.ParameterLocation.HEADERS";
		                    })) {
		                        return khttp.headers.map(function (x) { return x.header; });
		                    }
		                    if (x.property()) {
		                        if (x.property().nameId() == "headers") {
		                            return khttp.headers.map(function (x) { return x.header; });
		                        }
		                    }
		                }
		                return null;
		            });
		            f.setValueDocProvider(function (name) {
		                var s = _.find(khttp.headers, function (x) { return x.header == name; });
		                if (s) {
		                    return (name + ":" + s.description);
		                }
		                return null;
		            });
		        }
		        if (a.arguments[0] == "methods") {
		            f.setValueDocProvider(function (name) {
		                var s = _.find(khttp.methods, function (x) { return x.method == name.toUpperCase(); });
		                if (s) {
		                    return (name + ":" + s.description);
		                }
		                return null;
		            });
		        }
		    },
		    requireValue: function (a, f) {
		        f.withContextRequirement("" + a.arguments[0], "" + a.arguments[1]);
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    allowMultiple: function (a, f) {
		        f.withMultiValue(true);
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    selector: function (a, f) {
		        f.setSelector("" + a.arguments[0]);
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    constraint: function (a, f) {
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    newInstanceName: function (a, f) {
		        f.withNewInstanceName("" + a.arguments[0]);
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    declaringFields: function (a, f) {
		        f.withThisPropertyDeclaresFields();
		        //f.withKeyRestriction(<string>a.arguments[0])
		    },
		    describesAnnotation: function (a, f) {
		        //f.withReferenceParameters();
		        f.withDescribes(a.arguments[0]);
		    },
		    allowNull: function (a, f) {
		        f.withAllowNull();
		    },
		    descriminatingProperty: function (a, f) {
		        //f.withReferenceParameters();
		        f.withDescriminating(true);
		    },
		    description: function (a, f) {
		        f.withDescription("" + a.arguments[0]);
		        //f.withReferenceParameters();
		        //f.withDescriminating(true)
		    },
		    inherited: function (a, f) {
		        f.withInherited(true);
		    },
		    selfNode: function (a, f) {
		        f.withSelfNode();
		    },
		    grammarTokenKind: function (a, f) {
		        f.getAdapter(services.RAMLPropertyService).withPropertyGrammarType("" + a.arguments[0]);
		    },
		    canInherit: function (a, f) {
		        f.withInheritedContextValue("" + a.arguments[0]);
		    },
		    canBeDuplicator: function (a, f) {
		        f.setCanBeDuplicator();
		    },
		    hide: function (a, f) {
		        if (a.arguments.length == 0) {
		            f.getAdapter(services.RAMLPropertyDocumentationService).setHidden(true);
		        }
		        else {
		            f.getAdapter(services.RAMLPropertyDocumentationService).setHidden(a.arguments[0]);
		        }
		    },
		    documentationTableLabel: function (a, f) {
		        f.getAdapter(services.RAMLPropertyDocumentationService).setDocTableName("" + a.arguments[0]);
		    },
		    markdownDescription: function (a, f) {
		        f.getAdapter(services.RAMLPropertyDocumentationService).setMarkdownDescription("" + a.arguments[0]);
		    },
		    valueDescription: function (a, f) {
		        f.getAdapter(services.RAMLPropertyDocumentationService).setValueDescription(a.arguments[0] != null ? ("" + a.arguments[0]) : null);
		    }
		};
		function recordAnnotation(p, a) {
		    exports.annotationHandlers[a.name](a, p);
		}
		exports.recordAnnotation = recordAnnotation;


	/***/ },
	/* 85 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(32);

	/***/ },
	/* 86 */
	/***/ function(module, exports) {

		module.exports = [
			{
				"classes": [
					{
						"name": "GlobalSchema",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.Referencable",
								"nameSpace": "Sys",
								"basicName": "Referencable",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "Sys.SchemaString",
										"nameSpace": "Sys",
										"basicName": "SchemaString",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"fields": [
							{
								"name": "key",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the global schema, used to refer on schema content"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "value",
								"type": {
									"typeName": "Sys.SchemaString",
									"nameSpace": "Sys",
									"basicName": "SchemaString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Content of the schema"
										]
									},
									{
										"name": "MetaModel.canBeValue",
										"arguments": []
									},
									{
										"name": "MetaModel.value",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"value"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"Content of the schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLSimpleElement",
								"nameSpace": "Common",
								"basicName": "RAMLSimpleElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ImportDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "key",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name prefix (without dot) used to refer imported declarations"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "value",
								"type": {
									"typeName": "Library",
									"nameSpace": "",
									"basicName": "Library",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Content of the declared namespace"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLSimpleElement",
								"nameSpace": "Common",
								"basicName": "RAMLSimpleElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Library",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"contains description of why library exist"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "LibraryBase",
								"nameSpace": "",
								"basicName": "LibraryBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "LibraryBase",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "schemas",
								"type": {
									"base": {
										"typeName": "GlobalSchema",
										"nameSpace": "",
										"basicName": "GlobalSchema",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Alias for the equivalent \"types\" property, for compatibility with RAML 0.8. Deprecated - API definitions should use the \"types\" property, as the \"schemas\" alias for that property name may be removed in a future RAML version. The \"types\" property allows for XML and JSON schemas."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "types",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"models.LocationKind.MODELS"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of (data) types for use within this API"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"Declarations of (data) types for use within this API. See [[raml-10-spec-types|Types]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map type names to type declarations; or an array of such objects"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "traits",
								"type": {
									"base": {
										"typeName": "RM.Trait",
										"nameSpace": "RM",
										"basicName": "Trait",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of traits used in this API"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of traits for use within this API"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"Declarations of traits for use within this API. See [[raml-10-spec-resource-types-and-traits|Resource Types and Traits]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map trait names to trait declarations; or an array of such objects"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "resourceTypes",
								"type": {
									"base": {
										"typeName": "RM.ResourceType",
										"nameSpace": "RM",
										"basicName": "ResourceType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declaration of resource types used in this API"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of resource types for use within this API"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"Declarations of resource types for use within this API. See [[raml-10-spec-resource-types-and-traits|Resource Types and Traits]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map resource type names to resource type declarations; or an array of such objects"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "annotationTypes",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"decls",
											"true"
										]
									},
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of annotation types for use by annotations"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"Declarations of annotation types for use by annotations. See [[raml-10-spec-declaring-annotation-types|Annotation Types]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map annotation type names to annotation type declarations; or an array of such objects"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securitySchemes",
								"type": {
									"base": {
										"typeName": "RM.AbstractSecurityScheme",
										"nameSpace": "RM",
										"basicName": "AbstractSecurityScheme",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Security schemas declarations"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of security schemes for use within this API."
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"Declarations of security schemes for use within this API. See [[raml-10-spec-security|Security Schemes]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map security scheme names to security scheme declarations; or an array of such objects"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uses",
								"type": {
									"base": {
										"typeName": "Library",
										"nameSpace": "",
										"basicName": "Library",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Importing libraries"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"decls",
											"true"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An array of libraries or a single library"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.internalClass",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Overlay",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"contains description of why overlay exist"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "masterRef",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Short plain-text label for the API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Api",
								"nameSpace": "",
								"basicName": "Api",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Extension",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"contains description of why extension exist"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "masterRef",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Short plain-text label for the API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Api",
								"nameSpace": "",
								"basicName": "Api",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Api",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Short plain-text label for the API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "version",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The version of the API, e.g. \"v1\""
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "baseUri",
								"type": {
									"typeName": "Sys.FullUriTemplateString",
									"nameSpace": "Sys",
									"basicName": "FullUriTemplateString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A URI that's to be used as the base of all the resources' URIs. Often used as the base of the URL of each resource, containing the location of the API. Can be a template URI."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "baseUriParameters",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"models.ModelLocation.BURI"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"models.LocationKind.APISTRUCTURE"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Named parameters used in the baseUri (template)"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "protocols",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"HTTP",
												"HTTPS"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The protocols supported by the API"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Array of strings, with each being \"HTTP\" or \"HTTPS\", case-insensitive"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "mediaType",
								"type": {
									"typeName": "Bodies.MimeType",
									"nameSpace": "Bodies",
									"basicName": "MimeType",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.oftenKeys",
										"arguments": [
											[
												"application/json",
												"application/xml",
												"application/x-www-form-urlencoded",
												"multipart/form-data"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The default media type to use for request and response bodies (payloads), e.g. \"application/json\""
										]
									},
									{
										"name": "MetaModel.inherited",
										"arguments": []
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Media type string"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "RM.SecuritySchemeRef",
										"nameSpace": "RM",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The security schemes that apply to every resource and method in the API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "resources",
								"type": {
									"base": {
										"typeName": "RM.Resource",
										"nameSpace": "RM",
										"basicName": "Resource",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.documentationTableLabel",
										"arguments": [
											"/&lt;relativeUri&gt;"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Resource"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The resources of the API, identified as relative URIs that begin with a slash (/). Every property whose key begins with a slash (/), and is either at the root of the API definition or is the child property of a resource property, is a resource property, e.g.: /users, /{groupId}, etc"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "documentation",
								"type": {
									"base": {
										"typeName": "DocumentationItem",
										"nameSpace": "",
										"basicName": "DocumentationItem",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Additional overall documentation for the API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "LibraryBase",
								"nameSpace": "",
								"basicName": "LibraryBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"displayName": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							],
							"name": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the API"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Annotations to be applied to this API. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See the [[raml-10-spec-annotations|section on annotations]]."
									]
								}
							]
						}
					},
					{
						"name": "DocumentationItem",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Title of documentation section"
										]
									},
									{
										"name": "MetaModel.required",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "content",
								"type": {
									"typeName": "Sys.MarkdownString",
									"nameSpace": "Sys",
									"basicName": "MarkdownString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Content of documentation section"
										]
									},
									{
										"name": "MetaModel.required",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ScriptSpec",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "language",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "content",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ApiDescription",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "apiFiles",
								"type": {
									"base": {
										"typeName": "Api",
										"nameSpace": "",
										"basicName": "Api",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "script",
								"type": {
									"base": {
										"typeName": "ScriptSpec",
										"nameSpace": "",
										"basicName": "ScriptSpec",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"endpoint",
												"callback"
											]
										]
									},
									{
										"name": "MetaModel.descriminatingProperty",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "CallbackAPIDescription",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "callback"
								},
								"optional": false
							},
							{
								"name": "callbackFor",
								"type": {
									"typeName": "Api",
									"nameSpace": "",
									"basicName": "Api",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "ApiDescription",
								"nameSpace": "",
								"basicName": "ApiDescription",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLProject",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "relatedProjects",
								"type": {
									"base": {
										"typeName": "RAMLProject",
										"nameSpace": "",
										"basicName": "RAMLProject",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "declaredApis",
								"type": {
									"base": {
										"typeName": "ApiDescription",
										"nameSpace": "",
										"basicName": "ApiDescription",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "license",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "overview",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "url",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"RM": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts",
					"Decls": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts",
					"Params": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts",
					"Bodies": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts",
					"models": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
			},
			{
				"classes": [
					{
						"name": "SpecPartMetaData",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts"
			},
			{
				"classes": [
					{
						"name": "ValueType",
						"methods": [
							{
								"name": "parse",
								"start": 87,
								"end": 252,
								"text": "\n    /**\n     * parses inner structure of value type if value type has invalid value you should throw error\n     * with descriptive message\n     */\n    parse():any{}"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "StringType",
						"methods": [
							{
								"name": "value",
								"start": 365,
								"end": 393,
								"text": " value():string{return null}"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"string"
								]
							},
							{
								"name": "MetaModel.alias",
								"arguments": [
									"string"
								]
							}
						],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "NumberType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"number"
								]
							},
							{
								"name": "MetaModel.alias",
								"arguments": [
									"integer"
								]
							},
							{
								"name": "MetaModel.alias",
								"arguments": [
									"number"
								]
							}
						],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BooleanType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"boolean"
								]
							},
							{
								"name": "MetaModel.alias",
								"arguments": [
									"boolean"
								]
							}
						],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Referencable",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Reference",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DeclaresDynamicType",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [
							{
								"typeName": "Referencable",
								"nameSpace": "",
								"basicName": "Referencable",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "T",
										"nameSpace": "",
										"basicName": "T",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "UriTemplate",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This type currently serves both for absolute and relative urls"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "StatusCodeString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RelativeUriString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This  type describes relative uri templates"
								]
							}
						],
						"extends": [
							{
								"typeName": "UriTemplate",
								"nameSpace": "",
								"basicName": "UriTemplate",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "FullUriTemplateString",
						"methods": [
							{
								"name": "validate",
								"start": 2371,
								"end": 3301,
								"text": "\n    //parse():string[]{\n    //    var value=this.value();\n    //    var result=[]\n    //    var temp=\"\";\n    //    var inPar=false;\n    //    var count=0;\n    //    for (var a=0;a<value.length;a++){\n    //        var c=value[a];\n    //        if (c=='{'){\n    //            count++;\n    //            inPar=true;\n    //            continue;\n    //        }\n    //        if (c=='}'){\n    //            count--;\n    //            inPar=false;\n    //            result.push(temp);\n    //            temp=\"\";\n    //            continue;\n    //        }\n    //        if (inPar){\n    //            temp+=c;\n    //        }\n    //    }\n    //    if (count>0){\n    //        throw new Error(\"Unmatched '{'\")\n    //    }\n    //    if (count<0){\n    //        throw new Error(\"Unmatched '}'\")\n    //    }\n    //    return result;\n    //}\n\n    validate(){\n        var str=this.value();\n        //write something to validate Url here\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This  type describes absolute uri templates"
								]
							}
						],
						"extends": [
							{
								"typeName": "UriTemplate",
								"nameSpace": "",
								"basicName": "UriTemplate",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "FixedUriString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This  type describes fixed uris"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ContentType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ValidityExpression",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "MarkdownString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.innerType",
								"arguments": [
									"markdown"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"[GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/)"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DateFormatSpec",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "FunctionalInterface",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SchemaString",
						"methods": [
							{
								"name": "validate",
								"start": 4078,
								"end": 4261,
								"text": "\n\n    validate(){\n        var str=this.value();\n        //write something to validate schema here here\n        //in fact it should check that content is valid json or xsd schema\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Schema at this moment only two subtypes are supported (json schema and xsd)"
								]
							},
							{
								"name": "MetaModel.alias",
								"arguments": [
									"schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ExampleString",
						"methods": [
							{
								"name": "validate",
								"start": 4415,
								"end": 4598,
								"text": "\n\n    validate(){\n        var str=this.value();\n        //write something to validate schema here here\n        //in fact it should check that content is valid json or xsd schema\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Examples at this moment only two subtypes are supported (json  and xml)"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "JSonSchemaString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.innerType",
								"arguments": [
									"json"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"JSON schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "SchemaString",
								"nameSpace": "",
								"basicName": "SchemaString",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "XMLSchemaString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.innerType",
								"arguments": [
									"xsd"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"XSD schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "SchemaString",
								"nameSpace": "",
								"basicName": "SchemaString",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLPointer",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLSelector",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
			},
			{
				"classes": [
					{
						"name": "ResourceTypeRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "ResourceType",
										"nameSpace": "",
										"basicName": "ResourceType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "TraitRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "Trait",
										"nameSpace": "",
										"basicName": "Trait",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecuritySchemePart",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "MethodBase",
								"nameSpace": "",
								"basicName": "MethodBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"headers": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Optional array of headers, documenting the possible headers that could be accepted. See [[raml-10-spec-headers|Headers]] section."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose property names are the request header names and whose values describe the values."
									]
								}
							],
							"queryParameters": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Query parameters, used by the scheme in order to authorize the request. Mutually exclusive with queryString. See [[raml-10-spec-query-parameters-in-a-query-string|Query Parameters]] section."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose property names are the query parameter names and whose values describe the values."
									]
								}
							],
							"queryString": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Specifies the query string, used by the scheme in order to authorize the request. Mutually exclusive with queryParameters."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Type name or type declaration"
									]
								}
							],
							"responses": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Optional array of responses, describing the possible responses that could be sent. See [[raml-10-spec-responses|Responses]] section."
									]
								}
							],
							"is": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							],
							"securedBy": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							],
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the security scheme part"
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the security scheme part"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Markdown string"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Annotations to be applied to this security scheme part. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See [[raml-10-spec-annotations|the section on annotations]]."
									]
								}
							]
						}
					},
					{
						"name": "SecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							}
						],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "OAuth1SecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "requestTokenUri",
								"type": {
									"typeName": "Sys.FixedUriString",
									"nameSpace": "Sys",
									"basicName": "FixedUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Temporary Credential Request endpoint as defined in RFC5849 Section 2.1"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "authorizationUri",
								"type": {
									"typeName": "Sys.FixedUriString",
									"nameSpace": "Sys",
									"basicName": "FixedUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Resource Owner Authorization endpoint as defined in RFC5849 Section 2.2"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "tokenCredentialsUri",
								"type": {
									"typeName": "Sys.FixedUriString",
									"nameSpace": "Sys",
									"basicName": "FixedUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Token Request endpoint as defined in RFC5849 Section 2.3"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "signatures",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"HMAC-SHA1",
												"RSA-SHA1",
												"PLAINTEXT"
											]
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							},
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"$parent.type=='OAuth 1.0'"
								]
							}
						],
						"extends": [
							{
								"typeName": "SecuritySchemeSettings",
								"nameSpace": "",
								"basicName": "SecuritySchemeSettings",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "OAuth2SecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "accessTokenUri",
								"type": {
									"typeName": "Sys.FixedUriString",
									"nameSpace": "Sys",
									"basicName": "FixedUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Token Endpoint as defined in RFC6749 [RFC6748] Section 3.2. Not required forby implicit grant type."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "authorizationUri",
								"type": {
									"typeName": "Sys.FixedUriString",
									"nameSpace": "Sys",
									"basicName": "FixedUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Authorization Endpoint as defined in RFC6749 [RFC6748] Section 3.1. Required forby authorization_code and implicit grant types."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "authorizationGrants",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"A list of the Authorization grants supported by the API as defined in RFC6749 [RFC6749] Sections 4.1, 4.2, 4.3 and 4.4, can be any of:<br>* authorization_code<br>* password<br>* client_credentials<br>* implicit<br>* refresh_token."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "scopes",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A list of scopes supported by the security scheme as defined in RFC6749 [RFC6749] Section 3.3"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "SecuritySchemeSettings",
								"nameSpace": "",
								"basicName": "SecuritySchemeSettings",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "PassThroughSecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "queryParameterName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "headerName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "SecuritySchemeSettings",
								"nameSpace": "",
								"basicName": "SecuritySchemeSettings",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecuritySchemeRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "AbstractSecurityScheme",
										"nameSpace": "",
										"basicName": "AbstractSecurityScheme",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AbstractSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.Referencable",
								"nameSpace": "Sys",
								"basicName": "Referencable",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "AbstractSecurityScheme",
										"nameSpace": "",
										"basicName": "AbstractSecurityScheme",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.startFrom",
										"arguments": [
											""
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"OAuth 1.0",
												"OAuth 2.0",
												"Basic Authentication",
												"Digest Authentication",
												"Pass Through",
												"x-{other}"
											]
										]
									},
									{
										"name": "MetaModel.descriminatingProperty",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The securitySchemes property MUST be used to specify an API's security mechanisms, including the required settings and the authentication methods that the API supports. one authentication method is allowed if the API supports them."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"string<br><br>The value MUST be one of<br>* OAuth 1.0,<br>* OAuth 2.0,<br>* BasicSecurityScheme Authentication<br>* DigestSecurityScheme Authentication<br>* Pass Through<br>* x-&lt;other&gt;"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "description",
								"type": {
									"typeName": "Sys.MarkdownString",
									"nameSpace": "Sys",
									"basicName": "MarkdownString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The description attribute MAY be used to describe a security schemes property."
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The description MAY be used to describe a securityScheme."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "describedBy",
								"type": {
									"typeName": "SecuritySchemePart",
									"nameSpace": "",
									"basicName": "SecuritySchemePart",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A description of the request components related to Security that are determined by the scheme: the headers, query parameters or responses. As a best practice, even for standard security schemes, API designers SHOULD describe these properties of security schemes.\nIncluding the security scheme description completes an API documentation."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "SecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "SecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The settings attribute MAY be used to provide security scheme-specific information. The required attributes vary depending on the type of security scheme is being declared.\nIt describes the minimum set of properties which any processing application MUST provide and validate if it chooses to implement the security scheme. Processing applications MAY choose to recognize other properties for things such as token lifetime, preferred cryptographic algorithms, and more."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "OAuth2SecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "OAuth 2.0"
								},
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "OAuth2SecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "OAuth2SecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "OAuth1SecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "OAuth 1.0"
								},
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "OAuth1SecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "OAuth1SecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "PassThroughSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "Pass Through"
								},
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "PassThroughSecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "PassThroughSecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BasicSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "Basic Authentication"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DigestSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "Digest Authentication"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "CustomSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "x-{other}"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security scheme definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "MethodBase",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "responses",
								"type": {
									"base": {
										"typeName": "Bodies.Response",
										"nameSpace": "Bodies",
										"basicName": "Response",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"response",
											"true"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Response"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Information about the expected responses to a request"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose keys are the HTTP status codes of the responses and whose values describe the responses."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "body",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Body"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Some method verbs expect the resource to be sent as a request body. For example, to create a resource, the request must include the details of the resource to create.\nResources CAN have alternate representations. For example, an API might support both JSON and XML representations.\nA method's body is defined in the body property as a hashmap, in which the key MUST be a valid media type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "protocols",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"HTTP",
												"HTTPS"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A method can override the protocols specified in the resource or at the API root, by employing this property."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"array of strings of value HTTP or HTTPS, or a single string of such kind, case-insensitive"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "is",
								"type": {
									"base": {
										"typeName": "TraitRef",
										"nameSpace": "",
										"basicName": "TraitRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instantiation of applyed traits"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "SecuritySchemeRef",
										"nameSpace": "",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											" securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.\nTo indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Params.HasNormalParameters",
								"nameSpace": "Params",
								"basicName": "HasNormalParameters",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Trait",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.DeclaresDynamicType",
								"nameSpace": "Sys",
								"basicName": "DeclaresDynamicType",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "Trait",
										"nameSpace": "",
										"basicName": "Trait",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the trait"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uses",
								"type": {
									"base": {
										"typeName": "api.Library",
										"nameSpace": "api",
										"basicName": "Library",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"You may import library locally here it contents is accessible only inside of this trait"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"decls",
											"true"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An array of libraries or a single library"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.inlinedTemplates",
								"arguments": []
							},
							{
								"name": "MetaModel.allowQuestion",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "MethodBase",
								"nameSpace": "",
								"basicName": "MethodBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ResourceBase",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "methods",
								"type": {
									"base": {
										"typeName": "Method",
										"nameSpace": "",
										"basicName": "Method",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Methods that are part of this resource type definition"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"The methods available on this resource. See [[raml-10-spec-methods|the section on method properties]]."
										]
									},
									{
										"name": "MetaModel.documentationTableLabel",
										"arguments": [
											"get?<br>patch?<br>put?<br>post?<br>delete?<br>options?<br>head?<br>trace?<br>connect?"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Object describing the method"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "is",
								"type": {
									"base": {
										"typeName": "TraitRef",
										"nameSpace": "",
										"basicName": "TraitRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A list of the traits to apply to all methods declared (implicitly or explicitly) for this resource. See [[raml-10-spec-applying-resource-types-and-traits|Applying Resource Types and Traits]] section. Individual methods may override this declaration"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"array, which can contain each of the following elements:<br>* name of unparametrized trait<br>* a key-value pair with trait name as key and a map of trait parameters as value<br>* inline trait declaration<br><br>(or a single element of any above kind)"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "ResourceTypeRef",
									"nameSpace": "",
									"basicName": "ResourceTypeRef",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The resource type which this resource inherits. . See [[raml-10-spec-applying-resource-types-and-traits|Applying Resource Types and Traits]] section."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"one of the following elements:<br>* name of unparametrized resource type<br>* a key-value pair with resource type name as key and a map of its parameters as value<br>* inline resource type declaration"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "SecuritySchemeRef",
										"nameSpace": "",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The security schemes that apply to all methods declared (implicitly or explicitly) for this resource."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"array of security scheme names or a single security scheme name"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uriParameters",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"models.ModelLocation.URI"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"models.LocationKind.APISTRUCTURE"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Detailed information about any URI parameters of this resource"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"object whose property names are the URI parameter names and whose values describe the values"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ResourceType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.DeclaresDynamicType",
								"nameSpace": "Sys",
								"basicName": "DeclaresDynamicType",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "ResourceType",
										"nameSpace": "",
										"basicName": "ResourceType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the resource type"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uses",
								"type": {
									"base": {
										"typeName": "api.Library",
										"nameSpace": "api",
										"basicName": "Library",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"You may import library locally here it contents is accessible only inside of this resource type"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"decls",
											"true"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An array of libraries"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.inlinedTemplates",
								"arguments": []
							},
							{
								"name": "MetaModel.allowQuestion",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "ResourceBase",
								"nameSpace": "",
								"basicName": "ResourceBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ResourceTypeOrTrait",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instructions on how and when to use this resource type in a RAML spec"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Markdown string"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uses",
								"type": {
									"base": {
										"typeName": "api.Library",
										"nameSpace": "api",
										"basicName": "Library",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"You may import library locally here it contents is accessible only inside of this trait"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An array of libraries"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "parameters",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Optional declaration of the parameters that the resource type employs."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose property names are the parameter names and whose property values describe the parameter data types."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Method",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "method",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"methods"
										]
									},
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"get",
												"put",
												"post",
												"delete",
												"options",
												"head",
												"patch",
												"trace",
												"connect"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Method that can be called"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "MethodBase",
								"nameSpace": "",
								"basicName": "MethodBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the method (in the resource's context)."
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the method (in the resource's context)"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Markdown string"
									]
								}
							],
							"queryString": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Specifies the query string needed by this method. Mutually exclusive with queryParameters."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Type name or type declaration"
									]
								}
							],
							"queryParameters": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Detailed information about any query parameters needed by this method. Mutually exclusive with queryString."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose property names are the query parameter names and whose values describe the values."
									]
								}
							],
							"headers": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Detailed information about any request headers needed by this method."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose property names are the request header names and whose values describe the values."
									]
								}
							],
							"body": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Some methods admit request bodies, which are described by this property."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose properties are either<br>1) media types and whose values are type objects describing the request body for that media type, or<br>2) a type object describing the request body for the default media type specified in the root mediaType property"
									]
								}
							],
							"is": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A list of the traits to apply to this method. See [[raml-10-spec-applying-resource-types-and-traits|Applying Resource Types and Traits]] section."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"array, which can contain each of the following elements:<br>* name of unparametrized trait<br>* a key-value pair with trait name as key and a map of trait parameters as value<br>* inline trait declaration<br><br>(or a single element of any above kind)"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Annotations to be applied to this method. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See the [[raml-10-spec-annotations|section on annotations]]."
									]
								}
							],
							"securedBy": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"The security schemes that apply to this method"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Array of security scheme names or a  single security scheme name"
									]
								}
							]
						}
					},
					{
						"name": "Resource",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "relativeUri",
								"type": {
									"typeName": "Sys.RelativeUriString",
									"nameSpace": "Sys",
									"basicName": "RelativeUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.startFrom",
										"arguments": [
											"/"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Relative URL of this resource from the parent resource"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "resources",
								"type": {
									"base": {
										"typeName": "Resource",
										"nameSpace": "",
										"basicName": "Resource",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Resource"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A nested resource is identified as any property whose name begins with a slash (\"/\") and is therefore treated as a relative URI."
										]
									},
									{
										"name": "MetaModel.documentationTableLabel",
										"arguments": [
											"/&lt;relativeUri&gt;"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"object describing the nested resource"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "ResourceBase",
								"nameSpace": "",
								"basicName": "ResourceBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the resource."
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the resource."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Markdown string"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Annotations to be applied to this resource. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See the [[raml-10-spec-annotations|section on annotations]]."
									]
								}
							]
						}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"Params": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts",
					"Bodies": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts",
					"Declarations": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts",
					"models": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts",
					"auth": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/auth.ts",
					"api": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/api.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/methodsAndResources.ts"
			},
			{
				"classes": [
					{
						"name": "FileTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "file"
								},
								"optional": false
							},
							{
								"name": "fileTypes",
								"type": {
									"base": {
										"typeName": "Sys.ContentType",
										"nameSpace": "Sys",
										"basicName": "ContentType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"It should also include a new property: fileTypes, which should be a list of valid content-type strings for the file. The file type */* should be a valid value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "minLength",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The minLength attribute specifies the parameter value's minimum number of bytes."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maxLength",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The maxLength attribute specifies the parameter value's maximum number of bytes."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"(Applicable only to Form properties) Value is a file. Client generators SHOULD use this type to handle file uploads correctly."
								]
							}
						],
						"extends": [
							{
								"typeName": "datamodel.TypeDeclaration",
								"nameSpace": "datamodel",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "HasNormalParameters",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "queryParameters",
								"type": {
									"base": {
										"typeName": "datamodel.TypeDeclaration",
										"nameSpace": "datamodel",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"datamodel.ModelLocation.QUERY"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"datamodel.LocationKind.APISTRUCTURE"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New query parameter"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"An APIs resources MAY be filtered (to return a subset of results) or altered (such as transforming a response body from JSON to XML format) by the use of query strings. If the resource or its method supports a query string, the query string MUST be defined by the queryParameters property"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "headers",
								"type": {
									"base": {
										"typeName": "datamodel.TypeDeclaration",
										"nameSpace": "datamodel",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"datamodel.ModelLocation.HEADERS"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"datamodel.LocationKind.APISTRUCTURE"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Headers that allowed at this position"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Header"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "queryString",
								"type": {
									"typeName": "datamodel.TypeDeclaration",
									"nameSpace": "datamodel",
									"basicName": "TypeDeclaration",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts",
					"datamodel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/parameters.ts"
			},
			{
				"classes": [
					{
						"name": "RAMLLanguageElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "displayName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The displayName attribute specifies the $self's display name. It is a friendly name used only for display or documentation purposes. If displayName is not specified, it defaults to the element's key (the name of the property itself)."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "description",
								"type": {
									"typeName": "Sys.MarkdownString",
									"nameSpace": "Sys",
									"basicName": "MarkdownString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The description attribute describes the intended use or meaning of the $self. This value MAY be formatted using Markdown [MARKDOWN]"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "annotations",
								"type": {
									"base": {
										"typeName": "Decls.AnnotationRef",
										"nameSpace": "Decls",
										"basicName": "AnnotationRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.noDirectParse",
										"arguments": []
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"datamodel.LocationKind.APISTRUCTURE"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"datamodel.ModelLocation.ANNOTATION"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Most of RAML model elements may have attached annotations decribing additional meta data about this element"
										]
									},
									{
										"name": "MetaModel.documentationTableLabel",
										"arguments": [
											"(&lt;annotationName&gt;)"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"A value corresponding to the declared type of this annotation."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLSimpleElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"Decls": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts"
			},
			{
				"classes": [
					{
						"name": "AnnotationTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.DeclaresDynamicType",
								"nameSpace": "Sys",
								"basicName": "DeclaresDynamicType",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "AnnotationTypeDeclaration",
										"nameSpace": "",
										"basicName": "AnnotationTypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
							}
						],
						"fields": [
							{
								"name": "allowMultiple",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Whether multiple instances of annotations of this type may be applied simultaneously at the same location"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "allowedTargets",
								"type": {
									"base": {
										"typeName": "AnnotationTarget",
										"nameSpace": "",
										"basicName": "AnnotationTarget",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"API",
												"DocumentationItem",
												"Resource",
												"Method",
												"Response",
												"RequestBody",
												"ResponseBody",
												"TypeDeclaration",
												"NamedExample",
												"ResourceType",
												"Trait",
												"SecurityScheme",
												"SecuritySchemeSettings",
												"AnnotationTypeDeclaration",
												"Library",
												"Overlay",
												"Extension"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Restrictions on where annotations of this type can be applied. If this property is specified, annotations of this type may only be applied on a property corresponding to one of the target names specified as the value of this property."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An array of names (or a single name) from the list of Target Names in the [[raml-10-spec-target-locations-table|Target Locations table]]  below. "
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"Annotation"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"AnnotationTypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "common.RAMLLanguageElement",
								"nameSpace": "common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"usage": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Instructions on how and when to use this annotation in a RAML spec."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Markdown string"
									]
								}
							]
						}
					},
					{
						"name": "AnnotationRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Annotations allow you to attach information to your API"
								]
							},
							{
								"name": "MetaModel.tags",
								"arguments": [
									[
										"annotations"
									]
								]
							}
						],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "AnnotationTypeDeclaration",
										"nameSpace": "",
										"basicName": "AnnotationTypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AnnotationTarget",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Elements to which this Annotation can be applied (enum)"
								]
							},
							{
								"name": "MetaModel.tags",
								"arguments": [
									[
										"annotations"
									]
								]
							}
						],
						"extends": [
							{
								"typeName": "Sys.ValueType",
								"nameSpace": "Sys",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Annotation",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"datamodel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts",
					"common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
			},
			{
				"classes": [
					{
						"name": "ExampleSpec",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "content",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.selfNode",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The example itself"
										]
									},
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"* Valid value for this type<br>* String representing the serialized version of a valid value"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "strict",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"By default, examples are validated against any type declaration. Set this to false to allow examples that need not validate."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the example"
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the example"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"markdown string"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Annotations to be applied to this example. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See the [[raml-10-spec-annotations|section on annotations]]."
									]
								}
							]
						}
					},
					{
						"name": "DataElementProperty",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"name of the parameter"
										]
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"headers"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "location",
								"type": {
									"typeName": "ModelLocation",
									"nameSpace": "",
									"basicName": "ModelLocation",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.system",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Location of the parameter (can not be edited by user)"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "locationKind",
								"type": {
									"typeName": "LocationKind",
									"nameSpace": "",
									"basicName": "LocationKind",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.system",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Kind of location"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "default",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Provides default value for a property"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"any"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "required",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.requireValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Sets if property is optional or not"
										]
									},
									{
										"name": "MetaModel.describesAnnotation",
										"arguments": [
											"required"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"boolean = true"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "TypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"name of the parameter"
										]
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"headers"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "facets",
								"type": {
									"base": {
										"typeName": "TypeDeclaration",
										"nameSpace": "",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.declaringFields",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"When extending from a type you can define new facets (which can then be set to concrete values by subtypes)."
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "schema",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Alias for the equivalent \"type\" property, for compatibility with RAML 0.8. Deprecated - API definitions should use the \"type\" property, as the \"schema\" alias for that property name may be removed in a future RAML version. The \"type\" property allows for XML and JSON schemas."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Single string denoting the base type or type expression"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.allowMultiple",
										"arguments": []
									},
									{
										"name": "MetaModel.canBeValue",
										"arguments": []
									},
									{
										"name": "MetaModel.defaultValue",
										"arguments": [
											"string"
										]
									},
									{
										"name": "MetaModel.descriminatingProperty",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A base type which the current type extends, or more generally a type expression."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"string denoting the base type or type expression"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "location",
								"type": {
									"typeName": "ModelLocation",
									"nameSpace": "",
									"basicName": "ModelLocation",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.system",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Location of the parameter (can not be edited by user)"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "locationKind",
								"type": {
									"typeName": "LocationKind",
									"nameSpace": "",
									"basicName": "LocationKind",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.system",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Kind of location"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "default",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Provides default value for a property"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "example",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.selfNode",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"An example of an instance of this type. This can be used, e.g., by documentation generators to generate sample values for an object of this type. Cannot be present if the examples property is present."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"* Valid value for this type<br>* String representing the serialized version of a valid value"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "examples",
								"type": {
									"base": {
										"typeName": "ExampleSpec",
										"nameSpace": "",
										"basicName": "ExampleSpec",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"An object containing named examples of instances of this type. This can be used, e.g., by documentation generators to generate sample values for an object of this type. Cannot be present if the examples property is present."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map example names to Example objects (see [[raml-10-spec-examples|Examples]] section); or an array of Example objects."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "repeat",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.requireValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The repeat attribute specifies that the parameter can be repeated. If the parameter can be used multiple times, the repeat parameter value MUST be set to 'true'. Otherwise, the default value is 'false' and the parameter may not be repeated."
										]
									},
									{
										"name": "MetaModel.defaultBooleanValue",
										"arguments": [
											false
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "required",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.requireValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Sets if property is optional or not"
										]
									},
									{
										"name": "MetaModel.describesAnnotation",
										"arguments": [
											"required"
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									},
									{
										"name": "MetaModel.defaultBooleanValue",
										"arguments": [
											true
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.convertsToGlobalOfType",
								"arguments": [
									"SchemaString"
								]
							},
							{
								"name": "MetaModel.canInherit",
								"arguments": [
									"mediaType"
								]
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the type"
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the type"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"markdown string"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Annotations to be applied to this type. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See the [[raml-10-spec-annotations|section on annotations]]."
									]
								}
							]
						}
					},
					{
						"name": "ScalarElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "facets",
								"type": {
									"base": {
										"typeName": "TypeDeclaration",
										"nameSpace": "",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.declaringFields",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"When extending from a scalar type you can define new facets (which can then be set to concrete values by subtypes)."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map facets names to their types."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "enum",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.describesAnnotation",
										"arguments": [
											"oneOf"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Enumeration of possible values for this primitive type. Cannot be used with the file type."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Array containing string representations of possible values, or a single string if there is only one possible value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ArrayTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "array"
								},
								"optional": false
							},
							{
								"name": "uniqueItems",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"uniqueItems"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Should items in array be unique"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "items",
								"type": {
									"typeName": "TypeDeclaration",
									"nameSpace": "",
									"basicName": "TypeDeclaration",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Array component type."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Inline type declaration or type name."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "minItems",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"minItems"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Minimum amount of items in array"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"integer ( >= 0 ). Defaults to 0"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maxItems",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"maxItems"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Maximum amount of items in array"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"integer ( >= 0 ). Defaults to undefined."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.convertsToGlobalOfType",
								"arguments": [
									"SchemaString"
								]
							},
							{
								"name": "MetaModel.alias",
								"arguments": [
									"array"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "UnionTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "discriminator",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.selector",
										"arguments": [
											"*.DataElement"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Type property name to be used as a discriminator or boolean"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "union"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.convertsToGlobalOfType",
								"arguments": [
									"SchemaString"
								]
							},
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"locationKind",
									"LocationKind.MODELS"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DataElementRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "TypeDeclaration",
										"nameSpace": "",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ObjectTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "properties",
								"type": {
									"base": {
										"typeName": "TypeDeclaration",
										"nameSpace": "",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The properties that instances of this type may or must have."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose keys are the properties' names and whose values are property declarations."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "minProperties",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"minProperties"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The minimum number of properties allowed for instances of this type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maxProperties",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"maxProperties"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The maximum number of properties allowed for instances of this type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "additionalProperties",
								"type": {
									"typeName": "TypeDeclaration",
									"nameSpace": "",
									"basicName": "TypeDeclaration",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"JSON schema style syntax for declaring maps"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"JSON schema style syntax for declaring maps. See [[raml-10-spec-map-types|Map Types]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Inline type declaration or typename"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "patternProperties",
								"type": {
									"base": {
										"typeName": "TypeDeclaration",
										"nameSpace": "",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"JSON schema style syntax for declaring key restricted maps"
										]
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"JSON schema style syntax for declaring key restricted maps. See [[raml-10-spec-map-types|Map Types]]."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"An object whose properties map regular expressions (which are regarded as defining ranges for property names) to types of properties expressed as Inline type declaration or typename."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "discriminator",
								"type": {
									"typeName": "pointer",
									"nameSpace": "",
									"basicName": "pointer",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.selector",
										"arguments": [
											"*.DataElement"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Type property name to be used as discriminator, or boolean"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "discriminatorValue",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The value of discriminator for the type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": null,
								"annotations": [
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "object"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.definingPropertyIsEnough",
								"arguments": [
									"properties"
								]
							},
							{
								"name": "MetaModel.setsContextValue",
								"arguments": [
									"field",
									"true"
								]
							},
							{
								"name": "MetaModel.convertsToGlobalOfType",
								"arguments": [
									"SchemaString"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "StringTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "pattern",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"pattern"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Regular expression that this string should path"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"regexp"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "minLength",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"minLength"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Minimum length of the string"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maxLength",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"maxLength"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Maximum length of the string"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "string"
								},
								"optional": false
							},
							{
								"name": "enum",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"enum"
										]
									},
									{
										"name": "MetaModel.describesAnnotation",
										"arguments": [
											"oneOf"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type string) The enum attribute provides an enumeration of the parameter's valid values. This MUST be an array. If the enum attribute is defined, API clients and servers MUST verify that a parameter's value matches a value in the enum array. If there is no matching value, the clients and servers MUST treat this as an error."
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value must be a string"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BooleanTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "boolean"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value must be a boolean"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ValueTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "value"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value must be a boolean"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "NumberTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "number"
								},
								"optional": false
							},
							{
								"name": "minimum",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"minimum"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type number or integer) The minimum attribute specifies the parameter's minimum value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maximum",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"maximum"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type number or integer) The maximum attribute specifies the parameter's maximum value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "enum",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.facetId",
										"arguments": [
											"enum"
										]
									},
									{
										"name": "MetaModel.describesAnnotation",
										"arguments": [
											"oneOf"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type string) The enum attribute provides an enumeration of the parameter's valid values. This MUST be an array. If the enum attribute is defined, API clients and servers MUST verify that a parameter's value matches a value in the enum array. If there is no matching value, the clients and servers MUST treat this as an error."
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "format",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"int32",
												"int64",
												"int",
												"long",
												"float",
												"double",
												"int16",
												"int8"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Value format"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "multipleOf",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A numeric instance is valid against \"multipleOf\" if the result of the division of the instance by this keyword's value is an integer."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value MUST be a number. Indicate floating point numbers as defined by YAML."
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "IntegerTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "integer"
								},
								"optional": false
							},
							{
								"name": "format",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"int32",
												"int64",
												"int",
												"long",
												"int16",
												"int8"
											]
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value MUST be a integer."
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "NumberTypeDeclaration",
								"nameSpace": "",
								"basicName": "NumberTypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLPointerElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "pointer"
								},
								"optional": false
							},
							{
								"name": "target",
								"type": {
									"typeName": "Sys.RAMLSelector",
									"nameSpace": "Sys",
									"basicName": "RAMLSelector",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"locationKind",
									"LocationKind.APISTRUCTURE"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "pointer",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.ValueType",
								"nameSpace": "Sys",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLExpression",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "ramlexpression"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"locationKind",
									"LocationKind.APISTRUCTURE"
								]
							},
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"location",
									"ModelLocation.ANNOTATION"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ScriptHookElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "script"
								},
								"optional": false
							},
							{
								"name": "declaredIn",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Typescript file defining interface which this scrip should comply to"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "interfaceName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the interface which scripts should comply to"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"locationKind",
									"LocationKind.APISTRUCTURE"
								]
							},
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"location",
									"ModelLocation.ANNOTATION"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SchemaElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "schema"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"locationKind",
									"LocationKind.APISTRUCTURE"
								]
							},
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"SchemaString"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DateTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "date"
								},
								"optional": false
							},
							{
								"name": "dateFormat",
								"type": {
									"typeName": "Sys.DateFormatSpec",
									"nameSpace": "Sys",
									"basicName": "DateFormatSpec",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value MUST be a string representation of a date as defined in RFC2616 Section 3.3 [RFC2616]. or according to specified date format"
								]
							},
							{
								"name": "MetaModel.declaresSubTypeOf",
								"arguments": [
									"TypeDeclaration"
								]
							}
						],
						"extends": [
							{
								"typeName": "TypeDeclaration",
								"nameSpace": "",
								"basicName": "TypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [
					{
						"name": "ModelLocation",
						"members": [
							"QUERY",
							"HEADERS",
							"URI",
							"FORM",
							"BURI",
							"ANNOTATION",
							"MODEL",
							"SECURITYSCHEMATYPE"
						]
					},
					{
						"name": "LocationKind",
						"members": [
							"APISTRUCTURE",
							"DECLARATIONS",
							"MODELS"
						]
					}
				],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"Bodies": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts",
					"Declarations": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/declarations.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts"
			},
			{
				"classes": [
					{
						"name": "MimeTypeModel",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "tree",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": true
							},
							{
								"name": "subtype",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "suffix",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": true
							},
							{
								"name": "parameters",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": true
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "MimeType",
						"methods": [
							{
								"name": "isForm",
								"start": 402,
								"end": 627,
								"text": "\n    isForm(){\n        if (this.value()==\"application/x-www-form-urlencoded\"||this.value()=='multipart/form-data'){\n            return true;\n        }\n        //TODO USE PARSE\n        return false;//more smart code here\n    }"
							},
							{
								"name": "isXML",
								"start": 627,
								"end": 798,
								"text": "\n\n    isXML(){\n        //TODO USE PARSE\n\n        if (this.value()==\"application/xml\"){\n            return true;\n        }\n        return false;//more smart code here\n    }"
							},
							{
								"name": "isJSON",
								"start": 798,
								"end": 971,
								"text": "\n\n    isJSON(){\n        //TODO USE PARSE\n\n        if (this.value()==\"application/json\"){\n            return true;\n        }\n        return false;//more smart code here\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This sub type of the string represents mime types"
								]
							}
						],
						"extends": [
							{
								"typeName": "Sys.StringType",
								"nameSpace": "Sys",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Response",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "code",
								"type": {
									"typeName": "Sys.StatusCodeString",
									"nameSpace": "Sys",
									"basicName": "StatusCodeString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"statusCodes"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Responses MUST be a map of one or more HTTP status codes, where each status code itself is a map that describes that status code."
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "headers",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"models.ModelLocation.HEADERS"
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"locationKind",
											"models.LocationKind.APISTRUCTURE"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Header"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Detailed information about any response headers returned by this method"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Object whose property names are the response header names and whose values describe the values."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "body",
								"type": {
									"base": {
										"typeName": "models.TypeDeclaration",
										"nameSpace": "models",
										"basicName": "TypeDeclaration",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Body"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The body of the response: a body declaration"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"Object whose properties are either<br>* Media types and whose values are type objects describing the request body for that media type, or<br>* a type object describing the request body for the default media type specified in the root mediaType property."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the response"
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the response"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Markdown string"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Annotations to be applied to this response. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See the [[raml-10-spec-annotations|section on annotations]]."
									]
								}
							]
						}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts",
					"models": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/datamodel.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/common.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/bodies.ts"
			},
			{
				"classes": [
					{
						"name": "Status",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "code",
								"type": {
									"typeName": "StatusCode",
									"nameSpace": "",
									"basicName": "StatusCode",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/auth.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "message",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AuthentificationState",
						"methods": [
							{
								"name": "testAccessControl",
								"start": 436,
								"end": 565,
								"text": "\n\n    /**\n     * allows to test if method can be accessed\n     * @param req\n     */\n    testAccessControl(req:har.Request):Status"
							},
							{
								"name": "testAccessControl",
								"start": 565,
								"end": 623,
								"text": "\n\n\n    testAccessControl(method:RamlWrapper.Method):Status"
							},
							{
								"name": "status",
								"start": 623,
								"end": 645,
								"text": "\n\n    status():Status;"
							},
							{
								"name": "schemeId",
								"start": 645,
								"end": 668,
								"text": "\n\n    schemeId():string"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AuthentificationParameters",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AuthData",
						"methods": [
							{
								"name": "api",
								"start": 755,
								"end": 781,
								"text": "\n    api():RamlWrapper.Api"
							},
							{
								"name": "apiUrl",
								"start": 781,
								"end": 802,
								"text": "\n    apiUrl():string;"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "authentificationParameters",
								"type": {
									"typeName": "AuthentificationParameters",
									"nameSpace": "",
									"basicName": "AuthentificationParameters",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/auth.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ParameterSpec",
						"methods": [
							{
								"name": "name",
								"start": 888,
								"end": 906,
								"text": "\n    name():string"
							},
							{
								"name": "required",
								"start": 906,
								"end": 930,
								"text": "\n    required():boolean;"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "PromptSpec",
						"methods": [
							{
								"name": "name",
								"start": 1032,
								"end": 1050,
								"text": "\n    name():string"
							},
							{
								"name": "description",
								"start": 1050,
								"end": 1075,
								"text": "\n    description():string"
							},
							{
								"name": "toPrompt",
								"start": 1075,
								"end": 1107,
								"text": "\n    toPrompt():ParameterSpec[];"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "UserResponse",
						"methods": [
							{
								"name": "isCancelled",
								"start": 1158,
								"end": 1184,
								"text": "\n    isCancelled():boolean"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "QueryListener",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "EndPoint",
						"methods": [
							{
								"name": "endpointUrl",
								"start": 1266,
								"end": 1291,
								"text": "\n    endpointUrl():string"
							},
							{
								"name": "addListener",
								"start": 1291,
								"end": 1332,
								"text": "\n    addListener(listener:QueryListener);"
							},
							{
								"name": "removeListener",
								"start": 1332,
								"end": 1375,
								"text": "\n    removeListener(listenr:QueryListener);"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "EndPointSpec",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "url",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "needToSendResponse",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecurityEnvironment",
						"methods": [
							{
								"name": "executeHTTPRequest",
								"start": 1482,
								"end": 1636,
								"text": "\n\n    /**\n     * execute authentification step to external service\n     * @param reg\n     */\n    executeHTTPRequest(reg:har.Request):Promise<har.Response>"
							},
							{
								"name": "askForExtraData",
								"start": 1636,
								"end": 1823,
								"text": "\n\n\n    /**\n     * asks for extra parameters( stored in cfg file or asked in dialog)\n     * @param parameterSpec\n     */\n    askForExtraData(parameterSpec:PromptSpec):Promise<UserResponse>"
							},
							{
								"name": "getOrCreateEndPoint",
								"start": 1823,
								"end": 1895,
								"text": "\n\n\n    // create\n    getOrCreateEndPoint(EndPointSpec):Promise<EndPoint>"
							},
							{
								"name": "hasEndpoints",
								"start": 1895,
								"end": 1924,
								"text": "\n\n    hasEndpoints():boolean;"
							},
							{
								"name": "isInteractive",
								"start": 1924,
								"end": 1953,
								"text": "\n    isInteractive():boolean;"
							},
							{
								"name": "isGraphical",
								"start": 1953,
								"end": 1979,
								"text": "\n    isGraphical():boolean"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AuthentificationManager",
						"methods": [
							{
								"name": "supports",
								"start": 2017,
								"end": 2068,
								"text": "\n\n    supports(client:SecurityEnvironment):boolean;"
							},
							{
								"name": "doAuth",
								"start": 2068,
								"end": 2319,
								"text": "\n\n    /**\n     * performs authentification\n     * everything may happen here even sending horse rider to a new city\n     * or flight to moon\n     * @param env\n     */\n    doAuth(env:SecurityEnvironment,authData:AuthData):Promise<AuthentificationState>"
							},
							{
								"name": "doLogout",
								"start": 2319,
								"end": 2541,
								"text": "\n\n    /**\n     * performs log out\n     * if it is needed to blow a nuke to logout it is possible\n     * @param env\n     */\n    doLogout(env:SecurityEnvironment,authData:AuthentificationState):Promise<AuthentificationState>"
							},
							{
								"name": "addAuthDataToRequest",
								"start": 2541,
								"end": 2781,
								"text": "\n\n\n    /**\n     * performs arbitrary request transform (as a sample might change actual url)\n     * or do complex encoding\n     * @param req\n     */\n    addAuthDataToRequest(req:har.Request,state:AuthentificationState):Promise<har.Response>"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SchemeInfo",
						"methods": [
							{
								"name": "name",
								"start": 2839,
								"end": 2857,
								"text": "\n    name():string"
							},
							{
								"name": "description",
								"start": 2857,
								"end": 2882,
								"text": "\n    description():string"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "parameterSpec",
								"type": {
									"base": {
										"typeName": "ParameterSpec",
										"nameSpace": "",
										"basicName": "ParameterSpec",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/auth.ts"
									},
									"typeKind": 1
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecurityScheme",
						"methods": [
							{
								"name": "info",
								"start": 2910,
								"end": 2933,
								"text": "\n\n    info():SchemeInfo"
							},
							{
								"name": "id",
								"start": 2933,
								"end": 2949,
								"text": "\n    id():string"
							},
							{
								"name": "needsEndpoints",
								"start": 2949,
								"end": 2979,
								"text": "\n    needsEndpoints():boolean;"
							},
							{
								"name": "isInteractive",
								"start": 2979,
								"end": 3008,
								"text": "\n    isInteractive():boolean;"
							},
							{
								"name": "isGraphical",
								"start": 3008,
								"end": 3127,
								"text": "\n    /***\n     * means that you potentially need to have graphical display to pass it\n     */\n    isGraphical():boolean"
							},
							{
								"name": "createAuthManager",
								"start": 3127,
								"end": 3177,
								"text": "\n\n    createAuthManager():AuthentificationManager;"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecurityAwareApiClient",
						"methods": [
							{
								"name": "api",
								"start": 3214,
								"end": 3240,
								"text": "\n    api():RamlWrapper.Api"
							},
							{
								"name": "securitySchemes",
								"start": 3240,
								"end": 3280,
								"text": "\n\n    securitySchemes():SecurityScheme[]"
							},
							{
								"name": "getOrCreateAuthManager",
								"start": 3280,
								"end": 3350,
								"text": "\n\n    getOrCreateAuthManager(s:SecurityScheme):AuthentificationManager"
							},
							{
								"name": "doAuth",
								"start": 3350,
								"end": 3416,
								"text": "\n\n    doAuth(scheme:SecurityScheme):Promise<AuthentificationState>"
							},
							{
								"name": "doAuthSync",
								"start": 3416,
								"end": 3476,
								"text": "\n    doAuthSync(scheme:SecurityScheme):AuthentificationState"
							},
							{
								"name": "setCurrentAuthData",
								"start": 3476,
								"end": 3532,
								"text": "\n\n\n\n    setCurrentAuthData(state:AuthentificationState);"
							},
							{
								"name": "getCurrentAuthData",
								"start": 3532,
								"end": 3606,
								"text": "//needed for multiple users\n    getCurrentAuthData():AuthentificationState"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecuritySchemeHook",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [
					{
						"name": "StatusCode",
						"members": [
							"OK",
							"WARNING",
							"ERROR",
							"UNKNOWN",
							"CANCELLED"
						]
					}
				],
				"imports": {
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/systemTypes.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-1.0/auth.ts"
			}
		];

	/***/ },
	/* 87 */
	/***/ function(module, exports) {

		module.exports = [
			{
				"classes": [
					{
						"name": "GlobalSchema",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.Referencable",
								"nameSpace": "Sys",
								"basicName": "Referencable",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "Sys.SchemaString",
										"nameSpace": "Sys",
										"basicName": "SchemaString",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
							}
						],
						"fields": [
							{
								"name": "key",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the global schema, used to refer on schema content"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "value",
								"type": {
									"typeName": "Sys.SchemaString",
									"nameSpace": "Sys",
									"basicName": "SchemaString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Content of the schema"
										]
									},
									{
										"name": "MetaModel.value",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"value"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"Content of the schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLSimpleElement",
								"nameSpace": "Common",
								"basicName": "RAMLSimpleElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
							}
						],
						"moduleName": "RAMLSpec",
						"annotationOverridings": {}
					},
					{
						"name": "Api",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The title property is a short plain text description of the RESTful API. The title property's value SHOULD be suitable for use as a title for the contained user documentation."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "version",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"If the RAML API definition is targeted to a specific API version, the API definition MUST contain a version property. The version property is OPTIONAL and should not be used if:\nThe API itself is not versioned.\nThe API definition does not change between versions. The API architect can decide whether a change to user documentation elements, but no change to the API's resources, constitutes a version change.\nThe API architect MAY use any versioning scheme so long as version numbers retain the same format. For example, \"v3\", \"v3.0\", and \"V3\" are all allowed, but are not considered to be equal."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "baseUri",
								"type": {
									"typeName": "Sys.FullUriTemplateString",
									"nameSpace": "Sys",
									"basicName": "FullUriTemplateString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional during development; Required after implementation) A RESTful API's resources are defined relative to the API's base URI. The use of the baseUri field is OPTIONAL to allow describing APIs that have not yet been implemented. After the API is implemented (even a mock implementation) and can be accessed at a service endpoint, the API definition MUST contain a baseUri property. The baseUri property's value MUST conform to the URI specification [RFC2396] or a Level 1 Template URI as defined in RFC 6570 [RFC6570].\n            The baseUri property SHOULD only be used as a reference value. API client generators MAY make the baseUri configurable by the API client's users.\n            If the baseUri value is a Level 1 Template URI, the following reserved base URI parameters are available for replacement:"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "baseUriParameters",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.BURI"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Base uri parameters are named parameters which described template parameters in the base uri"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uriParameters",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.BURI"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"URI parameters can be further defined by using the uriParameters property. The use of uriParameters is OPTIONAL. The uriParameters property MUST be a map in which each key MUST be the name of the URI parameter as defined in the baseUri property. The uriParameters CANNOT contain a key named version because it is a reserved URI parameter name. The value of the uriParameters property is itself a map that specifies  the property's attributes as named parameters"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "protocols",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"HTTP",
												"HTTPS"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A RESTful API can be reached HTTP, HTTPS, or both. The protocols property MAY be used to specify the protocols that an API supports. If the protocols property is not specified, the protocol specified at the baseUri property is used. The protocols property MUST be an array of strings, of values `HTTP` and/or `HTTPS`."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "mediaType",
								"type": {
									"typeName": "Bodies.MimeType",
									"nameSpace": "Bodies",
									"basicName": "MimeType",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.oftenKeys",
										"arguments": [
											[
												"application/json",
												"application/xml",
												"application/x-www-form-urlencoded",
												"multipart/formdata"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional) The media types returned by API responses, and expected from API requests that accept a body, MAY be defaulted by specifying the mediaType property. This property is specified at the root level of the API definition. The property's value MAY be a single string with a valid media type:\nOne of the following YAML media types:\ntext/yaml\ntext/x-yaml\napplication/yaml\napplication/x-yaml*\nAny type from the list of IANA MIME Media Types, http://www.iana.org/assignments/media-types\nA custom type that conforms to the regular expression, \"application/[A-Za-z.-0-1]*+?(json|xml)\"\nFor any combination of resource and operation in the API, if a media type is specified as a key of the body property for that resource and operation, or if a media type is specified in the mediaType property, the body MUST be in the specified media types. Moreover, if the client specifies an Accepts header containing multiple media types that are allowed by the specification for the requested resource and operation, the server SHOULD return a body using the media type in the Accepts header's mediaType list.\n"
										]
									},
									{
										"name": "MetaModel.inherited",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "schemas",
								"type": {
									"base": {
										"typeName": "GlobalSchema",
										"nameSpace": "",
										"basicName": "GlobalSchema",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"To better achieve consistency and simplicity, the API definition SHOULD include an OPTIONAL schemas property in the root section. The schemas property specifies collections of schemas that could be used anywhere in the API definition. The value of the schemas property is an array of maps; in each map, the keys are the schema name, and the values are schema definitions. The schema definitions MAY be included inline or by using the RAML !include user-defined data type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "traits",
								"type": {
									"base": {
										"typeName": "RM.Trait",
										"nameSpace": "RM",
										"basicName": "Trait",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declarations of traits used in this API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "RM.SecuritySchemeRef",
										"nameSpace": "RM",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A list of the security schemas to apply to all methods, these must be defined in the securitySchemes declaration."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securitySchemes",
								"type": {
									"base": {
										"typeName": "RM.AbstractSecurityScheme",
										"nameSpace": "RM",
										"basicName": "AbstractSecurityScheme",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Security schemas that can be applied with securedBy"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "resourceTypes",
								"type": {
									"base": {
										"typeName": "RM.ResourceType",
										"nameSpace": "RM",
										"basicName": "ResourceType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.embeddedInMaps",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Declaration of resource types used in this API"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "resources",
								"type": {
									"base": {
										"typeName": "RM.Resource",
										"nameSpace": "RM",
										"basicName": "Resource",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Resource"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Resources are identified by their relative URI, which MUST begin with a slash (/).\nA resource defined as a root-level property is called a top-level resource. Its property's key is the resource's URI relative to the baseUri.\nA resource defined as a child property of another resource is called a nested resource, and its property's key is its URI relative to its parent resource's URI.\nEvery property whose key begins with a slash (/), and is either at the root of the API definition or is the child property of a resource property, is a resource property. The key of a resource, i.e. its relative URI, MAY consist of multiple URI path fragments separated by slashes; e.g. \"/bom/items\" may indicate the collection of items in a bill of materials as a single resource. However, if the individual URI path fragments are themselves resources, the API definition SHOULD use nested resources to describe this structure; e.g. if \"/bom\" is itself a resource then \"/items\" should be a nested resource of \"/bom\", while \"/bom/items\" should not be used."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "documentation",
								"type": {
									"base": {
										"typeName": "DocumentationItem",
										"nameSpace": "",
										"basicName": "DocumentationItem",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The API definition can include a variety of documents that serve as a user guides and reference documentation for the API. Such documents can clarify how the API works or provide business context.\n            Documentation-generators MUST include all the sections in an API definition's documentation property in the documentation output, and they MUST preserve the order in which the documentation is declared.\n            To add user documentation to the API, include the documentation property at the root of the API definition. The documentation property MUST be an array of documents. Each document MUST contain title and content attributes, both of which are REQUIRED. If the documentation property is specified, it MUST include at least one document.\n            Documentation-generators MUST process the content field as if it was defined using Markdown [MARKDOWN].\n\n        This example shows an API definition with a single user document."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
							}
						],
						"moduleName": "RAMLSpec",
						"annotationOverridings": {}
					},
					{
						"name": "DocumentationItem",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"title of documentation section"
										]
									},
									{
										"name": "MetaModel.required",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "content",
								"type": {
									"typeName": "Sys.MarkdownString",
									"nameSpace": "Sys",
									"basicName": "MarkdownString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Content of documentation section"
										]
									},
									{
										"name": "MetaModel.required",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLSimpleElement",
								"nameSpace": "Common",
								"basicName": "RAMLSimpleElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
							}
						],
						"moduleName": "RAMLSpec",
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts",
					"RM": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts",
					"Params": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/common.ts",
					"Bodies": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/api.ts"
			},
			{
				"classes": [
					{
						"name": "SpecPartMetaData",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "title",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts"
			},
			{
				"classes": [
					{
						"name": "ValueType",
						"methods": [
							{
								"name": "parse",
								"start": 87,
								"end": 253,
								"text": "\n\n    /**\n     * parses inner structure of value type if value type has invalid value you should throw error\n     * with descriptive message\n     */\n    parse():any{}"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "StringType",
						"methods": [
							{
								"name": "value",
								"start": 339,
								"end": 367,
								"text": " value():string{return null}"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"string"
								]
							}
						],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "NumberType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"number"
								]
							}
						],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BooleanType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.nameAtRuntime",
								"arguments": [
									"boolean"
								]
							}
						],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Referencable",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Reference",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "ValueType",
								"nameSpace": "",
								"basicName": "ValueType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DeclaresDynamicType",
						"methods": [],
						"typeParameters": [
							"T"
						],
						"typeParameterConstraint": [
							null
						],
						"implements": [],
						"fields": [],
						"isInterface": true,
						"annotations": [],
						"extends": [
							{
								"typeName": "Referencable",
								"nameSpace": "",
								"basicName": "Referencable",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "T",
										"nameSpace": "",
										"basicName": "T",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "UriTemplate",
						"methods": [
							{
								"name": "templateArguments",
								"start": 1091,
								"end": 1529,
								"text": "\n\n    templateArguments():string[]{\n        var pos=0;\n        var str=this.value();\n        var result=[];\n        while(true){\n            var start=str.indexOf(\"{\",pos)\n            if (start!=-1){\n                var end=str.indexOf(\"}\",start+1);\n                result.push(str.substring(start+1,end))\n                pos=end;\n            }\n            else{\n                break;\n            }\n        }\n        return result;\n    }"
							},
							{
								"name": "validate",
								"start": 1529,
								"end": 1629,
								"text": "\n\n    validate(){\n        var str=this.value();\n        //write something to validate Url here\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This type currently serves both for absolute and relative urls"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RelativeUriString",
						"methods": [
							{
								"name": "parse",
								"start": 1760,
								"end": 2554,
								"text": "\n    parse():string[]{\n        //FIXME INHERITANCE\n        var value=this.value();\n        var result=[]\n        var temp=\"\";\n        var inPar=false;\n        var count=0;\n        for (var a=0;a<value.length;a++){\n            var c=value[a];\n            if (c=='{'){\n                count++;\n                inPar=true;\n                continue;\n            }\n            if (c=='}'){\n                count--;\n                inPar=false;\n                result.push(temp);\n                temp=\"\";\n                continue;\n            }\n            if (inPar){\n                temp+=c;\n            }\n        }\n        if (count>0){\n            throw new Error(\"Unmatched '{'\")\n        }\n        if (count<0){\n            throw new Error(\"Unmatched '}'\")\n        }\n        return result;\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This  type describes relative uri templates"
								]
							}
						],
						"extends": [
							{
								"typeName": "UriTemplate",
								"nameSpace": "",
								"basicName": "UriTemplate",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "FullUriTemplateString",
						"methods": [
							{
								"name": "parse",
								"start": 2689,
								"end": 3474,
								"text": "\n    parse():string[]{//FIXME INHERITANCE\n        var value=this.value();\n        var result=[]\n        var temp=\"\";\n        var inPar=false;\n        var count=0;\n        for (var a=0;a<value.length;a++){\n            var c=value[a];\n            if (c=='{'){\n                count++;\n                inPar=true;\n                continue;\n            }\n            if (c=='}'){\n                count--;\n                inPar=false;\n                result.push(temp);\n                temp=\"\";\n                continue;\n            }\n            if (inPar){\n                temp+=c;\n            }\n        }\n        if (count>0){\n            throw new Error(\"Unmatched '{'\")\n        }\n        if (count<0){\n            throw new Error(\"Unmatched '}'\")\n        }\n        return result;\n    }"
							},
							{
								"name": "validate",
								"start": 3474,
								"end": 3573,
								"text": "\n    validate(){\n        var str=this.value();\n        //write something to validate Url here\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This  type describes absolute uri templates"
								]
							}
						],
						"extends": [
							{
								"typeName": "UriTemplate",
								"nameSpace": "",
								"basicName": "UriTemplate",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "FixedUri",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This  type describes fixed uris"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "MarkdownString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.innerType",
								"arguments": [
									"markdown"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"Mardown string is a string which can contain markdown as an extension this markdown should support links with RAML Pointers since 1.0"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SchemaString",
						"methods": [
							{
								"name": "validate",
								"start": 4110,
								"end": 4293,
								"text": "\n\n    validate(){\n        var str=this.value();\n        //write something to validate schema here here\n        //in fact it should check that content is valid json or xsd schema\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Schema at this moment only two subtypes are supported (json schema and xsd)"
								]
							}
						],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "JSonSchemaString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"this.mediaType&&this.mediaType.isJSON()"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"JSON schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "SchemaString",
								"nameSpace": "",
								"basicName": "SchemaString",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "XMLSchemaString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.innerType",
								"arguments": [
									"xml"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"XSD schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "SchemaString",
								"nameSpace": "",
								"basicName": "SchemaString",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ExampleString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "StatusCodeString",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "StringType",
								"nameSpace": "",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "JSONExample",
						"methods": [
							{
								"name": "parse",
								"start": 4831,
								"end": 5233,
								"text": "\n\n    parse():any{\n        try {\n            JSON.parse(this.value());\n        } catch (e){\n            var ne=new Error(\"Warning: Can not parse JSON:\"+e.message);\n            throw ne\n        }\n        var a=this.$$.parent().attr('schema');\n        if (a) {\n          var sm=  a.findReferencedValue()\n          if (sm&&sm.validate){\n              sm.validate(this.value());\n          }\n        }\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"this.mediaType.isJSON()"
								]
							}
						],
						"extends": [
							{
								"typeName": "ExampleString",
								"nameSpace": "",
								"basicName": "ExampleString",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "XMLExample",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"this.mediaType.isXML()"
								]
							}
						],
						"extends": [
							{
								"typeName": "ExampleString",
								"nameSpace": "",
								"basicName": "ExampleString",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
			},
			{
				"classes": [
					{
						"name": "ResourceTypeRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "ResourceType",
										"nameSpace": "",
										"basicName": "ResourceType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "TraitRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "Trait",
										"nameSpace": "",
										"basicName": "Trait",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "MethodBase",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "responses",
								"type": {
									"base": {
										"typeName": "Bodies.Response",
										"nameSpace": "Bodies",
										"basicName": "Response",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Response"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Resource methods MAY have one or more responses. Responses MAY be described using the description property, and MAY include example attributes or schema properties.\n"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "body",
								"type": {
									"base": {
										"typeName": "Bodies.BodyLike",
										"nameSpace": "Bodies",
										"basicName": "BodyLike",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Body"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Some method verbs expect the resource to be sent as a request body. For example, to create a resource, the request must include the details of the resource to create.\nResources CAN have alternate representations. For example, an API might support both JSON and XML representations.\nA method's body is defined in the body property as a hashmap, in which the key MUST be a valid media type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "is",
								"type": {
									"base": {
										"typeName": "TraitRef",
										"nameSpace": "",
										"basicName": "TraitRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instantiation of applyed traits"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "SecuritySchemeRef",
										"nameSpace": "",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A list of the security schemas to apply, these must be defined in the securitySchemes declaration.\nTo indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme.\nSecurity schemas may also be applied to a resource with securedBy, which is equivalent to applying the security schemas to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Params.HasNormalParameters",
								"nameSpace": "Params",
								"basicName": "HasNormalParameters",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Trait",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.DeclaresDynamicType",
								"nameSpace": "Sys",
								"basicName": "DeclaresDynamicType",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "Trait",
										"nameSpace": "",
										"basicName": "Trait",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the trait"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.inlinedTemplates",
								"arguments": []
							},
							{
								"name": "MetaModel.allowQuestion",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "MethodBase",
								"nameSpace": "",
								"basicName": "MethodBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "ResourceType",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.DeclaresDynamicType",
								"nameSpace": "Sys",
								"basicName": "DeclaresDynamicType",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "ResourceType",
										"nameSpace": "",
										"basicName": "ResourceType",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Name of the resource type"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "usage",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "methods",
								"type": {
									"base": {
										"typeName": "Method",
										"nameSpace": "",
										"basicName": "Method",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Methods that are part of this resource type definition"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "is",
								"type": {
									"base": {
										"typeName": "TraitRef",
										"nameSpace": "",
										"basicName": "TraitRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instantiation of applyed traits"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "ResourceTypeRef",
									"nameSpace": "",
									"basicName": "ResourceTypeRef",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instantiation of applyed resource type"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "SecuritySchemeRef",
										"nameSpace": "",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											" securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.\nTo indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uriParameters",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.URI"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Uri parameters of this resource"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "displayName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.inlinedTemplates",
								"arguments": []
							},
							{
								"name": "MetaModel.allowQuestion",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Method",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "method",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"methods"
										]
									},
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"get",
												"put",
												"post",
												"delete",
												"patch",
												"options",
												"head",
												"trace",
												"connect"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Method that can be called"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "protocols",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"HTTP",
												"HTTPS"
											]
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A method can override an API's protocols value for that single method by setting a different value for the fields."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "SecuritySchemeRef",
										"nameSpace": "",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											" securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.\nTo indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Method object allows description of http methods"
								]
							}
						],
						"extends": [
							{
								"typeName": "MethodBase",
								"nameSpace": "",
								"basicName": "MethodBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Resource",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "relativeUri",
								"type": {
									"typeName": "Sys.RelativeUriString",
									"nameSpace": "Sys",
									"basicName": "RelativeUriString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.startFrom",
										"arguments": [
											"/"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Relative URL of this resource from the parent resource"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "ResourceTypeRef",
									"nameSpace": "",
									"basicName": "ResourceTypeRef",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instantiation of applyed resource type"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "is",
								"type": {
									"base": {
										"typeName": "TraitRef",
										"nameSpace": "",
										"basicName": "TraitRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Instantiation of applyed traits"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "securedBy",
								"type": {
									"base": {
										"typeName": "SecuritySchemeRef",
										"nameSpace": "",
										"basicName": "SecuritySchemeRef",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.allowNull",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											" securityScheme may also be applied to a resource by using the securedBy key, which is equivalent to applying the securityScheme to all methods that may be declared, explicitly or implicitly, by defining the resourceTypes or traits property for that resource.\nTo indicate that the method may be called without applying any securityScheme, the method may be annotated with the null securityScheme."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "uriParameters",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.URI"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Uri parameters of this resource"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "methods",
								"type": {
									"base": {
										"typeName": "Method",
										"nameSpace": "",
										"basicName": "Method",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Method"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Methods that can be called on this resource"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "resources",
								"type": {
									"base": {
										"typeName": "Resource",
										"nameSpace": "",
										"basicName": "Resource",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Resource"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Children resources"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "displayName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "baseUriParameters",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"fieldOrParam",
											true
										]
									},
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.BURI"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"A resource or a method can override a base URI template's values. This is useful to restrict or change the default or parameter selection in the base URI. The baseUriParameters property MAY be used to override any or all parameters defined at the root level baseUriParameters property, as well as base URI parameters not specified at the root level."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecuritySchemePart",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "MethodBase",
								"nameSpace": "",
								"basicName": "MethodBase",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"headers": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Optional array of headers, documenting the possible headers that could be accepted."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose property names are the request header names and whose values describe the values."
									]
								}
							],
							"queryParameters": [
								{
									"name": "MetaModel.markdownDescription",
									"arguments": [
										"Query parameters, used by the schema in order to authorize the request. Mutually exclusive with queryString."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Object whose property names are the query parameter names and whose values describe the values."
									]
								}
							],
							"queryString": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Specifies the query string, used by the schema in order to authorize the request. Mutually exclusive with queryParameters."
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Type name or type declaration"
									]
								}
							],
							"responses": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Optional array of responses, describing the possible responses that could be sent."
									]
								}
							],
							"is": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							],
							"securedBy": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							],
							"displayName": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"An alternate, human-friendly name for the security scheme part"
									]
								}
							],
							"description": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"A longer, human-friendly description of the security scheme part"
									]
								},
								{
									"name": "MetaModel.valueDescription",
									"arguments": [
										"Markdown string"
									]
								}
							],
							"annotations": [
								{
									"name": "MetaModel.description",
									"arguments": [
										"Annotations to be applied to this security scheme part. Annotations are any property whose key begins with \"(\" and ends with \")\" and whose name (the part between the beginning and ending parentheses) is a declared annotation name. See [[raml-10-spec-annotations|the section on annotations]]."
									]
								}
							]
						}
					},
					{
						"name": "SecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							}
						],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "AbstractSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [
							{
								"typeName": "Sys.Referencable",
								"nameSpace": "Sys",
								"basicName": "Referencable",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "AbstractSecurityScheme",
										"nameSpace": "",
										"basicName": "AbstractSecurityScheme",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.startFrom",
										"arguments": [
											""
										]
									},
									{
										"name": "MetaModel.hide",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.oneOf",
										"arguments": [
											[
												"OAuth 1.0",
												"OAuth 2.0",
												"Basic Authentication",
												"DigestSecurityScheme Authentication",
												"x-{other}"
											]
										]
									},
									{
										"name": "MetaModel.descriminatingProperty",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The securitySchemes property MUST be used to specify an API's security mechanisms, including the required settings and the authentication methods that the API supports. one authentication method is allowed if the API supports them."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"string<br><br>The value MUST be one of<br>* OAuth 1.0,<br>* OAuth 2.0,<br>* BasicSecurityScheme Authentication<br>* DigestSecurityScheme Authentication<br>* x-&lt;other&gt;"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "description",
								"type": {
									"typeName": "Sys.MarkdownString",
									"nameSpace": "Sys",
									"basicName": "MarkdownString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The description attribute MAY be used to describe a security schemes property."
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The description MAY be used to describe a securityScheme."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "describedBy",
								"type": {
									"typeName": "SecuritySchemePart",
									"nameSpace": "",
									"basicName": "SecuritySchemePart",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A description of the request components related to Security that are determined by the scheme: the headers, query parameters or responses. As a best practice, even for standard security schemes, API designers SHOULD describe these properties of security schemes.\nIncluding the security scheme description completes an API documentation."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "SecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "SecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The settings attribute MAY be used to provide security scheme-specific information. The required attributes vary depending on the type of security scheme is being declared.\nIt describes the minimum set of properties which any processing application MUST provide and validate if it chooses to implement the security scheme. Processing applications MAY choose to recognize other properties for things such as token lifetime, preferred cryptographic algorithms, and more."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security schema definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "SecuritySchemeRef",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "Sys.Reference",
								"nameSpace": "Sys",
								"basicName": "Reference",
								"typeKind": 0,
								"typeArguments": [
									{
										"typeName": "AbstractSecurityScheme",
										"nameSpace": "",
										"basicName": "AbstractSecurityScheme",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
									}
								],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "OAuth1SecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "requestTokenUri",
								"type": {
									"typeName": "Sys.FixedUri",
									"nameSpace": "Sys",
									"basicName": "FixedUri",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Temporary Credential Request endpoint as defined in RFC5849 Section 2.1"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "authorizationUri",
								"type": {
									"typeName": "Sys.FixedUri",
									"nameSpace": "Sys",
									"basicName": "FixedUri",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Resource Owner Authorization endpoint as defined in RFC5849 Section 2.2"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "tokenCredentialsUri",
								"type": {
									"typeName": "Sys.FixedUri",
									"nameSpace": "Sys",
									"basicName": "FixedUri",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Token Request endpoint as defined in RFC5849 Section 2.3"
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							},
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"$parent.type=='OAuth 1.0'"
								]
							}
						],
						"extends": [
							{
								"typeName": "SecuritySchemeSettings",
								"nameSpace": "",
								"basicName": "SecuritySchemeSettings",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"annotations": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							]
						}
					},
					{
						"name": "OAuth2SecuritySchemeSettings",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "accessTokenUri",
								"type": {
									"typeName": "Sys.FixedUri",
									"nameSpace": "Sys",
									"basicName": "FixedUri",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Token Endpoint as defined in RFC6749 [RFC6748] Section 3.2. Not required forby implicit grant type."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "authorizationUri",
								"type": {
									"typeName": "Sys.FixedUri",
									"nameSpace": "Sys",
									"basicName": "FixedUri",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The URI of the Authorization Endpoint as defined in RFC6749 [RFC6748] Section 3.1. Required forby authorization_code and implicit grant types."
										]
									},
									{
										"name": "MetaModel.valueDescription",
										"arguments": [
											"FixedUriString"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "authorizationGrants",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.required",
										"arguments": []
									},
									{
										"name": "MetaModel.markdownDescription",
										"arguments": [
											"A list of the Authorization grants supported by the API as defined in RFC6749 [RFC6749] Sections 4.1, 4.2, 4.3 and 4.4, can be any of:<br>* authorization_code<br>* password<br>* client_credentials<br>* implicit<br>* refresh_token."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "scopes",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"A list of scopes supported by the security scheme as defined in RFC6749 [RFC6749] Section 3.3"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.allowAny",
								"arguments": []
							}
						],
						"extends": [
							{
								"typeName": "SecuritySchemeSettings",
								"nameSpace": "",
								"basicName": "SecuritySchemeSettings",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {
							"annotations": [
								{
									"name": "MetaModel.hide",
									"arguments": []
								}
							]
						}
					},
					{
						"name": "OAuth2SecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "OAuth 2.0"
								},
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "OAuth2SecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "OAuth2SecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security schema definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "OAuth1SecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "OAuth 1.0"
								},
								"optional": false
							},
							{
								"name": "settings",
								"type": {
									"typeName": "OAuth1SecuritySchemeSettings",
									"nameSpace": "",
									"basicName": "OAuth1SecuritySchemeSettings",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security schema definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BasicSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "Basic Authentication"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security schema definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DigestSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "DigestSecurityScheme Authentication"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security schema definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "CustomSecurityScheme",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "x-{other}"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Declares globally referable security schema definition"
								]
							},
							{
								"name": "MetaModel.actuallyExports",
								"arguments": [
									"$self"
								]
							},
							{
								"name": "MetaModel.referenceIs",
								"arguments": [
									"settings"
								]
							}
						],
						"extends": [
							{
								"typeName": "AbstractSecurityScheme",
								"nameSpace": "",
								"basicName": "AbstractSecurityScheme",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts",
					"Params": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts",
					"Bodies": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/common.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/methodsAndResources.ts"
			},
			{
				"classes": [
					{
						"name": "Parameter",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"name of the parameter"
										]
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"headers"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "displayName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.defaultValue",
										"arguments": [
											"string"
										]
									},
									{
										"name": "MetaModel.descriminatingProperty",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"The type attribute specifies the primitive type of the parameter's resolved value. API clients MUST return/throw an error if the parameter's resolved value does not match the specified type. If type is not specified, it defaults to string."
										]
									},
									{
										"name": "MetaModel.canBeDuplicator",
										"arguments": []
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "location",
								"type": {
									"typeName": "ParameterLocation",
									"nameSpace": "",
									"basicName": "ParameterLocation",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.system",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Location of the parameter (can not be edited by user)"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "required",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Set to true if parameter is required"
										]
									},
									{
										"name": "MetaModel.defaultBooleanValue",
										"arguments": [
											true
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "default",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The default attribute specifies the default value to use for the property if the property is omitted or its value is not specified. This SHOULD NOT be interpreted as a requirement for the client to send the default attribute's value if there is no other value to send. Instead, the default attribute's value is the value the server uses if the client does not send a value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "example",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional) The example attribute shows an example value for the property. This can be used, e.g., by documentation generators to generate sample values for the property."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "repeat",
								"type": {
									"typeName": "boolean",
									"nameSpace": "",
									"basicName": "boolean",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The repeat attribute specifies that the parameter can be repeated. If the parameter can be used multiple times, the repeat parameter value MUST be set to 'true'. Otherwise, the default value is 'false' and the parameter may not be repeated."
										]
									},
									{
										"name": "MetaModel.defaultBooleanValue",
										"arguments": [
											false
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "StringTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "pattern",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type string) The pattern attribute is a regular expression that a parameter of type string MUST match. Regular expressions MUST follow the regular expression specification from ECMA 262/Perl 5. The pattern MAY be enclosed in double quotes for readability and clarity."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "enum",
								"type": {
									"base": {
										"typeName": "string",
										"nameSpace": "",
										"basicName": "string",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": null
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type string) The enum attribute provides an enumeration of the parameter's valid values. This MUST be an array. If the enum attribute is defined, API clients and servers MUST verify that a parameter's value matches a value in the enum array. If there is no matching value, the clients and servers MUST treat this as an error."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "minLength",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type string) The minLength attribute specifies the parameter value's minimum number of characters."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maxLength",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type string) The maxLength attribute specifies the parameter value's maximum number of characters."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "string"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value must be a string"
								]
							}
						],
						"extends": [
							{
								"typeName": "Parameter",
								"nameSpace": "",
								"basicName": "Parameter",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BooleanTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "boolean"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value must be a boolean"
								]
							}
						],
						"extends": [
							{
								"typeName": "Parameter",
								"nameSpace": "",
								"basicName": "Parameter",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "NumberTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "number"
								},
								"optional": false
							},
							{
								"name": "minimum",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type number or integer) The minimum attribute specifies the parameter's minimum value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "maximum",
								"type": {
									"typeName": "number",
									"nameSpace": "",
									"basicName": "number",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"(Optional, applicable only for parameters of type number or integer) The maximum attribute specifies the parameter's maximum value."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value MUST be a number. Indicate floating point numbers as defined by YAML."
								]
							}
						],
						"extends": [
							{
								"typeName": "Parameter",
								"nameSpace": "",
								"basicName": "Parameter",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "IntegerTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "integer"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value MUST be a integer."
								]
							}
						],
						"extends": [
							{
								"typeName": "NumberTypeDeclaration",
								"nameSpace": "",
								"basicName": "NumberTypeDeclaration",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "DateTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "date"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"Value MUST be a string representation of a date as defined in RFC2616 Section 3.3 [RFC2616]. "
								]
							}
						],
						"extends": [
							{
								"typeName": "Parameter",
								"nameSpace": "",
								"basicName": "Parameter",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "FileTypeDeclaration",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": null,
								"annotations": [],
								"valueConstraint": {
									"isCallConstraint": false,
									"value": "file"
								},
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.requireValue",
								"arguments": [
									"location",
									"ParameterLocation.FORM"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"(Applicable only to Form properties) Value is a file. Client generators SHOULD use this type to handle file uploads correctly."
								]
							}
						],
						"extends": [
							{
								"typeName": "Parameter",
								"nameSpace": "",
								"basicName": "Parameter",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "HasNormalParameters",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "queryParameters",
								"type": {
									"base": {
										"typeName": "Parameter",
										"nameSpace": "",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"ParameterLocation.QUERY"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New query parameter"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"An APIs resources MAY be filtered (to return a subset of results) or altered (such as transforming a response body from JSON to XML format) by the use of query strings. If the resource or its method supports a query string, the query string MUST be defined by the queryParameters property"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "displayName",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "headers",
								"type": {
									"base": {
										"typeName": "Parameter",
										"nameSpace": "",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"ParameterLocation.HEADERS"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Headers that allowed at this position"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Header"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [
					{
						"name": "ParameterLocation",
						"members": [
							"QUERY",
							"HEADERS",
							"URI",
							"FORM",
							"BURI"
						]
					}
				],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/common.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts"
			},
			{
				"classes": [
					{
						"name": "RAMLLanguageElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "description",
								"type": {
									"typeName": "Sys.MarkdownString",
									"nameSpace": "Sys",
									"basicName": "MarkdownString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/common.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"The description attribute describes the intended use or meaning of the $self. This value MAY be formatted using Markdown [MARKDOWN]"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "RAMLSimpleElement",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/common.ts"
			},
			{
				"classes": [
					{
						"name": "MimeTypeModel",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "type",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "tree",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": true
							},
							{
								"name": "subtype",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "suffix",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": true
							},
							{
								"name": "parameters",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [],
								"valueConstraint": null,
								"optional": true
							}
						],
						"isInterface": true,
						"annotations": [],
						"extends": [],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "MimeType",
						"methods": [
							{
								"name": "isForm",
								"start": 449,
								"end": 650,
								"text": "\n    isForm(){\n        if (this.value()==\"application/x-www-form-urlencoded\"||this.value()=='multipart/form-data'){\n            return true;\n        }\n\n        return false;//more smart code here\n    }"
							},
							{
								"name": "isXML",
								"start": 650,
								"end": 795,
								"text": "\n\n    isXML(){\n        if (this.value()==\"application/xml\"){\n            return true;\n        }\n        return false;//more smart code here\n    }"
							},
							{
								"name": "isJSON",
								"start": 795,
								"end": 942,
								"text": "\n\n    isJSON(){\n        if (this.value()==\"application/json\"){\n            return true;\n        }\n        return false;//more smart code here\n    }"
							},
							{
								"name": "parse",
								"start": 1025,
								"end": 1567,
								"text": "\n    parse(){\n        /**\n         * top-level type name / subtype name [ ; parameters ]\n         *\n         * top-level type name / [ tree. ] subtype name [ +suffix ] [ ; parameters ]\n         */\n        var v=this.value();\n        if (v==\"*/*\"){\n            return\n        }\n        var res= mediaTypeParser.parse(v);\n        var types={application:1, audio:1, example:1, image:1, message:1, model:1, multipart:1, text:1, video:1}\n        if (!types[res.type]){\n            throw new Error(\"Unknown media type 'type' value\")\n        }\n    }"
							}
						],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.description",
								"arguments": [
									"This sub type of the string represents mime types"
								]
							}
						],
						"extends": [
							{
								"typeName": "Sys.StringType",
								"nameSpace": "Sys",
								"basicName": "StringType",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "BodyLike",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "name",
								"type": {
									"typeName": "string",
									"nameSpace": "",
									"basicName": "string",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": null
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Mime type of the request or response body"
										]
									},
									{
										"name": "MetaModel.canInherit",
										"arguments": [
											"mediaType"
										]
									},
									{
										"name": "MetaModel.oftenKeys",
										"arguments": [
											[
												"application/json",
												"application/xml",
												"application/x-www-form-urlencoded",
												"multipart/form-data"
											]
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "schema",
								"type": {
									"typeName": "Sys.SchemaString",
									"nameSpace": "Sys",
									"basicName": "SchemaString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.requireValue",
										"arguments": [
											"this.name.isForm()",
											"false"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"\n    The structure of a request or response body MAY be further specified by the schema property under the appropriate media type.\n\nThe schema key CANNOT be specified if a body's media type is application/x-www-form-urlencoded or multipart/form-data.\n\nAll parsers of RAML MUST be able to interpret JSON Schema [JSON_SCHEMA] and XML Schema [XML_SCHEMA].\n\nSchema MAY be declared inline or in an external file. However, if the schema is sufficiently large so as to make it difficult for a person to read the API definition, or the schema is reused across multiple APIs or across multiple miles in the same API, the !include user-defined data type SHOULD be used instead of including the content inline.\nAlternatively, the value of the schema field MAY be the name of a schema specified in the root-level schemas property (see Named Parameters, or it MAY be declared in an external file and included by using the by using the RAML !include user-defined data type."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "example",
								"type": {
									"typeName": "Sys.ExampleString",
									"nameSpace": "Sys",
									"basicName": "ExampleString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"Documentation generators MUST use body properties' example attributes to generate example invocations.\nThis example shows example attributes for two body property media types."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "formParameters",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.FORM"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Web forms REQUIRE special encoding and custom declaration.\nIf the API's media type is either application/x-www-form-urlencoded or multipart/form-data, the formParameters property MUST specify the name-value pairs that the API is expecting.\nThe formParameters property is a map in which the key is the name of the web form parameter, and the value is itself a map the specifies the web form parameter's attributes"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.canInherit",
								"arguments": [
									"mediaType"
								]
							}
						],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "XMLBody",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "schema",
								"type": {
									"typeName": "Sys.XMLSchemaString",
									"nameSpace": "Sys",
									"basicName": "XMLSchemaString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"XSD Schema"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"this.mime.isXML()"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"Needed to set connection between xml related mime types and xsd schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "BodyLike",
								"nameSpace": "",
								"basicName": "BodyLike",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "JSONBody",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "schema",
								"type": {
									"typeName": "Sys.JSonSchemaString",
									"nameSpace": "Sys",
									"basicName": "JSonSchemaString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.description",
										"arguments": [
											"JSON Schema"
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [
							{
								"name": "MetaModel.functionalDescriminator",
								"arguments": [
									"this.mime.isJSON()"
								]
							},
							{
								"name": "MetaModel.description",
								"arguments": [
									"Needed to set connection between json related mime types and json schema"
								]
							}
						],
						"extends": [
							{
								"typeName": "BodyLike",
								"nameSpace": "",
								"basicName": "BodyLike",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					},
					{
						"name": "Response",
						"methods": [],
						"typeParameters": [],
						"typeParameterConstraint": [],
						"implements": [],
						"fields": [
							{
								"name": "code",
								"type": {
									"typeName": "Sys.StatusCodeString",
									"nameSpace": "Sys",
									"basicName": "StatusCodeString",
									"typeKind": 0,
									"typeArguments": [],
									"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
								},
								"annotations": [
									{
										"name": "MetaModel.key",
										"arguments": []
									},
									{
										"name": "MetaModel.extraMetaKey",
										"arguments": [
											"statusCodes"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Responses MUST be a map of one or more HTTP status codes, where each status code itself is a map that describes that status code."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "headers",
								"type": {
									"base": {
										"typeName": "Params.Parameter",
										"nameSpace": "Params",
										"basicName": "Parameter",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.setsContextValue",
										"arguments": [
											"location",
											"Params.ParameterLocation.HEADERS"
										]
									},
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Header"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"An API's methods may support custom header values in responses. The custom, non-standard HTTP headers MUST be specified by the headers property.\n        API's may include the the placeholder token {?} in a header name to indicate that any number of headers that conform to the specified format can be sent in responses. This is particularly useful for APIs that allow HTTP headers that conform to some naming convention to send arbitrary, custom data.\n\nIn the following example, the header x-metadata-{?} is used to send metadata that has been saved with the media."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							},
							{
								"name": "body",
								"type": {
									"base": {
										"typeName": "BodyLike",
										"nameSpace": "",
										"basicName": "BodyLike",
										"typeKind": 0,
										"typeArguments": [],
										"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
									},
									"typeKind": 1
								},
								"annotations": [
									{
										"name": "MetaModel.newInstanceName",
										"arguments": [
											"New Body"
										]
									},
									{
										"name": "MetaModel.description",
										"arguments": [
											"Each response MAY contain a body property, which conforms to the same structure as request body properties (see Body). Responses that can return more than one response code MAY therefore have multiple bodies defined.\nFor APIs without a priori knowledge of the response types for their responses, \"*/*\" MAY be used to indicate that responses that do not matching other defined data types MUST be accepted. Processing applications MUST match the most descriptive media type first if \"*/*\" is used."
										]
									}
								],
								"valueConstraint": null,
								"optional": false
							}
						],
						"isInterface": false,
						"annotations": [],
						"extends": [
							{
								"typeName": "Common.RAMLLanguageElement",
								"nameSpace": "Common",
								"basicName": "RAMLLanguageElement",
								"typeKind": 0,
								"typeArguments": [],
								"modulePath": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
							}
						],
						"moduleName": null,
						"annotationOverridings": {}
					}
				],
				"aliases": [],
				"enumDeclarations": [],
				"imports": {
					"MetaModel": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/definition-system/metamodel.ts",
					"Sys": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/systemTypes.ts",
					"Params": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/parameters.ts",
					"Common": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/common.ts"
				},
				"name": "/Users/munch/work/apiworkbench/api-workbench/src/raml1/spec-0.8/bodies.ts"
			}
		];

	/***/ },
	/* 88 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(37);

	/***/ },
	/* 89 */
	/***/ function(module, exports, __webpack_require__) {

		var RamlWrapper = __webpack_require__(74);
		var hl = __webpack_require__(2);
		var hlimpl = __webpack_require__(5);
		var universes = __webpack_require__(54);
		var expander = __webpack_require__(73);
		var lowLevelProxy = __webpack_require__(6);
		var util = __webpack_require__(11);
		var search = __webpack_require__(53);
		var ramlservices = __webpack_require__(49);
		var ll = __webpack_require__(15);
		var path = __webpack_require__(16);
		//export function resolveType(p:RamlWrapper.TypeDeclaration):hl.ITypeDefinition{
		//    var tpe=typeexpression.typeFromNode(p.highLevel());
		//    return tpe.toRuntime();
		//}
		function load(pth) {
		    var m = new ll.Project(path.dirname(pth));
		    var unit = m.unit(path.basename(pth));
		    if (unit) {
		        if (unit.isRAMLUnit()) {
		            return hl.fromUnit(unit).wrapperNode();
		        }
		    }
		    return null;
		}
		exports.load = load;
		//__$helperMethod__ Equivalent API with traits and resource types expanded __$meta__={"name":"expand"}
		function expandTraitsAndResourceTypes(api) {
		    var lowLevelNode = api.highLevel().lowLevel();
		    if (lowLevelNode instanceof lowLevelProxy.LowLevelProxyNode) {
		        return api;
		    }
		    return expander.expandTraitsAndResourceTypes(api);
		}
		exports.expandTraitsAndResourceTypes = expandTraitsAndResourceTypes;
		//__$helperMethod__ Path relative to API root
		function completeRelativeUri(res) {
		    var uri = '';
		    var parent = res;
		    do {
		        res = parent; //(parent instanceof RamlWrapper.ResourceImpl) ? <RamlWrapper.Resource>parent : null;
		        uri = res.relativeUri().value() + uri;
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe08.Resource.name);
		    return uri;
		}
		exports.completeRelativeUri = completeRelativeUri;
		//__$helperMethod__ baseUri of owning Api concatenated with completeRelativeUri
		function absoluteUri(res) {
		    var uri = '';
		    var parent = res;
		    do {
		        res = parent; //(parent instanceof RamlWrapper.ResourceImpl) ? <RamlWrapper.Resource>parent : null;
		        uri = res.relativeUri().value() + uri;
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe08.Resource.name);
		    uri = uri.replace(/\/\//g, '/');
		    var buri = parent.baseUri();
		    var base = buri ? buri.value() : "";
		    base = base ? base : '';
		    if (util.stringEndsWith(base, '/')) {
		        uri = uri.substring(1);
		    }
		    uri = base + uri;
		    return uri;
		}
		exports.absoluteUri = absoluteUri;
		function qName(c) {
		    return hlimpl.qName(c.highLevel(), c.highLevel().root());
		}
		exports.qName = qName;
		//__$helperMethod__ Retrieve all traits including those defined in libraries
		function allTraits(a) {
		    return search.globalDeclarations(a.highLevel()).filter(function (x) { return x.definition().key().name == "Trait"; }).map(function (x) { return x.wrapperNode(); });
		}
		exports.allTraits = allTraits;
		//__$helperMethod__ Retrieve all resource types including those defined in libraries
		function allResourceTypes(a) {
		    return search.globalDeclarations(a.highLevel()).filter(function (x) { return x.definition().key().name == "ResourceType"; }).map(function (x) { return x.wrapperNode(); });
		}
		exports.allResourceTypes = allResourceTypes;
		function relativeUriSegments(res) {
		    var result = [];
		    var parent = res;
		    do {
		        res = parent; //(parent instanceof RamlWrapper.ResourceImpl) ? <RamlWrapper.Resource>parent : null;
		        result.push(res.relativeUri().value());
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe08.Resource.name);
		    return result.reverse();
		}
		exports.relativeUriSegments = relativeUriSegments;
		//__$helperMethod__ For methods of Resources returns parent resource. For methods of ResourceTypes returns null.
		function parentResource(method) {
		    if (method.parent() instanceof RamlWrapper.ResourceImpl) {
		        return method.parent();
		    }
		    return null;
		}
		exports.parentResource = parentResource;
		//__$helperMethod__ Parent resource for non top level resources __$meta__={"name":"parentResource"}
		function parent(resource) {
		    var parent = resource.parent();
		    if (parent.definition().key().name == universes.Universe08.Resource.name) {
		        parent;
		    }
		    return null;
		}
		exports.parent = parent;
		//__$helperMethod__ Get child resource by its relative path
		function childResource(container, relPath) {
		    if (container == null) {
		        return null;
		    }
		    var resources = container.resources();
		    if (!resources) {
		        return null;
		    }
		    resources = resources.filter(function (x) { return x.relativeUri().value() == relPath; });
		    if (resources.length == 0) {
		        return null;
		    }
		    return resources[0];
		}
		exports.childResource = childResource;
		function getResource(container, path) {
		    if (!container) {
		        return null;
		    }
		    var res = null;
		    for (var i = 0; i < path.length; i++) {
		        res = childResource(container, path[i]);
		        if (!res) {
		            return null;
		        }
		        container = res;
		    }
		    return res;
		}
		exports.getResource = getResource;
		//__$helperMethod__ Get child method by its name
		function childMethod(resource, method) {
		    if (!resource) {
		        return null;
		    }
		    return resource.methods().filter(function (x) { return x.method() == method; });
		}
		exports.childMethod = childMethod;
		function getMethod(container, path, method) {
		    var resource = getResource(container, path);
		    if (resource == null) {
		        return null;
		    }
		    return childMethod(resource, method);
		}
		exports.getMethod = getMethod;
		function isApi(obj) {
		    return (obj.definition().key().name == universes.Universe08.Api.name);
		}
		;
		//__$helperMethod__ Api owning the resource as a sibling
		function ownerApi(method) {
		    var obj = method;
		    while (!isApi(obj)) {
		        obj = obj.parent();
		    }
		    return obj;
		}
		exports.ownerApi = ownerApi;
		//__$helperMethod__
		// For methods of Resources: `{parent Resource relative path} {methodName}`.
		// For methods of ResourceTypes: `{parent ResourceType name} {methodName}`.
		// For other methods throws Exception.
		function methodId(method) {
		    var parent = method.parent();
		    if (parent instanceof RamlWrapper.ResourceImpl) {
		        return completeRelativeUri(parent) + ' ' + method.method().toLowerCase();
		    }
		    else if (parent instanceof RamlWrapper.ResourceTypeImpl) {
		        return parent.name() + ' ' + method.method().toLowerCase();
		    }
		    throw new Error("Method is supposed to be owned by Resource or ResourceType.\nHere the method is owned by " + method.definition().key().name);
		}
		exports.methodId = methodId;
		//__$helperMethod__ true for codes < 400 and false otherwise
		function isOkRange(response) {
		    var str = response.code().value();
		    var err = ramlservices.validateResponseString(str);
		    if (err != null) {
		        return false;
		    }
		    try {
		        if (parseInt(str.charAt(0)) < 4) {
		            return true;
		        }
		    }
		    catch (e) {
		    }
		    return false;
		}
		exports.isOkRange = isOkRange;
		//__$helperMethod__  Retrieve all resources of the Api
		function allResources(api) {
		    var resources = [];
		    var visitor = function (res) {
		        resources.push(res);
		        res.resources().forEach(function (x) { return visitor(x); });
		    };
		    api.resources().forEach(function (x) { return visitor(x); });
		    return resources;
		}
		exports.allResources = allResources;
		//export function matchUri(apiRootRelativeUri:string, resource:RamlWrapper.Resource):Opt<ParamValue[]>{
		//
		//    var allParameters:Raml08Parser.NamedParameterMap = {}
		//    var opt:Opt<RamlWrapper.Resource> = new Opt<RamlWrapper.Resource>(resource);
		//    while(opt.isDefined()){
		//        var res:RamlWrapper.Resource = opt.getOrThrow();
		//        uriParameters(res).forEach(x=>allParameters[x.name()]=new ParamWrapper(x));
		//        opt = parent(res);
		//    }
		//    var result = ramlPathMatch(completeRelativeUri(resource), allParameters, {})(apiRootRelativeUri);
		//    if (result) {
		//        return new Opt<ParamValue[]>(Object.keys((<any>result).params)
		//            .map(x=>new ParamValue(x, result['params'][x])));
		//    }
		//    return Opt.empty<ParamValue[]>();
		//}
		var schemaContentChars = ['{', '<'];
		//export function schema(body:RamlWrapper.TypeDeclaration, api:RamlWrapper.Api):Opt<SchemaDef>{
		//
		//    var schemaNode = body.schema();
		//    if(!schemaNode){
		//        return Opt.empty<SchemaDef>();
		//    }
		//    var schemaString = schemaNode;
		//    var isContent:boolean = false;
		//    schemaContentChars.forEach(x=>{try{ isContent = isContent||schemaString.indexOf(x)>=0}catch(e){}});
		//    var schDef:SchemaDef;
		//    if(isContent) {
		//        schDef = new SchemaDef(schemaString);
		//    }
		//    else{
		//        var globalSchemes = api.schemas().filter(x=>x.key()==schemaString);
		//        if(globalSchemes.length>0){
		//            schDef = new SchemaDef(globalSchemes[0].value().value(),globalSchemes[0].key());
		//        }
		//        else{
		//            return Opt.empty<SchemaDef>();
		//        }
		//    }
		//    return new Opt<SchemaDef>(schDef);
		//}
		/**
		 * __$helperMethod__ Retrieve an ordered list of all uri parameters including those which are not described in the `uriParameters` node.
		 * Consider a fragment of RAML specification:
		 * ```yaml
		 * /resource/{objectId}/{propertyId}:
		 *   uriParameters:
		 *     objectId:
		 * ```
		 * Here `propertyId` uri parameter is not described in the `uriParameters` node.
		 * Thus, it is not among Resource.uriParameters(), but it is among Resource.allUriParameters().
		 * __$meta__={"name":"allUriParameters"}
		 **/
		function uriParameters(resource) {
		    var uri = resource.relativeUri().value();
		    var params = resource.uriParameters();
		    var propName = universes.Universe08.Resource.properties.uriParameters.name;
		    return extractParams(params, uri, resource, propName);
		}
		exports.uriParameters = uriParameters;
		/**__$helperMethod__
		 * Retrieve an ordered list of all base uri parameters regardless of whether they are described in `baseUriParameters` or not
		 * Consider a fragment of RAML specification:
		 * ```yaml
		 * version: v1
		 * baseUri: https://{organization}.example.com/{version}/{service}
		 * baseUriParameters:
		 *   service:
		 * ```
		 * Here `version` and `organization` are base uri parameters which are not described in the `baseUriParameters` node.
		 * Thus, they are not among `Api.baseUriParameters()`, but they are among `Api.allBaseUriParameters()`.
		 * __$meta__={"name":"allBaseUriParameters"}
		 **/
		function baseUriParameters(api) {
		    var uri = api.baseUri() ? api.baseUri().value() : '';
		    var params = api.baseUriParameters();
		    var propName = universes.Universe08.Api.properties.baseUriParameters.name;
		    return extractParams(params, uri, api, propName);
		}
		exports.baseUriParameters = baseUriParameters;
		/**__$helperMethod__
		 * Retrieve an ordered list of all absolute uri parameters. Returns a union of `Api.allBaseUriParameters()`
		 * for `Api` owning the `Resource` and `Resource.allUriParameters()`.
		 */
		function absoluteUriParameters(res) {
		    var uriParamsPropName = universes.Universe08.Resource.properties.uriParameters.name;
		    var baseUriParamsPropName = universes.Universe08.Api.properties.baseUriParameters.name;
		    var params = [];
		    var parent = res;
		    do {
		        res = parent;
		        var uri = res.relativeUri().value();
		        var uriParams = res.uriParameters();
		        params = extractParams(uriParams, uri, res, uriParamsPropName).concat(params);
		        parent = res.parent();
		    } while (parent.definition().key().name == universes.Universe08.Resource.name);
		    var api = parent;
		    var baseUri = api.baseUri().value();
		    var baseUriParams = api.baseUriParameters();
		    params = extractParams(baseUriParams, baseUri, api, baseUriParamsPropName).concat(params);
		    return params;
		}
		exports.absoluteUriParameters = absoluteUriParameters;
		/**
		 * __$helperMethod__ Protocols used by the API. Returns the `protocols` property value if it is specified.
		 * Otherwise, returns protocol, specified in the base URI.
		 **/
		function allProtocols(api) {
		    var result = api.protocols();
		    if (result.length != 0) {
		        return result;
		    }
		    var baseUriAttr = api.baseUri();
		    if (baseUriAttr) {
		        var baseUri = baseUriAttr.value();
		        if (baseUri) {
		            var ind = baseUri.indexOf('://');
		            if (ind >= 0) {
		                result = [baseUri.substring(0, ind)];
		            }
		        }
		    }
		    return result;
		}
		exports.allProtocols = allProtocols;
		/**
		 * __$helperMethod__ Returns security schemes, resource or method is secured with. If no security schemes are set at resource or method level,
		 * returns schemes defined with `securedBy` at API level.
		 */
		function allSecuredBy(resourceOrMethod) {
		    var currentSecuredBy = resourceOrMethod.securedBy();
		    if (currentSecuredBy && currentSecuredBy.length > 0) {
		        return currentSecuredBy;
		    }
		    //instanceof, but have to avoid direct usage of instanceof in JS.
		    if (resourceOrMethod.highLevel().definition().key() == universes.Universe08.Method) {
		        var resource = resourceOrMethod.parentResource();
		        if (resource && resource.securedBy() && resource.securedBy().length > 0) {
		            return resource.securedBy();
		        }
		    }
		    return resourceOrMethod.ownerApi().securedBy();
		}
		exports.allSecuredBy = allSecuredBy;
		/**
		 * __$helperMethod__ Returns the name of security scheme, this reference refers to.
		 */
		function securitySchemeName(schemeReference) {
		    var highLevel = schemeReference.highLevel();
		    if (!highLevel)
		        return "";
		    var attributeValue = highLevel.value();
		    if (!attributeValue)
		        return "";
		    return attributeValue.toString();
		}
		exports.securitySchemeName = securitySchemeName;
		/**
		 * __$helperMethod__ Returns AST node of security scheme, this reference refers to, or null.
		 */
		function securityScheme(schemeReference) {
		    var highLevel = schemeReference.highLevel();
		    if (!highLevel)
		        return null;
		    var declaration = search.findDeclarationByNode(highLevel, 0 /* VALUE_COMPLETION */);
		    if (!declaration)
		        return null;
		    if (!declaration.getKind || declaration.getKind() != 1 /* NODE */) {
		        return null;
		    }
		    var result = declaration.wrapperNode();
		    if (!(result instanceof RamlWrapper.AbstractSecuritySchemeImpl)) {
		        //I do not see how to avoid instanceof here
		        return null;
		    }
		    return result;
		}
		exports.securityScheme = securityScheme;
		//__$helperMethod__ Returns RAML version. "RAML10" string is returned for RAML 1.0. "RAML08" string is returned for RAML 0.8.
		function RAMLVersion(api) {
		    return api.highLevel().definition().universe().version();
		}
		exports.RAMLVersion = RAMLVersion;
		function extractParams(params, uri, owner, propName) {
		    var ownerHl = owner.highLevel();
		    var prop = ownerHl.definition().property(propName);
		    if (!uri) {
		        return [];
		    }
		    var describedParams = {};
		    params.forEach(function (x) {
		        var arr = describedParams[x.name()];
		        if (!arr) {
		            arr = [];
		            describedParams[x.name()] = arr;
		        }
		        arr.push(x);
		    });
		    var allParams = [];
		    var prev = 0;
		    var mentionedParams = {};
		    for (var i = uri.indexOf('{'); i >= 0; i = uri.indexOf('{', prev)) {
		        prev = uri.indexOf('}', ++i);
		        var paramName = uri.substring(i, prev);
		        mentionedParams[paramName] = true;
		        if (describedParams[paramName]) {
		            describedParams[paramName].forEach(function (x) { return allParams.push(x); });
		        }
		        else {
		            var uriParameter = new RamlWrapper.ParameterImpl(paramName);
		            uriParameter.setName(paramName);
		            var hlNode = uriParameter.highLevel();
		            hlNode.setParent(ownerHl);
		            hlNode.patchProp(prop);
		            allParams.push(uriParameter);
		        }
		    }
		    Object.keys(describedParams).filter(function (x) { return !mentionedParams[x]; }).forEach(function (x) { return describedParams[x].forEach(function (y) { return allParams.push(y); }); });
		    return allParams;
		}
		;
		//__$helperMethod__ Returns schema content for the cases when schema is inlined, when schema is included, and when schema is a reference.
		function schemaContent(bodyDeclaration) {
		    var schemaDecl = bodyDeclaration.schema();
		    if (schemaDecl == null) {
		        return null;
		    }
		    var schemaString = schemaDecl.value();
		    if (!schemaString) {
		        return null;
		    }
		    var schemaAttribute = bodyDeclaration.highLevel().attr(universes.Universe08.BodyLike.properties.schema.name);
		    if (!schemaAttribute) {
		        return schemaString;
		    }
		    var declaration = search.findDeclarationByNode(schemaAttribute, 0 /* VALUE_COMPLETION */);
		    if (!declaration)
		        return schemaString;
		    if (!declaration.getKind || declaration.getKind() != 1 /* NODE */) {
		        return schemaString;
		    }
		    //we found the schema declaration and should get its contents
		    if (declaration.definition().key() != universes.Universe08.GlobalSchema) {
		        return null;
		    }
		    var valueAttribute = declaration.attr(universes.Universe08.GlobalSchema.properties.value.name);
		    if (valueAttribute == null) {
		        return null;
		    }
		    return valueAttribute.value();
		}
		exports.schemaContent = schemaContent;
		//
		//export class SchemaDef{
		//
		//    constructor(private _content:string, private _name?:string){}
		//
		//    name():string{return this._name}
		//
		//    content(): string{return this._content}
		//}
		//
		//
		//export class ParamValue{
		//    key:string
		//    value:any
		//
		//    constructor(key:string, value:any) {
		//        this.key = key;
		//        this.value = value;
		//    }
		//}
		//
		//
		//class ParamWrapper implements Raml08Parser.BasicNamedParameter{
		//
		//    constructor(private _param:RamlWrapper.TypeDeclaration){
		//
		//        this.description = _param.description() ? _param.description().value() : this.description;
		//
		//        this.displayName = _param.displayName();
		//
		////        this.enum = _param.enum();
		//
		//        this.type = _param.type().length > 0 ? _param.type()[0] : "string";
		//
		//        this.example = _param.example();
		//
		//        this.repeat = _param.repeat();
		//
		//        this.required = _param.required();
		//
		//        this.default = _param.default();
		//    }
		//
		//    description: Raml08Parser.MarkdownString
		//
		//    displayName: string
		//
		//    'enum': any[]
		//
		//    type: string
		//
		//    example: any
		//
		//    repeat: boolean
		//
		//    required: boolean
		//
		//    'default': any
		//
		//}


	/***/ },
	/* 90 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(38);

	/***/ },
	/* 91 */
	/***/ function(module, exports, __webpack_require__) {

		exports.dot = exports.dotCase = __webpack_require__(92)
		exports.swap = exports.swapCase = __webpack_require__(98)
		exports.path = exports.pathCase = __webpack_require__(100)
		exports.upper = exports.upperCase = __webpack_require__(99)
		exports.lower = exports.lowerCase = __webpack_require__(94)
		exports.camel = exports.camelCase = __webpack_require__(101)
		exports.snake = exports.snakeCase = __webpack_require__(102)
		exports.title = exports.titleCase = __webpack_require__(103)
		exports.param = exports.paramCase = __webpack_require__(104)
		exports.pascal = exports.pascalCase = __webpack_require__(105)
		exports.constant = exports.constantCase = __webpack_require__(107)
		exports.sentence = exports.sentenceCase = __webpack_require__(93)
		exports.isUpper = exports.isUpperCase = __webpack_require__(108)
		exports.isLower = exports.isLowerCase = __webpack_require__(109)
		exports.ucFirst = exports.upperCaseFirst = __webpack_require__(106)
		exports.lcFirst = exports.lowerCaseFirst = __webpack_require__(110)


	/***/ },
	/* 92 */
	/***/ function(module, exports, __webpack_require__) {

		var sentenceCase = __webpack_require__(93);

		/**
		 * Dot case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (string, locale) {
		  return sentenceCase(string, locale, '.');
		};


	/***/ },
	/* 93 */
	/***/ function(module, exports, __webpack_require__) {

		var lowerCase = __webpack_require__(94)

		var NON_WORD_REGEXP = __webpack_require__(95)
		var CAMEL_CASE_REGEXP = __webpack_require__(96)
		var TRAILING_DIGIT_REGEXP = __webpack_require__(97)

		/**
		 * Sentence case a string.
		 *
		 * @param  {String} str
		 * @param  {String} locale
		 * @param  {String} replacement
		 * @return {String}
		 */
		module.exports = function (str, locale, replacement) {
		  if (str == null) {
		    return ''
		  }

		  replacement = replacement || ' '

		  function replace (match, index, string) {
		    if (index === 0 || index === (string.length - match.length)) {
		      return ''
		    }

		    return replacement
		  }

		  str = String(str)
		    // Support camel case ("camelCase" -> "camel Case").
		    .replace(CAMEL_CASE_REGEXP, '$1 $2')
		    // Support digit groups ("test2012" -> "test 2012").
		    .replace(TRAILING_DIGIT_REGEXP, '$1 $2')
		    // Remove all non-word characters and replace with a single space.
		    .replace(NON_WORD_REGEXP, replace)

		  // Lower case the entire string.
		  return lowerCase(str, locale)
		}


	/***/ },
	/* 94 */
	/***/ function(module, exports) {

		/**
		 * Special language-specific overrides.
		 *
		 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
		 *
		 * @type {Object}
		 */
		var LANGUAGES = {
		  tr: {
		    regexp: /\u0130|\u0049|\u0049\u0307/g,
		    map: {
		      '\u0130': '\u0069',
		      '\u0049': '\u0131',
		      '\u0049\u0307': '\u0069'
		    }
		  },
		  az: {
		    regexp: /[\u0130]/g,
		    map: {
		      '\u0130': '\u0069',
		      '\u0049': '\u0131',
		      '\u0049\u0307': '\u0069'
		    }
		  },
		  lt: {
		    regexp: /[\u0049\u004A\u012E\u00CC\u00CD\u0128]/g,
		    map: {
		      '\u0049': '\u0069\u0307',
		      '\u004A': '\u006A\u0307',
		      '\u012E': '\u012F\u0307',
		      '\u00CC': '\u0069\u0307\u0300',
		      '\u00CD': '\u0069\u0307\u0301',
		      '\u0128': '\u0069\u0307\u0303'
		    }
		  }
		}

		/**
		 * Lowercase a string.
		 *
		 * @param  {String} str
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  var lang = LANGUAGES[locale]

		  str = str == null ? '' : String(str)

		  if (lang) {
		    str = str.replace(lang.regexp, function (m) { return lang.map[m] })
		  }

		  return str.toLowerCase()
		}


	/***/ },
	/* 95 */
	/***/ function(module, exports) {

		module.exports = /[^\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]+/g


	/***/ },
	/* 96 */
	/***/ function(module, exports) {

		module.exports = /([\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0561-\u0587\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7FA\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A])([\u0041-\u005A\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA\uFF21-\uFF3A\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])/g


	/***/ },
	/* 97 */
	/***/ function(module, exports) {

		module.exports = /([\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])([^\u0030-\u0039\u00B2\u00B3\u00B9\u00BC-\u00BE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])/g


	/***/ },
	/* 98 */
	/***/ function(module, exports, __webpack_require__) {

		var upperCase = __webpack_require__(99)
		var lowerCase = __webpack_require__(94)

		/**
		 * Swap the case of a string. Manually iterate over every character and check
		 * instead of replacing certain characters for better unicode support.
		 *
		 * @param  {String} str
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  if (str == null) {
		    return ''
		  }

		  var result = ''

		  for (var i = 0; i < str.length; i++) {
		    var c = str[i]
		    var u = upperCase(c, locale)

		    result += u === c ? lowerCase(c, locale) : u
		  }

		  return result
		}


	/***/ },
	/* 99 */
	/***/ function(module, exports) {

		/**
		 * Special language-specific overrides.
		 *
		 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
		 *
		 * @type {Object}
		 */
		var LANGUAGES = {
		  tr: {
		    regexp: /[\u0069]/g,
		    map: {
		      '\u0069': '\u0130'
		    }
		  },
		  az: {
		    regexp: /[\u0069]/g,
		    map: {
		      '\u0069': '\u0130'
		    }
		  },
		  lt: {
		    regexp: /[\u0069\u006A\u012F]\u0307|\u0069\u0307[\u0300\u0301\u0303]/g,
		    map: {
		      '\u0069\u0307': '\u0049',
		      '\u006A\u0307': '\u004A',
		      '\u012F\u0307': '\u012E',
		      '\u0069\u0307\u0300': '\u00CC',
		      '\u0069\u0307\u0301': '\u00CD',
		      '\u0069\u0307\u0303': '\u0128'
		    }
		  }
		}

		/**
		 * Upper case a string.
		 *
		 * @param  {String} str
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  var lang = LANGUAGES[locale]

		  str = str == null ? '' : String(str)

		  if (lang) {
		    str = str.replace(lang.regexp, function (m) { return lang.map[m] })
		  }

		  return str.toUpperCase()
		}


	/***/ },
	/* 100 */
	/***/ function(module, exports, __webpack_require__) {

		var sentenceCase = __webpack_require__(93);

		/**
		 * Path case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (string, locale) {
		  return sentenceCase(string, locale, '/');
		};


	/***/ },
	/* 101 */
	/***/ function(module, exports, __webpack_require__) {

		var upperCase = __webpack_require__(99)
		var sentenceCase = __webpack_require__(93)

		/**
		 * Camel case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (string, locale, mergeNumbers) {
		  var result = sentenceCase(string, locale)

		  // Replace periods between numeric entities with an underscore.
		  if (!mergeNumbers) {
		    result = result.replace(/(\d) (?=\d)/g, '$1_')
		  }

		  // Replace spaces between words with an upper cased character.
		  return result.replace(/ (.)/g, function (m, $1) {
		    return upperCase($1, locale)
		  })
		}


	/***/ },
	/* 102 */
	/***/ function(module, exports, __webpack_require__) {

		var sentenceCase = __webpack_require__(93);

		/**
		 * Snake case a string.
		 *
		 * @param  {String} str
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  return sentenceCase(str, locale, '_');
		};


	/***/ },
	/* 103 */
	/***/ function(module, exports, __webpack_require__) {

		var upperCase = __webpack_require__(99)
		var sentenceCase = __webpack_require__(93)

		/**
		 * Title case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  return sentenceCase(str, locale).replace(/^.| ./g, function (m) {
		    return upperCase(m, locale)
		  })
		}


	/***/ },
	/* 104 */
	/***/ function(module, exports, __webpack_require__) {

		var sentenceCase = __webpack_require__(93);

		/**
		 * Param case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (string, locale) {
		  return sentenceCase(string, locale, '-');
		};


	/***/ },
	/* 105 */
	/***/ function(module, exports, __webpack_require__) {

		var camelCase = __webpack_require__(101)
		var upperCaseFirst = __webpack_require__(106)

		/**
		 * Pascal case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (string, locale) {
		  return upperCaseFirst(camelCase(string, locale), locale)
		}


	/***/ },
	/* 106 */
	/***/ function(module, exports, __webpack_require__) {

		var upperCase = __webpack_require__(99)

		/**
		 * Upper case the first character of a string.
		 *
		 * @param  {String} str
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  if (str == null) {
		    return ''
		  }

		  str = String(str)

		  return upperCase(str.charAt(0), locale) + str.substr(1)
		}


	/***/ },
	/* 107 */
	/***/ function(module, exports, __webpack_require__) {

		var upperCase = __webpack_require__(99)
		var snakeCase = __webpack_require__(102)

		/**
		 * Constant case a string.
		 *
		 * @param  {String} string
		 * @param  {String} [locale]
		 * @return {String}
		 */
		module.exports = function (string, locale) {
		  return upperCase(snakeCase(string, locale), locale)
		}


	/***/ },
	/* 108 */
	/***/ function(module, exports, __webpack_require__) {

		var upperCase = __webpack_require__(99)

		/**
		 * Check if a string is upper case.
		 *
		 * @param  {String}  string
		 * @param  {String}  [locale]
		 * @return {Boolean}
		 */
		module.exports = function (string, locale) {
		  return upperCase(string, locale) === string
		}


	/***/ },
	/* 109 */
	/***/ function(module, exports, __webpack_require__) {

		var lowerCase = __webpack_require__(94)

		/**
		 * Check if a string is lower case.
		 *
		 * @param  {String}  string
		 * @param  {String}  [locale]
		 * @return {Boolean}
		 */
		module.exports = function (string, locale) {
		  return lowerCase(string, locale) === string
		}


	/***/ },
	/* 110 */
	/***/ function(module, exports, __webpack_require__) {

		var lowerCase = __webpack_require__(94)

		/**
		 * Lower case the first character of a string.
		 *
		 * @param  {String} str
		 * @return {String}
		 */
		module.exports = function (str, locale) {
		  if (str == null) {
		    return ''
		  }

		  str = String(str)

		  return lowerCase(str.charAt(0), locale) + str.substr(1)
		}


	/***/ },
	/* 111 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var hl = __webpack_require__(2);
		var linter = __webpack_require__(55);
		var wrapperHelper = __webpack_require__(89);
		function escapeUri(u) {
		    var ss = "";
		    var level = 0;
		    for (var i = 0; i < u.length; i++) {
		        var c = u.charAt(i);
		        if (level == 0) {
		            ss = ss + c;
		        }
		        if (c == '{') {
		            level++;
		        }
		        if (c == '}') {
		            level--;
		        }
		    }
		    return ss;
		}
		var OverloadingValidator = (function () {
		    function OverloadingValidator() {
		        this.holder = {};
		        this.conflicting = {};
		    }
		    OverloadingValidator.prototype.validateApi = function (q, v) {
		        var _this = this;
		        q.resources().forEach(function (x) {
		            _this.acceptResource(x);
		            x.resources().forEach(function (y) { return _this.acceptResource(y); });
		        });
		        for (var c in this.conflicting) {
		            var ms = this.conflicting[c];
		            var notPushed = ms;
		            if (notPushed.length > 1) {
		                notPushed.forEach(function (m) {
		                    v.accept(linter.createIssue(5 /* KEY_SHOULD_BE_UNIQUE_INTHISCONTEXT */, "resources share same URI", m.highLevel(), true));
		                });
		            }
		        }
		    };
		    OverloadingValidator.prototype.acceptResource = function (x) {
		        var uri = escapeUri(wrapperHelper.absoluteUri(x));
		        var pos = this.holder[uri];
		        if (!pos) {
		            pos = [];
		            this.holder[uri] = pos;
		        }
		        pos.push(x);
		        if (pos.length > 1) {
		            this.conflicting[uri] = pos;
		        }
		    };
		    return OverloadingValidator;
		})();
		module.exports = OverloadingValidator;


	/***/ },
	/* 112 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(39);

	/***/ },
	/* 113 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var HttpResponse = __webpack_require__(114);
		__webpack_require__(115);
		__webpack_require__(116);
		var lru = __webpack_require__(59);
		var globalCache = lru(50);
		function hasAsyncRequests() {
		    return Object.keys(notifies).length > 0;
		}
		exports.hasAsyncRequests = hasAsyncRequests;
		function addLoadCallback(listener) {
		    nlisteners.push(listener);
		}
		exports.addLoadCallback = addLoadCallback;
		var nlisteners = [];
		var notifies = {};
		function addNotify(url) {
		    notifies[url] = true;
		}
		exports.addNotify = addNotify;
		function removeNotity(url) {
		    delete notifies[url];
		    nlisteners.forEach(function (x) { return x(url); });
		}
		exports.removeNotity = removeNotity;
		function set(url, content) {
		    globalCache.set(url, content);
		}
		exports.set = set;
		function get(url) {
		    return globalCache.get(url);
		}
		exports.get = get;


	/***/ },
	/* 114 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(42);

	/***/ },
	/* 115 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(43);

	/***/ },
	/* 116 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(76);

	/***/ },
	/* 117 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../typings/main.d.ts" />
		var XMLHttpRequestConstructor = __webpack_require__(118).XMLHttpRequest;
		function buildXHR() {
		    var x = new XMLHttpRequestConstructor;
		    return x;
		}
		var SimpleExecutor = (function () {
		    function SimpleExecutor() {
		    }
		    SimpleExecutor.prototype.execute = function (req, doAppendParams) {
		        if (doAppendParams === void 0) { doAppendParams = true; }
		        var xhr = buildXHR();
		        var url = req.url;
		        if (doAppendParams) {
		            url = this.appendParams(req, req.url);
		        }
		        xhr.open(req.method, url, false);
		        this.doRequest(req, xhr);
		        //rheaders=xhr.getAllResponseHeaders();
		        var status = xhr.status;
		        if (status > 300 && status < 400) {
		            var locHeader = xhr.getResponseHeader('location');
		            if (locHeader) {
		                req.url = locHeader;
		                return this.execute(req, false);
		            }
		        }
		        var response = {
		            status: status,
		            statusText: xhr.statusText,
		            headers: xhr.getAllResponseHeaders().split('\n').map(function (x) {
		                var ind = x.indexOf(':');
		                return {
		                    name: x.substring(0, ind).trim(),
		                    value: x.substring(ind + 1).trim()
		                };
		            }),
		            content: {
		                text: xhr.responseText,
		                mimeType: xhr.responseType
		            }
		        };
		        return response;
		    };
		    SimpleExecutor.prototype.appendParams = function (req, url) {
		        var gotQueryParams = (req.queryString && req.queryString.length > 0);
		        if (gotQueryParams) {
		            url = url + '?';
		            var arr = [];
		            if (gotQueryParams) {
		                arr = arr.concat(req.queryString.map(function (q) {
		                    return encodeURIComponent(q.name) + '=' + encodeURIComponent(q.value);
		                }));
		            }
		            url += arr.join('&');
		        }
		        return url;
		    };
		    SimpleExecutor.prototype.log = function (varName, value) {
		    };
		    SimpleExecutor.prototype.executeAsync = function (req, doAppendParams) {
		        if (doAppendParams === void 0) { doAppendParams = true; }
		        var xhr = buildXHR();
		        var url = req.url;
		        if (doAppendParams) {
		            url = this.appendParams(req, req.url);
		        }
		        var outer = this;
		        return new Promise(function (resolve, reject) {
		            xhr.open(req.method, url, true);
		            xhr.onload = function () {
		                //rheaders=xhr.getAllResponseHeaders();
		                var status = xhr.status;
		                if (status > 300 && status < 400) {
		                    var locHeader = xhr.getResponseHeader('location');
		                    if (locHeader) {
		                        req.url = locHeader;
		                        return outer.executeAsync(req, false);
		                    }
		                }
		                var response = {
		                    status: status,
		                    statusText: xhr.statusText,
		                    headers: xhr.getAllResponseHeaders().split('\n').map(function (x) {
		                        var ind = x.indexOf(':');
		                        return {
		                            name: x.substring(0, ind).trim(),
		                            value: x.substring(ind + 1).trim()
		                        };
		                    }),
		                    content: {
		                        text: xhr.responseText,
		                        mimeType: xhr.responseType
		                    }
		                };
		                resolve(response);
		            };
		            xhr.onerror = function () {
		                reject(Error("Network Error"));
		            };
		            outer.doRequest(req, xhr);
		        });
		    };
		    SimpleExecutor.prototype.doRequest = function (req, xhr) {
		        // Make the request
		        if (req.headers) {
		            req.headers.forEach(function (x) { return xhr.setRequestHeader(x.name, x.value); });
		        }
		        if (req.postData) {
		            if (req.postData.params) {
		                var body = req.postData.params.map(function (p) { return encodeURIComponent(p.name) + '=' + encodeURIComponent(p.value); }).join('&');
		                xhr.send(body);
		            }
		            else {
		                xhr.send(req.postData.text);
		            }
		        }
		        else {
		            xhr.send();
		        }
		    };
		    return SimpleExecutor;
		})();
		exports.SimpleExecutor = SimpleExecutor;


	/***/ },
	/* 118 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(90);

	/***/ },
	/* 119 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(91);

	/***/ },
	/* 120 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var _ = __webpack_require__(4);
		/**
		 * Gets pure include path portion from the complete include.
		 * Does not include the reference part.
		 * @param includeString
		 */
		function getIncludePath(includeString) {
		    var index = includeString.indexOf("#");
		    if (index == -1)
		        return includeString;
		    return includeString.substring(0, index);
		}
		exports.getIncludePath = getIncludePath;
		/**
		 * Gets reference portion of the include string and returns it as
		 * an array of segments. Returns null of no reference is contained in the include.
		 * @param includeString
		 */
		function getIncludeReference(includeString) {
		    var index = includeString.indexOf("#");
		    if (index == -1)
		        return null;
		    var referenceString = index == includeString.length - 1 ? "" : includeString.substring(index + 1, includeString.length);
		    var segments = referenceString.split("/");
		    if (segments.length == 0)
		        return null;
		    if (segments[0].trim() == "") {
		        segments.splice(0, 1);
		    }
		    return new IncludeReferenceImpl(referenceString, segments);
		}
		exports.getIncludeReference = getIncludeReference;
		/**
		 * Factory method returning all include reference resolvers, registered in the system.
		 */
		function getIncludeReferenceResolvers() {
		    return [new JSONResolver()];
		}
		exports.getIncludeReferenceResolvers = getIncludeReferenceResolvers;
		/**
		 * Checks all resolvers, finds the suitable one, resolves the reference and returns the result
		 * of resolving. Returns null if no suitable resolver is found or resolver itself fails to resolve.
		 * @param includeString - complete include string
		 * @param content - include contents
		 */
		function resolveContents(includeString, content) {
		    if (!includeString) {
		        return content;
		    }
		    var reference = getIncludeReference(includeString);
		    if (!reference) {
		        return content;
		    }
		    var includePath = getIncludePath(includeString);
		    return resolve(includePath, reference, content).content;
		}
		exports.resolveContents = resolveContents;
		/**
		 * Checks all resolvers, finds the suitable one, resolves the reference and returns the result
		 * of resolving. Returns null if no suitable resolver is found or resolver itself fails to resolve.
		 * @param includePath
		 * @param includeReference
		 * @param content
		 */
		function resolve(includePath, includeReference, content) {
		    if (!content) {
		        return {
		            content: null,
		            validation: []
		        };
		    }
		    var resolver = _.find(getIncludeReferenceResolvers(), function (currentResolver) { return currentResolver.isApplicable(includePath, content); });
		    if (!resolver)
		        return {
		            content: content,
		            validation: []
		        };
		    return resolver.resolveReference(content, includeReference);
		}
		exports.resolve = resolve;
		function completeReference(includePath, includeReference, content) {
		    if (!content) {
		        return [];
		    }
		    var resolver = _.find(getIncludeReferenceResolvers(), function (currentResolver) { return currentResolver.isApplicable(includePath, content); });
		    if (!resolver)
		        return [];
		    return resolver.completeReference(content, includeReference);
		}
		exports.completeReference = completeReference;
		var IncludeReferenceImpl = (function () {
		    function IncludeReferenceImpl(originalString, segments) {
		        this.segments = segments;
		        this.originalString = originalString;
		    }
		    IncludeReferenceImpl.prototype.getFragments = function () {
		        return this.segments;
		    };
		    IncludeReferenceImpl.prototype.asString = function () {
		        return this.originalString;
		    };
		    return IncludeReferenceImpl;
		})();
		var JSONResolver = (function () {
		    function JSONResolver() {
		    }
		    JSONResolver.prototype.isApplicable = function (includePath, content) {
		        return true;
		    };
		    JSONResolver.prototype.resolveReference = function (content, reference) {
		        try {
		            var jsonRoot = JSON.parse(content);
		            var fragments = reference.getFragments();
		            if (!fragments || fragments.length == 0) {
		                return {
		                    content: content,
		                    validation: []
		                };
		            }
		            var currentJSON = jsonRoot;
		            for (var i = 0; i < fragments.length; i++) {
		                var fragment = fragments[i];
		                currentJSON = this.findChild(currentJSON, fragment);
		                if (!currentJSON) {
		                    var validationIssue = {
		                        message: "Can not resolve " + fragment + " in #" + reference.asString() + " reference"
		                    };
		                    return {
		                        content: content,
		                        validation: [validationIssue]
		                    };
		                }
		            }
		            return {
		                content: JSON.stringify(currentJSON, null, 2),
		                validation: []
		            };
		        }
		        catch (Error) {
		            console.log(Error);
		        }
		        return {
		            content: content,
		            validation: []
		        };
		    };
		    JSONResolver.prototype.completeReference = function (content, reference) {
		        try {
		            var jsonRoot = JSON.parse(content);
		            var fragments = reference.getFragments();
		            if (!fragments || fragments.length == 0) {
		                return this.getChildren(jsonRoot);
		            }
		            var currentJSON = jsonRoot;
		            var emptyPrefixCompletion = reference.asString().lastIndexOf("/") == reference.asString().length - 1;
		            var limit = emptyPrefixCompletion ? fragments.length : fragments.length - 1;
		            for (var i = 0; i < fragments.length - 1; i++) {
		                var fragment = fragments[i];
		                currentJSON = this.findChild(currentJSON, fragment);
		                if (!currentJSON) {
		                    return [];
		                }
		            }
		            if (emptyPrefixCompletion) {
		                return this.getChildren(currentJSON);
		            }
		            else {
		                var lastPrefix = fragments[fragments.length - 1];
		                var result = [];
		                this.getChildren(currentJSON).forEach(function (child) {
		                    if (child.indexOf(lastPrefix) == 0) {
		                        result.push(child);
		                    }
		                });
		                return result;
		            }
		        }
		        catch (Error) {
		            console.log(Error);
		        }
		        return [];
		    };
		    JSONResolver.prototype.findChild = function (jsonObject, fragment) {
		        var decoded = fragment.replace('~1', '/');
		        decoded = fragment.replace('~0', '~');
		        return jsonObject[decoded];
		    };
		    JSONResolver.prototype.getChildren = function (jsonObject) {
		        return Object.keys(jsonObject);
		    };
		    return JSONResolver;
		})();


	/***/ },
	/* 121 */
	/***/ function(module, exports) {

		module.exports = __webpack_require__(97);

	/***/ },
	/* 122 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var defs = __webpack_require__(3);
		var _ = __webpack_require__(4);
		var yaml = __webpack_require__(7);
		var typeExpression = __webpack_require__(51);
		var def = __webpack_require__(3);
		var high = __webpack_require__(2);
		var hlimpl = __webpack_require__(5);
		var search = __webpack_require__(53);
		var universes = __webpack_require__(54);
		var services = __webpack_require__(49);
		var KeyMatcher = (function () {
		    function KeyMatcher(_props) {
		        this._props = _props;
		        this.parentValue = _.find(_props, function (x) { return x.isFromParentValue(); });
		        this.parentKey = _.find(_props, function (x) { return x.isFromParentKey(); });
		        this.canBeValue = _.find(_props, function (x) { return x.canBeValue(); });
		    }
		    KeyMatcher.prototype.match = function (key) {
		        var _this = this;
		        var _res = null;
		        var lastPref = "";
		        this._props.forEach(function (p) {
		            if (p.getAdapter(services.RAMLPropertyService).isSystem()) {
		                return;
		            }
		            if (p != _this.parentValue && p != _this.parentKey && p.matchKey(key)) {
		                if (p.keyPrefix() != null) {
		                    if (p.keyPrefix().length >= lastPref.length) {
		                        lastPref = p.keyPrefix();
		                        _res = p;
		                    }
		                }
		                else {
		                    _res = p;
		                    lastPref = p.nameId();
		                }
		            }
		        });
		        return _res;
		    };
		    return KeyMatcher;
		})();
		function getAllOptions(c, deep) {
		    if (deep === void 0) { deep = 0; }
		    if (deep > 20) {
		        return [];
		    }
		    try {
		        var result = [];
		        var tp = c.leftType();
		        if (tp) {
		            result.push(tp);
		        }
		        var r = c.rightType();
		        if (r) {
		            if (r.hasUnionInHierarchy()) {
		                var options = getAllOptions(r.unionInHierarchy(), deep + 1);
		                result = result.concat(options);
		            }
		            else {
		                result.push(r);
		            }
		        }
		        return result;
		    }
		    finally {
		    }
		}
		var ad = 0;
		var BasicNodeBuilder = (function () {
		    function BasicNodeBuilder() {
		        this.shouldDescriminate = false;
		    }
		    BasicNodeBuilder.prototype.process = function (node, childrenToAdopt) {
		        var _this = this;
		        var nn = node.lowLevel();
		        var cha = nn._node ? nn._node : nn;
		        try {
		            if (cha['currentChildren']) {
		                return cha['currentChildren'];
		            }
		            if (!node.definition()) {
		                return;
		            }
		            if (node.parent() == null && (!this.shouldDescriminate)) {
		                this.shouldDescriminate = true;
		                try {
		                    var children = this.process(node, childrenToAdopt);
		                    var ts = node;
		                    ts._children = children;
		                    var t = doDescrimination(node);
		                    if (t) {
		                        ts.patchType(t);
		                    }
		                    var children = this.process(node, childrenToAdopt);
		                    ts._children = children;
		                }
		                finally {
		                    this.shouldDescriminate = false;
		                }
		            }
		            if (node.definition().hasUnionInHierarchy()) {
		                if (true && (node.parent() && node.property().nameId() == universes.Universe10.RAMLLanguageElement.properties.annotations.name)) {
		                    var optins = getAllOptions(node.definition().unionInHierarchy());
		                    var actualResult = null;
		                    var bestResult = null;
		                    var bestType = null;
		                    var bestCount = 1000;
		                    var llnode = node;
		                    optins.forEach(function (x) {
		                        if (!actualResult) {
		                            //TODO ADD UNION + Descriminator
		                            if (!(x).hasUnionInHierarchy()) {
		                                var tp = llnode.patchType(x);
		                                if (ad == 0) {
		                                    ad++;
		                                    try {
		                                        var result = _this.process(node, childrenToAdopt);
		                                        var uc = 0;
		                                        for (var i = 0; i < result.length; i++) {
		                                            if (result[i].isUnknown()) {
		                                                uc++;
		                                            }
		                                        }
		                                        if (uc == 0) {
		                                            actualResult = result;
		                                        }
		                                        if (bestCount > uc) {
		                                            bestCount = uc;
		                                            bestResult = result;
		                                            bestType = x;
		                                        }
		                                    }
		                                    finally {
		                                        ad--;
		                                    }
		                                }
		                            }
		                        }
		                    });
		                    if (actualResult) {
		                        llnode.patchType(bestType);
		                        return actualResult;
		                    }
		                    if (bestResult) {
		                        llnode.patchType(bestType);
		                    }
		                }
		            }
		            var km = new KeyMatcher(node.definition().allProperties());
		            var aNode = node;
		            var allowsQuestion = aNode._allowQuestion || node.definition().getAdapter(services.RAMLService).getAllowQuestion();
		            var res = [];
		            //cha['currentChildren']=res;
		            if (km.parentKey) {
		                if (node.lowLevel().key()) {
		                    res.push(new hlimpl.ASTPropImpl(node.lowLevel(), node, km.parentKey.range(), km.parentKey, true));
		                }
		            }
		            if (node.lowLevel().value()) {
		                if (km.parentValue) {
		                    res.push(new hlimpl.ASTPropImpl(node.lowLevel(), node, km.parentValue.range(), km.parentValue));
		                }
		                else if (km.canBeValue) {
		                    var s = node.lowLevel().value();
		                    if (typeof s == 'string' && s.trim().length > 0) {
		                        //if (km.canBeValue.nameId()==universes.Universe10.Resource.properties.signature.name){
		                        //      if (s.trim().charAt(0)=='('){
		                        //          //TODO BETTER DECITION current one prevents completion from working correctly
		                        //          //in few other cases
		                        //          res.push(new hlimpl.ASTPropImpl(node.lowLevel(), node, km.canBeValue.range(), km.canBeValue));
		                        //      }
		                        //}
		                        //else {
		                        res.push(new hlimpl.ASTPropImpl(node.lowLevel(), node, km.canBeValue.range(), km.canBeValue));
		                    }
		                    else if (node.definition().isAssignableFrom(universes.Universe10.Annotation.name) && node.definition().property("value")) {
		                        //"value" is a magic property name we do not have reflected in serialized def. system, so have to use plain string
		                        var lowLevelNode = node.lowLevel();
		                        var valueAttribute = _.find(lowLevelNode.children(), function (child) {
		                            return child.kind() == 1 /* MAPPING */ && child.key() && child.key() == "value";
		                        });
		                        if (!valueAttribute) {
		                            //annotation reference is not a scalar and does not have value attribute, but has value defined in the annotation declaration
		                            //that means user wants to use a shortcut and specify value object directly under annotation
		                            var valueProperty = node.definition().property("value");
		                            //creating "value" high-level node referencing the same low-level node so the children can be collected
		                            var valueNode = new hlimpl.ASTNodeImpl(node.lowLevel(), node, valueProperty.range(), valueProperty);
		                            return [valueNode];
		                        }
		                    }
		                }
		            }
		            else {
		                if (km.canBeValue && (km.canBeValue.range() instanceof def.NodeClass || (km.canBeValue.range().hasUnionInHierarchy() && node.definition().isAssignableFrom(universes.Universe10.Annotation.name)))) {
		                    //check check for annotation is just for safety, generally, imho, we should go inside for any unions
		                    var ch = new hlimpl.ASTNodeImpl(node.lowLevel(), aNode, km.canBeValue.range(), km.canBeValue);
		                    return [ch];
		                }
		            }
		            aNode._children = res;
		            if (!aNode.definition().getAdapter(services.RAMLService).isUserDefined()) {
		                if (aNode.definition().key() == universes.Universe08.Api || aNode.definition().key() == universes.Universe10.Api) {
		                    var uses = childrenToAdopt.filter(function (x) { return x.key() == "uses"; });
		                    res = this.processChildren(uses, aNode, res, allowsQuestion, km);
		                    var types = childrenToAdopt.filter(function (x) { return x.key() == "types"; });
		                    res = this.processChildren(types, aNode, res, allowsQuestion, km);
		                    var other = childrenToAdopt.filter(function (x) { return (x.key() != "types" && x.key() != "uses"); });
		                    res = this.processChildren(other, aNode, res, allowsQuestion, km);
		                }
		                else {
		                    res = this.processChildren(childrenToAdopt, aNode, res, allowsQuestion, km);
		                }
		            }
		            else {
		                res = this.processChildren(childrenToAdopt, aNode, res, allowsQuestion, km);
		            }
		            aNode._children = res;
		            return res;
		        }
		        finally {
		            if (ch) {
		                delete cha['currentChildren'];
		            }
		        }
		    };
		    BasicNodeBuilder.prototype.processChildren = function (childrenToAdopt, aNode, res, allowsQuestion, km) {
		        childrenToAdopt.forEach(function (x) {
		            var key = x.key();
		            if (x.optional() && !allowsQuestion) {
		                return;
		            }
		            var p = key != null ? km.match(key) : null;
		            if (p != null) {
		                var range = p.range();
		                if (p.isAnnotation() && key != "annotations") {
		                    var pi = new hlimpl.ASTPropImpl(x, aNode, range, p);
		                    res.push(pi);
		                    return;
		                }
		                var um = false;
		                var multyValue = p.isMultiValue();
		                if (range instanceof def.Array) {
		                    var at = range;
		                    multyValue = true;
		                    range = at.component;
		                    um = true;
		                }
		                else if (range.hasArrayInHierarchy()) {
		                    multyValue = true;
		                    um = true;
		                }
		                //TODO DESCRIMINATORS
		                if (range.hasValueTypeInHierarchy()) {
		                    var ch = x.children();
		                    var seq = (x.valueKind() == 3 /* SEQ */);
		                    if ((seq && ch.length > 0 || ch.length > 1) && multyValue) {
		                        ch.forEach(function (y) {
		                            var pi = new hlimpl.ASTPropImpl(y, aNode, range, p);
		                            res.push(pi);
		                        });
		                    }
		                    else {
		                        if (p.isInherited()) {
		                            aNode.setComputed(p.nameId(), x.value());
		                        }
		                        var attrNode = new hlimpl.ASTPropImpl(x, aNode, range, p);
		                        if ((seq || x.valueKind() == 2 /* MAP */)) {
		                            var rng = p.range().nameId();
		                            if (!p.getAdapter(services.RAMLPropertyService).isExampleProperty()) {
		                                if (rng == 'StringType') {
		                                    rng = "string";
		                                }
		                                if (rng == 'NumberType') {
		                                    rng = "number";
		                                }
		                                if (rng == 'BooleanType') {
		                                    rng = "boolean";
		                                }
		                                if (rng == "string" || rng == "number" || rng == "boolean") {
		                                    attrNode.errorMessage = "property '" + p.groupName() + "' must be a " + rng;
		                                    if (x.children().length == 0 && p.groupName() == "enum") {
		                                        attrNode.errorMessage = "enum is empty";
		                                        if (x.valueKind() == 2 /* MAP */) {
		                                            attrNode.errorMessage = "the value of enum must be an array";
		                                        }
		                                    }
		                                }
		                            }
		                        }
		                        res.push(attrNode);
		                    }
		                    //}
		                    return;
		                }
		                else {
		                    var rs = [];
		                    //now we need determine actual type
		                    aNode._children = res;
		                    if (x.value() && typeof x.value() == 'string') {
		                        if (x.value().trim().length > 0) {
		                            var c = p.range();
		                            if (!c.allProperties().some(function (x) {
		                                var srv = x;
		                                if (srv) {
		                                    return srv.canBeValue() && srv.isFromParentValue();
		                                }
		                                return false;
		                            })) {
		                                var bnode = new hlimpl.BasicASTNode(x, aNode);
		                                bnode.getLowLevelEnd = function () {
		                                    return -1;
		                                };
		                                bnode.getLowLevelStart = function () {
		                                    return -1;
		                                };
		                                bnode.knownProperty = p;
		                                res.push(bnode);
		                            }
		                        }
		                    }
		                    if (!p.isMerged()) {
		                        if (multyValue) {
		                            if (p.getAdapter(services.RAMLPropertyService).isEmbedMap()) {
		                                var chld = x.children();
		                                if (chld.length == 0) {
		                                    if (p.range().key() == universes.Universe08.ResourceType) {
		                                        var error = new hlimpl.BasicASTNode(x, aNode);
		                                        error.errorMessage = "property: '" + p.nameId() + "' must be a map";
		                                        res.push(error);
		                                    }
		                                    if (x.valueKind() == 0 /* SCALAR */) {
		                                        if (p.range().key() == universes.Universe08.AbstractSecurityScheme) {
		                                            var error = new hlimpl.BasicASTNode(x, aNode);
		                                            error.errorMessage = "property: '" + p.nameId() + "' must be a map";
		                                            res.push(error);
		                                        }
		                                    }
		                                }
		                                chld.forEach(function (y) {
		                                    //TODO TRACK GROUP KEY
		                                    var cld = y.children();
		                                    if (!y.key() && cld.length == 1) {
		                                        var node = new hlimpl.ASTNodeImpl(cld[0], aNode, range, p);
		                                        node._allowQuestion = allowsQuestion;
		                                        rs.push(node);
		                                    }
		                                    else {
		                                        if (aNode.universe().version() == "RAML10") {
		                                            var node = new hlimpl.ASTNodeImpl(y, aNode, range, p);
		                                            node._allowQuestion = allowsQuestion;
		                                            rs.push(node);
		                                        }
		                                        else {
		                                            var bnode = new hlimpl.BasicASTNode(y, aNode);
		                                            res.push(bnode);
		                                            if (y.key()) {
		                                                bnode.needSequence = true;
		                                            }
		                                        }
		                                    }
		                                });
		                            }
		                            else {
		                                var filter = {};
		                                var inherited = [];
		                                if (range instanceof defs.NodeClass) {
		                                    var nc = range;
		                                    if (nc.getAdapter(services.RAMLService).getCanInherit().length > 0) {
		                                        nc.getAdapter(services.RAMLService).getCanInherit().forEach(function (v) {
		                                            var vl = aNode.computedValue(v);
		                                            if (vl && p.nameId() == universes.Universe10.Response.properties.body.name) {
		                                                if (!_.find(x.children(), function (x) { return x.key() == vl; })) {
		                                                    //we can create inherited node;
		                                                    var pc = aNode.parent().definition().key();
		                                                    var node = new hlimpl.ASTNodeImpl(x, aNode, range, p);
		                                                    if (pc == universes.Universe10.MethodBase || pc == universes.Universe08.MethodBase) {
		                                                        node.setComputed("form", "true"); //FIXME
		                                                    }
		                                                    var t = descriminate(p, aNode, node);
		                                                    if (t) {
		                                                        node.patchType(t);
		                                                    }
		                                                    var ch = node.children();
		                                                    //this are false unknowns actual unknowns will be reported by parent node
		                                                    node._children = ch.filter(function (x) { return !x.isUnknown(); });
		                                                    node._allowQuestion = allowsQuestion;
		                                                    inherited.push(node);
		                                                    node.children().forEach(function (x) {
		                                                        if (x.property().getAdapter(services.RAMLPropertyService).isKey()) {
		                                                            var atr = x;
		                                                            atr._computed = true;
		                                                            return;
		                                                        }
		                                                        if (x.isElement()) {
		                                                            if (!x.property().getAdapter(services.RAMLPropertyService).isMerged()) {
		                                                                filter[x.property().nameId()] = true;
		                                                            }
		                                                        }
		                                                        if (x.property().isAnnotation()) {
		                                                            var atr = x;
		                                                            var vl = atr.value();
		                                                            var strVal = "";
		                                                            if (vl instanceof hlimpl.StructuredValue) {
		                                                                strVal = vl.valueName();
		                                                            }
		                                                            else {
		                                                                strVal = "" + vl;
		                                                            }
		                                                            filter["(" + strVal + ")"] = true;
		                                                        }
		                                                        else {
		                                                            filter[x.name()] = true;
		                                                        }
		                                                    });
		                                                    var ap = node.definition().allProperties();
		                                                    ap.forEach(function (p) {
		                                                        if (p.getAdapter(services.RAMLPropertyService).isKey()) {
		                                                            return;
		                                                        }
		                                                        if (p.getAdapter(services.RAMLPropertyService).isSystem()) {
		                                                            return;
		                                                        }
		                                                        if (node.lowLevel().children().some(function (x) { return x.key() == p.nameId(); })) {
		                                                            filter[p.nameId()] = true;
		                                                        }
		                                                    });
		                                                    node._computed = true;
		                                                }
		                                            }
		                                        });
		                                    }
		                                }
		                                var parsed = [];
		                                if (x.children().length == 0) {
		                                    if (x.valueKind() == 3 /* SEQ */) {
		                                        if (p.range().key() == universes.Universe08.Parameter) {
		                                            var error = new hlimpl.BasicASTNode(x, aNode);
		                                            error.errorMessage = "property: '" + p.nameId() + "' must be a map";
		                                            res.push(error);
		                                        }
		                                    }
		                                }
		                                x.children().forEach(function (y) {
		                                    if (filter[y.key()]) {
		                                        return;
		                                    }
		                                    if (y.valueKind() == 3 /* SEQ */) {
		                                        y.children().forEach(function (z) {
		                                            var node = new hlimpl.ASTNodeImpl(z, aNode, range, p);
		                                            node._allowQuestion = allowsQuestion;
		                                            node.setNamePatch(y.key());
		                                            parsed.push(node);
		                                        });
		                                        if (y.children().length == 0) {
		                                            var error = new hlimpl.BasicASTNode(y, aNode);
		                                            if (p.range().key() == universes.Universe08.Parameter) {
		                                                error.errorMessage = "named parameter needs at least one type";
		                                            }
		                                            else {
		                                                error.errorMessage = "node should have at least one member value";
		                                            }
		                                            res.push(error);
		                                        }
		                                    }
		                                    else {
		                                        var node = new hlimpl.ASTNodeImpl(y, aNode, range, p);
		                                        var dc = p.domain().key();
		                                        if (p.nameId() == "body" && (dc == universes.Universe08.MethodBase || dc == universes.Universe10.MethodBase)) {
		                                            node.setComputed("form", "true"); //FIXME
		                                        }
		                                        node._allowQuestion = allowsQuestion;
		                                        parsed.push(node);
		                                    }
		                                });
		                                if (parsed.length > 0) {
		                                    parsed.forEach(function (x) { return rs.push(x); });
		                                }
		                                else {
		                                    inherited.forEach(function (x) { return rs.push(x); });
		                                }
		                            }
		                        }
		                        else {
		                            //var y=x.children()[0];
		                            rs.push(new hlimpl.ASTNodeImpl(x, aNode, range, p));
		                        }
		                    }
		                    else {
		                        var node = new hlimpl.ASTNodeImpl(x, aNode, range, p);
		                        node._allowQuestion = allowsQuestion;
		                        rs.push(node);
		                    }
		                    aNode._children = aNode._children.concat(rs);
		                    res = res.concat(rs);
		                    rs.forEach(function (x) {
		                        var rt = descriminate(p, aNode, x);
		                        if (rt && rt != x.definition()) {
		                            x.patchType(rt);
		                        }
		                        x._associatedDef = null;
		                        p.childRestrictions().forEach(function (y) {
		                            x.setComputed(y.name, y.value);
		                        });
		                        var def = x.definition();
		                    });
		                }
		            }
		            else {
		                res.push(new hlimpl.BasicASTNode(x, aNode));
		            }
		        });
		        return res;
		    };
		    return BasicNodeBuilder;
		})();
		exports.BasicNodeBuilder = BasicNodeBuilder;
		function desc1(p, parent, x) {
		    var tp = x.attr("type");
		    var value = "";
		    if (tp) {
		        var mn = {};
		        var c = new def.NodeClass(x.name(), x.definition().universe(), "");
		        c.getAdapter(services.RAMLService).setDeclaringNode(x);
		        c._superTypes.push(x.definition().universe().type(universes.Universe10.TypeDeclaration.name));
		        mn[tp.value()] = c;
		        var newType = typeExpression.getType(parent ? parent : x, tp.value(), mn);
		        if (newType instanceof def.Array) {
		            newType.getAdapter(services.RAMLService).setDeclaringNode(x);
		        }
		        return newType;
		    }
		    else {
		        if (p) {
		            if (p.nameId() == "body" || _.find(x.lowLevel().children(), function (x) { return x.key() == "properties"; })) {
		                return x.definition().universe().type(universes.Universe10.ObjectTypeDeclaration.name);
		            }
		        }
		        return x.definition().universe().type(universes.Universe10.StringTypeDeclaration.name);
		    }
		    return null;
		}
		function doDescrimination(node) {
		    try {
		        var nodeDefenitionName = node.definition().nameId();
		        var isApi = nodeDefenitionName === universes.Universe10.Api.name || nodeDefenitionName === universes.Universe08.Api.name;
		        if (!isApi && !node.property() && !node.parent() && node.definition().nameId() === high.getFragmentDefenitionName(node)) {
		            var result = null;
		            var subTypes = node.definition().allSubTypes();
		            subTypes.forEach(function (subType) {
		                if (!result && subType.getAdapter(services.RAMLService).match(node, null)) {
		                    result = subType;
		                }
		            });
		            return result;
		        }
		    }
		    catch (exception) {
		    }
		    return descriminate(node.property(), node.parent(), node);
		}
		exports.doDescrimination = doDescrimination;
		function descriminate(p, parent, x) {
		    var n = x.lowLevel();
		    if (p) {
		        if (p.nameId() == universes.Universe10.LibraryBase.properties.uses.name && p.range().nameId() == universes.Universe10.Library.name) {
		        }
		    }
		    var range = p ? p.range().nameId() : x.definition().nameId();
		    if (n._node && n._node['descriminate']) {
		        return null;
		    }
		    if (n._node) {
		        n._node['descriminate'] = 1;
		    }
		    try {
		        if (range == universes.Universe10.TypeDeclaration.name) {
		            var res = desc1(p, parent, x);
		            //FIXME (think about it later)
		            if (p) {
		                if (res != null && ((p.nameId() == universes.Universe10.MethodBase.properties.body.name || p.nameId() == universes.Universe10.Response.properties.headers.name) || p.nameId() == universes.Universe10.Method.properties.queryParameters.name)) {
		                    var ares = new defs.UserDefinedClass(x.lowLevel().key(), res.universe(), x, x.lowLevel().unit() ? x.lowLevel().unit().path() : "", "");
		                    ares._superTypes.push(res);
		                    return ares;
		                }
		                if (res != null && (p.nameId() == universes.Universe10.LibraryBase.properties.annotationTypes.name)) {
		                    var ares = new defs.UserDefinedClass(x.lowLevel().key(), res.universe(), x, x.lowLevel().unit() ? x.lowLevel().unit().path() : "", "");
		                    ares._superTypes.push(p.range().universe().type(universes.Universe10.AnnotationTypeDeclaration.name));
		                    ares._superTypes.push(res);
		                    return ares;
		                }
		            }
		            if (res) {
		                return res;
		            }
		        }
		        //generic case;
		        var rt = null;
		        if (p && parent) {
		            var types = search.findAllSubTypes(p, parent);
		            if (types.length > 0) {
		                types.forEach(function (y) {
		                    if (!rt) {
		                        if (y.getAdapter(services.RAMLService).match(x, rt)) {
		                            rt = y;
		                        }
		                    }
		                });
		            }
		            return rt;
		        }
		    }
		    finally {
		        if (n._node) {
		            delete n._node['descriminate'];
		        }
		    }
		}
		;


	/***/ },
	/* 123 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var jsyaml = __webpack_require__(15);
		var ll = __webpack_require__(10);
		var _ = __webpack_require__(4);
		var yaml = __webpack_require__(7);
		var hlimpl = __webpack_require__(5);
		var universes = __webpack_require__(54);
		var services = __webpack_require__(49);
		function findLastAttributeIndex(n) {
		    var last = -1;
		    var children = n.lowLevel().children();
		    for (var i = 0; i < children.length; i++) {
		        var node = children[i];
		        if (!node.isMapping())
		            continue;
		        var name = node.asMapping().key.value;
		        var property = n.definition().property(name);
		        if (!property)
		            continue;
		        //console.log(property.name() + ': isval: ' + property.isValue() + '; multi: ' + property.isMultiValue() + '; range val: ' + property.range().isValueType());
		        //if((property.isValue() || /*property.isMultiValue()) ||*/ property.range().isValueType()) {
		        if (property.isFromParentValue() || property.range().hasValueTypeInHierarchy()) {
		            last = i;
		        }
		    }
		    //console.log('last attr index1: ' + last);
		    return last;
		}
		function findInsertionPointLowLevel(node, llnode, property, attr) {
		    //console.log('LL find insertion: node is attr: ' + attr);
		    var insertionPoint = null;
		    var embed = property && property.getAdapter(services.RAMLPropertyService).isEmbedMap();
		    if (embed && _.find(node.lowLevel().children(), function (x) { return x.key() == property.nameId(); })) {
		        embed = false;
		    }
		    if (attr || embed) {
		        var last = findLastAttribute(node);
		        if (!last) {
		            //insertionPoint = new jsyaml.InsertionPoint(jsyaml.InsertionPointType.START);
		            insertionPoint = jsyaml.InsertionPoint.atStart();
		        }
		        else {
		            insertionPoint = last;
		        }
		    }
		    return insertionPoint;
		}
		function findInsertionPoint(where, node) {
		    //console.log('find insertion point for node (HL): ' + node.property().name() + '; attr: ' + node.isAttr());
		    //console.log('node1: ' + node.lowLevel().text());
		    //always insert attributes at start
		    if (!where.isStub()) {
		        where.clearChildrenCache();
		    }
		    var ch = where.children();
		    var embed = node.property() && node.property().getAdapter(services.RAMLPropertyService).isEmbedMap();
		    if (embed && _.find(where.lowLevel().children(), function (x) { return x.key() == node.property().nameId(); })) {
		        embed = false;
		    }
		    //console.log('node2: ' + node.lowLevel().text());
		    if (node.isAttr() || embed) {
		        var toRet = null;
		        for (var i = 0; i < ch.length; i++) {
		            if (!ch[i].isAttr()) {
		                break;
		            }
		            else {
		                toRet = ch[i].lowLevel();
		            }
		        }
		        if (toRet == null) {
		            toRet = where.lowLevel();
		        }
		        return toRet;
		    }
		    else {
		        var pname = node.property().nameId();
		        var cls = where.definition();
		        var props = cls.allProperties();
		        //console.log('class: ' + cls.name());
		        //props.forEach(x=> console.log('  prop: ' + x.name()));
		        var pindex = cls.propertyIndex(pname);
		        if (pindex < 0) {
		            return null;
		        }
		        var llchilds = where.lowLevel().children();
		        for (var i = 0; i < llchilds.length; i++) {
		            var llch = llchilds[i];
		            //console.log('  child: ' + llch.kindName());
		            if (!llch.isMapping())
		                continue;
		            var cpnme = llch.asMapping().key.value;
		            var pi = cls.propertyIndex(cpnme);
		            //console.log('  property: ' + cpnme + ' index: ' + pi + ' at pos: ' + i);
		            if (pi > pindex) {
		                //console.log('  property: ' + cpnme + ' - found');
		                var lastok = i - 1;
		                //console.log('lastok: ' + lastok);
		                if (lastok < 0) {
		                    //TODO insert at the very beginning
		                    //console.log('insert to very beginning');
		                    return null;
		                }
		                else {
		                    console.log('insert to node: ' + lastok);
		                    return llchilds[lastok];
		                }
		            }
		            else {
		            }
		        }
		        return null;
		    }
		    //console.log('HL insertion: ' + toRet);
		    //return toRet;
		}
		function removeNodeFrom(source, node) {
		    if (source.isStub()) {
		        if (node instanceof hlimpl.ASTNodeImpl) {
		            var cm = node;
		            if (cm.isInEdit) {
		                return;
		            }
		        }
		        if (!source._children) {
		            return;
		        }
		        source._children = source._children.filter(function (x) { return x != node; });
		        return;
		    }
		    var command = new ll.CompositeCommand();
		    if (node instanceof hlimpl.ASTNodeImpl) {
		        var aNode = node;
		        if (!aNode.property().getAdapter(services.RAMLPropertyService).isMerged()) {
		            if (source.elementsOfKind(aNode.property().nameId()).length == 1) {
		                command.commands.push(ll.removeNode(source.lowLevel(), aNode.lowLevel().parent().parent()));
		            }
		            else {
		                command.commands.push(ll.removeNode(source.lowLevel(), aNode.lowLevel()));
		            }
		        }
		        else {
		            command.commands.push(ll.removeNode(source.lowLevel(), aNode.lowLevel()));
		        }
		    }
		    else {
		        command.commands.push(ll.removeNode(source.lowLevel(), node.lowLevel()));
		    }
		    source.lowLevel().execute(command);
		}
		exports.removeNodeFrom = removeNodeFrom;
		function initEmptyRAMLFile(node) {
		    var llroot = node.lowLevel().root();
		    var command = new ll.CompositeCommand();
		    var newroot = jsyaml.createMap([]);
		    command.commands.push(ll.initRamlFile(node.lowLevel(), newroot));
		    node.lowLevel().execute(command);
		    var root = node.root();
		    //console.log('root: ' + root);
		    root._node = newroot;
		    root.clearChildrenCache();
		}
		exports.initEmptyRAMLFile = initEmptyRAMLFile;
		function setValue(node, value) {
		    if (value == node.value())
		        return;
		    var c = new ll.CompositeCommand();
		    if (typeof value === 'string') {
		        var val = value;
		        //FIXME actually isFromParentKey should be enough in future does not changing it now for safety reasons
		        if (node.property().isFromParentKey() || node.property().isAnnotation()) {
		            if (node.property().isAnnotation()) {
		                val = '(' + val + ')';
		            }
		            c.commands.push(ll.setKey(node.lowLevel(), val));
		        }
		        else {
		            if ((!val || val.length == 0) && !node.isEmbedded()) {
		                c.commands.push(ll.removeNode(node.lowLevel().parent(), node.lowLevel()));
		                node.parent().clearChildrenCache();
		            }
		            else {
		                if (!val)
		                    val = '';
		                c.commands.push(ll.setAttr(node.lowLevel(), val));
		            }
		        }
		    }
		    else {
		        if (node.property().isFromParentKey()) {
		            throw new Error("couldn't set structured value to a key: " + node.property().nameId());
		        }
		        var sval = value;
		        c.commands.push(ll.setAttrStructured(node.lowLevel(), sval));
		    }
		    node.lowLevel().execute(c);
		}
		exports.setValue = setValue;
		function addStringValue(attr, value) {
		    var sc = jsyaml.createScalar(value);
		    var target = attr.lowLevel();
		    //console.log('add to target: ' + target.kindName());
		    if (target.isScalar()) {
		        target = target.parent();
		    }
		    else if (target.isMapping()) {
		    }
		    var command = new ll.CompositeCommand();
		    command.commands.push(ll.insertNode(target, sc, null, true));
		    attr.lowLevel().execute(command);
		    attr.parent().clearChildrenCache();
		}
		exports.addStringValue = addStringValue;
		function addStructuredValue(attr, sv) {
		    //var sc = jsyaml.createScalar(value);
		    var target = attr.lowLevel();
		    //console.log('add to target: ' + target.kindName());
		    if (target.isScalar()) {
		        target = target.parent();
		    }
		    else if (target.isMapping()) {
		        var ln = attr.lowLevel();
		    }
		    var command = new ll.CompositeCommand();
		    command.commands.push(ll.insertNode(target, sv.lowLevel(), null, true));
		    attr.lowLevel().execute(command);
		    attr.parent().clearChildrenCache();
		}
		exports.addStructuredValue = addStructuredValue;
		function removeAttr(attr) {
		    var llparent = attr.lowLevel().parent();
		    if (!attr.property().isMultiValue() && attr.isEmbedded()) {
		        // it's embedded value, need to clean scalar instead
		        //console.log('embedded!');
		        attr.setValue('');
		    }
		    else {
		        var command = new ll.CompositeCommand();
		        command.commands.push(ll.removeNode(llparent, attr.lowLevel()));
		        attr.lowLevel().execute(command);
		        attr.parent().clearChildrenCache();
		    }
		}
		exports.removeAttr = removeAttr;
		function setValues(attr, values) {
		    if (!attr.property().isMultiValue())
		        throw new Error("setValue(string[]) only apply to multi-values properties");
		    var node = attr.parent();
		    if (attr.isEmpty()) {
		    }
		    else {
		        var llnode = node.lowLevel();
		        var attrs = node.attributes(attr.name());
		        attrs.forEach(function (attr) { return attr.remove(); });
		    }
		    values.forEach(function (val) { return node.attrOrCreate(attr.name()).addValue(val); });
		}
		exports.setValues = setValues;
		function setKey(node, value) {
		    if (value == node.name())
		        return;
		    var c = new ll.CompositeCommand();
		    c.commands.push(ll.setKey(node.lowLevel(), value));
		    node.lowLevel().execute(c);
		}
		exports.setKey = setKey;
		function createAttr(node, n, v) {
		    var mapping = jsyaml.createMapping(n, v);
		    var map;
		    if (node.definition() && node.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		        if (node.lowLevel() && node.lowLevel().valueKind() === 0 /* SCALAR */) {
		            var typePropertyName = universes.Universe10.TypeDeclaration.properties.type.name;
		            var typeMapping = jsyaml.createMapping(typePropertyName, node.lowLevel().value());
		            var command = new ll.CompositeCommand();
		            command.commands.push(ll.setAttr(node.lowLevel(), ""));
		            node.lowLevel().execute(command);
		            command = new ll.CompositeCommand();
		            var insertionPoint = findInsertionPointLowLevel(node, typeMapping, node.definition().property(typePropertyName), true);
		            command.commands.push(ll.insertNode(node.lowLevel(), typeMapping, insertionPoint));
		            node.lowLevel().execute(command);
		        }
		    }
		    //console.log('create attribute: ' + n);
		    if (node.isStub()) {
		        //console.log('create-attr: stub case');
		        var insertionIndex = findLastAttributeIndex(node);
		        //console.log('stub insertion index: ' + insertionIndex);
		        node.lowLevel().addChild(mapping, insertionIndex + 1);
		    }
		    else {
		        //console.log('root: ' + llroot.kindName());
		        if (node.isEmptyRamlFile()) {
		            node.initRamlFile();
		        }
		        //console.log('create-attr: real node case');
		        //node._node.addChild(mapping);
		        //node.clearChildrenCache();
		        var command = new ll.CompositeCommand();
		        var insertionPoint = findInsertionPointLowLevel(node, mapping, node.definition().property(n), true);
		        //command.commands.push(ll.insertNode(node.lowLevel(), mapping, null));
		        //var toseq = node.property().isMultiValue();
		        command.commands.push(ll.insertNode(node.lowLevel(), mapping, insertionPoint));
		        node.lowLevel().execute(command);
		    }
		    node.clearChildrenCache();
		}
		exports.createAttr = createAttr;
		function findLastAttribute(node) {
		    var childs = node.lowLevel().children();
		    var index = findLastAttributeIndex(node);
		    //console.log('last attr index2: ' + index);
		    return (index < 0) ? null : childs[index];
		}
		function addToNode(target, node) {
		    if (!target.isStub() && target.isEmptyRamlFile()) {
		        target.initRamlFile();
		    }
		    var llnode = node.lowLevel();
		    if (!target._children) {
		        target._children = [];
		    }
		    if (!node.property()) {
		        //now we should find correct property;
		        var an = node;
		        var allProps = target.definition().allProperties();
		        var cp = null;
		        allProps.forEach(function (x) {
		            var r = x.range();
		            if (r == an.definition()) {
		                cp = x;
		            }
		            var isOk = _.find(an.definition().allSuperTypes(), function (x) { return x == r; });
		            if (isOk) {
		                cp = x;
		            }
		        });
		        if (!cp) {
		            throw new Error("Unable to find correct child");
		        }
		        else {
		            an.patchProp(cp);
		        }
		    }
		    var insertionPoint = findInsertionPoint(target, node);
		    //console.log('high level op: ' + target.property() + '.add ' + node.property().name());
		    if (insertionPoint) {
		    }
		    //var newLowLevel:ll.ILowLevelASTNode=null;
		    var command = new ll.CompositeCommand();
		    //now we need to understand to which low level node it should go
		    //command.commands.push(ll.insertNode(target.lowLevel(), node.lowLevel()))
		    var insertionTarget = null;
		    if (node.property().getAdapter(services.RAMLPropertyService).isMerged() || node.property().range().hasValueTypeInHierarchy()) {
		        //console.log('CASE 1');
		        //newLowLevel = node.lowLevel();
		        command.commands.push(ll.insertNode(target.lowLevel(), node.lowLevel(), insertionPoint));
		        insertionTarget = target.lowLevel();
		    }
		    else {
		        //console.log('CASE 2');
		        var name = node.property().nameId();
		        var target2 = target.lowLevel();
		        //target.show('TARGET:');
		        //llnode.show('NODE:');
		        var found = target.lowLevel().find(name);
		        insertionTarget = found;
		        if (!found) {
		            //console.log('node not found');
		            var nn = null;
		            //var nn: jsyaml.ASTNode = jsyaml.createSeqNode(name);
		            //var mapping = <yaml.YAMLMapping>nn._actualNode();
		            //var seq: yaml.YAMLSequence = <yaml.YAMLSequence>mapping.value;
		            //if(!seq.items) seq.items = [];
		            //seq.items.push((<jsyaml.ASTNode>node.lowLevel())._actualNode());
		            if (node.property().getAdapter(services.RAMLPropertyService).isEmbedMap()) {
		                var v10 = target.definition().universe().version() == 'RAML10';
		                if (llnode.isValueMap() && v10)
		                    nn = jsyaml.createMapNode(name);
		                else
		                    nn = jsyaml.createSeqNode(name);
		                //console.log('NN: ' + yaml.Kind[nn._actualNode().kind]);
		                nn.addChild(node.lowLevel());
		            }
		            else {
		                nn = jsyaml.createNode(name);
		                nn.addChild(node.lowLevel());
		            }
		            //nn.show('WRAPPED NODE:');
		            //target.show('INSERT WRAPPED NODE TO:');
		            command.commands.push(ll.insertNode(target2, nn, insertionPoint));
		            insertionTarget = target2;
		        }
		        else {
		            //console.log('node found');
		            //found.show('INSERT2: ');
		            if (node.property().getAdapter(services.RAMLPropertyService).isEmbedMap()) {
		                //newLowLevel=node.lowLevel();
		                command.commands.push(ll.insertNode(found, node.lowLevel(), insertionPoint, true));
		            }
		            else {
		                //newLowLevel=node.lowLevel();
		                command.commands.push(ll.insertNode(found, node.lowLevel(), insertionPoint, false));
		            }
		        }
		    }
		    if (target.isStub()) {
		        var insertionIndex = findLastAttributeIndex(target);
		        if (insertionIndex < 0) {
		            target._children.push(node);
		        }
		        else {
		            //TODO behavior should be smarter we are ignoring insertion points now
		            target._children.splice(insertionIndex, 0, node);
		        }
		        command.commands.forEach(function (x) { return insertionTarget.addChild(x.value); });
		        return;
		    }
		    target.lowLevel().execute(command);
		    target._children.push(node);
		    //now we need to add new child to our children;
		    node.setParent(target);
		}
		exports.addToNode = addToNode;


	/***/ },
	/* 124 */
	/***/ function(module, exports, __webpack_require__) {

		var RamlWrapper = __webpack_require__(1);
		/**
		 * @hidden
		 * Build Wrapper node corresponding to the High Level node
		 **/
		function buildWrapperNode(node) {
		    var nodeClassName = node.definition().nameId();
		    var wrapperConstructor = classMap[nodeClassName];
		    if (!wrapperConstructor) {
		        var m = node.definition().allSuperTypes();
		        var wr = null;
		        for (var i = 0; i < m.length; i++) {
		            var nm = m[i].nameId();
		            wrapperConstructor = classMap[nm];
		            if (nm == "DataElement") {
		                wr = nm;
		                continue;
		            }
		            if (nm == "RAMLLanguageElement") {
		                continue;
		            }
		            if (wrapperConstructor) {
		                break;
		            }
		        }
		        if (!wrapperConstructor) {
		            wr = nm;
		        }
		    }
		    if (!wrapperConstructor) {
		        wrapperConstructor = classMap["RAMLLanguageElement"];
		    }
		    return wrapperConstructor(node);
		}
		exports.buildWrapperNode = buildWrapperNode;
		var classMap = {
		    "AbstractSecurityScheme": function (x) {
		        return new RamlWrapper.AbstractSecuritySchemeImpl(x);
		    },
		    "AnnotationRef": function (x) {
		        return new RamlWrapper.AnnotationRefImpl(x);
		    },
		    "AnnotationTarget": function (x) {
		        return new RamlWrapper.AnnotationTargetImpl(x);
		    },
		    "AnnotationTypeDeclaration": function (x) {
		        return new RamlWrapper.AnnotationTypeDeclarationImpl(x);
		    },
		    "Api": function (x) {
		        return new RamlWrapper.ApiImpl(x);
		    },
		    "ApiDescription": function (x) {
		        return new RamlWrapper.ApiDescriptionImpl(x);
		    },
		    "ArrayTypeDeclaration": function (x) {
		        return new RamlWrapper.ArrayTypeDeclarationImpl(x);
		    },
		    "BasicSecurityScheme": function (x) {
		        return new RamlWrapper.BasicSecuritySchemeImpl(x);
		    },
		    "BooleanType": function (x) {
		        return new RamlWrapper.BooleanTypeImpl(x);
		    },
		    "BooleanTypeDeclaration": function (x) {
		        return new RamlWrapper.BooleanTypeDeclarationImpl(x);
		    },
		    "CallbackAPIDescription": function (x) {
		        return new RamlWrapper.CallbackAPIDescriptionImpl(x);
		    },
		    "ContentType": function (x) {
		        return new RamlWrapper.ContentTypeImpl(x);
		    },
		    "CustomSecurityScheme": function (x) {
		        return new RamlWrapper.CustomSecuritySchemeImpl(x);
		    },
		    "DataElementRef": function (x) {
		        return new RamlWrapper.DataElementRefImpl(x);
		    },
		    "DateFormatSpec": function (x) {
		        return new RamlWrapper.DateFormatSpecImpl(x);
		    },
		    "DateTypeDeclaration": function (x) {
		        return new RamlWrapper.DateTypeDeclarationImpl(x);
		    },
		    "DigestSecurityScheme": function (x) {
		        return new RamlWrapper.DigestSecuritySchemeImpl(x);
		    },
		    "DocumentationItem": function (x) {
		        return new RamlWrapper.DocumentationItemImpl(x);
		    },
		    "ExampleSpec": function (x) {
		        return new RamlWrapper.ExampleSpecImpl(x);
		    },
		    "ExampleString": function (x) {
		        return new RamlWrapper.ExampleStringImpl(x);
		    },
		    "Extension": function (x) {
		        return new RamlWrapper.ExtensionImpl(x);
		    },
		    "FileTypeDeclaration": function (x) {
		        return new RamlWrapper.FileTypeDeclarationImpl(x);
		    },
		    "FixedUriString": function (x) {
		        return new RamlWrapper.FixedUriStringImpl(x);
		    },
		    "FullUriTemplateString": function (x) {
		        return new RamlWrapper.FullUriTemplateStringImpl(x);
		    },
		    "FunctionalInterface": function (x) {
		        return new RamlWrapper.FunctionalInterfaceImpl(x);
		    },
		    "GlobalSchema": function (x) {
		        return new RamlWrapper.GlobalSchemaImpl(x);
		    },
		    "HasNormalParameters": function (x) {
		        return new RamlWrapper.HasNormalParametersImpl(x);
		    },
		    "ImportDeclaration": function (x) {
		        return new RamlWrapper.ImportDeclarationImpl(x);
		    },
		    "IntegerTypeDeclaration": function (x) {
		        return new RamlWrapper.IntegerTypeDeclarationImpl(x);
		    },
		    "JSonSchemaString": function (x) {
		        return new RamlWrapper.JSonSchemaStringImpl(x);
		    },
		    "Library": function (x) {
		        return new RamlWrapper.LibraryImpl(x);
		    },
		    "LibraryBase": function (x) {
		        return new RamlWrapper.LibraryBaseImpl(x);
		    },
		    "LocationKind": function (x) {
		        return new RamlWrapper.LocationKindImpl(x);
		    },
		    "MarkdownString": function (x) {
		        return new RamlWrapper.MarkdownStringImpl(x);
		    },
		    "Method": function (x) {
		        return new RamlWrapper.MethodImpl(x);
		    },
		    "MethodBase": function (x) {
		        return new RamlWrapper.MethodBaseImpl(x);
		    },
		    "MimeType": function (x) {
		        return new RamlWrapper.MimeTypeImpl(x);
		    },
		    "ModelLocation": function (x) {
		        return new RamlWrapper.ModelLocationImpl(x);
		    },
		    "NumberType": function (x) {
		        return new RamlWrapper.NumberTypeImpl(x);
		    },
		    "NumberTypeDeclaration": function (x) {
		        return new RamlWrapper.NumberTypeDeclarationImpl(x);
		    },
		    "OAuth1SecurityScheme": function (x) {
		        return new RamlWrapper.OAuth1SecuritySchemeImpl(x);
		    },
		    "OAuth1SecuritySchemeSettings": function (x) {
		        return new RamlWrapper.OAuth1SecuritySchemeSettingsImpl(x);
		    },
		    "OAuth2SecurityScheme": function (x) {
		        return new RamlWrapper.OAuth2SecuritySchemeImpl(x);
		    },
		    "OAuth2SecuritySchemeSettings": function (x) {
		        return new RamlWrapper.OAuth2SecuritySchemeSettingsImpl(x);
		    },
		    "ObjectTypeDeclaration": function (x) {
		        return new RamlWrapper.ObjectTypeDeclarationImpl(x);
		    },
		    "Overlay": function (x) {
		        return new RamlWrapper.OverlayImpl(x);
		    },
		    "PassThroughSecurityScheme": function (x) {
		        return new RamlWrapper.PassThroughSecuritySchemeImpl(x);
		    },
		    "PassThroughSecuritySchemeSettings": function (x) {
		        return new RamlWrapper.PassThroughSecuritySchemeSettingsImpl(x);
		    },
		    "RAMLExpression": function (x) {
		        return new RamlWrapper.RAMLExpressionImpl(x);
		    },
		    "RAMLLanguageElement": function (x) {
		        return new RamlWrapper.RAMLLanguageElementImpl(x);
		    },
		    "RAMLPointer": function (x) {
		        return new RamlWrapper.RAMLPointerImpl(x);
		    },
		    "RAMLPointerElement": function (x) {
		        return new RamlWrapper.RAMLPointerElementImpl(x);
		    },
		    "RAMLProject": function (x) {
		        return new RamlWrapper.RAMLProjectImpl(x);
		    },
		    "RAMLSelector": function (x) {
		        return new RamlWrapper.RAMLSelectorImpl(x);
		    },
		    "RAMLSimpleElement": function (x) {
		        return new RamlWrapper.RAMLSimpleElementImpl(x);
		    },
		    "Reference": function (x) {
		        return new RamlWrapper.ReferenceImpl(x);
		    },
		    "RelativeUriString": function (x) {
		        return new RamlWrapper.RelativeUriStringImpl(x);
		    },
		    "Resource": function (x) {
		        return new RamlWrapper.ResourceImpl(x);
		    },
		    "ResourceBase": function (x) {
		        return new RamlWrapper.ResourceBaseImpl(x);
		    },
		    "ResourceType": function (x) {
		        return new RamlWrapper.ResourceTypeImpl(x);
		    },
		    "ResourceTypeRef": function (x) {
		        return new RamlWrapper.ResourceTypeRefImpl(x);
		    },
		    "Response": function (x) {
		        return new RamlWrapper.ResponseImpl(x);
		    },
		    "SchemaElement": function (x) {
		        return new RamlWrapper.SchemaElementImpl(x);
		    },
		    "SchemaString": function (x) {
		        return new RamlWrapper.SchemaStringImpl(x);
		    },
		    "ScriptHookElement": function (x) {
		        return new RamlWrapper.ScriptHookElementImpl(x);
		    },
		    "ScriptSpec": function (x) {
		        return new RamlWrapper.ScriptSpecImpl(x);
		    },
		    "SecuritySchemePart": function (x) {
		        return new RamlWrapper.SecuritySchemePartImpl(x);
		    },
		    "SecuritySchemeRef": function (x) {
		        return new RamlWrapper.SecuritySchemeRefImpl(x);
		    },
		    "SecuritySchemeSettings": function (x) {
		        return new RamlWrapper.SecuritySchemeSettingsImpl(x);
		    },
		    "StatusCodeString": function (x) {
		        return new RamlWrapper.StatusCodeStringImpl(x);
		    },
		    "StringType": function (x) {
		        return new RamlWrapper.StringTypeImpl(x);
		    },
		    "StringTypeDeclaration": function (x) {
		        return new RamlWrapper.StringTypeDeclarationImpl(x);
		    },
		    "Trait": function (x) {
		        return new RamlWrapper.TraitImpl(x);
		    },
		    "TraitRef": function (x) {
		        return new RamlWrapper.TraitRefImpl(x);
		    },
		    "TypeDeclaration": function (x) {
		        return new RamlWrapper.TypeDeclarationImpl(x);
		    },
		    "UnionTypeDeclaration": function (x) {
		        return new RamlWrapper.UnionTypeDeclarationImpl(x);
		    },
		    "UriTemplate": function (x) {
		        return new RamlWrapper.UriTemplateImpl(x);
		    },
		    "ValidityExpression": function (x) {
		        return new RamlWrapper.ValidityExpressionImpl(x);
		    },
		    "ValueType": function (x) {
		        return new RamlWrapper.ValueTypeImpl(x);
		    },
		    "ValueTypeDeclaration": function (x) {
		        return new RamlWrapper.ValueTypeDeclarationImpl(x);
		    },
		    "XMLSchemaString": function (x) {
		        return new RamlWrapper.XMLSchemaStringImpl(x);
		    },
		    "pointer": function (x) {
		        return new RamlWrapper.pointerImpl(x);
		    }
		};


	/***/ },
	/* 125 */
	/***/ function(module, exports, __webpack_require__) {

		var RamlWrapper = __webpack_require__(74);
		/**
		 * @hidden
		 * Build Wrapper node corresponding to the High Level node
		 **/
		function buildWrapperNode(node) {
		    var nodeClassName = node.definition().nameId();
		    var wrapperConstructor = classMap[nodeClassName];
		    if (!wrapperConstructor) {
		        var m = node.definition().allSuperTypes();
		        var wr = null;
		        for (var i = 0; i < m.length; i++) {
		            var nm = m[i].nameId();
		            wrapperConstructor = classMap[nm];
		            if (nm == "DataElement") {
		                wr = nm;
		                continue;
		            }
		            if (nm == "RAMLLanguageElement") {
		                continue;
		            }
		            if (wrapperConstructor) {
		                break;
		            }
		        }
		        if (!wrapperConstructor) {
		            wr = nm;
		        }
		    }
		    if (!wrapperConstructor) {
		        wrapperConstructor = classMap["RAMLLanguageElement"];
		    }
		    return wrapperConstructor(node);
		}
		exports.buildWrapperNode = buildWrapperNode;
		var classMap = {
		    "AbstractSecurityScheme": function (x) {
		        return new RamlWrapper.AbstractSecuritySchemeImpl(x);
		    },
		    "Api": function (x) {
		        return new RamlWrapper.ApiImpl(x);
		    },
		    "BasicSecurityScheme": function (x) {
		        return new RamlWrapper.BasicSecuritySchemeImpl(x);
		    },
		    "BodyLike": function (x) {
		        return new RamlWrapper.BodyLikeImpl(x);
		    },
		    "BooleanType": function (x) {
		        return new RamlWrapper.BooleanTypeImpl(x);
		    },
		    "BooleanTypeDeclaration": function (x) {
		        return new RamlWrapper.BooleanTypeDeclarationImpl(x);
		    },
		    "CustomSecurityScheme": function (x) {
		        return new RamlWrapper.CustomSecuritySchemeImpl(x);
		    },
		    "DateTypeDeclaration": function (x) {
		        return new RamlWrapper.DateTypeDeclarationImpl(x);
		    },
		    "DigestSecurityScheme": function (x) {
		        return new RamlWrapper.DigestSecuritySchemeImpl(x);
		    },
		    "DocumentationItem": function (x) {
		        return new RamlWrapper.DocumentationItemImpl(x);
		    },
		    "ExampleString": function (x) {
		        return new RamlWrapper.ExampleStringImpl(x);
		    },
		    "FileTypeDeclaration": function (x) {
		        return new RamlWrapper.FileTypeDeclarationImpl(x);
		    },
		    "FixedUri": function (x) {
		        return new RamlWrapper.FixedUriImpl(x);
		    },
		    "FullUriTemplateString": function (x) {
		        return new RamlWrapper.FullUriTemplateStringImpl(x);
		    },
		    "GlobalSchema": function (x) {
		        return new RamlWrapper.GlobalSchemaImpl(x);
		    },
		    "HasNormalParameters": function (x) {
		        return new RamlWrapper.HasNormalParametersImpl(x);
		    },
		    "IntegerTypeDeclaration": function (x) {
		        return new RamlWrapper.IntegerTypeDeclarationImpl(x);
		    },
		    "JSONBody": function (x) {
		        return new RamlWrapper.JSONBodyImpl(x);
		    },
		    "JSONExample": function (x) {
		        return new RamlWrapper.JSONExampleImpl(x);
		    },
		    "JSonSchemaString": function (x) {
		        return new RamlWrapper.JSonSchemaStringImpl(x);
		    },
		    "MarkdownString": function (x) {
		        return new RamlWrapper.MarkdownStringImpl(x);
		    },
		    "Method": function (x) {
		        return new RamlWrapper.MethodImpl(x);
		    },
		    "MethodBase": function (x) {
		        return new RamlWrapper.MethodBaseImpl(x);
		    },
		    "MimeType": function (x) {
		        return new RamlWrapper.MimeTypeImpl(x);
		    },
		    "NumberType": function (x) {
		        return new RamlWrapper.NumberTypeImpl(x);
		    },
		    "NumberTypeDeclaration": function (x) {
		        return new RamlWrapper.NumberTypeDeclarationImpl(x);
		    },
		    "OAuth1SecurityScheme": function (x) {
		        return new RamlWrapper.OAuth1SecuritySchemeImpl(x);
		    },
		    "OAuth1SecuritySchemeSettings": function (x) {
		        return new RamlWrapper.OAuth1SecuritySchemeSettingsImpl(x);
		    },
		    "OAuth2SecurityScheme": function (x) {
		        return new RamlWrapper.OAuth2SecuritySchemeImpl(x);
		    },
		    "OAuth2SecuritySchemeSettings": function (x) {
		        return new RamlWrapper.OAuth2SecuritySchemeSettingsImpl(x);
		    },
		    "Parameter": function (x) {
		        return new RamlWrapper.ParameterImpl(x);
		    },
		    "ParameterLocation": function (x) {
		        return new RamlWrapper.ParameterLocationImpl(x);
		    },
		    "RAMLLanguageElement": function (x) {
		        return new RamlWrapper.RAMLLanguageElementImpl(x);
		    },
		    "RAMLSimpleElement": function (x) {
		        return new RamlWrapper.RAMLSimpleElementImpl(x);
		    },
		    "Reference": function (x) {
		        return new RamlWrapper.ReferenceImpl(x);
		    },
		    "RelativeUriString": function (x) {
		        return new RamlWrapper.RelativeUriStringImpl(x);
		    },
		    "Resource": function (x) {
		        return new RamlWrapper.ResourceImpl(x);
		    },
		    "ResourceType": function (x) {
		        return new RamlWrapper.ResourceTypeImpl(x);
		    },
		    "ResourceTypeRef": function (x) {
		        return new RamlWrapper.ResourceTypeRefImpl(x);
		    },
		    "Response": function (x) {
		        return new RamlWrapper.ResponseImpl(x);
		    },
		    "SchemaString": function (x) {
		        return new RamlWrapper.SchemaStringImpl(x);
		    },
		    "SecuritySchemePart": function (x) {
		        return new RamlWrapper.SecuritySchemePartImpl(x);
		    },
		    "SecuritySchemeRef": function (x) {
		        return new RamlWrapper.SecuritySchemeRefImpl(x);
		    },
		    "SecuritySchemeSettings": function (x) {
		        return new RamlWrapper.SecuritySchemeSettingsImpl(x);
		    },
		    "StatusCodeString": function (x) {
		        return new RamlWrapper.StatusCodeStringImpl(x);
		    },
		    "StringType": function (x) {
		        return new RamlWrapper.StringTypeImpl(x);
		    },
		    "StringTypeDeclaration": function (x) {
		        return new RamlWrapper.StringTypeDeclarationImpl(x);
		    },
		    "Trait": function (x) {
		        return new RamlWrapper.TraitImpl(x);
		    },
		    "TraitRef": function (x) {
		        return new RamlWrapper.TraitRefImpl(x);
		    },
		    "UriTemplate": function (x) {
		        return new RamlWrapper.UriTemplateImpl(x);
		    },
		    "ValueType": function (x) {
		        return new RamlWrapper.ValueTypeImpl(x);
		    },
		    "XMLBody": function (x) {
		        return new RamlWrapper.XMLBodyImpl(x);
		    },
		    "XMLExample": function (x) {
		        return new RamlWrapper.XMLExampleImpl(x);
		    },
		    "XMLSchemaString": function (x) {
		        return new RamlWrapper.XMLSchemaStringImpl(x);
		    }
		};


	/***/ },
	/* 126 */
	/***/ function(module, exports, __webpack_require__) {

		/// <reference path="../../../typings/main.d.ts" />
		var __extends = this.__extends || function (d, b) {
		    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
		    function __() { this.constructor = d; }
		    __.prototype = b.prototype;
		    d.prototype = new __();
		};
		var _ = __webpack_require__(4);
		var sel = __webpack_require__(127);
		var Selector = (function () {
		    function Selector() {
		    }
		    Selector.prototype.candidates = function (context) {
		        return context;
		    };
		    Selector.prototype.apply = function (h) {
		        return this.candidates([h]);
		    };
		    return Selector;
		})();
		exports.Selector = Selector;
		var OrMatch = (function (_super) {
		    __extends(OrMatch, _super);
		    function OrMatch(left, right) {
		        _super.call(this);
		        this.left = left;
		        this.right = right;
		    }
		    OrMatch.prototype.candidates = function (context) {
		        var l = this.left.candidates(context);
		        l = l.concat(this.right.candidates(context));
		        return _.unique(l);
		    };
		    return OrMatch;
		})(Selector);
		exports.OrMatch = OrMatch;
		var DotMatch = (function (_super) {
		    __extends(DotMatch, _super);
		    function DotMatch(left, right) {
		        _super.call(this);
		        this.left = left;
		        this.right = right;
		    }
		    DotMatch.prototype.candidates = function (context) {
		        var l = this.left.candidates(context);
		        if (this.left instanceof AnyParentMatch) {
		            l = this.right.candidates(new AnyChildMatch().candidates(l));
		            return _.unique(l);
		        }
		        if (this.left instanceof ParentMatch) {
		            l = this.right.candidates(new AnyChildMatch().candidates(l));
		            return _.unique(l);
		        }
		        l = this.right.candidates(l);
		        return _.unique(l);
		    };
		    return DotMatch;
		})(Selector);
		exports.DotMatch = DotMatch;
		function resolveSelector(s, n) {
		    if (s.type == "or") {
		        var b = s;
		        var l = resolveSelector(b.left, n);
		        var r = resolveSelector(b.right, n);
		        return new OrMatch(l, r);
		    }
		    if (s.type == "dot") {
		        var b = s;
		        var l = resolveSelector(b.left, n);
		        var r = resolveSelector(b.right, n);
		        return new DotMatch(l, r);
		    }
		    if (s.type == 'classLiteral') {
		        var literal = s;
		        var tp = n.definition().universe().type(literal.name);
		        if (tp == null || tp.hasValueTypeInHierarchy()) {
		            throw new Error("Referencing unknown type:" + literal.name);
		        }
		        return new IdMatch(literal.name);
		    }
		    if (s.type == 'parent') {
		        return new ParentMatch();
		    }
		    if (s.type == 'ancestor') {
		        return new AnyParentMatch();
		    }
		    if (s.type == 'descendant') {
		        return new AnyChildMatch();
		    }
		    if (s.type == 'child') {
		        return new ChildMatch();
		    }
		}
		exports.resolveSelector = resolveSelector;
		var IdMatch = (function (_super) {
		    __extends(IdMatch, _super);
		    function IdMatch(name) {
		        _super.call(this);
		        this.name = name;
		    }
		    IdMatch.prototype.candidates = function (context) {
		        var _this = this;
		        return context.filter(function (x) {
		            if (!x) {
		                return false;
		            }
		            if (x.definition().nameId() == _this.name) {
		                return true;
		            }
		            var superTypes = x.definition().allSuperTypes();
		            if (_.find(superTypes, function (x) { return x.nameId() == _this.name; })) {
		                return true;
		            }
		            return false;
		        });
		    };
		    return IdMatch;
		})(Selector);
		exports.IdMatch = IdMatch;
		var AnyParentMatch = (function (_super) {
		    __extends(AnyParentMatch, _super);
		    function AnyParentMatch() {
		        _super.apply(this, arguments);
		    }
		    AnyParentMatch.prototype.candidates = function (context) {
		        var res = [];
		        context.forEach(function (x) {
		            if (x) {
		                var z = x.parent();
		                while (z) {
		                    res.push(z);
		                    z = z.parent();
		                }
		            }
		        });
		        return _.unique(res);
		    };
		    return AnyParentMatch;
		})(Selector);
		exports.AnyParentMatch = AnyParentMatch;
		function addChildren(x, r) {
		    r.push(x);
		    x.elements().forEach(function (y) { return addChildren(y, r); });
		}
		var AnyChildMatch = (function (_super) {
		    __extends(AnyChildMatch, _super);
		    function AnyChildMatch() {
		        _super.apply(this, arguments);
		    }
		    AnyChildMatch.prototype.candidates = function (context) {
		        var res = [];
		        context.forEach(function (x) {
		            if (x) {
		                addChildren(x, res);
		            }
		        });
		        return _.unique(res);
		    };
		    return AnyChildMatch;
		})(Selector);
		exports.AnyChildMatch = AnyChildMatch;
		var ParentMatch = (function (_super) {
		    __extends(ParentMatch, _super);
		    function ParentMatch() {
		        _super.apply(this, arguments);
		    }
		    ParentMatch.prototype.candidates = function (context) {
		        return context.map(function (x) { return x.parent(); });
		    };
		    return ParentMatch;
		})(Selector);
		exports.ParentMatch = ParentMatch;
		var ChildMatch = (function (_super) {
		    __extends(ChildMatch, _super);
		    function ChildMatch() {
		        _super.apply(this, arguments);
		    }
		    ChildMatch.prototype.candidates = function (context) {
		        var res = [];
		        context.forEach(function (x) {
		            if (x) {
		                res = res.concat(x.elements());
		            }
		        });
		        return res;
		    };
		    return ChildMatch;
		})(Selector);
		exports.ChildMatch = ChildMatch;
		function parse(h, path) {
		    return resolveSelector(sel.parse(path), h);
		}
		exports.parse = parse;


	/***/ },
	/* 127 */
	/***/ function(module, exports) {

		var mod = (function () {
		    /*
		     * Generated by PEG.js 0.8.0.
		     *
		     * http://pegjs.majda.cz/
		     */
		    function peg$subclass(child, parent) {
		        function ctor() {
		            this.constructor = child;
		        }
		        ctor.prototype = parent.prototype;
		        child.prototype = new ctor();
		    }
		    function SyntaxError(message, expected, found, offset, line, column) {
		        this.message = message;
		        this.expected = expected;
		        this.found = found;
		        this.offset = offset;
		        this.line = line;
		        this.column = column;
		        this.name = "SyntaxError";
		    }
		    peg$subclass(SyntaxError, Error);
		    function parse(input) {
		        var options = arguments.length > 1 ? arguments[1] : {}, peg$FAILED = {}, peg$startRuleFunctions = { start: peg$parsestart }, peg$startRuleFunction = peg$parsestart, peg$c0 = peg$FAILED, peg$c1 = "|", peg$c2 = { type: "literal", value: "|", description: "\"|\"" }, peg$c3 = function (left, r) {
		            return { 'type': 'or', 'left': left, 'right': r ? r : null };
		        }, peg$c4 = ".", peg$c5 = { type: "literal", value: ".", description: "\".\"" }, peg$c6 = function (left, r) {
		            return { 'type': 'dot', 'left': left, 'right': r };
		        }, peg$c7 = "$", peg$c8 = { type: "literal", value: "$", description: "\"$\"" }, peg$c9 = function () {
		            return { 'type': 'parent' };
		        }, peg$c10 = "$$", peg$c11 = { type: "literal", value: "$$", description: "\"$$\"" }, peg$c12 = function () {
		            return { 'type': 'ancestor' };
		        }, peg$c13 = "**", peg$c14 = { type: "literal", value: "**", description: "\"**\"" }, peg$c15 = function () {
		            return { 'type': 'descendant' };
		        }, peg$c16 = "*", peg$c17 = { type: "literal", value: "*", description: "\"*\"" }, peg$c18 = function () {
		            return { 'type': 'child' };
		        }, peg$c19 = [], peg$c20 = /^[A-z]/, peg$c21 = { type: "class", value: "[A-z]", description: "[A-z]" }, peg$c22 = function (chars) {
		            return { 'type': 'classLiteral', "name": chars.join("") };
		        }, peg$currPos = 0, peg$reportedPos = 0, peg$cachedPos = 0, peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, peg$result;
		        if ("startRule" in options) {
		            if (!(options.startRule in peg$startRuleFunctions)) {
		                throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
		            }
		            peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
		        }
		        function text() {
		            return input.substring(peg$reportedPos, peg$currPos);
		        }
		        function offset() {
		            return peg$reportedPos;
		        }
		        function line() {
		            return peg$computePosDetails(peg$reportedPos).line;
		        }
		        function column() {
		            return peg$computePosDetails(peg$reportedPos).column;
		        }
		        function expected(description) {
		            throw peg$buildException(null, [{ type: "other", description: description }], peg$reportedPos);
		        }
		        function error(message) {
		            throw peg$buildException(message, null, peg$reportedPos);
		        }
		        function peg$computePosDetails(pos) {
		            function advance(details, startPos, endPos) {
		                var p, ch;
		                for (p = startPos; p < endPos; p++) {
		                    ch = input.charAt(p);
		                    if (ch === "\n") {
		                        if (!details.seenCR) {
		                            details.line++;
		                        }
		                        details.column = 1;
		                        details.seenCR = false;
		                    }
		                    else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
		                        details.line++;
		                        details.column = 1;
		                        details.seenCR = true;
		                    }
		                    else {
		                        details.column++;
		                        details.seenCR = false;
		                    }
		                }
		            }
		            if (peg$cachedPos !== pos) {
		                if (peg$cachedPos > pos) {
		                    peg$cachedPos = 0;
		                    peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
		                }
		                advance(peg$cachedPosDetails, peg$cachedPos, pos);
		                peg$cachedPos = pos;
		            }
		            return peg$cachedPosDetails;
		        }
		        function peg$fail(expected) {
		            if (peg$currPos < peg$maxFailPos) {
		                return;
		            }
		            if (peg$currPos > peg$maxFailPos) {
		                peg$maxFailPos = peg$currPos;
		                peg$maxFailExpected = [];
		            }
		            peg$maxFailExpected.push(expected);
		        }
		        function peg$buildException(message, expected, pos) {
		            function cleanupExpected(expected) {
		                var i = 1;
		                expected.sort(function (a, b) {
		                    if (a.description < b.description) {
		                        return -1;
		                    }
		                    else if (a.description > b.description) {
		                        return 1;
		                    }
		                    else {
		                        return 0;
		                    }
		                });
		                while (i < expected.length) {
		                    if (expected[i - 1] === expected[i]) {
		                        expected.splice(i, 1);
		                    }
		                    else {
		                        i++;
		                    }
		                }
		            }
		            function buildMessage(expected, found) {
		                function stringEscape(s) {
		                    function hex(ch) {
		                        return ch.charCodeAt(0).toString(16).toUpperCase();
		                    }
		                    return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\x08/g, '\\b').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\f/g, '\\f').replace(/\r/g, '\\r').replace(/[\x00-\x07\x0B\x0E\x0F]/g, function (ch) {
		                        return '\\x0' + hex(ch);
		                    }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) {
		                        return '\\x' + hex(ch);
		                    }).replace(/[\u0180-\u0FFF]/g, function (ch) {
		                        return '\\u0' + hex(ch);
		                    }).replace(/[\u1080-\uFFFF]/g, function (ch) {
		                        return '\\u' + hex(ch);
		                    });
		                }
		                var expectedDescs = new Array(expected.length), expectedDesc, foundDesc, i;
		                for (i = 0; i < expected.length; i++) {
		                    expectedDescs[i] = expected[i].description;
		                }
		                expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(", ") + " or " + expectedDescs[expected.length - 1] : expectedDescs[0];
		                foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
		                return "Expected " + expectedDesc + " but " + foundDesc + " found.";
		            }
		            var posDetails = peg$computePosDetails(pos), found = pos < input.length ? input.charAt(pos) : null;
		            if (expected !== null) {
		                cleanupExpected(expected);
		            }
		            return new SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column);
		        }
		        function peg$parsestart() {
		            var s0;
		            s0 = peg$parseor();
		            return s0;
		        }
		        function peg$parseor() {
		            var s0, s1, s2, s3;
		            s0 = peg$currPos;
		            s1 = peg$parsesequence();
		            if (s1 !== peg$FAILED) {
		                if (input.charCodeAt(peg$currPos) === 124) {
		                    s2 = peg$c1;
		                    peg$currPos++;
		                }
		                else {
		                    s2 = peg$FAILED;
		                    if (peg$silentFails === 0) {
		                        peg$fail(peg$c2);
		                    }
		                }
		                if (s2 !== peg$FAILED) {
		                    s3 = peg$parseor();
		                    if (s3 !== peg$FAILED) {
		                        peg$reportedPos = s0;
		                        s1 = peg$c3(s1, s3);
		                        s0 = s1;
		                    }
		                    else {
		                        peg$currPos = s0;
		                        s0 = peg$c0;
		                    }
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$c0;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$c0;
		            }
		            if (s0 === peg$FAILED) {
		                s0 = peg$parsesequence();
		            }
		            return s0;
		        }
		        function peg$parsesequence() {
		            var s0, s1, s2, s3;
		            s0 = peg$currPos;
		            s1 = peg$parseprimary();
		            if (s1 !== peg$FAILED) {
		                if (input.charCodeAt(peg$currPos) === 46) {
		                    s2 = peg$c4;
		                    peg$currPos++;
		                }
		                else {
		                    s2 = peg$FAILED;
		                    if (peg$silentFails === 0) {
		                        peg$fail(peg$c5);
		                    }
		                }
		                if (s2 !== peg$FAILED) {
		                    s3 = peg$parsesequence();
		                    if (s3 !== peg$FAILED) {
		                        peg$reportedPos = s0;
		                        s1 = peg$c6(s1, s3);
		                        s0 = s1;
		                    }
		                    else {
		                        peg$currPos = s0;
		                        s0 = peg$c0;
		                    }
		                }
		                else {
		                    peg$currPos = s0;
		                    s0 = peg$c0;
		                }
		            }
		            else {
		                peg$currPos = s0;
		                s0 = peg$c0;
		            }
		            if (s0 === peg$FAILED) {
		                s0 = peg$parseprimary();
		            }
		            return s0;
		        }
		        function peg$parseprimary() {
		            var s0;
		            s0 = peg$parsechildRef();
		            if (s0 === peg$FAILED) {
		                s0 = peg$parsedoubleStar();
		                if (s0 === peg$FAILED) {
		                    s0 = peg$parsestar();
		                    if (s0 === peg$FAILED) {
		                        s0 = peg$parsedoubleDollar();
		                        if (s0 === peg$FAILED) {
		                            s0 = peg$parsedollar();
		                        }
		                    }
		                }
		            }
		            return s0;
		        }
		        function peg$parsedollar() {
		            var s0, s1;
		            s0 = peg$currPos;
		            if (input.charCodeAt(peg$currPos) === 36) {
		                s1 = peg$c7;
		                peg$currPos++;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c8);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                peg$reportedPos = s0;
		                s1 = peg$c9();
		            }
		            s0 = s1;
		            return s0;
		        }
		        function peg$parsedoubleDollar() {
		            var s0, s1;
		            s0 = peg$currPos;
		            if (input.substr(peg$currPos, 2) === peg$c10) {
		                s1 = peg$c10;
		                peg$currPos += 2;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c11);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                peg$reportedPos = s0;
		                s1 = peg$c12();
		            }
		            s0 = s1;
		            return s0;
		        }
		        function peg$parsedoubleStar() {
		            var s0, s1;
		            s0 = peg$currPos;
		            if (input.substr(peg$currPos, 2) === peg$c13) {
		                s1 = peg$c13;
		                peg$currPos += 2;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c14);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                peg$reportedPos = s0;
		                s1 = peg$c15();
		            }
		            s0 = s1;
		            return s0;
		        }
		        function peg$parsestar() {
		            var s0, s1;
		            s0 = peg$currPos;
		            if (input.charCodeAt(peg$currPos) === 42) {
		                s1 = peg$c16;
		                peg$currPos++;
		            }
		            else {
		                s1 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c17);
		                }
		            }
		            if (s1 !== peg$FAILED) {
		                peg$reportedPos = s0;
		                s1 = peg$c18();
		            }
		            s0 = s1;
		            return s0;
		        }
		        function peg$parsechildRef() {
		            var s0, s1, s2;
		            s0 = peg$currPos;
		            s1 = [];
		            if (peg$c20.test(input.charAt(peg$currPos))) {
		                s2 = input.charAt(peg$currPos);
		                peg$currPos++;
		            }
		            else {
		                s2 = peg$FAILED;
		                if (peg$silentFails === 0) {
		                    peg$fail(peg$c21);
		                }
		            }
		            if (s2 !== peg$FAILED) {
		                while (s2 !== peg$FAILED) {
		                    s1.push(s2);
		                    if (peg$c20.test(input.charAt(peg$currPos))) {
		                        s2 = input.charAt(peg$currPos);
		                        peg$currPos++;
		                    }
		                    else {
		                        s2 = peg$FAILED;
		                        if (peg$silentFails === 0) {
		                            peg$fail(peg$c21);
		                        }
		                    }
		                }
		            }
		            else {
		                s1 = peg$c0;
		            }
		            if (s1 !== peg$FAILED) {
		                peg$reportedPos = s0;
		                s1 = peg$c22(s1);
		            }
		            s0 = s1;
		            return s0;
		        }
		        peg$result = peg$startRuleFunction();
		        if (peg$result !== peg$FAILED && peg$currPos === input.length) {
		            return peg$result;
		        }
		        else {
		            if (peg$result !== peg$FAILED && peg$currPos < input.length) {
		                peg$fail({ type: "end", description: "end of input" });
		            }
		            throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
		        }
		    }
		    return {
		        SyntaxError: SyntaxError,
		        parse: parse
		    };
		})();
		module.exports = mod;


	/***/ },
	/* 128 */
	/***/ function(module, exports, __webpack_require__) {

		var hlimpl = __webpack_require__(5);
		var universes = __webpack_require__(54);
		var ramlServices = __webpack_require__(49);
		var linter = __webpack_require__(55);
		var xmlutil = __webpack_require__(57);
		var exampleGen = __webpack_require__(129);
		function createExamples(typeDefinition) {
		    var declaringNode = typeDefinition.getAdapter(ramlServices.RAMLService).getDeclaringNode();
		    if (declaringNode == null) {
		        return [new EmptyExpandableExample()];
		    }
		    var exampleAttribute = declaringNode.attr(universes.Universe10.TypeDeclaration.properties.example.name);
		    if (exampleAttribute != null) {
		        return [new ExpandableExampleImpl(exampleAttribute)];
		    }
		    var exampleSpecs = declaringNode.elementsOfKind(universes.Universe10.TypeDeclaration.properties.examples.name);
		    if (exampleSpecs != null && exampleSpecs.length > 0) {
		        var result = [];
		        exampleSpecs.forEach(function (spec) {
		            result.push(createExampleFromSpec(spec));
		        });
		        return result;
		    }
		    return [new EmptyExpandableExample(typeDefinition)];
		}
		exports.createExamples = createExamples;
		function createExampleFromSpec(exampleSpecNode) {
		    var contentAttribute = exampleSpecNode.attr(universes.Universe10.ExampleSpec.properties.content.name);
		    if (contentAttribute == null) {
		        return new EmptyExpandableExample();
		    }
		    return new ExpandableExampleImpl(contentAttribute);
		}
		exports.createExampleFromSpec = createExampleFromSpec;
		/**
		 * Default implementation of example.
		 */
		var ExpandableExampleImpl = (function () {
		    function ExpandableExampleImpl(attribute) {
		        this._built = false;
		        this._isEmpty = true;
		        this._isJSONString = false;
		        this._isXMLString = false;
		        this._isYAML = false;
		        this._stringRepresentation = null;
		        this._jsonRepresentation = null;
		        this.attribute = attribute;
		    }
		    /**
		     * Returns true if the application in question does not have an example set directly.
		     * It is still possible that while application has no direct example, references may have
		     * example pieces, current example may be expanded with.
		     */
		    ExpandableExampleImpl.prototype.isEmpty = function () {
		        this.buildIfNeeded();
		        return this._isEmpty;
		    };
		    /**
		     * Whether the original example is JSON string.
		     */
		    ExpandableExampleImpl.prototype.isJSONString = function () {
		        this.buildIfNeeded();
		        return this._isJSONString;
		    };
		    /**
		     * Whether the original example is XML string.
		     */
		    ExpandableExampleImpl.prototype.isXMLString = function () {
		        this.buildIfNeeded();
		        return this._isXMLString;
		    };
		    /**
		     * Whether original example is set up as YAML.
		     */
		    ExpandableExampleImpl.prototype.isYAML = function () {
		        this.buildIfNeeded();
		        return this._isYAML;
		    };
		    /**
		     * Returns representation of this example as a string.
		     * This method works for any type of example.
		     */
		    ExpandableExampleImpl.prototype.asString = function () {
		        this.buildIfNeeded();
		        return this._stringRepresentation;
		    };
		    /**
		     * Returns representation of this example as JSON object.
		     * This works for examples being JSON strings and YAML objects.
		     * It -may- work for XML string examples, but is not guaranteed.
		     */
		    ExpandableExampleImpl.prototype.asJSON = function () {
		        this.buildIfNeeded();
		        return this._jsonRepresentation;
		    };
		    /**
		     * Returns an original example. It is string for XML and JSON strings,
		     * or JSON object for YAML example.
		     */
		    ExpandableExampleImpl.prototype.original = function () {
		        this.buildIfNeeded();
		        return this.internalExampleContent();
		    };
		    /**
		     * Expands the example with what its application references can provide.
		     * Returns null or expansion result as string. XML examples are not supported.
		     */
		    ExpandableExampleImpl.prototype.expandAsString = function () {
		        var expandedJSON = this.expandAsJSON();
		        if (expandedJSON == null)
		            return null;
		        return JSON.stringify(expandedJSON, null, 2);
		    };
		    /**
		     * Expands the example with what its application references can provide.
		     * Returns null or expansion result as JSON object. XML examples are not supported.
		     */
		    ExpandableExampleImpl.prototype.expandAsJSON = function () {
		        this.buildIfNeeded();
		        var typeDefinition = this.getTypeDefinition();
		        if (typeDefinition == null)
		            return null;
		        var runtimeType = typeDefinition.getAdapter(ramlServices.RAMLService).toRuntime();
		        if (runtimeType == null)
		            return null;
		        return exampleGen.createExampleObjectFromTypeDefinition(runtimeType);
		    };
		    ExpandableExampleImpl.prototype.buildIfNeeded = function () {
		        if (!this._built) {
		            this._built = true;
		            this.build();
		        }
		    };
		    ExpandableExampleImpl.prototype.build = function () {
		        var exampleContent = this.internalExampleContent();
		        //determining example kind
		        if (exampleContent == null) {
		            this._isEmpty = true;
		            return;
		        }
		        this._isEmpty = false;
		        if (typeof exampleContent === "string") {
		            this._isJSONString = this.testExampleJson(exampleContent);
		            if (!this._isJSONString) {
		                this._isXMLString = this.testExampleXML(exampleContent);
		            }
		        }
		        else {
		            this._isYAML = true;
		        }
		        //setting string representation for string type
		        if (typeof exampleContent === "string") {
		            this._stringRepresentation = exampleContent;
		        }
		        //setting json representation
		        if (this._isJSONString) {
		            try {
		                this._jsonRepresentation = JSON.parse(exampleContent);
		            }
		            catch (Error) {
		            }
		        }
		        else if (this._isYAML) {
		            this._jsonRepresentation = new linter.ExampleValidator().parseObject(this.attribute, {
		                begin: function () {
		                },
		                end: function () {
		                },
		                accept: function (e) {
		                }
		            }, false);
		        }
		        //string representation for YAML samples
		        if (this._isYAML && this._jsonRepresentation != null) {
		            this._stringRepresentation = JSON.stringify(this._jsonRepresentation, null, 2);
		        }
		    };
		    /**
		     * Gets sample contents from declaring node.
		     * Returns either a string, json object for YAML, or null
		     */
		    ExpandableExampleImpl.prototype.internalExampleContent = function () {
		        if (this.attribute == null) {
		            return null;
		        }
		        var value = this.attribute.value();
		        if (value == null) {
		            return null;
		        }
		        if (typeof value === "string") {
		            return value;
		        }
		        else if (value instanceof hlimpl.StructuredValue) {
		            var dumped = value.lowLevel().dumpToObject(true);
		            //TODO check how valid those checks got from linter are
		            //these ones are probably caused by the upper attribute name, and thus additional check for attribute name is required
		            if (dumped["example"]) {
		                return dumped["example"];
		            }
		            if (dumped["content"]) {
		                return dumped["content"];
		            }
		            return dumped;
		        }
		        //failed to recognize
		        return null;
		    };
		    ExpandableExampleImpl.prototype.testExampleJson = function (content) {
		        var mediaType = linter.getMediaType(this.attribute);
		        if (mediaType != null) {
		            return linter.isJson(mediaType);
		        }
		        try {
		            JSON.parse(content);
		            return true;
		        }
		        catch (e) {
		            return false;
		        }
		    };
		    ExpandableExampleImpl.prototype.testExampleXML = function (content) {
		        var mediaType = linter.getMediaType(this.attribute);
		        if (mediaType != null) {
		            return linter.isXML(mediaType);
		        }
		        //no media type found, testing by parsing
		        if (content.trim().indexOf("<") == -1) {
		            return false;
		        }
		        try {
		            xmlutil(content);
		            return true;
		        }
		        catch (e) {
		            return false;
		        }
		    };
		    ExpandableExampleImpl.prototype.getTypeDefinition = function () {
		        var parent = this.attribute.parent();
		        if (parent == null) {
		            return null;
		        }
		        if (parent.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		            return parent.definition().getAdapter(ramlServices.RAMLService).toRuntime();
		        }
		        var parentsParent = parent.parent();
		        if (parentsParent == null) {
		            return null;
		        }
		        if (parentsParent.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
		            return parentsParent.definition().getAdapter(ramlServices.RAMLService).toRuntime();
		        }
		        return null;
		    };
		    return ExpandableExampleImpl;
		})();
		exports.ExpandableExampleImpl = ExpandableExampleImpl;
		var EmptyExpandableExample = (function () {
		    function EmptyExpandableExample(typeDefinition) {
		        this.typeDefinition = typeDefinition;
		        var k = 0;
		        k++;
		    }
		    EmptyExpandableExample.prototype.isEmpty = function () {
		        return true;
		    };
		    EmptyExpandableExample.prototype.isJSONString = function () {
		        return false;
		    };
		    EmptyExpandableExample.prototype.isXMLString = function () {
		        return false;
		    };
		    EmptyExpandableExample.prototype.isYAML = function () {
		        return false;
		    };
		    EmptyExpandableExample.prototype.asString = function () {
		        return "";
		    };
		    EmptyExpandableExample.prototype.asJSON = function () {
		        return null;
		    };
		    EmptyExpandableExample.prototype.original = function () {
		        return null;
		    };
		    EmptyExpandableExample.prototype.expandAsString = function () {
		        var expandedJSON = this.expandAsJSON();
		        if (expandedJSON == null)
		            return null;
		        return JSON.stringify(expandedJSON, null, 2);
		    };
		    EmptyExpandableExample.prototype.expandAsJSON = function () {
		        if (this.typeDefinition == null)
		            return null;
		        return exampleGen.createExampleObjectFromTypeDefinition(this.typeDefinition);
		    };
		    return EmptyExpandableExample;
		})();
		exports.EmptyExpandableExample = EmptyExpandableExample;


	/***/ },
	/* 129 */
	/***/ function(module, exports, __webpack_require__) {

		var defs = __webpack_require__(3);
		var wrapperHelper = __webpack_require__(65);
		var services = __webpack_require__(49);
		var linter = __webpack_require__(55);
		function createExampleObject(w, generateFakeExamples) {
		    if (generateFakeExamples === void 0) { generateFakeExamples = false; }
		    var tp = wrapperHelper.resolveType(w);
		    return createExampleObjectFromTypeDefinition(tp, generateFakeExamples);
		}
		exports.createExampleObject = createExampleObject;
		function createExampleObjectFromTypeDefinition(tp, generateFakeExamples) {
		    if (generateFakeExamples === void 0) { generateFakeExamples = false; }
		    if (tp instanceof defs.NodeClass) {
		        var nc = tp;
		        var node = nc.getAdapter(services.RAMLService).getDeclaringNode();
		        if (node) {
		            var e = node.attr("example");
		            if (e) {
		                return new linter.ExampleValidator().parseObject(e, {
		                    begin: function () {
		                    },
		                    end: function () {
		                    },
		                    accept: function (e) {
		                    }
		                }, false);
		            }
		            else {
		                var em = node.elementsOfKind("examples");
		                if (em.length > 0) {
		                    var result = null;
		                    em.forEach(function (x) {
		                        var cnt = x.attr("content");
		                        if (cnt) {
		                            result = new linter.ExampleValidator().parseObject(cnt, {
		                                begin: function () {
		                                },
		                                end: function () {
		                                },
		                                accept: function (e) {
		                                }
		                            }, false);
		                        }
		                    });
		                    if (result) {
		                        return mergeSuperTypes(result, tp);
		                    }
		                }
		            }
		        }
		    }
		    if (tp.hasArrayInHierarchy()) {
		        var arr = tp;
		        var res = [];
		        var cm = arr.componentType();
		        if (cm) {
		            res.push(createExampleObjectFromTypeDefinition(cm));
		        }
		        return res;
		    }
		    else if (tp.hasUnionInHierarchy()) {
		        var ut = tp;
		        if (ut.leftType()) {
		            if (ut.leftType().getAdapter(services.RAMLService).isUserDefined()) {
		                return createExampleObjectFromTypeDefinition(ut.leftType());
		            }
		        }
		        if (ut.rightType()) {
		            if (ut.rightType().getAdapter(services.RAMLService).isUserDefined()) {
		                return createExampleObjectFromTypeDefinition(ut.rightType());
		            }
		        }
		    }
		    else if (tp.hasValueTypeInHierarchy() && generateFakeExamples) {
		        var original = tp.getAdapter(services.RAMLService).getRepresentationOf();
		        var exString = "some value " + tp.nameId();
		        if (original) {
		            var supers = original.allSuperTypes();
		            supers.forEach(function (x) {
		                if (!x.getAdapter(services.RAMLService).isUserDefined() && x.nameId() == "NumberTypeDeclaration") {
		                    exString = 1;
		                }
		                if (!x.getAdapter(services.RAMLService).isUserDefined() && x.nameId() == "BooleanTypeDeclaration") {
		                    exString = true;
		                }
		                if (!x.getAdapter(services.RAMLService).isUserDefined() && x.nameId() == "IntegerTypeDeclaration") {
		                    exString = 1;
		                }
		            });
		        }
		        return exString;
		    }
		    else {
		        var obj = {};
		        tp.allProperties().forEach(function (x) {
		            obj[x.nameId()] = exampleObject(x);
		        });
		        return mergeSuperTypes(obj, tp);
		    }
		}
		exports.createExampleObjectFromTypeDefinition = createExampleObjectFromTypeDefinition;
		/**
		 * Merges parent example (not its properties example) into the specified example.
		 * @param exampleToMergeTo - modifies the argument!
		 * @param type
		 * @return modified example
		 */
		function mergeSuperTypes(exampleToMergeTo, type) {
		    type.superTypes().forEach(function (superType) {
		        var superTypeExample = createExampleObjectFromTypeDefinition(superType);
		        if (superTypeExample) {
		            Object.keys(superTypeExample).forEach(function (parentProperty) {
		                var propertyValue = exampleToMergeTo[parentProperty];
		                if (!propertyValue || (typeof propertyValue === 'object' && Object.keys(propertyValue).length == 0)) {
		                    exampleToMergeTo[parentProperty] = superTypeExample[parentProperty];
		                }
		            });
		        }
		    });
		    return exampleToMergeTo;
		}
		function exampleObject(x) {
		    var vl = x.defaultValue();
		    if (vl) {
		        return vl;
		    }
		    var res = x.range();
		    if (res) {
		        return createExampleObjectFromTypeDefinition(res);
		    }
		}


	/***/ }
	/******/ ]);

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;//     Underscore.js 1.8.3
	//     http://underscorejs.org
	//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Underscore may be freely distributed under the MIT license.

	(function() {

	  // Baseline setup
	  // --------------

	  // Establish the root object, `window` in the browser, or `exports` on the server.
	  var root = this;

	  // Save the previous value of the `_` variable.
	  var previousUnderscore = root._;

	  // Save bytes in the minified (but not gzipped) version:
	  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;

	  // Create quick reference variables for speed access to core prototypes.
	  var
	    push             = ArrayProto.push,
	    slice            = ArrayProto.slice,
	    toString         = ObjProto.toString,
	    hasOwnProperty   = ObjProto.hasOwnProperty;

	  // All **ECMAScript 5** native function implementations that we hope to use
	  // are declared here.
	  var
	    nativeIsArray      = Array.isArray,
	    nativeKeys         = Object.keys,
	    nativeBind         = FuncProto.bind,
	    nativeCreate       = Object.create;

	  // Naked function reference for surrogate-prototype-swapping.
	  var Ctor = function(){};

	  // Create a safe reference to the Underscore object for use below.
	  var _ = function(obj) {
	    if (obj instanceof _) return obj;
	    if (!(this instanceof _)) return new _(obj);
	    this._wrapped = obj;
	  };

	  // Export the Underscore object for **Node.js**, with
	  // backwards-compatibility for the old `require()` API. If we're in
	  // the browser, add `_` as a global object.
	  if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	      exports = module.exports = _;
	    }
	    exports._ = _;
	  } else {
	    root._ = _;
	  }

	  // Current version.
	  _.VERSION = '1.8.3';

	  // Internal function that returns an efficient (for current engines) version
	  // of the passed-in callback, to be repeatedly applied in other Underscore
	  // functions.
	  var optimizeCb = function(func, context, argCount) {
	    if (context === void 0) return func;
	    switch (argCount == null ? 3 : argCount) {
	      case 1: return function(value) {
	        return func.call(context, value);
	      };
	      case 2: return function(value, other) {
	        return func.call(context, value, other);
	      };
	      case 3: return function(value, index, collection) {
	        return func.call(context, value, index, collection);
	      };
	      case 4: return function(accumulator, value, index, collection) {
	        return func.call(context, accumulator, value, index, collection);
	      };
	    }
	    return function() {
	      return func.apply(context, arguments);
	    };
	  };

	  // A mostly-internal function to generate callbacks that can be applied
	  // to each element in a collection, returning the desired result — either
	  // identity, an arbitrary callback, a property matcher, or a property accessor.
	  var cb = function(value, context, argCount) {
	    if (value == null) return _.identity;
	    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
	    if (_.isObject(value)) return _.matcher(value);
	    return _.property(value);
	  };
	  _.iteratee = function(value, context) {
	    return cb(value, context, Infinity);
	  };

	  // An internal function for creating assigner functions.
	  var createAssigner = function(keysFunc, undefinedOnly) {
	    return function(obj) {
	      var length = arguments.length;
	      if (length < 2 || obj == null) return obj;
	      for (var index = 1; index < length; index++) {
	        var source = arguments[index],
	            keys = keysFunc(source),
	            l = keys.length;
	        for (var i = 0; i < l; i++) {
	          var key = keys[i];
	          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
	        }
	      }
	      return obj;
	    };
	  };

	  // An internal function for creating a new object that inherits from another.
	  var baseCreate = function(prototype) {
	    if (!_.isObject(prototype)) return {};
	    if (nativeCreate) return nativeCreate(prototype);
	    Ctor.prototype = prototype;
	    var result = new Ctor;
	    Ctor.prototype = null;
	    return result;
	  };

	  var property = function(key) {
	    return function(obj) {
	      return obj == null ? void 0 : obj[key];
	    };
	  };

	  // Helper for collection methods to determine whether a collection
	  // should be iterated as an array or as an object
	  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
	  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
	  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
	  var getLength = property('length');
	  var isArrayLike = function(collection) {
	    var length = getLength(collection);
	    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
	  };

	  // Collection Functions
	  // --------------------

	  // The cornerstone, an `each` implementation, aka `forEach`.
	  // Handles raw objects in addition to array-likes. Treats all
	  // sparse array-likes as if they were dense.
	  _.each = _.forEach = function(obj, iteratee, context) {
	    iteratee = optimizeCb(iteratee, context);
	    var i, length;
	    if (isArrayLike(obj)) {
	      for (i = 0, length = obj.length; i < length; i++) {
	        iteratee(obj[i], i, obj);
	      }
	    } else {
	      var keys = _.keys(obj);
	      for (i = 0, length = keys.length; i < length; i++) {
	        iteratee(obj[keys[i]], keys[i], obj);
	      }
	    }
	    return obj;
	  };

	  // Return the results of applying the iteratee to each element.
	  _.map = _.collect = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length,
	        results = Array(length);
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      results[index] = iteratee(obj[currentKey], currentKey, obj);
	    }
	    return results;
	  };

	  // Create a reducing function iterating left or right.
	  function createReduce(dir) {
	    // Optimized iterator function as using arguments.length
	    // in the main function will deoptimize the, see #1991.
	    function iterator(obj, iteratee, memo, keys, index, length) {
	      for (; index >= 0 && index < length; index += dir) {
	        var currentKey = keys ? keys[index] : index;
	        memo = iteratee(memo, obj[currentKey], currentKey, obj);
	      }
	      return memo;
	    }

	    return function(obj, iteratee, memo, context) {
	      iteratee = optimizeCb(iteratee, context, 4);
	      var keys = !isArrayLike(obj) && _.keys(obj),
	          length = (keys || obj).length,
	          index = dir > 0 ? 0 : length - 1;
	      // Determine the initial value if none is provided.
	      if (arguments.length < 3) {
	        memo = obj[keys ? keys[index] : index];
	        index += dir;
	      }
	      return iterator(obj, iteratee, memo, keys, index, length);
	    };
	  }

	  // **Reduce** builds up a single result from a list of values, aka `inject`,
	  // or `foldl`.
	  _.reduce = _.foldl = _.inject = createReduce(1);

	  // The right-associative version of reduce, also known as `foldr`.
	  _.reduceRight = _.foldr = createReduce(-1);

	  // Return the first value which passes a truth test. Aliased as `detect`.
	  _.find = _.detect = function(obj, predicate, context) {
	    var key;
	    if (isArrayLike(obj)) {
	      key = _.findIndex(obj, predicate, context);
	    } else {
	      key = _.findKey(obj, predicate, context);
	    }
	    if (key !== void 0 && key !== -1) return obj[key];
	  };

	  // Return all the elements that pass a truth test.
	  // Aliased as `select`.
	  _.filter = _.select = function(obj, predicate, context) {
	    var results = [];
	    predicate = cb(predicate, context);
	    _.each(obj, function(value, index, list) {
	      if (predicate(value, index, list)) results.push(value);
	    });
	    return results;
	  };

	  // Return all the elements for which a truth test fails.
	  _.reject = function(obj, predicate, context) {
	    return _.filter(obj, _.negate(cb(predicate)), context);
	  };

	  // Determine whether all of the elements match a truth test.
	  // Aliased as `all`.
	  _.every = _.all = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (!predicate(obj[currentKey], currentKey, obj)) return false;
	    }
	    return true;
	  };

	  // Determine if at least one element in the object matches a truth test.
	  // Aliased as `any`.
	  _.some = _.any = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (predicate(obj[currentKey], currentKey, obj)) return true;
	    }
	    return false;
	  };

	  // Determine if the array or object contains a given item (using `===`).
	  // Aliased as `includes` and `include`.
	  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
	    if (!isArrayLike(obj)) obj = _.values(obj);
	    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
	    return _.indexOf(obj, item, fromIndex) >= 0;
	  };

	  // Invoke a method (with arguments) on every item in a collection.
	  _.invoke = function(obj, method) {
	    var args = slice.call(arguments, 2);
	    var isFunc = _.isFunction(method);
	    return _.map(obj, function(value) {
	      var func = isFunc ? method : value[method];
	      return func == null ? func : func.apply(value, args);
	    });
	  };

	  // Convenience version of a common use case of `map`: fetching a property.
	  _.pluck = function(obj, key) {
	    return _.map(obj, _.property(key));
	  };

	  // Convenience version of a common use case of `filter`: selecting only objects
	  // containing specific `key:value` pairs.
	  _.where = function(obj, attrs) {
	    return _.filter(obj, _.matcher(attrs));
	  };

	  // Convenience version of a common use case of `find`: getting the first object
	  // containing specific `key:value` pairs.
	  _.findWhere = function(obj, attrs) {
	    return _.find(obj, _.matcher(attrs));
	  };

	  // Return the maximum element (or element-based computation).
	  _.max = function(obj, iteratee, context) {
	    var result = -Infinity, lastComputed = -Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value > result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };

	  // Return the minimum element (or element-based computation).
	  _.min = function(obj, iteratee, context) {
	    var result = Infinity, lastComputed = Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value < result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed < lastComputed || computed === Infinity && result === Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };

	  // Shuffle a collection, using the modern version of the
	  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
	  _.shuffle = function(obj) {
	    var set = isArrayLike(obj) ? obj : _.values(obj);
	    var length = set.length;
	    var shuffled = Array(length);
	    for (var index = 0, rand; index < length; index++) {
	      rand = _.random(0, index);
	      if (rand !== index) shuffled[index] = shuffled[rand];
	      shuffled[rand] = set[index];
	    }
	    return shuffled;
	  };

	  // Sample **n** random values from a collection.
	  // If **n** is not specified, returns a single random element.
	  // The internal `guard` argument allows it to work with `map`.
	  _.sample = function(obj, n, guard) {
	    if (n == null || guard) {
	      if (!isArrayLike(obj)) obj = _.values(obj);
	      return obj[_.random(obj.length - 1)];
	    }
	    return _.shuffle(obj).slice(0, Math.max(0, n));
	  };

	  // Sort the object's values by a criterion produced by an iteratee.
	  _.sortBy = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    return _.pluck(_.map(obj, function(value, index, list) {
	      return {
	        value: value,
	        index: index,
	        criteria: iteratee(value, index, list)
	      };
	    }).sort(function(left, right) {
	      var a = left.criteria;
	      var b = right.criteria;
	      if (a !== b) {
	        if (a > b || a === void 0) return 1;
	        if (a < b || b === void 0) return -1;
	      }
	      return left.index - right.index;
	    }), 'value');
	  };

	  // An internal function used for aggregate "group by" operations.
	  var group = function(behavior) {
	    return function(obj, iteratee, context) {
	      var result = {};
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index) {
	        var key = iteratee(value, index, obj);
	        behavior(result, value, key);
	      });
	      return result;
	    };
	  };

	  // Groups the object's values by a criterion. Pass either a string attribute
	  // to group by, or a function that returns the criterion.
	  _.groupBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key].push(value); else result[key] = [value];
	  });

	  // Indexes the object's values by a criterion, similar to `groupBy`, but for
	  // when you know that your index values will be unique.
	  _.indexBy = group(function(result, value, key) {
	    result[key] = value;
	  });

	  // Counts instances of an object that group by a certain criterion. Pass
	  // either a string attribute to count by, or a function that returns the
	  // criterion.
	  _.countBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key]++; else result[key] = 1;
	  });

	  // Safely create a real, live array from anything iterable.
	  _.toArray = function(obj) {
	    if (!obj) return [];
	    if (_.isArray(obj)) return slice.call(obj);
	    if (isArrayLike(obj)) return _.map(obj, _.identity);
	    return _.values(obj);
	  };

	  // Return the number of elements in an object.
	  _.size = function(obj) {
	    if (obj == null) return 0;
	    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
	  };

	  // Split a collection into two arrays: one whose elements all satisfy the given
	  // predicate, and one whose elements all do not satisfy the predicate.
	  _.partition = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var pass = [], fail = [];
	    _.each(obj, function(value, key, obj) {
	      (predicate(value, key, obj) ? pass : fail).push(value);
	    });
	    return [pass, fail];
	  };

	  // Array Functions
	  // ---------------

	  // Get the first element of an array. Passing **n** will return the first N
	  // values in the array. Aliased as `head` and `take`. The **guard** check
	  // allows it to work with `_.map`.
	  _.first = _.head = _.take = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[0];
	    return _.initial(array, array.length - n);
	  };

	  // Returns everything but the last entry of the array. Especially useful on
	  // the arguments object. Passing **n** will return all the values in
	  // the array, excluding the last N.
	  _.initial = function(array, n, guard) {
	    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
	  };

	  // Get the last element of an array. Passing **n** will return the last N
	  // values in the array.
	  _.last = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[array.length - 1];
	    return _.rest(array, Math.max(0, array.length - n));
	  };

	  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
	  // Especially useful on the arguments object. Passing an **n** will return
	  // the rest N values in the array.
	  _.rest = _.tail = _.drop = function(array, n, guard) {
	    return slice.call(array, n == null || guard ? 1 : n);
	  };

	  // Trim out all falsy values from an array.
	  _.compact = function(array) {
	    return _.filter(array, _.identity);
	  };

	  // Internal implementation of a recursive `flatten` function.
	  var flatten = function(input, shallow, strict, startIndex) {
	    var output = [], idx = 0;
	    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
	      var value = input[i];
	      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
	        //flatten current level of array or arguments object
	        if (!shallow) value = flatten(value, shallow, strict);
	        var j = 0, len = value.length;
	        output.length += len;
	        while (j < len) {
	          output[idx++] = value[j++];
	        }
	      } else if (!strict) {
	        output[idx++] = value;
	      }
	    }
	    return output;
	  };

	  // Flatten out an array, either recursively (by default), or just one level.
	  _.flatten = function(array, shallow) {
	    return flatten(array, shallow, false);
	  };

	  // Return a version of the array that does not contain the specified value(s).
	  _.without = function(array) {
	    return _.difference(array, slice.call(arguments, 1));
	  };

	  // Produce a duplicate-free version of the array. If the array has already
	  // been sorted, you have the option of using a faster algorithm.
	  // Aliased as `unique`.
	  _.uniq = _.unique = function(array, isSorted, iteratee, context) {
	    if (!_.isBoolean(isSorted)) {
	      context = iteratee;
	      iteratee = isSorted;
	      isSorted = false;
	    }
	    if (iteratee != null) iteratee = cb(iteratee, context);
	    var result = [];
	    var seen = [];
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var value = array[i],
	          computed = iteratee ? iteratee(value, i, array) : value;
	      if (isSorted) {
	        if (!i || seen !== computed) result.push(value);
	        seen = computed;
	      } else if (iteratee) {
	        if (!_.contains(seen, computed)) {
	          seen.push(computed);
	          result.push(value);
	        }
	      } else if (!_.contains(result, value)) {
	        result.push(value);
	      }
	    }
	    return result;
	  };

	  // Produce an array that contains the union: each distinct element from all of
	  // the passed-in arrays.
	  _.union = function() {
	    return _.uniq(flatten(arguments, true, true));
	  };

	  // Produce an array that contains every item shared between all the
	  // passed-in arrays.
	  _.intersection = function(array) {
	    var result = [];
	    var argsLength = arguments.length;
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var item = array[i];
	      if (_.contains(result, item)) continue;
	      for (var j = 1; j < argsLength; j++) {
	        if (!_.contains(arguments[j], item)) break;
	      }
	      if (j === argsLength) result.push(item);
	    }
	    return result;
	  };

	  // Take the difference between one array and a number of other arrays.
	  // Only the elements present in just the first array will remain.
	  _.difference = function(array) {
	    var rest = flatten(arguments, true, true, 1);
	    return _.filter(array, function(value){
	      return !_.contains(rest, value);
	    });
	  };

	  // Zip together multiple lists into a single array -- elements that share
	  // an index go together.
	  _.zip = function() {
	    return _.unzip(arguments);
	  };

	  // Complement of _.zip. Unzip accepts an array of arrays and groups
	  // each array's elements on shared indices
	  _.unzip = function(array) {
	    var length = array && _.max(array, getLength).length || 0;
	    var result = Array(length);

	    for (var index = 0; index < length; index++) {
	      result[index] = _.pluck(array, index);
	    }
	    return result;
	  };

	  // Converts lists into objects. Pass either a single array of `[key, value]`
	  // pairs, or two parallel arrays of the same length -- one of keys, and one of
	  // the corresponding values.
	  _.object = function(list, values) {
	    var result = {};
	    for (var i = 0, length = getLength(list); i < length; i++) {
	      if (values) {
	        result[list[i]] = values[i];
	      } else {
	        result[list[i][0]] = list[i][1];
	      }
	    }
	    return result;
	  };

	  // Generator function to create the findIndex and findLastIndex functions
	  function createPredicateIndexFinder(dir) {
	    return function(array, predicate, context) {
	      predicate = cb(predicate, context);
	      var length = getLength(array);
	      var index = dir > 0 ? 0 : length - 1;
	      for (; index >= 0 && index < length; index += dir) {
	        if (predicate(array[index], index, array)) return index;
	      }
	      return -1;
	    };
	  }

	  // Returns the first index on an array-like that passes a predicate test
	  _.findIndex = createPredicateIndexFinder(1);
	  _.findLastIndex = createPredicateIndexFinder(-1);

	  // Use a comparator function to figure out the smallest index at which
	  // an object should be inserted so as to maintain order. Uses binary search.
	  _.sortedIndex = function(array, obj, iteratee, context) {
	    iteratee = cb(iteratee, context, 1);
	    var value = iteratee(obj);
	    var low = 0, high = getLength(array);
	    while (low < high) {
	      var mid = Math.floor((low + high) / 2);
	      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
	    }
	    return low;
	  };

	  // Generator function to create the indexOf and lastIndexOf functions
	  function createIndexFinder(dir, predicateFind, sortedIndex) {
	    return function(array, item, idx) {
	      var i = 0, length = getLength(array);
	      if (typeof idx == 'number') {
	        if (dir > 0) {
	            i = idx >= 0 ? idx : Math.max(idx + length, i);
	        } else {
	            length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
	        }
	      } else if (sortedIndex && idx && length) {
	        idx = sortedIndex(array, item);
	        return array[idx] === item ? idx : -1;
	      }
	      if (item !== item) {
	        idx = predicateFind(slice.call(array, i, length), _.isNaN);
	        return idx >= 0 ? idx + i : -1;
	      }
	      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
	        if (array[idx] === item) return idx;
	      }
	      return -1;
	    };
	  }

	  // Return the position of the first occurrence of an item in an array,
	  // or -1 if the item is not included in the array.
	  // If the array is large and already in sort order, pass `true`
	  // for **isSorted** to use binary search.
	  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
	  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);

	  // Generate an integer Array containing an arithmetic progression. A port of
	  // the native Python `range()` function. See
	  // [the Python documentation](http://docs.python.org/library/functions.html#range).
	  _.range = function(start, stop, step) {
	    if (stop == null) {
	      stop = start || 0;
	      start = 0;
	    }
	    step = step || 1;

	    var length = Math.max(Math.ceil((stop - start) / step), 0);
	    var range = Array(length);

	    for (var idx = 0; idx < length; idx++, start += step) {
	      range[idx] = start;
	    }

	    return range;
	  };

	  // Function (ahem) Functions
	  // ------------------

	  // Determines whether to execute a function as a constructor
	  // or a normal function with the provided arguments
	  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
	    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
	    var self = baseCreate(sourceFunc.prototype);
	    var result = sourceFunc.apply(self, args);
	    if (_.isObject(result)) return result;
	    return self;
	  };

	  // Create a function bound to a given object (assigning `this`, and arguments,
	  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
	  // available.
	  _.bind = function(func, context) {
	    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
	    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
	    var args = slice.call(arguments, 2);
	    var bound = function() {
	      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
	    };
	    return bound;
	  };

	  // Partially apply a function by creating a version that has had some of its
	  // arguments pre-filled, without changing its dynamic `this` context. _ acts
	  // as a placeholder, allowing any combination of arguments to be pre-filled.
	  _.partial = function(func) {
	    var boundArgs = slice.call(arguments, 1);
	    var bound = function() {
	      var position = 0, length = boundArgs.length;
	      var args = Array(length);
	      for (var i = 0; i < length; i++) {
	        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
	      }
	      while (position < arguments.length) args.push(arguments[position++]);
	      return executeBound(func, bound, this, this, args);
	    };
	    return bound;
	  };

	  // Bind a number of an object's methods to that object. Remaining arguments
	  // are the method names to be bound. Useful for ensuring that all callbacks
	  // defined on an object belong to it.
	  _.bindAll = function(obj) {
	    var i, length = arguments.length, key;
	    if (length <= 1) throw new Error('bindAll must be passed function names');
	    for (i = 1; i < length; i++) {
	      key = arguments[i];
	      obj[key] = _.bind(obj[key], obj);
	    }
	    return obj;
	  };

	  // Memoize an expensive function by storing its results.
	  _.memoize = function(func, hasher) {
	    var memoize = function(key) {
	      var cache = memoize.cache;
	      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
	      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
	      return cache[address];
	    };
	    memoize.cache = {};
	    return memoize;
	  };

	  // Delays a function for the given number of milliseconds, and then calls
	  // it with the arguments supplied.
	  _.delay = function(func, wait) {
	    var args = slice.call(arguments, 2);
	    return setTimeout(function(){
	      return func.apply(null, args);
	    }, wait);
	  };

	  // Defers a function, scheduling it to run after the current call stack has
	  // cleared.
	  _.defer = _.partial(_.delay, _, 1);

	  // Returns a function, that, when invoked, will only be triggered at most once
	  // during a given window of time. Normally, the throttled function will run
	  // as much as it can, without ever going more than once per `wait` duration;
	  // but if you'd like to disable the execution on the leading edge, pass
	  // `{leading: false}`. To disable execution on the trailing edge, ditto.
	  _.throttle = function(func, wait, options) {
	    var context, args, result;
	    var timeout = null;
	    var previous = 0;
	    if (!options) options = {};
	    var later = function() {
	      previous = options.leading === false ? 0 : _.now();
	      timeout = null;
	      result = func.apply(context, args);
	      if (!timeout) context = args = null;
	    };
	    return function() {
	      var now = _.now();
	      if (!previous && options.leading === false) previous = now;
	      var remaining = wait - (now - previous);
	      context = this;
	      args = arguments;
	      if (remaining <= 0 || remaining > wait) {
	        if (timeout) {
	          clearTimeout(timeout);
	          timeout = null;
	        }
	        previous = now;
	        result = func.apply(context, args);
	        if (!timeout) context = args = null;
	      } else if (!timeout && options.trailing !== false) {
	        timeout = setTimeout(later, remaining);
	      }
	      return result;
	    };
	  };

	  // Returns a function, that, as long as it continues to be invoked, will not
	  // be triggered. The function will be called after it stops being called for
	  // N milliseconds. If `immediate` is passed, trigger the function on the
	  // leading edge, instead of the trailing.
	  _.debounce = function(func, wait, immediate) {
	    var timeout, args, context, timestamp, result;

	    var later = function() {
	      var last = _.now() - timestamp;

	      if (last < wait && last >= 0) {
	        timeout = setTimeout(later, wait - last);
	      } else {
	        timeout = null;
	        if (!immediate) {
	          result = func.apply(context, args);
	          if (!timeout) context = args = null;
	        }
	      }
	    };

	    return function() {
	      context = this;
	      args = arguments;
	      timestamp = _.now();
	      var callNow = immediate && !timeout;
	      if (!timeout) timeout = setTimeout(later, wait);
	      if (callNow) {
	        result = func.apply(context, args);
	        context = args = null;
	      }

	      return result;
	    };
	  };

	  // Returns the first function passed as an argument to the second,
	  // allowing you to adjust arguments, run code before and after, and
	  // conditionally execute the original function.
	  _.wrap = function(func, wrapper) {
	    return _.partial(wrapper, func);
	  };

	  // Returns a negated version of the passed-in predicate.
	  _.negate = function(predicate) {
	    return function() {
	      return !predicate.apply(this, arguments);
	    };
	  };

	  // Returns a function that is the composition of a list of functions, each
	  // consuming the return value of the function that follows.
	  _.compose = function() {
	    var args = arguments;
	    var start = args.length - 1;
	    return function() {
	      var i = start;
	      var result = args[start].apply(this, arguments);
	      while (i--) result = args[i].call(this, result);
	      return result;
	    };
	  };

	  // Returns a function that will only be executed on and after the Nth call.
	  _.after = function(times, func) {
	    return function() {
	      if (--times < 1) {
	        return func.apply(this, arguments);
	      }
	    };
	  };

	  // Returns a function that will only be executed up to (but not including) the Nth call.
	  _.before = function(times, func) {
	    var memo;
	    return function() {
	      if (--times > 0) {
	        memo = func.apply(this, arguments);
	      }
	      if (times <= 1) func = null;
	      return memo;
	    };
	  };

	  // Returns a function that will be executed at most one time, no matter how
	  // often you call it. Useful for lazy initialization.
	  _.once = _.partial(_.before, 2);

	  // Object Functions
	  // ----------------

	  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
	  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
	  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
	                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

	  function collectNonEnumProps(obj, keys) {
	    var nonEnumIdx = nonEnumerableProps.length;
	    var constructor = obj.constructor;
	    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;

	    // Constructor is a special case.
	    var prop = 'constructor';
	    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);

	    while (nonEnumIdx--) {
	      prop = nonEnumerableProps[nonEnumIdx];
	      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
	        keys.push(prop);
	      }
	    }
	  }

	  // Retrieve the names of an object's own properties.
	  // Delegates to **ECMAScript 5**'s native `Object.keys`
	  _.keys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    if (nativeKeys) return nativeKeys(obj);
	    var keys = [];
	    for (var key in obj) if (_.has(obj, key)) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };

	  // Retrieve all the property names of an object.
	  _.allKeys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    var keys = [];
	    for (var key in obj) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };

	  // Retrieve the values of an object's properties.
	  _.values = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var values = Array(length);
	    for (var i = 0; i < length; i++) {
	      values[i] = obj[keys[i]];
	    }
	    return values;
	  };

	  // Returns the results of applying the iteratee to each element of the object
	  // In contrast to _.map it returns an object
	  _.mapObject = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys =  _.keys(obj),
	          length = keys.length,
	          results = {},
	          currentKey;
	      for (var index = 0; index < length; index++) {
	        currentKey = keys[index];
	        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
	      }
	      return results;
	  };

	  // Convert an object into a list of `[key, value]` pairs.
	  _.pairs = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var pairs = Array(length);
	    for (var i = 0; i < length; i++) {
	      pairs[i] = [keys[i], obj[keys[i]]];
	    }
	    return pairs;
	  };

	  // Invert the keys and values of an object. The values must be serializable.
	  _.invert = function(obj) {
	    var result = {};
	    var keys = _.keys(obj);
	    for (var i = 0, length = keys.length; i < length; i++) {
	      result[obj[keys[i]]] = keys[i];
	    }
	    return result;
	  };

	  // Return a sorted list of the function names available on the object.
	  // Aliased as `methods`
	  _.functions = _.methods = function(obj) {
	    var names = [];
	    for (var key in obj) {
	      if (_.isFunction(obj[key])) names.push(key);
	    }
	    return names.sort();
	  };

	  // Extend a given object with all the properties in passed-in object(s).
	  _.extend = createAssigner(_.allKeys);

	  // Assigns a given object with all the own properties in the passed-in object(s)
	  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
	  _.extendOwn = _.assign = createAssigner(_.keys);

	  // Returns the first key on an object that passes a predicate test
	  _.findKey = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = _.keys(obj), key;
	    for (var i = 0, length = keys.length; i < length; i++) {
	      key = keys[i];
	      if (predicate(obj[key], key, obj)) return key;
	    }
	  };

	  // Return a copy of the object only containing the whitelisted properties.
	  _.pick = function(object, oiteratee, context) {
	    var result = {}, obj = object, iteratee, keys;
	    if (obj == null) return result;
	    if (_.isFunction(oiteratee)) {
	      keys = _.allKeys(obj);
	      iteratee = optimizeCb(oiteratee, context);
	    } else {
	      keys = flatten(arguments, false, false, 1);
	      iteratee = function(value, key, obj) { return key in obj; };
	      obj = Object(obj);
	    }
	    for (var i = 0, length = keys.length; i < length; i++) {
	      var key = keys[i];
	      var value = obj[key];
	      if (iteratee(value, key, obj)) result[key] = value;
	    }
	    return result;
	  };

	   // Return a copy of the object without the blacklisted properties.
	  _.omit = function(obj, iteratee, context) {
	    if (_.isFunction(iteratee)) {
	      iteratee = _.negate(iteratee);
	    } else {
	      var keys = _.map(flatten(arguments, false, false, 1), String);
	      iteratee = function(value, key) {
	        return !_.contains(keys, key);
	      };
	    }
	    return _.pick(obj, iteratee, context);
	  };

	  // Fill in a given object with default properties.
	  _.defaults = createAssigner(_.allKeys, true);

	  // Creates an object that inherits from the given prototype object.
	  // If additional properties are provided then they will be added to the
	  // created object.
	  _.create = function(prototype, props) {
	    var result = baseCreate(prototype);
	    if (props) _.extendOwn(result, props);
	    return result;
	  };

	  // Create a (shallow-cloned) duplicate of an object.
	  _.clone = function(obj) {
	    if (!_.isObject(obj)) return obj;
	    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
	  };

	  // Invokes interceptor with the obj, and then returns obj.
	  // The primary purpose of this method is to "tap into" a method chain, in
	  // order to perform operations on intermediate results within the chain.
	  _.tap = function(obj, interceptor) {
	    interceptor(obj);
	    return obj;
	  };

	  // Returns whether an object has a given set of `key:value` pairs.
	  _.isMatch = function(object, attrs) {
	    var keys = _.keys(attrs), length = keys.length;
	    if (object == null) return !length;
	    var obj = Object(object);
	    for (var i = 0; i < length; i++) {
	      var key = keys[i];
	      if (attrs[key] !== obj[key] || !(key in obj)) return false;
	    }
	    return true;
	  };


	  // Internal recursive comparison function for `isEqual`.
	  var eq = function(a, b, aStack, bStack) {
	    // Identical objects are equal. `0 === -0`, but they aren't identical.
	    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
	    if (a === b) return a !== 0 || 1 / a === 1 / b;
	    // A strict comparison is necessary because `null == undefined`.
	    if (a == null || b == null) return a === b;
	    // Unwrap any wrapped objects.
	    if (a instanceof _) a = a._wrapped;
	    if (b instanceof _) b = b._wrapped;
	    // Compare `[[Class]]` names.
	    var className = toString.call(a);
	    if (className !== toString.call(b)) return false;
	    switch (className) {
	      // Strings, numbers, regular expressions, dates, and booleans are compared by value.
	      case '[object RegExp]':
	      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
	      case '[object String]':
	        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
	        // equivalent to `new String("5")`.
	        return '' + a === '' + b;
	      case '[object Number]':
	        // `NaN`s are equivalent, but non-reflexive.
	        // Object(NaN) is equivalent to NaN
	        if (+a !== +a) return +b !== +b;
	        // An `egal` comparison is performed for other numeric values.
	        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
	      case '[object Date]':
	      case '[object Boolean]':
	        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
	        // millisecond representations. Note that invalid dates with millisecond representations
	        // of `NaN` are not equivalent.
	        return +a === +b;
	    }

	    var areArrays = className === '[object Array]';
	    if (!areArrays) {
	      if (typeof a != 'object' || typeof b != 'object') return false;

	      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
	      // from different frames are.
	      var aCtor = a.constructor, bCtor = b.constructor;
	      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
	                               _.isFunction(bCtor) && bCtor instanceof bCtor)
	                          && ('constructor' in a && 'constructor' in b)) {
	        return false;
	      }
	    }
	    // Assume equality for cyclic structures. The algorithm for detecting cyclic
	    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.

	    // Initializing stack of traversed objects.
	    // It's done here since we only need them for objects and arrays comparison.
	    aStack = aStack || [];
	    bStack = bStack || [];
	    var length = aStack.length;
	    while (length--) {
	      // Linear search. Performance is inversely proportional to the number of
	      // unique nested structures.
	      if (aStack[length] === a) return bStack[length] === b;
	    }

	    // Add the first object to the stack of traversed objects.
	    aStack.push(a);
	    bStack.push(b);

	    // Recursively compare objects and arrays.
	    if (areArrays) {
	      // Compare array lengths to determine if a deep comparison is necessary.
	      length = a.length;
	      if (length !== b.length) return false;
	      // Deep compare the contents, ignoring non-numeric properties.
	      while (length--) {
	        if (!eq(a[length], b[length], aStack, bStack)) return false;
	      }
	    } else {
	      // Deep compare objects.
	      var keys = _.keys(a), key;
	      length = keys.length;
	      // Ensure that both objects contain the same number of properties before comparing deep equality.
	      if (_.keys(b).length !== length) return false;
	      while (length--) {
	        // Deep compare each member
	        key = keys[length];
	        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
	      }
	    }
	    // Remove the first object from the stack of traversed objects.
	    aStack.pop();
	    bStack.pop();
	    return true;
	  };

	  // Perform a deep comparison to check if two objects are equal.
	  _.isEqual = function(a, b) {
	    return eq(a, b);
	  };

	  // Is a given array, string, or object empty?
	  // An "empty" object has no enumerable own-properties.
	  _.isEmpty = function(obj) {
	    if (obj == null) return true;
	    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
	    return _.keys(obj).length === 0;
	  };

	  // Is a given value a DOM element?
	  _.isElement = function(obj) {
	    return !!(obj && obj.nodeType === 1);
	  };

	  // Is a given value an array?
	  // Delegates to ECMA5's native Array.isArray
	  _.isArray = nativeIsArray || function(obj) {
	    return toString.call(obj) === '[object Array]';
	  };

	  // Is a given variable an object?
	  _.isObject = function(obj) {
	    var type = typeof obj;
	    return type === 'function' || type === 'object' && !!obj;
	  };

	  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
	  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
	    _['is' + name] = function(obj) {
	      return toString.call(obj) === '[object ' + name + ']';
	    };
	  });

	  // Define a fallback version of the method in browsers (ahem, IE < 9), where
	  // there isn't any inspectable "Arguments" type.
	  if (!_.isArguments(arguments)) {
	    _.isArguments = function(obj) {
	      return _.has(obj, 'callee');
	    };
	  }

	  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
	  // IE 11 (#1621), and in Safari 8 (#1929).
	  if (typeof /./ != 'function' && typeof Int8Array != 'object') {
	    _.isFunction = function(obj) {
	      return typeof obj == 'function' || false;
	    };
	  }

	  // Is a given object a finite number?
	  _.isFinite = function(obj) {
	    return isFinite(obj) && !isNaN(parseFloat(obj));
	  };

	  // Is the given value `NaN`? (NaN is the only number which does not equal itself).
	  _.isNaN = function(obj) {
	    return _.isNumber(obj) && obj !== +obj;
	  };

	  // Is a given value a boolean?
	  _.isBoolean = function(obj) {
	    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
	  };

	  // Is a given value equal to null?
	  _.isNull = function(obj) {
	    return obj === null;
	  };

	  // Is a given variable undefined?
	  _.isUndefined = function(obj) {
	    return obj === void 0;
	  };

	  // Shortcut function for checking if an object has a given property directly
	  // on itself (in other words, not on a prototype).
	  _.has = function(obj, key) {
	    return obj != null && hasOwnProperty.call(obj, key);
	  };

	  // Utility Functions
	  // -----------------

	  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
	  // previous owner. Returns a reference to the Underscore object.
	  _.noConflict = function() {
	    root._ = previousUnderscore;
	    return this;
	  };

	  // Keep the identity function around for default iteratees.
	  _.identity = function(value) {
	    return value;
	  };

	  // Predicate-generating functions. Often useful outside of Underscore.
	  _.constant = function(value) {
	    return function() {
	      return value;
	    };
	  };

	  _.noop = function(){};

	  _.property = property;

	  // Generates a function for a given object that returns a given property.
	  _.propertyOf = function(obj) {
	    return obj == null ? function(){} : function(key) {
	      return obj[key];
	    };
	  };

	  // Returns a predicate for checking whether an object has a given set of
	  // `key:value` pairs.
	  _.matcher = _.matches = function(attrs) {
	    attrs = _.extendOwn({}, attrs);
	    return function(obj) {
	      return _.isMatch(obj, attrs);
	    };
	  };

	  // Run a function **n** times.
	  _.times = function(n, iteratee, context) {
	    var accum = Array(Math.max(0, n));
	    iteratee = optimizeCb(iteratee, context, 1);
	    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
	    return accum;
	  };

	  // Return a random integer between min and max (inclusive).
	  _.random = function(min, max) {
	    if (max == null) {
	      max = min;
	      min = 0;
	    }
	    return min + Math.floor(Math.random() * (max - min + 1));
	  };

	  // A (possibly faster) way to get the current timestamp as an integer.
	  _.now = Date.now || function() {
	    return new Date().getTime();
	  };

	   // List of HTML entities for escaping.
	  var escapeMap = {
	    '&': '&amp;',
	    '<': '&lt;',
	    '>': '&gt;',
	    '"': '&quot;',
	    "'": '&#x27;',
	    '`': '&#x60;'
	  };
	  var unescapeMap = _.invert(escapeMap);

	  // Functions for escaping and unescaping strings to/from HTML interpolation.
	  var createEscaper = function(map) {
	    var escaper = function(match) {
	      return map[match];
	    };
	    // Regexes for identifying a key that needs to be escaped
	    var source = '(?:' + _.keys(map).join('|') + ')';
	    var testRegexp = RegExp(source);
	    var replaceRegexp = RegExp(source, 'g');
	    return function(string) {
	      string = string == null ? '' : '' + string;
	      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
	    };
	  };
	  _.escape = createEscaper(escapeMap);
	  _.unescape = createEscaper(unescapeMap);

	  // If the value of the named `property` is a function then invoke it with the
	  // `object` as context; otherwise, return it.
	  _.result = function(object, property, fallback) {
	    var value = object == null ? void 0 : object[property];
	    if (value === void 0) {
	      value = fallback;
	    }
	    return _.isFunction(value) ? value.call(object) : value;
	  };

	  // Generate a unique integer id (unique within the entire client session).
	  // Useful for temporary DOM ids.
	  var idCounter = 0;
	  _.uniqueId = function(prefix) {
	    var id = ++idCounter + '';
	    return prefix ? prefix + id : id;
	  };

	  // By default, Underscore uses ERB-style template delimiters, change the
	  // following template settings to use alternative delimiters.
	  _.templateSettings = {
	    evaluate    : /<%([\s\S]+?)%>/g,
	    interpolate : /<%=([\s\S]+?)%>/g,
	    escape      : /<%-([\s\S]+?)%>/g
	  };

	  // When customizing `templateSettings`, if you don't want to define an
	  // interpolation, evaluation or escaping regex, we need one that is
	  // guaranteed not to match.
	  var noMatch = /(.)^/;

	  // Certain characters need to be escaped so that they can be put into a
	  // string literal.
	  var escapes = {
	    "'":      "'",
	    '\\':     '\\',
	    '\r':     'r',
	    '\n':     'n',
	    '\u2028': 'u2028',
	    '\u2029': 'u2029'
	  };

	  var escaper = /\\|'|\r|\n|\u2028|\u2029/g;

	  var escapeChar = function(match) {
	    return '\\' + escapes[match];
	  };

	  // JavaScript micro-templating, similar to John Resig's implementation.
	  // Underscore templating handles arbitrary delimiters, preserves whitespace,
	  // and correctly escapes quotes within interpolated code.
	  // NB: `oldSettings` only exists for backwards compatibility.
	  _.template = function(text, settings, oldSettings) {
	    if (!settings && oldSettings) settings = oldSettings;
	    settings = _.defaults({}, settings, _.templateSettings);

	    // Combine delimiters into one regular expression via alternation.
	    var matcher = RegExp([
	      (settings.escape || noMatch).source,
	      (settings.interpolate || noMatch).source,
	      (settings.evaluate || noMatch).source
	    ].join('|') + '|$', 'g');

	    // Compile the template source, escaping string literals appropriately.
	    var index = 0;
	    var source = "__p+='";
	    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
	      source += text.slice(index, offset).replace(escaper, escapeChar);
	      index = offset + match.length;

	      if (escape) {
	        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
	      } else if (interpolate) {
	        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
	      } else if (evaluate) {
	        source += "';\n" + evaluate + "\n__p+='";
	      }

	      // Adobe VMs need the match returned to produce the correct offest.
	      return match;
	    });
	    source += "';\n";

	    // If a variable is not specified, place data values in local scope.
	    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

	    source = "var __t,__p='',__j=Array.prototype.join," +
	      "print=function(){__p+=__j.call(arguments,'');};\n" +
	      source + 'return __p;\n';

	    try {
	      var render = new Function(settings.variable || 'obj', '_', source);
	    } catch (e) {
	      e.source = source;
	      throw e;
	    }

	    var template = function(data) {
	      return render.call(this, data, _);
	    };

	    // Provide the compiled source as a convenience for precompilation.
	    var argument = settings.variable || 'obj';
	    template.source = 'function(' + argument + '){\n' + source + '}';

	    return template;
	  };

	  // Add a "chain" function. Start chaining a wrapped Underscore object.
	  _.chain = function(obj) {
	    var instance = _(obj);
	    instance._chain = true;
	    return instance;
	  };

	  // OOP
	  // ---------------
	  // If Underscore is called as a function, it returns a wrapped object that
	  // can be used OO-style. This wrapper holds altered versions of all the
	  // underscore functions. Wrapped objects may be chained.

	  // Helper function to continue chaining intermediate results.
	  var result = function(instance, obj) {
	    return instance._chain ? _(obj).chain() : obj;
	  };

	  // Add your own custom functions to the Underscore object.
	  _.mixin = function(obj) {
	    _.each(_.functions(obj), function(name) {
	      var func = _[name] = obj[name];
	      _.prototype[name] = function() {
	        var args = [this._wrapped];
	        push.apply(args, arguments);
	        return result(this, func.apply(_, args));
	      };
	    });
	  };

	  // Add all of the Underscore functions to the wrapper object.
	  _.mixin(_);

	  // Add all mutator Array functions to the wrapper.
	  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      var obj = this._wrapped;
	      method.apply(obj, arguments);
	      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
	      return result(this, obj);
	    };
	  });

	  // Add all accessor Array functions to the wrapper.
	  _.each(['concat', 'join', 'slice'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      return result(this, method.apply(this._wrapped, arguments));
	    };
	  });

	  // Extracts the result from a wrapped and chained object.
	  _.prototype.value = function() {
	    return this._wrapped;
	  };

	  // Provide unwrapping proxy for some methods used in engine operations
	  // such as arithmetic and JSON stringification.
	  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;

	  _.prototype.toString = function() {
	    return '' + this._wrapped;
	  };

	  // AMD registration happens at the end for compatibility with AMD loaders
	  // that may not enforce next-turn semantics on modules. Even though general
	  // practice for AMD registration is to be anonymous, underscore registers
	  // as a named module because, like jQuery, it is a base library that is
	  // popular enough to be bundled in a third party lib, but not be part of
	  // an AMD load request. Those cases could generate an error when an
	  // anonymous define() is called outside of a loader request.
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	}.call(this));


/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// resolves . and .. elements in a path array with directory names there
	// must be no slashes, empty elements, or device names (c:\) in the array
	// (so also no leading and trailing slashes - it does not distinguish
	// relative and absolute paths)
	function normalizeArray(parts, allowAboveRoot) {
	  // if the path tries to go above the root, `up` ends up > 0
	  var up = 0;
	  for (var i = parts.length - 1; i >= 0; i--) {
	    var last = parts[i];
	    if (last === '.') {
	      parts.splice(i, 1);
	    } else if (last === '..') {
	      parts.splice(i, 1);
	      up++;
	    } else if (up) {
	      parts.splice(i, 1);
	      up--;
	    }
	  }

	  // if the path is allowed to go above the root, restore leading ..s
	  if (allowAboveRoot) {
	    for (; up--; up) {
	      parts.unshift('..');
	    }
	  }

	  return parts;
	}

	// Split a filename into [root, dir, basename, ext], unix version
	// 'root' is just a slash, or nothing.
	var splitPathRe =
	    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
	var splitPath = function(filename) {
	  return splitPathRe.exec(filename).slice(1);
	};

	// path.resolve([from ...], to)
	// posix version
	exports.resolve = function() {
	  var resolvedPath = '',
	      resolvedAbsolute = false;

	  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
	    var path = (i >= 0) ? arguments[i] : process.cwd();

	    // Skip empty and invalid entries
	    if (typeof path !== 'string') {
	      throw new TypeError('Arguments to path.resolve must be strings');
	    } else if (!path) {
	      continue;
	    }

	    resolvedPath = path + '/' + resolvedPath;
	    resolvedAbsolute = path.charAt(0) === '/';
	  }

	  // At this point the path should be resolved to a full absolute path, but
	  // handle relative paths to be safe (might happen when process.cwd() fails)

	  // Normalize the path
	  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
	    return !!p;
	  }), !resolvedAbsolute).join('/');

	  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
	};

	// path.normalize(path)
	// posix version
	exports.normalize = function(path) {
	  var isAbsolute = exports.isAbsolute(path),
	      trailingSlash = substr(path, -1) === '/';

	  // Normalize the path
	  path = normalizeArray(filter(path.split('/'), function(p) {
	    return !!p;
	  }), !isAbsolute).join('/');

	  if (!path && !isAbsolute) {
	    path = '.';
	  }
	  if (path && trailingSlash) {
	    path += '/';
	  }

	  return (isAbsolute ? '/' : '') + path;
	};

	// posix version
	exports.isAbsolute = function(path) {
	  return path.charAt(0) === '/';
	};

	// posix version
	exports.join = function() {
	  var paths = Array.prototype.slice.call(arguments, 0);
	  return exports.normalize(filter(paths, function(p, index) {
	    if (typeof p !== 'string') {
	      throw new TypeError('Arguments to path.join must be strings');
	    }
	    return p;
	  }).join('/'));
	};


	// path.relative(from, to)
	// posix version
	exports.relative = function(from, to) {
	  from = exports.resolve(from).substr(1);
	  to = exports.resolve(to).substr(1);

	  function trim(arr) {
	    var start = 0;
	    for (; start < arr.length; start++) {
	      if (arr[start] !== '') break;
	    }

	    var end = arr.length - 1;
	    for (; end >= 0; end--) {
	      if (arr[end] !== '') break;
	    }

	    if (start > end) return [];
	    return arr.slice(start, end - start + 1);
	  }

	  var fromParts = trim(from.split('/'));
	  var toParts = trim(to.split('/'));

	  var length = Math.min(fromParts.length, toParts.length);
	  var samePartsLength = length;
	  for (var i = 0; i < length; i++) {
	    if (fromParts[i] !== toParts[i]) {
	      samePartsLength = i;
	      break;
	    }
	  }

	  var outputParts = [];
	  for (var i = samePartsLength; i < fromParts.length; i++) {
	    outputParts.push('..');
	  }

	  outputParts = outputParts.concat(toParts.slice(samePartsLength));

	  return outputParts.join('/');
	};

	exports.sep = '/';
	exports.delimiter = ':';

	exports.dirname = function(path) {
	  var result = splitPath(path),
	      root = result[0],
	      dir = result[1];

	  if (!root && !dir) {
	    // No dirname whatsoever
	    return '.';
	  }

	  if (dir) {
	    // It has a dirname, strip trailing slash
	    dir = dir.substr(0, dir.length - 1);
	  }

	  return root + dir;
	};


	exports.basename = function(path, ext) {
	  var f = splitPath(path)[2];
	  // TODO: make this comparison case-insensitive on windows?
	  if (ext && f.substr(-1 * ext.length) === ext) {
	    f = f.substr(0, f.length - ext.length);
	  }
	  return f;
	};


	exports.extname = function(path) {
	  return splitPath(path)[3];
	};

	function filter (xs, f) {
	    if (xs.filter) return xs.filter(f);
	    var res = [];
	    for (var i = 0; i < xs.length; i++) {
	        if (f(xs[i], i, xs)) res.push(xs[i]);
	    }
	    return res;
	}

	// String.prototype.substr - negative index don't work in IE8
	var substr = 'ab'.substr(-1) === 'b'
	    ? function (str, start, len) { return str.substr(start, len) }
	    : function (str, start, len) {
	        if (start < 0) start = str.length + start;
	        return str.substr(start, len);
	    }
	;

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 3 */
/***/ function(module, exports) {

	// shim for using process in browser

	var process = module.exports = {};
	var queue = [];
	var draining = false;
	var currentQueue;
	var queueIndex = -1;

	function cleanUpNextTick() {
	    draining = false;
	    if (currentQueue.length) {
	        queue = currentQueue.concat(queue);
	    } else {
	        queueIndex = -1;
	    }
	    if (queue.length) {
	        drainQueue();
	    }
	}

	function drainQueue() {
	    if (draining) {
	        return;
	    }
	    var timeout = setTimeout(cleanUpNextTick);
	    draining = true;

	    var len = queue.length;
	    while(len) {
	        currentQueue = queue;
	        queue = [];
	        while (++queueIndex < len) {
	            if (currentQueue) {
	                currentQueue[queueIndex].run();
	            }
	        }
	        queueIndex = -1;
	        len = queue.length;
	    }
	    currentQueue = null;
	    draining = false;
	    clearTimeout(timeout);
	}

	process.nextTick = function (fun) {
	    var args = new Array(arguments.length - 1);
	    if (arguments.length > 1) {
	        for (var i = 1; i < arguments.length; i++) {
	            args[i - 1] = arguments[i];
	        }
	    }
	    queue.push(new Item(fun, args));
	    if (queue.length === 1 && !draining) {
	        setTimeout(drainQueue, 0);
	    }
	};

	// v8 likes predictible objects
	function Item(fun, array) {
	    this.fun = fun;
	    this.array = array;
	}
	Item.prototype.run = function () {
	    this.fun.apply(null, this.array);
	};
	process.title = 'browser';
	process.browser = true;
	process.env = {};
	process.argv = [];
	process.version = ''; // empty string to avoid regexp issues
	process.versions = {};

	function noop() {}

	process.on = noop;
	process.addListener = noop;
	process.once = noop;
	process.off = noop;
	process.removeListener = noop;
	process.removeAllListeners = noop;
	process.emit = noop;

	process.binding = function (name) {
	    throw new Error('process.binding is not supported');
	};

	process.cwd = function () { return '/' };
	process.chdir = function (dir) {
	    throw new Error('process.chdir is not supported');
	};
	process.umask = function() { return 0; };


/***/ },
/* 4 */
/***/ function(module, exports) {

	/* (ignored) */

/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(Buffer, global) {/*!
	 * The buffer module from node.js, for the browser.
	 *
	 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
	 * @license  MIT
	 */
	/* eslint-disable no-proto */

	var base64 = __webpack_require__(6)
	var ieee754 = __webpack_require__(7)
	var isArray = __webpack_require__(8)

	exports.Buffer = Buffer
	exports.SlowBuffer = SlowBuffer
	exports.INSPECT_MAX_BYTES = 50
	Buffer.poolSize = 8192 // not used by this implementation

	var rootParent = {}

	/**
	 * If `Buffer.TYPED_ARRAY_SUPPORT`:
	 *   === true    Use Uint8Array implementation (fastest)
	 *   === false   Use Object implementation (most compatible, even IE6)
	 *
	 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
	 * Opera 11.6+, iOS 4.2+.
	 *
	 * Due to various browser bugs, sometimes the Object implementation will be used even
	 * when the browser supports typed arrays.
	 *
	 * Note:
	 *
	 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
	 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
	 *
	 *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
	 *     on objects.
	 *
	 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
	 *
	 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
	 *     incorrect length in some situations.

	 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
	 * get the Object implementation, which is slower but behaves correctly.
	 */
	Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
	  ? global.TYPED_ARRAY_SUPPORT
	  : typedArraySupport()

	function typedArraySupport () {
	  function Bar () {}
	  try {
	    var arr = new Uint8Array(1)
	    arr.foo = function () { return 42 }
	    arr.constructor = Bar
	    return arr.foo() === 42 && // typed array instances can be augmented
	        arr.constructor === Bar && // constructor can be set
	        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
	        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
	  } catch (e) {
	    return false
	  }
	}

	function kMaxLength () {
	  return Buffer.TYPED_ARRAY_SUPPORT
	    ? 0x7fffffff
	    : 0x3fffffff
	}

	/**
	 * Class: Buffer
	 * =============
	 *
	 * The Buffer constructor returns instances of `Uint8Array` that are augmented
	 * with function properties for all the node `Buffer` API functions. We use
	 * `Uint8Array` so that square bracket notation works as expected -- it returns
	 * a single octet.
	 *
	 * By augmenting the instances, we can avoid modifying the `Uint8Array`
	 * prototype.
	 */
	function Buffer (arg) {
	  if (!(this instanceof Buffer)) {
	    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
	    if (arguments.length > 1) return new Buffer(arg, arguments[1])
	    return new Buffer(arg)
	  }

	  this.length = 0
	  this.parent = undefined

	  // Common case.
	  if (typeof arg === 'number') {
	    return fromNumber(this, arg)
	  }

	  // Slightly less common case.
	  if (typeof arg === 'string') {
	    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
	  }

	  // Unusual.
	  return fromObject(this, arg)
	}

	function fromNumber (that, length) {
	  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) {
	    for (var i = 0; i < length; i++) {
	      that[i] = 0
	    }
	  }
	  return that
	}

	function fromString (that, string, encoding) {
	  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'

	  // Assumption: byteLength() return value is always < kMaxLength.
	  var length = byteLength(string, encoding) | 0
	  that = allocate(that, length)

	  that.write(string, encoding)
	  return that
	}

	function fromObject (that, object) {
	  if (Buffer.isBuffer(object)) return fromBuffer(that, object)

	  if (isArray(object)) return fromArray(that, object)

	  if (object == null) {
	    throw new TypeError('must start with number, buffer, array or string')
	  }

	  if (typeof ArrayBuffer !== 'undefined') {
	    if (object.buffer instanceof ArrayBuffer) {
	      return fromTypedArray(that, object)
	    }
	    if (object instanceof ArrayBuffer) {
	      return fromArrayBuffer(that, object)
	    }
	  }

	  if (object.length) return fromArrayLike(that, object)

	  return fromJsonObject(that, object)
	}

	function fromBuffer (that, buffer) {
	  var length = checked(buffer.length) | 0
	  that = allocate(that, length)
	  buffer.copy(that, 0, 0, length)
	  return that
	}

	function fromArray (that, array) {
	  var length = checked(array.length) | 0
	  that = allocate(that, length)
	  for (var i = 0; i < length; i += 1) {
	    that[i] = array[i] & 255
	  }
	  return that
	}

	// Duplicate of fromArray() to keep fromArray() monomorphic.
	function fromTypedArray (that, array) {
	  var length = checked(array.length) | 0
	  that = allocate(that, length)
	  // Truncating the elements is probably not what people expect from typed
	  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
	  // of the old Buffer constructor.
	  for (var i = 0; i < length; i += 1) {
	    that[i] = array[i] & 255
	  }
	  return that
	}

	function fromArrayBuffer (that, array) {
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    // Return an augmented `Uint8Array` instance, for best performance
	    array.byteLength
	    that = Buffer._augment(new Uint8Array(array))
	  } else {
	    // Fallback: Return an object instance of the Buffer class
	    that = fromTypedArray(that, new Uint8Array(array))
	  }
	  return that
	}

	function fromArrayLike (that, array) {
	  var length = checked(array.length) | 0
	  that = allocate(that, length)
	  for (var i = 0; i < length; i += 1) {
	    that[i] = array[i] & 255
	  }
	  return that
	}

	// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
	// Returns a zero-length buffer for inputs that don't conform to the spec.
	function fromJsonObject (that, object) {
	  var array
	  var length = 0

	  if (object.type === 'Buffer' && isArray(object.data)) {
	    array = object.data
	    length = checked(array.length) | 0
	  }
	  that = allocate(that, length)

	  for (var i = 0; i < length; i += 1) {
	    that[i] = array[i] & 255
	  }
	  return that
	}

	if (Buffer.TYPED_ARRAY_SUPPORT) {
	  Buffer.prototype.__proto__ = Uint8Array.prototype
	  Buffer.__proto__ = Uint8Array
	}

	function allocate (that, length) {
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    // Return an augmented `Uint8Array` instance, for best performance
	    that = Buffer._augment(new Uint8Array(length))
	    that.__proto__ = Buffer.prototype
	  } else {
	    // Fallback: Return an object instance of the Buffer class
	    that.length = length
	    that._isBuffer = true
	  }

	  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
	  if (fromPool) that.parent = rootParent

	  return that
	}

	function checked (length) {
	  // Note: cannot use `length < kMaxLength` here because that fails when
	  // length is NaN (which is otherwise coerced to zero.)
	  if (length >= kMaxLength()) {
	    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
	                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
	  }
	  return length | 0
	}

	function SlowBuffer (subject, encoding) {
	  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)

	  var buf = new Buffer(subject, encoding)
	  delete buf.parent
	  return buf
	}

	Buffer.isBuffer = function isBuffer (b) {
	  return !!(b != null && b._isBuffer)
	}

	Buffer.compare = function compare (a, b) {
	  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
	    throw new TypeError('Arguments must be Buffers')
	  }

	  if (a === b) return 0

	  var x = a.length
	  var y = b.length

	  var i = 0
	  var len = Math.min(x, y)
	  while (i < len) {
	    if (a[i] !== b[i]) break

	    ++i
	  }

	  if (i !== len) {
	    x = a[i]
	    y = b[i]
	  }

	  if (x < y) return -1
	  if (y < x) return 1
	  return 0
	}

	Buffer.isEncoding = function isEncoding (encoding) {
	  switch (String(encoding).toLowerCase()) {
	    case 'hex':
	    case 'utf8':
	    case 'utf-8':
	    case 'ascii':
	    case 'binary':
	    case 'base64':
	    case 'raw':
	    case 'ucs2':
	    case 'ucs-2':
	    case 'utf16le':
	    case 'utf-16le':
	      return true
	    default:
	      return false
	  }
	}

	Buffer.concat = function concat (list, length) {
	  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')

	  if (list.length === 0) {
	    return new Buffer(0)
	  }

	  var i
	  if (length === undefined) {
	    length = 0
	    for (i = 0; i < list.length; i++) {
	      length += list[i].length
	    }
	  }

	  var buf = new Buffer(length)
	  var pos = 0
	  for (i = 0; i < list.length; i++) {
	    var item = list[i]
	    item.copy(buf, pos)
	    pos += item.length
	  }
	  return buf
	}

	function byteLength (string, encoding) {
	  if (typeof string !== 'string') string = '' + string

	  var len = string.length
	  if (len === 0) return 0

	  // Use a for loop to avoid recursion
	  var loweredCase = false
	  for (;;) {
	    switch (encoding) {
	      case 'ascii':
	      case 'binary':
	      // Deprecated
	      case 'raw':
	      case 'raws':
	        return len
	      case 'utf8':
	      case 'utf-8':
	        return utf8ToBytes(string).length
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return len * 2
	      case 'hex':
	        return len >>> 1
	      case 'base64':
	        return base64ToBytes(string).length
	      default:
	        if (loweredCase) return utf8ToBytes(string).length // assume utf8
	        encoding = ('' + encoding).toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	Buffer.byteLength = byteLength

	// pre-set for values that may exist in the future
	Buffer.prototype.length = undefined
	Buffer.prototype.parent = undefined

	function slowToString (encoding, start, end) {
	  var loweredCase = false

	  start = start | 0
	  end = end === undefined || end === Infinity ? this.length : end | 0

	  if (!encoding) encoding = 'utf8'
	  if (start < 0) start = 0
	  if (end > this.length) end = this.length
	  if (end <= start) return ''

	  while (true) {
	    switch (encoding) {
	      case 'hex':
	        return hexSlice(this, start, end)

	      case 'utf8':
	      case 'utf-8':
	        return utf8Slice(this, start, end)

	      case 'ascii':
	        return asciiSlice(this, start, end)

	      case 'binary':
	        return binarySlice(this, start, end)

	      case 'base64':
	        return base64Slice(this, start, end)

	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return utf16leSlice(this, start, end)

	      default:
	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
	        encoding = (encoding + '').toLowerCase()
	        loweredCase = true
	    }
	  }
	}

	Buffer.prototype.toString = function toString () {
	  var length = this.length | 0
	  if (length === 0) return ''
	  if (arguments.length === 0) return utf8Slice(this, 0, length)
	  return slowToString.apply(this, arguments)
	}

	Buffer.prototype.equals = function equals (b) {
	  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
	  if (this === b) return true
	  return Buffer.compare(this, b) === 0
	}

	Buffer.prototype.inspect = function inspect () {
	  var str = ''
	  var max = exports.INSPECT_MAX_BYTES
	  if (this.length > 0) {
	    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
	    if (this.length > max) str += ' ... '
	  }
	  return '<Buffer ' + str + '>'
	}

	Buffer.prototype.compare = function compare (b) {
	  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
	  if (this === b) return 0
	  return Buffer.compare(this, b)
	}

	Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
	  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
	  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
	  byteOffset >>= 0

	  if (this.length === 0) return -1
	  if (byteOffset >= this.length) return -1

	  // Negative offsets start from the end of the buffer
	  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)

	  if (typeof val === 'string') {
	    if (val.length === 0) return -1 // special case: looking for empty string always fails
	    return String.prototype.indexOf.call(this, val, byteOffset)
	  }
	  if (Buffer.isBuffer(val)) {
	    return arrayIndexOf(this, val, byteOffset)
	  }
	  if (typeof val === 'number') {
	    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
	      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
	    }
	    return arrayIndexOf(this, [ val ], byteOffset)
	  }

	  function arrayIndexOf (arr, val, byteOffset) {
	    var foundIndex = -1
	    for (var i = 0; byteOffset + i < arr.length; i++) {
	      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
	        if (foundIndex === -1) foundIndex = i
	        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
	      } else {
	        foundIndex = -1
	      }
	    }
	    return -1
	  }

	  throw new TypeError('val must be string, number or Buffer')
	}

	// `get` is deprecated
	Buffer.prototype.get = function get (offset) {
	  console.log('.get() is deprecated. Access using array indexes instead.')
	  return this.readUInt8(offset)
	}

	// `set` is deprecated
	Buffer.prototype.set = function set (v, offset) {
	  console.log('.set() is deprecated. Access using array indexes instead.')
	  return this.writeUInt8(v, offset)
	}

	function hexWrite (buf, string, offset, length) {
	  offset = Number(offset) || 0
	  var remaining = buf.length - offset
	  if (!length) {
	    length = remaining
	  } else {
	    length = Number(length)
	    if (length > remaining) {
	      length = remaining
	    }
	  }

	  // must be an even number of digits
	  var strLen = string.length
	  if (strLen % 2 !== 0) throw new Error('Invalid hex string')

	  if (length > strLen / 2) {
	    length = strLen / 2
	  }
	  for (var i = 0; i < length; i++) {
	    var parsed = parseInt(string.substr(i * 2, 2), 16)
	    if (isNaN(parsed)) throw new Error('Invalid hex string')
	    buf[offset + i] = parsed
	  }
	  return i
	}

	function utf8Write (buf, string, offset, length) {
	  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
	}

	function asciiWrite (buf, string, offset, length) {
	  return blitBuffer(asciiToBytes(string), buf, offset, length)
	}

	function binaryWrite (buf, string, offset, length) {
	  return asciiWrite(buf, string, offset, length)
	}

	function base64Write (buf, string, offset, length) {
	  return blitBuffer(base64ToBytes(string), buf, offset, length)
	}

	function ucs2Write (buf, string, offset, length) {
	  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
	}

	Buffer.prototype.write = function write (string, offset, length, encoding) {
	  // Buffer#write(string)
	  if (offset === undefined) {
	    encoding = 'utf8'
	    length = this.length
	    offset = 0
	  // Buffer#write(string, encoding)
	  } else if (length === undefined && typeof offset === 'string') {
	    encoding = offset
	    length = this.length
	    offset = 0
	  // Buffer#write(string, offset[, length][, encoding])
	  } else if (isFinite(offset)) {
	    offset = offset | 0
	    if (isFinite(length)) {
	      length = length | 0
	      if (encoding === undefined) encoding = 'utf8'
	    } else {
	      encoding = length
	      length = undefined
	    }
	  // legacy write(string, encoding, offset, length) - remove in v0.13
	  } else {
	    var swap = encoding
	    encoding = offset
	    offset = length | 0
	    length = swap
	  }

	  var remaining = this.length - offset
	  if (length === undefined || length > remaining) length = remaining

	  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
	    throw new RangeError('attempt to write outside buffer bounds')
	  }

	  if (!encoding) encoding = 'utf8'

	  var loweredCase = false
	  for (;;) {
	    switch (encoding) {
	      case 'hex':
	        return hexWrite(this, string, offset, length)

	      case 'utf8':
	      case 'utf-8':
	        return utf8Write(this, string, offset, length)

	      case 'ascii':
	        return asciiWrite(this, string, offset, length)

	      case 'binary':
	        return binaryWrite(this, string, offset, length)

	      case 'base64':
	        // Warning: maxLength not taken into account in base64Write
	        return base64Write(this, string, offset, length)

	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return ucs2Write(this, string, offset, length)

	      default:
	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
	        encoding = ('' + encoding).toLowerCase()
	        loweredCase = true
	    }
	  }
	}

	Buffer.prototype.toJSON = function toJSON () {
	  return {
	    type: 'Buffer',
	    data: Array.prototype.slice.call(this._arr || this, 0)
	  }
	}

	function base64Slice (buf, start, end) {
	  if (start === 0 && end === buf.length) {
	    return base64.fromByteArray(buf)
	  } else {
	    return base64.fromByteArray(buf.slice(start, end))
	  }
	}

	function utf8Slice (buf, start, end) {
	  end = Math.min(buf.length, end)
	  var res = []

	  var i = start
	  while (i < end) {
	    var firstByte = buf[i]
	    var codePoint = null
	    var bytesPerSequence = (firstByte > 0xEF) ? 4
	      : (firstByte > 0xDF) ? 3
	      : (firstByte > 0xBF) ? 2
	      : 1

	    if (i + bytesPerSequence <= end) {
	      var secondByte, thirdByte, fourthByte, tempCodePoint

	      switch (bytesPerSequence) {
	        case 1:
	          if (firstByte < 0x80) {
	            codePoint = firstByte
	          }
	          break
	        case 2:
	          secondByte = buf[i + 1]
	          if ((secondByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
	            if (tempCodePoint > 0x7F) {
	              codePoint = tempCodePoint
	            }
	          }
	          break
	        case 3:
	          secondByte = buf[i + 1]
	          thirdByte = buf[i + 2]
	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
	            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
	              codePoint = tempCodePoint
	            }
	          }
	          break
	        case 4:
	          secondByte = buf[i + 1]
	          thirdByte = buf[i + 2]
	          fourthByte = buf[i + 3]
	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
	            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
	              codePoint = tempCodePoint
	            }
	          }
	      }
	    }

	    if (codePoint === null) {
	      // we did not generate a valid codePoint so insert a
	      // replacement char (U+FFFD) and advance only 1 byte
	      codePoint = 0xFFFD
	      bytesPerSequence = 1
	    } else if (codePoint > 0xFFFF) {
	      // encode to utf16 (surrogate pair dance)
	      codePoint -= 0x10000
	      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
	      codePoint = 0xDC00 | codePoint & 0x3FF
	    }

	    res.push(codePoint)
	    i += bytesPerSequence
	  }

	  return decodeCodePointsArray(res)
	}

	// Based on http://stackoverflow.com/a/22747272/680742, the browser with
	// the lowest limit is Chrome, with 0x10000 args.
	// We go 1 magnitude less, for safety
	var MAX_ARGUMENTS_LENGTH = 0x1000

	function decodeCodePointsArray (codePoints) {
	  var len = codePoints.length
	  if (len <= MAX_ARGUMENTS_LENGTH) {
	    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
	  }

	  // Decode in chunks to avoid "call stack size exceeded".
	  var res = ''
	  var i = 0
	  while (i < len) {
	    res += String.fromCharCode.apply(
	      String,
	      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
	    )
	  }
	  return res
	}

	function asciiSlice (buf, start, end) {
	  var ret = ''
	  end = Math.min(buf.length, end)

	  for (var i = start; i < end; i++) {
	    ret += String.fromCharCode(buf[i] & 0x7F)
	  }
	  return ret
	}

	function binarySlice (buf, start, end) {
	  var ret = ''
	  end = Math.min(buf.length, end)

	  for (var i = start; i < end; i++) {
	    ret += String.fromCharCode(buf[i])
	  }
	  return ret
	}

	function hexSlice (buf, start, end) {
	  var len = buf.length

	  if (!start || start < 0) start = 0
	  if (!end || end < 0 || end > len) end = len

	  var out = ''
	  for (var i = start; i < end; i++) {
	    out += toHex(buf[i])
	  }
	  return out
	}

	function utf16leSlice (buf, start, end) {
	  var bytes = buf.slice(start, end)
	  var res = ''
	  for (var i = 0; i < bytes.length; i += 2) {
	    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
	  }
	  return res
	}

	Buffer.prototype.slice = function slice (start, end) {
	  var len = this.length
	  start = ~~start
	  end = end === undefined ? len : ~~end

	  if (start < 0) {
	    start += len
	    if (start < 0) start = 0
	  } else if (start > len) {
	    start = len
	  }

	  if (end < 0) {
	    end += len
	    if (end < 0) end = 0
	  } else if (end > len) {
	    end = len
	  }

	  if (end < start) end = start

	  var newBuf
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    newBuf = Buffer._augment(this.subarray(start, end))
	  } else {
	    var sliceLen = end - start
	    newBuf = new Buffer(sliceLen, undefined)
	    for (var i = 0; i < sliceLen; i++) {
	      newBuf[i] = this[i + start]
	    }
	  }

	  if (newBuf.length) newBuf.parent = this.parent || this

	  return newBuf
	}

	/*
	 * Need to make sure that buffer isn't trying to write out of bounds.
	 */
	function checkOffset (offset, ext, length) {
	  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
	  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
	}

	Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)

	  var val = this[offset]
	  var mul = 1
	  var i = 0
	  while (++i < byteLength && (mul *= 0x100)) {
	    val += this[offset + i] * mul
	  }

	  return val
	}

	Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    checkOffset(offset, byteLength, this.length)
	  }

	  var val = this[offset + --byteLength]
	  var mul = 1
	  while (byteLength > 0 && (mul *= 0x100)) {
	    val += this[offset + --byteLength] * mul
	  }

	  return val
	}

	Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 1, this.length)
	  return this[offset]
	}

	Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  return this[offset] | (this[offset + 1] << 8)
	}

	Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  return (this[offset] << 8) | this[offset + 1]
	}

	Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)

	  return ((this[offset]) |
	      (this[offset + 1] << 8) |
	      (this[offset + 2] << 16)) +
	      (this[offset + 3] * 0x1000000)
	}

	Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)

	  return (this[offset] * 0x1000000) +
	    ((this[offset + 1] << 16) |
	    (this[offset + 2] << 8) |
	    this[offset + 3])
	}

	Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)

	  var val = this[offset]
	  var mul = 1
	  var i = 0
	  while (++i < byteLength && (mul *= 0x100)) {
	    val += this[offset + i] * mul
	  }
	  mul *= 0x80

	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

	  return val
	}

	Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)

	  var i = byteLength
	  var mul = 1
	  var val = this[offset + --i]
	  while (i > 0 && (mul *= 0x100)) {
	    val += this[offset + --i] * mul
	  }
	  mul *= 0x80

	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

	  return val
	}

	Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 1, this.length)
	  if (!(this[offset] & 0x80)) return (this[offset])
	  return ((0xff - this[offset] + 1) * -1)
	}

	Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  var val = this[offset] | (this[offset + 1] << 8)
	  return (val & 0x8000) ? val | 0xFFFF0000 : val
	}

	Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  var val = this[offset + 1] | (this[offset] << 8)
	  return (val & 0x8000) ? val | 0xFFFF0000 : val
	}

	Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)

	  return (this[offset]) |
	    (this[offset + 1] << 8) |
	    (this[offset + 2] << 16) |
	    (this[offset + 3] << 24)
	}

	Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)

	  return (this[offset] << 24) |
	    (this[offset + 1] << 16) |
	    (this[offset + 2] << 8) |
	    (this[offset + 3])
	}

	Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	  return ieee754.read(this, offset, true, 23, 4)
	}

	Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	  return ieee754.read(this, offset, false, 23, 4)
	}

	Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 8, this.length)
	  return ieee754.read(this, offset, true, 52, 8)
	}

	Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 8, this.length)
	  return ieee754.read(this, offset, false, 52, 8)
	}

	function checkInt (buf, value, offset, ext, max, min) {
	  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
	  if (value > max || value < min) throw new RangeError('value is out of bounds')
	  if (offset + ext > buf.length) throw new RangeError('index out of range')
	}

	Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)

	  var mul = 1
	  var i = 0
	  this[offset] = value & 0xFF
	  while (++i < byteLength && (mul *= 0x100)) {
	    this[offset + i] = (value / mul) & 0xFF
	  }

	  return offset + byteLength
	}

	Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)

	  var i = byteLength - 1
	  var mul = 1
	  this[offset + i] = value & 0xFF
	  while (--i >= 0 && (mul *= 0x100)) {
	    this[offset + i] = (value / mul) & 0xFF
	  }

	  return offset + byteLength
	}

	Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
	  this[offset] = (value & 0xff)
	  return offset + 1
	}

	function objectWriteUInt16 (buf, value, offset, littleEndian) {
	  if (value < 0) value = 0xffff + value + 1
	  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
	    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
	      (littleEndian ? i : 1 - i) * 8
	  }
	}

	Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	  } else {
	    objectWriteUInt16(this, value, offset, true)
	  }
	  return offset + 2
	}

	Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 8)
	    this[offset + 1] = (value & 0xff)
	  } else {
	    objectWriteUInt16(this, value, offset, false)
	  }
	  return offset + 2
	}

	function objectWriteUInt32 (buf, value, offset, littleEndian) {
	  if (value < 0) value = 0xffffffff + value + 1
	  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
	    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
	  }
	}

	Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset + 3] = (value >>> 24)
	    this[offset + 2] = (value >>> 16)
	    this[offset + 1] = (value >>> 8)
	    this[offset] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, true)
	  }
	  return offset + 4
	}

	Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 24)
	    this[offset + 1] = (value >>> 16)
	    this[offset + 2] = (value >>> 8)
	    this[offset + 3] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, false)
	  }
	  return offset + 4
	}

	Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) {
	    var limit = Math.pow(2, 8 * byteLength - 1)

	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
	  }

	  var i = 0
	  var mul = 1
	  var sub = value < 0 ? 1 : 0
	  this[offset] = value & 0xFF
	  while (++i < byteLength && (mul *= 0x100)) {
	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
	  }

	  return offset + byteLength
	}

	Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) {
	    var limit = Math.pow(2, 8 * byteLength - 1)

	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
	  }

	  var i = byteLength - 1
	  var mul = 1
	  var sub = value < 0 ? 1 : 0
	  this[offset + i] = value & 0xFF
	  while (--i >= 0 && (mul *= 0x100)) {
	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
	  }

	  return offset + byteLength
	}

	Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
	  if (value < 0) value = 0xff + value + 1
	  this[offset] = (value & 0xff)
	  return offset + 1
	}

	Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	  } else {
	    objectWriteUInt16(this, value, offset, true)
	  }
	  return offset + 2
	}

	Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 8)
	    this[offset + 1] = (value & 0xff)
	  } else {
	    objectWriteUInt16(this, value, offset, false)
	  }
	  return offset + 2
	}

	Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	    this[offset + 2] = (value >>> 16)
	    this[offset + 3] = (value >>> 24)
	  } else {
	    objectWriteUInt32(this, value, offset, true)
	  }
	  return offset + 4
	}

	Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
	  if (value < 0) value = 0xffffffff + value + 1
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 24)
	    this[offset + 1] = (value >>> 16)
	    this[offset + 2] = (value >>> 8)
	    this[offset + 3] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, false)
	  }
	  return offset + 4
	}

	function checkIEEE754 (buf, value, offset, ext, max, min) {
	  if (value > max || value < min) throw new RangeError('value is out of bounds')
	  if (offset + ext > buf.length) throw new RangeError('index out of range')
	  if (offset < 0) throw new RangeError('index out of range')
	}

	function writeFloat (buf, value, offset, littleEndian, noAssert) {
	  if (!noAssert) {
	    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
	  }
	  ieee754.write(buf, value, offset, littleEndian, 23, 4)
	  return offset + 4
	}

	Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
	  return writeFloat(this, value, offset, true, noAssert)
	}

	Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
	  return writeFloat(this, value, offset, false, noAssert)
	}

	function writeDouble (buf, value, offset, littleEndian, noAssert) {
	  if (!noAssert) {
	    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
	  }
	  ieee754.write(buf, value, offset, littleEndian, 52, 8)
	  return offset + 8
	}

	Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
	  return writeDouble(this, value, offset, true, noAssert)
	}

	Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
	  return writeDouble(this, value, offset, false, noAssert)
	}

	// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
	Buffer.prototype.copy = function copy (target, targetStart, start, end) {
	  if (!start) start = 0
	  if (!end && end !== 0) end = this.length
	  if (targetStart >= target.length) targetStart = target.length
	  if (!targetStart) targetStart = 0
	  if (end > 0 && end < start) end = start

	  // Copy 0 bytes; we're done
	  if (end === start) return 0
	  if (target.length === 0 || this.length === 0) return 0

	  // Fatal error conditions
	  if (targetStart < 0) {
	    throw new RangeError('targetStart out of bounds')
	  }
	  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
	  if (end < 0) throw new RangeError('sourceEnd out of bounds')

	  // Are we oob?
	  if (end > this.length) end = this.length
	  if (target.length - targetStart < end - start) {
	    end = target.length - targetStart + start
	  }

	  var len = end - start
	  var i

	  if (this === target && start < targetStart && targetStart < end) {
	    // descending copy from end
	    for (i = len - 1; i >= 0; i--) {
	      target[i + targetStart] = this[i + start]
	    }
	  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
	    // ascending copy from start
	    for (i = 0; i < len; i++) {
	      target[i + targetStart] = this[i + start]
	    }
	  } else {
	    target._set(this.subarray(start, start + len), targetStart)
	  }

	  return len
	}

	// fill(value, start=0, end=buffer.length)
	Buffer.prototype.fill = function fill (value, start, end) {
	  if (!value) value = 0
	  if (!start) start = 0
	  if (!end) end = this.length

	  if (end < start) throw new RangeError('end < start')

	  // Fill 0 bytes; we're done
	  if (end === start) return
	  if (this.length === 0) return

	  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
	  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')

	  var i
	  if (typeof value === 'number') {
	    for (i = start; i < end; i++) {
	      this[i] = value
	    }
	  } else {
	    var bytes = utf8ToBytes(value.toString())
	    var len = bytes.length
	    for (i = start; i < end; i++) {
	      this[i] = bytes[i % len]
	    }
	  }

	  return this
	}

	/**
	 * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
	 * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
	 */
	Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
	  if (typeof Uint8Array !== 'undefined') {
	    if (Buffer.TYPED_ARRAY_SUPPORT) {
	      return (new Buffer(this)).buffer
	    } else {
	      var buf = new Uint8Array(this.length)
	      for (var i = 0, len = buf.length; i < len; i += 1) {
	        buf[i] = this[i]
	      }
	      return buf.buffer
	    }
	  } else {
	    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
	  }
	}

	// HELPER FUNCTIONS
	// ================

	var BP = Buffer.prototype

	/**
	 * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
	 */
	Buffer._augment = function _augment (arr) {
	  arr.constructor = Buffer
	  arr._isBuffer = true

	  // save reference to original Uint8Array set method before overwriting
	  arr._set = arr.set

	  // deprecated
	  arr.get = BP.get
	  arr.set = BP.set

	  arr.write = BP.write
	  arr.toString = BP.toString
	  arr.toLocaleString = BP.toString
	  arr.toJSON = BP.toJSON
	  arr.equals = BP.equals
	  arr.compare = BP.compare
	  arr.indexOf = BP.indexOf
	  arr.copy = BP.copy
	  arr.slice = BP.slice
	  arr.readUIntLE = BP.readUIntLE
	  arr.readUIntBE = BP.readUIntBE
	  arr.readUInt8 = BP.readUInt8
	  arr.readUInt16LE = BP.readUInt16LE
	  arr.readUInt16BE = BP.readUInt16BE
	  arr.readUInt32LE = BP.readUInt32LE
	  arr.readUInt32BE = BP.readUInt32BE
	  arr.readIntLE = BP.readIntLE
	  arr.readIntBE = BP.readIntBE
	  arr.readInt8 = BP.readInt8
	  arr.readInt16LE = BP.readInt16LE
	  arr.readInt16BE = BP.readInt16BE
	  arr.readInt32LE = BP.readInt32LE
	  arr.readInt32BE = BP.readInt32BE
	  arr.readFloatLE = BP.readFloatLE
	  arr.readFloatBE = BP.readFloatBE
	  arr.readDoubleLE = BP.readDoubleLE
	  arr.readDoubleBE = BP.readDoubleBE
	  arr.writeUInt8 = BP.writeUInt8
	  arr.writeUIntLE = BP.writeUIntLE
	  arr.writeUIntBE = BP.writeUIntBE
	  arr.writeUInt16LE = BP.writeUInt16LE
	  arr.writeUInt16BE = BP.writeUInt16BE
	  arr.writeUInt32LE = BP.writeUInt32LE
	  arr.writeUInt32BE = BP.writeUInt32BE
	  arr.writeIntLE = BP.writeIntLE
	  arr.writeIntBE = BP.writeIntBE
	  arr.writeInt8 = BP.writeInt8
	  arr.writeInt16LE = BP.writeInt16LE
	  arr.writeInt16BE = BP.writeInt16BE
	  arr.writeInt32LE = BP.writeInt32LE
	  arr.writeInt32BE = BP.writeInt32BE
	  arr.writeFloatLE = BP.writeFloatLE
	  arr.writeFloatBE = BP.writeFloatBE
	  arr.writeDoubleLE = BP.writeDoubleLE
	  arr.writeDoubleBE = BP.writeDoubleBE
	  arr.fill = BP.fill
	  arr.inspect = BP.inspect
	  arr.toArrayBuffer = BP.toArrayBuffer

	  return arr
	}

	var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g

	function base64clean (str) {
	  // Node strips out invalid characters like \n and \t from the string, base64-js does not
	  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
	  // Node converts strings with length < 2 to ''
	  if (str.length < 2) return ''
	  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
	  while (str.length % 4 !== 0) {
	    str = str + '='
	  }
	  return str
	}

	function stringtrim (str) {
	  if (str.trim) return str.trim()
	  return str.replace(/^\s+|\s+$/g, '')
	}

	function toHex (n) {
	  if (n < 16) return '0' + n.toString(16)
	  return n.toString(16)
	}

	function utf8ToBytes (string, units) {
	  units = units || Infinity
	  var codePoint
	  var length = string.length
	  var leadSurrogate = null
	  var bytes = []

	  for (var i = 0; i < length; i++) {
	    codePoint = string.charCodeAt(i)

	    // is surrogate component
	    if (codePoint > 0xD7FF && codePoint < 0xE000) {
	      // last char was a lead
	      if (!leadSurrogate) {
	        // no lead yet
	        if (codePoint > 0xDBFF) {
	          // unexpected trail
	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	          continue
	        } else if (i + 1 === length) {
	          // unpaired lead
	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	          continue
	        }

	        // valid lead
	        leadSurrogate = codePoint

	        continue
	      }

	      // 2 leads in a row
	      if (codePoint < 0xDC00) {
	        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	        leadSurrogate = codePoint
	        continue
	      }

	      // valid surrogate pair
	      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
	    } else if (leadSurrogate) {
	      // valid bmp char, but last char was a lead
	      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	    }

	    leadSurrogate = null

	    // encode utf8
	    if (codePoint < 0x80) {
	      if ((units -= 1) < 0) break
	      bytes.push(codePoint)
	    } else if (codePoint < 0x800) {
	      if ((units -= 2) < 0) break
	      bytes.push(
	        codePoint >> 0x6 | 0xC0,
	        codePoint & 0x3F | 0x80
	      )
	    } else if (codePoint < 0x10000) {
	      if ((units -= 3) < 0) break
	      bytes.push(
	        codePoint >> 0xC | 0xE0,
	        codePoint >> 0x6 & 0x3F | 0x80,
	        codePoint & 0x3F | 0x80
	      )
	    } else if (codePoint < 0x110000) {
	      if ((units -= 4) < 0) break
	      bytes.push(
	        codePoint >> 0x12 | 0xF0,
	        codePoint >> 0xC & 0x3F | 0x80,
	        codePoint >> 0x6 & 0x3F | 0x80,
	        codePoint & 0x3F | 0x80
	      )
	    } else {
	      throw new Error('Invalid code point')
	    }
	  }

	  return bytes
	}

	function asciiToBytes (str) {
	  var byteArray = []
	  for (var i = 0; i < str.length; i++) {
	    // Node's code seems to be doing this and not & 0x7F..
	    byteArray.push(str.charCodeAt(i) & 0xFF)
	  }
	  return byteArray
	}

	function utf16leToBytes (str, units) {
	  var c, hi, lo
	  var byteArray = []
	  for (var i = 0; i < str.length; i++) {
	    if ((units -= 2) < 0) break

	    c = str.charCodeAt(i)
	    hi = c >> 8
	    lo = c % 256
	    byteArray.push(lo)
	    byteArray.push(hi)
	  }

	  return byteArray
	}

	function base64ToBytes (str) {
	  return base64.toByteArray(base64clean(str))
	}

	function blitBuffer (src, dst, offset, length) {
	  for (var i = 0; i < length; i++) {
	    if ((i + offset >= dst.length) || (i >= src.length)) break
	    dst[i + offset] = src[i]
	  }
	  return i
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer, (function() { return this; }())))

/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {

	var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

	;(function (exports) {
		'use strict';

	  var Arr = (typeof Uint8Array !== 'undefined')
	    ? Uint8Array
	    : Array

		var PLUS   = '+'.charCodeAt(0)
		var SLASH  = '/'.charCodeAt(0)
		var NUMBER = '0'.charCodeAt(0)
		var LOWER  = 'a'.charCodeAt(0)
		var UPPER  = 'A'.charCodeAt(0)
		var PLUS_URL_SAFE = '-'.charCodeAt(0)
		var SLASH_URL_SAFE = '_'.charCodeAt(0)

		function decode (elt) {
			var code = elt.charCodeAt(0)
			if (code === PLUS ||
			    code === PLUS_URL_SAFE)
				return 62 // '+'
			if (code === SLASH ||
			    code === SLASH_URL_SAFE)
				return 63 // '/'
			if (code < NUMBER)
				return -1 //no match
			if (code < NUMBER + 10)
				return code - NUMBER + 26 + 26
			if (code < UPPER + 26)
				return code - UPPER
			if (code < LOWER + 26)
				return code - LOWER + 26
		}

		function b64ToByteArray (b64) {
			var i, j, l, tmp, placeHolders, arr

			if (b64.length % 4 > 0) {
				throw new Error('Invalid string. Length must be a multiple of 4')
			}

			// the number of equal signs (place holders)
			// if there are two placeholders, than the two characters before it
			// represent one byte
			// if there is only one, then the three characters before it represent 2 bytes
			// this is just a cheap hack to not do indexOf twice
			var len = b64.length
			placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0

			// base64 is 4/3 + up to two characters of the original data
			arr = new Arr(b64.length * 3 / 4 - placeHolders)

			// if there are placeholders, only get up to the last complete 4 chars
			l = placeHolders > 0 ? b64.length - 4 : b64.length

			var L = 0

			function push (v) {
				arr[L++] = v
			}

			for (i = 0, j = 0; i < l; i += 4, j += 3) {
				tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
				push((tmp & 0xFF0000) >> 16)
				push((tmp & 0xFF00) >> 8)
				push(tmp & 0xFF)
			}

			if (placeHolders === 2) {
				tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
				push(tmp & 0xFF)
			} else if (placeHolders === 1) {
				tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
				push((tmp >> 8) & 0xFF)
				push(tmp & 0xFF)
			}

			return arr
		}

		function uint8ToBase64 (uint8) {
			var i,
				extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
				output = "",
				temp, length

			function encode (num) {
				return lookup.charAt(num)
			}

			function tripletToBase64 (num) {
				return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
			}

			// go through the array every three bytes, we'll deal with trailing stuff later
			for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
				temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
				output += tripletToBase64(temp)
			}

			// pad the end with zeros, but make sure to not forget the extra bytes
			switch (extraBytes) {
				case 1:
					temp = uint8[uint8.length - 1]
					output += encode(temp >> 2)
					output += encode((temp << 4) & 0x3F)
					output += '=='
					break
				case 2:
					temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
					output += encode(temp >> 10)
					output += encode((temp >> 4) & 0x3F)
					output += encode((temp << 2) & 0x3F)
					output += '='
					break
			}

			return output
		}

		exports.toByteArray = b64ToByteArray
		exports.fromByteArray = uint8ToBase64
	}( false ? (this.base64js = {}) : exports))


/***/ },
/* 7 */
/***/ function(module, exports) {

	exports.read = function (buffer, offset, isLE, mLen, nBytes) {
	  var e, m
	  var eLen = nBytes * 8 - mLen - 1
	  var eMax = (1 << eLen) - 1
	  var eBias = eMax >> 1
	  var nBits = -7
	  var i = isLE ? (nBytes - 1) : 0
	  var d = isLE ? -1 : 1
	  var s = buffer[offset + i]

	  i += d

	  e = s & ((1 << (-nBits)) - 1)
	  s >>= (-nBits)
	  nBits += eLen
	  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}

	  m = e & ((1 << (-nBits)) - 1)
	  e >>= (-nBits)
	  nBits += mLen
	  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}

	  if (e === 0) {
	    e = 1 - eBias
	  } else if (e === eMax) {
	    return m ? NaN : ((s ? -1 : 1) * Infinity)
	  } else {
	    m = m + Math.pow(2, mLen)
	    e = e - eBias
	  }
	  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
	}

	exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
	  var e, m, c
	  var eLen = nBytes * 8 - mLen - 1
	  var eMax = (1 << eLen) - 1
	  var eBias = eMax >> 1
	  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
	  var i = isLE ? 0 : (nBytes - 1)
	  var d = isLE ? 1 : -1
	  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0

	  value = Math.abs(value)

	  if (isNaN(value) || value === Infinity) {
	    m = isNaN(value) ? 1 : 0
	    e = eMax
	  } else {
	    e = Math.floor(Math.log(value) / Math.LN2)
	    if (value * (c = Math.pow(2, -e)) < 1) {
	      e--
	      c *= 2
	    }
	    if (e + eBias >= 1) {
	      value += rt / c
	    } else {
	      value += rt * Math.pow(2, 1 - eBias)
	    }
	    if (value * c >= 2) {
	      e++
	      c /= 2
	    }

	    if (e + eBias >= eMax) {
	      m = 0
	      e = eMax
	    } else if (e + eBias >= 1) {
	      m = (value * c - 1) * Math.pow(2, mLen)
	      e = e + eBias
	    } else {
	      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
	      e = 0
	    }
	  }

	  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

	  e = (e << mLen) | m
	  eLen += mLen
	  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

	  buffer[offset + i - d] |= s * 128
	}


/***/ },
/* 8 */
/***/ function(module, exports) {

	
	/**
	 * isArray
	 */

	var isArray = Array.isArray;

	/**
	 * toString
	 */

	var str = Object.prototype.toString;

	/**
	 * Whether or not the given `val`
	 * is an array.
	 *
	 * example:
	 *
	 *        isArray([]);
	 *        // > true
	 *        isArray(arguments);
	 *        // > false
	 *        isArray('');
	 *        // > false
	 *
	 * @param {mixed} val
	 * @return {bool}
	 */

	module.exports = isArray || function (val) {
	  return !! val && '[object Array]' == str.call(val);
	};


/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
	  Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.

	  Redistribution and use in source and binary forms, with or without
	  modification, are permitted provided that the following conditions are met:

	    * Redistributions of source code must retain the above copyright
	      notice, this list of conditions and the following disclaimer.
	    * Redistributions in binary form must reproduce the above copyright
	      notice, this list of conditions and the following disclaimer in the
	      documentation and/or other materials provided with the distribution.

	  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
	  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
	  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
	  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
	  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
	*/

	(function (root, factory) {
	    'use strict';

	    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
	    // Rhino, and plain browser loading.

	    /* istanbul ignore next */
	    if (true) {
	        !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	    } else if (typeof exports !== 'undefined') {
	        factory(exports);
	    } else {
	        factory((root.esprima = {}));
	    }
	}(this, function (exports) {
	    'use strict';

	    var Token,
	        TokenName,
	        FnExprTokens,
	        Syntax,
	        PlaceHolders,
	        Messages,
	        Regex,
	        source,
	        strict,
	        index,
	        lineNumber,
	        lineStart,
	        hasLineTerminator,
	        lastIndex,
	        lastLineNumber,
	        lastLineStart,
	        startIndex,
	        startLineNumber,
	        startLineStart,
	        scanning,
	        length,
	        lookahead,
	        state,
	        extra,
	        isBindingElement,
	        isAssignmentTarget,
	        firstCoverInitializedNameError;

	    Token = {
	        BooleanLiteral: 1,
	        EOF: 2,
	        Identifier: 3,
	        Keyword: 4,
	        NullLiteral: 5,
	        NumericLiteral: 6,
	        Punctuator: 7,
	        StringLiteral: 8,
	        RegularExpression: 9,
	        Template: 10
	    };

	    TokenName = {};
	    TokenName[Token.BooleanLiteral] = 'Boolean';
	    TokenName[Token.EOF] = '<end>';
	    TokenName[Token.Identifier] = 'Identifier';
	    TokenName[Token.Keyword] = 'Keyword';
	    TokenName[Token.NullLiteral] = 'Null';
	    TokenName[Token.NumericLiteral] = 'Numeric';
	    TokenName[Token.Punctuator] = 'Punctuator';
	    TokenName[Token.StringLiteral] = 'String';
	    TokenName[Token.RegularExpression] = 'RegularExpression';
	    TokenName[Token.Template] = 'Template';

	    // A function following one of those tokens is an expression.
	    FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
	                    'return', 'case', 'delete', 'throw', 'void',
	                    // assignment operators
	                    '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
	                    '&=', '|=', '^=', ',',
	                    // binary/unary operators
	                    '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
	                    '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
	                    '<=', '<', '>', '!=', '!=='];

	    Syntax = {
	        AssignmentExpression: 'AssignmentExpression',
	        AssignmentPattern: 'AssignmentPattern',
	        ArrayExpression: 'ArrayExpression',
	        ArrayPattern: 'ArrayPattern',
	        ArrowFunctionExpression: 'ArrowFunctionExpression',
	        BlockStatement: 'BlockStatement',
	        BinaryExpression: 'BinaryExpression',
	        BreakStatement: 'BreakStatement',
	        CallExpression: 'CallExpression',
	        CatchClause: 'CatchClause',
	        ClassBody: 'ClassBody',
	        ClassDeclaration: 'ClassDeclaration',
	        ClassExpression: 'ClassExpression',
	        ConditionalExpression: 'ConditionalExpression',
	        ContinueStatement: 'ContinueStatement',
	        DoWhileStatement: 'DoWhileStatement',
	        DebuggerStatement: 'DebuggerStatement',
	        EmptyStatement: 'EmptyStatement',
	        ExportAllDeclaration: 'ExportAllDeclaration',
	        ExportDefaultDeclaration: 'ExportDefaultDeclaration',
	        ExportNamedDeclaration: 'ExportNamedDeclaration',
	        ExportSpecifier: 'ExportSpecifier',
	        ExpressionStatement: 'ExpressionStatement',
	        ForStatement: 'ForStatement',
	        ForOfStatement: 'ForOfStatement',
	        ForInStatement: 'ForInStatement',
	        FunctionDeclaration: 'FunctionDeclaration',
	        FunctionExpression: 'FunctionExpression',
	        Identifier: 'Identifier',
	        IfStatement: 'IfStatement',
	        ImportDeclaration: 'ImportDeclaration',
	        ImportDefaultSpecifier: 'ImportDefaultSpecifier',
	        ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
	        ImportSpecifier: 'ImportSpecifier',
	        Literal: 'Literal',
	        LabeledStatement: 'LabeledStatement',
	        LogicalExpression: 'LogicalExpression',
	        MemberExpression: 'MemberExpression',
	        MetaProperty: 'MetaProperty',
	        MethodDefinition: 'MethodDefinition',
	        NewExpression: 'NewExpression',
	        ObjectExpression: 'ObjectExpression',
	        ObjectPattern: 'ObjectPattern',
	        Program: 'Program',
	        Property: 'Property',
	        RestElement: 'RestElement',
	        ReturnStatement: 'ReturnStatement',
	        SequenceExpression: 'SequenceExpression',
	        SpreadElement: 'SpreadElement',
	        Super: 'Super',
	        SwitchCase: 'SwitchCase',
	        SwitchStatement: 'SwitchStatement',
	        TaggedTemplateExpression: 'TaggedTemplateExpression',
	        TemplateElement: 'TemplateElement',
	        TemplateLiteral: 'TemplateLiteral',
	        ThisExpression: 'ThisExpression',
	        ThrowStatement: 'ThrowStatement',
	        TryStatement: 'TryStatement',
	        UnaryExpression: 'UnaryExpression',
	        UpdateExpression: 'UpdateExpression',
	        VariableDeclaration: 'VariableDeclaration',
	        VariableDeclarator: 'VariableDeclarator',
	        WhileStatement: 'WhileStatement',
	        WithStatement: 'WithStatement',
	        YieldExpression: 'YieldExpression'
	    };

	    PlaceHolders = {
	        ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder'
	    };

	    // Error messages should be identical to V8.
	    Messages = {
	        UnexpectedToken: 'Unexpected token %0',
	        UnexpectedNumber: 'Unexpected number',
	        UnexpectedString: 'Unexpected string',
	        UnexpectedIdentifier: 'Unexpected identifier',
	        UnexpectedReserved: 'Unexpected reserved word',
	        UnexpectedTemplate: 'Unexpected quasi %0',
	        UnexpectedEOS: 'Unexpected end of input',
	        NewlineAfterThrow: 'Illegal newline after throw',
	        InvalidRegExp: 'Invalid regular expression',
	        UnterminatedRegExp: 'Invalid regular expression: missing /',
	        InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
	        InvalidLHSInForIn: 'Invalid left-hand side in for-in',
	        InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
	        MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
	        NoCatchOrFinally: 'Missing catch or finally after try',
	        UnknownLabel: 'Undefined label \'%0\'',
	        Redeclaration: '%0 \'%1\' has already been declared',
	        IllegalContinue: 'Illegal continue statement',
	        IllegalBreak: 'Illegal break statement',
	        IllegalReturn: 'Illegal return statement',
	        StrictModeWith: 'Strict mode code may not include a with statement',
	        StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
	        StrictVarName: 'Variable name may not be eval or arguments in strict mode',
	        StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
	        StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
	        StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
	        StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
	        StrictDelete: 'Delete of an unqualified identifier in strict mode.',
	        StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
	        StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
	        StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
	        StrictReservedWord: 'Use of future reserved word in strict mode',
	        TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
	        ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
	        DefaultRestParameter: 'Unexpected token =',
	        ObjectPatternAsRestParameter: 'Unexpected token {',
	        DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
	        ConstructorSpecialMethod: 'Class constructor may not be an accessor',
	        DuplicateConstructor: 'A class may only have one constructor',
	        StaticPrototype: 'Classes may not have static property named prototype',
	        MissingFromClause: 'Unexpected token',
	        NoAsAfterImportNamespace: 'Unexpected token',
	        InvalidModuleSpecifier: 'Unexpected token',
	        IllegalImportDeclaration: 'Unexpected token',
	        IllegalExportDeclaration: 'Unexpected token',
	        DuplicateBinding: 'Duplicate binding %0'
	    };

	    // See also tools/generate-unicode-regex.js.
	    Regex = {
	        // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart:
	        NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/,

	        // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart:
	        NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
	    };

	    // Ensure the condition is true, otherwise throw an error.
	    // This is only to have a better contract semantic, i.e. another safety net
	    // to catch a logic error. The condition shall be fulfilled in normal case.
	    // Do NOT use this to enforce a certain condition on any user input.

	    function assert(condition, message) {
	        /* istanbul ignore if */
	        if (!condition) {
	            throw new Error('ASSERT: ' + message);
	        }
	    }

	    function isDecimalDigit(ch) {
	        return (ch >= 0x30 && ch <= 0x39);   // 0..9
	    }

	    function isHexDigit(ch) {
	        return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
	    }

	    function isOctalDigit(ch) {
	        return '01234567'.indexOf(ch) >= 0;
	    }

	    function octalToDecimal(ch) {
	        // \0 is not octal escape sequence
	        var octal = (ch !== '0'), code = '01234567'.indexOf(ch);

	        if (index < length && isOctalDigit(source[index])) {
	            octal = true;
	            code = code * 8 + '01234567'.indexOf(source[index++]);

	            // 3 digits are only allowed when string starts
	            // with 0, 1, 2, 3
	            if ('0123'.indexOf(ch) >= 0 &&
	                    index < length &&
	                    isOctalDigit(source[index])) {
	                code = code * 8 + '01234567'.indexOf(source[index++]);
	            }
	        }

	        return {
	            code: code,
	            octal: octal
	        };
	    }

	    // ECMA-262 11.2 White Space

	    function isWhiteSpace(ch) {
	        return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
	            (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
	    }

	    // ECMA-262 11.3 Line Terminators

	    function isLineTerminator(ch) {
	        return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
	    }

	    // ECMA-262 11.6 Identifier Names and Identifiers

	    function fromCodePoint(cp) {
	        return (cp < 0x10000) ? String.fromCharCode(cp) :
	            String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) +
	            String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023));
	    }

	    function isIdentifierStart(ch) {
	        return (ch === 0x24) || (ch === 0x5F) ||  // $ (dollar) and _ (underscore)
	            (ch >= 0x41 && ch <= 0x5A) ||         // A..Z
	            (ch >= 0x61 && ch <= 0x7A) ||         // a..z
	            (ch === 0x5C) ||                      // \ (backslash)
	            ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)));
	    }

	    function isIdentifierPart(ch) {
	        return (ch === 0x24) || (ch === 0x5F) ||  // $ (dollar) and _ (underscore)
	            (ch >= 0x41 && ch <= 0x5A) ||         // A..Z
	            (ch >= 0x61 && ch <= 0x7A) ||         // a..z
	            (ch >= 0x30 && ch <= 0x39) ||         // 0..9
	            (ch === 0x5C) ||                      // \ (backslash)
	            ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)));
	    }

	    // ECMA-262 11.6.2.2 Future Reserved Words

	    function isFutureReservedWord(id) {
	        switch (id) {
	        case 'enum':
	        case 'export':
	        case 'import':
	        case 'super':
	            return true;
	        default:
	            return false;
	        }
	    }

	    function isStrictModeReservedWord(id) {
	        switch (id) {
	        case 'implements':
	        case 'interface':
	        case 'package':
	        case 'private':
	        case 'protected':
	        case 'public':
	        case 'static':
	        case 'yield':
	        case 'let':
	            return true;
	        default:
	            return false;
	        }
	    }

	    function isRestrictedWord(id) {
	        return id === 'eval' || id === 'arguments';
	    }

	    // ECMA-262 11.6.2.1 Keywords

	    function isKeyword(id) {
	        switch (id.length) {
	        case 2:
	            return (id === 'if') || (id === 'in') || (id === 'do');
	        case 3:
	            return (id === 'var') || (id === 'for') || (id === 'new') ||
	                (id === 'try') || (id === 'let');
	        case 4:
	            return (id === 'this') || (id === 'else') || (id === 'case') ||
	                (id === 'void') || (id === 'with') || (id === 'enum');
	        case 5:
	            return (id === 'while') || (id === 'break') || (id === 'catch') ||
	                (id === 'throw') || (id === 'const') || (id === 'yield') ||
	                (id === 'class') || (id === 'super');
	        case 6:
	            return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
	                (id === 'switch') || (id === 'export') || (id === 'import');
	        case 7:
	            return (id === 'default') || (id === 'finally') || (id === 'extends');
	        case 8:
	            return (id === 'function') || (id === 'continue') || (id === 'debugger');
	        case 10:
	            return (id === 'instanceof');
	        default:
	            return false;
	        }
	    }

	    // ECMA-262 11.4 Comments

	    function addComment(type, value, start, end, loc) {
	        var comment;

	        assert(typeof start === 'number', 'Comment must have valid position');

	        state.lastCommentStart = start;

	        comment = {
	            type: type,
	            value: value
	        };
	        if (extra.range) {
	            comment.range = [start, end];
	        }
	        if (extra.loc) {
	            comment.loc = loc;
	        }
	        extra.comments.push(comment);
	        if (extra.attachComment) {
	            extra.leadingComments.push(comment);
	            extra.trailingComments.push(comment);
	        }
	        if (extra.tokenize) {
	            comment.type = comment.type + 'Comment';
	            if (extra.delegate) {
	                comment = extra.delegate(comment);
	            }
	            extra.tokens.push(comment);
	        }
	    }

	    function skipSingleLineComment(offset) {
	        var start, loc, ch, comment;

	        start = index - offset;
	        loc = {
	            start: {
	                line: lineNumber,
	                column: index - lineStart - offset
	            }
	        };

	        while (index < length) {
	            ch = source.charCodeAt(index);
	            ++index;
	            if (isLineTerminator(ch)) {
	                hasLineTerminator = true;
	                if (extra.comments) {
	                    comment = source.slice(start + offset, index - 1);
	                    loc.end = {
	                        line: lineNumber,
	                        column: index - lineStart - 1
	                    };
	                    addComment('Line', comment, start, index - 1, loc);
	                }
	                if (ch === 13 && source.charCodeAt(index) === 10) {
	                    ++index;
	                }
	                ++lineNumber;
	                lineStart = index;
	                return;
	            }
	        }

	        if (extra.comments) {
	            comment = source.slice(start + offset, index);
	            loc.end = {
	                line: lineNumber,
	                column: index - lineStart
	            };
	            addComment('Line', comment, start, index, loc);
	        }
	    }

	    function skipMultiLineComment() {
	        var start, loc, ch, comment;

	        if (extra.comments) {
	            start = index - 2;
	            loc = {
	                start: {
	                    line: lineNumber,
	                    column: index - lineStart - 2
	                }
	            };
	        }

	        while (index < length) {
	            ch = source.charCodeAt(index);
	            if (isLineTerminator(ch)) {
	                if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
	                    ++index;
	                }
	                hasLineTerminator = true;
	                ++lineNumber;
	                ++index;
	                lineStart = index;
	            } else if (ch === 0x2A) {
	                // Block comment ends with '*/'.
	                if (source.charCodeAt(index + 1) === 0x2F) {
	                    ++index;
	                    ++index;
	                    if (extra.comments) {
	                        comment = source.slice(start + 2, index - 2);
	                        loc.end = {
	                            line: lineNumber,
	                            column: index - lineStart
	                        };
	                        addComment('Block', comment, start, index, loc);
	                    }
	                    return;
	                }
	                ++index;
	            } else {
	                ++index;
	            }
	        }

	        // Ran off the end of the file - the whole thing is a comment
	        if (extra.comments) {
	            loc.end = {
	                line: lineNumber,
	                column: index - lineStart
	            };
	            comment = source.slice(start + 2, index);
	            addComment('Block', comment, start, index, loc);
	        }
	        tolerateUnexpectedToken();
	    }

	    function skipComment() {
	        var ch, start;
	        hasLineTerminator = false;

	        start = (index === 0);
	        while (index < length) {
	            ch = source.charCodeAt(index);

	            if (isWhiteSpace(ch)) {
	                ++index;
	            } else if (isLineTerminator(ch)) {
	                hasLineTerminator = true;
	                ++index;
	                if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
	                    ++index;
	                }
	                ++lineNumber;
	                lineStart = index;
	                start = true;
	            } else if (ch === 0x2F) { // U+002F is '/'
	                ch = source.charCodeAt(index + 1);
	                if (ch === 0x2F) {
	                    ++index;
	                    ++index;
	                    skipSingleLineComment(2);
	                    start = true;
	                } else if (ch === 0x2A) {  // U+002A is '*'
	                    ++index;
	                    ++index;
	                    skipMultiLineComment();
	                } else {
	                    break;
	                }
	            } else if (start && ch === 0x2D) { // U+002D is '-'
	                // U+003E is '>'
	                if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
	                    // '-->' is a single-line comment
	                    index += 3;
	                    skipSingleLineComment(3);
	                } else {
	                    break;
	                }
	            } else if (ch === 0x3C) { // U+003C is '<'
	                if (source.slice(index + 1, index + 4) === '!--') {
	                    ++index; // `<`
	                    ++index; // `!`
	                    ++index; // `-`
	                    ++index; // `-`
	                    skipSingleLineComment(4);
	                } else {
	                    break;
	                }
	            } else {
	                break;
	            }
	        }
	    }

	    function scanHexEscape(prefix) {
	        var i, len, ch, code = 0;

	        len = (prefix === 'u') ? 4 : 2;
	        for (i = 0; i < len; ++i) {
	            if (index < length && isHexDigit(source[index])) {
	                ch = source[index++];
	                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
	            } else {
	                return '';
	            }
	        }
	        return String.fromCharCode(code);
	    }

	    function scanUnicodeCodePointEscape() {
	        var ch, code;

	        ch = source[index];
	        code = 0;

	        // At least, one hex digit is required.
	        if (ch === '}') {
	            throwUnexpectedToken();
	        }

	        while (index < length) {
	            ch = source[index++];
	            if (!isHexDigit(ch)) {
	                break;
	            }
	            code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
	        }

	        if (code > 0x10FFFF || ch !== '}') {
	            throwUnexpectedToken();
	        }

	        return fromCodePoint(code);
	    }

	    function codePointAt(i) {
	        var cp, first, second;

	        cp = source.charCodeAt(i);
	        if (cp >= 0xD800 && cp <= 0xDBFF) {
	            second = source.charCodeAt(i + 1);
	            if (second >= 0xDC00 && second <= 0xDFFF) {
	                first = cp;
	                cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
	            }
	        }

	        return cp;
	    }

	    function getComplexIdentifier() {
	        var cp, ch, id;

	        cp = codePointAt(index);
	        id = fromCodePoint(cp);
	        index += id.length;

	        // '\u' (U+005C, U+0075) denotes an escaped character.
	        if (cp === 0x5C) {
	            if (source.charCodeAt(index) !== 0x75) {
	                throwUnexpectedToken();
	            }
	            ++index;
	            if (source[index] === '{') {
	                ++index;
	                ch = scanUnicodeCodePointEscape();
	            } else {
	                ch = scanHexEscape('u');
	                cp = ch.charCodeAt(0);
	                if (!ch || ch === '\\' || !isIdentifierStart(cp)) {
	                    throwUnexpectedToken();
	                }
	            }
	            id = ch;
	        }

	        while (index < length) {
	            cp = codePointAt(index);
	            if (!isIdentifierPart(cp)) {
	                break;
	            }
	            ch = fromCodePoint(cp);
	            id += ch;
	            index += ch.length;

	            // '\u' (U+005C, U+0075) denotes an escaped character.
	            if (cp === 0x5C) {
	                id = id.substr(0, id.length - 1);
	                if (source.charCodeAt(index) !== 0x75) {
	                    throwUnexpectedToken();
	                }
	                ++index;
	                if (source[index] === '{') {
	                    ++index;
	                    ch = scanUnicodeCodePointEscape();
	                } else {
	                    ch = scanHexEscape('u');
	                    cp = ch.charCodeAt(0);
	                    if (!ch || ch === '\\' || !isIdentifierPart(cp)) {
	                        throwUnexpectedToken();
	                    }
	                }
	                id += ch;
	            }
	        }

	        return id;
	    }

	    function getIdentifier() {
	        var start, ch;

	        start = index++;
	        while (index < length) {
	            ch = source.charCodeAt(index);
	            if (ch === 0x5C) {
	                // Blackslash (U+005C) marks Unicode escape sequence.
	                index = start;
	                return getComplexIdentifier();
	            } else if (ch >= 0xD800 && ch < 0xDFFF) {
	                // Need to handle surrogate pairs.
	                index = start;
	                return getComplexIdentifier();
	            }
	            if (isIdentifierPart(ch)) {
	                ++index;
	            } else {
	                break;
	            }
	        }

	        return source.slice(start, index);
	    }

	    function scanIdentifier() {
	        var start, id, type;

	        start = index;

	        // Backslash (U+005C) starts an escaped character.
	        id = (source.charCodeAt(index) === 0x5C) ? getComplexIdentifier() : getIdentifier();

	        // There is no keyword or literal with only one character.
	        // Thus, it must be an identifier.
	        if (id.length === 1) {
	            type = Token.Identifier;
	        } else if (isKeyword(id)) {
	            type = Token.Keyword;
	        } else if (id === 'null') {
	            type = Token.NullLiteral;
	        } else if (id === 'true' || id === 'false') {
	            type = Token.BooleanLiteral;
	        } else {
	            type = Token.Identifier;
	        }

	        return {
	            type: type,
	            value: id,
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: start,
	            end: index
	        };
	    }


	    // ECMA-262 11.7 Punctuators

	    function scanPunctuator() {
	        var token, str;

	        token = {
	            type: Token.Punctuator,
	            value: '',
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: index,
	            end: index
	        };

	        // Check for most common single-character punctuators.
	        str = source[index];
	        switch (str) {

	        case '(':
	            if (extra.tokenize) {
	                extra.openParenToken = extra.tokenValues.length;
	            }
	            ++index;
	            break;

	        case '{':
	            if (extra.tokenize) {
	                extra.openCurlyToken = extra.tokenValues.length;
	            }
	            state.curlyStack.push('{');
	            ++index;
	            break;

	        case '.':
	            ++index;
	            if (source[index] === '.' && source[index + 1] === '.') {
	                // Spread operator: ...
	                index += 2;
	                str = '...';
	            }
	            break;

	        case '}':
	            ++index;
	            state.curlyStack.pop();
	            break;
	        case ')':
	        case ';':
	        case ',':
	        case '[':
	        case ']':
	        case ':':
	        case '?':
	        case '~':
	            ++index;
	            break;

	        default:
	            // 4-character punctuator.
	            str = source.substr(index, 4);
	            if (str === '>>>=') {
	                index += 4;
	            } else {

	                // 3-character punctuators.
	                str = str.substr(0, 3);
	                if (str === '===' || str === '!==' || str === '>>>' ||
	                    str === '<<=' || str === '>>=') {
	                    index += 3;
	                } else {

	                    // 2-character punctuators.
	                    str = str.substr(0, 2);
	                    if (str === '&&' || str === '||' || str === '==' || str === '!=' ||
	                        str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
	                        str === '++' || str === '--' || str === '<<' || str === '>>' ||
	                        str === '&=' || str === '|=' || str === '^=' || str === '%=' ||
	                        str === '<=' || str === '>=' || str === '=>') {
	                        index += 2;
	                    } else {

	                        // 1-character punctuators.
	                        str = source[index];
	                        if ('<>=!+-*%&|^/'.indexOf(str) >= 0) {
	                            ++index;
	                        }
	                    }
	                }
	            }
	        }

	        if (index === token.start) {
	            throwUnexpectedToken();
	        }

	        token.end = index;
	        token.value = str;
	        return token;
	    }

	    // ECMA-262 11.8.3 Numeric Literals

	    function scanHexLiteral(start) {
	        var number = '';

	        while (index < length) {
	            if (!isHexDigit(source[index])) {
	                break;
	            }
	            number += source[index++];
	        }

	        if (number.length === 0) {
	            throwUnexpectedToken();
	        }

	        if (isIdentifierStart(source.charCodeAt(index))) {
	            throwUnexpectedToken();
	        }

	        return {
	            type: Token.NumericLiteral,
	            value: parseInt('0x' + number, 16),
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: start,
	            end: index
	        };
	    }

	    function scanBinaryLiteral(start) {
	        var ch, number;

	        number = '';

	        while (index < length) {
	            ch = source[index];
	            if (ch !== '0' && ch !== '1') {
	                break;
	            }
	            number += source[index++];
	        }

	        if (number.length === 0) {
	            // only 0b or 0B
	            throwUnexpectedToken();
	        }

	        if (index < length) {
	            ch = source.charCodeAt(index);
	            /* istanbul ignore else */
	            if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
	                throwUnexpectedToken();
	            }
	        }

	        return {
	            type: Token.NumericLiteral,
	            value: parseInt(number, 2),
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: start,
	            end: index
	        };
	    }

	    function scanOctalLiteral(prefix, start) {
	        var number, octal;

	        if (isOctalDigit(prefix)) {
	            octal = true;
	            number = '0' + source[index++];
	        } else {
	            octal = false;
	            ++index;
	            number = '';
	        }

	        while (index < length) {
	            if (!isOctalDigit(source[index])) {
	                break;
	            }
	            number += source[index++];
	        }

	        if (!octal && number.length === 0) {
	            // only 0o or 0O
	            throwUnexpectedToken();
	        }

	        if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
	            throwUnexpectedToken();
	        }

	        return {
	            type: Token.NumericLiteral,
	            value: parseInt(number, 8),
	            octal: octal,
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: start,
	            end: index
	        };
	    }

	    function isImplicitOctalLiteral() {
	        var i, ch;

	        // Implicit octal, unless there is a non-octal digit.
	        // (Annex B.1.1 on Numeric Literals)
	        for (i = index + 1; i < length; ++i) {
	            ch = source[i];
	            if (ch === '8' || ch === '9') {
	                return false;
	            }
	            if (!isOctalDigit(ch)) {
	                return true;
	            }
	        }

	        return true;
	    }

	    function scanNumericLiteral() {
	        var number, start, ch;

	        ch = source[index];
	        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
	            'Numeric literal must start with a decimal digit or a decimal point');

	        start = index;
	        number = '';
	        if (ch !== '.') {
	            number = source[index++];
	            ch = source[index];

	            // Hex number starts with '0x'.
	            // Octal number starts with '0'.
	            // Octal number in ES6 starts with '0o'.
	            // Binary number in ES6 starts with '0b'.
	            if (number === '0') {
	                if (ch === 'x' || ch === 'X') {
	                    ++index;
	                    return scanHexLiteral(start);
	                }
	                if (ch === 'b' || ch === 'B') {
	                    ++index;
	                    return scanBinaryLiteral(start);
	                }
	                if (ch === 'o' || ch === 'O') {
	                    return scanOctalLiteral(ch, start);
	                }

	                if (isOctalDigit(ch)) {
	                    if (isImplicitOctalLiteral()) {
	                        return scanOctalLiteral(ch, start);
	                    }
	                }
	            }

	            while (isDecimalDigit(source.charCodeAt(index))) {
	                number += source[index++];
	            }
	            ch = source[index];
	        }

	        if (ch === '.') {
	            number += source[index++];
	            while (isDecimalDigit(source.charCodeAt(index))) {
	                number += source[index++];
	            }
	            ch = source[index];
	        }

	        if (ch === 'e' || ch === 'E') {
	            number += source[index++];

	            ch = source[index];
	            if (ch === '+' || ch === '-') {
	                number += source[index++];
	            }
	            if (isDecimalDigit(source.charCodeAt(index))) {
	                while (isDecimalDigit(source.charCodeAt(index))) {
	                    number += source[index++];
	                }
	            } else {
	                throwUnexpectedToken();
	            }
	        }

	        if (isIdentifierStart(source.charCodeAt(index))) {
	            throwUnexpectedToken();
	        }

	        return {
	            type: Token.NumericLiteral,
	            value: parseFloat(number),
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: start,
	            end: index
	        };
	    }

	    // ECMA-262 11.8.4 String Literals

	    function scanStringLiteral() {
	        var str = '', quote, start, ch, unescaped, octToDec, octal = false;

	        quote = source[index];
	        assert((quote === '\'' || quote === '"'),
	            'String literal must starts with a quote');

	        start = index;
	        ++index;

	        while (index < length) {
	            ch = source[index++];

	            if (ch === quote) {
	                quote = '';
	                break;
	            } else if (ch === '\\') {
	                ch = source[index++];
	                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
	                    switch (ch) {
	                    case 'u':
	                    case 'x':
	                        if (source[index] === '{') {
	                            ++index;
	                            str += scanUnicodeCodePointEscape();
	                        } else {
	                            unescaped = scanHexEscape(ch);
	                            if (!unescaped) {
	                                throw throwUnexpectedToken();
	                            }
	                            str += unescaped;
	                        }
	                        break;
	                    case 'n':
	                        str += '\n';
	                        break;
	                    case 'r':
	                        str += '\r';
	                        break;
	                    case 't':
	                        str += '\t';
	                        break;
	                    case 'b':
	                        str += '\b';
	                        break;
	                    case 'f':
	                        str += '\f';
	                        break;
	                    case 'v':
	                        str += '\x0B';
	                        break;
	                    case '8':
	                    case '9':
	                        str += ch;
	                        tolerateUnexpectedToken();
	                        break;

	                    default:
	                        if (isOctalDigit(ch)) {
	                            octToDec = octalToDecimal(ch);

	                            octal = octToDec.octal || octal;
	                            str += String.fromCharCode(octToDec.code);
	                        } else {
	                            str += ch;
	                        }
	                        break;
	                    }
	                } else {
	                    ++lineNumber;
	                    if (ch === '\r' && source[index] === '\n') {
	                        ++index;
	                    }
	                    lineStart = index;
	                }
	            } else if (isLineTerminator(ch.charCodeAt(0))) {
	                break;
	            } else {
	                str += ch;
	            }
	        }

	        if (quote !== '') {
	            throwUnexpectedToken();
	        }

	        return {
	            type: Token.StringLiteral,
	            value: str,
	            octal: octal,
	            lineNumber: startLineNumber,
	            lineStart: startLineStart,
	            start: start,
	            end: index
	        };
	    }

	    // ECMA-262 11.8.6 Template Literal Lexical Components

	    function scanTemplate() {
	        var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped;

	        terminated = false;
	        tail = false;
	        start = index;
	        head = (source[index] === '`');
	        rawOffset = 2;

	        ++index;

	        while (index < length) {
	            ch = source[index++];
	            if (ch === '`') {
	                rawOffset = 1;
	                tail = true;
	                terminated = true;
	                break;
	            } else if (ch === '$') {
	                if (source[index] === '{') {
	                    state.curlyStack.push('${');
	                    ++index;
	                    terminated = true;
	                    break;
	                }
	                cooked += ch;
	            } else if (ch === '\\') {
	                ch = source[index++];
	                if (!isLineTerminator(ch.charCodeAt(0))) {
	                    switch (ch) {
	                    case 'n':
	                        cooked += '\n';
	                        break;
	                    case 'r':
	                        cooked += '\r';
	                        break;
	                    case 't':
	                        cooked += '\t';
	                        break;
	                    case 'u':
	                    case 'x':
	                        if (source[index] === '{') {
	                            ++index;
	                            cooked += scanUnicodeCodePointEscape();
	                        } else {
	                            restore = index;
	                            unescaped = scanHexEscape(ch);
	                            if (unescaped) {
	                                cooked += unescaped;
	                            } else {
	                                index = restore;
	                                cooked += ch;
	                            }
	                        }
	                        break;
	                    case 'b':
	                        cooked += '\b';
	                        break;
	                    case 'f':
	                        cooked += '\f';
	                        break;
	                    case 'v':
	                        cooked += '\v';
	                        break;

	                    default:
	                        if (ch === '0') {
	                            if (isDecimalDigit(source.charCodeAt(index))) {
	                                // Illegal: \01 \02 and so on
	                                throwError(Messages.TemplateOctalLiteral);
	                            }
	                            cooked += '\0';
	                        } else if (isOctalDigit(ch)) {
	                            // Illegal: \1 \2
	                            throwError(Messages.TemplateOctalLiteral);
	                        } else {
	                            cooked += ch;
	                        }
	                        break;
	                    }
	                } else {
	                    ++lineNumber;
	                    if (ch === '\r' && source[index] === '\n') {
	                        ++index;
	                    }
	                    lineStart = index;
	                }
	            } else if (isLineTerminator(ch.charCodeAt(0))) {
	                ++lineNumber;
	                if (ch === '\r' && source[index] === '\n') {
	                    ++index;
	                }
	                lineStart = index;
	                cooked += '\n';
	            } else {
	                cooked += ch;
	            }
	        }

	        if (!terminated) {
	            throwUnexpectedToken();
	        }

	        if (!head) {
	            state.curlyStack.pop();
	        }

	        return {
	            type: Token.Template,
	            value: {
	                cooked: cooked,
	                raw: source.slice(start + 1, index - rawOffset)
	            },
	            head: head,
	            tail: tail,
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            start: start,
	            end: index
	        };
	    }

	    // ECMA-262 11.8.5 Regular Expression Literals

	    function testRegExp(pattern, flags) {
	        // The BMP character to use as a replacement for astral symbols when
	        // translating an ES6 "u"-flagged pattern to an ES5-compatible
	        // approximation.
	        // Note: replacing with '\uFFFF' enables false positives in unlikely
	        // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
	        // pattern that would not be detected by this substitution.
	        var astralSubstitute = '\uFFFF',
	            tmp = pattern;

	        if (flags.indexOf('u') >= 0) {
	            tmp = tmp
	                // Replace every Unicode escape sequence with the equivalent
	                // BMP character or a constant ASCII code point in the case of
	                // astral symbols. (See the above note on `astralSubstitute`
	                // for more information.)
	                .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
	                    var codePoint = parseInt($1 || $2, 16);
	                    if (codePoint > 0x10FFFF) {
	                        throwUnexpectedToken(null, Messages.InvalidRegExp);
	                    }
	                    if (codePoint <= 0xFFFF) {
	                        return String.fromCharCode(codePoint);
	                    }
	                    return astralSubstitute;
	                })
	                // Replace each paired surrogate with a single ASCII symbol to
	                // avoid throwing on regular expressions that are only valid in
	                // combination with the "u" flag.
	                .replace(
	                    /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
	                    astralSubstitute
	                );
	        }

	        // First, detect invalid regular expressions.
	        try {
	            RegExp(tmp);
	        } catch (e) {
	            throwUnexpectedToken(null, Messages.InvalidRegExp);
	        }

	        // Return a regular expression object for this pattern-flag pair, or
	        // `null` in case the current environment doesn't support the flags it
	        // uses.
	        try {
	            return new RegExp(pattern, flags);
	        } catch (exception) {
	            return null;
	        }
	    }

	    function scanRegExpBody() {
	        var ch, str, classMarker, terminated, body;

	        ch = source[index];
	        assert(ch === '/', 'Regular expression literal must start with a slash');
	        str = source[index++];

	        classMarker = false;
	        terminated = false;
	        while (index < length) {
	            ch = source[index++];
	            str += ch;
	            if (ch === '\\') {
	                ch = source[index++];
	                // ECMA-262 7.8.5
	                if (isLineTerminator(ch.charCodeAt(0))) {
	                    throwUnexpectedToken(null, Messages.UnterminatedRegExp);
	                }
	                str += ch;
	            } else if (isLineTerminator(ch.charCodeAt(0))) {
	                throwUnexpectedToken(null, Messages.UnterminatedRegExp);
	            } else if (classMarker) {
	                if (ch === ']') {
	                    classMarker = false;
	                }
	            } else {
	                if (ch === '/') {
	                    terminated = true;
	                    break;
	                } else if (ch === '[') {
	                    classMarker = true;
	                }
	            }
	        }

	        if (!terminated) {
	            throwUnexpectedToken(null, Messages.UnterminatedRegExp);
	        }

	        // Exclude leading and trailing slash.
	        body = str.substr(1, str.length - 2);
	        return {
	            value: body,
	            literal: str
	        };
	    }

	    function scanRegExpFlags() {
	        var ch, str, flags, restore;

	        str = '';
	        flags = '';
	        while (index < length) {
	            ch = source[index];
	            if (!isIdentifierPart(ch.charCodeAt(0))) {
	                break;
	            }

	            ++index;
	            if (ch === '\\' && index < length) {
	                ch = source[index];
	                if (ch === 'u') {
	                    ++index;
	                    restore = index;
	                    ch = scanHexEscape('u');
	                    if (ch) {
	                        flags += ch;
	                        for (str += '\\u'; restore < index; ++restore) {
	                            str += source[restore];
	                        }
	                    } else {
	                        index = restore;
	                        flags += 'u';
	                        str += '\\u';
	                    }
	                    tolerateUnexpectedToken();
	                } else {
	                    str += '\\';
	                    tolerateUnexpectedToken();
	                }
	            } else {
	                flags += ch;
	                str += ch;
	            }
	        }

	        return {
	            value: flags,
	            literal: str
	        };
	    }

	    function scanRegExp() {
	        var start, body, flags, value;
	        scanning = true;

	        lookahead = null;
	        skipComment();
	        start = index;

	        body = scanRegExpBody();
	        flags = scanRegExpFlags();
	        value = testRegExp(body.value, flags.value);
	        scanning = false;
	        if (extra.tokenize) {
	            return {
	                type: Token.RegularExpression,
	                value: value,
	                regex: {
	                    pattern: body.value,
	                    flags: flags.value
	                },
	                lineNumber: lineNumber,
	                lineStart: lineStart,
	                start: start,
	                end: index
	            };
	        }

	        return {
	            literal: body.literal + flags.literal,
	            value: value,
	            regex: {
	                pattern: body.value,
	                flags: flags.value
	            },
	            start: start,
	            end: index
	        };
	    }

	    function collectRegex() {
	        var pos, loc, regex, token;

	        skipComment();

	        pos = index;
	        loc = {
	            start: {
	                line: lineNumber,
	                column: index - lineStart
	            }
	        };

	        regex = scanRegExp();

	        loc.end = {
	            line: lineNumber,
	            column: index - lineStart
	        };

	        /* istanbul ignore next */
	        if (!extra.tokenize) {
	            // Pop the previous token, which is likely '/' or '/='
	            if (extra.tokens.length > 0) {
	                token = extra.tokens[extra.tokens.length - 1];
	                if (token.range[0] === pos && token.type === 'Punctuator') {
	                    if (token.value === '/' || token.value === '/=') {
	                        extra.tokens.pop();
	                    }
	                }
	            }

	            extra.tokens.push({
	                type: 'RegularExpression',
	                value: regex.literal,
	                regex: regex.regex,
	                range: [pos, index],
	                loc: loc
	            });
	        }

	        return regex;
	    }

	    function isIdentifierName(token) {
	        return token.type === Token.Identifier ||
	            token.type === Token.Keyword ||
	            token.type === Token.BooleanLiteral ||
	            token.type === Token.NullLiteral;
	    }

	    // Using the following algorithm:
	    // https://github.com/mozilla/sweet.js/wiki/design

	    function advanceSlash() {
	        var regex, previous, check;

	        function testKeyword(value) {
	            return value && (value.length > 1) && (value[0] >= 'a') && (value[0] <= 'z');
	        }

	        previous = extra.tokenValues[extra.tokens.length - 1];
	        regex = (previous !== null);

	        switch (previous) {
	        case 'this':
	        case ']':
	            regex = false;
	            break;

	        case ')':
	            check = extra.tokenValues[extra.openParenToken - 1];
	            regex = (check === 'if' || check === 'while' || check === 'for' || check === 'with');
	            break;

	        case '}':
	            // Dividing a function by anything makes little sense,
	            // but we have to check for that.
	            regex = false;
	            if (testKeyword(extra.tokenValues[extra.openCurlyToken - 3])) {
	                // Anonymous function, e.g. function(){} /42
	                check = extra.tokenValues[extra.openCurlyToken - 4];
	                regex = check ? (FnExprTokens.indexOf(check) < 0) : false;
	            } else if (testKeyword(extra.tokenValues[extra.openCurlyToken - 4])) {
	                // Named function, e.g. function f(){} /42/
	                check = extra.tokenValues[extra.openCurlyToken - 5];
	                regex = check ? (FnExprTokens.indexOf(check) < 0) : true;
	            }
	        }

	        return regex ? collectRegex() : scanPunctuator();
	    }

	    function advance() {
	        var cp, token;

	        if (index >= length) {
	            return {
	                type: Token.EOF,
	                lineNumber: lineNumber,
	                lineStart: lineStart,
	                start: index,
	                end: index
	            };
	        }

	        cp = source.charCodeAt(index);

	        if (isIdentifierStart(cp)) {
	            token = scanIdentifier();
	            if (strict && isStrictModeReservedWord(token.value)) {
	                token.type = Token.Keyword;
	            }
	            return token;
	        }

	        // Very common: ( and ) and ;
	        if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
	            return scanPunctuator();
	        }

	        // String literal starts with single quote (U+0027) or double quote (U+0022).
	        if (cp === 0x27 || cp === 0x22) {
	            return scanStringLiteral();
	        }

	        // Dot (.) U+002E can also start a floating-point number, hence the need
	        // to check the next character.
	        if (cp === 0x2E) {
	            if (isDecimalDigit(source.charCodeAt(index + 1))) {
	                return scanNumericLiteral();
	            }
	            return scanPunctuator();
	        }

	        if (isDecimalDigit(cp)) {
	            return scanNumericLiteral();
	        }

	        // Slash (/) U+002F can also start a regex.
	        if (extra.tokenize && cp === 0x2F) {
	            return advanceSlash();
	        }

	        // Template literals start with ` (U+0060) for template head
	        // or } (U+007D) for template middle or template tail.
	        if (cp === 0x60 || (cp === 0x7D && state.curlyStack[state.curlyStack.length - 1] === '${')) {
	            return scanTemplate();
	        }

	        // Possible identifier start in a surrogate pair.
	        if (cp >= 0xD800 && cp < 0xDFFF) {
	            cp = codePointAt(index);
	            if (isIdentifierStart(cp)) {
	                return scanIdentifier();
	            }
	        }

	        return scanPunctuator();
	    }

	    function collectToken() {
	        var loc, token, value, entry;

	        loc = {
	            start: {
	                line: lineNumber,
	                column: index - lineStart
	            }
	        };

	        token = advance();
	        loc.end = {
	            line: lineNumber,
	            column: index - lineStart
	        };

	        if (token.type !== Token.EOF) {
	            value = source.slice(token.start, token.end);
	            entry = {
	                type: TokenName[token.type],
	                value: value,
	                range: [token.start, token.end],
	                loc: loc
	            };
	            if (token.regex) {
	                entry.regex = {
	                    pattern: token.regex.pattern,
	                    flags: token.regex.flags
	                };
	            }
	            if (extra.tokenValues) {
	                extra.tokenValues.push((entry.type === 'Punctuator' || entry.type === 'Keyword') ? entry.value : null);
	            }
	            if (extra.tokenize) {
	                if (!extra.range) {
	                    delete entry.range;
	                }
	                if (!extra.loc) {
	                    delete entry.loc;
	                }
	                if (extra.delegate) {
	                    entry = extra.delegate(entry);
	                }
	            }
	            extra.tokens.push(entry);
	        }

	        return token;
	    }

	    function lex() {
	        var token;
	        scanning = true;

	        lastIndex = index;
	        lastLineNumber = lineNumber;
	        lastLineStart = lineStart;

	        skipComment();

	        token = lookahead;

	        startIndex = index;
	        startLineNumber = lineNumber;
	        startLineStart = lineStart;

	        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
	        scanning = false;
	        return token;
	    }

	    function peek() {
	        scanning = true;

	        skipComment();

	        lastIndex = index;
	        lastLineNumber = lineNumber;
	        lastLineStart = lineStart;

	        startIndex = index;
	        startLineNumber = lineNumber;
	        startLineStart = lineStart;

	        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
	        scanning = false;
	    }

	    function Position() {
	        this.line = startLineNumber;
	        this.column = startIndex - startLineStart;
	    }

	    function SourceLocation() {
	        this.start = new Position();
	        this.end = null;
	    }

	    function WrappingSourceLocation(startToken) {
	        this.start = {
	            line: startToken.lineNumber,
	            column: startToken.start - startToken.lineStart
	        };
	        this.end = null;
	    }

	    function Node() {
	        if (extra.range) {
	            this.range = [startIndex, 0];
	        }
	        if (extra.loc) {
	            this.loc = new SourceLocation();
	        }
	    }

	    function WrappingNode(startToken) {
	        if (extra.range) {
	            this.range = [startToken.start, 0];
	        }
	        if (extra.loc) {
	            this.loc = new WrappingSourceLocation(startToken);
	        }
	    }

	    WrappingNode.prototype = Node.prototype = {

	        processComment: function () {
	            var lastChild,
	                innerComments,
	                leadingComments,
	                trailingComments,
	                bottomRight = extra.bottomRightStack,
	                i,
	                comment,
	                last = bottomRight[bottomRight.length - 1];

	            if (this.type === Syntax.Program) {
	                if (this.body.length > 0) {
	                    return;
	                }
	            }
	            /**
	             * patch innnerComments for properties empty block
	             * `function a() {/** comments **\/}`
	             */

	            if (this.type === Syntax.BlockStatement && this.body.length === 0) {
	                innerComments = [];
	                for (i = extra.leadingComments.length - 1; i >= 0; --i) {
	                    comment = extra.leadingComments[i];
	                    if (this.range[1] >= comment.range[1]) {
	                        innerComments.unshift(comment);
	                        extra.leadingComments.splice(i, 1);
	                        extra.trailingComments.splice(i, 1);
	                    }
	                }
	                if (innerComments.length) {
	                    this.innerComments = innerComments;
	                    //bottomRight.push(this);
	                    return;
	                }
	            }

	            if (extra.trailingComments.length > 0) {
	                trailingComments = [];
	                for (i = extra.trailingComments.length - 1; i >= 0; --i) {
	                    comment = extra.trailingComments[i];
	                    if (comment.range[0] >= this.range[1]) {
	                        trailingComments.unshift(comment);
	                        extra.trailingComments.splice(i, 1);
	                    }
	                }
	                extra.trailingComments = [];
	            } else {
	                if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) {
	                    trailingComments = last.trailingComments;
	                    delete last.trailingComments;
	                }
	            }

	            // Eating the stack.
	            while (last && last.range[0] >= this.range[0]) {
	                lastChild = bottomRight.pop();
	                last = bottomRight[bottomRight.length - 1];
	            }

	            if (lastChild) {
	                if (lastChild.leadingComments) {
	                    leadingComments = [];
	                    for (i = lastChild.leadingComments.length - 1; i >= 0; --i) {
	                        comment = lastChild.leadingComments[i];
	                        if (comment.range[1] <= this.range[0]) {
	                            leadingComments.unshift(comment);
	                            lastChild.leadingComments.splice(i, 1);
	                        }
	                    }

	                    if (!lastChild.leadingComments.length) {
	                        lastChild.leadingComments = undefined;
	                    }
	                }
	            } else if (extra.leadingComments.length > 0) {
	                leadingComments = [];
	                for (i = extra.leadingComments.length - 1; i >= 0; --i) {
	                    comment = extra.leadingComments[i];
	                    if (comment.range[1] <= this.range[0]) {
	                        leadingComments.unshift(comment);
	                        extra.leadingComments.splice(i, 1);
	                    }
	                }
	            }


	            if (leadingComments && leadingComments.length > 0) {
	                this.leadingComments = leadingComments;
	            }
	            if (trailingComments && trailingComments.length > 0) {
	                this.trailingComments = trailingComments;
	            }

	            bottomRight.push(this);
	        },

	        finish: function () {
	            if (extra.range) {
	                this.range[1] = lastIndex;
	            }
	            if (extra.loc) {
	                this.loc.end = {
	                    line: lastLineNumber,
	                    column: lastIndex - lastLineStart
	                };
	                if (extra.source) {
	                    this.loc.source = extra.source;
	                }
	            }

	            if (extra.attachComment) {
	                this.processComment();
	            }
	        },

	        finishArrayExpression: function (elements) {
	            this.type = Syntax.ArrayExpression;
	            this.elements = elements;
	            this.finish();
	            return this;
	        },

	        finishArrayPattern: function (elements) {
	            this.type = Syntax.ArrayPattern;
	            this.elements = elements;
	            this.finish();
	            return this;
	        },

	        finishArrowFunctionExpression: function (params, defaults, body, expression) {
	            this.type = Syntax.ArrowFunctionExpression;
	            this.id = null;
	            this.params = params;
	            this.defaults = defaults;
	            this.body = body;
	            this.generator = false;
	            this.expression = expression;
	            this.finish();
	            return this;
	        },

	        finishAssignmentExpression: function (operator, left, right) {
	            this.type = Syntax.AssignmentExpression;
	            this.operator = operator;
	            this.left = left;
	            this.right = right;
	            this.finish();
	            return this;
	        },

	        finishAssignmentPattern: function (left, right) {
	            this.type = Syntax.AssignmentPattern;
	            this.left = left;
	            this.right = right;
	            this.finish();
	            return this;
	        },

	        finishBinaryExpression: function (operator, left, right) {
	            this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression;
	            this.operator = operator;
	            this.left = left;
	            this.right = right;
	            this.finish();
	            return this;
	        },

	        finishBlockStatement: function (body) {
	            this.type = Syntax.BlockStatement;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishBreakStatement: function (label) {
	            this.type = Syntax.BreakStatement;
	            this.label = label;
	            this.finish();
	            return this;
	        },

	        finishCallExpression: function (callee, args) {
	            this.type = Syntax.CallExpression;
	            this.callee = callee;
	            this.arguments = args;
	            this.finish();
	            return this;
	        },

	        finishCatchClause: function (param, body) {
	            this.type = Syntax.CatchClause;
	            this.param = param;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishClassBody: function (body) {
	            this.type = Syntax.ClassBody;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishClassDeclaration: function (id, superClass, body) {
	            this.type = Syntax.ClassDeclaration;
	            this.id = id;
	            this.superClass = superClass;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishClassExpression: function (id, superClass, body) {
	            this.type = Syntax.ClassExpression;
	            this.id = id;
	            this.superClass = superClass;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishConditionalExpression: function (test, consequent, alternate) {
	            this.type = Syntax.ConditionalExpression;
	            this.test = test;
	            this.consequent = consequent;
	            this.alternate = alternate;
	            this.finish();
	            return this;
	        },

	        finishContinueStatement: function (label) {
	            this.type = Syntax.ContinueStatement;
	            this.label = label;
	            this.finish();
	            return this;
	        },

	        finishDebuggerStatement: function () {
	            this.type = Syntax.DebuggerStatement;
	            this.finish();
	            return this;
	        },

	        finishDoWhileStatement: function (body, test) {
	            this.type = Syntax.DoWhileStatement;
	            this.body = body;
	            this.test = test;
	            this.finish();
	            return this;
	        },

	        finishEmptyStatement: function () {
	            this.type = Syntax.EmptyStatement;
	            this.finish();
	            return this;
	        },

	        finishExpressionStatement: function (expression) {
	            this.type = Syntax.ExpressionStatement;
	            this.expression = expression;
	            this.finish();
	            return this;
	        },

	        finishForStatement: function (init, test, update, body) {
	            this.type = Syntax.ForStatement;
	            this.init = init;
	            this.test = test;
	            this.update = update;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishForOfStatement: function (left, right, body) {
	            this.type = Syntax.ForOfStatement;
	            this.left = left;
	            this.right = right;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishForInStatement: function (left, right, body) {
	            this.type = Syntax.ForInStatement;
	            this.left = left;
	            this.right = right;
	            this.body = body;
	            this.each = false;
	            this.finish();
	            return this;
	        },

	        finishFunctionDeclaration: function (id, params, defaults, body, generator) {
	            this.type = Syntax.FunctionDeclaration;
	            this.id = id;
	            this.params = params;
	            this.defaults = defaults;
	            this.body = body;
	            this.generator = generator;
	            this.expression = false;
	            this.finish();
	            return this;
	        },

	        finishFunctionExpression: function (id, params, defaults, body, generator) {
	            this.type = Syntax.FunctionExpression;
	            this.id = id;
	            this.params = params;
	            this.defaults = defaults;
	            this.body = body;
	            this.generator = generator;
	            this.expression = false;
	            this.finish();
	            return this;
	        },

	        finishIdentifier: function (name) {
	            this.type = Syntax.Identifier;
	            this.name = name;
	            this.finish();
	            return this;
	        },

	        finishIfStatement: function (test, consequent, alternate) {
	            this.type = Syntax.IfStatement;
	            this.test = test;
	            this.consequent = consequent;
	            this.alternate = alternate;
	            this.finish();
	            return this;
	        },

	        finishLabeledStatement: function (label, body) {
	            this.type = Syntax.LabeledStatement;
	            this.label = label;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishLiteral: function (token) {
	            this.type = Syntax.Literal;
	            this.value = token.value;
	            this.raw = source.slice(token.start, token.end);
	            if (token.regex) {
	                this.regex = token.regex;
	            }
	            this.finish();
	            return this;
	        },

	        finishMemberExpression: function (accessor, object, property) {
	            this.type = Syntax.MemberExpression;
	            this.computed = accessor === '[';
	            this.object = object;
	            this.property = property;
	            this.finish();
	            return this;
	        },

	        finishMetaProperty: function (meta, property) {
	            this.type = Syntax.MetaProperty;
	            this.meta = meta;
	            this.property = property;
	            this.finish();
	            return this;
	        },

	        finishNewExpression: function (callee, args) {
	            this.type = Syntax.NewExpression;
	            this.callee = callee;
	            this.arguments = args;
	            this.finish();
	            return this;
	        },

	        finishObjectExpression: function (properties) {
	            this.type = Syntax.ObjectExpression;
	            this.properties = properties;
	            this.finish();
	            return this;
	        },

	        finishObjectPattern: function (properties) {
	            this.type = Syntax.ObjectPattern;
	            this.properties = properties;
	            this.finish();
	            return this;
	        },

	        finishPostfixExpression: function (operator, argument) {
	            this.type = Syntax.UpdateExpression;
	            this.operator = operator;
	            this.argument = argument;
	            this.prefix = false;
	            this.finish();
	            return this;
	        },

	        finishProgram: function (body, sourceType) {
	            this.type = Syntax.Program;
	            this.body = body;
	            this.sourceType = sourceType;
	            this.finish();
	            return this;
	        },

	        finishProperty: function (kind, key, computed, value, method, shorthand) {
	            this.type = Syntax.Property;
	            this.key = key;
	            this.computed = computed;
	            this.value = value;
	            this.kind = kind;
	            this.method = method;
	            this.shorthand = shorthand;
	            this.finish();
	            return this;
	        },

	        finishRestElement: function (argument) {
	            this.type = Syntax.RestElement;
	            this.argument = argument;
	            this.finish();
	            return this;
	        },

	        finishReturnStatement: function (argument) {
	            this.type = Syntax.ReturnStatement;
	            this.argument = argument;
	            this.finish();
	            return this;
	        },

	        finishSequenceExpression: function (expressions) {
	            this.type = Syntax.SequenceExpression;
	            this.expressions = expressions;
	            this.finish();
	            return this;
	        },

	        finishSpreadElement: function (argument) {
	            this.type = Syntax.SpreadElement;
	            this.argument = argument;
	            this.finish();
	            return this;
	        },

	        finishSwitchCase: function (test, consequent) {
	            this.type = Syntax.SwitchCase;
	            this.test = test;
	            this.consequent = consequent;
	            this.finish();
	            return this;
	        },

	        finishSuper: function () {
	            this.type = Syntax.Super;
	            this.finish();
	            return this;
	        },

	        finishSwitchStatement: function (discriminant, cases) {
	            this.type = Syntax.SwitchStatement;
	            this.discriminant = discriminant;
	            this.cases = cases;
	            this.finish();
	            return this;
	        },

	        finishTaggedTemplateExpression: function (tag, quasi) {
	            this.type = Syntax.TaggedTemplateExpression;
	            this.tag = tag;
	            this.quasi = quasi;
	            this.finish();
	            return this;
	        },

	        finishTemplateElement: function (value, tail) {
	            this.type = Syntax.TemplateElement;
	            this.value = value;
	            this.tail = tail;
	            this.finish();
	            return this;
	        },

	        finishTemplateLiteral: function (quasis, expressions) {
	            this.type = Syntax.TemplateLiteral;
	            this.quasis = quasis;
	            this.expressions = expressions;
	            this.finish();
	            return this;
	        },

	        finishThisExpression: function () {
	            this.type = Syntax.ThisExpression;
	            this.finish();
	            return this;
	        },

	        finishThrowStatement: function (argument) {
	            this.type = Syntax.ThrowStatement;
	            this.argument = argument;
	            this.finish();
	            return this;
	        },

	        finishTryStatement: function (block, handler, finalizer) {
	            this.type = Syntax.TryStatement;
	            this.block = block;
	            this.guardedHandlers = [];
	            this.handlers = handler ? [handler] : [];
	            this.handler = handler;
	            this.finalizer = finalizer;
	            this.finish();
	            return this;
	        },

	        finishUnaryExpression: function (operator, argument) {
	            this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression;
	            this.operator = operator;
	            this.argument = argument;
	            this.prefix = true;
	            this.finish();
	            return this;
	        },

	        finishVariableDeclaration: function (declarations) {
	            this.type = Syntax.VariableDeclaration;
	            this.declarations = declarations;
	            this.kind = 'var';
	            this.finish();
	            return this;
	        },

	        finishLexicalDeclaration: function (declarations, kind) {
	            this.type = Syntax.VariableDeclaration;
	            this.declarations = declarations;
	            this.kind = kind;
	            this.finish();
	            return this;
	        },

	        finishVariableDeclarator: function (id, init) {
	            this.type = Syntax.VariableDeclarator;
	            this.id = id;
	            this.init = init;
	            this.finish();
	            return this;
	        },

	        finishWhileStatement: function (test, body) {
	            this.type = Syntax.WhileStatement;
	            this.test = test;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishWithStatement: function (object, body) {
	            this.type = Syntax.WithStatement;
	            this.object = object;
	            this.body = body;
	            this.finish();
	            return this;
	        },

	        finishExportSpecifier: function (local, exported) {
	            this.type = Syntax.ExportSpecifier;
	            this.exported = exported || local;
	            this.local = local;
	            this.finish();
	            return this;
	        },

	        finishImportDefaultSpecifier: function (local) {
	            this.type = Syntax.ImportDefaultSpecifier;
	            this.local = local;
	            this.finish();
	            return this;
	        },

	        finishImportNamespaceSpecifier: function (local) {
	            this.type = Syntax.ImportNamespaceSpecifier;
	            this.local = local;
	            this.finish();
	            return this;
	        },

	        finishExportNamedDeclaration: function (declaration, specifiers, src) {
	            this.type = Syntax.ExportNamedDeclaration;
	            this.declaration = declaration;
	            this.specifiers = specifiers;
	            this.source = src;
	            this.finish();
	            return this;
	        },

	        finishExportDefaultDeclaration: function (declaration) {
	            this.type = Syntax.ExportDefaultDeclaration;
	            this.declaration = declaration;
	            this.finish();
	            return this;
	        },

	        finishExportAllDeclaration: function (src) {
	            this.type = Syntax.ExportAllDeclaration;
	            this.source = src;
	            this.finish();
	            return this;
	        },

	        finishImportSpecifier: function (local, imported) {
	            this.type = Syntax.ImportSpecifier;
	            this.local = local || imported;
	            this.imported = imported;
	            this.finish();
	            return this;
	        },

	        finishImportDeclaration: function (specifiers, src) {
	            this.type = Syntax.ImportDeclaration;
	            this.specifiers = specifiers;
	            this.source = src;
	            this.finish();
	            return this;
	        },

	        finishYieldExpression: function (argument, delegate) {
	            this.type = Syntax.YieldExpression;
	            this.argument = argument;
	            this.delegate = delegate;
	            this.finish();
	            return this;
	        }
	    };


	    function recordError(error) {
	        var e, existing;

	        for (e = 0; e < extra.errors.length; e++) {
	            existing = extra.errors[e];
	            // Prevent duplicated error.
	            /* istanbul ignore next */
	            if (existing.index === error.index && existing.message === error.message) {
	                return;
	            }
	        }

	        extra.errors.push(error);
	    }

	    function constructError(msg, column) {
	        var error = new Error(msg);
	        try {
	            throw error;
	        } catch (base) {
	            /* istanbul ignore else */
	            if (Object.create && Object.defineProperty) {
	                error = Object.create(base);
	                Object.defineProperty(error, 'column', { value: column });
	            }
	        } finally {
	            return error;
	        }
	    }

	    function createError(line, pos, description) {
	        var msg, column, error;

	        msg = 'Line ' + line + ': ' + description;
	        column = pos - (scanning ? lineStart : lastLineStart) + 1;
	        error = constructError(msg, column);
	        error.lineNumber = line;
	        error.description = description;
	        error.index = pos;
	        return error;
	    }

	    // Throw an exception

	    function throwError(messageFormat) {
	        var args, msg;

	        args = Array.prototype.slice.call(arguments, 1);
	        msg = messageFormat.replace(/%(\d)/g,
	            function (whole, idx) {
	                assert(idx < args.length, 'Message reference must be in range');
	                return args[idx];
	            }
	        );

	        throw createError(lastLineNumber, lastIndex, msg);
	    }

	    function tolerateError(messageFormat) {
	        var args, msg, error;

	        args = Array.prototype.slice.call(arguments, 1);
	        /* istanbul ignore next */
	        msg = messageFormat.replace(/%(\d)/g,
	            function (whole, idx) {
	                assert(idx < args.length, 'Message reference must be in range');
	                return args[idx];
	            }
	        );

	        error = createError(lineNumber, lastIndex, msg);
	        if (extra.errors) {
	            recordError(error);
	        } else {
	            throw error;
	        }
	    }

	    // Throw an exception because of the token.

	    function unexpectedTokenError(token, message) {
	        var value, msg = message || Messages.UnexpectedToken;

	        if (token) {
	            if (!message) {
	                msg = (token.type === Token.EOF) ? Messages.UnexpectedEOS :
	                    (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier :
	                    (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber :
	                    (token.type === Token.StringLiteral) ? Messages.UnexpectedString :
	                    (token.type === Token.Template) ? Messages.UnexpectedTemplate :
	                    Messages.UnexpectedToken;

	                if (token.type === Token.Keyword) {
	                    if (isFutureReservedWord(token.value)) {
	                        msg = Messages.UnexpectedReserved;
	                    } else if (strict && isStrictModeReservedWord(token.value)) {
	                        msg = Messages.StrictReservedWord;
	                    }
	                }
	            }

	            value = (token.type === Token.Template) ? token.value.raw : token.value;
	        } else {
	            value = 'ILLEGAL';
	        }

	        msg = msg.replace('%0', value);

	        return (token && typeof token.lineNumber === 'number') ?
	            createError(token.lineNumber, token.start, msg) :
	            createError(scanning ? lineNumber : lastLineNumber, scanning ? index : lastIndex, msg);
	    }

	    function throwUnexpectedToken(token, message) {
	        throw unexpectedTokenError(token, message);
	    }

	    function tolerateUnexpectedToken(token, message) {
	        var error = unexpectedTokenError(token, message);
	        if (extra.errors) {
	            recordError(error);
	        } else {
	            throw error;
	        }
	    }

	    // Expect the next token to match the specified punctuator.
	    // If not, an exception will be thrown.

	    function expect(value) {
	        var token = lex();
	        if (token.type !== Token.Punctuator || token.value !== value) {
	            throwUnexpectedToken(token);
	        }
	    }

	    /**
	     * @name expectCommaSeparator
	     * @description Quietly expect a comma when in tolerant mode, otherwise delegates
	     * to <code>expect(value)</code>
	     * @since 2.0
	     */
	    function expectCommaSeparator() {
	        var token;

	        if (extra.errors) {
	            token = lookahead;
	            if (token.type === Token.Punctuator && token.value === ',') {
	                lex();
	            } else if (token.type === Token.Punctuator && token.value === ';') {
	                lex();
	                tolerateUnexpectedToken(token);
	            } else {
	                tolerateUnexpectedToken(token, Messages.UnexpectedToken);
	            }
	        } else {
	            expect(',');
	        }
	    }

	    // Expect the next token to match the specified keyword.
	    // If not, an exception will be thrown.

	    function expectKeyword(keyword) {
	        var token = lex();
	        if (token.type !== Token.Keyword || token.value !== keyword) {
	            throwUnexpectedToken(token);
	        }
	    }

	    // Return true if the next token matches the specified punctuator.

	    function match(value) {
	        return lookahead.type === Token.Punctuator && lookahead.value === value;
	    }

	    // Return true if the next token matches the specified keyword

	    function matchKeyword(keyword) {
	        return lookahead.type === Token.Keyword && lookahead.value === keyword;
	    }

	    // Return true if the next token matches the specified contextual keyword
	    // (where an identifier is sometimes a keyword depending on the context)

	    function matchContextualKeyword(keyword) {
	        return lookahead.type === Token.Identifier && lookahead.value === keyword;
	    }

	    // Return true if the next token is an assignment operator

	    function matchAssign() {
	        var op;

	        if (lookahead.type !== Token.Punctuator) {
	            return false;
	        }
	        op = lookahead.value;
	        return op === '=' ||
	            op === '*=' ||
	            op === '/=' ||
	            op === '%=' ||
	            op === '+=' ||
	            op === '-=' ||
	            op === '<<=' ||
	            op === '>>=' ||
	            op === '>>>=' ||
	            op === '&=' ||
	            op === '^=' ||
	            op === '|=';
	    }

	    function consumeSemicolon() {
	        // Catch the very common case first: immediately a semicolon (U+003B).
	        if (source.charCodeAt(startIndex) === 0x3B || match(';')) {
	            lex();
	            return;
	        }

	        if (hasLineTerminator) {
	            return;
	        }

	        // FIXME(ikarienator): this is seemingly an issue in the previous location info convention.
	        lastIndex = startIndex;
	        lastLineNumber = startLineNumber;
	        lastLineStart = startLineStart;

	        if (lookahead.type !== Token.EOF && !match('}')) {
	            throwUnexpectedToken(lookahead);
	        }
	    }

	    // Cover grammar support.
	    //
	    // When an assignment expression position starts with an left parenthesis, the determination of the type
	    // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
	    // or the first comma. This situation also defers the determination of all the expressions nested in the pair.
	    //
	    // There are three productions that can be parsed in a parentheses pair that needs to be determined
	    // after the outermost pair is closed. They are:
	    //
	    //   1. AssignmentExpression
	    //   2. BindingElements
	    //   3. AssignmentTargets
	    //
	    // In order to avoid exponential backtracking, we use two flags to denote if the production can be
	    // binding element or assignment target.
	    //
	    // The three productions have the relationship:
	    //
	    //   BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression
	    //
	    // with a single exception that CoverInitializedName when used directly in an Expression, generates
	    // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
	    // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
	    //
	    // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
	    // effect the current flags. This means the production the parser parses is only used as an expression. Therefore
	    // the CoverInitializedName check is conducted.
	    //
	    // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
	    // the flags outside of the parser. This means the production the parser parses is used as a part of a potential
	    // pattern. The CoverInitializedName check is deferred.
	    function isolateCoverGrammar(parser) {
	        var oldIsBindingElement = isBindingElement,
	            oldIsAssignmentTarget = isAssignmentTarget,
	            oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
	            result;
	        isBindingElement = true;
	        isAssignmentTarget = true;
	        firstCoverInitializedNameError = null;
	        result = parser();
	        if (firstCoverInitializedNameError !== null) {
	            throwUnexpectedToken(firstCoverInitializedNameError);
	        }
	        isBindingElement = oldIsBindingElement;
	        isAssignmentTarget = oldIsAssignmentTarget;
	        firstCoverInitializedNameError = oldFirstCoverInitializedNameError;
	        return result;
	    }

	    function inheritCoverGrammar(parser) {
	        var oldIsBindingElement = isBindingElement,
	            oldIsAssignmentTarget = isAssignmentTarget,
	            oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
	            result;
	        isBindingElement = true;
	        isAssignmentTarget = true;
	        firstCoverInitializedNameError = null;
	        result = parser();
	        isBindingElement = isBindingElement && oldIsBindingElement;
	        isAssignmentTarget = isAssignmentTarget && oldIsAssignmentTarget;
	        firstCoverInitializedNameError = oldFirstCoverInitializedNameError || firstCoverInitializedNameError;
	        return result;
	    }

	    // ECMA-262 13.3.3 Destructuring Binding Patterns

	    function parseArrayPattern(params, kind) {
	        var node = new Node(), elements = [], rest, restNode;
	        expect('[');

	        while (!match(']')) {
	            if (match(',')) {
	                lex();
	                elements.push(null);
	            } else {
	                if (match('...')) {
	                    restNode = new Node();
	                    lex();
	                    params.push(lookahead);
	                    rest = parseVariableIdentifier(kind);
	                    elements.push(restNode.finishRestElement(rest));
	                    break;
	                } else {
	                    elements.push(parsePatternWithDefault(params, kind));
	                }
	                if (!match(']')) {
	                    expect(',');
	                }
	            }

	        }

	        expect(']');

	        return node.finishArrayPattern(elements);
	    }

	    function parsePropertyPattern(params, kind) {
	        var node = new Node(), key, keyToken, computed = match('['), init;
	        if (lookahead.type === Token.Identifier) {
	            keyToken = lookahead;
	            key = parseVariableIdentifier();
	            if (match('=')) {
	                params.push(keyToken);
	                lex();
	                init = parseAssignmentExpression();

	                return node.finishProperty(
	                    'init', key, false,
	                    new WrappingNode(keyToken).finishAssignmentPattern(key, init), false, false);
	            } else if (!match(':')) {
	                params.push(keyToken);
	                return node.finishProperty('init', key, false, key, false, true);
	            }
	        } else {
	            key = parseObjectPropertyKey();
	        }
	        expect(':');
	        init = parsePatternWithDefault(params, kind);
	        return node.finishProperty('init', key, computed, init, false, false);
	    }

	    function parseObjectPattern(params, kind) {
	        var node = new Node(), properties = [];

	        expect('{');

	        while (!match('}')) {
	            properties.push(parsePropertyPattern(params, kind));
	            if (!match('}')) {
	                expect(',');
	            }
	        }

	        lex();

	        return node.finishObjectPattern(properties);
	    }

	    function parsePattern(params, kind) {
	        if (match('[')) {
	            return parseArrayPattern(params, kind);
	        } else if (match('{')) {
	            return parseObjectPattern(params, kind);
	        } else if (matchKeyword('let')) {
	            if (kind === 'const' || kind === 'let') {
	                tolerateUnexpectedToken(lookahead, Messages.UnexpectedToken);
	            }
	        }

	        params.push(lookahead);
	        return parseVariableIdentifier(kind);
	    }

	    function parsePatternWithDefault(params, kind) {
	        var startToken = lookahead, pattern, previousAllowYield, right;
	        pattern = parsePattern(params, kind);
	        if (match('=')) {
	            lex();
	            previousAllowYield = state.allowYield;
	            state.allowYield = true;
	            right = isolateCoverGrammar(parseAssignmentExpression);
	            state.allowYield = previousAllowYield;
	            pattern = new WrappingNode(startToken).finishAssignmentPattern(pattern, right);
	        }
	        return pattern;
	    }

	    // ECMA-262 12.2.5 Array Initializer

	    function parseArrayInitializer() {
	        var elements = [], node = new Node(), restSpread;

	        expect('[');

	        while (!match(']')) {
	            if (match(',')) {
	                lex();
	                elements.push(null);
	            } else if (match('...')) {
	                restSpread = new Node();
	                lex();
	                restSpread.finishSpreadElement(inheritCoverGrammar(parseAssignmentExpression));

	                if (!match(']')) {
	                    isAssignmentTarget = isBindingElement = false;
	                    expect(',');
	                }
	                elements.push(restSpread);
	            } else {
	                elements.push(inheritCoverGrammar(parseAssignmentExpression));

	                if (!match(']')) {
	                    expect(',');
	                }
	            }
	        }

	        lex();

	        return node.finishArrayExpression(elements);
	    }

	    // ECMA-262 12.2.6 Object Initializer

	    function parsePropertyFunction(node, paramInfo, isGenerator) {
	        var previousStrict, body;

	        isAssignmentTarget = isBindingElement = false;

	        previousStrict = strict;
	        body = isolateCoverGrammar(parseFunctionSourceElements);

	        if (strict && paramInfo.firstRestricted) {
	            tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message);
	        }
	        if (strict && paramInfo.stricted) {
	            tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message);
	        }

	        strict = previousStrict;
	        return node.finishFunctionExpression(null, paramInfo.params, paramInfo.defaults, body, isGenerator);
	    }

	    function parsePropertyMethodFunction() {
	        var params, method, node = new Node(),
	            previousAllowYield = state.allowYield;

	        state.allowYield = false;
	        params = parseParams();
	        state.allowYield = previousAllowYield;

	        state.allowYield = false;
	        method = parsePropertyFunction(node, params, false);
	        state.allowYield = previousAllowYield;

	        return method;
	    }

	    function parseObjectPropertyKey() {
	        var token, node = new Node(), expr;

	        token = lex();

	        // Note: This function is called only from parseObjectProperty(), where
	        // EOF and Punctuator tokens are already filtered out.

	        switch (token.type) {
	        case Token.StringLiteral:
	        case Token.NumericLiteral:
	            if (strict && token.octal) {
	                tolerateUnexpectedToken(token, Messages.StrictOctalLiteral);
	            }
	            return node.finishLiteral(token);
	        case Token.Identifier:
	        case Token.BooleanLiteral:
	        case Token.NullLiteral:
	        case Token.Keyword:
	            return node.finishIdentifier(token.value);
	        case Token.Punctuator:
	            if (token.value === '[') {
	                expr = isolateCoverGrammar(parseAssignmentExpression);
	                expect(']');
	                return expr;
	            }
	            break;
	        }
	        throwUnexpectedToken(token);
	    }

	    function lookaheadPropertyName() {
	        switch (lookahead.type) {
	        case Token.Identifier:
	        case Token.StringLiteral:
	        case Token.BooleanLiteral:
	        case Token.NullLiteral:
	        case Token.NumericLiteral:
	        case Token.Keyword:
	            return true;
	        case Token.Punctuator:
	            return lookahead.value === '[';
	        }
	        return false;
	    }

	    // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals,
	    // it might be called at a position where there is in fact a short hand identifier pattern or a data property.
	    // This can only be determined after we consumed up to the left parentheses.
	    //
	    // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller
	    // is responsible to visit other options.
	    function tryParseMethodDefinition(token, key, computed, node) {
	        var value, options, methodNode, params,
	            previousAllowYield = state.allowYield;

	        if (token.type === Token.Identifier) {
	            // check for `get` and `set`;

	            if (token.value === 'get' && lookaheadPropertyName()) {
	                computed = match('[');
	                key = parseObjectPropertyKey();
	                methodNode = new Node();
	                expect('(');
	                expect(')');

	                state.allowYield = false;
	                value = parsePropertyFunction(methodNode, {
	                    params: [],
	                    defaults: [],
	                    stricted: null,
	                    firstRestricted: null,
	                    message: null
	                }, false);
	                state.allowYield = previousAllowYield;

	                return node.finishProperty('get', key, computed, value, false, false);
	            } else if (token.value === 'set' && lookaheadPropertyName()) {
	                computed = match('[');
	                key = parseObjectPropertyKey();
	                methodNode = new Node();
	                expect('(');

	                options = {
	                    params: [],
	                    defaultCount: 0,
	                    defaults: [],
	                    firstRestricted: null,
	                    paramSet: {}
	                };
	                if (match(')')) {
	                    tolerateUnexpectedToken(lookahead);
	                } else {
	                    state.allowYield = false;
	                    parseParam(options);
	                    state.allowYield = previousAllowYield;
	                    if (options.defaultCount === 0) {
	                        options.defaults = [];
	                    }
	                }
	                expect(')');

	                state.allowYield = false;
	                value = parsePropertyFunction(methodNode, options, false);
	                state.allowYield = previousAllowYield;

	                return node.finishProperty('set', key, computed, value, false, false);
	            }
	        } else if (token.type === Token.Punctuator && token.value === '*' && lookaheadPropertyName()) {
	            computed = match('[');
	            key = parseObjectPropertyKey();
	            methodNode = new Node();

	            state.allowYield = true;
	            params = parseParams();
	            state.allowYield = previousAllowYield;

	            state.allowYield = false;
	            value = parsePropertyFunction(methodNode, params, true);
	            state.allowYield = previousAllowYield;

	            return node.finishProperty('init', key, computed, value, true, false);
	        }

	        if (key && match('(')) {
	            value = parsePropertyMethodFunction();
	            return node.finishProperty('init', key, computed, value, true, false);
	        }

	        // Not a MethodDefinition.
	        return null;
	    }

	    function parseObjectProperty(hasProto) {
	        var token = lookahead, node = new Node(), computed, key, maybeMethod, proto, value;

	        computed = match('[');
	        if (match('*')) {
	            lex();
	        } else {
	            key = parseObjectPropertyKey();
	        }
	        maybeMethod = tryParseMethodDefinition(token, key, computed, node);
	        if (maybeMethod) {
	            return maybeMethod;
	        }

	        if (!key) {
	            throwUnexpectedToken(lookahead);
	        }

	        // Check for duplicated __proto__
	        if (!computed) {
	            proto = (key.type === Syntax.Identifier && key.name === '__proto__') ||
	                (key.type === Syntax.Literal && key.value === '__proto__');
	            if (hasProto.value && proto) {
	                tolerateError(Messages.DuplicateProtoProperty);
	            }
	            hasProto.value |= proto;
	        }

	        if (match(':')) {
	            lex();
	            value = inheritCoverGrammar(parseAssignmentExpression);
	            return node.finishProperty('init', key, computed, value, false, false);
	        }

	        if (token.type === Token.Identifier) {
	            if (match('=')) {
	                firstCoverInitializedNameError = lookahead;
	                lex();
	                value = isolateCoverGrammar(parseAssignmentExpression);
	                return node.finishProperty('init', key, computed,
	                    new WrappingNode(token).finishAssignmentPattern(key, value), false, true);
	            }
	            return node.finishProperty('init', key, computed, key, false, true);
	        }

	        throwUnexpectedToken(lookahead);
	    }

	    function parseObjectInitializer() {
	        var properties = [], hasProto = {value: false}, node = new Node();

	        expect('{');

	        while (!match('}')) {
	            properties.push(parseObjectProperty(hasProto));

	            if (!match('}')) {
	                expectCommaSeparator();
	            }
	        }

	        expect('}');

	        return node.finishObjectExpression(properties);
	    }

	    function reinterpretExpressionAsPattern(expr) {
	        var i;
	        switch (expr.type) {
	        case Syntax.Identifier:
	        case Syntax.MemberExpression:
	        case Syntax.RestElement:
	        case Syntax.AssignmentPattern:
	            break;
	        case Syntax.SpreadElement:
	            expr.type = Syntax.RestElement;
	            reinterpretExpressionAsPattern(expr.argument);
	            break;
	        case Syntax.ArrayExpression:
	            expr.type = Syntax.ArrayPattern;
	            for (i = 0; i < expr.elements.length; i++) {
	                if (expr.elements[i] !== null) {
	                    reinterpretExpressionAsPattern(expr.elements[i]);
	                }
	            }
	            break;
	        case Syntax.ObjectExpression:
	            expr.type = Syntax.ObjectPattern;
	            for (i = 0; i < expr.properties.length; i++) {
	                reinterpretExpressionAsPattern(expr.properties[i].value);
	            }
	            break;
	        case Syntax.AssignmentExpression:
	            expr.type = Syntax.AssignmentPattern;
	            reinterpretExpressionAsPattern(expr.left);
	            break;
	        default:
	            // Allow other node type for tolerant parsing.
	            break;
	        }
	    }

	    // ECMA-262 12.2.9 Template Literals

	    function parseTemplateElement(option) {
	        var node, token;

	        if (lookahead.type !== Token.Template || (option.head && !lookahead.head)) {
	            throwUnexpectedToken();
	        }

	        node = new Node();
	        token = lex();

	        return node.finishTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail);
	    }

	    function parseTemplateLiteral() {
	        var quasi, quasis, expressions, node = new Node();

	        quasi = parseTemplateElement({ head: true });
	        quasis = [quasi];
	        expressions = [];

	        while (!quasi.tail) {
	            expressions.push(parseExpression());
	            quasi = parseTemplateElement({ head: false });
	            quasis.push(quasi);
	        }

	        return node.finishTemplateLiteral(quasis, expressions);
	    }

	    // ECMA-262 12.2.10 The Grouping Operator

	    function parseGroupExpression() {
	        var expr, expressions, startToken, i, params = [];

	        expect('(');

	        if (match(')')) {
	            lex();
	            if (!match('=>')) {
	                expect('=>');
	            }
	            return {
	                type: PlaceHolders.ArrowParameterPlaceHolder,
	                params: [],
	                rawParams: []
	            };
	        }

	        startToken = lookahead;
	        if (match('...')) {
	            expr = parseRestElement(params);
	            expect(')');
	            if (!match('=>')) {
	                expect('=>');
	            }
	            return {
	                type: PlaceHolders.ArrowParameterPlaceHolder,
	                params: [expr]
	            };
	        }

	        isBindingElement = true;
	        expr = inheritCoverGrammar(parseAssignmentExpression);

	        if (match(',')) {
	            isAssignmentTarget = false;
	            expressions = [expr];

	            while (startIndex < length) {
	                if (!match(',')) {
	                    break;
	                }
	                lex();

	                if (match('...')) {
	                    if (!isBindingElement) {
	                        throwUnexpectedToken(lookahead);
	                    }
	                    expressions.push(parseRestElement(params));
	                    expect(')');
	                    if (!match('=>')) {
	                        expect('=>');
	                    }
	                    isBindingElement = false;
	                    for (i = 0; i < expressions.length; i++) {
	                        reinterpretExpressionAsPattern(expressions[i]);
	                    }
	                    return {
	                        type: PlaceHolders.ArrowParameterPlaceHolder,
	                        params: expressions
	                    };
	                }

	                expressions.push(inheritCoverGrammar(parseAssignmentExpression));
	            }

	            expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
	        }


	        expect(')');

	        if (match('=>')) {
	            if (expr.type === Syntax.Identifier && expr.name === 'yield') {
	                return {
	                    type: PlaceHolders.ArrowParameterPlaceHolder,
	                    params: [expr]
	                };
	            }

	            if (!isBindingElement) {
	                throwUnexpectedToken(lookahead);
	            }

	            if (expr.type === Syntax.SequenceExpression) {
	                for (i = 0; i < expr.expressions.length; i++) {
	                    reinterpretExpressionAsPattern(expr.expressions[i]);
	                }
	            } else {
	                reinterpretExpressionAsPattern(expr);
	            }

	            expr = {
	                type: PlaceHolders.ArrowParameterPlaceHolder,
	                params: expr.type === Syntax.SequenceExpression ? expr.expressions : [expr]
	            };
	        }
	        isBindingElement = false;
	        return expr;
	    }


	    // ECMA-262 12.2 Primary Expressions

	    function parsePrimaryExpression() {
	        var type, token, expr, node;

	        if (match('(')) {
	            isBindingElement = false;
	            return inheritCoverGrammar(parseGroupExpression);
	        }

	        if (match('[')) {
	            return inheritCoverGrammar(parseArrayInitializer);
	        }

	        if (match('{')) {
	            return inheritCoverGrammar(parseObjectInitializer);
	        }

	        type = lookahead.type;
	        node = new Node();

	        if (type === Token.Identifier) {
	            if (state.sourceType === 'module' && lookahead.value === 'await') {
	                tolerateUnexpectedToken(lookahead);
	            }
	            expr = node.finishIdentifier(lex().value);
	        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
	            isAssignmentTarget = isBindingElement = false;
	            if (strict && lookahead.octal) {
	                tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral);
	            }
	            expr = node.finishLiteral(lex());
	        } else if (type === Token.Keyword) {
	            if (!strict && state.allowYield && matchKeyword('yield')) {
	                return parseNonComputedProperty();
	            }
	            if (!strict && matchKeyword('let')) {
	                return node.finishIdentifier(lex().value);
	            }
	            isAssignmentTarget = isBindingElement = false;
	            if (matchKeyword('function')) {
	                return parseFunctionExpression();
	            }
	            if (matchKeyword('this')) {
	                lex();
	                return node.finishThisExpression();
	            }
	            if (matchKeyword('class')) {
	                return parseClassExpression();
	            }
	            throwUnexpectedToken(lex());
	        } else if (type === Token.BooleanLiteral) {
	            isAssignmentTarget = isBindingElement = false;
	            token = lex();
	            token.value = (token.value === 'true');
	            expr = node.finishLiteral(token);
	        } else if (type === Token.NullLiteral) {
	            isAssignmentTarget = isBindingElement = false;
	            token = lex();
	            token.value = null;
	            expr = node.finishLiteral(token);
	        } else if (match('/') || match('/=')) {
	            isAssignmentTarget = isBindingElement = false;
	            index = startIndex;

	            if (typeof extra.tokens !== 'undefined') {
	                token = collectRegex();
	            } else {
	                token = scanRegExp();
	            }
	            lex();
	            expr = node.finishLiteral(token);
	        } else if (type === Token.Template) {
	            expr = parseTemplateLiteral();
	        } else {
	            throwUnexpectedToken(lex());
	        }

	        return expr;
	    }

	    // ECMA-262 12.3 Left-Hand-Side Expressions

	    function parseArguments() {
	        var args = [], expr;

	        expect('(');

	        if (!match(')')) {
	            while (startIndex < length) {
	                if (match('...')) {
	                    expr = new Node();
	                    lex();
	                    expr.finishSpreadElement(isolateCoverGrammar(parseAssignmentExpression));
	                } else {
	                    expr = isolateCoverGrammar(parseAssignmentExpression);
	                }
	                args.push(expr);
	                if (match(')')) {
	                    break;
	                }
	                expectCommaSeparator();
	            }
	        }

	        expect(')');

	        return args;
	    }

	    function parseNonComputedProperty() {
	        var token, node = new Node();

	        token = lex();

	        if (!isIdentifierName(token)) {
	            throwUnexpectedToken(token);
	        }

	        return node.finishIdentifier(token.value);
	    }

	    function parseNonComputedMember() {
	        expect('.');

	        return parseNonComputedProperty();
	    }

	    function parseComputedMember() {
	        var expr;

	        expect('[');

	        expr = isolateCoverGrammar(parseExpression);

	        expect(']');

	        return expr;
	    }

	    // ECMA-262 12.3.3 The new Operator

	    function parseNewExpression() {
	        var callee, args, node = new Node();

	        expectKeyword('new');

	        if (match('.')) {
	            lex();
	            if (lookahead.type === Token.Identifier && lookahead.value === 'target') {
	                if (state.inFunctionBody) {
	                    lex();
	                    return node.finishMetaProperty('new', 'target');
	                }
	            }
	            throwUnexpectedToken(lookahead);
	        }

	        callee = isolateCoverGrammar(parseLeftHandSideExpression);
	        args = match('(') ? parseArguments() : [];

	        isAssignmentTarget = isBindingElement = false;

	        return node.finishNewExpression(callee, args);
	    }

	    // ECMA-262 12.3.4 Function Calls

	    function parseLeftHandSideExpressionAllowCall() {
	        var quasi, expr, args, property, startToken, previousAllowIn = state.allowIn;

	        startToken = lookahead;
	        state.allowIn = true;

	        if (matchKeyword('super') && state.inFunctionBody) {
	            expr = new Node();
	            lex();
	            expr = expr.finishSuper();
	            if (!match('(') && !match('.') && !match('[')) {
	                throwUnexpectedToken(lookahead);
	            }
	        } else {
	            expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
	        }

	        for (;;) {
	            if (match('.')) {
	                isBindingElement = false;
	                isAssignmentTarget = true;
	                property = parseNonComputedMember();
	                expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
	            } else if (match('(')) {
	                isBindingElement = false;
	                isAssignmentTarget = false;
	                args = parseArguments();
	                expr = new WrappingNode(startToken).finishCallExpression(expr, args);
	            } else if (match('[')) {
	                isBindingElement = false;
	                isAssignmentTarget = true;
	                property = parseComputedMember();
	                expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
	            } else if (lookahead.type === Token.Template && lookahead.head) {
	                quasi = parseTemplateLiteral();
	                expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
	            } else {
	                break;
	            }
	        }
	        state.allowIn = previousAllowIn;

	        return expr;
	    }

	    // ECMA-262 12.3 Left-Hand-Side Expressions

	    function parseLeftHandSideExpression() {
	        var quasi, expr, property, startToken;
	        assert(state.allowIn, 'callee of new expression always allow in keyword.');

	        startToken = lookahead;

	        if (matchKeyword('super') && state.inFunctionBody) {
	            expr = new Node();
	            lex();
	            expr = expr.finishSuper();
	            if (!match('[') && !match('.')) {
	                throwUnexpectedToken(lookahead);
	            }
	        } else {
	            expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
	        }

	        for (;;) {
	            if (match('[')) {
	                isBindingElement = false;
	                isAssignmentTarget = true;
	                property = parseComputedMember();
	                expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
	            } else if (match('.')) {
	                isBindingElement = false;
	                isAssignmentTarget = true;
	                property = parseNonComputedMember();
	                expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
	            } else if (lookahead.type === Token.Template && lookahead.head) {
	                quasi = parseTemplateLiteral();
	                expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
	            } else {
	                break;
	            }
	        }
	        return expr;
	    }

	    // ECMA-262 12.4 Postfix Expressions

	    function parsePostfixExpression() {
	        var expr, token, startToken = lookahead;

	        expr = inheritCoverGrammar(parseLeftHandSideExpressionAllowCall);

	        if (!hasLineTerminator && lookahead.type === Token.Punctuator) {
	            if (match('++') || match('--')) {
	                // ECMA-262 11.3.1, 11.3.2
	                if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
	                    tolerateError(Messages.StrictLHSPostfix);
	                }

	                if (!isAssignmentTarget) {
	                    tolerateError(Messages.InvalidLHSInAssignment);
	                }

	                isAssignmentTarget = isBindingElement = false;

	                token = lex();
	                expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr);
	            }
	        }

	        return expr;
	    }

	    // ECMA-262 12.5 Unary Operators

	    function parseUnaryExpression() {
	        var token, expr, startToken;

	        if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
	            expr = parsePostfixExpression();
	        } else if (match('++') || match('--')) {
	            startToken = lookahead;
	            token = lex();
	            expr = inheritCoverGrammar(parseUnaryExpression);
	            // ECMA-262 11.4.4, 11.4.5
	            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
	                tolerateError(Messages.StrictLHSPrefix);
	            }

	            if (!isAssignmentTarget) {
	                tolerateError(Messages.InvalidLHSInAssignment);
	            }
	            expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
	            isAssignmentTarget = isBindingElement = false;
	        } else if (match('+') || match('-') || match('~') || match('!')) {
	            startToken = lookahead;
	            token = lex();
	            expr = inheritCoverGrammar(parseUnaryExpression);
	            expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
	            isAssignmentTarget = isBindingElement = false;
	        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
	            startToken = lookahead;
	            token = lex();
	            expr = inheritCoverGrammar(parseUnaryExpression);
	            expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
	            if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
	                tolerateError(Messages.StrictDelete);
	            }
	            isAssignmentTarget = isBindingElement = false;
	        } else {
	            expr = parsePostfixExpression();
	        }

	        return expr;
	    }

	    function binaryPrecedence(token, allowIn) {
	        var prec = 0;

	        if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
	            return 0;
	        }

	        switch (token.value) {
	        case '||':
	            prec = 1;
	            break;

	        case '&&':
	            prec = 2;
	            break;

	        case '|':
	            prec = 3;
	            break;

	        case '^':
	            prec = 4;
	            break;

	        case '&':
	            prec = 5;
	            break;

	        case '==':
	        case '!=':
	        case '===':
	        case '!==':
	            prec = 6;
	            break;

	        case '<':
	        case '>':
	        case '<=':
	        case '>=':
	        case 'instanceof':
	            prec = 7;
	            break;

	        case 'in':
	            prec = allowIn ? 7 : 0;
	            break;

	        case '<<':
	        case '>>':
	        case '>>>':
	            prec = 8;
	            break;

	        case '+':
	        case '-':
	            prec = 9;
	            break;

	        case '*':
	        case '/':
	        case '%':
	            prec = 11;
	            break;

	        default:
	            break;
	        }

	        return prec;
	    }

	    // ECMA-262 12.6 Multiplicative Operators
	    // ECMA-262 12.7 Additive Operators
	    // ECMA-262 12.8 Bitwise Shift Operators
	    // ECMA-262 12.9 Relational Operators
	    // ECMA-262 12.10 Equality Operators
	    // ECMA-262 12.11 Binary Bitwise Operators
	    // ECMA-262 12.12 Binary Logical Operators

	    function parseBinaryExpression() {
	        var marker, markers, expr, token, prec, stack, right, operator, left, i;

	        marker = lookahead;
	        left = inheritCoverGrammar(parseUnaryExpression);

	        token = lookahead;
	        prec = binaryPrecedence(token, state.allowIn);
	        if (prec === 0) {
	            return left;
	        }
	        isAssignmentTarget = isBindingElement = false;
	        token.prec = prec;
	        lex();

	        markers = [marker, lookahead];
	        right = isolateCoverGrammar(parseUnaryExpression);

	        stack = [left, token, right];

	        while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {

	            // Reduce: make a binary expression from the three topmost entries.
	            while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
	                right = stack.pop();
	                operator = stack.pop().value;
	                left = stack.pop();
	                markers.pop();
	                expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right);
	                stack.push(expr);
	            }

	            // Shift.
	            token = lex();
	            token.prec = prec;
	            stack.push(token);
	            markers.push(lookahead);
	            expr = isolateCoverGrammar(parseUnaryExpression);
	            stack.push(expr);
	        }

	        // Final reduce to clean-up the stack.
	        i = stack.length - 1;
	        expr = stack[i];
	        markers.pop();
	        while (i > 1) {
	            expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
	            i -= 2;
	        }

	        return expr;
	    }


	    // ECMA-262 12.13 Conditional Operator

	    function parseConditionalExpression() {
	        var expr, previousAllowIn, consequent, alternate, startToken;

	        startToken = lookahead;

	        expr = inheritCoverGrammar(parseBinaryExpression);
	        if (match('?')) {
	            lex();
	            previousAllowIn = state.allowIn;
	            state.allowIn = true;
	            consequent = isolateCoverGrammar(parseAssignmentExpression);
	            state.allowIn = previousAllowIn;
	            expect(':');
	            alternate = isolateCoverGrammar(parseAssignmentExpression);

	            expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate);
	            isAssignmentTarget = isBindingElement = false;
	        }

	        return expr;
	    }

	    // ECMA-262 14.2 Arrow Function Definitions

	    function parseConciseBody() {
	        if (match('{')) {
	            return parseFunctionSourceElements();
	        }
	        return isolateCoverGrammar(parseAssignmentExpression);
	    }

	    function checkPatternParam(options, param) {
	        var i;
	        switch (param.type) {
	        case Syntax.Identifier:
	            validateParam(options, param, param.name);
	            break;
	        case Syntax.RestElement:
	            checkPatternParam(options, param.argument);
	            break;
	        case Syntax.AssignmentPattern:
	            checkPatternParam(options, param.left);
	            break;
	        case Syntax.ArrayPattern:
	            for (i = 0; i < param.elements.length; i++) {
	                if (param.elements[i] !== null) {
	                    checkPatternParam(options, param.elements[i]);
	                }
	            }
	            break;
	        case Syntax.YieldExpression:
	            break;
	        default:
	            assert(param.type === Syntax.ObjectPattern, 'Invalid type');
	            for (i = 0; i < param.properties.length; i++) {
	                checkPatternParam(options, param.properties[i].value);
	            }
	            break;
	        }
	    }
	    function reinterpretAsCoverFormalsList(expr) {
	        var i, len, param, params, defaults, defaultCount, options, token;

	        defaults = [];
	        defaultCount = 0;
	        params = [expr];

	        switch (expr.type) {
	        case Syntax.Identifier:
	            break;
	        case PlaceHolders.ArrowParameterPlaceHolder:
	            params = expr.params;
	            break;
	        default:
	            return null;
	        }

	        options = {
	            paramSet: {}
	        };

	        for (i = 0, len = params.length; i < len; i += 1) {
	            param = params[i];
	            switch (param.type) {
	            case Syntax.AssignmentPattern:
	                params[i] = param.left;
	                if (param.right.type === Syntax.YieldExpression) {
	                    if (param.right.argument) {
	                        throwUnexpectedToken(lookahead);
	                    }
	                    param.right.type = Syntax.Identifier;
	                    param.right.name = 'yield';
	                    delete param.right.argument;
	                    delete param.right.delegate;
	                }
	                defaults.push(param.right);
	                ++defaultCount;
	                checkPatternParam(options, param.left);
	                break;
	            default:
	                checkPatternParam(options, param);
	                params[i] = param;
	                defaults.push(null);
	                break;
	            }
	        }

	        if (strict || !state.allowYield) {
	            for (i = 0, len = params.length; i < len; i += 1) {
	                param = params[i];
	                if (param.type === Syntax.YieldExpression) {
	                    throwUnexpectedToken(lookahead);
	                }
	            }
	        }

	        if (options.message === Messages.StrictParamDupe) {
	            token = strict ? options.stricted : options.firstRestricted;
	            throwUnexpectedToken(token, options.message);
	        }

	        if (defaultCount === 0) {
	            defaults = [];
	        }

	        return {
	            params: params,
	            defaults: defaults,
	            stricted: options.stricted,
	            firstRestricted: options.firstRestricted,
	            message: options.message
	        };
	    }

	    function parseArrowFunctionExpression(options, node) {
	        var previousStrict, previousAllowYield, body;

	        if (hasLineTerminator) {
	            tolerateUnexpectedToken(lookahead);
	        }
	        expect('=>');

	        previousStrict = strict;
	        previousAllowYield = state.allowYield;
	        state.allowYield = true;

	        body = parseConciseBody();

	        if (strict && options.firstRestricted) {
	            throwUnexpectedToken(options.firstRestricted, options.message);
	        }
	        if (strict && options.stricted) {
	            tolerateUnexpectedToken(options.stricted, options.message);
	        }

	        strict = previousStrict;
	        state.allowYield = previousAllowYield;

	        return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement);
	    }

	    // ECMA-262 14.4 Yield expression

	    function parseYieldExpression() {
	        var argument, expr, delegate, previousAllowYield;

	        argument = null;
	        expr = new Node();
	        delegate = false;

	        expectKeyword('yield');

	        if (!hasLineTerminator) {
	            previousAllowYield = state.allowYield;
	            state.allowYield = false;
	            delegate = match('*');
	            if (delegate) {
	                lex();
	                argument = parseAssignmentExpression();
	            } else {
	                if (!match(';') && !match('}') && !match(')') && lookahead.type !== Token.EOF) {
	                    argument = parseAssignmentExpression();
	                }
	            }
	            state.allowYield = previousAllowYield;
	        }

	        return expr.finishYieldExpression(argument, delegate);
	    }

	    // ECMA-262 12.14 Assignment Operators

	    function parseAssignmentExpression() {
	        var token, expr, right, list, startToken;

	        startToken = lookahead;
	        token = lookahead;

	        if (!state.allowYield && matchKeyword('yield')) {
	            return parseYieldExpression();
	        }

	        expr = parseConditionalExpression();

	        if (expr.type === PlaceHolders.ArrowParameterPlaceHolder || match('=>')) {
	            isAssignmentTarget = isBindingElement = false;
	            list = reinterpretAsCoverFormalsList(expr);

	            if (list) {
	                firstCoverInitializedNameError = null;
	                return parseArrowFunctionExpression(list, new WrappingNode(startToken));
	            }

	            return expr;
	        }

	        if (matchAssign()) {
	            if (!isAssignmentTarget) {
	                tolerateError(Messages.InvalidLHSInAssignment);
	            }

	            // ECMA-262 12.1.1
	            if (strict && expr.type === Syntax.Identifier) {
	                if (isRestrictedWord(expr.name)) {
	                    tolerateUnexpectedToken(token, Messages.StrictLHSAssignment);
	                }
	                if (isStrictModeReservedWord(expr.name)) {
	                    tolerateUnexpectedToken(token, Messages.StrictReservedWord);
	                }
	            }

	            if (!match('=')) {
	                isAssignmentTarget = isBindingElement = false;
	            } else {
	                reinterpretExpressionAsPattern(expr);
	            }

	            token = lex();
	            right = isolateCoverGrammar(parseAssignmentExpression);
	            expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right);
	            firstCoverInitializedNameError = null;
	        }

	        return expr;
	    }

	    // ECMA-262 12.15 Comma Operator

	    function parseExpression() {
	        var expr, startToken = lookahead, expressions;

	        expr = isolateCoverGrammar(parseAssignmentExpression);

	        if (match(',')) {
	            expressions = [expr];

	            while (startIndex < length) {
	                if (!match(',')) {
	                    break;
	                }
	                lex();
	                expressions.push(isolateCoverGrammar(parseAssignmentExpression));
	            }

	            expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
	        }

	        return expr;
	    }

	    // ECMA-262 13.2 Block

	    function parseStatementListItem() {
	        if (lookahead.type === Token.Keyword) {
	            switch (lookahead.value) {
	            case 'export':
	                if (state.sourceType !== 'module') {
	                    tolerateUnexpectedToken(lookahead, Messages.IllegalExportDeclaration);
	                }
	                return parseExportDeclaration();
	            case 'import':
	                if (state.sourceType !== 'module') {
	                    tolerateUnexpectedToken(lookahead, Messages.IllegalImportDeclaration);
	                }
	                return parseImportDeclaration();
	            case 'const':
	                return parseLexicalDeclaration({inFor: false});
	            case 'function':
	                return parseFunctionDeclaration(new Node());
	            case 'class':
	                return parseClassDeclaration();
	            }
	        }

	        if (matchKeyword('let') && isLexicalDeclaration()) {
	            return parseLexicalDeclaration({inFor: false});
	        }

	        return parseStatement();
	    }

	    function parseStatementList() {
	        var list = [];
	        while (startIndex < length) {
	            if (match('}')) {
	                break;
	            }
	            list.push(parseStatementListItem());
	        }

	        return list;
	    }

	    function parseBlock() {
	        var block, node = new Node();

	        expect('{');

	        block = parseStatementList();

	        expect('}');

	        return node.finishBlockStatement(block);
	    }

	    // ECMA-262 13.3.2 Variable Statement

	    function parseVariableIdentifier(kind) {
	        var token, node = new Node();

	        token = lex();

	        if (token.type === Token.Keyword && token.value === 'yield') {
	            if (strict) {
	                tolerateUnexpectedToken(token, Messages.StrictReservedWord);
	            } if (!state.allowYield) {
	                throwUnexpectedToken(token);
	            }
	        } else if (token.type !== Token.Identifier) {
	            if (strict && token.type === Token.Keyword && isStrictModeReservedWord(token.value)) {
	                tolerateUnexpectedToken(token, Messages.StrictReservedWord);
	            } else {
	                if (strict || token.value !== 'let' || kind !== 'var') {
	                    throwUnexpectedToken(token);
	                }
	            }
	        } else if (state.sourceType === 'module' && token.type === Token.Identifier && token.value === 'await') {
	            tolerateUnexpectedToken(token);
	        }

	        return node.finishIdentifier(token.value);
	    }

	    function parseVariableDeclaration(options) {
	        var init = null, id, node = new Node(), params = [];

	        id = parsePattern(params, 'var');

	        // ECMA-262 12.2.1
	        if (strict && isRestrictedWord(id.name)) {
	            tolerateError(Messages.StrictVarName);
	        }

	        if (match('=')) {
	            lex();
	            init = isolateCoverGrammar(parseAssignmentExpression);
	        } else if (id.type !== Syntax.Identifier && !options.inFor) {
	            expect('=');
	        }

	        return node.finishVariableDeclarator(id, init);
	    }

	    function parseVariableDeclarationList(options) {
	        var opt, list;

	        opt = { inFor: options.inFor };
	        list = [parseVariableDeclaration(opt)];

	        while (match(',')) {
	            lex();
	            list.push(parseVariableDeclaration(opt));
	        }

	        return list;
	    }

	    function parseVariableStatement(node) {
	        var declarations;

	        expectKeyword('var');

	        declarations = parseVariableDeclarationList({ inFor: false });

	        consumeSemicolon();

	        return node.finishVariableDeclaration(declarations);
	    }

	    // ECMA-262 13.3.1 Let and Const Declarations

	    function parseLexicalBinding(kind, options) {
	        var init = null, id, node = new Node(), params = [];

	        id = parsePattern(params, kind);

	        // ECMA-262 12.2.1
	        if (strict && id.type === Syntax.Identifier && isRestrictedWord(id.name)) {
	            tolerateError(Messages.StrictVarName);
	        }

	        if (kind === 'const') {
	            if (!matchKeyword('in') && !matchContextualKeyword('of')) {
	                expect('=');
	                init = isolateCoverGrammar(parseAssignmentExpression);
	            }
	        } else if ((!options.inFor && id.type !== Syntax.Identifier) || match('=')) {
	            expect('=');
	            init = isolateCoverGrammar(parseAssignmentExpression);
	        }

	        return node.finishVariableDeclarator(id, init);
	    }

	    function parseBindingList(kind, options) {
	        var list = [parseLexicalBinding(kind, options)];

	        while (match(',')) {
	            lex();
	            list.push(parseLexicalBinding(kind, options));
	        }

	        return list;
	    }


	    function tokenizerState() {
	        return {
	            index: index,
	            lineNumber: lineNumber,
	            lineStart: lineStart,
	            hasLineTerminator: hasLineTerminator,
	            lastIndex: lastIndex,
	            lastLineNumber: lastLineNumber,
	            lastLineStart: lastLineStart,
	            startIndex: startIndex,
	            startLineNumber: startLineNumber,
	            startLineStart: startLineStart,
	            lookahead: lookahead,
	            tokenCount: extra.tokens ? extra.tokens.length : 0
	        };
	    }

	    function resetTokenizerState(ts) {
	        index = ts.index;
	        lineNumber = ts.lineNumber;
	        lineStart = ts.lineStart;
	        hasLineTerminator = ts.hasLineTerminator;
	        lastIndex = ts.lastIndex;
	        lastLineNumber = ts.lastLineNumber;
	        lastLineStart = ts.lastLineStart;
	        startIndex = ts.startIndex;
	        startLineNumber = ts.startLineNumber;
	        startLineStart = ts.startLineStart;
	        lookahead = ts.lookahead;
	        if (extra.tokens) {
	            extra.tokens.splice(ts.tokenCount, extra.tokens.length);
	        }
	    }

	    function isLexicalDeclaration() {
	        var lexical, ts;

	        ts = tokenizerState();

	        lex();
	        lexical = (lookahead.type === Token.Identifier) || match('[') || match('{') ||
	            matchKeyword('let') || matchKeyword('yield');

	        resetTokenizerState(ts);

	        return lexical;
	    }

	    function parseLexicalDeclaration(options) {
	        var kind, declarations, node = new Node();

	        kind = lex().value;
	        assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');

	        declarations = parseBindingList(kind, options);

	        consumeSemicolon();

	        return node.finishLexicalDeclaration(declarations, kind);
	    }

	    function parseRestElement(params) {
	        var param, node = new Node();

	        lex();

	        if (match('{')) {
	            throwError(Messages.ObjectPatternAsRestParameter);
	        }

	        params.push(lookahead);

	        param = parseVariableIdentifier();

	        if (match('=')) {
	            throwError(Messages.DefaultRestParameter);
	        }

	        if (!match(')')) {
	            throwError(Messages.ParameterAfterRestParameter);
	        }

	        return node.finishRestElement(param);
	    }

	    // ECMA-262 13.4 Empty Statement

	    function parseEmptyStatement(node) {
	        expect(';');
	        return node.finishEmptyStatement();
	    }

	    // ECMA-262 12.4 Expression Statement

	    function parseExpressionStatement(node) {
	        var expr = parseExpression();
	        consumeSemicolon();
	        return node.finishExpressionStatement(expr);
	    }

	    // ECMA-262 13.6 If statement

	    function parseIfStatement(node) {
	        var test, consequent, alternate;

	        expectKeyword('if');

	        expect('(');

	        test = parseExpression();

	        expect(')');

	        consequent = parseStatement();

	        if (matchKeyword('else')) {
	            lex();
	            alternate = parseStatement();
	        } else {
	            alternate = null;
	        }

	        return node.finishIfStatement(test, consequent, alternate);
	    }

	    // ECMA-262 13.7 Iteration Statements

	    function parseDoWhileStatement(node) {
	        var body, test, oldInIteration;

	        expectKeyword('do');

	        oldInIteration = state.inIteration;
	        state.inIteration = true;

	        body = parseStatement();

	        state.inIteration = oldInIteration;

	        expectKeyword('while');

	        expect('(');

	        test = parseExpression();

	        expect(')');

	        if (match(';')) {
	            lex();
	        }

	        return node.finishDoWhileStatement(body, test);
	    }

	    function parseWhileStatement(node) {
	        var test, body, oldInIteration;

	        expectKeyword('while');

	        expect('(');

	        test = parseExpression();

	        expect(')');

	        oldInIteration = state.inIteration;
	        state.inIteration = true;

	        body = parseStatement();

	        state.inIteration = oldInIteration;

	        return node.finishWhileStatement(test, body);
	    }

	    function parseForStatement(node) {
	        var init, forIn, initSeq, initStartToken, test, update, left, right, kind, declarations,
	            body, oldInIteration, previousAllowIn = state.allowIn;

	        init = test = update = null;
	        forIn = true;

	        expectKeyword('for');

	        expect('(');

	        if (match(';')) {
	            lex();
	        } else {
	            if (matchKeyword('var')) {
	                init = new Node();
	                lex();

	                state.allowIn = false;
	                declarations = parseVariableDeclarationList({ inFor: true });
	                state.allowIn = previousAllowIn;

	                if (declarations.length === 1 && matchKeyword('in')) {
	                    init = init.finishVariableDeclaration(declarations);
	                    lex();
	                    left = init;
	                    right = parseExpression();
	                    init = null;
	                } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) {
	                    init = init.finishVariableDeclaration(declarations);
	                    lex();
	                    left = init;
	                    right = parseAssignmentExpression();
	                    init = null;
	                    forIn = false;
	                } else {
	                    init = init.finishVariableDeclaration(declarations);
	                    expect(';');
	                }
	            } else if (matchKeyword('const') || matchKeyword('let')) {
	                init = new Node();
	                kind = lex().value;

	                if (!strict && lookahead.value === 'in') {
	                    init = init.finishIdentifier(kind);
	                    lex();
	                    left = init;
	                    right = parseExpression();
	                    init = null;
	                } else {
	                    state.allowIn = false;
	                    declarations = parseBindingList(kind, {inFor: true});
	                    state.allowIn = previousAllowIn;

	                    if (declarations.length === 1 && declarations[0].init === null && matchKeyword('in')) {
	                        init = init.finishLexicalDeclaration(declarations, kind);
	                        lex();
	                        left = init;
	                        right = parseExpression();
	                        init = null;
	                    } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) {
	                        init = init.finishLexicalDeclaration(declarations, kind);
	                        lex();
	                        left = init;
	                        right = parseAssignmentExpression();
	                        init = null;
	                        forIn = false;
	                    } else {
	                        consumeSemicolon();
	                        init = init.finishLexicalDeclaration(declarations, kind);
	                    }
	                }
	            } else {
	                initStartToken = lookahead;
	                state.allowIn = false;
	                init = inheritCoverGrammar(parseAssignmentExpression);
	                state.allowIn = previousAllowIn;

	                if (matchKeyword('in')) {
	                    if (!isAssignmentTarget) {
	                        tolerateError(Messages.InvalidLHSInForIn);
	                    }

	                    lex();
	                    reinterpretExpressionAsPattern(init);
	                    left = init;
	                    right = parseExpression();
	                    init = null;
	                } else if (matchContextualKeyword('of')) {
	                    if (!isAssignmentTarget) {
	                        tolerateError(Messages.InvalidLHSInForLoop);
	                    }

	                    lex();
	                    reinterpretExpressionAsPattern(init);
	                    left = init;
	                    right = parseAssignmentExpression();
	                    init = null;
	                    forIn = false;
	                } else {
	                    if (match(',')) {
	                        initSeq = [init];
	                        while (match(',')) {
	                            lex();
	                            initSeq.push(isolateCoverGrammar(parseAssignmentExpression));
	                        }
	                        init = new WrappingNode(initStartToken).finishSequenceExpression(initSeq);
	                    }
	                    expect(';');
	                }
	            }
	        }

	        if (typeof left === 'undefined') {

	            if (!match(';')) {
	                test = parseExpression();
	            }
	            expect(';');

	            if (!match(')')) {
	                update = parseExpression();
	            }
	        }

	        expect(')');

	        oldInIteration = state.inIteration;
	        state.inIteration = true;

	        body = isolateCoverGrammar(parseStatement);

	        state.inIteration = oldInIteration;

	        return (typeof left === 'undefined') ?
	                node.finishForStatement(init, test, update, body) :
	                forIn ? node.finishForInStatement(left, right, body) :
	                    node.finishForOfStatement(left, right, body);
	    }

	    // ECMA-262 13.8 The continue statement

	    function parseContinueStatement(node) {
	        var label = null, key;

	        expectKeyword('continue');

	        // Optimize the most common form: 'continue;'.
	        if (source.charCodeAt(startIndex) === 0x3B) {
	            lex();

	            if (!state.inIteration) {
	                throwError(Messages.IllegalContinue);
	            }

	            return node.finishContinueStatement(null);
	        }

	        if (hasLineTerminator) {
	            if (!state.inIteration) {
	                throwError(Messages.IllegalContinue);
	            }

	            return node.finishContinueStatement(null);
	        }

	        if (lookahead.type === Token.Identifier) {
	            label = parseVariableIdentifier();

	            key = '$' + label.name;
	            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
	                throwError(Messages.UnknownLabel, label.name);
	            }
	        }

	        consumeSemicolon();

	        if (label === null && !state.inIteration) {
	            throwError(Messages.IllegalContinue);
	        }

	        return node.finishContinueStatement(label);
	    }

	    // ECMA-262 13.9 The break statement

	    function parseBreakStatement(node) {
	        var label = null, key;

	        expectKeyword('break');

	        // Catch the very common case first: immediately a semicolon (U+003B).
	        if (source.charCodeAt(lastIndex) === 0x3B) {
	            lex();

	            if (!(state.inIteration || state.inSwitch)) {
	                throwError(Messages.IllegalBreak);
	            }

	            return node.finishBreakStatement(null);
	        }

	        if (hasLineTerminator) {
	            if (!(state.inIteration || state.inSwitch)) {
	                throwError(Messages.IllegalBreak);
	            }
	        } else if (lookahead.type === Token.Identifier) {
	            label = parseVariableIdentifier();

	            key = '$' + label.name;
	            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
	                throwError(Messages.UnknownLabel, label.name);
	            }
	        }

	        consumeSemicolon();

	        if (label === null && !(state.inIteration || state.inSwitch)) {
	            throwError(Messages.IllegalBreak);
	        }

	        return node.finishBreakStatement(label);
	    }

	    // ECMA-262 13.10 The return statement

	    function parseReturnStatement(node) {
	        var argument = null;

	        expectKeyword('return');

	        if (!state.inFunctionBody) {
	            tolerateError(Messages.IllegalReturn);
	        }

	        // 'return' followed by a space and an identifier is very common.
	        if (source.charCodeAt(lastIndex) === 0x20) {
	            if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) {
	                argument = parseExpression();
	                consumeSemicolon();
	                return node.finishReturnStatement(argument);
	            }
	        }

	        if (hasLineTerminator) {
	            // HACK
	            return node.finishReturnStatement(null);
	        }

	        if (!match(';')) {
	            if (!match('}') && lookahead.type !== Token.EOF) {
	                argument = parseExpression();
	            }
	        }

	        consumeSemicolon();

	        return node.finishReturnStatement(argument);
	    }

	    // ECMA-262 13.11 The with statement

	    function parseWithStatement(node) {
	        var object, body;

	        if (strict) {
	            tolerateError(Messages.StrictModeWith);
	        }

	        expectKeyword('with');

	        expect('(');

	        object = parseExpression();

	        expect(')');

	        body = parseStatement();

	        return node.finishWithStatement(object, body);
	    }

	    // ECMA-262 13.12 The switch statement

	    function parseSwitchCase() {
	        var test, consequent = [], statement, node = new Node();

	        if (matchKeyword('default')) {
	            lex();
	            test = null;
	        } else {
	            expectKeyword('case');
	            test = parseExpression();
	        }
	        expect(':');

	        while (startIndex < length) {
	            if (match('}') || matchKeyword('default') || matchKeyword('case')) {
	                break;
	            }
	            statement = parseStatementListItem();
	            consequent.push(statement);
	        }

	        return node.finishSwitchCase(test, consequent);
	    }

	    function parseSwitchStatement(node) {
	        var discriminant, cases, clause, oldInSwitch, defaultFound;

	        expectKeyword('switch');

	        expect('(');

	        discriminant = parseExpression();

	        expect(')');

	        expect('{');

	        cases = [];

	        if (match('}')) {
	            lex();
	            return node.finishSwitchStatement(discriminant, cases);
	        }

	        oldInSwitch = state.inSwitch;
	        state.inSwitch = true;
	        defaultFound = false;

	        while (startIndex < length) {
	            if (match('}')) {
	                break;
	            }
	            clause = parseSwitchCase();
	            if (clause.test === null) {
	                if (defaultFound) {
	                    throwError(Messages.MultipleDefaultsInSwitch);
	                }
	                defaultFound = true;
	            }
	            cases.push(clause);
	        }

	        state.inSwitch = oldInSwitch;

	        expect('}');

	        return node.finishSwitchStatement(discriminant, cases);
	    }

	    // ECMA-262 13.14 The throw statement

	    function parseThrowStatement(node) {
	        var argument;

	        expectKeyword('throw');

	        if (hasLineTerminator) {
	            throwError(Messages.NewlineAfterThrow);
	        }

	        argument = parseExpression();

	        consumeSemicolon();

	        return node.finishThrowStatement(argument);
	    }

	    // ECMA-262 13.15 The try statement

	    function parseCatchClause() {
	        var param, params = [], paramMap = {}, key, i, body, node = new Node();

	        expectKeyword('catch');

	        expect('(');
	        if (match(')')) {
	            throwUnexpectedToken(lookahead);
	        }

	        param = parsePattern(params);
	        for (i = 0; i < params.length; i++) {
	            key = '$' + params[i].value;
	            if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
	                tolerateError(Messages.DuplicateBinding, params[i].value);
	            }
	            paramMap[key] = true;
	        }

	        // ECMA-262 12.14.1
	        if (strict && isRestrictedWord(param.name)) {
	            tolerateError(Messages.StrictCatchVariable);
	        }

	        expect(')');
	        body = parseBlock();
	        return node.finishCatchClause(param, body);
	    }

	    function parseTryStatement(node) {
	        var block, handler = null, finalizer = null;

	        expectKeyword('try');

	        block = parseBlock();

	        if (matchKeyword('catch')) {
	            handler = parseCatchClause();
	        }

	        if (matchKeyword('finally')) {
	            lex();
	            finalizer = parseBlock();
	        }

	        if (!handler && !finalizer) {
	            throwError(Messages.NoCatchOrFinally);
	        }

	        return node.finishTryStatement(block, handler, finalizer);
	    }

	    // ECMA-262 13.16 The debugger statement

	    function parseDebuggerStatement(node) {
	        expectKeyword('debugger');

	        consumeSemicolon();

	        return node.finishDebuggerStatement();
	    }

	    // 13 Statements

	    function parseStatement() {
	        var type = lookahead.type,
	            expr,
	            labeledBody,
	            key,
	            node;

	        if (type === Token.EOF) {
	            throwUnexpectedToken(lookahead);
	        }

	        if (type === Token.Punctuator && lookahead.value === '{') {
	            return parseBlock();
	        }
	        isAssignmentTarget = isBindingElement = true;
	        node = new Node();

	        if (type === Token.Punctuator) {
	            switch (lookahead.value) {
	            case ';':
	                return parseEmptyStatement(node);
	            case '(':
	                return parseExpressionStatement(node);
	            default:
	                break;
	            }
	        } else if (type === Token.Keyword) {
	            switch (lookahead.value) {
	            case 'break':
	                return parseBreakStatement(node);
	            case 'continue':
	                return parseContinueStatement(node);
	            case 'debugger':
	                return parseDebuggerStatement(node);
	            case 'do':
	                return parseDoWhileStatement(node);
	            case 'for':
	                return parseForStatement(node);
	            case 'function':
	                return parseFunctionDeclaration(node);
	            case 'if':
	                return parseIfStatement(node);
	            case 'return':
	                return parseReturnStatement(node);
	            case 'switch':
	                return parseSwitchStatement(node);
	            case 'throw':
	                return parseThrowStatement(node);
	            case 'try':
	                return parseTryStatement(node);
	            case 'var':
	                return parseVariableStatement(node);
	            case 'while':
	                return parseWhileStatement(node);
	            case 'with':
	                return parseWithStatement(node);
	            default:
	                break;
	            }
	        }

	        expr = parseExpression();

	        // ECMA-262 12.12 Labelled Statements
	        if ((expr.type === Syntax.Identifier) && match(':')) {
	            lex();

	            key = '$' + expr.name;
	            if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
	                throwError(Messages.Redeclaration, 'Label', expr.name);
	            }

	            state.labelSet[key] = true;
	            labeledBody = parseStatement();
	            delete state.labelSet[key];
	            return node.finishLabeledStatement(expr, labeledBody);
	        }

	        consumeSemicolon();

	        return node.finishExpressionStatement(expr);
	    }

	    // ECMA-262 14.1 Function Definition

	    function parseFunctionSourceElements() {
	        var statement, body = [], token, directive, firstRestricted,
	            oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount,
	            node = new Node();

	        expect('{');

	        while (startIndex < length) {
	            if (lookahead.type !== Token.StringLiteral) {
	                break;
	            }
	            token = lookahead;

	            statement = parseStatementListItem();
	            body.push(statement);
	            if (statement.expression.type !== Syntax.Literal) {
	                // this is not directive
	                break;
	            }
	            directive = source.slice(token.start + 1, token.end - 1);
	            if (directive === 'use strict') {
	                strict = true;
	                if (firstRestricted) {
	                    tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
	                }
	            } else {
	                if (!firstRestricted && token.octal) {
	                    firstRestricted = token;
	                }
	            }
	        }

	        oldLabelSet = state.labelSet;
	        oldInIteration = state.inIteration;
	        oldInSwitch = state.inSwitch;
	        oldInFunctionBody = state.inFunctionBody;
	        oldParenthesisCount = state.parenthesizedCount;

	        state.labelSet = {};
	        state.inIteration = false;
	        state.inSwitch = false;
	        state.inFunctionBody = true;
	        state.parenthesizedCount = 0;

	        while (startIndex < length) {
	            if (match('}')) {
	                break;
	            }
	            body.push(parseStatementListItem());
	        }

	        expect('}');

	        state.labelSet = oldLabelSet;
	        state.inIteration = oldInIteration;
	        state.inSwitch = oldInSwitch;
	        state.inFunctionBody = oldInFunctionBody;
	        state.parenthesizedCount = oldParenthesisCount;

	        return node.finishBlockStatement(body);
	    }

	    function validateParam(options, param, name) {
	        var key = '$' + name;
	        if (strict) {
	            if (isRestrictedWord(name)) {
	                options.stricted = param;
	                options.message = Messages.StrictParamName;
	            }
	            if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
	                options.stricted = param;
	                options.message = Messages.StrictParamDupe;
	            }
	        } else if (!options.firstRestricted) {
	            if (isRestrictedWord(name)) {
	                options.firstRestricted = param;
	                options.message = Messages.StrictParamName;
	            } else if (isStrictModeReservedWord(name)) {
	                options.firstRestricted = param;
	                options.message = Messages.StrictReservedWord;
	            } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
	                options.stricted = param;
	                options.message = Messages.StrictParamDupe;
	            }
	        }
	        options.paramSet[key] = true;
	    }

	    function parseParam(options) {
	        var token, param, params = [], i, def;

	        token = lookahead;
	        if (token.value === '...') {
	            param = parseRestElement(params);
	            validateParam(options, param.argument, param.argument.name);
	            options.params.push(param);
	            options.defaults.push(null);
	            return false;
	        }

	        param = parsePatternWithDefault(params);
	        for (i = 0; i < params.length; i++) {
	            validateParam(options, params[i], params[i].value);
	        }

	        if (param.type === Syntax.AssignmentPattern) {
	            def = param.right;
	            param = param.left;
	            ++options.defaultCount;
	        }

	        options.params.push(param);
	        options.defaults.push(def);

	        return !match(')');
	    }

	    function parseParams(firstRestricted) {
	        var options;

	        options = {
	            params: [],
	            defaultCount: 0,
	            defaults: [],
	            firstRestricted: firstRestricted
	        };

	        expect('(');

	        if (!match(')')) {
	            options.paramSet = {};
	            while (startIndex < length) {
	                if (!parseParam(options)) {
	                    break;
	                }
	                expect(',');
	            }
	        }

	        expect(')');

	        if (options.defaultCount === 0) {
	            options.defaults = [];
	        }

	        return {
	            params: options.params,
	            defaults: options.defaults,
	            stricted: options.stricted,
	            firstRestricted: options.firstRestricted,
	            message: options.message
	        };
	    }

	    function parseFunctionDeclaration(node, identifierIsOptional) {
	        var id = null, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict,
	            isGenerator, previousAllowYield;

	        previousAllowYield = state.allowYield;

	        expectKeyword('function');

	        isGenerator = match('*');
	        if (isGenerator) {
	            lex();
	        }

	        if (!identifierIsOptional || !match('(')) {
	            token = lookahead;
	            id = parseVariableIdentifier();
	            if (strict) {
	                if (isRestrictedWord(token.value)) {
	                    tolerateUnexpectedToken(token, Messages.StrictFunctionName);
	                }
	            } else {
	                if (isRestrictedWord(token.value)) {
	                    firstRestricted = token;
	                    message = Messages.StrictFunctionName;
	                } else if (isStrictModeReservedWord(token.value)) {
	                    firstRestricted = token;
	                    message = Messages.StrictReservedWord;
	                }
	            }
	        }

	        state.allowYield = !isGenerator;
	        tmp = parseParams(firstRestricted);
	        params = tmp.params;
	        defaults = tmp.defaults;
	        stricted = tmp.stricted;
	        firstRestricted = tmp.firstRestricted;
	        if (tmp.message) {
	            message = tmp.message;
	        }


	        previousStrict = strict;
	        body = parseFunctionSourceElements();
	        if (strict && firstRestricted) {
	            throwUnexpectedToken(firstRestricted, message);
	        }
	        if (strict && stricted) {
	            tolerateUnexpectedToken(stricted, message);
	        }

	        strict = previousStrict;
	        state.allowYield = previousAllowYield;

	        return node.finishFunctionDeclaration(id, params, defaults, body, isGenerator);
	    }

	    function parseFunctionExpression() {
	        var token, id = null, stricted, firstRestricted, message, tmp,
	            params = [], defaults = [], body, previousStrict, node = new Node(),
	            isGenerator, previousAllowYield;

	        previousAllowYield = state.allowYield;

	        expectKeyword('function');

	        isGenerator = match('*');
	        if (isGenerator) {
	            lex();
	        }

	        state.allowYield = !isGenerator;
	        if (!match('(')) {
	            token = lookahead;
	            id = (!strict && !isGenerator && matchKeyword('yield')) ? parseNonComputedProperty() : parseVariableIdentifier();
	            if (strict) {
	                if (isRestrictedWord(token.value)) {
	                    tolerateUnexpectedToken(token, Messages.StrictFunctionName);
	                }
	            } else {
	                if (isRestrictedWord(token.value)) {
	                    firstRestricted = token;
	                    message = Messages.StrictFunctionName;
	                } else if (isStrictModeReservedWord(token.value)) {
	                    firstRestricted = token;
	                    message = Messages.StrictReservedWord;
	                }
	            }
	        }

	        tmp = parseParams(firstRestricted);
	        params = tmp.params;
	        defaults = tmp.defaults;
	        stricted = tmp.stricted;
	        firstRestricted = tmp.firstRestricted;
	        if (tmp.message) {
	            message = tmp.message;
	        }

	        previousStrict = strict;
	        body = parseFunctionSourceElements();
	        if (strict && firstRestricted) {
	            throwUnexpectedToken(firstRestricted, message);
	        }
	        if (strict && stricted) {
	            tolerateUnexpectedToken(stricted, message);
	        }
	        strict = previousStrict;
	        state.allowYield = previousAllowYield;

	        return node.finishFunctionExpression(id, params, defaults, body, isGenerator);
	    }

	    // ECMA-262 14.5 Class Definitions

	    function parseClassBody() {
	        var classBody, token, isStatic, hasConstructor = false, body, method, computed, key;

	        classBody = new Node();

	        expect('{');
	        body = [];
	        while (!match('}')) {
	            if (match(';')) {
	                lex();
	            } else {
	                method = new Node();
	                token = lookahead;
	                isStatic = false;
	                computed = match('[');
	                if (match('*')) {
	                    lex();
	                } else {
	                    key = parseObjectPropertyKey();
	                    if (key.name === 'static' && (lookaheadPropertyName() || match('*'))) {
	                        token = lookahead;
	                        isStatic = true;
	                        computed = match('[');
	                        if (match('*')) {
	                            lex();
	                        } else {
	                            key = parseObjectPropertyKey();
	                        }
	                    }
	                }
	                method = tryParseMethodDefinition(token, key, computed, method);
	                if (method) {
	                    method['static'] = isStatic; // jscs:ignore requireDotNotation
	                    if (method.kind === 'init') {
	                        method.kind = 'method';
	                    }
	                    if (!isStatic) {
	                        if (!method.computed && (method.key.name || method.key.value.toString()) === 'constructor') {
	                            if (method.kind !== 'method' || !method.method || method.value.generator) {
	                                throwUnexpectedToken(token, Messages.ConstructorSpecialMethod);
	                            }
	                            if (hasConstructor) {
	                                throwUnexpectedToken(token, Messages.DuplicateConstructor);
	                            } else {
	                                hasConstructor = true;
	                            }
	                            method.kind = 'constructor';
	                        }
	                    } else {
	                        if (!method.computed && (method.key.name || method.key.value.toString()) === 'prototype') {
	                            throwUnexpectedToken(token, Messages.StaticPrototype);
	                        }
	                    }
	                    method.type = Syntax.MethodDefinition;
	                    delete method.method;
	                    delete method.shorthand;
	                    body.push(method);
	                } else {
	                    throwUnexpectedToken(lookahead);
	                }
	            }
	        }
	        lex();
	        return classBody.finishClassBody(body);
	    }

	    function parseClassDeclaration(identifierIsOptional) {
	        var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
	        strict = true;

	        expectKeyword('class');

	        if (!identifierIsOptional || lookahead.type === Token.Identifier) {
	            id = parseVariableIdentifier();
	        }

	        if (matchKeyword('extends')) {
	            lex();
	            superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
	        }
	        classBody = parseClassBody();
	        strict = previousStrict;

	        return classNode.finishClassDeclaration(id, superClass, classBody);
	    }

	    function parseClassExpression() {
	        var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
	        strict = true;

	        expectKeyword('class');

	        if (lookahead.type === Token.Identifier) {
	            id = parseVariableIdentifier();
	        }

	        if (matchKeyword('extends')) {
	            lex();
	            superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
	        }
	        classBody = parseClassBody();
	        strict = previousStrict;

	        return classNode.finishClassExpression(id, superClass, classBody);
	    }

	    // ECMA-262 15.2 Modules

	    function parseModuleSpecifier() {
	        var node = new Node();

	        if (lookahead.type !== Token.StringLiteral) {
	            throwError(Messages.InvalidModuleSpecifier);
	        }
	        return node.finishLiteral(lex());
	    }

	    // ECMA-262 15.2.3 Exports

	    function parseExportSpecifier() {
	        var exported, local, node = new Node(), def;
	        if (matchKeyword('default')) {
	            // export {default} from 'something';
	            def = new Node();
	            lex();
	            local = def.finishIdentifier('default');
	        } else {
	            local = parseVariableIdentifier();
	        }
	        if (matchContextualKeyword('as')) {
	            lex();
	            exported = parseNonComputedProperty();
	        }
	        return node.finishExportSpecifier(local, exported);
	    }

	    function parseExportNamedDeclaration(node) {
	        var declaration = null,
	            isExportFromIdentifier,
	            src = null, specifiers = [];

	        // non-default export
	        if (lookahead.type === Token.Keyword) {
	            // covers:
	            // export var f = 1;
	            switch (lookahead.value) {
	                case 'let':
	                case 'const':
	                    declaration = parseLexicalDeclaration({inFor: false});
	                    return node.finishExportNamedDeclaration(declaration, specifiers, null);
	                case 'var':
	                case 'class':
	                case 'function':
	                    declaration = parseStatementListItem();
	                    return node.finishExportNamedDeclaration(declaration, specifiers, null);
	            }
	        }

	        expect('{');
	        while (!match('}')) {
	            isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default');
	            specifiers.push(parseExportSpecifier());
	            if (!match('}')) {
	                expect(',');
	                if (match('}')) {
	                    break;
	                }
	            }
	        }
	        expect('}');

	        if (matchContextualKeyword('from')) {
	            // covering:
	            // export {default} from 'foo';
	            // export {foo} from 'foo';
	            lex();
	            src = parseModuleSpecifier();
	            consumeSemicolon();
	        } else if (isExportFromIdentifier) {
	            // covering:
	            // export {default}; // missing fromClause
	            throwError(lookahead.value ?
	                    Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
	        } else {
	            // cover
	            // export {foo};
	            consumeSemicolon();
	        }
	        return node.finishExportNamedDeclaration(declaration, specifiers, src);
	    }

	    function parseExportDefaultDeclaration(node) {
	        var declaration = null,
	            expression = null;

	        // covers:
	        // export default ...
	        expectKeyword('default');

	        if (matchKeyword('function')) {
	            // covers:
	            // export default function foo () {}
	            // export default function () {}
	            declaration = parseFunctionDeclaration(new Node(), true);
	            return node.finishExportDefaultDeclaration(declaration);
	        }
	        if (matchKeyword('class')) {
	            declaration = parseClassDeclaration(true);
	            return node.finishExportDefaultDeclaration(declaration);
	        }

	        if (matchContextualKeyword('from')) {
	            throwError(Messages.UnexpectedToken, lookahead.value);
	        }

	        // covers:
	        // export default {};
	        // export default [];
	        // export default (1 + 2);
	        if (match('{')) {
	            expression = parseObjectInitializer();
	        } else if (match('[')) {
	            expression = parseArrayInitializer();
	        } else {
	            expression = parseAssignmentExpression();
	        }
	        consumeSemicolon();
	        return node.finishExportDefaultDeclaration(expression);
	    }

	    function parseExportAllDeclaration(node) {
	        var src;

	        // covers:
	        // export * from 'foo';
	        expect('*');
	        if (!matchContextualKeyword('from')) {
	            throwError(lookahead.value ?
	                    Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
	        }
	        lex();
	        src = parseModuleSpecifier();
	        consumeSemicolon();

	        return node.finishExportAllDeclaration(src);
	    }

	    function parseExportDeclaration() {
	        var node = new Node();
	        if (state.inFunctionBody) {
	            throwError(Messages.IllegalExportDeclaration);
	        }

	        expectKeyword('export');

	        if (matchKeyword('default')) {
	            return parseExportDefaultDeclaration(node);
	        }
	        if (match('*')) {
	            return parseExportAllDeclaration(node);
	        }
	        return parseExportNamedDeclaration(node);
	    }

	    // ECMA-262 15.2.2 Imports

	    function parseImportSpecifier() {
	        // import {<foo as bar>} ...;
	        var local, imported, node = new Node();

	        imported = parseNonComputedProperty();
	        if (matchContextualKeyword('as')) {
	            lex();
	            local = parseVariableIdentifier();
	        }

	        return node.finishImportSpecifier(local, imported);
	    }

	    function parseNamedImports() {
	        var specifiers = [];
	        // {foo, bar as bas}
	        expect('{');
	        while (!match('}')) {
	            specifiers.push(parseImportSpecifier());
	            if (!match('}')) {
	                expect(',');
	                if (match('}')) {
	                    break;
	                }
	            }
	        }
	        expect('}');
	        return specifiers;
	    }

	    function parseImportDefaultSpecifier() {
	        // import <foo> ...;
	        var local, node = new Node();

	        local = parseNonComputedProperty();

	        return node.finishImportDefaultSpecifier(local);
	    }

	    function parseImportNamespaceSpecifier() {
	        // import <* as foo> ...;
	        var local, node = new Node();

	        expect('*');
	        if (!matchContextualKeyword('as')) {
	            throwError(Messages.NoAsAfterImportNamespace);
	        }
	        lex();
	        local = parseNonComputedProperty();

	        return node.finishImportNamespaceSpecifier(local);
	    }

	    function parseImportDeclaration() {
	        var specifiers = [], src, node = new Node();

	        if (state.inFunctionBody) {
	            throwError(Messages.IllegalImportDeclaration);
	        }

	        expectKeyword('import');

	        if (lookahead.type === Token.StringLiteral) {
	            // import 'foo';
	            src = parseModuleSpecifier();
	        } else {

	            if (match('{')) {
	                // import {bar}
	                specifiers = specifiers.concat(parseNamedImports());
	            } else if (match('*')) {
	                // import * as foo
	                specifiers.push(parseImportNamespaceSpecifier());
	            } else if (isIdentifierName(lookahead) && !matchKeyword('default')) {
	                // import foo
	                specifiers.push(parseImportDefaultSpecifier());
	                if (match(',')) {
	                    lex();
	                    if (match('*')) {
	                        // import foo, * as foo
	                        specifiers.push(parseImportNamespaceSpecifier());
	                    } else if (match('{')) {
	                        // import foo, {bar}
	                        specifiers = specifiers.concat(parseNamedImports());
	                    } else {
	                        throwUnexpectedToken(lookahead);
	                    }
	                }
	            } else {
	                throwUnexpectedToken(lex());
	            }

	            if (!matchContextualKeyword('from')) {
	                throwError(lookahead.value ?
	                        Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
	            }
	            lex();
	            src = parseModuleSpecifier();
	        }

	        consumeSemicolon();
	        return node.finishImportDeclaration(specifiers, src);
	    }

	    // ECMA-262 15.1 Scripts

	    function parseScriptBody() {
	        var statement, body = [], token, directive, firstRestricted;

	        while (startIndex < length) {
	            token = lookahead;
	            if (token.type !== Token.StringLiteral) {
	                break;
	            }

	            statement = parseStatementListItem();
	            body.push(statement);
	            if (statement.expression.type !== Syntax.Literal) {
	                // this is not directive
	                break;
	            }
	            directive = source.slice(token.start + 1, token.end - 1);
	            if (directive === 'use strict') {
	                strict = true;
	                if (firstRestricted) {
	                    tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
	                }
	            } else {
	                if (!firstRestricted && token.octal) {
	                    firstRestricted = token;
	                }
	            }
	        }

	        while (startIndex < length) {
	            statement = parseStatementListItem();
	            /* istanbul ignore if */
	            if (typeof statement === 'undefined') {
	                break;
	            }
	            body.push(statement);
	        }
	        return body;
	    }

	    function parseProgram() {
	        var body, node;

	        peek();
	        node = new Node();

	        body = parseScriptBody();
	        return node.finishProgram(body, state.sourceType);
	    }

	    function filterTokenLocation() {
	        var i, entry, token, tokens = [];

	        for (i = 0; i < extra.tokens.length; ++i) {
	            entry = extra.tokens[i];
	            token = {
	                type: entry.type,
	                value: entry.value
	            };
	            if (entry.regex) {
	                token.regex = {
	                    pattern: entry.regex.pattern,
	                    flags: entry.regex.flags
	                };
	            }
	            if (extra.range) {
	                token.range = entry.range;
	            }
	            if (extra.loc) {
	                token.loc = entry.loc;
	            }
	            tokens.push(token);
	        }

	        extra.tokens = tokens;
	    }

	    function tokenize(code, options, delegate) {
	        var toString,
	            tokens;

	        toString = String;
	        if (typeof code !== 'string' && !(code instanceof String)) {
	            code = toString(code);
	        }

	        source = code;
	        index = 0;
	        lineNumber = (source.length > 0) ? 1 : 0;
	        lineStart = 0;
	        startIndex = index;
	        startLineNumber = lineNumber;
	        startLineStart = lineStart;
	        length = source.length;
	        lookahead = null;
	        state = {
	            allowIn: true,
	            allowYield: true,
	            labelSet: {},
	            inFunctionBody: false,
	            inIteration: false,
	            inSwitch: false,
	            lastCommentStart: -1,
	            curlyStack: []
	        };

	        extra = {};

	        // Options matching.
	        options = options || {};

	        // Of course we collect tokens here.
	        options.tokens = true;
	        extra.tokens = [];
	        extra.tokenValues = [];
	        extra.tokenize = true;
	        extra.delegate = delegate;

	        // The following two fields are necessary to compute the Regex tokens.
	        extra.openParenToken = -1;
	        extra.openCurlyToken = -1;

	        extra.range = (typeof options.range === 'boolean') && options.range;
	        extra.loc = (typeof options.loc === 'boolean') && options.loc;

	        if (typeof options.comment === 'boolean' && options.comment) {
	            extra.comments = [];
	        }
	        if (typeof options.tolerant === 'boolean' && options.tolerant) {
	            extra.errors = [];
	        }

	        try {
	            peek();
	            if (lookahead.type === Token.EOF) {
	                return extra.tokens;
	            }

	            lex();
	            while (lookahead.type !== Token.EOF) {
	                try {
	                    lex();
	                } catch (lexError) {
	                    if (extra.errors) {
	                        recordError(lexError);
	                        // We have to break on the first error
	                        // to avoid infinite loops.
	                        break;
	                    } else {
	                        throw lexError;
	                    }
	                }
	            }

	            tokens = extra.tokens;
	            if (typeof extra.errors !== 'undefined') {
	                tokens.errors = extra.errors;
	            }
	        } catch (e) {
	            throw e;
	        } finally {
	            extra = {};
	        }
	        return tokens;
	    }

	    function parse(code, options) {
	        var program, toString;

	        toString = String;
	        if (typeof code !== 'string' && !(code instanceof String)) {
	            code = toString(code);
	        }

	        source = code;
	        index = 0;
	        lineNumber = (source.length > 0) ? 1 : 0;
	        lineStart = 0;
	        startIndex = index;
	        startLineNumber = lineNumber;
	        startLineStart = lineStart;
	        length = source.length;
	        lookahead = null;
	        state = {
	            allowIn: true,
	            allowYield: true,
	            labelSet: {},
	            inFunctionBody: false,
	            inIteration: false,
	            inSwitch: false,
	            lastCommentStart: -1,
	            curlyStack: [],
	            sourceType: 'script'
	        };
	        strict = false;

	        extra = {};
	        if (typeof options !== 'undefined') {
	            extra.range = (typeof options.range === 'boolean') && options.range;
	            extra.loc = (typeof options.loc === 'boolean') && options.loc;
	            extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;

	            if (extra.loc && options.source !== null && options.source !== undefined) {
	                extra.source = toString(options.source);
	            }

	            if (typeof options.tokens === 'boolean' && options.tokens) {
	                extra.tokens = [];
	            }
	            if (typeof options.comment === 'boolean' && options.comment) {
	                extra.comments = [];
	            }
	            if (typeof options.tolerant === 'boolean' && options.tolerant) {
	                extra.errors = [];
	            }
	            if (extra.attachComment) {
	                extra.range = true;
	                extra.comments = [];
	                extra.bottomRightStack = [];
	                extra.trailingComments = [];
	                extra.leadingComments = [];
	            }
	            if (options.sourceType === 'module') {
	                // very restrictive condition for now
	                state.sourceType = options.sourceType;
	                strict = true;
	            }
	        }

	        try {
	            program = parseProgram();
	            if (typeof extra.comments !== 'undefined') {
	                program.comments = extra.comments;
	            }
	            if (typeof extra.tokens !== 'undefined') {
	                filterTokenLocation();
	                program.tokens = extra.tokens;
	            }
	            if (typeof extra.errors !== 'undefined') {
	                program.errors = extra.errors;
	            }
	        } catch (e) {
	            throw e;
	        } finally {
	            extra = {};
	        }

	        return program;
	    }

	    // Sync with *.json manifests.
	    exports.version = '2.7.1';

	    exports.tokenize = tokenize;

	    exports.parse = parse;

	    // Deep copy.
	    /* istanbul ignore next */
	    exports.Syntax = (function () {
	        var name, types = {};

	        if (typeof Object.create === 'function') {
	            types = Object.create(null);
	        }

	        for (name in Syntax) {
	            if (Syntax.hasOwnProperty(name)) {
	                types[name] = Syntax[name];
	            }
	        }

	        if (typeof Object.freeze === 'function') {
	            Object.freeze(types);
	        }

	        return types;
	    }());

	}));
	/* vim: set sw=4 ts=4 et tw=80 : */


/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {

	function DOMParser(options){
		this.options = options ||{locator:{}};
		
	}
	DOMParser.prototype.parseFromString = function(source,mimeType){	
		var options = this.options;
		var sax =  new XMLReader();
		var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
		var errorHandler = options.errorHandler;
		var locator = options.locator;
		var defaultNSMap = options.xmlns||{};
		var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
		if(locator){
			domBuilder.setDocumentLocator(locator)
		}
		
		sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
		sax.domBuilder = options.domBuilder || domBuilder;
		if(/\/x?html?$/.test(mimeType)){
			entityMap.nbsp = '\xa0';
			entityMap.copy = '\xa9';
			defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
		}
		defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
		if(source){
			sax.parse(source,defaultNSMap,entityMap);
		}else{
			sax.errorHandler.error("invalid document source");
		}
		return domBuilder.document;
	}
	function buildErrorHandler(errorImpl,domBuilder,locator){
		if(!errorImpl){
			if(domBuilder instanceof DOMHandler){
				return domBuilder;
			}
			errorImpl = domBuilder ;
		}
		var errorHandler = {}
		var isCallback = errorImpl instanceof Function;
		locator = locator||{}
		function build(key){
			var fn = errorImpl[key];
			if(!fn && isCallback){
				fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
			}
			errorHandler[key] = fn && function(msg){
				fn('[xmldom '+key+']\t'+msg+_locator(locator));
			}||function(){};
		}
		build('warning');
		build('error');
		build('fatalError');
		return errorHandler;
	}

	//console.log('#\n\n\n\n\n\n\n####')
	/**
	 * +ContentHandler+ErrorHandler
	 * +LexicalHandler+EntityResolver2
	 * -DeclHandler-DTDHandler 
	 * 
	 * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
	 * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
	 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
	 */
	function DOMHandler() {
	    this.cdata = false;
	}
	function position(locator,node){
		node.lineNumber = locator.lineNumber;
		node.columnNumber = locator.columnNumber;
	}
	/**
	 * @see org.xml.sax.ContentHandler#startDocument
	 * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
	 */ 
	DOMHandler.prototype = {
		startDocument : function() {
	    	this.document = new DOMImplementation().createDocument(null, null, null);
	    	if (this.locator) {
	        	this.document.documentURI = this.locator.systemId;
	    	}
		},
		startElement:function(namespaceURI, localName, qName, attrs) {
			var doc = this.document;
		    var el = doc.createElementNS(namespaceURI, qName||localName);
		    var len = attrs.length;
		    appendElement(this, el);
		    this.currentElement = el;
		    
			this.locator && position(this.locator,el)
		    for (var i = 0 ; i < len; i++) {
		        var namespaceURI = attrs.getURI(i);
		        var value = attrs.getValue(i);
		        var qName = attrs.getQName(i);
				var attr = doc.createAttributeNS(namespaceURI, qName);
				if( attr.getOffset){
					position(attr.getOffset(1),attr)
				}
				attr.value = attr.nodeValue = value;
				el.setAttributeNode(attr)
		    }
		},
		endElement:function(namespaceURI, localName, qName) {
			var current = this.currentElement
		    var tagName = current.tagName;
		    this.currentElement = current.parentNode;
		},
		startPrefixMapping:function(prefix, uri) {
		},
		endPrefixMapping:function(prefix) {
		},
		processingInstruction:function(target, data) {
		    var ins = this.document.createProcessingInstruction(target, data);
		    this.locator && position(this.locator,ins)
		    appendElement(this, ins);
		},
		ignorableWhitespace:function(ch, start, length) {
		},
		characters:function(chars, start, length) {
			chars = _toString.apply(this,arguments)
			//console.log(chars)
			if(this.currentElement && chars){
				if (this.cdata) {
					var charNode = this.document.createCDATASection(chars);
					this.currentElement.appendChild(charNode);
				} else {
					var charNode = this.document.createTextNode(chars);
					this.currentElement.appendChild(charNode);
				}
				this.locator && position(this.locator,charNode)
			}
		},
		skippedEntity:function(name) {
		},
		endDocument:function() {
			this.document.normalize();
		},
		setDocumentLocator:function (locator) {
		    if(this.locator = locator){// && !('lineNumber' in locator)){
		    	locator.lineNumber = 0;
		    }
		},
		//LexicalHandler
		comment:function(chars, start, length) {
			chars = _toString.apply(this,arguments)
		    var comm = this.document.createComment(chars);
		    this.locator && position(this.locator,comm)
		    appendElement(this, comm);
		},
		
		startCDATA:function() {
		    //used in characters() methods
		    this.cdata = true;
		},
		endCDATA:function() {
		    this.cdata = false;
		},
		
		startDTD:function(name, publicId, systemId) {
			var impl = this.document.implementation;
		    if (impl && impl.createDocumentType) {
		        var dt = impl.createDocumentType(name, publicId, systemId);
		        this.locator && position(this.locator,dt)
		        appendElement(this, dt);
		    }
		},
		/**
		 * @see org.xml.sax.ErrorHandler
		 * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
		 */
		warning:function(error) {
			console.warn('[xmldom warning]\t'+error,_locator(this.locator));
		},
		error:function(error) {
			console.error('[xmldom error]\t'+error,_locator(this.locator));
		},
		fatalError:function(error) {
			console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
		    throw error;
		}
	}
	function _locator(l){
		if(l){
			return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
		}
	}
	function _toString(chars,start,length){
		if(typeof chars == 'string'){
			return chars.substr(start,length)
		}else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
			if(chars.length >= start+length || start){
				return new java.lang.String(chars,start,length)+'';
			}
			return chars;
		}
	}

	/*
	 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
	 * used method of org.xml.sax.ext.LexicalHandler:
	 *  #comment(chars, start, length)
	 *  #startCDATA()
	 *  #endCDATA()
	 *  #startDTD(name, publicId, systemId)
	 *
	 *
	 * IGNORED method of org.xml.sax.ext.LexicalHandler:
	 *  #endDTD()
	 *  #startEntity(name)
	 *  #endEntity(name)
	 *
	 *
	 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
	 * IGNORED method of org.xml.sax.ext.DeclHandler
	 * 	#attributeDecl(eName, aName, type, mode, value)
	 *  #elementDecl(name, model)
	 *  #externalEntityDecl(name, publicId, systemId)
	 *  #internalEntityDecl(name, value)
	 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
	 * IGNORED method of org.xml.sax.EntityResolver2
	 *  #resolveEntity(String name,String publicId,String baseURI,String systemId)
	 *  #resolveEntity(publicId, systemId)
	 *  #getExternalSubset(name, baseURI)
	 * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
	 * IGNORED method of org.xml.sax.DTDHandler
	 *  #notationDecl(name, publicId, systemId) {};
	 *  #unparsedEntityDecl(name, publicId, systemId, notationName) {};
	 */
	"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
		DOMHandler.prototype[key] = function(){return null}
	})

	/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
	function appendElement (hander,node) {
	    if (!hander.currentElement) {
	        hander.document.appendChild(node);
	    } else {
	        hander.currentElement.appendChild(node);
	    }
	}//appendChild and setAttributeNS are preformance key

	if(true){
		var XMLReader = __webpack_require__(11).XMLReader;
		var DOMImplementation = exports.DOMImplementation = __webpack_require__(12).DOMImplementation;
		exports.XMLSerializer = __webpack_require__(12).XMLSerializer ;
		exports.DOMParser = DOMParser;
	}


/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {

	//[4]   	NameStartChar	   ::=   	":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
	//[4a]   	NameChar	   ::=   	NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
	//[5]   	Name	   ::=   	NameStartChar (NameChar)*
	var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
	var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
	var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
	//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
	//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')

	//S_TAG,	S_ATTR,	S_EQ,	S_V
	//S_ATTR_S,	S_E,	S_S,	S_C
	var S_TAG = 0;//tag name offerring
	var S_ATTR = 1;//attr name offerring 
	var S_ATTR_S=2;//attr name end and space offer
	var S_EQ = 3;//=space?
	var S_V = 4;//attr value(no quot value only)
	var S_E = 5;//attr value end and no space(quot end)
	var S_S = 6;//(attr value end || tag end ) && (space offer)
	var S_C = 7;//closed el<el />

	function XMLReader(){
		
	}

	XMLReader.prototype = {
		parse:function(source,defaultNSMap,entityMap){
			var domBuilder = this.domBuilder;
			domBuilder.startDocument();
			_copy(defaultNSMap ,defaultNSMap = {})
			parse(source,defaultNSMap,entityMap,
					domBuilder,this.errorHandler);
			domBuilder.endDocument();
		}
	}
	function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
	  function fixedFromCharCode(code) {
			// String.prototype.fromCharCode does not supports
			// > 2 bytes unicode chars directly
			if (code > 0xffff) {
				code -= 0x10000;
				var surrogate1 = 0xd800 + (code >> 10)
					, surrogate2 = 0xdc00 + (code & 0x3ff);

				return String.fromCharCode(surrogate1, surrogate2);
			} else {
				return String.fromCharCode(code);
			}
		}
		function entityReplacer(a){
			var k = a.slice(1,-1);
			if(k in entityMap){
				return entityMap[k]; 
			}else if(k.charAt(0) === '#'){
				return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
			}else{
				errorHandler.error('entity not found:'+a);
				return a;
			}
		}
		function appendText(end){//has some bugs
			if(end>start){
				var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
				locator&&position(start);
				domBuilder.characters(xt,0,end-start);
				start = end
			}
		}
		function position(p,m){
			while(p>=lineEnd && (m = linePattern.exec(source))){
				lineStart = m.index;
				lineEnd = lineStart + m[0].length;
				locator.lineNumber++;
				//console.log('line++:',locator,startPos,endPos)
			}
			locator.columnNumber = p-lineStart+1;
		}
		var lineStart = 0;
		var lineEnd = 0;
		var linePattern = /.+(?:\r\n?|\n)|.*$/g
		var locator = domBuilder.locator;
		
		var parseStack = [{currentNSMap:defaultNSMapCopy}]
		var closeMap = {};
		var start = 0;
		while(true){
			try{
				var tagStart = source.indexOf('<',start);
				if(tagStart<0){
					if(!source.substr(start).match(/^\s*$/)){
						var doc = domBuilder.document;
		    			var text = doc.createTextNode(source.substr(start));
		    			doc.appendChild(text);
		    			domBuilder.currentElement = text;
					}
					return;
				}
				if(tagStart>start){
					appendText(tagStart);
				}
				switch(source.charAt(tagStart+1)){
				case '/':
					var end = source.indexOf('>',tagStart+3);
					var tagName = source.substring(tagStart+2,end);
					var config = parseStack.pop();
					var localNSMap = config.localNSMap;
			        if(config.tagName != tagName){
			            errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
			        }
					domBuilder.endElement(config.uri,config.localName,tagName);
					if(localNSMap){
						for(var prefix in localNSMap){
							domBuilder.endPrefixMapping(prefix) ;
						}
					}
					end++;
					break;
					// end elment
				case '?':// <?...?>
					locator&&position(tagStart);
					end = parseInstruction(source,tagStart,domBuilder);
					break;
				case '!':// <!doctype,<![CDATA,<!--
					locator&&position(tagStart);
					end = parseDCC(source,tagStart,domBuilder,errorHandler);
					break;
				default:
				
					locator&&position(tagStart);
					
					var el = new ElementAttributes();
					
					//elStartEnd
					var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
					var len = el.length;
					
					if(locator){
						if(len){
							//attribute position fixed
							for(var i = 0;i<len;i++){
								var a = el[i];
								position(a.offset);
								a.offset = copyLocator(locator,{});
							}
						}
						position(end);
					}
					if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
						el.closed = true;
						if(!entityMap.nbsp){
							errorHandler.warning('unclosed xml attribute');
						}
					}
					appendElement(el,domBuilder,parseStack);
					
					
					if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
						end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
					}else{
						end++;
					}
				}
			}catch(e){
				errorHandler.error('element parse error: '+e);
				end = -1;
			}
			if(end>start){
				start = end;
			}else{
				//TODO: 这里有可能sax回退，有位置错误风险
				appendText(Math.max(tagStart,start)+1);
			}
		}
	}
	function copyLocator(f,t){
		t.lineNumber = f.lineNumber;
		t.columnNumber = f.columnNumber;
		return t;
	}

	/**
	 * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
	 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
	 */
	function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
		var attrName;
		var value;
		var p = ++start;
		var s = S_TAG;//status
		while(true){
			var c = source.charAt(p);
			switch(c){
			case '=':
				if(s === S_ATTR){//attrName
					attrName = source.slice(start,p);
					s = S_EQ;
				}else if(s === S_ATTR_S){
					s = S_EQ;
				}else{
					//fatalError: equal must after attrName or space after attrName
					throw new Error('attribute equal must after attrName');
				}
				break;
			case '\'':
			case '"':
				if(s === S_EQ){//equal
					start = p+1;
					p = source.indexOf(c,start)
					if(p>0){
						value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
						el.add(attrName,value,start-1);
						s = S_E;
					}else{
						//fatalError: no end quot match
						throw new Error('attribute value no end \''+c+'\' match');
					}
				}else if(s == S_V){
					value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
					//console.log(attrName,value,start,p)
					el.add(attrName,value,start);
					//console.dir(el)
					errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
					start = p+1;
					s = S_E
				}else{
					//fatalError: no equal before
					throw new Error('attribute value must after "="');
				}
				break;
			case '/':
				switch(s){
				case S_TAG:
					el.setTagName(source.slice(start,p));
				case S_E:
				case S_S:
				case S_C:
					s = S_C;
					el.closed = true;
				case S_V:
				case S_ATTR:
				case S_ATTR_S:
					break;
				//case S_EQ:
				default:
					throw new Error("attribute invalid close char('/')")
				}
				break;
			case ''://end document
				//throw new Error('unexpected end of input')
				errorHandler.error('unexpected end of input');
			case '>':
				switch(s){
				case S_TAG:
					el.setTagName(source.slice(start,p));
				case S_E:
				case S_S:
				case S_C:
					break;//normal
				case S_V://Compatible state
				case S_ATTR:
					value = source.slice(start,p);
					if(value.slice(-1) === '/'){
						el.closed  = true;
						value = value.slice(0,-1)
					}
				case S_ATTR_S:
					if(s === S_ATTR_S){
						value = attrName;
					}
					if(s == S_V){
						errorHandler.warning('attribute "'+value+'" missed quot(")!!');
						el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start)
					}else{
						errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
						el.add(value,value,start)
					}
					break;
				case S_EQ:
					throw new Error('attribute value missed!!');
				}
	//			console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
				return p;
			/*xml space '\x20' | #x9 | #xD | #xA; */
			case '\u0080':
				c = ' ';
			default:
				if(c<= ' '){//space
					switch(s){
					case S_TAG:
						el.setTagName(source.slice(start,p));//tagName
						s = S_S;
						break;
					case S_ATTR:
						attrName = source.slice(start,p)
						s = S_ATTR_S;
						break;
					case S_V:
						var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
						errorHandler.warning('attribute "'+value+'" missed quot(")!!');
						el.add(attrName,value,start)
					case S_E:
						s = S_S;
						break;
					//case S_S:
					//case S_EQ:
					//case S_ATTR_S:
					//	void();break;
					//case S_C:
						//ignore warning
					}
				}else{//not space
	//S_TAG,	S_ATTR,	S_EQ,	S_V
	//S_ATTR_S,	S_E,	S_S,	S_C
					switch(s){
					//case S_TAG:void();break;
					//case S_ATTR:void();break;
					//case S_V:void();break;
					case S_ATTR_S:
						errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!')
						el.add(attrName,attrName,start);
						start = p;
						s = S_ATTR;
						break;
					case S_E:
						errorHandler.warning('attribute space is required"'+attrName+'"!!')
					case S_S:
						s = S_ATTR;
						start = p;
						break;
					case S_EQ:
						s = S_V;
						start = p;
						break;
					case S_C:
						throw new Error("elements closed character '/' and '>' must be connected to");
					}
				}
			}
			p++;
		}
	}
	/**
	 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
	 */
	function appendElement(el,domBuilder,parseStack){
		var tagName = el.tagName;
		var localNSMap = null;
		var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
		var i = el.length;
		while(i--){
			var a = el[i];
			var qName = a.qName;
			var value = a.value;
			var nsp = qName.indexOf(':');
			if(nsp>0){
				var prefix = a.prefix = qName.slice(0,nsp);
				var localName = qName.slice(nsp+1);
				var nsPrefix = prefix === 'xmlns' && localName
			}else{
				localName = qName;
				prefix = null
				nsPrefix = qName === 'xmlns' && ''
			}
			//can not set prefix,because prefix !== ''
			a.localName = localName ;
			//prefix == null for no ns prefix attribute 
			if(nsPrefix !== false){//hack!!
				if(localNSMap == null){
					localNSMap = {}
					//console.log(currentNSMap,0)
					_copy(currentNSMap,currentNSMap={})
					//console.log(currentNSMap,1)
				}
				currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
				a.uri = 'http://www.w3.org/2000/xmlns/'
				domBuilder.startPrefixMapping(nsPrefix, value) 
			}
		}
		var i = el.length;
		while(i--){
			a = el[i];
			var prefix = a.prefix;
			if(prefix){//no prefix attribute has no namespace
				if(prefix === 'xml'){
					a.uri = 'http://www.w3.org/XML/1998/namespace';
				}if(prefix !== 'xmlns'){
					a.uri = currentNSMap[prefix]
					
					//{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
				}
			}
		}
		var nsp = tagName.indexOf(':');
		if(nsp>0){
			prefix = el.prefix = tagName.slice(0,nsp);
			localName = el.localName = tagName.slice(nsp+1);
		}else{
			prefix = null;//important!!
			localName = el.localName = tagName;
		}
		//no prefix element has default namespace
		var ns = el.uri = currentNSMap[prefix || ''];
		domBuilder.startElement(ns,localName,tagName,el);
		//endPrefixMapping and startPrefixMapping have not any help for dom builder
		//localNSMap = null
		if(el.closed){
			domBuilder.endElement(ns,localName,tagName);
			if(localNSMap){
				for(prefix in localNSMap){
					domBuilder.endPrefixMapping(prefix) 
				}
			}
		}else{
			el.currentNSMap = currentNSMap;
			el.localNSMap = localNSMap;
			parseStack.push(el);
		}
	}
	function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
		if(/^(?:script|textarea)$/i.test(tagName)){
			var elEndStart =  source.indexOf('</'+tagName+'>',elStartEnd);
			var text = source.substring(elStartEnd+1,elEndStart);
			if(/[&<]/.test(text)){
				if(/^script$/i.test(tagName)){
					//if(!/\]\]>/.test(text)){
						//lexHandler.startCDATA();
						domBuilder.characters(text,0,text.length);
						//lexHandler.endCDATA();
						return elEndStart;
					//}
				}//}else{//text area
					text = text.replace(/&#?\w+;/g,entityReplacer);
					domBuilder.characters(text,0,text.length);
					return elEndStart;
				//}
				
			}
		}
		return elStartEnd+1;
	}
	function fixSelfClosed(source,elStartEnd,tagName,closeMap){
		//if(tagName in closeMap){
		var pos = closeMap[tagName];
		if(pos == null){
			//console.log(tagName)
			pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>')
		}
		return pos<elStartEnd;
		//} 
	}
	function _copy(source,target){
		for(var n in source){target[n] = source[n]}
	}
	function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
		var next= source.charAt(start+2)
		switch(next){
		case '-':
			if(source.charAt(start + 3) === '-'){
				var end = source.indexOf('-->',start+4);
				//append comment source.substring(4,end)//<!--
				if(end>start){
					domBuilder.comment(source,start+4,end-start-4);
					return end+3;
				}else{
					errorHandler.error("Unclosed comment");
					return -1;
				}
			}else{
				//error
				return -1;
			}
		default:
			if(source.substr(start+3,6) == 'CDATA['){
				var end = source.indexOf(']]>',start+9);
				domBuilder.startCDATA();
				domBuilder.characters(source,start+9,end-start-9);
				domBuilder.endCDATA() 
				return end+3;
			}
			//<!DOCTYPE
			//startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId) 
			var matchs = split(source,start);
			var len = matchs.length;
			if(len>1 && /!doctype/i.test(matchs[0][0])){
				var name = matchs[1][0];
				var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
				var sysid = len>4 && matchs[4][0];
				var lastMatch = matchs[len-1]
				domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
						sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
				domBuilder.endDTD();
				
				return lastMatch.index+lastMatch[0].length
			}
		}
		return -1;
	}



	function parseInstruction(source,start,domBuilder){
		var end = source.indexOf('?>',start);
		if(end){
			var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
			if(match){
				var len = match[0].length;
				domBuilder.processingInstruction(match[1], match[2]) ;
				return end+2;
			}else{//error
				return -1;
			}
		}
		return -1;
	}

	/**
	 * @param source
	 */
	function ElementAttributes(source){
		
	}
	ElementAttributes.prototype = {
		setTagName:function(tagName){
			if(!tagNamePattern.test(tagName)){
				throw new Error('invalid tagName:'+tagName)
			}
			this.tagName = tagName
		},
		add:function(qName,value,offset){
			if(!tagNamePattern.test(qName)){
				throw new Error('invalid attribute:'+qName)
			}
			this[this.length++] = {qName:qName,value:value,offset:offset}
		},
		length:0,
		getLocalName:function(i){return this[i].localName},
		getOffset:function(i){return this[i].offset},
		getQName:function(i){return this[i].qName},
		getURI:function(i){return this[i].uri},
		getValue:function(i){return this[i].value}
	//	,getIndex:function(uri, localName)){
	//		if(localName){
	//			
	//		}else{
	//			var qName = uri
	//		}
	//	},
	//	getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
	//	getType:function(uri,localName){}
	//	getType:function(i){},
	}




	function _set_proto_(thiz,parent){
		thiz.__proto__ = parent;
		return thiz;
	}
	if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
		_set_proto_ = function(thiz,parent){
			function p(){};
			p.prototype = parent;
			p = new p();
			for(parent in thiz){
				p[parent] = thiz[parent];
			}
			return p;
		}
	}

	function split(source,start){
		var match;
		var buf = [];
		var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
		reg.lastIndex = start;
		reg.exec(source);//skip <
		while(match = reg.exec(source)){
			buf.push(match);
			if(match[1])return buf;
		}
	}

	if(true){
		exports.XMLReader = XMLReader;
	}



/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {

	/*
	 * DOM Level 2
	 * Object DOMException
	 * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
	 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
	 */

	function copy(src,dest){
		for(var p in src){
			dest[p] = src[p];
		}
	}
	/**
	^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
	^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
	 */
	function _extends(Class,Super){
		var pt = Class.prototype;
		if(Object.create){
			var ppt = Object.create(Super.prototype)
			pt.__proto__ = ppt;
		}
		if(!(pt instanceof Super)){
			function t(){};
			t.prototype = Super.prototype;
			t = new t();
			copy(pt,t);
			Class.prototype = pt = t;
		}
		if(pt.constructor != Class){
			if(typeof Class != 'function'){
				console.error("unknow Class:"+Class)
			}
			pt.constructor = Class
		}
	}
	var htmlns = 'http://www.w3.org/1999/xhtml' ;
	// Node Types
	var NodeType = {}
	var ELEMENT_NODE                = NodeType.ELEMENT_NODE                = 1;
	var ATTRIBUTE_NODE              = NodeType.ATTRIBUTE_NODE              = 2;
	var TEXT_NODE                   = NodeType.TEXT_NODE                   = 3;
	var CDATA_SECTION_NODE          = NodeType.CDATA_SECTION_NODE          = 4;
	var ENTITY_REFERENCE_NODE       = NodeType.ENTITY_REFERENCE_NODE       = 5;
	var ENTITY_NODE                 = NodeType.ENTITY_NODE                 = 6;
	var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
	var COMMENT_NODE                = NodeType.COMMENT_NODE                = 8;
	var DOCUMENT_NODE               = NodeType.DOCUMENT_NODE               = 9;
	var DOCUMENT_TYPE_NODE          = NodeType.DOCUMENT_TYPE_NODE          = 10;
	var DOCUMENT_FRAGMENT_NODE      = NodeType.DOCUMENT_FRAGMENT_NODE      = 11;
	var NOTATION_NODE               = NodeType.NOTATION_NODE               = 12;

	// ExceptionCode
	var ExceptionCode = {}
	var ExceptionMessage = {};
	var INDEX_SIZE_ERR              = ExceptionCode.INDEX_SIZE_ERR              = ((ExceptionMessage[1]="Index size error"),1);
	var DOMSTRING_SIZE_ERR          = ExceptionCode.DOMSTRING_SIZE_ERR          = ((ExceptionMessage[2]="DOMString size error"),2);
	var HIERARCHY_REQUEST_ERR       = ExceptionCode.HIERARCHY_REQUEST_ERR       = ((ExceptionMessage[3]="Hierarchy request error"),3);
	var WRONG_DOCUMENT_ERR          = ExceptionCode.WRONG_DOCUMENT_ERR          = ((ExceptionMessage[4]="Wrong document"),4);
	var INVALID_CHARACTER_ERR       = ExceptionCode.INVALID_CHARACTER_ERR       = ((ExceptionMessage[5]="Invalid character"),5);
	var NO_DATA_ALLOWED_ERR         = ExceptionCode.NO_DATA_ALLOWED_ERR         = ((ExceptionMessage[6]="No data allowed"),6);
	var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
	var NOT_FOUND_ERR               = ExceptionCode.NOT_FOUND_ERR               = ((ExceptionMessage[8]="Not found"),8);
	var NOT_SUPPORTED_ERR           = ExceptionCode.NOT_SUPPORTED_ERR           = ((ExceptionMessage[9]="Not supported"),9);
	var INUSE_ATTRIBUTE_ERR         = ExceptionCode.INUSE_ATTRIBUTE_ERR         = ((ExceptionMessage[10]="Attribute in use"),10);
	//level2
	var INVALID_STATE_ERR        	= ExceptionCode.INVALID_STATE_ERR        	= ((ExceptionMessage[11]="Invalid state"),11);
	var SYNTAX_ERR               	= ExceptionCode.SYNTAX_ERR               	= ((ExceptionMessage[12]="Syntax error"),12);
	var INVALID_MODIFICATION_ERR 	= ExceptionCode.INVALID_MODIFICATION_ERR 	= ((ExceptionMessage[13]="Invalid modification"),13);
	var NAMESPACE_ERR            	= ExceptionCode.NAMESPACE_ERR           	= ((ExceptionMessage[14]="Invalid namespace"),14);
	var INVALID_ACCESS_ERR       	= ExceptionCode.INVALID_ACCESS_ERR      	= ((ExceptionMessage[15]="Invalid access"),15);


	function DOMException(code, message) {
		if(message instanceof Error){
			var error = message;
		}else{
			error = this;
			Error.call(this, ExceptionMessage[code]);
			this.message = ExceptionMessage[code];
			if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
		}
		error.code = code;
		if(message) this.message = this.message + ": " + message;
		return error;
	};
	DOMException.prototype = Error.prototype;
	copy(ExceptionCode,DOMException)
	/**
	 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
	 * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
	 * The items in the NodeList are accessible via an integral index, starting from 0.
	 */
	function NodeList() {
	};
	NodeList.prototype = {
		/**
		 * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
		 * @standard level1
		 */
		length:0, 
		/**
		 * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
		 * @standard level1
		 * @param index  unsigned long 
		 *   Index into the collection.
		 * @return Node
		 * 	The node at the indexth position in the NodeList, or null if that is not a valid index. 
		 */
		item: function(index) {
			return this[index] || null;
		},
		toString:function(){
			for(var buf = [], i = 0;i<this.length;i++){
				serializeToString(this[i],buf);
			}
			return buf.join('');
		}
	};
	function LiveNodeList(node,refresh){
		this._node = node;
		this._refresh = refresh
		_updateLiveList(this);
	}
	function _updateLiveList(list){
		var inc = list._node._inc || list._node.ownerDocument._inc;
		if(list._inc != inc){
			var ls = list._refresh(list._node);
			//console.log(ls.length)
			__set__(list,'length',ls.length);
			copy(ls,list);
			list._inc = inc;
		}
	}
	LiveNodeList.prototype.item = function(i){
		_updateLiveList(this);
		return this[i];
	}

	_extends(LiveNodeList,NodeList);
	/**
	 * 
	 * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
	 * NamedNodeMap objects in the DOM are live.
	 * used for attributes or DocumentType entities 
	 */
	function NamedNodeMap() {
	};

	function _findNodeIndex(list,node){
		var i = list.length;
		while(i--){
			if(list[i] === node){return i}
		}
	}

	function _addNamedNode(el,list,newAttr,oldAttr){
		if(oldAttr){
			list[_findNodeIndex(list,oldAttr)] = newAttr;
		}else{
			list[list.length++] = newAttr;
		}
		if(el){
			newAttr.ownerElement = el;
			var doc = el.ownerDocument;
			if(doc){
				oldAttr && _onRemoveAttribute(doc,el,oldAttr);
				_onAddAttribute(doc,el,newAttr);
			}
		}
	}
	function _removeNamedNode(el,list,attr){
		var i = _findNodeIndex(list,attr);
		if(i>=0){
			var lastIndex = list.length-1
			while(i<lastIndex){
				list[i] = list[++i]
			}
			list.length = lastIndex;
			if(el){
				var doc = el.ownerDocument;
				if(doc){
					_onRemoveAttribute(doc,el,attr);
					attr.ownerElement = null;
				}
			}
		}else{
			throw DOMException(NOT_FOUND_ERR,new Error())
		}
	}
	NamedNodeMap.prototype = {
		length:0,
		item:NodeList.prototype.item,
		getNamedItem: function(key) {
	//		if(key.indexOf(':')>0 || key == 'xmlns'){
	//			return null;
	//		}
			var i = this.length;
			while(i--){
				var attr = this[i];
				if(attr.nodeName == key){
					return attr;
				}
			}
		},
		setNamedItem: function(attr) {
			var el = attr.ownerElement;
			if(el && el!=this._ownerElement){
				throw new DOMException(INUSE_ATTRIBUTE_ERR);
			}
			var oldAttr = this.getNamedItem(attr.nodeName);
			_addNamedNode(this._ownerElement,this,attr,oldAttr);
			return oldAttr;
		},
		/* returns Node */
		setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
			var el = attr.ownerElement, oldAttr;
			if(el && el!=this._ownerElement){
				throw new DOMException(INUSE_ATTRIBUTE_ERR);
			}
			oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
			_addNamedNode(this._ownerElement,this,attr,oldAttr);
			return oldAttr;
		},

		/* returns Node */
		removeNamedItem: function(key) {
			var attr = this.getNamedItem(key);
			_removeNamedNode(this._ownerElement,this,attr);
			return attr;
			
			
		},// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
		
		//for level2
		removeNamedItemNS:function(namespaceURI,localName){
			var attr = this.getNamedItemNS(namespaceURI,localName);
			_removeNamedNode(this._ownerElement,this,attr);
			return attr;
		},
		getNamedItemNS: function(namespaceURI, localName) {
			var i = this.length;
			while(i--){
				var node = this[i];
				if(node.localName == localName && node.namespaceURI == namespaceURI){
					return node;
				}
			}
			return null;
		}
	};
	/**
	 * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
	 */
	function DOMImplementation(/* Object */ features) {
		this._features = {};
		if (features) {
			for (var feature in features) {
				 this._features = features[feature];
			}
		}
	};

	DOMImplementation.prototype = {
		hasFeature: function(/* string */ feature, /* string */ version) {
			var versions = this._features[feature.toLowerCase()];
			if (versions && (!version || version in versions)) {
				return true;
			} else {
				return false;
			}
		},
		// Introduced in DOM Level 2:
		createDocument:function(namespaceURI,  qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
			var doc = new Document();
			doc.implementation = this;
			doc.childNodes = new NodeList();
			doc.doctype = doctype;
			if(doctype){
				doc.appendChild(doctype);
			}
			if(qualifiedName){
				var root = doc.createElementNS(namespaceURI,qualifiedName);
				doc.appendChild(root);
			}
			return doc;
		},
		// Introduced in DOM Level 2:
		createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
			var node = new DocumentType();
			node.name = qualifiedName;
			node.nodeName = qualifiedName;
			node.publicId = publicId;
			node.systemId = systemId;
			// Introduced in DOM Level 2:
			//readonly attribute DOMString        internalSubset;
			
			//TODO:..
			//  readonly attribute NamedNodeMap     entities;
			//  readonly attribute NamedNodeMap     notations;
			return node;
		}
	};


	/**
	 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
	 */

	function Node() {
	};

	Node.prototype = {
		firstChild : null,
		lastChild : null,
		previousSibling : null,
		nextSibling : null,
		attributes : null,
		parentNode : null,
		childNodes : null,
		ownerDocument : null,
		nodeValue : null,
		namespaceURI : null,
		prefix : null,
		localName : null,
		// Modified in DOM Level 2:
		insertBefore:function(newChild, refChild){//raises 
			return _insertBefore(this,newChild,refChild);
		},
		replaceChild:function(newChild, oldChild){//raises 
			this.insertBefore(newChild,oldChild);
			if(oldChild){
				this.removeChild(oldChild);
			}
		},
		removeChild:function(oldChild){
			return _removeChild(this,oldChild);
		},
		appendChild:function(newChild){
			return this.insertBefore(newChild,null);
		},
		hasChildNodes:function(){
			return this.firstChild != null;
		},
		cloneNode:function(deep){
			return cloneNode(this.ownerDocument||this,this,deep);
		},
		// Modified in DOM Level 2:
		normalize:function(){
			var child = this.firstChild;
			while(child){
				var next = child.nextSibling;
				if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
					this.removeChild(next);
					child.appendData(next.data);
				}else{
					child.normalize();
					child = next;
				}
			}
		},
	  	// Introduced in DOM Level 2:
		isSupported:function(feature, version){
			return this.ownerDocument.implementation.hasFeature(feature,version);
		},
	    // Introduced in DOM Level 2:
	    hasAttributes:function(){
	    	return this.attributes.length>0;
	    },
	    lookupPrefix:function(namespaceURI){
	    	var el = this;
	    	while(el){
	    		var map = el._nsMap;
	    		//console.dir(map)
	    		if(map){
	    			for(var n in map){
	    				if(map[n] == namespaceURI){
	    					return n;
	    				}
	    			}
	    		}
	    		el = el.nodeType == 2?el.ownerDocument : el.parentNode;
	    	}
	    	return null;
	    },
	    // Introduced in DOM Level 3:
	    lookupNamespaceURI:function(prefix){
	    	var el = this;
	    	while(el){
	    		var map = el._nsMap;
	    		//console.dir(map)
	    		if(map){
	    			if(prefix in map){
	    				return map[prefix] ;
	    			}
	    		}
	    		el = el.nodeType == 2?el.ownerDocument : el.parentNode;
	    	}
	    	return null;
	    },
	    // Introduced in DOM Level 3:
	    isDefaultNamespace:function(namespaceURI){
	    	var prefix = this.lookupPrefix(namespaceURI);
	    	return prefix == null;
	    }
	};


	function _xmlEncoder(c){
		return c == '<' && '&lt;' ||
	         c == '>' && '&gt;' ||
	         c == '&' && '&amp;' ||
	         c == '"' && '&quot;' ||
	         '&#'+c.charCodeAt()+';'
	}


	copy(NodeType,Node);
	copy(NodeType,Node.prototype);

	/**
	 * @param callback return true for continue,false for break
	 * @return boolean true: break visit;
	 */
	function _visitNode(node,callback){
		if(callback(node)){
			return true;
		}
		if(node = node.firstChild){
			do{
				if(_visitNode(node,callback)){return true}
	        }while(node=node.nextSibling)
	    }
	}



	function Document(){
	}
	function _onAddAttribute(doc,el,newAttr){
		doc && doc._inc++;
		var ns = newAttr.namespaceURI ;
		if(ns == 'http://www.w3.org/2000/xmlns/'){
			//update namespace
			el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value
		}
	}
	function _onRemoveAttribute(doc,el,newAttr,remove){
		doc && doc._inc++;
		var ns = newAttr.namespaceURI ;
		if(ns == 'http://www.w3.org/2000/xmlns/'){
			//update namespace
			delete el._nsMap[newAttr.prefix?newAttr.localName:'']
		}
	}
	function _onUpdateChild(doc,el,newChild){
		if(doc && doc._inc){
			doc._inc++;
			//update childNodes
			var cs = el.childNodes;
			if(newChild){
				cs[cs.length++] = newChild;
			}else{
				//console.log(1)
				var child = el.firstChild;
				var i = 0;
				while(child){
					cs[i++] = child;
					child =child.nextSibling;
				}
				cs.length = i;
			}
		}
	}

	/**
	 * attributes;
	 * children;
	 * 
	 * writeable properties:
	 * nodeValue,Attr:value,CharacterData:data
	 * prefix
	 */
	function _removeChild(parentNode,child){
		var previous = child.previousSibling;
		var next = child.nextSibling;
		if(previous){
			previous.nextSibling = next;
		}else{
			parentNode.firstChild = next
		}
		if(next){
			next.previousSibling = previous;
		}else{
			parentNode.lastChild = previous;
		}
		_onUpdateChild(parentNode.ownerDocument,parentNode);
		return child;
	}
	/**
	 * preformance key(refChild == null)
	 */
	function _insertBefore(parentNode,newChild,nextChild){
		var cp = newChild.parentNode;
		if(cp){
			cp.removeChild(newChild);//remove and update
		}
		if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
			var newFirst = newChild.firstChild;
			if (newFirst == null) {
				return newChild;
			}
			var newLast = newChild.lastChild;
		}else{
			newFirst = newLast = newChild;
		}
		var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;

		newFirst.previousSibling = pre;
		newLast.nextSibling = nextChild;
		
		
		if(pre){
			pre.nextSibling = newFirst;
		}else{
			parentNode.firstChild = newFirst;
		}
		if(nextChild == null){
			parentNode.lastChild = newLast;
		}else{
			nextChild.previousSibling = newLast;
		}
		do{
			newFirst.parentNode = parentNode;
		}while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
		_onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
		//console.log(parentNode.lastChild.nextSibling == null)
		if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
			newChild.firstChild = newChild.lastChild = null;
		}
		return newChild;
	}
	function _appendSingleChild(parentNode,newChild){
		var cp = newChild.parentNode;
		if(cp){
			var pre = parentNode.lastChild;
			cp.removeChild(newChild);//remove and update
			var pre = parentNode.lastChild;
		}
		var pre = parentNode.lastChild;
		newChild.parentNode = parentNode;
		newChild.previousSibling = pre;
		newChild.nextSibling = null;
		if(pre){
			pre.nextSibling = newChild;
		}else{
			parentNode.firstChild = newChild;
		}
		parentNode.lastChild = newChild;
		_onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
		return newChild;
		//console.log("__aa",parentNode.lastChild.nextSibling == null)
	}
	Document.prototype = {
		//implementation : null,
		nodeName :  '#document',
		nodeType :  DOCUMENT_NODE,
		doctype :  null,
		documentElement :  null,
		_inc : 1,
		
		insertBefore :  function(newChild, refChild){//raises 
			if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
				var child = newChild.firstChild;
				while(child){
					var next = child.nextSibling;
					this.insertBefore(child,refChild);
					child = next;
				}
				return newChild;
			}
			if(this.documentElement == null && newChild.nodeType == 1){
				this.documentElement = newChild;
			}
			
			return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
		},
		removeChild :  function(oldChild){
			if(this.documentElement == oldChild){
				this.documentElement = null;
			}
			return _removeChild(this,oldChild);
		},
		// Introduced in DOM Level 2:
		importNode : function(importedNode,deep){
			return importNode(this,importedNode,deep);
		},
		// Introduced in DOM Level 2:
		getElementById :	function(id){
			var rtv = null;
			_visitNode(this.documentElement,function(node){
				if(node.nodeType == 1){
					if(node.getAttribute('id') == id){
						rtv = node;
						return true;
					}
				}
			})
			return rtv;
		},
		
		//document factory method:
		createElement :	function(tagName){
			var node = new Element();
			node.ownerDocument = this;
			node.nodeName = tagName;
			node.tagName = tagName;
			node.childNodes = new NodeList();
			var attrs	= node.attributes = new NamedNodeMap();
			attrs._ownerElement = node;
			return node;
		},
		createDocumentFragment :	function(){
			var node = new DocumentFragment();
			node.ownerDocument = this;
			node.childNodes = new NodeList();
			return node;
		},
		createTextNode :	function(data){
			var node = new Text();
			node.ownerDocument = this;
			node.appendData(data)
			return node;
		},
		createComment :	function(data){
			var node = new Comment();
			node.ownerDocument = this;
			node.appendData(data)
			return node;
		},
		createCDATASection :	function(data){
			var node = new CDATASection();
			node.ownerDocument = this;
			node.appendData(data)
			return node;
		},
		createProcessingInstruction :	function(target,data){
			var node = new ProcessingInstruction();
			node.ownerDocument = this;
			node.tagName = node.target = target;
			node.nodeValue= node.data = data;
			return node;
		},
		createAttribute :	function(name){
			var node = new Attr();
			node.ownerDocument	= this;
			node.name = name;
			node.nodeName	= name;
			node.localName = name;
			node.specified = true;
			return node;
		},
		createEntityReference :	function(name){
			var node = new EntityReference();
			node.ownerDocument	= this;
			node.nodeName	= name;
			return node;
		},
		// Introduced in DOM Level 2:
		createElementNS :	function(namespaceURI,qualifiedName){
			var node = new Element();
			var pl = qualifiedName.split(':');
			var attrs	= node.attributes = new NamedNodeMap();
			node.childNodes = new NodeList();
			node.ownerDocument = this;
			node.nodeName = qualifiedName;
			node.tagName = qualifiedName;
			node.namespaceURI = namespaceURI;
			if(pl.length == 2){
				node.prefix = pl[0];
				node.localName = pl[1];
			}else{
				//el.prefix = null;
				node.localName = qualifiedName;
			}
			attrs._ownerElement = node;
			return node;
		},
		// Introduced in DOM Level 2:
		createAttributeNS :	function(namespaceURI,qualifiedName){
			var node = new Attr();
			var pl = qualifiedName.split(':');
			node.ownerDocument = this;
			node.nodeName = qualifiedName;
			node.name = qualifiedName;
			node.namespaceURI = namespaceURI;
			node.specified = true;
			if(pl.length == 2){
				node.prefix = pl[0];
				node.localName = pl[1];
			}else{
				//el.prefix = null;
				node.localName = qualifiedName;
			}
			return node;
		}
	};
	_extends(Document,Node);


	function Element() {
		this._nsMap = {};
	};
	Element.prototype = {
		nodeType : ELEMENT_NODE,
		hasAttribute : function(name){
			return this.getAttributeNode(name)!=null;
		},
		getAttribute : function(name){
			var attr = this.getAttributeNode(name);
			return attr && attr.value || '';
		},
		getAttributeNode : function(name){
			return this.attributes.getNamedItem(name);
		},
		setAttribute : function(name, value){
			var attr = this.ownerDocument.createAttribute(name);
			attr.value = attr.nodeValue = "" + value;
			this.setAttributeNode(attr)
		},
		removeAttribute : function(name){
			var attr = this.getAttributeNode(name)
			attr && this.removeAttributeNode(attr);
		},
		
		//four real opeartion method
		appendChild:function(newChild){
			if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
				return this.insertBefore(newChild,null);
			}else{
				return _appendSingleChild(this,newChild);
			}
		},
		setAttributeNode : function(newAttr){
			return this.attributes.setNamedItem(newAttr);
		},
		setAttributeNodeNS : function(newAttr){
			return this.attributes.setNamedItemNS(newAttr);
		},
		removeAttributeNode : function(oldAttr){
			return this.attributes.removeNamedItem(oldAttr.nodeName);
		},
		//get real attribute name,and remove it by removeAttributeNode
		removeAttributeNS : function(namespaceURI, localName){
			var old = this.getAttributeNodeNS(namespaceURI, localName);
			old && this.removeAttributeNode(old);
		},
		
		hasAttributeNS : function(namespaceURI, localName){
			return this.getAttributeNodeNS(namespaceURI, localName)!=null;
		},
		getAttributeNS : function(namespaceURI, localName){
			var attr = this.getAttributeNodeNS(namespaceURI, localName);
			return attr && attr.value || '';
		},
		setAttributeNS : function(namespaceURI, qualifiedName, value){
			var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
			attr.value = attr.nodeValue = "" + value;
			this.setAttributeNode(attr)
		},
		getAttributeNodeNS : function(namespaceURI, localName){
			return this.attributes.getNamedItemNS(namespaceURI, localName);
		},
		
		getElementsByTagName : function(tagName){
			return new LiveNodeList(this,function(base){
				var ls = [];
				_visitNode(base,function(node){
					if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
						ls.push(node);
					}
				});
				return ls;
			});
		},
		getElementsByTagNameNS : function(namespaceURI, localName){
			return new LiveNodeList(this,function(base){
				var ls = [];
				_visitNode(base,function(node){
					if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
						ls.push(node);
					}
				});
				return ls;
			});
		}
	};
	Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
	Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;


	_extends(Element,Node);
	function Attr() {
	};
	Attr.prototype.nodeType = ATTRIBUTE_NODE;
	_extends(Attr,Node);


	function CharacterData() {
	};
	CharacterData.prototype = {
		data : '',
		substringData : function(offset, count) {
			return this.data.substring(offset, offset+count);
		},
		appendData: function(text) {
			text = this.data+text;
			this.nodeValue = this.data = text;
			this.length = text.length;
		},
		insertData: function(offset,text) {
			this.replaceData(offset,0,text);
		
		},
		appendChild:function(newChild){
			//if(!(newChild instanceof CharacterData)){
				throw new Error(ExceptionMessage[3])
			//}
			return Node.prototype.appendChild.apply(this,arguments)
		},
		deleteData: function(offset, count) {
			this.replaceData(offset,count,"");
		},
		replaceData: function(offset, count, text) {
			var start = this.data.substring(0,offset);
			var end = this.data.substring(offset+count);
			text = start + text + end;
			this.nodeValue = this.data = text;
			this.length = text.length;
		}
	}
	_extends(CharacterData,Node);
	function Text() {
	};
	Text.prototype = {
		nodeName : "#text",
		nodeType : TEXT_NODE,
		splitText : function(offset) {
			var text = this.data;
			var newText = text.substring(offset);
			text = text.substring(0, offset);
			this.data = this.nodeValue = text;
			this.length = text.length;
			var newNode = this.ownerDocument.createTextNode(newText);
			if(this.parentNode){
				this.parentNode.insertBefore(newNode, this.nextSibling);
			}
			return newNode;
		}
	}
	_extends(Text,CharacterData);
	function Comment() {
	};
	Comment.prototype = {
		nodeName : "#comment",
		nodeType : COMMENT_NODE
	}
	_extends(Comment,CharacterData);

	function CDATASection() {
	};
	CDATASection.prototype = {
		nodeName : "#cdata-section",
		nodeType : CDATA_SECTION_NODE
	}
	_extends(CDATASection,CharacterData);


	function DocumentType() {
	};
	DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
	_extends(DocumentType,Node);

	function Notation() {
	};
	Notation.prototype.nodeType = NOTATION_NODE;
	_extends(Notation,Node);

	function Entity() {
	};
	Entity.prototype.nodeType = ENTITY_NODE;
	_extends(Entity,Node);

	function EntityReference() {
	};
	EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
	_extends(EntityReference,Node);

	function DocumentFragment() {
	};
	DocumentFragment.prototype.nodeName =	"#document-fragment";
	DocumentFragment.prototype.nodeType =	DOCUMENT_FRAGMENT_NODE;
	_extends(DocumentFragment,Node);


	function ProcessingInstruction() {
	}
	ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
	_extends(ProcessingInstruction,Node);
	function XMLSerializer(){}
	XMLSerializer.prototype.serializeToString = function(node,attributeSorter){
		return node.toString(attributeSorter);
	}
	Node.prototype.toString =function(attributeSorter){
		var buf = [];
		serializeToString(this,buf,attributeSorter);
		return buf.join('');
	}
	function serializeToString(node,buf,attributeSorter,isHTML){
		switch(node.nodeType){
		case ELEMENT_NODE:
			var attrs = node.attributes;
			var len = attrs.length;
			var child = node.firstChild;
			var nodeName = node.tagName;
			isHTML =  (htmlns === node.namespaceURI) ||isHTML 
			buf.push('<',nodeName);
			if(attributeSorter){
				buf.sort.apply(attrs, attributeSorter);
			}
			for(var i=0;i<len;i++){
				serializeToString(attrs.item(i),buf,attributeSorter,isHTML);
			}
			if(child || isHTML && !/^(?:meta|link|img|br|hr|input|button)$/i.test(nodeName)){
				buf.push('>');
				//if is cdata child node
				if(isHTML && /^script$/i.test(nodeName)){
					if(child){
						buf.push(child.data);
					}
				}else{
					while(child){
						serializeToString(child,buf,attributeSorter,isHTML);
						child = child.nextSibling;
					}
				}
				buf.push('</',nodeName,'>');
			}else{
				buf.push('/>');
			}
			return;
		case DOCUMENT_NODE:
		case DOCUMENT_FRAGMENT_NODE:
			var child = node.firstChild;
			while(child){
				serializeToString(child,buf,attributeSorter,isHTML);
				child = child.nextSibling;
			}
			return;
		case ATTRIBUTE_NODE:
			return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
		case TEXT_NODE:
			return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
		case CDATA_SECTION_NODE:
			return buf.push( '<![CDATA[',node.data,']]>');
		case COMMENT_NODE:
			return buf.push( "<!--",node.data,"-->");
		case DOCUMENT_TYPE_NODE:
			var pubid = node.publicId;
			var sysid = node.systemId;
			buf.push('<!DOCTYPE ',node.name);
			if(pubid){
				buf.push(' PUBLIC "',pubid);
				if (sysid && sysid!='.') {
					buf.push( '" "',sysid);
				}
				buf.push('">');
			}else if(sysid && sysid!='.'){
				buf.push(' SYSTEM "',sysid,'">');
			}else{
				var sub = node.internalSubset;
				if(sub){
					buf.push(" [",sub,"]");
				}
				buf.push(">");
			}
			return;
		case PROCESSING_INSTRUCTION_NODE:
			return buf.push( "<?",node.target," ",node.data,"?>");
		case ENTITY_REFERENCE_NODE:
			return buf.push( '&',node.nodeName,';');
		//case ENTITY_NODE:
		//case NOTATION_NODE:
		default:
			buf.push('??',node.nodeName);
		}
	}
	function importNode(doc,node,deep){
		var node2;
		switch (node.nodeType) {
		case ELEMENT_NODE:
			node2 = node.cloneNode(false);
			node2.ownerDocument = doc;
			//var attrs = node2.attributes;
			//var len = attrs.length;
			//for(var i=0;i<len;i++){
				//node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
			//}
		case DOCUMENT_FRAGMENT_NODE:
			break;
		case ATTRIBUTE_NODE:
			deep = true;
			break;
		//case ENTITY_REFERENCE_NODE:
		//case PROCESSING_INSTRUCTION_NODE:
		////case TEXT_NODE:
		//case CDATA_SECTION_NODE:
		//case COMMENT_NODE:
		//	deep = false;
		//	break;
		//case DOCUMENT_NODE:
		//case DOCUMENT_TYPE_NODE:
		//cannot be imported.
		//case ENTITY_NODE:
		//case NOTATION_NODE：
		//can not hit in level3
		//default:throw e;
		}
		if(!node2){
			node2 = node.cloneNode(false);//false
		}
		node2.ownerDocument = doc;
		node2.parentNode = null;
		if(deep){
			var child = node.firstChild;
			while(child){
				node2.appendChild(importNode(doc,child,deep));
				child = child.nextSibling;
			}
		}
		return node2;
	}
	//
	//var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
	//					attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
	function cloneNode(doc,node,deep){
		var node2 = new node.constructor();
		for(var n in node){
			var v = node[n];
			if(typeof v != 'object' ){
				if(v != node2[n]){
					node2[n] = v;
				}
			}
		}
		if(node.childNodes){
			node2.childNodes = new NodeList();
		}
		node2.ownerDocument = doc;
		switch (node2.nodeType) {
		case ELEMENT_NODE:
			var attrs	= node.attributes;
			var attrs2	= node2.attributes = new NamedNodeMap();
			var len = attrs.length
			attrs2._ownerElement = node2;
			for(var i=0;i<len;i++){
				node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
			}
			break;;
		case ATTRIBUTE_NODE:
			deep = true;
		}
		if(deep){
			var child = node.firstChild;
			while(child){
				node2.appendChild(cloneNode(doc,child,deep));
				child = child.nextSibling;
			}
		}
		return node2;
	}

	function __set__(object,key,value){
		object[key] = value
	}
	//do dynamic
	try{
		if(Object.defineProperty){
			Object.defineProperty(LiveNodeList.prototype,'length',{
				get:function(){
					_updateLiveList(this);
					return this.$$length;
				}
			});
			Object.defineProperty(Node.prototype,'textContent',{
				get:function(){
					return getTextContent(this);
				},
				set:function(data){
					switch(this.nodeType){
					case 1:
					case 11:
						while(this.firstChild){
							this.removeChild(this.firstChild);
						}
						if(data || String(data)){
							this.appendChild(this.ownerDocument.createTextNode(data));
						}
						break;
					default:
						//TODO:
						this.data = data;
						this.value = value;
						this.nodeValue = data;
					}
				}
			})
			
			function getTextContent(node){
				switch(node.nodeType){
				case 1:
				case 11:
					var buf = [];
					node = node.firstChild;
					while(node){
						if(node.nodeType!==7 && node.nodeType !==8){
							buf.push(getTextContent(node));
						}
						node = node.nextSibling;
					}
					return buf.join('');
				default:
					return node.nodeValue;
				}
			}
			__set__ = function(object,key,value){
				//console.log(value)
				object['$$'+key] = value
			}
		}
	}catch(e){//ie8
	}

	if(true){
		exports.DOMImplementation = DOMImplementation;
		exports.XMLSerializer = XMLSerializer;
	}


/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// **Github:** https://github.com/zensh/lrucache
	//
	// **License:** MIT

	/* global module, define */
	;(function (root, factory) {
	  'use strict'

	  if (typeof module === 'object' && typeof module.exports === 'object') {
	    module.exports = factory()
	  } else if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))
	  } else {
	    root.LRUCache = factory()
	  }
	}(typeof window === 'object' ? window : this, function () {
	  'use strict'

	  var undef = void 0

	  function LRUCache (capacity) {
	    if (!(this instanceof LRUCache)) return new LRUCache(capacity)
	    this._LRUCacheState = new CacheState(capacity)
	  }

	  var proto = LRUCache.prototype

	  proto.get = function (key) {
	    var state = this._LRUCacheState
	    var lruEntry = state.hash[key]
	    if (!lruEntry) return
	    refresh(state.linkedList, lruEntry)
	    return state.data[key]
	  }

	  proto.set = function (key, value) {
	    var state = this._LRUCacheState
	    var lruEntry = state.hash[key]
	    if (value === undef) return this
	    if (!lruEntry) {
	      state.hash[key] = new LRUEntry(key)
	      state.linkedList.length += 1
	      lruEntry = state.hash[key]
	    }
	    refresh(state.linkedList, lruEntry)
	    state.data[key] = value
	    if (state.linkedList.length > state.capacity) this.remove(state.linkedList.end.key)
	    return this
	  }

	  proto.update = function (key, parseFn) {
	    if (this.has(key)) this.set(key, parseFn(this.get(key)))
	    return this
	  }

	  proto.remove = function (key) {
	    var state = this._LRUCacheState
	    var lruEntry = state.hash[key]
	    if (!lruEntry) return this
	    if (lruEntry === state.linkedList.head) state.linkedList.head = lruEntry.p
	    if (lruEntry === state.linkedList.end) state.linkedList.end = lruEntry.n
	    link(lruEntry.n, lruEntry.p)
	    delete state.hash[key]
	    delete state.data[key]
	    state.linkedList.length -= 1
	    return this
	  }

	  proto.removeAll = function () {
	    this._LRUCacheState = new CacheState(this._LRUCacheState.capacity)
	    return this
	  }

	  proto.info = function () {
	    var state = this._LRUCacheState
	    return {
	      capacity: state.capacity,
	      length: state.linkedList.length
	    }
	  }

	  proto.keys = function () {
	    var keys = []
	    var lruEntry = this._LRUCacheState.linkedList.head
	    while (lruEntry) {
	      keys.push(lruEntry.key)
	      lruEntry = lruEntry.p
	    }
	    return keys
	  }

	  proto.has = function (key) {
	    return !!this._LRUCacheState.hash[key]
	  }

	  proto.staleKey = function () {
	    return this._LRUCacheState.linkedList.end && this._LRUCacheState.linkedList.end.key
	  }

	  proto.popStale = function () {
	    var staleKey = this.staleKey()
	    if (!staleKey) return null
	    var stale = [staleKey, this._LRUCacheState.data[staleKey]]
	    this.remove(staleKey)
	    return stale
	  }

	  function CacheState (capacity) {
	    this.capacity = capacity > 0 ? +capacity : Number.MAX_VALUE
	    this.data = Object.create ? Object.create(null) : {}
	    this.hash = Object.create ? Object.create(null) : {}
	    this.linkedList = new LinkedList()
	  }

	  function LinkedList () {
	    this.length = 0
	    this.head = null
	    this.end = null
	  }

	  function LRUEntry (key) {
	    this.key = key
	    this.p = null
	    this.n = null
	  }

	  // 更新链表，把get或put方法操作的key提到链表head，即表示最新
	  function refresh (linkedList, entry) {
	    if (entry === linkedList.head) return
	    if (!linkedList.end) {
	      linkedList.end = entry
	    } else if (linkedList.end === entry) {
	      linkedList.end = entry.n
	    }

	    link(entry.n, entry.p)
	    link(entry, linkedList.head)
	    linkedList.head = entry
	    linkedList.head.n = null
	  }

	  // 对两个链表对象建立链接，形成一条链
	  function link (nextEntry, prevEntry) {
	    if (nextEntry === prevEntry) return
	    if (nextEntry) nextEntry.p = prevEntry
	    if (prevEntry) prevEntry.n = nextEntry
	  }

	  LRUCache.NAME = 'LRUCache'
	  LRUCache.VERSION = 'v0.3.0'
	  return LRUCache
	}))


/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {"use strict";

	__webpack_require__(15);
	var get               = __webpack_require__(16);
	var Report            = __webpack_require__(20);
	var FormatValidators  = __webpack_require__(23);
	var JsonValidation    = __webpack_require__(25);
	var SchemaCache       = __webpack_require__(26);
	var SchemaCompilation = __webpack_require__(27);
	var SchemaValidation  = __webpack_require__(28);
	var Utils             = __webpack_require__(22);
	var Draft4Schema      = __webpack_require__(29);
	var Draft4HyperSchema = __webpack_require__(30);

	/*
	    default options
	*/
	var defaultOptions = {
	    // default timeout for all async tasks
	    asyncTimeout: 2000,
	    // force additionalProperties and additionalItems to be defined on "object" and "array" types
	    forceAdditional: false,
	    // assume additionalProperties and additionalItems are defined as "false" where appropriate
	    assumeAdditional: false,
	    // force items to be defined on "array" types
	    forceItems: false,
	    // force minItems to be defined on "array" types
	    forceMinItems: false,
	    // force maxItems to be defined on "array" types
	    forceMaxItems: false,
	    // force minLength to be defined on "string" types
	    forceMinLength: false,
	    // force maxLength to be defined on "string" types
	    forceMaxLength: false,
	    // force properties or patternProperties to be defined on "object" types
	    forceProperties: false,
	    // ignore references that cannot be resolved (remote schemas) // TODO: make sure this is only for remote schemas, not local ones
	    ignoreUnresolvableReferences: false,
	    // disallow usage of keywords that this validator can't handle
	    noExtraKeywords: false,
	    // disallow usage of schema's without "type" defined
	    noTypeless: false,
	    // disallow zero length strings in validated objects
	    noEmptyStrings: false,
	    // disallow zero length arrays in validated objects
	    noEmptyArrays: false,
	    // forces "uri" format to be in fully rfc3986 compliant
	    strictUris: false,
	    // turn on some of the above
	    strictMode: false,
	    // report error paths as an array of path segments to get to the offending node
	    reportPathAsArray: false,
	    // stops validation as soon as an error is found, true by default but can be turned off
	    breakOnFirstError: true,
	    // check if schema follow best practices and common sence
	    pedanticCheck: false,
	    // ignore unknown formats (do not report them as an error)
	    ignoreUnknownFormats: false
	};

	/*
	    constructor
	*/
	function ZSchema(options) {
	    this.cache = {};
	    this.referenceCache = [];

	    this.setRemoteReference("http://json-schema.org/draft-04/schema", Draft4Schema);
	    this.setRemoteReference("http://json-schema.org/draft-04/hyper-schema", Draft4HyperSchema);

	    // options
	    if (typeof options === "object") {
	        var keys = Object.keys(options),
	            idx = keys.length,
	            key;

	        // check that the options are correctly configured
	        while (idx--) {
	            key = keys[idx];
	            if (defaultOptions[key] === undefined) {
	                throw new Error("Unexpected option passed to constructor: " + key);
	            }
	        }

	        // copy the default options into passed options
	        keys = Object.keys(defaultOptions);
	        idx = keys.length;
	        while (idx--) {
	            key = keys[idx];
	            if (options[key] === undefined) {
	                options[key] = Utils.clone(defaultOptions[key]);
	            }
	        }

	        this.options = options;
	    } else {
	        this.options = Utils.clone(defaultOptions);
	    }

	    if (this.options.strictMode === true) {
	        this.options.forceAdditional  = true;
	        this.options.forceItems       = true;
	        this.options.forceMaxLength   = true;
	        this.options.forceProperties  = true;
	        this.options.noExtraKeywords  = true;
	        this.options.noTypeless       = true;
	        this.options.noEmptyStrings   = true;
	        this.options.noEmptyArrays    = true;
	    }

	}

	/*
	    instance methods
	*/
	ZSchema.prototype.compileSchema = function (schema) {
	    var report = new Report(this.options);

	    schema = SchemaCache.getSchema.call(this, report, schema);

	    SchemaCompilation.compileSchema.call(this, report, schema);

	    this.lastReport = report;
	    return report.isValid();
	};
	ZSchema.prototype.validateSchema = function (schema) {
	    if (Array.isArray(schema) && schema.length === 0) {
	        throw new Error(".validateSchema was called with an empty array");
	    }

	    var report = new Report(this.options);

	    schema = SchemaCache.getSchema.call(this, report, schema);

	    var compiled = SchemaCompilation.compileSchema.call(this, report, schema);
	    if (compiled) { SchemaValidation.validateSchema.call(this, report, schema); }

	    this.lastReport = report;
	    return report.isValid();
	};
	ZSchema.prototype.validate = function (json, schema, options, callback) {

	    if (Utils.whatIs(options) === "function") {
	        callback = options;
	        options = {};
	    }
	    if (!options) { options = {}; }

	    var whatIs = Utils.whatIs(schema);
	    if (whatIs !== "string" && whatIs !== "object") {
	        var e = new Error("Invalid .validate call - schema must be an string or object but " + whatIs + " was passed!");
	        if (callback) {
	            process.nextTick(function () {
	                callback(e, false);
	            });
	            return;
	        }
	        throw e;
	    }

	    var foundError = false;
	    var report = new Report(this.options);

	    if (typeof schema === "string") {
	        var schemaName = schema;
	        schema = SchemaCache.getSchema.call(this, report, schemaName);
	        if (!schema) {
	            throw new Error("Schema with id '" + schemaName + "' wasn't found in the validator cache!");
	        }
	    } else {
	        schema = SchemaCache.getSchema.call(this, report, schema);
	    }

	    var compiled = false;
	    if (!foundError) {
	        compiled = SchemaCompilation.compileSchema.call(this, report, schema);
	    }
	    if (!compiled) {
	        this.lastReport = report;
	        foundError = true;
	    }

	    var validated = false;
	    if (!foundError) {
	        validated = SchemaValidation.validateSchema.call(this, report, schema);
	    }
	    if (!validated) {
	        this.lastReport = report;
	        foundError = true;
	    }

	    if (options.schemaPath) {
	        report.rootSchema = schema;
	        schema = get(schema, options.schemaPath);
	        if (!schema) {
	            throw new Error("Schema path '" + options.schemaPath + "' wasn't found in the schema!");
	        }
	    }

	    if (!foundError) {
	        JsonValidation.validate.call(this, report, schema, json);
	    }

	    if (callback) {
	        report.processAsyncTasks(this.options.asyncTimeout, callback);
	        return;
	    } else if (report.asyncTasks.length > 0) {
	        throw new Error("This validation has async tasks and cannot be done in sync mode, please provide callback argument.");
	    }

	    // assign lastReport so errors are retrievable in sync mode
	    this.lastReport = report;
	    return report.isValid();
	};
	ZSchema.prototype.getLastError = function () {
	    if (this.lastReport.errors.length === 0) {
	        return null;
	    }
	    var e = new Error();
	    e.name = "z-schema validation error";
	    e.message = this.lastReport.commonErrorMessage;
	    e.details = this.lastReport.errors;
	    return e;
	};
	ZSchema.prototype.getLastErrors = function () {
	    return this.lastReport && this.lastReport.errors.length > 0 ? this.lastReport.errors : undefined;
	};
	ZSchema.prototype.getMissingReferences = function (arr) {
	    arr = arr || this.lastReport.errors;
	    var res = [],
	        idx = arr.length;
	    while (idx--) {
	        var error = arr[idx];
	        if (error.code === "UNRESOLVABLE_REFERENCE") {
	            var reference = error.params[0];
	            if (res.indexOf(reference) === -1) {
	                res.push(reference);
	            }
	        }
	        if (error.inner) {
	            res = res.concat(this.getMissingReferences(error.inner));
	        }
	    }
	    return res;
	};
	ZSchema.prototype.getMissingRemoteReferences = function () {
	    var missingReferences = this.getMissingReferences(),
	        missingRemoteReferences = [],
	        idx = missingReferences.length;
	    while (idx--) {
	        var remoteReference = SchemaCache.getRemotePath(missingReferences[idx]);
	        if (remoteReference && missingRemoteReferences.indexOf(remoteReference) === -1) {
	            missingRemoteReferences.push(remoteReference);
	        }
	    }
	    return missingRemoteReferences;
	};
	ZSchema.prototype.setRemoteReference = function (uri, schema) {
	    if (typeof schema === "string") {
	        schema = JSON.parse(schema);
	    } else {
	        schema = Utils.cloneDeep(schema);
	    }
	    SchemaCache.cacheSchemaByUri.call(this, uri, schema);
	};
	ZSchema.prototype.getResolvedSchema = function (schema) {
	    var report = new Report(this.options);
	    schema = SchemaCache.getSchema.call(this, report, schema);

	    // clone before making any modifications
	    schema = Utils.cloneDeep(schema);

	    var visited = [];

	    // clean-up the schema and resolve references
	    var cleanup = function (schema) {
	        var key,
	            typeOf = Utils.whatIs(schema);
	        if (typeOf !== "object" && typeOf !== "array") {
	            return;
	        }

	        if (schema.___$visited) {
	            return;
	        }

	        schema.___$visited = true;
	        visited.push(schema);

	        if (schema.$ref && schema.__$refResolved) {
	            var from = schema.__$refResolved;
	            var to = schema;
	            delete schema.$ref;
	            delete schema.__$refResolved;
	            for (key in from) {
	                if (from.hasOwnProperty(key)) {
	                    to[key] = from[key];
	                }
	            }
	        }
	        for (key in schema) {
	            if (schema.hasOwnProperty(key)) {
	                if (key.indexOf("__$") === 0) {
	                    delete schema[key];
	                } else {
	                    cleanup(schema[key]);
	                }
	            }
	        }
	    };

	    cleanup(schema);
	    visited.forEach(function (s) {
	        delete s.___$visited;
	    });

	    this.lastReport = report;
	    if (report.isValid()) {
	        return schema;
	    } else {
	        throw this.getLastError();
	    }
	};
	ZSchema.prototype.setSchemaReader = function (schemaReader) {
	    return ZSchema.setSchemaReader(schemaReader);
	};
	ZSchema.prototype.getSchemaReader = function () {
	    return ZSchema.schemaReader;
	};

	/*
	    static methods
	*/
	ZSchema.setSchemaReader = function (schemaReader) {
	    ZSchema.schemaReader = schemaReader;
	};
	ZSchema.registerFormat = function (formatName, validatorFunction) {
	    FormatValidators[formatName] = validatorFunction;
	};
	ZSchema.unregisterFormat = function (formatName) {
	    delete FormatValidators[formatName];
	};
	ZSchema.getRegisteredFormats = function () {
	    return Object.keys(FormatValidators);
	};
	ZSchema.getDefaultOptions = function () {
	    return Utils.cloneDeep(defaultOptions);
	};

	module.exports = ZSchema;

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 15 */
/***/ function(module, exports) {

	// Number.isFinite polyfill
	// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite
	if (typeof Number.isFinite !== "function") {
	    Number.isFinite = function isFinite(value) {
	        // 1. If Type(number) is not Number, return false.
	        if (typeof value !== "number") {
	            return false;
	        }
	        // 2. If number is NaN, +∞, or −∞, return false.
	        if (value !== value || value === Infinity || value === -Infinity) {
	            return false;
	        }
	        // 3. Otherwise, return true.
	        return true;
	    };
	}


/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * lodash 3.7.0 (Custom Build) <https://lodash.com/>
	 * Build: `lodash modern modularize exports="npm" -o ./`
	 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 * Available under MIT license <https://lodash.com/license>
	 */
	var baseGet = __webpack_require__(17),
	    toPath = __webpack_require__(18);

	/**
	 * Gets the property value of `path` on `object`. If the resolved value is
	 * `undefined` the `defaultValue` is used in its place.
	 *
	 * @static
	 * @memberOf _
	 * @category Object
	 * @param {Object} object The object to query.
	 * @param {Array|string} path The path of the property to get.
	 * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
	 * @returns {*} Returns the resolved value.
	 * @example
	 *
	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
	 *
	 * _.get(object, 'a[0].b.c');
	 * // => 3
	 *
	 * _.get(object, ['a', '0', 'b', 'c']);
	 * // => 3
	 *
	 * _.get(object, 'a.b.c', 'default');
	 * // => 'default'
	 */
	function get(object, path, defaultValue) {
	  var result = object == null ? undefined : baseGet(object, toPath(path), path + '');
	  return result === undefined ? defaultValue : result;
	}

	module.exports = get;


/***/ },
/* 17 */
/***/ function(module, exports) {

	/**
	 * lodash 3.7.2 (Custom Build) <https://lodash.com/>
	 * Build: `lodash modern modularize exports="npm" -o ./`
	 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 * Available under MIT license <https://lodash.com/license>
	 */

	/**
	 * The base implementation of `get` without support for string paths
	 * and default values.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {Array} path The path of the property to get.
	 * @param {string} [pathKey] The key representation of path.
	 * @returns {*} Returns the resolved value.
	 */
	function baseGet(object, path, pathKey) {
	  if (object == null) {
	    return;
	  }
	  if (pathKey !== undefined && pathKey in toObject(object)) {
	    path = [pathKey];
	  }
	  var index = 0,
	      length = path.length;

	  while (object != null && index < length) {
	    object = object[path[index++]];
	  }
	  return (index && index == length) ? object : undefined;
	}

	/**
	 * Converts `value` to an object if it's not one.
	 *
	 * @private
	 * @param {*} value The value to process.
	 * @returns {Object} Returns the object.
	 */
	function toObject(value) {
	  return isObject(value) ? value : Object(value);
	}

	/**
	 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
	 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	 *
	 * @static
	 * @memberOf _
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	 * @example
	 *
	 * _.isObject({});
	 * // => true
	 *
	 * _.isObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isObject(1);
	 * // => false
	 */
	function isObject(value) {
	  // Avoid a V8 JIT bug in Chrome 19-20.
	  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
	  var type = typeof value;
	  return !!value && (type == 'object' || type == 'function');
	}

	module.exports = baseGet;


/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * lodash 3.8.1 (Custom Build) <https://lodash.com/>
	 * Build: `lodash modern modularize exports="npm" -o ./`
	 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 * Available under MIT license <https://lodash.com/license>
	 */
	var isArray = __webpack_require__(19);

	/** Used to match property names within property paths. */
	var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;

	/** Used to match backslashes in property paths. */
	var reEscapeChar = /\\(\\)?/g;

	/**
	 * Converts `value` to a string if it's not one. An empty string is returned
	 * for `null` or `undefined` values.
	 *
	 * @private
	 * @param {*} value The value to process.
	 * @returns {string} Returns the string.
	 */
	function baseToString(value) {
	  return value == null ? '' : (value + '');
	}

	/**
	 * Converts `value` to property path array if it's not one.
	 *
	 * @private
	 * @param {*} value The value to process.
	 * @returns {Array} Returns the property path array.
	 */
	function toPath(value) {
	  if (isArray(value)) {
	    return value;
	  }
	  var result = [];
	  baseToString(value).replace(rePropName, function(match, number, quote, string) {
	    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
	  });
	  return result;
	}

	module.exports = toPath;


/***/ },
/* 19 */
/***/ function(module, exports) {

	/**
	 * lodash 3.0.4 (Custom Build) <https://lodash.com/>
	 * Build: `lodash modern modularize exports="npm" -o ./`
	 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 * Available under MIT license <https://lodash.com/license>
	 */

	/** `Object#toString` result references. */
	var arrayTag = '[object Array]',
	    funcTag = '[object Function]';

	/** Used to detect host constructors (Safari > 5). */
	var reIsHostCtor = /^\[object .+?Constructor\]$/;

	/**
	 * Checks if `value` is object-like.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
	 */
	function isObjectLike(value) {
	  return !!value && typeof value == 'object';
	}

	/** Used for native method references. */
	var objectProto = Object.prototype;

	/** Used to resolve the decompiled source of functions. */
	var fnToString = Function.prototype.toString;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
	 * of values.
	 */
	var objToString = objectProto.toString;

	/** Used to detect if a method is native. */
	var reIsNative = RegExp('^' +
	  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
	  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
	);

	/* Native method references for those with the same name as other `lodash` methods. */
	var nativeIsArray = getNative(Array, 'isArray');

	/**
	 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
	 * of an array-like value.
	 */
	var MAX_SAFE_INTEGER = 9007199254740991;

	/**
	 * Gets the native function at `key` of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {string} key The key of the method to get.
	 * @returns {*} Returns the function if it's native, else `undefined`.
	 */
	function getNative(object, key) {
	  var value = object == null ? undefined : object[key];
	  return isNative(value) ? value : undefined;
	}

	/**
	 * Checks if `value` is a valid array-like length.
	 *
	 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
	 */
	function isLength(value) {
	  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
	}

	/**
	 * Checks if `value` is classified as an `Array` object.
	 *
	 * @static
	 * @memberOf _
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
	 * @example
	 *
	 * _.isArray([1, 2, 3]);
	 * // => true
	 *
	 * _.isArray(function() { return arguments; }());
	 * // => false
	 */
	var isArray = nativeIsArray || function(value) {
	  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
	};

	/**
	 * Checks if `value` is classified as a `Function` object.
	 *
	 * @static
	 * @memberOf _
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
	 * @example
	 *
	 * _.isFunction(_);
	 * // => true
	 *
	 * _.isFunction(/abc/);
	 * // => false
	 */
	function isFunction(value) {
	  // The use of `Object#toString` avoids issues with the `typeof` operator
	  // in older versions of Chrome and Safari which return 'function' for regexes
	  // and Safari 8 equivalents which return 'object' for typed array constructors.
	  return isObject(value) && objToString.call(value) == funcTag;
	}

	/**
	 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
	 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	 *
	 * @static
	 * @memberOf _
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	 * @example
	 *
	 * _.isObject({});
	 * // => true
	 *
	 * _.isObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isObject(1);
	 * // => false
	 */
	function isObject(value) {
	  // Avoid a V8 JIT bug in Chrome 19-20.
	  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
	  var type = typeof value;
	  return !!value && (type == 'object' || type == 'function');
	}

	/**
	 * Checks if `value` is a native function.
	 *
	 * @static
	 * @memberOf _
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
	 * @example
	 *
	 * _.isNative(Array.prototype.push);
	 * // => true
	 *
	 * _.isNative(_);
	 * // => false
	 */
	function isNative(value) {
	  if (value == null) {
	    return false;
	  }
	  if (isFunction(value)) {
	    return reIsNative.test(fnToString.call(value));
	  }
	  return isObjectLike(value) && reIsHostCtor.test(value);
	}

	module.exports = isArray;


/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {"use strict";

	var get    = __webpack_require__(16);
	var Errors = __webpack_require__(21);
	var Utils  = __webpack_require__(22);

	function Report(parentOrOptions, reportOptions) {
	    this.parentReport = parentOrOptions instanceof Report ?
	                            parentOrOptions :
	                            undefined;

	    this.options = parentOrOptions instanceof Report ?
	                       parentOrOptions.options :
	                       parentOrOptions || {};

	    this.reportOptions = reportOptions || {};

	    this.errors = [];
	    this.path = [];
	    this.asyncTasks = [];
	}

	Report.prototype.isValid = function () {
	    if (this.asyncTasks.length > 0) {
	        throw new Error("Async tasks pending, can't answer isValid");
	    }
	    return this.errors.length === 0;
	};

	Report.prototype.addAsyncTask = function (fn, args, asyncTaskResultProcessFn) {
	    this.asyncTasks.push([fn, args, asyncTaskResultProcessFn]);
	};

	Report.prototype.processAsyncTasks = function (timeout, callback) {

	    var validationTimeout = timeout || 2000,
	        tasksCount        = this.asyncTasks.length,
	        idx               = tasksCount,
	        timedOut          = false,
	        self              = this;

	    function finish() {
	        process.nextTick(function () {
	            var valid = self.errors.length === 0,
	                err   = valid ? undefined : self.errors;
	            callback(err, valid);
	        });
	    }

	    function respond(asyncTaskResultProcessFn) {
	        return function (asyncTaskResult) {
	            if (timedOut) { return; }
	            asyncTaskResultProcessFn(asyncTaskResult);
	            if (--tasksCount === 0) {
	                finish();
	            }
	        };
	    }

	    if (tasksCount === 0 || this.errors.length > 0) {
	        finish();
	        return;
	    }

	    while (idx--) {
	        var task = this.asyncTasks[idx];
	        task[0].apply(null, task[1].concat(respond(task[2])));
	    }

	    setTimeout(function () {
	        if (tasksCount > 0) {
	            timedOut = true;
	            self.addError("ASYNC_TIMEOUT", [tasksCount, validationTimeout]);
	            callback(self.errors, false);
	        }
	    }, validationTimeout);

	};

	Report.prototype.getPath = function () {
	    var path = [];
	    if (this.parentReport) {
	        path = path.concat(this.parentReport.path);
	    }
	    path = path.concat(this.path);

	    if (this.options.reportPathAsArray !== true) {
	        // Sanitize the path segments (http://tools.ietf.org/html/rfc6901#section-4)
	        path = "#/" + path.map(function (segment) {

	            if (Utils.isAbsoluteUri(segment)) {
	                return "uri(" + segment + ")";
	            }

	            return segment.replace(/\~/g, "~0").replace(/\//g, "~1");
	        }).join("/");
	    }
	    return path;
	};

	Report.prototype.getSchemaId = function () {

	    if (!this.rootSchema) {
	        return null;
	    }

	    // get the error path as an array
	    var path = [];
	    if (this.parentReport) {
	        path = path.concat(this.parentReport.path);
	    }
	    path = path.concat(this.path);

	    // try to find id in the error path
	    while (path.length > 0) {
	        var obj = get(this.rootSchema, path);
	        if (obj && obj.id) { return obj.id; }
	        path.pop();
	    }

	    // return id of the root
	    return this.rootSchema.id;
	};

	Report.prototype.hasError = function (errorCode, params) {
	    var idx = this.errors.length;
	    while (idx--) {
	        if (this.errors[idx].code === errorCode) {
	            // assume match
	            var match = true;

	            // check the params too
	            var idx2 = this.errors[idx].params.length;
	            while (idx2--) {
	                if (this.errors[idx].params[idx2] !== params[idx2]) {
	                    match = false;
	                }
	            }

	            // if match, return true
	            if (match) { return match; }
	        }
	    }
	    return false;
	};

	Report.prototype.addError = function (errorCode, params, subReports, schemaDescription) {
	    if (this.errors.length >= this.reportOptions.maxErrors) {
	        return;
	    }

	    if (!errorCode) { throw new Error("No errorCode passed into addError()"); }
	    if (!Errors[errorCode]) { throw new Error("No errorMessage known for code " + errorCode); }

	    params = params || [];

	    var idx = params.length,
	        errorMessage = Errors[errorCode];
	    while (idx--) {
	        var whatIs = Utils.whatIs(params[idx]);
	        var param = (whatIs === "object" || whatIs === "null") ? JSON.stringify(params[idx]) : params[idx];
	        errorMessage = errorMessage.replace("{" + idx + "}", param);
	    }

	    var err = {
	        code: errorCode,
	        params: params,
	        message: errorMessage,
	        path: this.getPath(),
	        schemaId: this.getSchemaId()
	    };

	    if (schemaDescription) {
	        err.description = schemaDescription;
	    }

	    if (subReports != null) {
	        if (!Array.isArray(subReports)) {
	            subReports = [subReports];
	        }
	        err.inner = [];
	        idx = subReports.length;
	        while (idx--) {
	            var subReport = subReports[idx],
	                idx2 = subReport.errors.length;
	            while (idx2--) {
	                err.inner.push(subReport.errors[idx2]);
	            }
	        }
	        if (err.inner.length === 0) {
	            err.inner = undefined;
	        }
	    }

	    this.errors.push(err);
	};

	module.exports = Report;

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 21 */
/***/ function(module, exports) {

	"use strict";

	module.exports = {

	    INVALID_TYPE:                           "Expected type {0} but found type {1}",
	    INVALID_FORMAT:                         "Object didn't pass validation for format {0}: {1}",
	    ENUM_MISMATCH:                          "No enum match for: {0}",
	    ANY_OF_MISSING:                         "Data does not match any schemas from 'anyOf'",
	    ONE_OF_MISSING:                         "Data does not match any schemas from 'oneOf'",
	    ONE_OF_MULTIPLE:                        "Data is valid against more than one schema from 'oneOf'",
	    NOT_PASSED:                             "Data matches schema from 'not'",

	    // Array errors
	    ARRAY_LENGTH_SHORT:                     "Array is too short ({0}), minimum {1}",
	    ARRAY_LENGTH_LONG:                      "Array is too long ({0}), maximum {1}",
	    ARRAY_UNIQUE:                           "Array items are not unique (indexes {0} and {1})",
	    ARRAY_ADDITIONAL_ITEMS:                 "Additional items not allowed",

	    // Numeric errors
	    MULTIPLE_OF:                            "Value {0} is not a multiple of {1}",
	    MINIMUM:                                "Value {0} is less than minimum {1}",
	    MINIMUM_EXCLUSIVE:                      "Value {0} is equal or less than exclusive minimum {1}",
	    MAXIMUM:                                "Value {0} is greater than maximum {1}",
	    MAXIMUM_EXCLUSIVE:                      "Value {0} is equal or greater than exclusive maximum {1}",

	    // Object errors
	    OBJECT_PROPERTIES_MINIMUM:              "Too few properties defined ({0}), minimum {1}",
	    OBJECT_PROPERTIES_MAXIMUM:              "Too many properties defined ({0}), maximum {1}",
	    OBJECT_MISSING_REQUIRED_PROPERTY:       "Missing required property: {0}",
	    OBJECT_ADDITIONAL_PROPERTIES:           "Additional properties not allowed: {0}",
	    OBJECT_DEPENDENCY_KEY:                  "Dependency failed - key must exist: {0} (due to key: {1})",

	    // String errors
	    MIN_LENGTH:                             "String is too short ({0} chars), minimum {1}",
	    MAX_LENGTH:                             "String is too long ({0} chars), maximum {1}",
	    PATTERN:                                "String does not match pattern {0}: {1}",

	    // Schema validation errors
	    KEYWORD_TYPE_EXPECTED:                  "Keyword '{0}' is expected to be of type '{1}'",
	    KEYWORD_UNDEFINED_STRICT:               "Keyword '{0}' must be defined in strict mode",
	    KEYWORD_UNEXPECTED:                     "Keyword '{0}' is not expected to appear in the schema",
	    KEYWORD_MUST_BE:                        "Keyword '{0}' must be {1}",
	    KEYWORD_DEPENDENCY:                     "Keyword '{0}' requires keyword '{1}'",
	    KEYWORD_PATTERN:                        "Keyword '{0}' is not a valid RegExp pattern: {1}",
	    KEYWORD_VALUE_TYPE:                     "Each element of keyword '{0}' array must be a '{1}'",
	    UNKNOWN_FORMAT:                         "There is no validation function for format '{0}'",
	    CUSTOM_MODE_FORCE_PROPERTIES:           "{0} must define at least one property if present",

	    // Remote errors
	    REF_UNRESOLVED:                         "Reference has not been resolved during compilation: {0}",
	    UNRESOLVABLE_REFERENCE:                 "Reference could not be resolved: {0}",
	    SCHEMA_NOT_REACHABLE:                   "Validator was not able to read schema with uri: {0}",
	    SCHEMA_TYPE_EXPECTED:                   "Schema is expected to be of type 'object'",
	    SCHEMA_NOT_AN_OBJECT:                   "Schema is not an object: {0}",
	    ASYNC_TIMEOUT:                          "{0} asynchronous task(s) have timed out after {1} ms",
	    PARENT_SCHEMA_VALIDATION_FAILED:        "Schema failed to validate against its parent schema, see inner errors for details.",
	    REMOTE_NOT_VALID:                       "Remote reference didn't compile successfully: {0}"

	};


/***/ },
/* 22 */
/***/ function(module, exports) {

	"use strict";

	exports.isAbsoluteUri = function (uri) {
	    return /^https?:\/\//.test(uri);
	};

	exports.isRelativeUri = function (uri) {
	    // relative URIs that end with a hash sign, issue #56
	    return /.+#/.test(uri);
	};

	exports.whatIs = function (what) {

	    var to = typeof what;

	    if (to === "object") {
	        if (what === null) {
	            return "null";
	        }
	        if (Array.isArray(what)) {
	            return "array";
	        }
	        return "object"; // typeof what === 'object' && what === Object(what) && !Array.isArray(what);
	    }

	    if (to === "number") {
	        if (Number.isFinite(what)) {
	            if (what % 1 === 0) {
	                return "integer";
	            } else {
	                return "number";
	            }
	        }
	        if (Number.isNaN(what)) {
	            return "not-a-number";
	        }
	        return "unknown-number";
	    }

	    return to; // undefined, boolean, string, function

	};

	exports.areEqual = function areEqual(json1, json2) {
	    // http://json-schema.org/latest/json-schema-core.html#rfc.section.3.6

	    // Two JSON values are said to be equal if and only if:
	    // both are nulls; or
	    // both are booleans, and have the same value; or
	    // both are strings, and have the same value; or
	    // both are numbers, and have the same mathematical value; or
	    if (json1 === json2) {
	        return true;
	    }

	    var i, len;

	    // both are arrays, and:
	    if (Array.isArray(json1) && Array.isArray(json2)) {
	        // have the same number of items; and
	        if (json1.length !== json2.length) {
	            return false;
	        }
	        // items at the same index are equal according to this definition; or
	        len = json1.length;
	        for (i = 0; i < len; i++) {
	            if (!areEqual(json1[i], json2[i])) {
	                return false;
	            }
	        }
	        return true;
	    }

	    // both are objects, and:
	    if (exports.whatIs(json1) === "object" && exports.whatIs(json2) === "object") {
	        // have the same set of property names; and
	        var keys1 = Object.keys(json1);
	        var keys2 = Object.keys(json2);
	        if (!areEqual(keys1, keys2)) {
	            return false;
	        }
	        // values for a same property name are equal according to this definition.
	        len = keys1.length;
	        for (i = 0; i < len; i++) {
	            if (!areEqual(json1[keys1[i]], json2[keys1[i]])) {
	                return false;
	            }
	        }
	        return true;
	    }

	    return false;
	};

	exports.isUniqueArray = function (arr, indexes) {
	    var i, j, l = arr.length;
	    for (i = 0; i < l; i++) {
	        for (j = i + 1; j < l; j++) {
	            if (exports.areEqual(arr[i], arr[j])) {
	                if (indexes) { indexes.push(i, j); }
	                return false;
	            }
	        }
	    }
	    return true;
	};

	exports.difference = function (bigSet, subSet) {
	    var arr = [],
	        idx = bigSet.length;
	    while (idx--) {
	        if (subSet.indexOf(bigSet[idx]) === -1) {
	            arr.push(bigSet[idx]);
	        }
	    }
	    return arr;
	};

	// NOT a deep version of clone
	exports.clone = function (src) {
	    if (typeof src === "undefined") { return void 0; }
	    if (typeof src !== "object" || src === null) { return src; }
	    var res, idx;
	    if (Array.isArray(src)) {
	        res = [];
	        idx = src.length;
	        while (idx--) {
	            res[idx] = src[idx];
	        }
	    } else {
	        res = {};
	        var keys = Object.keys(src);
	        idx = keys.length;
	        while (idx--) {
	            var key = keys[idx];
	            res[key] = src[key];
	        }
	    }
	    return res;
	};

	exports.cloneDeep = function (src) {
	    var visited = [], cloned = [];
	    function cloneDeep(src) {
	        if (typeof src !== "object" || src === null) { return src; }
	        var res, idx, cidx;

	        cidx = visited.indexOf(src);
	        if (cidx !== -1) { return cloned[cidx]; }

	        visited.push(src);
	        if (Array.isArray(src)) {
	            res = [];
	            cloned.push(res);
	            idx = src.length;
	            while (idx--) {
	                res[idx] = cloneDeep(src[idx]);
	            }
	        } else {
	            res = {};
	            cloned.push(res);
	            var keys = Object.keys(src);
	            idx = keys.length;
	            while (idx--) {
	                var key = keys[idx];
	                res[key] = cloneDeep(src[key]);
	            }
	        }
	        return res;
	    }
	    return cloneDeep(src);
	};

	/*
	  following function comes from punycode.js library
	  see: https://github.com/bestiejs/punycode.js
	*/
	/*jshint -W016*/
	/**
	 * Creates an array containing the numeric code points of each Unicode
	 * character in the string. While JavaScript uses UCS-2 internally,
	 * this function will convert a pair of surrogate halves (each of which
	 * UCS-2 exposes as separate characters) into a single code point,
	 * matching UTF-16.
	 * @see `punycode.ucs2.encode`
	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
	 * @memberOf punycode.ucs2
	 * @name decode
	 * @param {String} string The Unicode input string (UCS-2).
	 * @returns {Array} The new array of code points.
	 */
	exports.ucs2decode = function (string) {
	    var output = [],
	        counter = 0,
	        length = string.length,
	        value,
	        extra;
	    while (counter < length) {
	        value = string.charCodeAt(counter++);
	        if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
	            // high surrogate, and there is a next character
	            extra = string.charCodeAt(counter++);
	            if ((extra & 0xFC00) == 0xDC00) { // low surrogate
	                output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
	            } else {
	                // unmatched surrogate; only append this code unit, in case the next
	                // code unit is the high surrogate of a surrogate pair
	                output.push(value);
	                counter--;
	            }
	        } else {
	            output.push(value);
	        }
	    }
	    return output;
	};
	/*jshint +W016*/


/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {

	/*jshint maxlen: false*/

	var validator = __webpack_require__(24);

	var FormatValidators = {
	    "date": function (date) {
	        if (typeof date !== "string") {
	            return true;
	        }
	        // full-date from http://tools.ietf.org/html/rfc3339#section-5.6
	        var matches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(date);
	        if (matches === null) {
	            return false;
	        }
	        // var year = matches[1];
	        // var month = matches[2];
	        // var day = matches[3];
	        if (matches[2] < "01" || matches[2] > "12" || matches[3] < "01" || matches[3] > "31") {
	            return false;
	        }
	        return true;
	    },
	    "date-time": function (dateTime) {
	        if (typeof dateTime !== "string") {
	            return true;
	        }
	        // date-time from http://tools.ietf.org/html/rfc3339#section-5.6
	        var s = dateTime.toLowerCase().split("t");
	        if (!FormatValidators.date(s[0])) {
	            return false;
	        }
	        var matches = /^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$/.exec(s[1]);
	        if (matches === null) {
	            return false;
	        }
	        // var hour = matches[1];
	        // var minute = matches[2];
	        // var second = matches[3];
	        // var fraction = matches[4];
	        // var timezone = matches[5];
	        if (matches[1] > "23" || matches[2] > "59" || matches[3] > "59") {
	            return false;
	        }
	        return true;
	    },
	    "email": function (email) {
	        if (typeof email !== "string") {
	            return true;
	        }
	        return validator.isEmail(email, { "require_tld": true });
	    },
	    "hostname": function (hostname) {
	        if (typeof hostname !== "string") {
	            return true;
	        }
	        /*
	            http://json-schema.org/latest/json-schema-validation.html#anchor114
	            A string instance is valid against this attribute if it is a valid
	            representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034].

	            http://tools.ietf.org/html/rfc1034#section-3.5

	            <digit> ::= any one of the ten digits 0 through 9
	            var digit = /[0-9]/;

	            <letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
	            var letter = /[a-zA-Z]/;

	            <let-dig> ::= <letter> | <digit>
	            var letDig = /[0-9a-zA-Z]/;

	            <let-dig-hyp> ::= <let-dig> | "-"
	            var letDigHyp = /[-0-9a-zA-Z]/;

	            <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
	            var ldhStr = /[-0-9a-zA-Z]+/;

	            <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
	            var label = /[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?/;

	            <subdomain> ::= <label> | <subdomain> "." <label>
	            var subdomain = /^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$/;

	            <domain> ::= <subdomain> | " "
	            var domain = null;
	        */
	        var valid = /^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$/.test(hostname);
	        if (valid) {
	            // the sum of all label octets and label lengths is limited to 255.
	            if (hostname.length > 255) { return false; }
	            // Each node has a label, which is zero to 63 octets in length
	            var labels = hostname.split(".");
	            for (var i = 0; i < labels.length; i++) { if (labels[i].length > 63) { return false; } }
	        }
	        return valid;
	    },
	    "host-name": function (hostname) {
	        return FormatValidators.hostname.call(this, hostname);
	    },
	    "ipv4": function (ipv4) {
	        if (typeof ipv4 !== "string") { return true; }
	        return validator.isIP(ipv4, 4);
	    },
	    "ipv6": function (ipv6) {
	        if (typeof ipv6 !== "string") { return true; }
	        return validator.isIP(ipv6, 6);
	    },
	    "regex": function (str) {
	        try {
	            RegExp(str);
	            return true;
	        } catch (e) {
	            return false;
	        }
	    },
	    "uri": function (uri) {
	        if (this.options.strictUris) {
	            return FormatValidators["strict-uri"].apply(this, arguments);
	        }
	        // https://github.com/zaggino/z-schema/issues/18
	        // RegExp from http://tools.ietf.org/html/rfc3986#appendix-B
	        return typeof uri !== "string" || RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?").test(uri);
	    },
	    "strict-uri": function (uri) {
	        return typeof uri !== "string" || validator.isURL(uri);
	    }
	};

	module.exports = FormatValidators;


/***/ },
/* 24 */
/***/ function(module, exports, __webpack_require__) {

	/*!
	 * Copyright (c) 2015 Chris O'Hara <cohara87@gmail.com>
	 *
	 * Permission is hereby granted, free of charge, to any person obtaining
	 * a copy of this software and associated documentation files (the
	 * "Software"), to deal in the Software without restriction, including
	 * without limitation the rights to use, copy, modify, merge, publish,
	 * distribute, sublicense, and/or sell copies of the Software, and to
	 * permit persons to whom the Software is furnished to do so, subject to
	 * the following conditions:
	 *
	 * The above copyright notice and this permission notice shall be
	 * included in all copies or substantial portions of the Software.
	 *
	 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
	 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
	 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
	 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
	 */

	(function (name, definition) {
	    if (true) {
	        module.exports = definition();
	    } else if (typeof define === 'function' && typeof define.amd === 'object') {
	        define(definition);
	    } else if (typeof define === 'function' && typeof define.petal === 'object') {
	        define(name, [], definition);
	    } else {
	        this[name] = definition();
	    }
	})('validator', function (validator) {

	    'use strict';

	    validator = { version: '4.5.2' };

	    var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
	    var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;

	    var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
	    var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;

	    var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i;

	    var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;

	    var isin = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;

	    var isbn10Maybe = /^(?:[0-9]{9}X|[0-9]{10})$/
	      , isbn13Maybe = /^(?:[0-9]{13})$/;

	    var macAddress = /^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$/;

	    var ipv4Maybe = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
	      , ipv6Block = /^[0-9A-F]{1,4}$/i;

	    var uuid = {
	        '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i
	      , '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
	      , '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
	      , all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
	    };

	    var alpha = /^[A-Z]+$/i
	      , alphanumeric = /^[0-9A-Z]+$/i
	      , numeric = /^[-+]?[0-9]+$/
	      , int = /^(?:[-+]?(?:0|[1-9][0-9]*))$/
	      , float = /^(?:[-+]?(?:[0-9]+))?(?:\.[0-9]*)?(?:[eE][\+\-]?(?:[0-9]+))?$/
	      , hexadecimal = /^[0-9A-F]+$/i
	      , decimal = /^[-+]?([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/
	      , hexcolor = /^#?([0-9A-F]{3}|[0-9A-F]{6})$/i;

	    var ascii = /^[\x00-\x7F]+$/
	      , multibyte = /[^\x00-\x7F]/
	      , fullWidth = /[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/
	      , halfWidth = /[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;

	    var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;

	    var base64 = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;

	    var phones = {
	      'zh-CN': /^(\+?0?86\-?)?((13\d|14[57]|15[^4,\D]|17[678]|18\d)\d{8}|170[059]\d{7})$/,
	      'zh-TW': /^(\+?886\-?|0)?9\d{8}$/,
	      'en-ZA': /^(\+?27|0)\d{9}$/,
	      'en-AU': /^(\+?61|0)4\d{8}$/,
	      'en-HK': /^(\+?852\-?)?[569]\d{3}\-?\d{4}$/,
	      'fr-FR': /^(\+?33|0)[67]\d{8}$/,
	      'pt-PT': /^(\+351)?9[1236]\d{7}$/,
	      'el-GR': /^(\+?30)?(69\d{8})$/,
	      'en-GB': /^(\+?44|0)7\d{9}$/,
	      'en-US': /^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$/,
	      'en-ZM': /^(\+26)?09[567]\d{7}$/,
	      'ru-RU': /^(\+?7|8)?9\d{9}$/,
	      'nb-NO': /^(\+?47)?[49]\d{7}$/,
	      'nn-NO': /^(\+?47)?[49]\d{7}$/,
	      'vi-VN': /^(0|\+?84)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$/,
	      'en-NZ': /^(\+?64|0)2\d{7,9}$/,
	      'en-IN': /^(\+?91|0)?[789]\d{9}$/
	    };

	    // from http://goo.gl/0ejHHW
	    var iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;

	    validator.extend = function (name, fn) {
	        validator[name] = function () {
	            var args = Array.prototype.slice.call(arguments);
	            args[0] = validator.toString(args[0]);
	            return fn.apply(validator, args);
	        };
	    };

	    //Right before exporting the validator object, pass each of the builtins
	    //through extend() so that their first argument is coerced to a string
	    validator.init = function () {
	        for (var name in validator) {
	            if (typeof validator[name] !== 'function' || name === 'toString' ||
	                    name === 'toDate' || name === 'extend' || name === 'init') {
	                continue;
	            }
	            validator.extend(name, validator[name]);
	        }
	    };

	    validator.toString = function (input) {
	        if (typeof input === 'object' && input !== null && input.toString) {
	            input = input.toString();
	        } else if (input === null || typeof input === 'undefined' || (isNaN(input) && !input.length)) {
	            input = '';
	        }
	        return '' + input;
	    };

	    validator.toDate = function (date) {
	        if (Object.prototype.toString.call(date) === '[object Date]') {
	            return date;
	        }
	        date = Date.parse(date);
	        return !isNaN(date) ? new Date(date) : null;
	    };

	    validator.toFloat = function (str) {
	        return parseFloat(str);
	    };

	    validator.toInt = function (str, radix) {
	        return parseInt(str, radix || 10);
	    };

	    validator.toBoolean = function (str, strict) {
	        if (strict) {
	            return str === '1' || str === 'true';
	        }
	        return str !== '0' && str !== 'false' && str !== '';
	    };

	    validator.equals = function (str, comparison) {
	        return str === validator.toString(comparison);
	    };

	    validator.contains = function (str, elem) {
	        return str.indexOf(validator.toString(elem)) >= 0;
	    };

	    validator.matches = function (str, pattern, modifiers) {
	        if (Object.prototype.toString.call(pattern) !== '[object RegExp]') {
	            pattern = new RegExp(pattern, modifiers);
	        }
	        return pattern.test(str);
	    };

	    var default_email_options = {
	        allow_display_name: false,
	        allow_utf8_local_part: true,
	        require_tld: true
	    };

	    validator.isEmail = function (str, options) {
	        options = merge(options, default_email_options);

	        if (options.allow_display_name) {
	            var display_email = str.match(displayName);
	            if (display_email) {
	                str = display_email[1];
	            }
	        }

	        var parts = str.split('@')
	          , domain = parts.pop()
	          , user = parts.join('@');

	        var lower_domain = domain.toLowerCase();
	        if (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com') {
	            user = user.replace(/\./g, '').toLowerCase();
	        }

	        if (!validator.isByteLength(user, {max: 64}) ||
	                !validator.isByteLength(domain, {max: 256})) {
	            return false;
	        }

	        if (!validator.isFQDN(domain, {require_tld: options.require_tld})) {
	            return false;
	        }

	        if (user[0] === '"') {
	            user = user.slice(1, user.length - 1);
	            return options.allow_utf8_local_part ?
	                quotedEmailUserUtf8.test(user) :
	                quotedEmailUser.test(user);
	        }

	        var pattern = options.allow_utf8_local_part ?
	            emailUserUtf8Part : emailUserPart;

	        var user_parts = user.split('.');
	        for (var i = 0; i < user_parts.length; i++) {
	            if (!pattern.test(user_parts[i])) {
	                return false;
	            }
	        }

	        return true;
	    };

	    var default_url_options = {
	        protocols: [ 'http', 'https', 'ftp' ]
	      , require_tld: true
	      , require_protocol: false
	      , require_valid_protocol: true
	      , allow_underscores: false
	      , allow_trailing_dot: false
	      , allow_protocol_relative_urls: false
	    };

	    validator.isURL = function (url, options) {
	        if (!url || url.length >= 2083 || /\s/.test(url)) {
	            return false;
	        }
	        if (url.indexOf('mailto:') === 0) {
	            return false;
	        }
	        options = merge(options, default_url_options);
	        var protocol, auth, host, hostname, port,
	            port_str, split;
	        split = url.split('://');
	        if (split.length > 1) {
	            protocol = split.shift();
	            if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
	                return false;
	            }
	        } else if (options.require_protocol) {
	            return false;
	        }  else if (options.allow_protocol_relative_urls && url.substr(0, 2) === '//') {
	            split[0] = url.substr(2);
	        }
	        url = split.join('://');
	        split = url.split('#');
	        url = split.shift();

	        split = url.split('?');
	        url = split.shift();

	        split = url.split('/');
	        url = split.shift();
	        split = url.split('@');
	        if (split.length > 1) {
	            auth = split.shift();
	            if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
	                return false;
	            }
	        }
	        hostname = split.join('@');
	        split = hostname.split(':');
	        host = split.shift();
	        if (split.length) {
	            port_str = split.join(':');
	            port = parseInt(port_str, 10);
	            if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
	                return false;
	            }
	        }
	        if (!validator.isIP(host) && !validator.isFQDN(host, options) &&
	                host !== 'localhost') {
	            return false;
	        }
	        if (options.host_whitelist &&
	                options.host_whitelist.indexOf(host) === -1) {
	            return false;
	        }
	        if (options.host_blacklist &&
	                options.host_blacklist.indexOf(host) !== -1) {
	            return false;
	        }
	        return true;
	    };

	    validator.isMACAddress = function (str) {
	        return macAddress.test(str);
	    };

	    validator.isIP = function (str, version) {
	        version = validator.toString(version);
	        if (!version) {
	            return validator.isIP(str, 4) || validator.isIP(str, 6);
	        } else if (version === '4') {
	            if (!ipv4Maybe.test(str)) {
	                return false;
	            }
	            var parts = str.split('.').sort(function (a, b) {
	                return a - b;
	            });
	            return parts[3] <= 255;
	        } else if (version === '6') {
	            var blocks = str.split(':');
	            var foundOmissionBlock = false; // marker to indicate ::

	            // At least some OS accept the last 32 bits of an IPv6 address
	            // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says
	            // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses,
	            // and '::a.b.c.d' is deprecated, but also valid.
	            var foundIPv4TransitionBlock = validator.isIP(blocks[blocks.length - 1], 4);
	            var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8;

	            if (blocks.length > expectedNumberOfBlocks)
	                return false;

	            // initial or final ::
	            if (str === '::') {
	                return true;
	            } else if (str.substr(0, 2) === '::') {
	                blocks.shift();
	                blocks.shift();
	                foundOmissionBlock = true;
	            } else if (str.substr(str.length - 2) === '::') {
	                blocks.pop();
	                blocks.pop();
	                foundOmissionBlock = true;
	            }

	            for (var i = 0; i < blocks.length; ++i) {
	                // test for a :: which can not be at the string start/end
	                // since those cases have been handled above
	                if (blocks[i] === '' && i > 0 && i < blocks.length -1) {
	                    if (foundOmissionBlock)
	                        return false; // multiple :: in address
	                    foundOmissionBlock = true;
	                } else if (foundIPv4TransitionBlock && i == blocks.length - 1) {
	                    // it has been checked before that the last
	                    // block is a valid IPv4 address
	                } else if (!ipv6Block.test(blocks[i])) {
	                    return false;
	                }
	            }

	            if (foundOmissionBlock) {
	                return blocks.length >= 1;
	            } else {
	                return blocks.length === expectedNumberOfBlocks;
	            }
	        }
	        return false;
	    };

	    var default_fqdn_options = {
	        require_tld: true
	      , allow_underscores: false
	      , allow_trailing_dot: false
	    };

	    validator.isFQDN = function (str, options) {
	        options = merge(options, default_fqdn_options);

	        /* Remove the optional trailing dot before checking validity */
	        if (options.allow_trailing_dot && str[str.length - 1] === '.') {
	            str = str.substring(0, str.length - 1);
	        }
	        var parts = str.split('.');
	        if (options.require_tld) {
	            var tld = parts.pop();
	            if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) {
	                return false;
	            }
	        }
	        for (var part, i = 0; i < parts.length; i++) {
	            part = parts[i];
	            if (options.allow_underscores) {
	                if (part.indexOf('__') >= 0) {
	                    return false;
	                }
	                part = part.replace(/_/g, '');
	            }
	            if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) {
	                return false;
	            }
	            if (/[\uff01-\uff5e]/.test(part)) {
	                // disallow full-width chars
	                return false;
	            }
	            if (part[0] === '-' || part[part.length - 1] === '-') {
	                return false;
	            }
	            if (part.indexOf('---') >= 0 && part.slice(0, 4) !== 'xn--') {
	                return false;
	            }
	        }
	        return true;
	    };

	    validator.isBoolean = function(str) {
	        return (['true', 'false', '1', '0'].indexOf(str) >= 0);
	    };

	    validator.isAlpha = function (str) {
	        return alpha.test(str);
	    };

	    validator.isAlphanumeric = function (str) {
	        return alphanumeric.test(str);
	    };

	    validator.isNumeric = function (str) {
	        return numeric.test(str);
	    };

	    validator.isDecimal = function (str) {
	        return str !== '' && decimal.test(str);
	    };

	    validator.isHexadecimal = function (str) {
	        return hexadecimal.test(str);
	    };

	    validator.isHexColor = function (str) {
	        return hexcolor.test(str);
	    };

	    validator.isLowercase = function (str) {
	        return str === str.toLowerCase();
	    };

	    validator.isUppercase = function (str) {
	        return str === str.toUpperCase();
	    };

	    validator.isInt = function (str, options) {
	        options = options || {};
	        return int.test(str) && (!options.hasOwnProperty('min') || str >= options.min) && (!options.hasOwnProperty('max') || str <= options.max);
	    };

	    validator.isFloat = function (str, options) {
	        options = options || {};
	        if (str === '' || str === '.') {
	            return false;
	        }
	        return float.test(str) && (!options.hasOwnProperty('min') || str >= options.min) && (!options.hasOwnProperty('max') || str <= options.max);
	    };

	    validator.isDivisibleBy = function (str, num) {
	        return validator.toFloat(str) % validator.toInt(num) === 0;
	    };

	    validator.isNull = function (str) {
	        return str.length === 0;
	    };

	    validator.isLength = function (str, options) {
	        var min, max;
	        if (typeof(options) === 'object') {
	            min = options.min || 0;
	            max = options.max;
	        } else { // backwards compatibility: isLength(str, min [, max])
	            min = arguments[1];
	            max = arguments[2];
	        }
	        var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
	        var len = str.length - surrogatePairs.length;
	        return len >= min && (typeof max === 'undefined' || len <= max);
	    };
	    validator.isByteLength = function (str, options) {
	        var min, max;
	        if (typeof(options) === 'object') {
	            min = options.min || 0;
	            max = options.max;
	        } else { // backwards compatibility: isByteLength(str, min [, max])
	            min = arguments[1];
	            max = arguments[2];
	        }
	        var len = encodeURI(str).split(/%..|./).length - 1;
	        return len >= min && (typeof max === 'undefined' || len <= max);
	    };

	    validator.isUUID = function (str, version) {
	        var pattern = uuid[version ? version : 'all'];
	        return pattern && pattern.test(str);
	    };

	    function getTimezoneOffset(str) {
	        var iso8601Parts = str.match(iso8601)
	          , timezone, sign, hours, minutes;
	        if (!iso8601Parts) {
	            str = str.toLowerCase();
	            timezone = str.match(/(?:\s|gmt\s*)(-|\+)(\d{1,4})(\s|$)/);
	            if (!timezone) {
	                return str.indexOf('gmt') !== -1 ? 0 : null;
	            }
	            sign = timezone[1];
	            var offset = timezone[2];
	            if (offset.length === 3) {
	                offset = '0' + offset;
	            }
	            if (offset.length <= 2) {
	                hours = 0;
	                minutes = parseInt(offset);
	            } else {
	                hours = parseInt(offset.slice(0, 2));
	                minutes = parseInt(offset.slice(2, 4));
	            }
	        } else {
	            timezone = iso8601Parts[21];
	            if (!timezone) {
	                // if no hour/minute was provided, the date is GMT
	                return !iso8601Parts[12] ? 0 : null;
	            }
	            if (timezone === 'z' || timezone === 'Z') {
	                return 0;
	            }
	            sign = iso8601Parts[22];
	            if (timezone.indexOf(':') !== -1) {
	                hours = parseInt(iso8601Parts[23]);
	                minutes = parseInt(iso8601Parts[24]);
	            } else {
	                hours = 0;
	                minutes = parseInt(iso8601Parts[23]);
	            }
	        }
	        return (hours * 60 + minutes) * (sign === '-' ? 1 : -1);
	    }

	    validator.isDate = function (str) {
	        var normalizedDate = new Date(Date.parse(str));
	        if (isNaN(normalizedDate)) {
	            return false;
	        }

	        // normalizedDate is in the user's timezone. Apply the input
	        // timezone offset to the date so that the year and day match
	        // the input
	        var timezoneOffset = getTimezoneOffset(str);
	        if (timezoneOffset !== null) {
	            var timezoneDifference = normalizedDate.getTimezoneOffset() -
	                timezoneOffset;
	            normalizedDate = new Date(normalizedDate.getTime() +
	                60000 * timezoneDifference);
	        }

	        var day = String(normalizedDate.getDate());
	        var dayOrYear, dayOrYearMatches, year;
	        //check for valid double digits that could be late days
	        //check for all matches since a string like '12/23' is a valid date
	        //ignore everything with nearby colons
	        dayOrYearMatches = str.match(/(^|[^:\d])[23]\d([^:\d]|$)/g);
	        if (!dayOrYearMatches) {
	            return true;
	        }
	        dayOrYear = dayOrYearMatches.map(function(digitString) {
	            return digitString.match(/\d+/g)[0];
	        }).join('/');

	        year = String(normalizedDate.getFullYear()).slice(-2);
	        if (dayOrYear === day || dayOrYear === year) {
	            return true;
	        } else if ((dayOrYear === (day + '/' + year)) || (dayOrYear === (year + '/' + day))) {
	            return true;
	        }
	        return false;
	    };

	    validator.isAfter = function (str, date) {
	        var comparison = validator.toDate(date || new Date())
	          , original = validator.toDate(str);
	        return !!(original && comparison && original > comparison);
	    };

	    validator.isBefore = function (str, date) {
	        var comparison = validator.toDate(date || new Date())
	          , original = validator.toDate(str);
	        return !!(original && comparison && original < comparison);
	    };

	    validator.isIn = function (str, options) {
	        var i;
	        if (Object.prototype.toString.call(options) === '[object Array]') {
	            var array = [];
	            for (i in options) {
	                array[i] = validator.toString(options[i]);
	            }
	            return array.indexOf(str) >= 0;
	        } else if (typeof options === 'object') {
	            return options.hasOwnProperty(str);
	        } else if (options && typeof options.indexOf === 'function') {
	            return options.indexOf(str) >= 0;
	        }
	        return false;
	    };

	    validator.isWhitelisted = function (str, chars) {
	        for (var i = str.length - 1; i >= 0; i--) {
	            if (chars.indexOf(str[i]) === -1) {
	                return false;
	            }
	        }

	        return true;
	    };

	    validator.isCreditCard = function (str) {
	        var sanitized = str.replace(/[^0-9]+/g, '');
	        if (!creditCard.test(sanitized)) {
	            return false;
	        }
	        var sum = 0, digit, tmpNum, shouldDouble;
	        for (var i = sanitized.length - 1; i >= 0; i--) {
	            digit = sanitized.substring(i, (i + 1));
	            tmpNum = parseInt(digit, 10);
	            if (shouldDouble) {
	                tmpNum *= 2;
	                if (tmpNum >= 10) {
	                    sum += ((tmpNum % 10) + 1);
	                } else {
	                    sum += tmpNum;
	                }
	            } else {
	                sum += tmpNum;
	            }
	            shouldDouble = !shouldDouble;
	        }
	        return !!((sum % 10) === 0 ? sanitized : false);
	    };

	    validator.isISIN = function (str) {
	        if (!isin.test(str)) {
	            return false;
	        }

	        var checksumStr = str.replace(/[A-Z]/g, function(character) {
	            return parseInt(character, 36);
	        });

	        var sum = 0, digit, tmpNum, shouldDouble = true;
	        for (var i = checksumStr.length - 2; i >= 0; i--) {
	            digit = checksumStr.substring(i, (i + 1));
	            tmpNum = parseInt(digit, 10);
	            if (shouldDouble) {
	                tmpNum *= 2;
	                if (tmpNum >= 10) {
	                    sum += tmpNum + 1;
	                } else {
	                    sum += tmpNum;
	                }
	            } else {
	                sum += tmpNum;
	            }
	            shouldDouble = !shouldDouble;
	        }

	        return parseInt(str.substr(str.length - 1), 10) === (10000 - sum) % 10;
	    };

	    validator.isISBN = function (str, version) {
	        version = validator.toString(version);
	        if (!version) {
	            return validator.isISBN(str, 10) || validator.isISBN(str, 13);
	        }
	        var sanitized = str.replace(/[\s-]+/g, '')
	          , checksum = 0, i;
	        if (version === '10') {
	            if (!isbn10Maybe.test(sanitized)) {
	                return false;
	            }
	            for (i = 0; i < 9; i++) {
	                checksum += (i + 1) * sanitized.charAt(i);
	            }
	            if (sanitized.charAt(9) === 'X') {
	                checksum += 10 * 10;
	            } else {
	                checksum += 10 * sanitized.charAt(9);
	            }
	            if ((checksum % 11) === 0) {
	                return !!sanitized;
	            }
	        } else  if (version === '13') {
	            if (!isbn13Maybe.test(sanitized)) {
	                return false;
	            }
	            var factor = [ 1, 3 ];
	            for (i = 0; i < 12; i++) {
	                checksum += factor[i % 2] * sanitized.charAt(i);
	            }
	            if (sanitized.charAt(12) - ((10 - (checksum % 10)) % 10) === 0) {
	                return !!sanitized;
	            }
	        }
	        return false;
	    };

	    validator.isMobilePhone = function(str, locale) {
	        if (locale in phones) {
	            return phones[locale].test(str);
	        }
	        return false;
	    };

	    var default_currency_options = {
	        symbol: '$'
	      , require_symbol: false
	      , allow_space_after_symbol: false
	      , symbol_after_digits: false
	      , allow_negatives: true
	      , parens_for_negatives: false
	      , negative_sign_before_digits: false
	      , negative_sign_after_digits: false
	      , allow_negative_sign_placeholder: false
	      , thousands_separator: ','
	      , decimal_separator: '.'
	      , allow_space_after_digits: false
	    };

	    validator.isCurrency = function (str, options) {
	        options = merge(options, default_currency_options);

	        return currencyRegex(options).test(str);
	    };

	    validator.isJSON = function (str) {
	        try {
	            var obj = JSON.parse(str);
	            return !!obj && typeof obj === 'object';
	        } catch (e) {}
	        return false;
	    };

	    validator.isMultibyte = function (str) {
	        return multibyte.test(str);
	    };

	    validator.isAscii = function (str) {
	        return ascii.test(str);
	    };

	    validator.isFullWidth = function (str) {
	        return fullWidth.test(str);
	    };

	    validator.isHalfWidth = function (str) {
	        return halfWidth.test(str);
	    };

	    validator.isVariableWidth = function (str) {
	        return fullWidth.test(str) && halfWidth.test(str);
	    };

	    validator.isSurrogatePair = function (str) {
	        return surrogatePair.test(str);
	    };

	    validator.isBase64 = function (str) {
	        return base64.test(str);
	    };

	    validator.isMongoId = function (str) {
	        return validator.isHexadecimal(str) && str.length === 24;
	    };

	    validator.isISO8601 = function (str) {
	        return iso8601.test(str);
	    };

	    validator.ltrim = function (str, chars) {
	        var pattern = chars ? new RegExp('^[' + chars + ']+', 'g') : /^\s+/g;
	        return str.replace(pattern, '');
	    };

	    validator.rtrim = function (str, chars) {
	        var pattern = chars ? new RegExp('[' + chars + ']+$', 'g') : /\s+$/g;
	        return str.replace(pattern, '');
	    };

	    validator.trim = function (str, chars) {
	        var pattern = chars ? new RegExp('^[' + chars + ']+|[' + chars + ']+$', 'g') : /^\s+|\s+$/g;
	        return str.replace(pattern, '');
	    };

	    validator.escape = function (str) {
	        return (str.replace(/&/g, '&amp;')
	            .replace(/"/g, '&quot;')
	            .replace(/'/g, '&#x27;')
	            .replace(/</g, '&lt;')
	            .replace(/>/g, '&gt;')
	            .replace(/\//g, '&#x2F;')
	            .replace(/\`/g, '&#96;'));
	    };

	    validator.stripLow = function (str, keep_new_lines) {
	        var chars = keep_new_lines ? '\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F' : '\\x00-\\x1F\\x7F';
	        return validator.blacklist(str, chars);
	    };

	    validator.whitelist = function (str, chars) {
	        return str.replace(new RegExp('[^' + chars + ']+', 'g'), '');
	    };

	    validator.blacklist = function (str, chars) {
	        return str.replace(new RegExp('[' + chars + ']+', 'g'), '');
	    };

	    var default_normalize_email_options = {
	        lowercase: true,
	        remove_dots: true,
	        remove_extension: true
	    };

	    validator.normalizeEmail = function (email, options) {
	        options = merge(options, default_normalize_email_options);
	        if (!validator.isEmail(email)) {
	            return false;
	        }
	        var parts = email.split('@', 2);
	        parts[1] = parts[1].toLowerCase();
	        if (parts[1] === 'gmail.com' || parts[1] === 'googlemail.com') {
	            if (options.remove_extension) {
	                parts[0] = parts[0].split('+')[0];
	            }
	            if (options.remove_dots) {
	                parts[0] = parts[0].replace(/\./g, '');
	            }
	            if (!parts[0].length) {
	                return false;
	            }
	            parts[0] = parts[0].toLowerCase();
	            parts[1] = 'gmail.com';
	        } else if (options.lowercase) {
	            parts[0] = parts[0].toLowerCase();
	        }
	        return parts.join('@');
	    };

	    function merge(obj, defaults) {
	        obj = obj || {};
	        for (var key in defaults) {
	            if (typeof obj[key] === 'undefined') {
	                obj[key] = defaults[key];
	            }
	        }
	        return obj;
	    }

	    function currencyRegex(options) {
	        var symbol = '(\\' + options.symbol.replace(/\./g, '\\.') + ')' + (options.require_symbol ? '' : '?')
	            , negative = '-?'
	            , whole_dollar_amount_without_sep = '[1-9]\\d*'
	            , whole_dollar_amount_with_sep = '[1-9]\\d{0,2}(\\' + options.thousands_separator + '\\d{3})*'
	            , valid_whole_dollar_amounts = ['0', whole_dollar_amount_without_sep, whole_dollar_amount_with_sep]
	            , whole_dollar_amount = '(' + valid_whole_dollar_amounts.join('|') + ')?'
	            , decimal_amount = '(\\' + options.decimal_separator + '\\d{2})?';
	        var pattern = whole_dollar_amount + decimal_amount;
	        // default is negative sign before symbol, but there are two other options (besides parens)
	        if (options.allow_negatives && !options.parens_for_negatives) {
	            if (options.negative_sign_after_digits) {
	                pattern += negative;
	            }
	            else if (options.negative_sign_before_digits) {
	                pattern = negative + pattern;
	            }
	        }
	        // South African Rand, for example, uses R 123 (space) and R-123 (no space)
	        if (options.allow_negative_sign_placeholder) {
	            pattern = '( (?!\\-))?' + pattern;
	        }
	        else if (options.allow_space_after_symbol) {
	            pattern = ' ?' + pattern;
	        }
	        else if (options.allow_space_after_digits) {
	            pattern += '( (?!$))?';
	        }
	        if (options.symbol_after_digits) {
	            pattern += symbol;
	        } else {
	            pattern = symbol + pattern;
	        }
	        if (options.allow_negatives) {
	            if (options.parens_for_negatives) {
	                pattern = '(\\(' + pattern + '\\)|' + pattern + ')';
	            }
	            else if (!(options.negative_sign_before_digits || options.negative_sign_after_digits)) {
	                pattern = negative + pattern;
	            }
	        }
	        return new RegExp(
	            '^' +
	            // ensure there's a dollar and/or decimal amount, and that it doesn't start with a space or a negative sign followed by a space
	            '(?!-? )(?=.*\\d)' +
	            pattern +
	            '$'
	        );
	    }

	    validator.init();

	    return validator;

	});


/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";

	var FormatValidators  = __webpack_require__(23),
	    Report            = __webpack_require__(20),
	    Utils             = __webpack_require__(22);

	var JsonValidators = {
	    multipleOf: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.1.2
	        if (typeof json !== "number") {
	            return;
	        }
	        if (Utils.whatIs(json / schema.multipleOf) !== "integer") {
	            report.addError("MULTIPLE_OF", [json, schema.multipleOf], null, schema.description);
	        }
	    },
	    maximum: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.2
	        if (typeof json !== "number") {
	            return;
	        }
	        if (schema.exclusiveMaximum !== true) {
	            if (json > schema.maximum) {
	                report.addError("MAXIMUM", [json, schema.maximum], null, schema.description);
	            }
	        } else {
	            if (json >= schema.maximum) {
	                report.addError("MAXIMUM_EXCLUSIVE", [json, schema.maximum], null, schema.description);
	            }
	        }
	    },
	    exclusiveMaximum: function () {
	        // covered in maximum
	    },
	    minimum: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.2
	        if (typeof json !== "number") {
	            return;
	        }
	        if (schema.exclusiveMinimum !== true) {
	            if (json < schema.minimum) {
	                report.addError("MINIMUM", [json, schema.minimum], null, schema.description);
	            }
	        } else {
	            if (json <= schema.minimum) {
	                report.addError("MINIMUM_EXCLUSIVE", [json, schema.minimum], null, schema.description);
	            }
	        }
	    },
	    exclusiveMinimum: function () {
	        // covered in minimum
	    },
	    maxLength: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.2
	        if (typeof json !== "string") {
	            return;
	        }
	        if (Utils.ucs2decode(json).length > schema.maxLength) {
	            report.addError("MAX_LENGTH", [json.length, schema.maxLength], null, schema.description);
	        }
	    },
	    minLength: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.2
	        if (typeof json !== "string") {
	            return;
	        }
	        if (Utils.ucs2decode(json).length < schema.minLength) {
	            report.addError("MIN_LENGTH", [json.length, schema.minLength], null, schema.description);
	        }
	    },
	    pattern: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3.2
	        if (typeof json !== "string") {
	            return;
	        }
	        if (RegExp(schema.pattern).test(json) === false) {
	            report.addError("PATTERN", [schema.pattern, json], null, schema.description);
	        }
	    },
	    additionalItems: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.2
	        if (!Array.isArray(json)) {
	            return;
	        }
	        // if the value of "additionalItems" is boolean value false and the value of "items" is an array,
	        // the json is valid if its size is less than, or equal to, the size of "items".
	        if (schema.additionalItems === false && Array.isArray(schema.items)) {
	            if (json.length > schema.items.length) {
	                report.addError("ARRAY_ADDITIONAL_ITEMS", null, null, schema.description);
	            }
	        }
	    },
	    items: function () { /*report, schema, json*/
	        // covered in additionalItems
	    },
	    maxItems: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.2.2
	        if (!Array.isArray(json)) {
	            return;
	        }
	        if (json.length > schema.maxItems) {
	            report.addError("ARRAY_LENGTH_LONG", [json.length, schema.maxItems], null, schema.description);
	        }
	    },
	    minItems: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.2
	        if (!Array.isArray(json)) {
	            return;
	        }
	        if (json.length < schema.minItems) {
	            report.addError("ARRAY_LENGTH_SHORT", [json.length, schema.minItems], null, schema.description);
	        }
	    },
	    uniqueItems: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.4.2
	        if (!Array.isArray(json)) {
	            return;
	        }
	        if (schema.uniqueItems === true) {
	            var matches = [];
	            if (Utils.isUniqueArray(json, matches) === false) {
	                report.addError("ARRAY_UNIQUE", matches, null, schema.description);
	            }
	        }
	    },
	    maxProperties: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.2
	        if (Utils.whatIs(json) !== "object") {
	            return;
	        }
	        var keysCount = Object.keys(json).length;
	        if (keysCount > schema.maxProperties) {
	            report.addError("OBJECT_PROPERTIES_MAXIMUM", [keysCount, schema.maxProperties], null, schema.description);
	        }
	    },
	    minProperties: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.2
	        if (Utils.whatIs(json) !== "object") {
	            return;
	        }
	        var keysCount = Object.keys(json).length;
	        if (keysCount < schema.minProperties) {
	            report.addError("OBJECT_PROPERTIES_MINIMUM", [keysCount, schema.minProperties], null, schema.description);
	        }
	    },
	    required: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.2
	        if (Utils.whatIs(json) !== "object") {
	            return;
	        }
	        var idx = schema.required.length;
	        while (idx--) {
	            var requiredPropertyName = schema.required[idx];
	            if (json[requiredPropertyName] === undefined) {
	                report.addError("OBJECT_MISSING_REQUIRED_PROPERTY", [requiredPropertyName], null, schema.description);
	            }
	        }
	    },
	    additionalProperties: function (report, schema, json) {
	        // covered in properties and patternProperties
	        if (schema.properties === undefined && schema.patternProperties === undefined) {
	            return JsonValidators.properties.call(this, report, schema, json);
	        }
	    },
	    patternProperties: function (report, schema, json) {
	        // covered in properties
	        if (schema.properties === undefined) {
	            return JsonValidators.properties.call(this, report, schema, json);
	        }
	    },
	    properties: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.2
	        if (Utils.whatIs(json) !== "object") {
	            return;
	        }
	        var properties = schema.properties !== undefined ? schema.properties : {};
	        var patternProperties = schema.patternProperties !== undefined ? schema.patternProperties : {};
	        if (schema.additionalProperties === false) {
	            // The property set of the json to validate.
	            var s = Object.keys(json);
	            // The property set from "properties".
	            var p = Object.keys(properties);
	            // The property set from "patternProperties".
	            var pp = Object.keys(patternProperties);
	            // remove from "s" all elements of "p", if any;
	            s = Utils.difference(s, p);
	            // for each regex in "pp", remove all elements of "s" which this regex matches.
	            var idx = pp.length;
	            while (idx--) {
	                var regExp = RegExp(pp[idx]),
	                    idx2 = s.length;
	                while (idx2--) {
	                    if (regExp.test(s[idx2]) === true) {
	                        s.splice(idx2, 1);
	                    }
	                }
	            }
	            // Validation of the json succeeds if, after these two steps, set "s" is empty.
	            if (s.length > 0) {
	                // assumeAdditional can be an array of allowed properties
	                var idx3 = this.options.assumeAdditional.length;
	                if (idx3) {
	                    while (idx3--) {
	                        var io = s.indexOf(this.options.assumeAdditional[idx3]);
	                        if (io !== -1) {
	                            s.splice(io, 1);
	                        }
	                    }
	                }
	                if (s.length > 0) {
	                    report.addError("OBJECT_ADDITIONAL_PROPERTIES", [s], null, schema.description);
	                }
	            }
	        }
	    },
	    dependencies: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.2
	        if (Utils.whatIs(json) !== "object") {
	            return;
	        }

	        var keys = Object.keys(schema.dependencies),
	            idx = keys.length;

	        while (idx--) {
	            // iterate all dependencies
	            var dependencyName = keys[idx];
	            if (json[dependencyName]) {
	                var dependencyDefinition = schema.dependencies[dependencyName];
	                if (Utils.whatIs(dependencyDefinition) === "object") {
	                    // if dependency is a schema, validate against this schema
	                    exports.validate.call(this, report, dependencyDefinition, json);
	                } else { // Array
	                    // if dependency is an array, object needs to have all properties in this array
	                    var idx2 = dependencyDefinition.length;
	                    while (idx2--) {
	                        var requiredPropertyName = dependencyDefinition[idx2];
	                        if (json[requiredPropertyName] === undefined) {
	                            report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], null, schema.description);
	                        }
	                    }
	                }
	            }
	        }
	    },
	    enum: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.2
	        var match = false,
	            idx = schema.enum.length;
	        while (idx--) {
	            if (Utils.areEqual(json, schema.enum[idx])) {
	                match = true;
	                break;
	            }
	        }
	        if (match === false) {
	            report.addError("ENUM_MISMATCH", [json], null, schema.description);
	        }
	    },
	    /*
	    type: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2
	        // type is handled before this is called so ignore
	    },
	    */
	    allOf: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.3.2
	        var idx = schema.allOf.length;
	        while (idx--) {
	            var validateResult = exports.validate.call(this, report, schema.allOf[idx], json);
	            if (this.options.breakOnFirstError && validateResult === false) {
	                break;
	            }
	        }
	    },
	    anyOf: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.4.2
	        var subReports = [],
	            passed = false,
	            idx = schema.anyOf.length;

	        while (idx-- && passed === false) {
	            var subReport = new Report(report);
	            subReports.push(subReport);
	            passed = exports.validate.call(this, subReport, schema.anyOf[idx], json);
	        }

	        if (passed === false) {
	            report.addError("ANY_OF_MISSING", undefined, subReports, schema.description);
	        }
	    },
	    oneOf: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.5.2
	        var passes = 0,
	            subReports = [],
	            idx = schema.oneOf.length;

	        while (idx--) {
	            var subReport = new Report(report, { maxErrors: 1 });
	            subReports.push(subReport);
	            if (exports.validate.call(this, subReport, schema.oneOf[idx], json) === true) {
	                passes++;
	            }
	        }

	        if (passes === 0) {
	            report.addError("ONE_OF_MISSING", undefined, subReports, schema.description);
	        } else if (passes > 1) {
	            report.addError("ONE_OF_MULTIPLE", null, null, schema.description);
	        }
	    },
	    not: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.2
	        var subReport = new Report(report);
	        if (exports.validate.call(this, subReport, schema.not, json) === true) {
	            report.addError("NOT_PASSED", null, null, schema.description);
	        }
	    },
	    definitions: function () { /*report, schema, json*/
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.2
	        // nothing to do here
	    },
	    format: function (report, schema, json) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.7.2
	        var formatValidatorFn = FormatValidators[schema.format];
	        if (typeof formatValidatorFn === "function") {
	            if (formatValidatorFn.length === 2) {
	                // async
	                report.addAsyncTask(formatValidatorFn, [json], function (result) {
	                    if (result !== true) {
	                        report.addError("INVALID_FORMAT", [schema.format, json], null, schema.description);
	                    }
	                });
	            } else {
	                // sync
	                if (formatValidatorFn.call(this, json) !== true) {
	                    report.addError("INVALID_FORMAT", [schema.format, json], null, schema.description);
	                }
	            }
	        } else if (this.options.ignoreUnknownFormats !== true) {
	            report.addError("UNKNOWN_FORMAT", [schema.format], null, schema.description);
	        }
	    }
	};

	var recurseArray = function (report, schema, json) {
	    // http://json-schema.org/latest/json-schema-validation.html#rfc.section.8.2

	    var idx = json.length;

	    // If "items" is an array, this situation, the schema depends on the index:
	    // if the index is less than, or equal to, the size of "items",
	    // the child instance must be valid against the corresponding schema in the "items" array;
	    // otherwise, it must be valid against the schema defined by "additionalItems".
	    if (Array.isArray(schema.items)) {

	        while (idx--) {
	            // equal to doesnt make sense here
	            if (idx < schema.items.length) {
	                report.path.push(idx.toString());
	                exports.validate.call(this, report, schema.items[idx], json[idx]);
	                report.path.pop();
	            } else {
	                // might be boolean, so check that it's an object
	                if (typeof schema.additionalItems === "object") {
	                    report.path.push(idx.toString());
	                    exports.validate.call(this, report, schema.additionalItems, json[idx]);
	                    report.path.pop();
	                }
	            }
	        }

	    } else if (typeof schema.items === "object") {

	        // If items is a schema, then the child instance must be valid against this schema,
	        // regardless of its index, and regardless of the value of "additionalItems".
	        while (idx--) {
	            report.path.push(idx.toString());
	            exports.validate.call(this, report, schema.items, json[idx]);
	            report.path.pop();
	        }

	    }
	};

	var recurseObject = function (report, schema, json) {
	    // http://json-schema.org/latest/json-schema-validation.html#rfc.section.8.3

	    // If "additionalProperties" is absent, it is considered present with an empty schema as a value.
	    // In addition, boolean value true is considered equivalent to an empty schema.
	    var additionalProperties = schema.additionalProperties;
	    if (additionalProperties === true || additionalProperties === undefined) {
	        additionalProperties = {};
	    }

	    // p - The property set from "properties".
	    var p = schema.properties ? Object.keys(schema.properties) : [];

	    // pp - The property set from "patternProperties". Elements of this set will be called regexes for convenience.
	    var pp = schema.patternProperties ? Object.keys(schema.patternProperties) : [];

	    // m - The property name of the child.
	    var keys = Object.keys(json),
	        idx = keys.length;

	    while (idx--) {
	        var m = keys[idx],
	            propertyValue = json[m];

	        // s - The set of schemas for the child instance.
	        var s = [];

	        // 1. If set "p" contains value "m", then the corresponding schema in "properties" is added to "s".
	        if (p.indexOf(m) !== -1) {
	            s.push(schema.properties[m]);
	        }

	        // 2. For each regex in "pp", if it matches "m" successfully, the corresponding schema in "patternProperties" is added to "s".
	        var idx2 = pp.length;
	        while (idx2--) {
	            var regexString = pp[idx2];
	            if (RegExp(regexString).test(m) === true) {
	                s.push(schema.patternProperties[regexString]);
	            }
	        }

	        // 3. The schema defined by "additionalProperties" is added to "s" if and only if, at this stage, "s" is empty.
	        if (s.length === 0 && additionalProperties !== false) {
	            s.push(additionalProperties);
	        }

	        // we are passing tests even without this assert because this is covered by properties check
	        // if s is empty in this stage, no additionalProperties are allowed
	        // report.expect(s.length !== 0, 'E001', m);

	        // Instance property value must pass all schemas from s
	        idx2 = s.length;
	        while (idx2--) {
	            report.path.push(m);
	            exports.validate.call(this, report, s[idx2], propertyValue);
	            report.path.pop();
	        }
	    }
	};

	exports.validate = function (report, schema, json) {

	    report.commonErrorMessage = "JSON_OBJECT_VALIDATION_FAILED";

	    // check if schema is an object
	    var to = Utils.whatIs(schema);
	    if (to !== "object") {
	        report.addError("SCHEMA_NOT_AN_OBJECT", [to], null, schema.description);
	        return false;
	    }

	    // check if schema is empty, everything is valid against empty schema
	    var keys = Object.keys(schema);
	    if (keys.length === 0) {
	        return true;
	    }

	    // this method can be called recursively, so we need to remember our root
	    var isRoot = false;
	    if (!report.rootSchema) {
	        report.rootSchema = schema;
	        isRoot = true;
	    }

	    // follow schema.$ref keys
	    if (schema.$ref !== undefined) {
	        // avoid infinite loop with maxRefs
	        var maxRefs = 99;
	        while (schema.$ref && maxRefs > 0) {
	            if (!schema.__$refResolved) {
	                report.addError("REF_UNRESOLVED", [schema.$ref], null, schema.description);
	                break;
	            } else if (schema.__$refResolved === schema) {
	                break;
	            } else {
	                schema = schema.__$refResolved;
	                keys = Object.keys(schema);
	            }
	            maxRefs--;
	        }
	        if (maxRefs === 0) {
	            throw new Error("Circular dependency by $ref references!");
	        }
	    }

	    // type checking first
	    // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2
	    var jsonType = Utils.whatIs(json);
	    if (schema.type) {
	        if (typeof schema.type === "string") {
	            if (jsonType !== schema.type && (jsonType !== "integer" || schema.type !== "number")) {
	                report.addError("INVALID_TYPE", [schema.type, jsonType], null, schema.description);
	                if (this.options.breakOnFirstError) {
	                    return false;
	                }
	            }
	        } else {
	            if (schema.type.indexOf(jsonType) === -1 && (jsonType !== "integer" || schema.type.indexOf("number") === -1)) {
	                report.addError("INVALID_TYPE", [schema.type, jsonType], null, schema.description);
	                if (this.options.breakOnFirstError) {
	                    return false;
	                }
	            }
	        }
	    }

	    // now iterate all the keys in schema and execute validation methods
	    var idx = keys.length;
	    while (idx--) {
	        if (JsonValidators[keys[idx]]) {
	            JsonValidators[keys[idx]].call(this, report, schema, json);
	            if (report.errors.length && this.options.breakOnFirstError) { break; }
	        }
	    }

	    if (report.errors.length === 0 || this.options.breakOnFirstError === false) {
	        if (jsonType === "array") {
	            recurseArray.call(this, report, schema, json);
	        } else if (jsonType === "object") {
	            recurseObject.call(this, report, schema, json);
	        }
	    }

	    // we don't need the root pointer anymore
	    if (isRoot) {
	        report.rootSchema = undefined;
	    }

	    // return valid just to be able to break at some code points
	    return report.errors.length === 0;

	};


/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";

	var Report              = __webpack_require__(20);
	var SchemaCompilation   = __webpack_require__(27);
	var SchemaValidation    = __webpack_require__(28);
	var Utils               = __webpack_require__(22);

	function decodeJSONPointer(str) {
	    // http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07#section-3
	    return decodeURIComponent(str).replace(/~[0-1]/g, function (x) {
	        return x === "~1" ? "/" : "~";
	    });
	}

	function getRemotePath(uri) {
	    var io = uri.indexOf("#");
	    return io === -1 ? uri : uri.slice(0, io);
	}

	function getQueryPath(uri) {
	    var io = uri.indexOf("#");
	    var res = io === -1 ? undefined : uri.slice(io + 1);
	    // WARN: do not slice slash, #/ means take root and go down from it
	    // if (res && res[0] === "/") { res = res.slice(1); }
	    return res;
	}

	function findId(schema, id) {
	    // process only arrays and objects
	    if (typeof schema !== "object" || schema === null) {
	        return;
	    }

	    // no id means root so return itself
	    if (!id) {
	        return schema;
	    }

	    if (schema.id) {
	        if (schema.id === id || schema.id[0] === "#" && schema.id.substring(1) === id) {
	            return schema;
	        }
	    }

	    var idx, result;
	    if (Array.isArray(schema)) {
	        idx = schema.length;
	        while (idx--) {
	            result = findId(schema[idx], id);
	            if (result) { return result; }
	        }
	    } else {
	        var keys = Object.keys(schema);
	        idx = keys.length;
	        while (idx--) {
	            var k = keys[idx];
	            if (k.indexOf("__$") === 0) {
	                continue;
	            }
	            result = findId(schema[k], id);
	            if (result) { return result; }
	        }
	    }
	}

	exports.cacheSchemaByUri = function (uri, schema) {
	    var remotePath = getRemotePath(uri);
	    if (remotePath) {
	        this.cache[remotePath] = schema;
	    }
	};

	exports.removeFromCacheByUri = function (uri) {
	    var remotePath = getRemotePath(uri);
	    if (remotePath) {
	        delete this.cache[remotePath];
	    }
	};

	exports.checkCacheForUri = function (uri) {
	    var remotePath = getRemotePath(uri);
	    return remotePath ? this.cache[remotePath] != null : false;
	};

	exports.getSchema = function (report, schema) {
	    if (typeof schema === "object") {
	        schema = exports.getSchemaByReference.call(this, report, schema);
	    }
	    if (typeof schema === "string") {
	        schema = exports.getSchemaByUri.call(this, report, schema);
	    }
	    return schema;
	};

	exports.getSchemaByReference = function (report, key) {
	    var i = this.referenceCache.length;
	    while (i--) {
	        if (this.referenceCache[i][0] === key) {
	            return this.referenceCache[i][1];
	        }
	    }
	    // not found
	    var schema = Utils.cloneDeep(key);
	    this.referenceCache.push([key, schema]);
	    return schema;
	};

	exports.getSchemaByUri = function (report, uri, root) {
	    var remotePath = getRemotePath(uri),
	        queryPath = getQueryPath(uri),
	        result = remotePath ? this.cache[remotePath] : root;

	    if (result && remotePath) {
	        // we need to avoid compiling schemas in a recursive loop
	        var compileRemote = result !== root;
	        // now we need to compile and validate resolved schema (in case it's not already)
	        if (compileRemote) {

	            report.path.push(remotePath);

	            var remoteReport = new Report(report);
	            if (SchemaCompilation.compileSchema.call(this, remoteReport, result)) {
	                SchemaValidation.validateSchema.call(this, remoteReport, result);
	            }
	            var remoteReportIsValid = remoteReport.isValid();
	            if (!remoteReportIsValid) {
	                report.addError("REMOTE_NOT_VALID", [uri], remoteReport);
	            }

	            report.path.pop();

	            if (!remoteReportIsValid) {
	                return undefined;
	            }
	        }
	    }

	    if (result && queryPath) {
	        var parts = queryPath.split("/");
	        for (var idx = 0, lim = parts.length; result && idx < lim; idx++) {
	            var key = decodeJSONPointer(parts[idx]);
	            if (idx === 0) { // it's an id
	                result = findId(result, key);
	            } else { // it's a path behind id
	                result = result[key];
	            }
	        }
	    }

	    return result;
	};

	exports.getRemotePath = getRemotePath;


/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";

	var Report      = __webpack_require__(20);
	var SchemaCache = __webpack_require__(26);
	var Utils       = __webpack_require__(22);

	function mergeReference(scope, ref) {
	    if (Utils.isAbsoluteUri(ref)) {
	        return ref;
	    }

	    var joinedScope = scope.join(""),
	        isScopeAbsolute = Utils.isAbsoluteUri(joinedScope),
	        isScopeRelative = Utils.isRelativeUri(joinedScope),
	        isRefRelative = Utils.isRelativeUri(ref),
	        toRemove;

	    if (isScopeAbsolute && isRefRelative) {
	        toRemove = joinedScope.match(/\/[^\/]*$/);
	        if (toRemove) {
	            joinedScope = joinedScope.slice(0, toRemove.index + 1);
	        }
	    } else if (isScopeRelative && isRefRelative) {
	        joinedScope = "";
	    } else {
	        toRemove = joinedScope.match(/[^#/]+$/);
	        if (toRemove) {
	            joinedScope = joinedScope.slice(0, toRemove.index);
	        }
	    }

	    var res = joinedScope + ref;
	    res = res.replace(/##/, "#");
	    return res;
	}

	function collectReferences(obj, results, scope, path) {
	    results = results || [];
	    scope = scope || [];
	    path = path || [];

	    if (typeof obj !== "object" || obj === null) {
	        return results;
	    }

	    if (typeof obj.id === "string") {
	        scope.push(obj.id);
	    }

	    if (typeof obj.$ref === "string" && typeof obj.__$refResolved === "undefined") {
	        results.push({
	            ref: mergeReference(scope, obj.$ref),
	            key: "$ref",
	            obj: obj,
	            path: path.slice(0)
	        });
	    }
	    if (typeof obj.$schema === "string" && typeof obj.__$schemaResolved === "undefined") {
	        results.push({
	            ref: mergeReference(scope, obj.$schema),
	            key: "$schema",
	            obj: obj,
	            path: path.slice(0)
	        });
	    }

	    var idx;
	    if (Array.isArray(obj)) {
	        idx = obj.length;
	        while (idx--) {
	            path.push(idx.toString());
	            collectReferences(obj[idx], results, scope, path);
	            path.pop();
	        }
	    } else {
	        var keys = Object.keys(obj);
	        idx = keys.length;
	        while (idx--) {
	            // do not recurse through resolved references and other z-schema props
	            if (keys[idx].indexOf("__$") === 0) { continue; }
	            path.push(keys[idx]);
	            collectReferences(obj[keys[idx]], results, scope, path);
	            path.pop();
	        }
	    }

	    if (typeof obj.id === "string") {
	        scope.pop();
	    }

	    return results;
	}

	var compileArrayOfSchemasLoop = function (mainReport, arr) {
	    var idx = arr.length,
	        compiledCount = 0;

	    while (idx--) {

	        // try to compile each schema separately
	        var report = new Report(mainReport);
	        var isValid = exports.compileSchema.call(this, report, arr[idx]);
	        if (isValid) { compiledCount++; }

	        // copy errors to report
	        mainReport.errors = mainReport.errors.concat(report.errors);

	    }

	    return compiledCount;
	};

	function findId(arr, id) {
	    var idx = arr.length;
	    while (idx--) {
	        if (arr[idx].id === id) {
	            return arr[idx];
	        }
	    }
	    return null;
	}

	var compileArrayOfSchemas = function (report, arr) {

	    var compiled = 0,
	        lastLoopCompiled;

	    do {

	        // remove all UNRESOLVABLE_REFERENCE errors before compiling array again
	        var idx = report.errors.length;
	        while (idx--) {
	            if (report.errors[idx].code === "UNRESOLVABLE_REFERENCE") {
	                report.errors.splice(idx, 1);
	            }
	        }

	        // remember how many were compiled in the last loop
	        lastLoopCompiled = compiled;

	        // count how many are compiled now
	        compiled = compileArrayOfSchemasLoop.call(this, report, arr);

	        // fix __$missingReferences if possible
	        idx = arr.length;
	        while (idx--) {
	            var sch = arr[idx];
	            if (sch.__$missingReferences) {
	                var idx2 = sch.__$missingReferences.length;
	                while (idx2--) {
	                    var refObj = sch.__$missingReferences[idx2];
	                    var response = findId(arr, refObj.ref);
	                    if (response) {
	                        // this might create circular references
	                        refObj.obj["__" + refObj.key + "Resolved"] = response;
	                        // it's resolved now so delete it
	                        sch.__$missingReferences.splice(idx2, 1);
	                    }
	                }
	                if (sch.__$missingReferences.length === 0) {
	                    delete sch.__$missingReferences;
	                }
	            }
	        }

	        // keep repeating if not all compiled and at least one more was compiled in the last loop
	    } while (compiled !== arr.length && compiled !== lastLoopCompiled);

	    return report.isValid();

	};

	exports.compileSchema = function (report, schema) {

	    report.commonErrorMessage = "SCHEMA_COMPILATION_FAILED";

	    // if schema is a string, assume it's a uri
	    if (typeof schema === "string") {
	        var loadedSchema = SchemaCache.getSchemaByUri.call(this, report, schema);
	        if (!loadedSchema) {
	            report.addError("SCHEMA_NOT_REACHABLE", [schema]);
	            return false;
	        }
	        schema = loadedSchema;
	    }

	    // if schema is an array, assume it's an array of schemas
	    if (Array.isArray(schema)) {
	        return compileArrayOfSchemas.call(this, report, schema);
	    }

	    // if we have an id than it should be cached already (if this instance has compiled it)
	    if (schema.__$compiled && schema.id && SchemaCache.checkCacheForUri.call(this, schema.id) === false) {
	        schema.__$compiled = undefined;
	    }

	    // do not re-compile schemas
	    if (schema.__$compiled) {
	        return true;
	    }

	    if (schema.id && typeof schema.id === "string") {
	        // add this to our schemaCache (before compilation in case we have references including id)
	        SchemaCache.cacheSchemaByUri.call(this, schema.id, schema);
	    }

	    // this method can be called recursively, so we need to remember our root
	    var isRoot = false;
	    if (!report.rootSchema) {
	        report.rootSchema = schema;
	        isRoot = true;
	    }

	    // delete all __$missingReferences from previous compilation attempts
	    var isValidExceptReferences = report.isValid();
	    delete schema.__$missingReferences;

	    // collect all references that need to be resolved - $ref and $schema
	    var refs = collectReferences.call(this, schema),
	        idx = refs.length;
	    while (idx--) {
	        // resolve all the collected references into __xxxResolved pointer
	        var refObj = refs[idx];
	        var response = SchemaCache.getSchemaByUri.call(this, report, refObj.ref, schema);

	        // we can try to use custom schemaReader if available
	        if (!response) {
	            var schemaReader = this.getSchemaReader();
	            if (schemaReader) {
	                // it's supposed to return a valid schema
	                var s = schemaReader(refObj.ref);
	                if (s) {
	                    // it needs to have the id
	                    s.id = refObj.ref;
	                    // try to compile the schema
	                    var subreport = new Report(report);
	                    if (!exports.compileSchema.call(this, subreport, s)) {
	                        // copy errors to report
	                        report.errors = report.errors.concat(subreport.errors);
	                    } else {
	                        response = SchemaCache.getSchemaByUri.call(this, report, refObj.ref, schema);
	                    }
	                }
	            }
	        }

	        if (!response) {

	            var hasNotValid = report.hasError("REMOTE_NOT_VALID", [refObj.ref]);
	            var isAbsolute = Utils.isAbsoluteUri(refObj.ref);
	            var isDownloaded = false;
	            var ignoreUnresolvableRemotes = this.options.ignoreUnresolvableReferences === true;

	            if (isAbsolute) {
	                // we shouldn't add UNRESOLVABLE_REFERENCE for schemas we already have downloaded
	                // and set through setRemoteReference method
	                isDownloaded = SchemaCache.checkCacheForUri.call(this, refObj.ref);
	            }

	            if (hasNotValid) {
	                // already has REMOTE_NOT_VALID error for this one
	            } else if (ignoreUnresolvableRemotes && isAbsolute) {
	                // ignoreUnresolvableRemotes is on and remote isAbsolute
	            } else if (isDownloaded) {
	                // remote is downloaded, so no UNRESOLVABLE_REFERENCE
	            } else {
	                Array.prototype.push.apply(report.path, refObj.path);
	                report.addError("UNRESOLVABLE_REFERENCE", [refObj.ref]);
	                report.path = report.path.slice(0, -refObj.path.length);

	                // pusblish unresolved references out
	                if (isValidExceptReferences) {
	                    schema.__$missingReferences = schema.__$missingReferences || [];
	                    schema.__$missingReferences.push(refObj);
	                }
	            }
	        }
	        // this might create circular references
	        refObj.obj["__" + refObj.key + "Resolved"] = response;
	    }

	    var isValid = report.isValid();
	    if (isValid) {
	        schema.__$compiled = true;
	    } else {
	        if (schema.id && typeof schema.id === "string") {
	            // remove this schema from schemaCache because it failed to compile
	            SchemaCache.removeFromCacheByUri.call(this, schema.id);
	        }
	    }

	    // we don't need the root pointer anymore
	    if (isRoot) {
	        report.rootSchema = undefined;
	    }

	    return isValid;

	};


/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";

	var FormatValidators = __webpack_require__(23),
	    JsonValidation   = __webpack_require__(25),
	    Report           = __webpack_require__(20),
	    Utils            = __webpack_require__(22);

	var SchemaValidators = {
	    $ref: function (report, schema) {
	        // http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
	        // http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
	        if (typeof schema.$ref !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["$ref", "string"]);
	        }
	    },
	    $schema: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-core.html#rfc.section.6
	        if (typeof schema.$schema !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["$schema", "string"]);
	        }
	    },
	    multipleOf: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.1.1
	        if (typeof schema.multipleOf !== "number") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["multipleOf", "number"]);
	        } else if (schema.multipleOf <= 0) {
	            report.addError("KEYWORD_MUST_BE", ["multipleOf", "strictly greater than 0"]);
	        }
	    },
	    maximum: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.1
	        if (typeof schema.maximum !== "number") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["maximum", "number"]);
	        }
	    },
	    exclusiveMaximum: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.1
	        if (typeof schema.exclusiveMaximum !== "boolean") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMaximum", "boolean"]);
	        } else if (schema.maximum === undefined) {
	            report.addError("KEYWORD_DEPENDENCY", ["exclusiveMaximum", "maximum"]);
	        }
	    },
	    minimum: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.1
	        if (typeof schema.minimum !== "number") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["minimum", "number"]);
	        }
	    },
	    exclusiveMinimum: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.1
	        if (typeof schema.exclusiveMinimum !== "boolean") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMinimum", "boolean"]);
	        } else if (schema.minimum === undefined) {
	            report.addError("KEYWORD_DEPENDENCY", ["exclusiveMinimum", "minimum"]);
	        }
	    },
	    maxLength: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.1
	        if (Utils.whatIs(schema.maxLength) !== "integer") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["maxLength", "integer"]);
	        } else if (schema.maxLength < 0) {
	            report.addError("KEYWORD_MUST_BE", ["maxLength", "greater than, or equal to 0"]);
	        }
	    },
	    minLength: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.1
	        if (Utils.whatIs(schema.minLength) !== "integer") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["minLength", "integer"]);
	        } else if (schema.minLength < 0) {
	            report.addError("KEYWORD_MUST_BE", ["minLength", "greater than, or equal to 0"]);
	        }
	    },
	    pattern: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3.1
	        if (typeof schema.pattern !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["pattern", "string"]);
	        } else {
	            try {
	                RegExp(schema.pattern);
	            } catch (e) {
	                report.addError("KEYWORD_PATTERN", ["pattern", schema.pattern]);
	            }
	        }
	    },
	    additionalItems: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
	        var type = Utils.whatIs(schema.additionalItems);
	        if (type !== "boolean" && type !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["additionalItems", ["boolean", "object"]]);
	        } else if (type === "object") {
	            report.path.push("additionalItems");
	            exports.validateSchema.call(this, report, schema.additionalItems);
	            report.path.pop();
	        }
	    },
	    items: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
	        var type = Utils.whatIs(schema.items);

	        if (type === "object") {
	            report.path.push("items");
	            exports.validateSchema.call(this, report, schema.items);
	            report.path.pop();
	        } else if (type === "array") {
	            var idx = schema.items.length;
	            while (idx--) {
	                report.path.push("items");
	                report.path.push(idx.toString());
	                exports.validateSchema.call(this, report, schema.items[idx]);
	                report.path.pop();
	                report.path.pop();
	            }
	        } else {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["items", ["array", "object"]]);
	        }

	        // custom - strict mode
	        if (this.options.forceAdditional === true && schema.additionalItems === undefined && Array.isArray(schema.items)) {
	            report.addError("KEYWORD_UNDEFINED_STRICT", ["additionalItems"]);
	        }
	        // custome - assume defined false mode
	        if (this.options.assumeAdditional && schema.additionalItems === undefined && Array.isArray(schema.items)) {
	            schema.additionalItems = false;
	        }
	    },
	    maxItems: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.2.1
	        if (typeof schema.maxItems !== "number") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["maxItems", "integer"]);
	        } else if (schema.maxItems < 0) {
	            report.addError("KEYWORD_MUST_BE", ["maxItems", "greater than, or equal to 0"]);
	        }
	    },
	    minItems: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.1
	        if (Utils.whatIs(schema.minItems) !== "integer") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["minItems", "integer"]);
	        } else if (schema.minItems < 0) {
	            report.addError("KEYWORD_MUST_BE", ["minItems", "greater than, or equal to 0"]);
	        }
	    },
	    uniqueItems: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.4.1
	        if (typeof schema.uniqueItems !== "boolean") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["uniqueItems", "boolean"]);
	        }
	    },
	    maxProperties: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.1
	        if (Utils.whatIs(schema.maxProperties) !== "integer") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["maxProperties", "integer"]);
	        } else if (schema.maxProperties < 0) {
	            report.addError("KEYWORD_MUST_BE", ["maxProperties", "greater than, or equal to 0"]);
	        }
	    },
	    minProperties: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.1
	        if (Utils.whatIs(schema.minProperties) !== "integer") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["minProperties", "integer"]);
	        } else if (schema.minProperties < 0) {
	            report.addError("KEYWORD_MUST_BE", ["minProperties", "greater than, or equal to 0"]);
	        }
	    },
	    required: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.1
	        if (Utils.whatIs(schema.required) !== "array") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["required", "array"]);
	        } else if (schema.required.length === 0) {
	            report.addError("KEYWORD_MUST_BE", ["required", "an array with at least one element"]);
	        } else {
	            var idx = schema.required.length;
	            while (idx--) {
	                if (typeof schema.required[idx] !== "string") {
	                    report.addError("KEYWORD_VALUE_TYPE", ["required", "string"]);
	                }
	            }
	            if (Utils.isUniqueArray(schema.required) === false) {
	                report.addError("KEYWORD_MUST_BE", ["required", "an array with unique items"]);
	            }
	        }
	    },
	    additionalProperties: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
	        var type = Utils.whatIs(schema.additionalProperties);
	        if (type !== "boolean" && type !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["additionalProperties", ["boolean", "object"]]);
	        } else if (type === "object") {
	            report.path.push("additionalProperties");
	            exports.validateSchema.call(this, report, schema.additionalProperties);
	            report.path.pop();
	        }
	    },
	    properties: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
	        if (Utils.whatIs(schema.properties) !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["properties", "object"]);
	            return;
	        }

	        var keys = Object.keys(schema.properties),
	            idx = keys.length;
	        while (idx--) {
	            var key = keys[idx],
	                val = schema.properties[key];
	            report.path.push("properties");
	            report.path.push(key);
	            exports.validateSchema.call(this, report, val);
	            report.path.pop();
	            report.path.pop();
	        }

	        // custom - strict mode
	        if (this.options.forceAdditional === true && schema.additionalProperties === undefined) {
	            report.addError("KEYWORD_UNDEFINED_STRICT", ["additionalProperties"]);
	        }
	        // custome - assume defined false mode
	        if (this.options.assumeAdditional && schema.additionalProperties === undefined) {
	            schema.additionalProperties = false;
	        }
	        // custom - forceProperties
	        if (this.options.forceProperties === true && keys.length === 0) {
	            report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["properties"]);
	        }
	    },
	    patternProperties: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
	        if (Utils.whatIs(schema.patternProperties) !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["patternProperties", "object"]);
	            return;
	        }

	        var keys = Object.keys(schema.patternProperties),
	            idx = keys.length;
	        while (idx--) {
	            var key = keys[idx],
	                val = schema.patternProperties[key];
	            try {
	                RegExp(key);
	            } catch (e) {
	                report.addError("KEYWORD_PATTERN", ["patternProperties", key]);
	            }
	            report.path.push("patternProperties");
	            report.path.push(key.toString());
	            exports.validateSchema.call(this, report, val);
	            report.path.pop();
	            report.path.pop();
	        }

	        // custom - forceProperties
	        if (this.options.forceProperties === true && keys.length === 0) {
	            report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["patternProperties"]);
	        }
	    },
	    dependencies: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.1
	        if (Utils.whatIs(schema.dependencies) !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["dependencies", "object"]);
	        } else {
	            var keys = Object.keys(schema.dependencies),
	                idx = keys.length;
	            while (idx--) {
	                var schemaKey = keys[idx],
	                    schemaDependency = schema.dependencies[schemaKey],
	                    type = Utils.whatIs(schemaDependency);

	                if (type === "object") {
	                    report.path.push("dependencies");
	                    report.path.push(schemaKey);
	                    exports.validateSchema.call(this, report, schemaDependency);
	                    report.path.pop();
	                    report.path.pop();
	                } else if (type === "array") {
	                    var idx2 = schemaDependency.length;
	                    if (idx2 === 0) {
	                        report.addError("KEYWORD_MUST_BE", ["dependencies", "not empty array"]);
	                    }
	                    while (idx2--) {
	                        if (typeof schemaDependency[idx2] !== "string") {
	                            report.addError("KEYWORD_VALUE_TYPE", ["dependensices", "string"]);
	                        }
	                    }
	                    if (Utils.isUniqueArray(schemaDependency) === false) {
	                        report.addError("KEYWORD_MUST_BE", ["dependencies", "an array with unique items"]);
	                    }
	                } else {
	                    report.addError("KEYWORD_VALUE_TYPE", ["dependencies", "object or array"]);
	                }
	            }
	        }
	    },
	    enum: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.1
	        if (Array.isArray(schema.enum) === false) {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["enum", "array"]);
	        } else if (schema.enum.length === 0) {
	            report.addError("KEYWORD_MUST_BE", ["enum", "an array with at least one element"]);
	        } else if (Utils.isUniqueArray(schema.enum) === false) {
	            report.addError("KEYWORD_MUST_BE", ["enum", "an array with unique elements"]);
	        }
	    },
	    type: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.1
	        var primitiveTypes = ["array", "boolean", "integer", "number", "null", "object", "string"],
	            primitiveTypeStr = primitiveTypes.join(","),
	            isArray = Array.isArray(schema.type);

	        if (isArray) {
	            var idx = schema.type.length;
	            while (idx--) {
	                if (primitiveTypes.indexOf(schema.type[idx]) === -1) {
	                    report.addError("KEYWORD_TYPE_EXPECTED", ["type", primitiveTypeStr]);
	                }
	            }
	            if (Utils.isUniqueArray(schema.type) === false) {
	                report.addError("KEYWORD_MUST_BE", ["type", "an object with unique properties"]);
	            }
	        } else if (typeof schema.type === "string") {
	            if (primitiveTypes.indexOf(schema.type) === -1) {
	                report.addError("KEYWORD_TYPE_EXPECTED", ["type", primitiveTypeStr]);
	            }
	        } else {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["type", ["string", "array"]]);
	        }

	        if (this.options.noEmptyStrings === true) {
	            if (schema.type === "string" || isArray && schema.type.indexOf("string") !== -1) {
	                if (schema.minLength === undefined &&
	                    schema.enum === undefined &&
	                    schema.format === undefined) {

	                    schema.minLength = 1;
	                }
	            }
	        }
	        if (this.options.noEmptyArrays === true) {
	            if (schema.type === "array" || isArray && schema.type.indexOf("array") !== -1) {
	                if (schema.minItems === undefined) {
	                    schema.minItems = 1;
	                }
	            }
	        }
	        if (this.options.forceProperties === true) {
	            if (schema.type === "object" || isArray && schema.type.indexOf("object") !== -1) {
	                if (schema.properties === undefined && schema.patternProperties === undefined) {
	                    report.addError("KEYWORD_UNDEFINED_STRICT", ["properties"]);
	                }
	            }
	        }
	        if (this.options.forceItems === true) {
	            if (schema.type === "array" || isArray && schema.type.indexOf("array") !== -1) {
	                if (schema.items === undefined) {
	                    report.addError("KEYWORD_UNDEFINED_STRICT", ["items"]);
	                }
	            }
	        }
	        if (this.options.forceMinItems === true) {
	            if (schema.type === "array" || isArray && schema.type.indexOf("array") !== -1) {
	                if (schema.minItems === undefined) {
	                    report.addError("KEYWORD_UNDEFINED_STRICT", ["minItems"]);
	                }
	            }
	        }
	        if (this.options.forceMaxItems === true) {
	            if (schema.type === "array" || isArray && schema.type.indexOf("array") !== -1) {
	                if (schema.maxItems === undefined) {
	                    report.addError("KEYWORD_UNDEFINED_STRICT", ["maxItems"]);
	                }
	            }
	        }
	        if (this.options.forceMinLength === true) {
	            if (schema.type === "string" || isArray && schema.type.indexOf("string") !== -1) {
	                if (schema.minLength === undefined &&
	                    schema.format === undefined &&
	                    schema.enum === undefined &&
	                    schema.pattern === undefined) {
	                    report.addError("KEYWORD_UNDEFINED_STRICT", ["minLength"]);
	                }
	            }
	        }
	        if (this.options.forceMaxLength === true) {
	            if (schema.type === "string" || isArray && schema.type.indexOf("string") !== -1) {
	                if (schema.maxLength === undefined &&
	                    schema.format === undefined &&
	                    schema.enum === undefined &&
	                    schema.pattern === undefined) {
	                    report.addError("KEYWORD_UNDEFINED_STRICT", ["maxLength"]);
	                }
	            }
	        }
	    },
	    allOf: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.3.1
	        if (Array.isArray(schema.allOf) === false) {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["allOf", "array"]);
	        } else if (schema.allOf.length === 0) {
	            report.addError("KEYWORD_MUST_BE", ["allOf", "an array with at least one element"]);
	        } else {
	            var idx = schema.allOf.length;
	            while (idx--) {
	                report.path.push("allOf");
	                report.path.push(idx.toString());
	                exports.validateSchema.call(this, report, schema.allOf[idx]);
	                report.path.pop();
	                report.path.pop();
	            }
	        }
	    },
	    anyOf: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.4.1
	        if (Array.isArray(schema.anyOf) === false) {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["anyOf", "array"]);
	        } else if (schema.anyOf.length === 0) {
	            report.addError("KEYWORD_MUST_BE", ["anyOf", "an array with at least one element"]);
	        } else {
	            var idx = schema.anyOf.length;
	            while (idx--) {
	                report.path.push("anyOf");
	                report.path.push(idx.toString());
	                exports.validateSchema.call(this, report, schema.anyOf[idx]);
	                report.path.pop();
	                report.path.pop();
	            }
	        }
	    },
	    oneOf: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.5.1
	        if (Array.isArray(schema.oneOf) === false) {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["oneOf", "array"]);
	        } else if (schema.oneOf.length === 0) {
	            report.addError("KEYWORD_MUST_BE", ["oneOf", "an array with at least one element"]);
	        } else {
	            var idx = schema.oneOf.length;
	            while (idx--) {
	                report.path.push("oneOf");
	                report.path.push(idx.toString());
	                exports.validateSchema.call(this, report, schema.oneOf[idx]);
	                report.path.pop();
	                report.path.pop();
	            }
	        }
	    },
	    not: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.1
	        if (Utils.whatIs(schema.not) !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["not", "object"]);
	        } else {
	            report.path.push("not");
	            exports.validateSchema.call(this, report, schema.not);
	            report.path.pop();
	        }
	    },
	    definitions: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.1
	        if (Utils.whatIs(schema.definitions) !== "object") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["definitions", "object"]);
	        } else {
	            var keys = Object.keys(schema.definitions),
	                idx = keys.length;
	            while (idx--) {
	                var key = keys[idx],
	                    val = schema.definitions[key];
	                report.path.push("definitions");
	                report.path.push(key);
	                exports.validateSchema.call(this, report, val);
	                report.path.pop();
	                report.path.pop();
	            }
	        }
	    },
	    format: function (report, schema) {
	        if (typeof schema.format !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["format", "string"]);
	        } else {
	            if (FormatValidators[schema.format] === undefined && this.options.ignoreUnknownFormats !== true) {
	                report.addError("UNKNOWN_FORMAT", [schema.format]);
	            }
	        }
	    },
	    id: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-core.html#rfc.section.7.2
	        if (typeof schema.id !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["id", "string"]);
	        }
	    },
	    title: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1
	        if (typeof schema.title !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["title", "string"]);
	        }
	    },
	    description: function (report, schema) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1
	        if (typeof schema.description !== "string") {
	            report.addError("KEYWORD_TYPE_EXPECTED", ["description", "string"]);
	        }
	    },
	    "default": function (/* report, schema */) {
	        // http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.2
	        // There are no restrictions placed on the value of this keyword.
	    }
	};

	var validateArrayOfSchemas = function (report, arr) {
	    var idx = arr.length;
	    while (idx--) {
	        exports.validateSchema.call(this, report, arr[idx]);
	    }
	    return report.isValid();
	};

	exports.validateSchema = function (report, schema) {

	    report.commonErrorMessage = "SCHEMA_VALIDATION_FAILED";

	    // if schema is an array, assume it's an array of schemas
	    if (Array.isArray(schema)) {
	        return validateArrayOfSchemas.call(this, report, schema);
	    }

	    // do not revalidate schema that has already been validated once
	    if (schema.__$validated) {
	        return true;
	    }

	    // if $schema is present, this schema should validate against that $schema
	    var hasParentSchema = schema.$schema && schema.id !== schema.$schema;
	    if (hasParentSchema) {
	        if (schema.__$schemaResolved && schema.__$schemaResolved !== schema) {
	            var subReport = new Report(report);
	            var valid = JsonValidation.validate.call(this, subReport, schema.__$schemaResolved, schema);
	            if (valid === false) {
	                report.addError("PARENT_SCHEMA_VALIDATION_FAILED", null, subReport);
	            }
	        } else {
	            if (this.options.ignoreUnresolvableReferences !== true) {
	                report.addError("REF_UNRESOLVED", [schema.$schema]);
	            }
	        }
	    }

	    if (this.options.noTypeless === true) {
	        // issue #36 - inherit type to anyOf, oneOf, allOf if noTypeless is defined
	        if (schema.type !== undefined) {
	            var schemas = [];
	            if (Array.isArray(schema.anyOf)) { schemas = schemas.concat(schema.anyOf); }
	            if (Array.isArray(schema.oneOf)) { schemas = schemas.concat(schema.oneOf); }
	            if (Array.isArray(schema.allOf)) { schemas = schemas.concat(schema.allOf); }
	            schemas.forEach(function (sch) {
	                if (!sch.type) { sch.type = schema.type; }
	            });
	        }
	        // end issue #36
	        if (schema.enum === undefined &&
	            schema.type === undefined &&
	            schema.anyOf === undefined &&
	            schema.oneOf === undefined &&
	            schema.not === undefined &&
	            schema.$ref === undefined) {
	            report.addError("KEYWORD_UNDEFINED_STRICT", ["type"]);
	        }
	    }

	    var keys = Object.keys(schema),
	        idx = keys.length;
	    while (idx--) {
	        var key = keys[idx];
	        if (key.indexOf("__") === 0) { continue; }
	        if (SchemaValidators[key] !== undefined) {
	            SchemaValidators[key].call(this, report, schema);
	        } else if (!hasParentSchema) {
	            if (this.options.noExtraKeywords === true) {
	                report.addError("KEYWORD_UNEXPECTED", [key]);
	            }
	        }
	    }

	    if (this.options.pedanticCheck === true) {
	        if (schema.enum) {
	            // break recursion
	            var tmpSchema = Utils.clone(schema);
	            delete tmpSchema.enum;
	            delete tmpSchema.default;

	            report.path.push("enum");
	            idx = schema.enum.length;
	            while (idx--) {
	                report.path.push(idx.toString());
	                JsonValidation.validate.call(this, report, tmpSchema, schema.enum[idx]);
	                report.path.pop();
	            }
	            report.path.pop();
	        }

	        if (schema.default) {
	            report.path.push("default");
	            JsonValidation.validate.call(this, report, schema, schema.default);
	            report.path.pop();
	        }
	    }

	    var isValid = report.isValid();
	    if (isValid) {
	        schema.__$validated = true;
	    }
	    return isValid;
	};


/***/ },
/* 29 */
/***/ function(module, exports) {

	module.exports = {
		"id": "http://json-schema.org/draft-04/schema#",
		"$schema": "http://json-schema.org/draft-04/schema#",
		"description": "Core schema meta-schema",
		"definitions": {
			"schemaArray": {
				"type": "array",
				"minItems": 1,
				"items": {
					"$ref": "#"
				}
			},
			"positiveInteger": {
				"type": "integer",
				"minimum": 0
			},
			"positiveIntegerDefault0": {
				"allOf": [
					{
						"$ref": "#/definitions/positiveInteger"
					},
					{
						"default": 0
					}
				]
			},
			"simpleTypes": {
				"enum": [
					"array",
					"boolean",
					"integer",
					"null",
					"number",
					"object",
					"string"
				]
			},
			"stringArray": {
				"type": "array",
				"items": {
					"type": "string"
				},
				"minItems": 1,
				"uniqueItems": true
			}
		},
		"type": "object",
		"properties": {
			"id": {
				"type": "string",
				"format": "uri"
			},
			"$schema": {
				"type": "string",
				"format": "uri"
			},
			"title": {
				"type": "string"
			},
			"description": {
				"type": "string"
			},
			"default": {},
			"multipleOf": {
				"type": "number",
				"minimum": 0,
				"exclusiveMinimum": true
			},
			"maximum": {
				"type": "number"
			},
			"exclusiveMaximum": {
				"type": "boolean",
				"default": false
			},
			"minimum": {
				"type": "number"
			},
			"exclusiveMinimum": {
				"type": "boolean",
				"default": false
			},
			"maxLength": {
				"$ref": "#/definitions/positiveInteger"
			},
			"minLength": {
				"$ref": "#/definitions/positiveIntegerDefault0"
			},
			"pattern": {
				"type": "string",
				"format": "regex"
			},
			"additionalItems": {
				"anyOf": [
					{
						"type": "boolean"
					},
					{
						"$ref": "#"
					}
				],
				"default": {}
			},
			"items": {
				"anyOf": [
					{
						"$ref": "#"
					},
					{
						"$ref": "#/definitions/schemaArray"
					}
				],
				"default": {}
			},
			"maxItems": {
				"$ref": "#/definitions/positiveInteger"
			},
			"minItems": {
				"$ref": "#/definitions/positiveIntegerDefault0"
			},
			"uniqueItems": {
				"type": "boolean",
				"default": false
			},
			"maxProperties": {
				"$ref": "#/definitions/positiveInteger"
			},
			"minProperties": {
				"$ref": "#/definitions/positiveIntegerDefault0"
			},
			"required": {
				"$ref": "#/definitions/stringArray"
			},
			"additionalProperties": {
				"anyOf": [
					{
						"type": "boolean"
					},
					{
						"$ref": "#"
					}
				],
				"default": {}
			},
			"definitions": {
				"type": "object",
				"additionalProperties": {
					"$ref": "#"
				},
				"default": {}
			},
			"properties": {
				"type": "object",
				"additionalProperties": {
					"$ref": "#"
				},
				"default": {}
			},
			"patternProperties": {
				"type": "object",
				"additionalProperties": {
					"$ref": "#"
				},
				"default": {}
			},
			"dependencies": {
				"type": "object",
				"additionalProperties": {
					"anyOf": [
						{
							"$ref": "#"
						},
						{
							"$ref": "#/definitions/stringArray"
						}
					]
				}
			},
			"enum": {
				"type": "array",
				"minItems": 1,
				"uniqueItems": true
			},
			"type": {
				"anyOf": [
					{
						"$ref": "#/definitions/simpleTypes"
					},
					{
						"type": "array",
						"items": {
							"$ref": "#/definitions/simpleTypes"
						},
						"minItems": 1,
						"uniqueItems": true
					}
				]
			},
			"format": {
				"type": "string"
			},
			"allOf": {
				"$ref": "#/definitions/schemaArray"
			},
			"anyOf": {
				"$ref": "#/definitions/schemaArray"
			},
			"oneOf": {
				"$ref": "#/definitions/schemaArray"
			},
			"not": {
				"$ref": "#"
			}
		},
		"dependencies": {
			"exclusiveMaximum": [
				"maximum"
			],
			"exclusiveMinimum": [
				"minimum"
			]
		},
		"default": {}
	};

/***/ },
/* 30 */
/***/ function(module, exports) {

	module.exports = {
		"$schema": "http://json-schema.org/draft-04/hyper-schema#",
		"id": "http://json-schema.org/draft-04/hyper-schema#",
		"title": "JSON Hyper-Schema",
		"allOf": [
			{
				"$ref": "http://json-schema.org/draft-04/schema#"
			}
		],
		"properties": {
			"additionalItems": {
				"anyOf": [
					{
						"type": "boolean"
					},
					{
						"$ref": "#"
					}
				]
			},
			"additionalProperties": {
				"anyOf": [
					{
						"type": "boolean"
					},
					{
						"$ref": "#"
					}
				]
			},
			"dependencies": {
				"additionalProperties": {
					"anyOf": [
						{
							"$ref": "#"
						},
						{
							"type": "array"
						}
					]
				}
			},
			"items": {
				"anyOf": [
					{
						"$ref": "#"
					},
					{
						"$ref": "#/definitions/schemaArray"
					}
				]
			},
			"definitions": {
				"additionalProperties": {
					"$ref": "#"
				}
			},
			"patternProperties": {
				"additionalProperties": {
					"$ref": "#"
				}
			},
			"properties": {
				"additionalProperties": {
					"$ref": "#"
				}
			},
			"allOf": {
				"$ref": "#/definitions/schemaArray"
			},
			"anyOf": {
				"$ref": "#/definitions/schemaArray"
			},
			"oneOf": {
				"$ref": "#/definitions/schemaArray"
			},
			"not": {
				"$ref": "#"
			},
			"links": {
				"type": "array",
				"items": {
					"$ref": "#/definitions/linkDescription"
				}
			},
			"fragmentResolution": {
				"type": "string"
			},
			"media": {
				"type": "object",
				"properties": {
					"type": {
						"description": "A media type, as described in RFC 2046",
						"type": "string"
					},
					"binaryEncoding": {
						"description": "A content encoding scheme, as described in RFC 2045",
						"type": "string"
					}
				}
			},
			"pathStart": {
				"description": "Instances' URIs must start with this value for this schema to apply to them",
				"type": "string",
				"format": "uri"
			}
		},
		"definitions": {
			"schemaArray": {
				"type": "array",
				"items": {
					"$ref": "#"
				}
			},
			"linkDescription": {
				"title": "Link Description Object",
				"type": "object",
				"required": [
					"href",
					"rel"
				],
				"properties": {
					"href": {
						"description": "a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing",
						"type": "string"
					},
					"rel": {
						"description": "relation to the target resource of the link",
						"type": "string"
					},
					"title": {
						"description": "a title for the link",
						"type": "string"
					},
					"targetSchema": {
						"description": "JSON Schema describing the link target",
						"$ref": "#"
					},
					"mediaType": {
						"description": "media type (as defined by RFC 2046) describing the link target",
						"type": "string"
					},
					"method": {
						"description": "method for requesting the target of the link (e.g. for HTTP this might be \"GET\" or \"DELETE\")",
						"type": "string"
					},
					"encType": {
						"description": "The media type in which to submit data along with the request",
						"type": "string",
						"default": "application/json"
					},
					"schema": {
						"description": "Schema describing the data to submit along with the request",
						"$ref": "#"
					}
				}
			}
		}
	};

/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {

	var JsonSchemaCompatability = (function () {

		function convert3to4Type(types, always) {
			if (!Array.isArray(types)) {
				types = [types];
			}
			var needsReplacement = !!always;
			var result = [];
			for (var i = 0; i < types.length; i++) {
				var entry = types[i];
				if (typeof entry === 'object') {
					result.push(entry);
					needsReplacement = true;
				} else {
					result.push({"type": entry});
				}
			}
			return needsReplacement && result;
		}

		function convert3to4(obj) {
			// Old-style "type"
			if (obj.type) {
				if (typeof obj.type !== 'string') {
					var anyOf = convert3to4Type(obj.type);
					if (anyOf) {
						obj.anyOf = anyOf;
						delete obj.type;
					}
				}
				else if (obj.type == 'any') {
					delete obj.type;
				}
			}
			if (obj['extends']) {
				var allOf = obj['extends'];
				if (!Array.isArray(allOf)) {
					allOf = [allOf];
				}
				obj.allOf = allOf;
				delete obj['extends'];
			}
			if (obj.disallow) {
				if (typeof obj.disallow === 'string') {
					obj.not = {"type": obj.disallow};
				} else {
					obj.not = {"anyOf": convert3to4Type(obj.disallow, true)};
				}
				delete obj.disallow;
			}

			// Object concerns
			if (obj.properties) {
				var required = Array.isArray(obj.required) ? obj.required : [];
				for (var key in obj.properties) {
					var subSchema = obj.properties[key];
					if (subSchema && typeof subSchema.required === 'boolean') {
						if (subSchema.required) {
							required.push(key);
						}
						delete subSchema.required;
					}
				}
				if (required.length) {
					obj.required = required;
				}
			}
			if (obj.dependencies) {
				for (var key in obj.dependencies) {
					if (typeof obj.dependencies[key] === 'string') {
						obj.dependencies[key] = [obj.dependencies[key]];
					}
				}
			}
			// This is safe as long as we process our children *after* we collect their "required" properties
			// - otherwise, they'd delete their "required" booleans before we got a chance to see them
			if (typeof obj.required === 'boolean') {
				delete obj.required;
			}
			
			// Numeric concerns
			if (typeof obj.divisibleBy !== 'undefined') {
				obj.multipleOf = obj.divisibleBy;
				delete obj.divisibleBy;
			}
			
			// This MUST happen at the end of the function, otherwise it'll screw up "required" collection
			for (var key in obj) {
				if (key === "properties" || key === "patternProperties" || key === "dependencies") {
					for (var subKey in obj[key]) {
						obj[key][subKey] = convert3to4(obj[key][subKey]);
					}
				} else if (key !== "enum") {
					if (Array.isArray(obj[key])) {
						for (var i = 0; i < obj[key].length; i++) {
							obj[key][i] = convert3to4(obj[key][i]);
						}
					} else if (typeof obj[key] === "object") {
						obj[key] = convert3to4(obj[key]);
					}
				}
			}
			return obj;
		}

		var api = {
			v4: convert3to4
		};
		
		if (true) {
			module.exports = api;
		}
		return api;
	})();

/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;/*jshint node:true*/

	if (false) {
	    var define = require('amdefine')(module);
	}

	!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
	    "use strict";

	    var statusCodes = __webpack_require__(33),
	        statusCodesToPhrases = {},
	        statusPhrasesToCodes = {},
	        methods = __webpack_require__(34),
	        headers = __webpack_require__(35),
	        relations = __webpack_require__(36);

	    statusCodes.forEach(function(item) {
	        var code = parseInt(item.code, 10),
	            phrase;

	        // Ignore codes for classes
	        if (code.toString() !== item.code) {
	            return;
	        }

	        phrase = item.phrase.toUpperCase().replace(/[^A-Z]/g, '_');

	        statusCodesToPhrases[code] = item.phrase;
	        statusPhrasesToCodes[phrase] = item.code;
	    });

	    return {
	        statusCodes: statusCodes,
	        statusCodesToPhrases: statusCodesToPhrases,
	        statusPhrasesToCodes: statusPhrasesToCodes,
	        methods: methods,
	        headers: headers,
	        relations: relations
	    };
	}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ },
/* 33 */
/***/ function(module, exports) {

	module.exports = [
		{
			"code": "1xx",
			"phrase": "**Informational**",
			"description": "\"indicates an interim response for communicating connection status or request progress prior to completing the requested action and sending a final response.\" ~ [sure](http://www.urbandictionary.com/define.php?term=sure)",
			"spec_title": "RFC7231#6.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.2"
		},
		{
			"code": "100",
			"phrase": "Continue",
			"description": "\"indicates that the initial part of a request has been received and has not yet been rejected by the server.\"",
			"spec_title": "RFC7231#6.2.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.2.1"
		},
		{
			"code": "101",
			"phrase": "Switching Protocols",
			"description": "\"indicates that the server understands and is willing to comply with the client's request, via the Upgrade header field, for a change in the application protocol being used on this connection.\"",
			"spec_title": "RFC7231#6.2.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.2.2"
		},
		{
			"code": "2xx",
			"phrase": "**Successful**",
			"description": "\"indicates that the client's request was successfully received, understood, and accepted.\" ~ [cool](https://twitter.com/DanaDanger/status/183316183494311936)",
			"spec_title": "RFC7231#6.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3"
		},
		{
			"code": "200",
			"phrase": "OK",
			"description": "\"indicates that the request has succeeded.\"",
			"spec_title": "RFC7231#6.3.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.1"
		},
		{
			"code": "201",
			"phrase": "Created",
			"description": "\"indicates that the request has been fulfilled and has resulted in one or more new resources being created.\"",
			"spec_title": "RFC7231#6.3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.2"
		},
		{
			"code": "202",
			"phrase": "Accepted",
			"description": "\"indicates that the request has been accepted for processing, but the processing has not been completed.\"",
			"spec_title": "RFC7231#6.3.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.3"
		},
		{
			"code": "203",
			"phrase": "Non-Authoritative Information",
			"description": "\"indicates that the request was successful but the enclosed payload has been modified from that of the origin server's 200 (OK) response by a transforming proxy.\"",
			"spec_title": "RFC7231#6.3.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.4"
		},
		{
			"code": "204",
			"phrase": "No Content",
			"description": "\"indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.\"",
			"spec_title": "RFC7231#6.3.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.5"
		},
		{
			"code": "205",
			"phrase": "Reset Content",
			"description": "\"indicates that the server has fulfilled the request and desires that the user agent reset the \"document view\", which caused the request to be sent, to its original state as received from the origin server.\"",
			"spec_title": "RFC7231#6.3.6",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.6"
		},
		{
			"code": "206",
			"phrase": "Partial Content",
			"description": "\"indicates that the server is successfully fulfilling a range request for the target resource by transferring one or more parts of the selected representation that correspond to the satisfiable ranges found in the requests's Range header field.\"",
			"spec_title": "RFC7233#4.1",
			"spec_href": "http://tools.ietf.org/html/rfc7233#section-4.1"
		},
		{
			"code": "3xx",
			"phrase": "**Redirection**",
			"description": "\"indicates that further action needs to be taken by the user agent in order to fulfill the request.\" ~ [ask that dude over there](https://twitter.com/DanaDanger/status/183316183494311936)",
			"spec_title": "RFC7231#6.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4"
		},
		{
			"code": "300",
			"phrase": "Multiple Choices",
			"description": "\"indicates that the target resource has more than one representation, each with its own more specific identifier, and information about the alternatives is being provided so that the user (or user agent) can select a preferred representation by redirecting its request to one or more of those identifiers.\"",
			"spec_title": "RFC7231#6.4.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4.1"
		},
		{
			"code": "301",
			"phrase": "Moved Permanently",
			"description": "\"indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.\"",
			"spec_title": "RFC7231#6.4.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4.2"
		},
		{
			"code": "302",
			"phrase": "Found",
			"description": "\"indicates that the target resource resides temporarily under a different URI.\"",
			"spec_title": "RFC7231#6.4.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4.3"
		},
		{
			"code": "303",
			"phrase": "See Other",
			"description": "\"indicates that the server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field, that is intended to provide an indirect response to the original request.\"",
			"spec_title": "RFC7231#6.4.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4.4"
		},
		{
			"code": "304",
			"phrase": "Not Modified",
			"description": "\"indicates that a conditional GET request has been received and would have resulted in a 200 (OK) response if it were not for the fact that the condition has evaluated to false.\"",
			"spec_title": "RFC7232#4.1",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-4.1"
		},
		{
			"code": "305",
			"phrase": "Use Proxy",
			"description": "*deprecated*",
			"spec_title": "RFC7231#6.4.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4.5"
		},
		{
			"code": "307",
			"phrase": "Temporary Redirect",
			"description": "\"indicates that the target resource resides temporarily under a different URI and the user agent MUST NOT change the request method if it performs an automatic redirection to that URI.\"",
			"spec_title": "RFC7231#6.4.7",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.4.7"
		},
		{
			"code": "4xx",
			"phrase": "**Client Error**",
			"description": "\"indicates that the client seems to have erred.\" ~ [*you* fucked up](https://twitter.com/DanaDanger/status/183316183494311936)",
			"spec_title": "RFC7231#6.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5"
		},
		{
			"code": "400",
			"phrase": "Bad Request",
			"description": "\"indicates that the server cannot or will not process the request because the received syntax is invalid, nonsensical, or exceeds some limitation on what the server is willing to process.\"",
			"spec_title": "RFC7231#6.5.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.1"
		},
		{
			"code": "401",
			"phrase": "Unauthorized",
			"description": "\"indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.\"",
			"spec_title": "RFC7235#6.3.1",
			"spec_href": "http://tools.ietf.org/html/rfc7235#section-3.1"
		},
		{
			"code": "402",
			"phrase": "Payment Required",
			"description": "*reserved*",
			"spec_title": "RFC7231#6.5.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.2"
		},
		{
			"code": "403",
			"phrase": "Forbidden",
			"description": "\"indicates that the server understood the request but refuses to authorize it.\"",
			"spec_title": "RFC7231#6.5.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.3"
		},
		{
			"code": "404",
			"phrase": "Not Found",
			"description": "\"indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.\"",
			"spec_title": "RFC7231#6.5.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.4"
		},
		{
			"code": "405",
			"phrase": "Method Not Allowed",
			"description": "\"indicates that the method specified in the request-line is known by the origin server but not supported by the target resource.\"",
			"spec_title": "RFC7231#6.5.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.5"
		},
		{
			"code": "406",
			"phrase": "Not Acceptable",
			"description": "\"indicates that the target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request, and the server is unwilling to supply a default representation.\"",
			"spec_title": "RFC7231#6.5.6",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.6"
		},
		{
			"code": "407",
			"phrase": "Proxy Authentication Required",
			"description": "\"is similar to 401 (Unauthorized), but indicates that the client needs to authenticate itself in order to use a proxy.\"",
			"spec_title": "RFC7231#6.3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.3.2"
		},
		{
			"code": "408",
			"phrase": "Request Timeout",
			"description": "\"indicates that the server did not receive a complete request message within the time that it was prepared to wait.\"",
			"spec_title": "RFC7231#6.5.7",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.7"
		},
		{
			"code": "409",
			"phrase": "Conflict",
			"description": "\"indicates that the request could not be completed due to a conflict with the current state of the resource.\"",
			"spec_title": "RFC7231#6.5.8",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.8"
		},
		{
			"code": "410",
			"phrase": "Gone",
			"description": "\"indicates that access to the target resource is no longer available at the origin server and that this condition is likely to be permanent.\"",
			"spec_title": "RFC7231#6.5.9",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.9"
		},
		{
			"code": "411",
			"phrase": "Length Required",
			"description": "\"indicates that the server refuses to accept the request without a defined Content-Length.\"",
			"spec_title": "RFC7231#6.5.10",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.10"
		},
		{
			"code": "412",
			"phrase": "Precondition Failed",
			"description": "\"indicates that one or more preconditions given in the request header fields evaluated to false when tested on the server.\"",
			"spec_title": "RFC7232#4.2",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-4.2"
		},
		{
			"code": "413",
			"phrase": "Payload Too Large",
			"description": "\"indicates that the server is refusing to process a request because the request payload is larger than the server is willing or able to process.\"",
			"spec_title": "RFC7231#6.5.11",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.11"
		},
		{
			"code": "414",
			"phrase": "URI Too Long",
			"description": "\"indicates that the server is refusing to service the request because the request-target is longer than the server is willing to interpret.\"",
			"spec_title": "RFC7231#6.5.12",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.12"
		},
		{
			"code": "415",
			"phrase": "Unsupported Media Type",
			"description": "\"indicates that the origin server is refusing to service the request because the payload is in a format not supported by the target resource for this method.\"",
			"spec_title": "RFC7231#6.5.13",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.13"
		},
		{
			"code": "416",
			"phrase": "Range Not Satisfiable",
			"description": "\"indicates that none of the ranges in the request's Range header field overlap the current extent of the selected resource or that the set of ranges requested has been rejected due to invalid ranges or an excessive request of small or overlapping ranges.\"",
			"spec_title": "RFC7233#4.4",
			"spec_href": "http://tools.ietf.org/html/rfc7233#section-4.4"
		},
		{
			"code": "417",
			"phrase": "Expectation Failed",
			"description": "\"indicates that the expectation given in the request's Expect header field could not be met by at least one of the inbound servers.\"",
			"spec_title": "RFC7231#6.5.14",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.14"
		},
		{
			"code": "426",
			"phrase": "Upgrade Required",
			"description": "\"indicates that the server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.\"",
			"spec_title": "RFC7231#6.5.15",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.5.15"
		},
		{
			"code": "5xx",
			"phrase": "**Server Error**",
			"description": "\"indicates that the server is aware that it has erred or is incapable of performing the requested method.\" ~ [*we* fucked up](https://twitter.com/DanaDanger/status/183316183494311936)",
			"spec_title": "RFC7231#6.6",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6"
		},
		{
			"code": "500",
			"phrase": "Internal Server Error",
			"description": "\"indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.\"",
			"spec_title": "RFC7231#6.6.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6.1"
		},
		{
			"code": "501",
			"phrase": "Not Implemented",
			"description": "\"indicates that the server does not support the functionality required to fulfill the request.\"",
			"spec_title": "RFC7231#6.6.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6.2"
		},
		{
			"code": "502",
			"phrase": "Bad Gateway",
			"description": "\"indicates that the server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request.\"",
			"spec_title": "RFC7231#6.6.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6.3"
		},
		{
			"code": "503",
			"phrase": "Service Unavailable",
			"description": "\"indicates that the server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay.\"",
			"spec_title": "RFC7231#6.6.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6.4"
		},
		{
			"code": "504",
			"phrase": "Gateway Time-out",
			"description": "\"indicates that the server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request.\"",
			"spec_title": "RFC7231#6.6.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6.5"
		},
		{
			"code": "505",
			"phrase": "HTTP Version Not Supported",
			"description": "\"indicates that the server does not support, or refuses to support, the protocol version that was used in the request message.\"",
			"spec_title": "RFC7231#6.6.6",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-6.6.6"
		},
		{
			"code": "102",
			"phrase": "Processing",
			"description": "\"is an interim response used to inform the client that the server has accepted the complete request, but has not yet completed it.\"",
			"spec_title": "RFC5218#10.1",
			"spec_href": "http://tools.ietf.org/html/rfc2518#section-10.1"
		},
		{
			"code": "207",
			"phrase": "Multi-Status",
			"description": "\"provides status for multiple independent operations.\"",
			"spec_title": "RFC5218#10.2",
			"spec_href": "http://tools.ietf.org/html/rfc2518#section-10.2"
		},
		{
			"code": "226",
			"phrase": "IM Used",
			"description": "\"The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.\"",
			"spec_title": "RFC3229#10.4.1",
			"spec_href": "http://tools.ietf.org/html/rfc3229#section-10.4.1"
		},
		{
			"code": "308",
			"phrase": "Permanent Redirect",
			"description": "\"The target resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. [...] This status code is similar to 301 Moved Permanently (Section 7.3.2 of rfc7231), except that it does not allow rewriting the request method from POST to GET.\"",
			"spec_title": "RFC7238",
			"spec_href": "http://tools.ietf.org/html/rfc7238"
		},
		{
			"code": "422",
			"phrase": "Unprocessable Entity",
			"description": "\"means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions.\"",
			"spec_title": "RFC5218#10.3",
			"spec_href": "http://tools.ietf.org/html/rfc2518#section-10.3"
		},
		{
			"code": "423",
			"phrase": "Locked",
			"description": "\"means the source or destination resource of a method is locked.\"",
			"spec_title": "RFC5218#10.4",
			"spec_href": "http://tools.ietf.org/html/rfc2518#section-10.4"
		},
		{
			"code": "424",
			"phrase": "Failed Dependency",
			"description": "\"means that the method could not be performed on the resource because the requested action depended on another action and that action failed.\"",
			"spec_title": "RFC5218#10.5",
			"spec_href": "http://tools.ietf.org/html/rfc2518#section-10.5"
		},
		{
			"code": "428",
			"phrase": "Precondition Required",
			"description": "\"indicates that the origin server requires the request to be conditional.\"",
			"spec_title": "RFC6585#3",
			"spec_href": "http://tools.ietf.org/html/rfc6585#section-3"
		},
		{
			"code": "429",
			"phrase": "Too Many Requests",
			"description": "\"indicates that the user has sent too many requests in a given amount of time (\"rate limiting\").\"",
			"spec_title": "RFC6585#4",
			"spec_href": "http://tools.ietf.org/html/rfc6585#section-4"
		},
		{
			"code": "431",
			"phrase": "Request Header Fields Too Large",
			"description": "\"indicates that the server is unwilling to process the request because its header fields are too large.\"",
			"spec_title": "RFC6585#5",
			"spec_href": "http://tools.ietf.org/html/rfc6585#section-5"
		},
		{
			"code": "451",
			"phrase": "Unavailable For Legal Reasons",
			"description": "\"This status code indicates that the server is denying access to the resource in response to a legal demand.\"",
			"spec_title": "draft-tbray-http-legally-restricted-status",
			"spec_href": "http://tools.ietf.org/html/draft-tbray-http-legally-restricted-status"
		},
		{
			"code": "506",
			"phrase": "Variant Also Negotiates",
			"description": "\"indicates that the server has an internal configuration error: the chosen variant resource is configured to engage in transparent content negotiation itself, and is therefore not a proper end point in the negotiation process.\"",
			"spec_title": "RFC2295#8.1",
			"spec_href": "http://tools.ietf.org/html/rfc2295#section-8.1"
		},
		{
			"code": "507",
			"phrase": "Insufficient Storage",
			"description": "\"means the method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request.\"",
			"spec_title": "RFC5218#10.6",
			"spec_href": "http://tools.ietf.org/html/rfc2518#section-10.6"
		},
		{
			"code": "511",
			"phrase": "Network Authentication Required",
			"description": "\"indicates that the client needs to authenticate to gain network access.\"",
			"spec_title": "RFC6585#6",
			"spec_href": "http://tools.ietf.org/html/rfc6585#section-6"
		},
		{
			"code": "7xx",
			"phrase": "**Developer Error**",
			"description": "[err](http://www.urbandictionary.com/define.php?term=err)",
			"spec_title": "7xx-rfc",
			"spec_href": "http://documentup.com/joho/7XX-rfc"
		}
	];

/***/ },
/* 34 */
/***/ function(module, exports) {

	module.exports = [
		{
			"method": "CONNECT",
			"description": "\"requests that the recipient establish a tunnel to the destination origin server identified by the request-target and, if successful, thereafter restrict its behavior to blind forwarding of packets, in both directions, until the connection is closed.\"",
			"safe": true,
			"idempotent": true,
			"cacheable": false,
			"spec_title": "RFC7231#4.3.6",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.6"
		},
		{
			"method": "DELETE",
			"description": "\"requests that the origin server remove the association between the target resource and its current functionality.\"",
			"safe": false,
			"idempotent": true,
			"cacheable": false,
			"spec_title": "RFC7231#4.3.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.5"
		},
		{
			"method": "GET",
			"description": "\"requests transfer of a current selected representation for the target resource.\"",
			"safe": true,
			"idempotent": true,
			"cacheable": true,
			"spec_title": "RFC7231#4.3.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.1"
		},
		{
			"method": "HEAD",
			"description": "\"is identical to GET except that the server MUST NOT send a message body in the response (i.e., the response terminates at the end of the header block).\"",
			"safe": true,
			"idempotent": true,
			"cacheable": true,
			"spec_title": "RFC7231#4.3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.2"
		},
		{
			"method": "OPTIONS",
			"description": "\"requests information about the communication options available on the request/response chain identified by the effective request URI.\"",
			"safe": true,
			"idempotent": true,
			"cacheable": false,
			"spec_title": "RFC7231#4.3.7",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.7"
		},
		{
			"method": "POST",
			"description": "\"requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.\"",
			"safe": false,
			"idempotent": false,
			"cacheable": false,
			"spec_title": "RFC7231#4.3.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.3"
		},
		{
			"method": "PUT",
			"description": "\"requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.\"",
			"safe": false,
			"idempotent": true,
			"cacheable": false,
			"spec_title": "RFC7231#4.3.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.4"
		},
		{
			"method": "TRACE",
			"description": "\"is used to invoke a remote, application-layer loopback of the request message.\"",
			"safe": true,
			"idempotent": true,
			"cacheable": false,
			"spec_title": "RFC7231#4.3.8",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-4.3.8"
		},
		{
			"method": "ACL",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3744#8.1",
			"spec_href": "http://tools.ietf.org/html/rfc3744#section-8.1"
		},
		{
			"method": "BASELINE-CONTROL",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#12.6",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-12.6"
		},
		{
			"method": "BIND",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC5842#4",
			"spec_href": "http://tools.ietf.org/html/rfc5842#section-4"
		},
		{
			"method": "CHECKIN",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#4.4",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-4.4"
		},
		{
			"method": "CHECKOUT",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#4.3",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-4.3"
		},
		{
			"method": "COPY",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4918#9.8",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.8"
		},
		{
			"method": "LABEL",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#8.2",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-8.2"
		},
		{
			"method": "LINK",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC2068#19.6.1.2",
			"spec_href": "http://tools.ietf.org/html/rfc2068#section-19.6.1.2"
		},
		{
			"method": "LOCK",
			"description": "",
			"safe": false,
			"idempotent": false,
			"cacheable": "",
			"spec_title": "RFC4918#9.10",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.10"
		},
		{
			"method": "MERGE",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#11.2",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-11.2"
		},
		{
			"method": "MKACTIVITY",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#13.5",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-13.5"
		},
		{
			"method": "MKCALENDAR",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4791#5.3.1",
			"spec_href": "http://tools.ietf.org/html/rfc4791#section-5.3.1"
		},
		{
			"method": "MKCOL",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4918#9.3",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.3"
		},
		{
			"method": "MKREDIRECTREF",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4437#6",
			"spec_href": "http://tools.ietf.org/html/rfc4437#section-6"
		},
		{
			"method": "MKWORKSPACE",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#6.3",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-6.3"
		},
		{
			"method": "MOVE",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4918#9.9",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.9"
		},
		{
			"method": "ORDERPATCH",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3648#7",
			"spec_href": "http://tools.ietf.org/html/rfc3648#section-7"
		},
		{
			"method": "PATCH",
			"description": "\"requests that a set of changes described in the request entity be applied to the resource identified by the Request-URI.\"",
			"safe": false,
			"idempotent": false,
			"cacheable": false,
			"spec_title": "RFC5789",
			"spec_href": "http://tools.ietf.org/html/rfc5789#section-2"
		},
		{
			"method": "PROPFIND",
			"description": "",
			"safe": true,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4918#9.1",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.1"
		},
		{
			"method": "PROPPATCH",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4918#9.2",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.2"
		},
		{
			"method": "REBIND",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC5842#6",
			"spec_href": "http://tools.ietf.org/html/rfc5842#section-6"
		},
		{
			"method": "REPORT",
			"description": "",
			"safe": true,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#3.6",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-3.6"
		},
		{
			"method": "SEARCH",
			"description": "",
			"safe": true,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC5323#2",
			"spec_href": "http://tools.ietf.org/html/rfc5323#section-2"
		},
		{
			"method": "UNBIND",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC5842#5",
			"spec_href": "http://tools.ietf.org/html/rfc5842#section-5"
		},
		{
			"method": "UNCHECKOUT",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#4.5",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-4.5"
		},
		{
			"method": "UNLINK",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC2068#19.6.1.3",
			"spec_href": "http://tools.ietf.org/html/rfc2068#section-19.6.1.3"
		},
		{
			"method": "UNLOCK",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4918#9.11",
			"spec_href": "http://tools.ietf.org/html/rfc4918#section-9.11"
		},
		{
			"method": "UPDATE",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#7.1",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-7.1"
		},
		{
			"method": "UPDATEREDIRECTREF",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC4437#7",
			"spec_href": "http://tools.ietf.org/html/rfc4437#section-7"
		},
		{
			"method": "VERSION-CONTROL",
			"description": "",
			"safe": false,
			"idempotent": true,
			"cacheable": "",
			"spec_title": "RFC3253#3.5",
			"spec_href": "http://tools.ietf.org/html/rfc3253#section-3.5"
		}
	];

/***/ },
/* 35 */
/***/ function(module, exports) {

	module.exports = [
		{
			"header": "Content-Encoding",
			"description": "\"indicates what content codings have been applied to the representation, beyond those inherent in the media type, and thus what decoding mechanisms have to be applied in order to obtain data in the media type referenced by the Content-Type header field.\"",
			"spec_title": "RFC7231#3.1.2.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-3.1.2.2"
		},
		{
			"header": "Content-Language",
			"description": "\"describes the natural language(s) of the intended audience for the representation.\"",
			"spec_title": "RFC7231#3.1.3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-3.1.3.2"
		},
		{
			"header": "Content-Location",
			"description": "\"references a URI that can be used as an identifier for a specific resource corresponding to the representation in this message's payload.\"",
			"spec_title": "RFC7231#3.1.4.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-3.1.4.2"
		},
		{
			"header": "Content-Type",
			"description": "\"indicates the media type of the associated representation: either the representation enclosed in the message payload or the selected representation, as determined by the message semantics.\"",
			"spec_title": "RFC7231#3.1.1.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-3.1.1.5"
		},
		{
			"header": "Content-Length",
			"description": "\"can provide the anticipated size, as a decimal number of octets, for a potential payload body.\"",
			"spec_title": "RFC7230#3.3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7230#section-3.3.2"
		},
		{
			"header": "Content-Range",
			"description": "\"is sent in a single part 206 (Partial Content) response to indicate the partial range of the selected representation enclosed as the message payload, sent in each part of a multipart 206 response to indicate the range enclosed within each body part, and sent in 416 (Range Not Satisfiable) responses to provide information about the selected representation.\"",
			"spec_title": "RFC7233#4.2",
			"spec_href": "http://tools.ietf.org/html/rfc7233#section-4.2"
		},
		{
			"header": "Transfer-Encoding",
			"description": "\"lists the transfer coding names corresponding to the sequence of transfer codings that have been (or will be) applied to the payload body in order to form the message body.\"",
			"spec_title": "RFC7230#3.3.1",
			"spec_href": "http://tools.ietf.org/html/rfc7230#section-3.3.1"
		},
		{
			"header": "Cache-Control",
			"description": "\"is used to specify directives for caches along the request/response chain.\"",
			"spec_title": "RFC7234#7.2",
			"spec_href": "http://tools.ietf.org/html/rfc7234#section-7.2"
		},
		{
			"header": "Expect",
			"description": "\"is used to indicate that particular server behaviors are required by the client.\"",
			"spec_title": "RFC7231#5.1.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.1.1"
		},
		{
			"header": "Host",
			"description": "\"provides the host and port information from the target URI, enabling the origin server to distinguish among resources while servicing requests for multiple host names on a single IP address.\"",
			"spec_title": "RFC7230#5.4",
			"spec_href": "http://tools.ietf.org/html/rfc7230#section-5.4"
		},
		{
			"header": "Max-Forwards",
			"description": "\"provides a mechanism with the TRACE and OPTIONS methods to limit the number of times that the request is forwarded by proxies.\"",
			"spec_title": "RFC7231#5.1.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.1.2"
		},
		{
			"header": "Pragma",
			"description": "\"allows backwards compatibility with HTTP/1.0 caches, so that clients can specify a \"no-cache\" request that they will understand (as Cache-Control was not defined until HTTP/1.1).\"",
			"spec_title": "RFC7234#7.4",
			"spec_href": "http://tools.ietf.org/html/rfc7234#section-7.4"
		},
		{
			"header": "Range",
			"description": "\"modifies the method semantics to request transfer of only one or more subranges of the selected representation data, rather than the entire selected representation data.\"",
			"spec_title": "RFC7233#3.1",
			"spec_href": "http://tools.ietf.org/html/rfc7233#section-3.1"
		},
		{
			"header": "TE",
			"description": "\"indicates what transfer codings, besides chunked, the client is willing to accept in response, and whether or not the client is willing to accept trailer fields in a chunked transfer coding.\"",
			"spec_title": "RFC7230#4.3",
			"spec_href": "http://tools.ietf.org/html/rfc7230#section-4.3"
		},
		{
			"header": "If-Match",
			"description": "\"can be used to make a request method conditional on the current existence or value of an entity-tag for one or more representations of the target resource.\"",
			"spec_title": "RFC7232#3.1",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-3.1"
		},
		{
			"header": "If-Modified-Since",
			"description": "\"can be used with GET or HEAD to make the method conditional by modification date: if the selected representation has not been modified since the time specified in this field, then do not perform the request method; instead, respond as detailed below.\"",
			"spec_title": "RFC7232#3.3",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-3.3"
		},
		{
			"header": "If-None-Match",
			"description": "\"can be used to make a request method conditional on not matching any of the current entity-tag values for representations of the target resource.\"",
			"spec_title": "RFC7232#3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-3.2"
		},
		{
			"header": "If-Range",
			"description": "\"Informally, its meaning is: if the representation is unchanged, send me the part(s) that I am requesting in Range; otherwise, send me the entire representation.\"",
			"spec_title": "RFC7233#3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7233#section-3.2"
		},
		{
			"header": "If-Unmodified-Since",
			"description": "\"can be used to make a request method conditional by modification date: if the selected representation has been modified since the time specified in this field, then the server MUST NOT perform the requested operation and MUST instead respond with the 412 (Precondition Failed) status code.\"",
			"spec_title": "RFC7232#3.4",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-3.4"
		},
		{
			"header": "Accept",
			"description": "\"can be used to specify certain media types which are acceptable for the response.\"",
			"spec_title": "RFC7231#5.3.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.3.2"
		},
		{
			"header": "Accept-Charset",
			"description": "\"can be sent by a user agent to indicate what charsets are acceptable in textual response content.\"",
			"spec_title": "RFC7231#5.3.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.3.3"
		},
		{
			"header": "Accept-Encoding",
			"description": "\"can be used by user agents to indicate what response content-codings are acceptable in the response.\"",
			"spec_title": "RFC7231#5.3.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.3.4"
		},
		{
			"header": "Accept-Language",
			"description": "\"can be used by user agents to indicate the set of natural languages that are preferred in the response.\"",
			"spec_title": "RFC7231#5.3.5",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.3.5"
		},
		{
			"header": "Authorization",
			"description": "\"allows a user agent to authenticate itself with a server -- usually, but not necessarily, after receiving a 401 (Unauthorized) response.\"",
			"spec_title": "RFC7235#4.1",
			"spec_href": "http://tools.ietf.org/html/rfc7235#section-4.1"
		},
		{
			"header": "Proxy-Authorization",
			"description": "\"allows the client to identify itself (or its user) to a proxy that requires authentication.\"",
			"spec_title": "RFC7235#4.3",
			"spec_href": "http://tools.ietf.org/html/rfc7235#section-4.3"
		},
		{
			"header": "DNT",
			"description": "\"defined as the means for expressing a user's tracking preference via HTTP.\"",
			"spec_title": "Tracking Preference Expression (DNT)",
			"spec_href": "http://www.w3.org/TR/tracking-dnt/#dnt-header-field"
		},
		{
			"header": "From",
			"description": "\"contains an Internet email address for a human user who controls the requesting user agent.\"",
			"spec_title": "RFC7231#5.5.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.5.1"
		},
		{
			"header": "Referer",
			"description": "\"allows the user agent to specify a URI reference for the resource from which the target URI was obtained (i.e., the \"referrer\", though the field name is misspelled).\"",
			"spec_title": "RFC7231#5.5.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.5.2"
		},
		{
			"header": "User-Agent",
			"description": "\"contains information about the user agent originating the request, which is often used by servers to help identify the scope of reported interoperability problems, to work around or tailor responses to avoid particular user agent limitations, and for analytics regarding browser or operating system use.\"",
			"spec_title": "RFC7231#5.5.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-5.5.3"
		},
		{
			"header": "Age",
			"description": "\"conveys the sender's estimate of the amount of time since the response was generated or successfully validated at the origin server.\"",
			"spec_title": "RFC7234#5.1",
			"spec_href": "http://tools.ietf.org/html/rfc7234#section-5.1"
		},
		{
			"header": "Cache-Control",
			"description": "\"is used to specify directives for caches along the request/response chain.\"",
			"spec_title": "RFC7234#7.2",
			"spec_href": "http://tools.ietf.org/html/rfc7234#section-7.2"
		},
		{
			"header": "Expires",
			"description": "\"gives the date/time after which the response is considered stale.\"",
			"spec_title": "RFC7234#7.3",
			"spec_href": "http://tools.ietf.org/html/rfc7234#section-7.3"
		},
		{
			"header": "Date",
			"description": "\"represents the date and time at which the message was originated\"",
			"spec_title": "RFC7231#7.1.1.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-7.1.1.2"
		},
		{
			"header": "Location",
			"description": "\"is used in some responses to refer to a specific resource in relation to the response.\"",
			"spec_title": "RFC7231#7.1.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-7.1.2"
		},
		{
			"header": "Retry-After",
			"description": "\"indicates how long the user agent ought to wait before making a follow-up request.\"",
			"spec_title": "RFC7231#7.1.3",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-7.1.3"
		},
		{
			"header": "Tk",
			"description": "\"defined as an OPTIONAL means for indicating the tracking status that applied to the corresponding request and as a REQUIRED means for indicating that a state-changing request has resulted in an interactive change to the tracking status. \"",
			"spec_title": "Tracking Preference Expression (DNT)",
			"spec_href": "http://www.w3.org/TR/tracking-dnt/#response-header-field"
		},
		{
			"header": "Vary",
			"description": "\"describes what parts of a request message, aside from the method and request target, might influence the origin server's process for selecting and representing the response.\"",
			"spec_title": "RFC7231#7.1.4",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-7.1.4"
		},
		{
			"header": "Warning",
			"description": "\"is used to carry additional information about the status or transformation of a message that might not be reflected in the message.\"",
			"spec_title": "RFC7234#7.6",
			"spec_href": "http://tools.ietf.org/html/rfc7234#section-7.6"
		},
		{
			"header": "ETag",
			"description": "\"provides the current entity-tag for the selected representation, as determined at the conclusion of handling the request.\"",
			"spec_title": "RFC7232#2.3",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-2.3"
		},
		{
			"header": "Last-Modified",
			"description": "\"provides a timestamp indicating the date and time at which the origin server believes the selected representation was last modified, as determined at the conclusion of handling the request.\"",
			"spec_title": "RFC7232#2.2",
			"spec_href": "http://tools.ietf.org/html/rfc7232#section-2.2"
		},
		{
			"header": "WWW-Authenticate",
			"description": "\"consists of at least one challenge that indicates the authentication scheme(s) and parameters applicable to the effective request URI.\"",
			"spec_title": "RFC7235#4.4",
			"spec_href": "http://tools.ietf.org/html/rfc7235#section-4.4"
		},
		{
			"header": "Proxy-Authenticate",
			"description": "\"consists of at least one challenge that indicates the authentication scheme(s) and parameters applicable to the proxy for this effective request URI.\"",
			"spec_title": "RFC7235#4.2",
			"spec_href": "http://tools.ietf.org/html/rfc7235#section-4.2"
		},
		{
			"header": "Accept-Ranges",
			"description": "\"allows a server to indicate that it supports range requests for the target resource.\"",
			"spec_title": "RFC7233#2.3",
			"spec_href": "http://tools.ietf.org/html/rfc7233#section-2.3"
		},
		{
			"header": "Allow",
			"description": "\"lists the set of methods advertised as supported by the target resource.\"",
			"spec_title": "RFC7231#7.4.1",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-7.4.1"
		},
		{
			"header": "Server",
			"description": "\"contains information about the software used by the origin server to handle the request, which is often used by clients to help identify the scope of reported interoperability problems, to work around or tailor requests to avoid particular server limitations, and for analytics regarding server or operating system use.\"",
			"spec_title": "RFC7231#7.4.2",
			"spec_href": "http://tools.ietf.org/html/rfc7231#section-7.4.2"
		},
		{
			"header": "Accept-Patch",
			"description": "\"used to specify the patch document formats accepted by the server.\"",
			"spec_title": "RFC5789#3.1",
			"spec_href": "http://tools.ietf.org/html/rfc5789#section-3.1"
		},
		{
			"header": "Accept-Post",
			"description": "\"indicates server support for specific media types for entity bodies in HTTP POST requests.\"",
			"spec_title": "draft-wilde-accept-post",
			"spec_href": "http://tools.ietf.org/html/draft-wilde-accept-post"
		},
		{
			"header": "Access-Control-Allow-Credentials",
			"description": "\"indicates whether the response to request can be exposed when the omit credentials flag is unset\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-allow-credentials-response-header"
		},
		{
			"header": "Access-Control-Allow-Headers",
			"description": "\"indicates, as part of the response to a preflight request, which header field names can be used during the actual request\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-allow-headers-response-header"
		},
		{
			"header": "Access-Control-Allow-Methods",
			"description": "\"indicates, as part of the response to a preflight request, which methods can be used during the actual request\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-allow-methods-response-header"
		},
		{
			"header": "Access-Control-Allow-Origin",
			"description": "\"indicates whether a resource can be shared\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-allow-origin-response-header"
		},
		{
			"header": "Access-Control-Expose-Headers",
			"description": "\"indicates which headers are safe to expose to the API of a CORS API specification\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-expose-headers-response-header"
		},
		{
			"header": "Access-Control-Max-Age",
			"description": "\"indicates how long the results of a preflight request can be cached in a preflight result cache\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-max-age-response-header"
		},
		{
			"header": "Access-Control-Request-Headers",
			"description": "\"indicates which headers will be used in the actual request as part of the preflight request\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-request-headers-request-header"
		},
		{
			"header": "Access-Control-Request-Method",
			"description": "\"indicates which method will be used in the actual request as part of the preflight request\"",
			"spec_title": "CORS",
			"spec_href": "http://www.w3.org/TR/cors/#access-control-request-method-request-header"
		},
		{
			"header": "Content-Disposition",
			"description": "\"standard\"",
			"spec_title": "RFC6266",
			"spec_href": "http://tools.ietf.org/html/rfc6266"
		},
		{
			"header": "Content-Security-Policy",
			"description": "\"is the preferred mechanism for delivering a CSP policy\"",
			"spec_title": "CSP",
			"spec_href": "http://www.w3.org/TR/CSP/#content-security-policy-header-field"
		},
		{
			"header": "Content-Security-Policy-Report-Only",
			"description": "\"lets servers experiment with policies by monitoring (rather than enforcing) a policy\"",
			"spec_title": "CSP",
			"spec_href": "http://www.w3.org/TR/CSP/#content-security-policy-report-only-header-field"
		},
		{
			"header": "Cookie",
			"description": "\"standard\"",
			"spec_title": "RFC6265",
			"spec_href": "http://tools.ietf.org/html/rfc6265"
		},
		{
			"header": "Forwarded",
			"description": "\"standard\"",
			"spec_title": "RFC7239",
			"spec_href": "http://tools.ietf.org/html/rfc7239"
		},
		{
			"header": "Link",
			"description": "\"provides a means for serialising one or more links in HTTP headers.\"",
			"spec_title": "RFC5988#5",
			"spec_href": "http://tools.ietf.org/html/rfc5988#section-5"
		},
		{
			"header": "Origin",
			"description": "\"standard\"",
			"spec_title": "RFC6454",
			"spec_href": "http://tools.ietf.org/html/rfc6454"
		},
		{
			"header": "Prefer",
			"description": "\"is used to indicate that particular server behaviors are preferred by the client, but not required for successful completion of the request.\"",
			"spec_title": "draft-snell-http-prefer#2",
			"spec_href": "http://tools.ietf.org/html/draft-snell-http-prefer#section-2"
		},
		{
			"header": "Preference-Applied",
			"description": "\"MAY be included within a response message as an indication as to which Prefer tokens were honored by the server and applied to the processing of a request.\"",
			"spec_title": "draft-snell-http-prefer#3",
			"spec_href": "http://tools.ietf.org/html/draft-snell-http-prefer#section-3"
		},
		{
			"header": "Set-Cookie",
			"description": "\"standard\"",
			"spec_title": "RFC6265",
			"spec_href": "http://tools.ietf.org/html/rfc6265"
		},
		{
			"header": "Strict-Transport-Security",
			"description": "\"standard\"",
			"spec_title": "RFC6797",
			"spec_href": "http://tools.ietf.org/html/rfc6797"
		},
		{
			"header": "Via",
			"description": "\"\"",
			"spec_title": "RFC7230#5.7.1",
			"spec_href": "http://tools.ietf.org/html/rfc7230#section-5.7.1"
		},
		{
			"header": "A-IM",
			"description": "\"\"",
			"spec_title": "RFC3229#10.5.3",
			"spec_href": "http://tools.ietf.org/html/rfc3229#section-10.5.3"
		},
		{
			"header": "Accept-Features",
			"description": "\"can be used by a user agent to give information about the presence or absence of certain features in the feature set of the current request.\"",
			"spec_title": "RFC2295#8.2",
			"spec_href": "http://tools.ietf.org/html/rfc2295#section-8.2"
		},
		{
			"header": "Alt-Svc",
			"description": "\"is advertising the availability of alternate services to HTTP/1.1 and HTTP/2.0 clients by adding an Alt-Svc header field to responses.\"",
			"spec_title": "draft-nottingham-httpbis-alt-svc",
			"spec_href": "http://tools.ietf.org/html/draft-nottingham-httpbis-alt-svc"
		},
		{
			"header": "Alternates",
			"description": "\"is used to convey the list of variants bound to a negotiable resource.\"",
			"spec_title": "RFC2295#8.3",
			"spec_href": "http://tools.ietf.org/html/rfc2295#section-8.3"
		},
		{
			"header": "Apply-To-Redirect-Ref",
			"description": "\"\"",
			"spec_title": "RFC4437",
			"spec_href": "http://tools.ietf.org/html/rfc4437"
		},
		{
			"header": "CH",
			"description": "\"describes an example list of client preferences that the server can use to adapt and optimize the resource to satisfy a given request.\"",
			"spec_title": "draft-grigorik-http-client-hints",
			"spec_href": "http://tools.ietf.org/html/draft-grigorik-http-client-hints"
		},
		{
			"header": "Content-Base",
			"description": "\"obsoleted\"",
			"spec_title": "RFC2068",
			"spec_href": "http://tools.ietf.org/html/rfc2068"
		},
		{
			"header": "Cookie2",
			"description": "\"obsoleted\"",
			"spec_title": "RFC2965",
			"spec_href": "http://tools.ietf.org/html/rfc2965"
		},
		{
			"header": "DASL",
			"description": "\"standard\"",
			"spec_title": "RFC5323",
			"spec_href": "http://tools.ietf.org/html/rfc5323"
		},
		{
			"header": "DAV",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "Delta-Base",
			"description": "\"\"",
			"spec_title": "RFC3229#10.5.1",
			"spec_href": "http://tools.ietf.org/html/rfc3229#section-10.5.1"
		},
		{
			"header": "Depth",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "Destination",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "IM",
			"description": "\"\"",
			"spec_title": "RFC3229#10.5.2",
			"spec_href": "http://tools.ietf.org/html/rfc3229#section-10.5.2"
		},
		{
			"header": "If",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "If-Schedule-Tag-Match",
			"description": "\"standard\"",
			"spec_title": "RFC6638",
			"spec_href": "http://tools.ietf.org/html/rfc6638"
		},
		{
			"header": "Last-Event-ID",
			"description": "\"The value of the event source's last event ID string, encoded as UTF-8.\"",
			"spec_title": "Server-Sent Events",
			"spec_href": "http://www.w3.org/TR/eventsource/#last-event-id"
		},
		{
			"header": "Link-Template",
			"description": "\"provides a means for serialising one or more links into HTTP headers.\"",
			"spec_title": "draft-nottingham-link-template",
			"spec_href": "http://tools.ietf.org/html/draft-nottingham-link-template"
		},
		{
			"header": "Lock-Token",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "Negotiate",
			"description": "\"can contain directives for any content negotiation process initiated by the request.\"",
			"spec_title": "RFC2295#8.4",
			"spec_href": "http://tools.ietf.org/html/rfc2295#section-8.4"
		},
		{
			"header": "Nice",
			"description": "\"indicates that a request is less important than a request that doesn't bear this header.\"",
			"spec_title": "draft-thomson-http-nice",
			"spec_href": "http://tools.ietf.org/html/draft-thomson-http-nice"
		},
		{
			"header": "Overwrite",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "Redirect-Ref",
			"description": "\"\"",
			"spec_title": "RFC4437",
			"spec_href": "http://tools.ietf.org/html/rfc4437"
		},
		{
			"header": "Schedule-Reply",
			"description": "\"standard\"",
			"spec_title": "RFC6638",
			"spec_href": "http://tools.ietf.org/html/rfc6638"
		},
		{
			"header": "Schedule-Tag",
			"description": "\"standard\"",
			"spec_title": "RFC6638",
			"spec_href": "http://tools.ietf.org/html/rfc6638"
		},
		{
			"header": "Sec-WebSocket-Accept",
			"description": "\"standard\"",
			"spec_title": "RFC6455",
			"spec_href": "http://tools.ietf.org/html/rfc6455"
		},
		{
			"header": "Sec-WebSocket-Extensions",
			"description": "\"standard\"",
			"spec_title": "RFC6455",
			"spec_href": "http://tools.ietf.org/html/rfc6455"
		},
		{
			"header": "Sec-WebSocket-Key",
			"description": "\"standard\"",
			"spec_title": "RFC6455",
			"spec_href": "http://tools.ietf.org/html/rfc6455"
		},
		{
			"header": "Sec-WebSocket-Protocol",
			"description": "\"standard\"",
			"spec_title": "RFC6455",
			"spec_href": "http://tools.ietf.org/html/rfc6455"
		},
		{
			"header": "Sec-WebSocket-Version",
			"description": "\"standard\"",
			"spec_title": "RFC6455",
			"spec_href": "http://tools.ietf.org/html/rfc6455"
		},
		{
			"header": "Set-Cookie2",
			"description": "\"obsoleted\"",
			"spec_title": "RFC2965",
			"spec_href": "http://tools.ietf.org/html/rfc2965"
		},
		{
			"header": "SLUG",
			"description": "\"standard\"",
			"spec_title": "RFC5023",
			"spec_href": "http://tools.ietf.org/html/rfc5023"
		},
		{
			"header": "TCN",
			"description": "\"is used by a server to signal that the resource is transparently negotiated.\"",
			"spec_title": "RFC2295#8.5",
			"spec_href": "http://tools.ietf.org/html/rfc2295#section-8.5"
		},
		{
			"header": "Timeout",
			"description": "\"standard\"",
			"spec_title": "RFC4918",
			"spec_href": "http://tools.ietf.org/html/rfc4918"
		},
		{
			"header": "Variant-Vary",
			"description": "\"can be used in a choice response to record any vary information which applies to the variant data (the entity body combined with some of the entity headers) contained in the response, rather than to the response as a whole.\"",
			"spec_title": "RFC2295#8.6",
			"spec_href": "http://tools.ietf.org/html/rfc2295#section-8.6"
		},
		{
			"header": "X-Frame-Options",
			"description": "\"indicates a policy that specifies whether the browser should render the transmitted resource within a <frame> or an <iframe>. Servers can declare this policy in the header of their HTTP responses to prevent clickjacking attacks, which ensures that their content is not embedded into other pages or frames.\"",
			"spec_title": "RFC7034",
			"spec_href": "http://tools.ietf.org/html/rfc7034"
		}
	];

/***/ },
/* 36 */
/***/ function(module, exports) {

	module.exports = [
		{
			"relation": "about",
			"description": "\"Refers to a resource that is the subject of the link's context.\"",
			"spec_title": "RFC6903",
			"spec_href": "http://tools.ietf.org/html/rfc6903"
		},
		{
			"relation": "alternate",
			"description": "\"Refers to a substitute for this context\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-alternate"
		},
		{
			"relation": "appendix",
			"description": "\"Refers to an appendix.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "archives",
			"description": "\"Refers to a collection of records, documents, or other materials of historical interest.\"",
			"spec_title": "HTML5linksWD",
			"spec_href": "http://www.w3.org/TR/2011/WD-html5-20110113/links.html#rel-archives"
		},
		{
			"relation": "author",
			"description": "\"Refers to the context's author.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-author"
		},
		{
			"relation": "bookmark",
			"description": "\"Gives a permanent link to use for bookmarking purposes.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-bookmark"
		},
		{
			"relation": "canonical",
			"description": "\"Designates the preferred version of a resource (the IRI and its contents).\"",
			"spec_title": "RFC6596",
			"spec_href": "http://tools.ietf.org/html/rfc6596"
		},
		{
			"relation": "chapter",
			"description": "\"Refers to a chapter in a collection of resources.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "collection",
			"description": "\"The target IRI points to a resource which represents the collection resource for the context IRI.\"",
			"spec_title": "RFC6573",
			"spec_href": "http://tools.ietf.org/html/rfc6573"
		},
		{
			"relation": "contents",
			"description": "\"Refers to a table of contents.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "copyright",
			"description": "\"Refers to a copyright statement that applies to the link's context.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "create-form",
			"description": "\"The target IRI points to a resource where a submission form can be obtained.\"",
			"spec_title": "RFC6861",
			"spec_href": "http://tools.ietf.org/html/rfc6861"
		},
		{
			"relation": "current",
			"description": "\"Refers to a resource containing the most recent item(s) in a collection of resources.\"",
			"spec_title": "RFC5005",
			"spec_href": "http://tools.ietf.org/html/rfc5005"
		},
		{
			"relation": "describedby",
			"description": "\"Refers to a resource providing information about the link's context.\"",
			"spec_title": "POWDER",
			"spec_href": "http://www.w3.org/TR/powder-dr/#assoc-linking"
		},
		{
			"relation": "describes",
			"description": "\"The relationship A 'describes' B asserts that resource A provides a description of resource B. There are no constraints on the format or representation of either A or B, neither are there any further constraints on either resource.\"",
			"spec_title": "RFC6892",
			"spec_href": "http://tools.ietf.org/html/rfc6892"
		},
		{
			"relation": "disclosure",
			"description": "\"Refers to a list of patent disclosures made with respect to material for which `disclosure` relation is specified.\"",
			"spec_title": "RFC6579",
			"spec_href": "http://tools.ietf.org/html/rfc6579"
		},
		{
			"relation": "duplicate",
			"description": "\"Refers to a resource whose available representations are byte-for-byte identical with the corresponding representations of the context IRI.\"",
			"spec_title": "RFC6249",
			"spec_href": "http://tools.ietf.org/html/rfc6249"
		},
		{
			"relation": "edit",
			"description": "\"Refers to a resource that can be used to edit the link's context.\"",
			"spec_title": "RFC5023",
			"spec_href": "http://tools.ietf.org/html/rfc5023"
		},
		{
			"relation": "edit-form",
			"description": "\"The target IRI points to a resource where a submission form for editing associated resource can be obtained.\"",
			"spec_title": "RFC6861",
			"spec_href": "http://tools.ietf.org/html/rfc6861"
		},
		{
			"relation": "edit-media",
			"description": "\"Refers to a resource that can be used to edit media associated with the link's context.\"",
			"spec_title": "RFC5023",
			"spec_href": "http://tools.ietf.org/html/rfc5023"
		},
		{
			"relation": "enclosure",
			"description": "\"Identifies a related resource that is potentially large and might require special handling.\"",
			"spec_title": "RFC4287",
			"spec_href": "http://tools.ietf.org/html/rfc4287"
		},
		{
			"relation": "first",
			"description": "\"An IRI that refers to the furthest preceding resource in a series of resources.\"",
			"spec_title": "RFC5988",
			"spec_href": "http://tools.ietf.org/html/rfc5988"
		},
		{
			"relation": "glossary",
			"description": "\"Refers to a glossary of terms.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "help",
			"description": "\"Refers to context-sensitive help.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-help"
		},
		{
			"relation": "hosts",
			"description": "\"Refers to a resource hosted by the server indicated by the link context.\"",
			"spec_title": "RFC6690",
			"spec_href": "http://tools.ietf.org/html/rfc6690"
		},
		{
			"relation": "hub",
			"description": "\"Refers to a hub that enables registration for notification of updates to the context.\"",
			"spec_title": "pubsubhubbub",
			"spec_href": "http://pubsubhubbub.googlecode.com"
		},
		{
			"relation": "icon",
			"description": "\"Refers to an icon representing the link's context.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-icon"
		},
		{
			"relation": "index",
			"description": "\"Refers to an index.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "item",
			"description": "\"The target IRI points to a resource that is a member of the collection represented by the context IRI.\"",
			"spec_title": "RFC6573",
			"spec_href": "http://tools.ietf.org/html/rfc6573"
		},
		{
			"relation": "last",
			"description": "\"An IRI that refers to the furthest following resource in a series of resources.\"",
			"spec_title": "RFC5988",
			"spec_href": "http://tools.ietf.org/html/rfc5988"
		},
		{
			"relation": "latest-version",
			"description": "\"Points to a resource containing the latest (e.g., current) version of the context.\"",
			"spec_title": "RFC5829",
			"spec_href": "http://tools.ietf.org/html/rfc5829"
		},
		{
			"relation": "license",
			"description": "\"Refers to a license associated with this context.\"",
			"spec_title": "RFC4946",
			"spec_href": "http://tools.ietf.org/html/rfc4946"
		},
		{
			"relation": "lrdd",
			"description": "\"Refers to further information about the link's context, expressed as a LRDD (Link-based Resource Descriptor Document) resource. See [RFC6415](http://tools.ietf.org/html/rfc6415) for information about processing this relation type in host-meta documents. When used elsewhere, it refers to additional links and other metadata. Multiple instances indicate additional LRDD resources. LRDD resources MUST have an \"application/xrd+xml\" representation, and MAY have others.\"",
			"spec_title": "RFC6415",
			"spec_href": "http://tools.ietf.org/html/rfc6415"
		},
		{
			"relation": "monitor",
			"description": "\"Refers to a resource that can be used to monitor changes in an HTTP resource.\"",
			"spec_title": "RFC5989",
			"spec_href": "http://tools.ietf.org/html/rfc5989"
		},
		{
			"relation": "monitor-group",
			"description": "\"Refers to a resource that can be used to monitor changes in a specified group of HTTP resources.\"",
			"spec_title": "RFC5989",
			"spec_href": "http://tools.ietf.org/html/rfc5989"
		},
		{
			"relation": "next",
			"description": "\"Indicates that the link's context is a part of a series, and that the next in the series is the link target.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-next"
		},
		{
			"relation": "next-archive",
			"description": "\"Refers to the immediately following archive resource.\"",
			"spec_title": "RFC5005",
			"spec_href": "http://tools.ietf.org/html/rfc5005"
		},
		{
			"relation": "nofollow",
			"description": "\"Indicates that the context’s original author or publisher does not endorse the link target.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-nofollow"
		},
		{
			"relation": "noreferrer",
			"description": "\"Indicates that no referrer information is to be leaked when following the link.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-noreferrer"
		},
		{
			"relation": "payment",
			"description": "\"Indicates a resource where payment is accepted.\"",
			"spec_title": "RFC5988",
			"spec_href": "http://tools.ietf.org/html/rfc5988"
		},
		{
			"relation": "predecessor-version",
			"description": "\"Points to a resource containing the predecessor version in the version history.\"",
			"spec_title": "RFC5829",
			"spec_href": "http://tools.ietf.org/html/rfc5829"
		},
		{
			"relation": "prefetch",
			"description": "\"Indicates that the link target should be preemptively cached.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-prefetch"
		},
		{
			"relation": "prev",
			"description": "\"Indicates that the link's context is a part of a series, and that the previous in the series is the link target.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-prev"
		},
		{
			"relation": "preview",
			"description": "\"Refers to a resource that provides a preview of the link's context.\"",
			"spec_title": "RFC6903",
			"spec_href": "http://tools.ietf.org/html/rfc6903"
		},
		{
			"relation": "previous",
			"description": "\"Refers to the previous resource in an ordered series of resources. Synonym for `prev`.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "prev-archive",
			"description": "\"Refers to the immediately preceding archive resource.\"",
			"spec_title": "RFC5005",
			"spec_href": "http://tools.ietf.org/html/rfc5005"
		},
		{
			"relation": "privacy-policy",
			"description": "\"Refers to a privacy policy associated with the link's context.\"",
			"spec_title": "RFC6903",
			"spec_href": "http://tools.ietf.org/html/rfc6903"
		},
		{
			"relation": "profile",
			"description": "Identifying that a resource representation conforms to a certain profile, without affecting the non-profile semantics of the resource representation",
			"spec_title": "RFC6906",
			"spec_href": "http://tools.ietf.org/html/rfc6906"
		},
		{
			"relation": "related",
			"description": "\"Identifies a related resource.\"",
			"spec_title": "RFC4287",
			"spec_href": "http://tools.ietf.org/html/rfc4287"
		},
		{
			"relation": "replies",
			"description": "\"Identifies a resource that is a reply to the context of the link.\"",
			"spec_title": "RFC4685",
			"spec_href": "http://tools.ietf.org/html/rfc4685"
		},
		{
			"relation": "search",
			"description": "\"Refers to a resource that can be used to search through the link's context and related resources.\"",
			"spec_title": "OpenSearch",
			"spec_href": "http://www.opensearch.org/Specifications/OpenSearch/1.1"
		},
		{
			"relation": "section",
			"description": "\"Refers to a section in a collection of resources.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "self",
			"description": "\"Conveys an identifier for the link's context.\"",
			"spec_title": "RFC4287",
			"spec_href": "http://tools.ietf.org/html/rfc4287"
		},
		{
			"relation": "service",
			"description": "\"Indicates a URI that can be used to retrieve a service document.\"",
			"spec_title": "RFC5023",
			"spec_href": "http://tools.ietf.org/html/rfc5023"
		},
		{
			"relation": "start",
			"description": "\"Refers to the first resource in a collection of resources.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "stylesheet",
			"description": "\"Refers to a stylesheet.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-stylesheet"
		},
		{
			"relation": "subsection",
			"description": "\"Refers to a resource serving as a subsection in a collection of resources.\"",
			"spec_title": "HTML401",
			"spec_href": "http://www.w3.org/TR/1999/REC-html401-19991224"
		},
		{
			"relation": "successor-version",
			"description": "\"Points to a resource containing the successor version in the version history.\"",
			"spec_title": "RFC5829",
			"spec_href": "http://tools.ietf.org/html/rfc5829"
		},
		{
			"relation": "tag",
			"description": "\"Gives a tag (identified by the given address) that applies to the current document.\"",
			"spec_title": "HTML5links",
			"spec_href": "http://www.w3.org/TR/html5/links.html#link-type-tag"
		},
		{
			"relation": "terms-of-service",
			"description": "\"Refers to the terms of service associated with the link's context.\"",
			"spec_title": "RFC6903",
			"spec_href": "http://tools.ietf.org/html/rfc6903"
		},
		{
			"relation": "type",
			"description": "\"Refers to a resource identifying the abstract semantic type of which the link's context is considered to be an instance.\"",
			"spec_title": "RFC6903",
			"spec_href": "http://tools.ietf.org/html/rfc6903"
		},
		{
			"relation": "up",
			"description": "\"Refers to a parent document in a hierarchy of documents.\"",
			"spec_title": "RFC5988",
			"spec_href": "http://tools.ietf.org/html/rfc5988"
		},
		{
			"relation": "version-history",
			"description": "\"Points to a resource containing the version history for the context.\"",
			"spec_title": "RFC5829",
			"spec_href": "http://tools.ietf.org/html/rfc5829"
		},
		{
			"relation": "via",
			"description": "\"Identifies a resource that is the source of the information in the link's context.\"",
			"spec_title": "RFC4287",
			"spec_href": "http://tools.ietf.org/html/rfc4287"
		},
		{
			"relation": "working-copy",
			"description": "\"Points to a working copy for this resource.\"",
			"spec_title": "RFC5829",
			"spec_href": "http://tools.ietf.org/html/rfc5829"
		},
		{
			"relation": "working-copy-of",
			"description": "\"Points to the versioned resource from which this working copy was obtained.\"",
			"spec_title": "RFC5829",
			"spec_href": "http://tools.ietf.org/html/rfc5829"
		}
	];

/***/ },
/* 37 */
/***/ function(module, exports) {

	/*!
	 * media-typer
	 * Copyright(c) 2014 Douglas Christopher Wilson
	 * MIT Licensed
	 */

	/**
	 * RegExp to match *( ";" parameter ) in RFC 2616 sec 3.7
	 *
	 * parameter     = token "=" ( token | quoted-string )
	 * token         = 1*<any CHAR except CTLs or separators>
	 * separators    = "(" | ")" | "<" | ">" | "@"
	 *               | "," | ";" | ":" | "\" | <">
	 *               | "/" | "[" | "]" | "?" | "="
	 *               | "{" | "}" | SP | HT
	 * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
	 * qdtext        = <any TEXT except <">>
	 * quoted-pair   = "\" CHAR
	 * CHAR          = <any US-ASCII character (octets 0 - 127)>
	 * TEXT          = <any OCTET except CTLs, but including LWS>
	 * LWS           = [CRLF] 1*( SP | HT )
	 * CRLF          = CR LF
	 * CR            = <US-ASCII CR, carriage return (13)>
	 * LF            = <US-ASCII LF, linefeed (10)>
	 * SP            = <US-ASCII SP, space (32)>
	 * SHT           = <US-ASCII HT, horizontal-tab (9)>
	 * CTL           = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
	 * OCTET         = <any 8-bit sequence of data>
	 */
	var paramRegExp = /; *([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *= *("(?:[ !\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u0020-\u007e])*"|[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) */g;
	var textRegExp = /^[\u0020-\u007e\u0080-\u00ff]+$/
	var tokenRegExp = /^[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+$/

	/**
	 * RegExp to match quoted-pair in RFC 2616
	 *
	 * quoted-pair = "\" CHAR
	 * CHAR        = <any US-ASCII character (octets 0 - 127)>
	 */
	var qescRegExp = /\\([\u0000-\u007f])/g;

	/**
	 * RegExp to match chars that must be quoted-pair in RFC 2616
	 */
	var quoteRegExp = /([\\"])/g;

	/**
	 * RegExp to match type in RFC 6838
	 *
	 * type-name = restricted-name
	 * subtype-name = restricted-name
	 * restricted-name = restricted-name-first *126restricted-name-chars
	 * restricted-name-first  = ALPHA / DIGIT
	 * restricted-name-chars  = ALPHA / DIGIT / "!" / "#" /
	 *                          "$" / "&" / "-" / "^" / "_"
	 * restricted-name-chars =/ "." ; Characters before first dot always
	 *                              ; specify a facet name
	 * restricted-name-chars =/ "+" ; Characters after last plus always
	 *                              ; specify a structured syntax suffix
	 * ALPHA =  %x41-5A / %x61-7A   ; A-Z / a-z
	 * DIGIT =  %x30-39             ; 0-9
	 */
	var subtypeNameRegExp = /^[A-Za-z0-9][A-Za-z0-9!#$&^_.-]{0,126}$/
	var typeNameRegExp = /^[A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126}$/
	var typeRegExp = /^ *([A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126})\/([A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}) *$/;

	/**
	 * Module exports.
	 */

	exports.format = format
	exports.parse = parse

	/**
	 * Format object to media type.
	 *
	 * @param {object} obj
	 * @return {string}
	 * @api public
	 */

	function format(obj) {
	  if (!obj || typeof obj !== 'object') {
	    throw new TypeError('argument obj is required')
	  }

	  var parameters = obj.parameters
	  var subtype = obj.subtype
	  var suffix = obj.suffix
	  var type = obj.type

	  if (!type || !typeNameRegExp.test(type)) {
	    throw new TypeError('invalid type')
	  }

	  if (!subtype || !subtypeNameRegExp.test(subtype)) {
	    throw new TypeError('invalid subtype')
	  }

	  // format as type/subtype
	  var string = type + '/' + subtype

	  // append +suffix
	  if (suffix) {
	    if (!typeNameRegExp.test(suffix)) {
	      throw new TypeError('invalid suffix')
	    }

	    string += '+' + suffix
	  }

	  // append parameters
	  if (parameters && typeof parameters === 'object') {
	    var param
	    var params = Object.keys(parameters).sort()

	    for (var i = 0; i < params.length; i++) {
	      param = params[i]

	      if (!tokenRegExp.test(param)) {
	        throw new TypeError('invalid parameter name')
	      }

	      string += '; ' + param + '=' + qstring(parameters[param])
	    }
	  }

	  return string
	}

	/**
	 * Parse media type to object.
	 *
	 * @param {string|object} string
	 * @return {Object}
	 * @api public
	 */

	function parse(string) {
	  if (!string) {
	    throw new TypeError('argument string is required')
	  }

	  // support req/res-like objects as argument
	  if (typeof string === 'object') {
	    string = getcontenttype(string)
	  }

	  if (typeof string !== 'string') {
	    throw new TypeError('argument string is required to be a string')
	  }

	  var index = string.indexOf(';')
	  var type = index !== -1
	    ? string.substr(0, index)
	    : string

	  var key
	  var match
	  var obj = splitType(type)
	  var params = {}
	  var value

	  paramRegExp.lastIndex = index

	  while (match = paramRegExp.exec(string)) {
	    if (match.index !== index) {
	      throw new TypeError('invalid parameter format')
	    }

	    index += match[0].length
	    key = match[1].toLowerCase()
	    value = match[2]

	    if (value[0] === '"') {
	      // remove quotes and escapes
	      value = value
	        .substr(1, value.length - 2)
	        .replace(qescRegExp, '$1')
	    }

	    params[key] = value
	  }

	  if (index !== -1 && index !== string.length) {
	    throw new TypeError('invalid parameter format')
	  }

	  obj.parameters = params

	  return obj
	}

	/**
	 * Get content-type from req/res objects.
	 *
	 * @param {object}
	 * @return {Object}
	 * @api private
	 */

	function getcontenttype(obj) {
	  if (typeof obj.getHeader === 'function') {
	    // res-like
	    return obj.getHeader('content-type')
	  }

	  if (typeof obj.headers === 'object') {
	    // req-like
	    return obj.headers && obj.headers['content-type']
	  }
	}

	/**
	 * Quote a string if necessary.
	 *
	 * @param {string} val
	 * @return {string}
	 * @api private
	 */

	function qstring(val) {
	  var str = String(val)

	  // no need to quote tokens
	  if (tokenRegExp.test(str)) {
	    return str
	  }

	  if (str.length > 0 && !textRegExp.test(str)) {
	    throw new TypeError('invalid parameter value')
	  }

	  return '"' + str.replace(quoteRegExp, '\\$1') + '"'
	}

	/**
	 * Simply "type/subtype+siffx" into parts.
	 *
	 * @param {string} string
	 * @return {Object}
	 * @api private
	 */

	function splitType(string) {
	  var match = typeRegExp.exec(string.toLowerCase())

	  if (!match) {
	    throw new TypeError('invalid media type')
	  }

	  var type = match[1]
	  var subtype = match[2]
	  var suffix

	  // suffix after last +
	  var index = subtype.lastIndexOf('+')
	  if (index !== -1) {
	    suffix = subtype.substr(index + 1)
	    subtype = subtype.substr(0, index)
	  }

	  var obj = {
	    type: type,
	    subtype: subtype,
	    suffix: suffix
	  }

	  return obj
	}


/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {

	/* global define */

	(function (root, pluralize) {
	  /* istanbul ignore else */
	  if (true) {
	    // Node.
	    module.exports = pluralize();
	  } else if (typeof define === 'function' && define.amd) {
	    // AMD, registers as an anonymous module.
	    define(function () {
	      return pluralize();
	    });
	  } else {
	    // Browser global.
	    root.pluralize = pluralize();
	  }
	})(this, function () {
	  // Rule storage - pluralize and singularize need to be run sequentially,
	  // while other rules can be optimized using an object for instant lookups.
	  var pluralRules = [];
	  var singularRules = [];
	  var uncountables = {};
	  var irregularPlurals = {};
	  var irregularSingles = {};

	  /**
	   * Title case a string.
	   *
	   * @param  {string} str
	   * @return {string}
	   */
	  function toTitleCase (str) {
	    return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
	  }

	  /**
	   * Sanitize a pluralization rule to a usable regular expression.
	   *
	   * @param  {(RegExp|string)} rule
	   * @return {RegExp}
	   */
	  function sanitizeRule (rule) {
	    if (typeof rule === 'string') {
	      return new RegExp('^' + rule + '$', 'i');
	    }

	    return rule;
	  }

	  /**
	   * Pass in a word token to produce a function that can replicate the case on
	   * another word.
	   *
	   * @param  {string}   word
	   * @param  {string}   token
	   * @return {Function}
	   */
	  function restoreCase (word, token) {
	    // Upper cased words. E.g. "HELLO".
	    if (word === word.toUpperCase()) {
	      return token.toUpperCase();
	    }

	    // Title cased words. E.g. "Title".
	    if (word[0] === word[0].toUpperCase()) {
	      return toTitleCase(token);
	    }

	    // Lower cased words. E.g. "test".
	    return token.toLowerCase();
	  }

	  /**
	   * Interpolate a regexp string.
	   *
	   * @param  {string} str
	   * @param  {Array}  args
	   * @return {string}
	   */
	  function interpolate (str, args) {
	    return str.replace(/\$(\d{1,2})/g, function (match, index) {
	      return args[index] || '';
	    });
	  }

	  /**
	   * Sanitize a word by passing in the word and sanitization rules.
	   *
	   * @param  {String}   token
	   * @param  {String}   word
	   * @param  {Array}    collection
	   * @return {String}
	   */
	  function sanitizeWord (token, word, collection) {
	    // Empty string or doesn't need fixing.
	    if (!token.length || uncountables.hasOwnProperty(token)) {
	      return word;
	    }

	    var len = collection.length;

	    // Iterate over the sanitization rules and use the first one to match.
	    while (len--) {
	      var rule = collection[len];

	      // If the rule passes, return the replacement.
	      if (rule[0].test(word)) {
	        return word.replace(rule[0], function (match, index, word) {
	          var result = interpolate(rule[1], arguments);

	          if (match === '') {
	            return restoreCase(word[index - 1], result);
	          }

	          return restoreCase(match, result);
	        });
	      }
	    }

	    return word;
	  }

	  /**
	   * Replace a word with the updated word.
	   *
	   * @param  {Object}   replaceMap
	   * @param  {Object}   keepMap
	   * @param  {Array}    rules
	   * @return {Function}
	   */
	  function replaceWord (replaceMap, keepMap, rules) {
	    return function (word) {
	      // Get the correct token and case restoration functions.
	      var token = word.toLowerCase();

	      // Check against the keep object map.
	      if (keepMap.hasOwnProperty(token)) {
	        return restoreCase(word, token);
	      }

	      // Check against the replacement map for a direct word replacement.
	      if (replaceMap.hasOwnProperty(token)) {
	        return restoreCase(word, replaceMap[token]);
	      }

	      // Run all the rules against the word.
	      return sanitizeWord(token, word, rules);
	    };
	  }

	  /**
	   * Pluralize or singularize a word based on the passed in count.
	   *
	   * @param  {String}  word
	   * @param  {Number}  count
	   * @param  {Boolean} inclusive
	   * @return {String}
	   */
	  function pluralize (word, count, inclusive) {
	    var pluralized = count === 1
	      ? pluralize.singular(word) : pluralize.plural(word);

	    return (inclusive ? count + ' ' : '') + pluralized;
	  }

	  /**
	   * Pluralize a word.
	   *
	   * @type {Function}
	   */
	  pluralize.plural = replaceWord(
	    irregularSingles, irregularPlurals, pluralRules
	  );

	  /**
	   * Singularize a word.
	   *
	   * @type {Function}
	   */
	  pluralize.singular = replaceWord(
	    irregularPlurals, irregularSingles, singularRules
	  );

	  /**
	   * Add a pluralization rule to the collection.
	   *
	   * @param {(string|RegExp)} rule
	   * @param {string}          replacement
	   */
	  pluralize.addPluralRule = function (rule, replacement) {
	    pluralRules.push([sanitizeRule(rule), replacement]);
	  };

	  /**
	   * Add a singularization rule to the collection.
	   *
	   * @param {(string|RegExp)} rule
	   * @param {string}          replacement
	   */
	  pluralize.addSingularRule = function (rule, replacement) {
	    singularRules.push([sanitizeRule(rule), replacement]);
	  };

	  /**
	   * Add an uncountable word rule.
	   *
	   * @param {(string|RegExp)} word
	   */
	  pluralize.addUncountableRule = function (word) {
	    if (typeof word === 'string') {
	      uncountables[word.toLowerCase()] = true;
	      return;
	    }

	    // Set singular and plural references for the word.
	    pluralize.addPluralRule(word, '$0');
	    pluralize.addSingularRule(word, '$0');
	  };

	  /**
	   * Add an irregular word definition.
	   *
	   * @param {String} single
	   * @param {String} plural
	   */
	  pluralize.addIrregularRule = function (single, plural) {
	    plural = plural.toLowerCase();
	    single = single.toLowerCase();

	    irregularSingles[single] = plural;
	    irregularPlurals[plural] = single;
	  };

	  /**
	   * Irregular rules.
	   */
	  [
	    // Pronouns.
	    ['I', 'we'],
	    ['me', 'us'],
	    ['he', 'they'],
	    ['she', 'they'],
	    ['them', 'them'],
	    ['myself', 'ourselves'],
	    ['yourself', 'yourselves'],
	    ['itself', 'themselves'],
	    ['herself', 'themselves'],
	    ['himself', 'themselves'],
	    ['themself', 'themselves'],
	    ['is', 'are'],
	    ['this', 'these'],
	    ['that', 'those'],
	    // Words ending in with a consonant and `o`.
	    ['echo', 'echoes'],
	    ['dingo', 'dingoes'],
	    ['volcano', 'volcanoes'],
	    ['tornado', 'tornadoes'],
	    ['torpedo', 'torpedoes'],
	    // Ends with `us`.
	    ['genus', 'genera'],
	    ['viscus', 'viscera'],
	    // Ends with `ma`.
	    ['stigma', 'stigmata'],
	    ['stoma', 'stomata'],
	    ['dogma', 'dogmata'],
	    ['lemma', 'lemmata'],
	    ['schema', 'schemata'],
	    ['anathema', 'anathemata'],
	    // Other irregular rules.
	    ['ox', 'oxen'],
	    ['axe', 'axes'],
	    ['die', 'dice'],
	    ['yes', 'yeses'],
	    ['foot', 'feet'],
	    ['eave', 'eaves'],
	    ['goose', 'geese'],
	    ['tooth', 'teeth'],
	    ['quiz', 'quizzes'],
	    ['human', 'humans'],
	    ['proof', 'proofs'],
	    ['carve', 'carves'],
	    ['valve', 'valves'],
	    ['thief', 'thieves'],
	    ['genie', 'genies'],
	    ['groove', 'grooves'],
	    ['pickaxe', 'pickaxes'],
	    ['whiskey', 'whiskies']
	  ].forEach(function (rule) {
	    return pluralize.addIrregularRule(rule[0], rule[1]);
	  });

	  /**
	   * Pluralization rules.
	   */
	  [
	    [/s?$/i, 's'],
	    [/([^aeiou]ese)$/i, '$1'],
	    [/(ax|test)is$/i, '$1es'],
	    [/(alias|[^aou]us|tlas|gas|ris)$/i, '$1es'],
	    [/(e[mn]u)s?$/i, '$1s'],
	    [/([^l]ias|[aeiou]las|[emjzr]as|[iu]am)$/i, '$1'],
	    [/(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'],
	    [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'],
	    [/(seraph|cherub)(?:im)?$/i, '$1im'],
	    [/(her|at|gr)o$/i, '$1oes'],
	    [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'],
	    [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'],
	    [/sis$/i, 'ses'],
	    [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'],
	    [/([^aeiouy]|qu)y$/i, '$1ies'],
	    [/([^ch][ieo][ln])ey$/i, '$1ies'],
	    [/(x|ch|ss|sh|zz)$/i, '$1es'],
	    [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'],
	    [/(m|l)(?:ice|ouse)$/i, '$1ice'],
	    [/(pe)(?:rson|ople)$/i, '$1ople'],
	    [/(child)(?:ren)?$/i, '$1ren'],
	    [/eaux$/i, '$0'],
	    [/m[ae]n$/i, 'men'],
	    ['thou', 'you']
	  ].forEach(function (rule) {
	    return pluralize.addPluralRule(rule[0], rule[1]);
	  });

	  /**
	   * Singularization rules.
	   */
	  [
	    [/s$/i, ''],
	    [/(ss)$/i, '$1'],
	    [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(?:sis|ses)$/i, '$1sis'],
	    [/(^analy)(?:sis|ses)$/i, '$1sis'],
	    [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'],
	    [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'],
	    [/([^aeiouy]|qu)ies$/i, '$1y'],
	    [/(^[pl]|zomb|^(?:neck)?t|[aeo][lt]|cut)ies$/i, '$1ie'],
	    [/(\b(?:mon|smil))ies$/i, '$1ey'],
	    [/(m|l)ice$/i, '$1ouse'],
	    [/(seraph|cherub)im$/i, '$1'],
	    [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|tlas|gas|(?:her|at|gr)o|ris)(?:es)?$/i, '$1'],
	    [/(e[mn]u)s?$/i, '$1'],
	    [/(movie|twelve)s$/i, '$1'],
	    [/(cris|test|diagnos)(?:is|es)$/i, '$1is'],
	    [/(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'],
	    [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'],
	    [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'],
	    [/(alumn|alg|vertebr)ae$/i, '$1a'],
	    [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'],
	    [/(matr|append)ices$/i, '$1ix'],
	    [/(pe)(rson|ople)$/i, '$1rson'],
	    [/(child)ren$/i, '$1'],
	    [/(eau)x?$/i, '$1'],
	    [/men$/i, 'man']
	  ].forEach(function (rule) {
	    return pluralize.addSingularRule(rule[0], rule[1]);
	  });

	  /**
	   * Uncountable rules.
	   */
	  [
	    // Singular words with no plurals.
	    'advice',
	    'agenda',
	    'bison',
	    'bream',
	    'buffalo',
	    'carp',
	    'chassis',
	    'cod',
	    'cooperation',
	    'corps',
	    'digestion',
	    'debris',
	    'diabetes',
	    'energy',
	    'equipment',
	    'elk',
	    'excretion',
	    'expertise',
	    'flounder',
	    'gallows',
	    'garbage',
	    'graffiti',
	    'headquarters',
	    'health',
	    'herpes',
	    'highjinks',
	    'homework',
	    'information',
	    'jeans',
	    'justice',
	    'kudos',
	    'labour',
	    'machinery',
	    'mackerel',
	    'media',
	    'mews',
	    'moose',
	    'news',
	    'pike',
	    'plankton',
	    'pliers',
	    'pollution',
	    'premises',
	    'rain',
	    'rice',
	    'salmon',
	    'scissors',
	    'series',
	    'sewage',
	    'shambles',
	    'shrimp',
	    'species',
	    'staff',
	    'swine',
	    'trout',
	    'tuna',
	    'whiting',
	    'wildebeest',
	    'wildlife',
	    'you',
	    // Regexes.
	    /pox$/i, // "chickpox", "smallpox"
	    /ois$/i,
	    /deer$/i, // "deer", "reindeer"
	    /fish$/i, // "fish", "blowfish", "angelfish"
	    /sheep$/i,
	    /measles$/i,
	    /[^aeiou]ese$/i // "chinese", "japanese"
	  ].forEach(pluralize.addUncountableRule);

	  return pluralize;
	});


/***/ },
/* 39 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {(function() {
	  var vm,
	    __slice = [].slice;

	  vm = __webpack_require__(40);

	  exports.allowUnsafeEval = function(fn) {
	    var previousEval;
	    previousEval = global["eval"];
	    try {
	      global["eval"] = function(source) {
	        return vm.runInThisContext(source);
	      };
	      return fn();
	    } finally {
	      global["eval"] = previousEval;
	    }
	  };

	  exports.allowUnsafeNewFunction = function(fn) {
	    var previousFunction;
	    previousFunction = global.Function;
	    try {
	      global.Function = exports.Function;
	      return fn();
	    } finally {
	      global.Function = previousFunction;
	    }
	  };

	  exports.Function = function() {
	    var body, paramList, paramLists, params, _i, _j, _len;
	    paramLists = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), body = arguments[_i++];
	    params = [];
	    for (_j = 0, _len = paramLists.length; _j < _len; _j++) {
	      paramList = paramLists[_j];
	      if (typeof paramList === 'string') {
	        paramList = paramList.split(/\s*,\s*/);
	      }
	      params.push.apply(params, paramList);
	    }
	    return vm.runInThisContext("(function(" + (params.join(', ')) + ") {\n  " + body + "\n})");
	  };

	  exports.Function.prototype = global.Function.prototype;

	}).call(this);

	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 40 */
/***/ function(module, exports, __webpack_require__) {

	var indexOf = __webpack_require__(41);

	var Object_keys = function (obj) {
	    if (Object.keys) return Object.keys(obj)
	    else {
	        var res = [];
	        for (var key in obj) res.push(key)
	        return res;
	    }
	};

	var forEach = function (xs, fn) {
	    if (xs.forEach) return xs.forEach(fn)
	    else for (var i = 0; i < xs.length; i++) {
	        fn(xs[i], i, xs);
	    }
	};

	var defineProp = (function() {
	    try {
	        Object.defineProperty({}, '_', {});
	        return function(obj, name, value) {
	            Object.defineProperty(obj, name, {
	                writable: true,
	                enumerable: false,
	                configurable: true,
	                value: value
	            })
	        };
	    } catch(e) {
	        return function(obj, name, value) {
	            obj[name] = value;
	        };
	    }
	}());

	var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
	'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
	'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
	'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
	'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];

	function Context() {}
	Context.prototype = {};

	var Script = exports.Script = function NodeScript (code) {
	    if (!(this instanceof Script)) return new Script(code);
	    this.code = code;
	};

	Script.prototype.runInContext = function (context) {
	    if (!(context instanceof Context)) {
	        throw new TypeError("needs a 'context' argument.");
	    }
	    
	    var iframe = document.createElement('iframe');
	    if (!iframe.style) iframe.style = {};
	    iframe.style.display = 'none';
	    
	    document.body.appendChild(iframe);
	    
	    var win = iframe.contentWindow;
	    var wEval = win.eval, wExecScript = win.execScript;

	    if (!wEval && wExecScript) {
	        // win.eval() magically appears when this is called in IE:
	        wExecScript.call(win, 'null');
	        wEval = win.eval;
	    }
	    
	    forEach(Object_keys(context), function (key) {
	        win[key] = context[key];
	    });
	    forEach(globals, function (key) {
	        if (context[key]) {
	            win[key] = context[key];
	        }
	    });
	    
	    var winKeys = Object_keys(win);

	    var res = wEval.call(win, this.code);
	    
	    forEach(Object_keys(win), function (key) {
	        // Avoid copying circular objects like `top` and `window` by only
	        // updating existing context properties or new properties in the `win`
	        // that was only introduced after the eval.
	        if (key in context || indexOf(winKeys, key) === -1) {
	            context[key] = win[key];
	        }
	    });

	    forEach(globals, function (key) {
	        if (!(key in context)) {
	            defineProp(context, key, win[key]);
	        }
	    });
	    
	    document.body.removeChild(iframe);
	    
	    return res;
	};

	Script.prototype.runInThisContext = function () {
	    return eval(this.code); // maybe...
	};

	Script.prototype.runInNewContext = function (context) {
	    var ctx = Script.createContext(context);
	    var res = this.runInContext(ctx);

	    forEach(Object_keys(ctx), function (key) {
	        context[key] = ctx[key];
	    });

	    return res;
	};

	forEach(Object_keys(Script.prototype), function (name) {
	    exports[name] = Script[name] = function (code) {
	        var s = Script(code);
	        return s[name].apply(s, [].slice.call(arguments, 1));
	    };
	});

	exports.createScript = function (code) {
	    return exports.Script(code);
	};

	exports.createContext = Script.createContext = function (context) {
	    var copy = new Context();
	    if(typeof context === 'object') {
	        forEach(Object_keys(context), function (key) {
	            copy[key] = context[key];
	        });
	    }
	    return copy;
	};


/***/ },
/* 41 */
/***/ function(module, exports) {

	
	var indexOf = [].indexOf;

	module.exports = function(arr, obj){
	  if (indexOf) return arr.indexOf(obj);
	  for (var i = 0; i < arr.length; ++i) {
	    if (arr[i] === obj) return i;
	  }
	  return -1;
	};

/***/ },
/* 42 */
/***/ function(module, exports) {

	'use strict';

	module.exports = Response;

	/**
	 * A response from a web request
	 *
	 * @param {Number} statusCode
	 * @param {Object} headers
	 * @param {Buffer} body
	 * @param {String} url
	 */
	function Response(statusCode, headers, body, url) {
	  if (typeof statusCode !== 'number') {
	    throw new TypeError('statusCode must be a number but was ' + (typeof statusCode));
	  }
	  if (headers === null) {
	    throw new TypeError('headers cannot be null');
	  }
	  if (typeof headers !== 'object') {
	    throw new TypeError('headers must be an object but was ' + (typeof headers));
	  }
	  this.statusCode = statusCode;
	  this.headers = {};
	  for (var key in headers) {
	    this.headers[key.toLowerCase()] = headers[key];
	  }
	  this.body = body;
	  this.url = url;
	}

	Response.prototype.getBody = function (encoding) {
	  if (this.statusCode >= 300) {
	    var err = new Error('Server responded with status code '
	                    + this.statusCode + ':\n' + this.body.toString());
	    err.statusCode = this.statusCode;
	    err.headers = this.headers;
	    err.body = this.body;
	    err.url = this.url;
	    throw err;
	  }
	  return encoding ? this.body.toString(encoding) : this.body;
	};


/***/ },
/* 43 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(Buffer) {var Writable = __webpack_require__(44).Writable
	var inherits = __webpack_require__(67)

	if (typeof Uint8Array === 'undefined') {
	  var U8 = __webpack_require__(75).Uint8Array
	} else {
	  var U8 = Uint8Array
	}

	function ConcatStream(opts, cb) {
	  if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb)

	  if (typeof opts === 'function') {
	    cb = opts
	    opts = {}
	  }
	  if (!opts) opts = {}

	  var encoding = opts.encoding
	  var shouldInferEncoding = false

	  if (!encoding) {
	    shouldInferEncoding = true
	  } else {
	    encoding =  String(encoding).toLowerCase()
	    if (encoding === 'u8' || encoding === 'uint8') {
	      encoding = 'uint8array'
	    }
	  }

	  Writable.call(this, { objectMode: true })

	  this.encoding = encoding
	  this.shouldInferEncoding = shouldInferEncoding

	  if (cb) this.on('finish', function () { cb(this.getBody()) })
	  this.body = []
	}

	module.exports = ConcatStream
	inherits(ConcatStream, Writable)

	ConcatStream.prototype._write = function(chunk, enc, next) {
	  this.body.push(chunk)
	  next()
	}

	ConcatStream.prototype.inferEncoding = function (buff) {
	  var firstBuffer = buff === undefined ? this.body[0] : buff;
	  if (Buffer.isBuffer(firstBuffer)) return 'buffer'
	  if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array'
	  if (Array.isArray(firstBuffer)) return 'array'
	  if (typeof firstBuffer === 'string') return 'string'
	  if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object'
	  return 'buffer'
	}

	ConcatStream.prototype.getBody = function () {
	  if (!this.encoding && this.body.length === 0) return []
	  if (this.shouldInferEncoding) this.encoding = this.inferEncoding()
	  if (this.encoding === 'array') return arrayConcat(this.body)
	  if (this.encoding === 'string') return stringConcat(this.body)
	  if (this.encoding === 'buffer') return bufferConcat(this.body)
	  if (this.encoding === 'uint8array') return u8Concat(this.body)
	  return this.body
	}

	var isArray = Array.isArray || function (arr) {
	  return Object.prototype.toString.call(arr) == '[object Array]'
	}

	function isArrayish (arr) {
	  return /Array\]$/.test(Object.prototype.toString.call(arr))
	}

	function stringConcat (parts) {
	  var strings = []
	  var needsToString = false
	  for (var i = 0; i < parts.length; i++) {
	    var p = parts[i]
	    if (typeof p === 'string') {
	      strings.push(p)
	    } else if (Buffer.isBuffer(p)) {
	      strings.push(p)
	    } else {
	      strings.push(Buffer(p))
	    }
	  }
	  if (Buffer.isBuffer(parts[0])) {
	    strings = Buffer.concat(strings)
	    strings = strings.toString('utf8')
	  } else {
	    strings = strings.join('')
	  }
	  return strings
	}

	function bufferConcat (parts) {
	  var bufs = []
	  for (var i = 0; i < parts.length; i++) {
	    var p = parts[i]
	    if (Buffer.isBuffer(p)) {
	      bufs.push(p)
	    } else if (typeof p === 'string' || isArrayish(p)
	    || (p && typeof p.subarray === 'function')) {
	      bufs.push(Buffer(p))
	    } else bufs.push(Buffer(String(p)))
	  }
	  return Buffer.concat(bufs)
	}

	function arrayConcat (parts) {
	  var res = []
	  for (var i = 0; i < parts.length; i++) {
	    res.push.apply(res, parts[i])
	  }
	  return res
	}

	function u8Concat (parts) {
	  var len = 0
	  for (var i = 0; i < parts.length; i++) {
	    if (typeof parts[i] === 'string') {
	      parts[i] = Buffer(parts[i])
	    }
	    len += parts[i].length
	  }
	  var u8 = new U8(len)
	  for (var i = 0, offset = 0; i < parts.length; i++) {
	    var part = parts[i]
	    for (var j = 0; j < part.length; j++) {
	      u8[offset++] = part[j]
	    }
	  }
	  return u8
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer))

/***/ },
/* 44 */
/***/ function(module, exports, __webpack_require__) {

	var Stream = (function (){
	  try {
	    return __webpack_require__(45); // hack to fix a circular dependency issue when used with browserify
	  } catch(_){}
	}());
	exports = module.exports = __webpack_require__(63);
	exports.Stream = Stream || exports;
	exports.Readable = exports;
	exports.Writable = __webpack_require__(70);
	exports.Duplex = __webpack_require__(69);
	exports.Transform = __webpack_require__(73);
	exports.PassThrough = __webpack_require__(74);


/***/ },
/* 45 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	module.exports = Stream;

	var EE = __webpack_require__(46).EventEmitter;
	var inherits = __webpack_require__(47);

	inherits(Stream, EE);
	Stream.Readable = __webpack_require__(48);
	Stream.Writable = __webpack_require__(59);
	Stream.Duplex = __webpack_require__(60);
	Stream.Transform = __webpack_require__(61);
	Stream.PassThrough = __webpack_require__(62);

	// Backwards-compat with node 0.4.x
	Stream.Stream = Stream;



	// old-style streams.  Note that the pipe method (the only relevant
	// part of this class) is overridden in the Readable class.

	function Stream() {
	  EE.call(this);
	}

	Stream.prototype.pipe = function(dest, options) {
	  var source = this;

	  function ondata(chunk) {
	    if (dest.writable) {
	      if (false === dest.write(chunk) && source.pause) {
	        source.pause();
	      }
	    }
	  }

	  source.on('data', ondata);

	  function ondrain() {
	    if (source.readable && source.resume) {
	      source.resume();
	    }
	  }

	  dest.on('drain', ondrain);

	  // If the 'end' option is not supplied, dest.end() will be called when
	  // source gets the 'end' or 'close' events.  Only dest.end() once.
	  if (!dest._isStdio && (!options || options.end !== false)) {
	    source.on('end', onend);
	    source.on('close', onclose);
	  }

	  var didOnEnd = false;
	  function onend() {
	    if (didOnEnd) return;
	    didOnEnd = true;

	    dest.end();
	  }


	  function onclose() {
	    if (didOnEnd) return;
	    didOnEnd = true;

	    if (typeof dest.destroy === 'function') dest.destroy();
	  }

	  // don't leave dangling pipes when there are errors.
	  function onerror(er) {
	    cleanup();
	    if (EE.listenerCount(this, 'error') === 0) {
	      throw er; // Unhandled stream error in pipe.
	    }
	  }

	  source.on('error', onerror);
	  dest.on('error', onerror);

	  // remove all the event listeners that were added.
	  function cleanup() {
	    source.removeListener('data', ondata);
	    dest.removeListener('drain', ondrain);

	    source.removeListener('end', onend);
	    source.removeListener('close', onclose);

	    source.removeListener('error', onerror);
	    dest.removeListener('error', onerror);

	    source.removeListener('end', cleanup);
	    source.removeListener('close', cleanup);

	    dest.removeListener('close', cleanup);
	  }

	  source.on('end', cleanup);
	  source.on('close', cleanup);

	  dest.on('close', cleanup);

	  dest.emit('pipe', source);

	  // Allow for unix-like usage: A.pipe(B).pipe(C)
	  return dest;
	};


/***/ },
/* 46 */
/***/ function(module, exports) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	function EventEmitter() {
	  this._events = this._events || {};
	  this._maxListeners = this._maxListeners || undefined;
	}
	module.exports = EventEmitter;

	// Backwards-compat with node 0.10.x
	EventEmitter.EventEmitter = EventEmitter;

	EventEmitter.prototype._events = undefined;
	EventEmitter.prototype._maxListeners = undefined;

	// By default EventEmitters will print a warning if more than 10 listeners are
	// added to it. This is a useful default which helps finding memory leaks.
	EventEmitter.defaultMaxListeners = 10;

	// Obviously not all Emitters should be limited to 10. This function allows
	// that to be increased. Set to zero for unlimited.
	EventEmitter.prototype.setMaxListeners = function(n) {
	  if (!isNumber(n) || n < 0 || isNaN(n))
	    throw TypeError('n must be a positive number');
	  this._maxListeners = n;
	  return this;
	};

	EventEmitter.prototype.emit = function(type) {
	  var er, handler, len, args, i, listeners;

	  if (!this._events)
	    this._events = {};

	  // If there is no 'error' event listener then throw.
	  if (type === 'error') {
	    if (!this._events.error ||
	        (isObject(this._events.error) && !this._events.error.length)) {
	      er = arguments[1];
	      if (er instanceof Error) {
	        throw er; // Unhandled 'error' event
	      }
	      throw TypeError('Uncaught, unspecified "error" event.');
	    }
	  }

	  handler = this._events[type];

	  if (isUndefined(handler))
	    return false;

	  if (isFunction(handler)) {
	    switch (arguments.length) {
	      // fast cases
	      case 1:
	        handler.call(this);
	        break;
	      case 2:
	        handler.call(this, arguments[1]);
	        break;
	      case 3:
	        handler.call(this, arguments[1], arguments[2]);
	        break;
	      // slower
	      default:
	        args = Array.prototype.slice.call(arguments, 1);
	        handler.apply(this, args);
	    }
	  } else if (isObject(handler)) {
	    args = Array.prototype.slice.call(arguments, 1);
	    listeners = handler.slice();
	    len = listeners.length;
	    for (i = 0; i < len; i++)
	      listeners[i].apply(this, args);
	  }

	  return true;
	};

	EventEmitter.prototype.addListener = function(type, listener) {
	  var m;

	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');

	  if (!this._events)
	    this._events = {};

	  // To avoid recursion in the case that type === "newListener"! Before
	  // adding it to the listeners, first emit "newListener".
	  if (this._events.newListener)
	    this.emit('newListener', type,
	              isFunction(listener.listener) ?
	              listener.listener : listener);

	  if (!this._events[type])
	    // Optimize the case of one listener. Don't need the extra array object.
	    this._events[type] = listener;
	  else if (isObject(this._events[type]))
	    // If we've already got an array, just append.
	    this._events[type].push(listener);
	  else
	    // Adding the second element, need to change to array.
	    this._events[type] = [this._events[type], listener];

	  // Check for listener leak
	  if (isObject(this._events[type]) && !this._events[type].warned) {
	    if (!isUndefined(this._maxListeners)) {
	      m = this._maxListeners;
	    } else {
	      m = EventEmitter.defaultMaxListeners;
	    }

	    if (m && m > 0 && this._events[type].length > m) {
	      this._events[type].warned = true;
	      console.error('(node) warning: possible EventEmitter memory ' +
	                    'leak detected. %d listeners added. ' +
	                    'Use emitter.setMaxListeners() to increase limit.',
	                    this._events[type].length);
	      if (typeof console.trace === 'function') {
	        // not supported in IE 10
	        console.trace();
	      }
	    }
	  }

	  return this;
	};

	EventEmitter.prototype.on = EventEmitter.prototype.addListener;

	EventEmitter.prototype.once = function(type, listener) {
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');

	  var fired = false;

	  function g() {
	    this.removeListener(type, g);

	    if (!fired) {
	      fired = true;
	      listener.apply(this, arguments);
	    }
	  }

	  g.listener = listener;
	  this.on(type, g);

	  return this;
	};

	// emits a 'removeListener' event iff the listener was removed
	EventEmitter.prototype.removeListener = function(type, listener) {
	  var list, position, length, i;

	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');

	  if (!this._events || !this._events[type])
	    return this;

	  list = this._events[type];
	  length = list.length;
	  position = -1;

	  if (list === listener ||
	      (isFunction(list.listener) && list.listener === listener)) {
	    delete this._events[type];
	    if (this._events.removeListener)
	      this.emit('removeListener', type, listener);

	  } else if (isObject(list)) {
	    for (i = length; i-- > 0;) {
	      if (list[i] === listener ||
	          (list[i].listener && list[i].listener === listener)) {
	        position = i;
	        break;
	      }
	    }

	    if (position < 0)
	      return this;

	    if (list.length === 1) {
	      list.length = 0;
	      delete this._events[type];
	    } else {
	      list.splice(position, 1);
	    }

	    if (this._events.removeListener)
	      this.emit('removeListener', type, listener);
	  }

	  return this;
	};

	EventEmitter.prototype.removeAllListeners = function(type) {
	  var key, listeners;

	  if (!this._events)
	    return this;

	  // not listening for removeListener, no need to emit
	  if (!this._events.removeListener) {
	    if (arguments.length === 0)
	      this._events = {};
	    else if (this._events[type])
	      delete this._events[type];
	    return this;
	  }

	  // emit removeListener for all listeners on all events
	  if (arguments.length === 0) {
	    for (key in this._events) {
	      if (key === 'removeListener') continue;
	      this.removeAllListeners(key);
	    }
	    this.removeAllListeners('removeListener');
	    this._events = {};
	    return this;
	  }

	  listeners = this._events[type];

	  if (isFunction(listeners)) {
	    this.removeListener(type, listeners);
	  } else if (listeners) {
	    // LIFO order
	    while (listeners.length)
	      this.removeListener(type, listeners[listeners.length - 1]);
	  }
	  delete this._events[type];

	  return this;
	};

	EventEmitter.prototype.listeners = function(type) {
	  var ret;
	  if (!this._events || !this._events[type])
	    ret = [];
	  else if (isFunction(this._events[type]))
	    ret = [this._events[type]];
	  else
	    ret = this._events[type].slice();
	  return ret;
	};

	EventEmitter.prototype.listenerCount = function(type) {
	  if (this._events) {
	    var evlistener = this._events[type];

	    if (isFunction(evlistener))
	      return 1;
	    else if (evlistener)
	      return evlistener.length;
	  }
	  return 0;
	};

	EventEmitter.listenerCount = function(emitter, type) {
	  return emitter.listenerCount(type);
	};

	function isFunction(arg) {
	  return typeof arg === 'function';
	}

	function isNumber(arg) {
	  return typeof arg === 'number';
	}

	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}

	function isUndefined(arg) {
	  return arg === void 0;
	}


/***/ },
/* 47 */
/***/ function(module, exports) {

	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}


/***/ },
/* 48 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(49);
	exports.Stream = __webpack_require__(45);
	exports.Readable = exports;
	exports.Writable = __webpack_require__(55);
	exports.Duplex = __webpack_require__(54);
	exports.Transform = __webpack_require__(57);
	exports.PassThrough = __webpack_require__(58);


/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	module.exports = Readable;

	/*<replacement>*/
	var isArray = __webpack_require__(50);
	/*</replacement>*/


	/*<replacement>*/
	var Buffer = __webpack_require__(5).Buffer;
	/*</replacement>*/

	Readable.ReadableState = ReadableState;

	var EE = __webpack_require__(46).EventEmitter;

	/*<replacement>*/
	if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
	  return emitter.listeners(type).length;
	};
	/*</replacement>*/

	var Stream = __webpack_require__(45);

	/*<replacement>*/
	var util = __webpack_require__(51);
	util.inherits = __webpack_require__(52);
	/*</replacement>*/

	var StringDecoder;


	/*<replacement>*/
	var debug = __webpack_require__(53);
	if (debug && debug.debuglog) {
	  debug = debug.debuglog('stream');
	} else {
	  debug = function () {};
	}
	/*</replacement>*/


	util.inherits(Readable, Stream);

	function ReadableState(options, stream) {
	  var Duplex = __webpack_require__(54);

	  options = options || {};

	  // the point at which it stops calling _read() to fill the buffer
	  // Note: 0 is a valid value, means "don't call _read preemptively ever"
	  var hwm = options.highWaterMark;
	  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;

	  // cast to ints.
	  this.highWaterMark = ~~this.highWaterMark;

	  this.buffer = [];
	  this.length = 0;
	  this.pipes = null;
	  this.pipesCount = 0;
	  this.flowing = null;
	  this.ended = false;
	  this.endEmitted = false;
	  this.reading = false;

	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;

	  // whenever we return null, then we set a flag to say
	  // that we're awaiting a 'readable' event emission.
	  this.needReadable = false;
	  this.emittedReadable = false;
	  this.readableListening = false;


	  // object stream flag. Used to make read(n) ignore n and to
	  // make all the buffer merging and length checks go away
	  this.objectMode = !!options.objectMode;

	  if (stream instanceof Duplex)
	    this.objectMode = this.objectMode || !!options.readableObjectMode;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // when piping, we only care about 'readable' events that happen
	  // after read()ing all the bytes and not getting any pushback.
	  this.ranOut = false;

	  // the number of writers that are awaiting a drain event in .pipe()s
	  this.awaitDrain = 0;

	  // if true, a maybeReadMore has been scheduled
	  this.readingMore = false;

	  this.decoder = null;
	  this.encoding = null;
	  if (options.encoding) {
	    if (!StringDecoder)
	      StringDecoder = __webpack_require__(56).StringDecoder;
	    this.decoder = new StringDecoder(options.encoding);
	    this.encoding = options.encoding;
	  }
	}

	function Readable(options) {
	  var Duplex = __webpack_require__(54);

	  if (!(this instanceof Readable))
	    return new Readable(options);

	  this._readableState = new ReadableState(options, this);

	  // legacy
	  this.readable = true;

	  Stream.call(this);
	}

	// Manually shove something into the read() buffer.
	// This returns true if the highWaterMark has not been hit yet,
	// similar to how Writable.write() returns true if you should
	// write() some more.
	Readable.prototype.push = function(chunk, encoding) {
	  var state = this._readableState;

	  if (util.isString(chunk) && !state.objectMode) {
	    encoding = encoding || state.defaultEncoding;
	    if (encoding !== state.encoding) {
	      chunk = new Buffer(chunk, encoding);
	      encoding = '';
	    }
	  }

	  return readableAddChunk(this, state, chunk, encoding, false);
	};

	// Unshift should *always* be something directly out of read()
	Readable.prototype.unshift = function(chunk) {
	  var state = this._readableState;
	  return readableAddChunk(this, state, chunk, '', true);
	};

	function readableAddChunk(stream, state, chunk, encoding, addToFront) {
	  var er = chunkInvalid(state, chunk);
	  if (er) {
	    stream.emit('error', er);
	  } else if (util.isNullOrUndefined(chunk)) {
	    state.reading = false;
	    if (!state.ended)
	      onEofChunk(stream, state);
	  } else if (state.objectMode || chunk && chunk.length > 0) {
	    if (state.ended && !addToFront) {
	      var e = new Error('stream.push() after EOF');
	      stream.emit('error', e);
	    } else if (state.endEmitted && addToFront) {
	      var e = new Error('stream.unshift() after end event');
	      stream.emit('error', e);
	    } else {
	      if (state.decoder && !addToFront && !encoding)
	        chunk = state.decoder.write(chunk);

	      if (!addToFront)
	        state.reading = false;

	      // if we want the data now, just emit it.
	      if (state.flowing && state.length === 0 && !state.sync) {
	        stream.emit('data', chunk);
	        stream.read(0);
	      } else {
	        // update the buffer info.
	        state.length += state.objectMode ? 1 : chunk.length;
	        if (addToFront)
	          state.buffer.unshift(chunk);
	        else
	          state.buffer.push(chunk);

	        if (state.needReadable)
	          emitReadable(stream);
	      }

	      maybeReadMore(stream, state);
	    }
	  } else if (!addToFront) {
	    state.reading = false;
	  }

	  return needMoreData(state);
	}



	// if it's past the high water mark, we can push in some more.
	// Also, if we have no data yet, we can stand some
	// more bytes.  This is to work around cases where hwm=0,
	// such as the repl.  Also, if the push() triggered a
	// readable event, and the user called read(largeNumber) such that
	// needReadable was set, then we ought to push more, so that another
	// 'readable' event will be triggered.
	function needMoreData(state) {
	  return !state.ended &&
	         (state.needReadable ||
	          state.length < state.highWaterMark ||
	          state.length === 0);
	}

	// backwards compatibility.
	Readable.prototype.setEncoding = function(enc) {
	  if (!StringDecoder)
	    StringDecoder = __webpack_require__(56).StringDecoder;
	  this._readableState.decoder = new StringDecoder(enc);
	  this._readableState.encoding = enc;
	  return this;
	};

	// Don't raise the hwm > 128MB
	var MAX_HWM = 0x800000;
	function roundUpToNextPowerOf2(n) {
	  if (n >= MAX_HWM) {
	    n = MAX_HWM;
	  } else {
	    // Get the next highest power of 2
	    n--;
	    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
	    n++;
	  }
	  return n;
	}

	function howMuchToRead(n, state) {
	  if (state.length === 0 && state.ended)
	    return 0;

	  if (state.objectMode)
	    return n === 0 ? 0 : 1;

	  if (isNaN(n) || util.isNull(n)) {
	    // only flow one buffer at a time
	    if (state.flowing && state.buffer.length)
	      return state.buffer[0].length;
	    else
	      return state.length;
	  }

	  if (n <= 0)
	    return 0;

	  // If we're asking for more than the target buffer level,
	  // then raise the water mark.  Bump up to the next highest
	  // power of 2, to prevent increasing it excessively in tiny
	  // amounts.
	  if (n > state.highWaterMark)
	    state.highWaterMark = roundUpToNextPowerOf2(n);

	  // don't have that much.  return null, unless we've ended.
	  if (n > state.length) {
	    if (!state.ended) {
	      state.needReadable = true;
	      return 0;
	    } else
	      return state.length;
	  }

	  return n;
	}

	// you can override either this method, or the async _read(n) below.
	Readable.prototype.read = function(n) {
	  debug('read', n);
	  var state = this._readableState;
	  var nOrig = n;

	  if (!util.isNumber(n) || n > 0)
	    state.emittedReadable = false;

	  // if we're doing read(0) to trigger a readable event, but we
	  // already have a bunch of data in the buffer, then just trigger
	  // the 'readable' event and move on.
	  if (n === 0 &&
	      state.needReadable &&
	      (state.length >= state.highWaterMark || state.ended)) {
	    debug('read: emitReadable', state.length, state.ended);
	    if (state.length === 0 && state.ended)
	      endReadable(this);
	    else
	      emitReadable(this);
	    return null;
	  }

	  n = howMuchToRead(n, state);

	  // if we've ended, and we're now clear, then finish it up.
	  if (n === 0 && state.ended) {
	    if (state.length === 0)
	      endReadable(this);
	    return null;
	  }

	  // All the actual chunk generation logic needs to be
	  // *below* the call to _read.  The reason is that in certain
	  // synthetic stream cases, such as passthrough streams, _read
	  // may be a completely synchronous operation which may change
	  // the state of the read buffer, providing enough data when
	  // before there was *not* enough.
	  //
	  // So, the steps are:
	  // 1. Figure out what the state of things will be after we do
	  // a read from the buffer.
	  //
	  // 2. If that resulting state will trigger a _read, then call _read.
	  // Note that this may be asynchronous, or synchronous.  Yes, it is
	  // deeply ugly to write APIs this way, but that still doesn't mean
	  // that the Readable class should behave improperly, as streams are
	  // designed to be sync/async agnostic.
	  // Take note if the _read call is sync or async (ie, if the read call
	  // has returned yet), so that we know whether or not it's safe to emit
	  // 'readable' etc.
	  //
	  // 3. Actually pull the requested chunks out of the buffer and return.

	  // if we need a readable event, then we need to do some reading.
	  var doRead = state.needReadable;
	  debug('need readable', doRead);

	  // if we currently have less than the highWaterMark, then also read some
	  if (state.length === 0 || state.length - n < state.highWaterMark) {
	    doRead = true;
	    debug('length less than watermark', doRead);
	  }

	  // however, if we've ended, then there's no point, and if we're already
	  // reading, then it's unnecessary.
	  if (state.ended || state.reading) {
	    doRead = false;
	    debug('reading or ended', doRead);
	  }

	  if (doRead) {
	    debug('do read');
	    state.reading = true;
	    state.sync = true;
	    // if the length is currently zero, then we *need* a readable event.
	    if (state.length === 0)
	      state.needReadable = true;
	    // call internal read method
	    this._read(state.highWaterMark);
	    state.sync = false;
	  }

	  // If _read pushed data synchronously, then `reading` will be false,
	  // and we need to re-evaluate how much data we can return to the user.
	  if (doRead && !state.reading)
	    n = howMuchToRead(nOrig, state);

	  var ret;
	  if (n > 0)
	    ret = fromList(n, state);
	  else
	    ret = null;

	  if (util.isNull(ret)) {
	    state.needReadable = true;
	    n = 0;
	  }

	  state.length -= n;

	  // If we have nothing in the buffer, then we want to know
	  // as soon as we *do* get something into the buffer.
	  if (state.length === 0 && !state.ended)
	    state.needReadable = true;

	  // If we tried to read() past the EOF, then emit end on the next tick.
	  if (nOrig !== n && state.ended && state.length === 0)
	    endReadable(this);

	  if (!util.isNull(ret))
	    this.emit('data', ret);

	  return ret;
	};

	function chunkInvalid(state, chunk) {
	  var er = null;
	  if (!util.isBuffer(chunk) &&
	      !util.isString(chunk) &&
	      !util.isNullOrUndefined(chunk) &&
	      !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  return er;
	}


	function onEofChunk(stream, state) {
	  if (state.decoder && !state.ended) {
	    var chunk = state.decoder.end();
	    if (chunk && chunk.length) {
	      state.buffer.push(chunk);
	      state.length += state.objectMode ? 1 : chunk.length;
	    }
	  }
	  state.ended = true;

	  // emit 'readable' now to make sure it gets picked up.
	  emitReadable(stream);
	}

	// Don't emit readable right away in sync mode, because this can trigger
	// another read() call => stack overflow.  This way, it might trigger
	// a nextTick recursion warning, but that's not so bad.
	function emitReadable(stream) {
	  var state = stream._readableState;
	  state.needReadable = false;
	  if (!state.emittedReadable) {
	    debug('emitReadable', state.flowing);
	    state.emittedReadable = true;
	    if (state.sync)
	      process.nextTick(function() {
	        emitReadable_(stream);
	      });
	    else
	      emitReadable_(stream);
	  }
	}

	function emitReadable_(stream) {
	  debug('emit readable');
	  stream.emit('readable');
	  flow(stream);
	}


	// at this point, the user has presumably seen the 'readable' event,
	// and called read() to consume some data.  that may have triggered
	// in turn another _read(n) call, in which case reading = true if
	// it's in progress.
	// However, if we're not ended, or reading, and the length < hwm,
	// then go ahead and try to read some more preemptively.
	function maybeReadMore(stream, state) {
	  if (!state.readingMore) {
	    state.readingMore = true;
	    process.nextTick(function() {
	      maybeReadMore_(stream, state);
	    });
	  }
	}

	function maybeReadMore_(stream, state) {
	  var len = state.length;
	  while (!state.reading && !state.flowing && !state.ended &&
	         state.length < state.highWaterMark) {
	    debug('maybeReadMore read 0');
	    stream.read(0);
	    if (len === state.length)
	      // didn't get any data, stop spinning.
	      break;
	    else
	      len = state.length;
	  }
	  state.readingMore = false;
	}

	// abstract method.  to be overridden in specific implementation classes.
	// call cb(er, data) where data is <= n in length.
	// for virtual (non-string, non-buffer) streams, "length" is somewhat
	// arbitrary, and perhaps not very meaningful.
	Readable.prototype._read = function(n) {
	  this.emit('error', new Error('not implemented'));
	};

	Readable.prototype.pipe = function(dest, pipeOpts) {
	  var src = this;
	  var state = this._readableState;

	  switch (state.pipesCount) {
	    case 0:
	      state.pipes = dest;
	      break;
	    case 1:
	      state.pipes = [state.pipes, dest];
	      break;
	    default:
	      state.pipes.push(dest);
	      break;
	  }
	  state.pipesCount += 1;
	  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);

	  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
	              dest !== process.stdout &&
	              dest !== process.stderr;

	  var endFn = doEnd ? onend : cleanup;
	  if (state.endEmitted)
	    process.nextTick(endFn);
	  else
	    src.once('end', endFn);

	  dest.on('unpipe', onunpipe);
	  function onunpipe(readable) {
	    debug('onunpipe');
	    if (readable === src) {
	      cleanup();
	    }
	  }

	  function onend() {
	    debug('onend');
	    dest.end();
	  }

	  // when the dest drains, it reduces the awaitDrain counter
	  // on the source.  This would be more elegant with a .once()
	  // handler in flow(), but adding and removing repeatedly is
	  // too slow.
	  var ondrain = pipeOnDrain(src);
	  dest.on('drain', ondrain);

	  function cleanup() {
	    debug('cleanup');
	    // cleanup event handlers once the pipe is broken
	    dest.removeListener('close', onclose);
	    dest.removeListener('finish', onfinish);
	    dest.removeListener('drain', ondrain);
	    dest.removeListener('error', onerror);
	    dest.removeListener('unpipe', onunpipe);
	    src.removeListener('end', onend);
	    src.removeListener('end', cleanup);
	    src.removeListener('data', ondata);

	    // if the reader is waiting for a drain event from this
	    // specific writer, then it would cause it to never start
	    // flowing again.
	    // So, if this is awaiting a drain, then we just call it now.
	    // If we don't know, then assume that we are waiting for one.
	    if (state.awaitDrain &&
	        (!dest._writableState || dest._writableState.needDrain))
	      ondrain();
	  }

	  src.on('data', ondata);
	  function ondata(chunk) {
	    debug('ondata');
	    var ret = dest.write(chunk);
	    if (false === ret) {
	      debug('false write response, pause',
	            src._readableState.awaitDrain);
	      src._readableState.awaitDrain++;
	      src.pause();
	    }
	  }

	  // if the dest has an error, then stop piping into it.
	  // however, don't suppress the throwing behavior for this.
	  function onerror(er) {
	    debug('onerror', er);
	    unpipe();
	    dest.removeListener('error', onerror);
	    if (EE.listenerCount(dest, 'error') === 0)
	      dest.emit('error', er);
	  }
	  // This is a brutally ugly hack to make sure that our error handler
	  // is attached before any userland ones.  NEVER DO THIS.
	  if (!dest._events || !dest._events.error)
	    dest.on('error', onerror);
	  else if (isArray(dest._events.error))
	    dest._events.error.unshift(onerror);
	  else
	    dest._events.error = [onerror, dest._events.error];



	  // Both close and finish should trigger unpipe, but only once.
	  function onclose() {
	    dest.removeListener('finish', onfinish);
	    unpipe();
	  }
	  dest.once('close', onclose);
	  function onfinish() {
	    debug('onfinish');
	    dest.removeListener('close', onclose);
	    unpipe();
	  }
	  dest.once('finish', onfinish);

	  function unpipe() {
	    debug('unpipe');
	    src.unpipe(dest);
	  }

	  // tell the dest that it's being piped to
	  dest.emit('pipe', src);

	  // start the flow if it hasn't been started already.
	  if (!state.flowing) {
	    debug('pipe resume');
	    src.resume();
	  }

	  return dest;
	};

	function pipeOnDrain(src) {
	  return function() {
	    var state = src._readableState;
	    debug('pipeOnDrain', state.awaitDrain);
	    if (state.awaitDrain)
	      state.awaitDrain--;
	    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
	      state.flowing = true;
	      flow(src);
	    }
	  };
	}


	Readable.prototype.unpipe = function(dest) {
	  var state = this._readableState;

	  // if we're not piping anywhere, then do nothing.
	  if (state.pipesCount === 0)
	    return this;

	  // just one destination.  most common case.
	  if (state.pipesCount === 1) {
	    // passed in one, but it's not the right one.
	    if (dest && dest !== state.pipes)
	      return this;

	    if (!dest)
	      dest = state.pipes;

	    // got a match.
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    if (dest)
	      dest.emit('unpipe', this);
	    return this;
	  }

	  // slow case. multiple pipe destinations.

	  if (!dest) {
	    // remove all.
	    var dests = state.pipes;
	    var len = state.pipesCount;
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;

	    for (var i = 0; i < len; i++)
	      dests[i].emit('unpipe', this);
	    return this;
	  }

	  // try to find the right one.
	  var i = indexOf(state.pipes, dest);
	  if (i === -1)
	    return this;

	  state.pipes.splice(i, 1);
	  state.pipesCount -= 1;
	  if (state.pipesCount === 1)
	    state.pipes = state.pipes[0];

	  dest.emit('unpipe', this);

	  return this;
	};

	// set up data events if they are asked for
	// Ensure readable listeners eventually get something
	Readable.prototype.on = function(ev, fn) {
	  var res = Stream.prototype.on.call(this, ev, fn);

	  // If listening to data, and it has not explicitly been paused,
	  // then call resume to start the flow of data on the next tick.
	  if (ev === 'data' && false !== this._readableState.flowing) {
	    this.resume();
	  }

	  if (ev === 'readable' && this.readable) {
	    var state = this._readableState;
	    if (!state.readableListening) {
	      state.readableListening = true;
	      state.emittedReadable = false;
	      state.needReadable = true;
	      if (!state.reading) {
	        var self = this;
	        process.nextTick(function() {
	          debug('readable nexttick read 0');
	          self.read(0);
	        });
	      } else if (state.length) {
	        emitReadable(this, state);
	      }
	    }
	  }

	  return res;
	};
	Readable.prototype.addListener = Readable.prototype.on;

	// pause() and resume() are remnants of the legacy readable stream API
	// If the user uses them, then switch into old mode.
	Readable.prototype.resume = function() {
	  var state = this._readableState;
	  if (!state.flowing) {
	    debug('resume');
	    state.flowing = true;
	    if (!state.reading) {
	      debug('resume read 0');
	      this.read(0);
	    }
	    resume(this, state);
	  }
	  return this;
	};

	function resume(stream, state) {
	  if (!state.resumeScheduled) {
	    state.resumeScheduled = true;
	    process.nextTick(function() {
	      resume_(stream, state);
	    });
	  }
	}

	function resume_(stream, state) {
	  state.resumeScheduled = false;
	  stream.emit('resume');
	  flow(stream);
	  if (state.flowing && !state.reading)
	    stream.read(0);
	}

	Readable.prototype.pause = function() {
	  debug('call pause flowing=%j', this._readableState.flowing);
	  if (false !== this._readableState.flowing) {
	    debug('pause');
	    this._readableState.flowing = false;
	    this.emit('pause');
	  }
	  return this;
	};

	function flow(stream) {
	  var state = stream._readableState;
	  debug('flow', state.flowing);
	  if (state.flowing) {
	    do {
	      var chunk = stream.read();
	    } while (null !== chunk && state.flowing);
	  }
	}

	// wrap an old-style stream as the async data source.
	// This is *not* part of the readable stream interface.
	// It is an ugly unfortunate mess of history.
	Readable.prototype.wrap = function(stream) {
	  var state = this._readableState;
	  var paused = false;

	  var self = this;
	  stream.on('end', function() {
	    debug('wrapped end');
	    if (state.decoder && !state.ended) {
	      var chunk = state.decoder.end();
	      if (chunk && chunk.length)
	        self.push(chunk);
	    }

	    self.push(null);
	  });

	  stream.on('data', function(chunk) {
	    debug('wrapped data');
	    if (state.decoder)
	      chunk = state.decoder.write(chunk);
	    if (!chunk || !state.objectMode && !chunk.length)
	      return;

	    var ret = self.push(chunk);
	    if (!ret) {
	      paused = true;
	      stream.pause();
	    }
	  });

	  // proxy all the other methods.
	  // important when wrapping filters and duplexes.
	  for (var i in stream) {
	    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
	      this[i] = function(method) { return function() {
	        return stream[method].apply(stream, arguments);
	      }}(i);
	    }
	  }

	  // proxy certain important events.
	  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
	  forEach(events, function(ev) {
	    stream.on(ev, self.emit.bind(self, ev));
	  });

	  // when we try to consume some more bytes, simply unpause the
	  // underlying stream.
	  self._read = function(n) {
	    debug('wrapped _read', n);
	    if (paused) {
	      paused = false;
	      stream.resume();
	    }
	  };

	  return self;
	};



	// exposed for testing purposes only.
	Readable._fromList = fromList;

	// Pluck off n bytes from an array of buffers.
	// Length is the combined lengths of all the buffers in the list.
	function fromList(n, state) {
	  var list = state.buffer;
	  var length = state.length;
	  var stringMode = !!state.decoder;
	  var objectMode = !!state.objectMode;
	  var ret;

	  // nothing in the list, definitely empty.
	  if (list.length === 0)
	    return null;

	  if (length === 0)
	    ret = null;
	  else if (objectMode)
	    ret = list.shift();
	  else if (!n || n >= length) {
	    // read it all, truncate the array.
	    if (stringMode)
	      ret = list.join('');
	    else
	      ret = Buffer.concat(list, length);
	    list.length = 0;
	  } else {
	    // read just some of it.
	    if (n < list[0].length) {
	      // just take a part of the first list item.
	      // slice is the same for buffers and strings.
	      var buf = list[0];
	      ret = buf.slice(0, n);
	      list[0] = buf.slice(n);
	    } else if (n === list[0].length) {
	      // first list is a perfect match
	      ret = list.shift();
	    } else {
	      // complex case.
	      // we have enough to cover it, but it spans past the first buffer.
	      if (stringMode)
	        ret = '';
	      else
	        ret = new Buffer(n);

	      var c = 0;
	      for (var i = 0, l = list.length; i < l && c < n; i++) {
	        var buf = list[0];
	        var cpy = Math.min(n - c, buf.length);

	        if (stringMode)
	          ret += buf.slice(0, cpy);
	        else
	          buf.copy(ret, c, 0, cpy);

	        if (cpy < buf.length)
	          list[0] = buf.slice(cpy);
	        else
	          list.shift();

	        c += cpy;
	      }
	    }
	  }

	  return ret;
	}

	function endReadable(stream) {
	  var state = stream._readableState;

	  // If we get here before consuming all the bytes, then that is a
	  // bug in node.  Should never happen.
	  if (state.length > 0)
	    throw new Error('endReadable called on non-empty stream');

	  if (!state.endEmitted) {
	    state.ended = true;
	    process.nextTick(function() {
	      // Check that we didn't get one last unshift.
	      if (!state.endEmitted && state.length === 0) {
	        state.endEmitted = true;
	        stream.readable = false;
	        stream.emit('end');
	      }
	    });
	  }
	}

	function forEach (xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}

	function indexOf (xs, x) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    if (xs[i] === x) return i;
	  }
	  return -1;
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 50 */
/***/ function(module, exports) {

	module.exports = Array.isArray || function (arr) {
	  return Object.prototype.toString.call(arr) == '[object Array]';
	};


/***/ },
/* 51 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.

	function isArray(arg) {
	  if (Array.isArray) {
	    return Array.isArray(arg);
	  }
	  return objectToString(arg) === '[object Array]';
	}
	exports.isArray = isArray;

	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;

	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;

	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;

	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;

	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;

	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;

	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;

	function isRegExp(re) {
	  return objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;

	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;

	function isDate(d) {
	  return objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;

	function isError(e) {
	  return (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;

	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;

	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;

	exports.isBuffer = Buffer.isBuffer;

	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer))

/***/ },
/* 52 */
/***/ function(module, exports) {

	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}


/***/ },
/* 53 */
/***/ function(module, exports) {

	/* (ignored) */

/***/ },
/* 54 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// a duplex stream is just a stream that is both readable and writable.
	// Since JS doesn't have multiple prototypal inheritance, this class
	// prototypally inherits from Readable, and then parasitically from
	// Writable.

	module.exports = Duplex;

	/*<replacement>*/
	var objectKeys = Object.keys || function (obj) {
	  var keys = [];
	  for (var key in obj) keys.push(key);
	  return keys;
	}
	/*</replacement>*/


	/*<replacement>*/
	var util = __webpack_require__(51);
	util.inherits = __webpack_require__(52);
	/*</replacement>*/

	var Readable = __webpack_require__(49);
	var Writable = __webpack_require__(55);

	util.inherits(Duplex, Readable);

	forEach(objectKeys(Writable.prototype), function(method) {
	  if (!Duplex.prototype[method])
	    Duplex.prototype[method] = Writable.prototype[method];
	});

	function Duplex(options) {
	  if (!(this instanceof Duplex))
	    return new Duplex(options);

	  Readable.call(this, options);
	  Writable.call(this, options);

	  if (options && options.readable === false)
	    this.readable = false;

	  if (options && options.writable === false)
	    this.writable = false;

	  this.allowHalfOpen = true;
	  if (options && options.allowHalfOpen === false)
	    this.allowHalfOpen = false;

	  this.once('end', onend);
	}

	// the no-half-open enforcer
	function onend() {
	  // if we allow half-open state, or if the writable side ended,
	  // then we're ok.
	  if (this.allowHalfOpen || this._writableState.ended)
	    return;

	  // no more data can be written.
	  // But allow more writes to happen in this tick.
	  process.nextTick(this.end.bind(this));
	}

	function forEach (xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// A bit simpler than readable streams.
	// Implement an async ._write(chunk, cb), and it'll handle all
	// the drain event emission and buffering.

	module.exports = Writable;

	/*<replacement>*/
	var Buffer = __webpack_require__(5).Buffer;
	/*</replacement>*/

	Writable.WritableState = WritableState;


	/*<replacement>*/
	var util = __webpack_require__(51);
	util.inherits = __webpack_require__(52);
	/*</replacement>*/

	var Stream = __webpack_require__(45);

	util.inherits(Writable, Stream);

	function WriteReq(chunk, encoding, cb) {
	  this.chunk = chunk;
	  this.encoding = encoding;
	  this.callback = cb;
	}

	function WritableState(options, stream) {
	  var Duplex = __webpack_require__(54);

	  options = options || {};

	  // the point at which write() starts returning false
	  // Note: 0 is a valid value, means that we always return false if
	  // the entire buffer is not flushed immediately on write()
	  var hwm = options.highWaterMark;
	  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;

	  // object stream flag to indicate whether or not this stream
	  // contains buffers or objects.
	  this.objectMode = !!options.objectMode;

	  if (stream instanceof Duplex)
	    this.objectMode = this.objectMode || !!options.writableObjectMode;

	  // cast to ints.
	  this.highWaterMark = ~~this.highWaterMark;

	  this.needDrain = false;
	  // at the start of calling end()
	  this.ending = false;
	  // when end() has been called, and returned
	  this.ended = false;
	  // when 'finish' is emitted
	  this.finished = false;

	  // should we decode strings into buffers before passing to _write?
	  // this is here so that some node-core streams can optimize string
	  // handling at a lower level.
	  var noDecode = options.decodeStrings === false;
	  this.decodeStrings = !noDecode;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // not an actual buffer we keep track of, but a measurement
	  // of how much we're waiting to get pushed to some underlying
	  // socket or file.
	  this.length = 0;

	  // a flag to see when we're in the middle of a write.
	  this.writing = false;

	  // when true all writes will be buffered until .uncork() call
	  this.corked = 0;

	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;

	  // a flag to know if we're processing previously buffered items, which
	  // may call the _write() callback in the same tick, so that we don't
	  // end up in an overlapped onwrite situation.
	  this.bufferProcessing = false;

	  // the callback that's passed to _write(chunk,cb)
	  this.onwrite = function(er) {
	    onwrite(stream, er);
	  };

	  // the callback that the user supplies to write(chunk,encoding,cb)
	  this.writecb = null;

	  // the amount that is being written when _write is called.
	  this.writelen = 0;

	  this.buffer = [];

	  // number of pending user-supplied write callbacks
	  // this must be 0 before 'finish' can be emitted
	  this.pendingcb = 0;

	  // emit prefinish if the only thing we're waiting for is _write cbs
	  // This is relevant for synchronous Transform streams
	  this.prefinished = false;

	  // True if the error was already emitted and should not be thrown again
	  this.errorEmitted = false;
	}

	function Writable(options) {
	  var Duplex = __webpack_require__(54);

	  // Writable ctor is applied to Duplexes, though they're not
	  // instanceof Writable, they're instanceof Readable.
	  if (!(this instanceof Writable) && !(this instanceof Duplex))
	    return new Writable(options);

	  this._writableState = new WritableState(options, this);

	  // legacy.
	  this.writable = true;

	  Stream.call(this);
	}

	// Otherwise people can pipe Writable streams, which is just wrong.
	Writable.prototype.pipe = function() {
	  this.emit('error', new Error('Cannot pipe. Not readable.'));
	};


	function writeAfterEnd(stream, state, cb) {
	  var er = new Error('write after end');
	  // TODO: defer error events consistently everywhere, not just the cb
	  stream.emit('error', er);
	  process.nextTick(function() {
	    cb(er);
	  });
	}

	// If we get something that is not a buffer, string, null, or undefined,
	// and we're not in objectMode, then that's an error.
	// Otherwise stream chunks are all considered to be of length=1, and the
	// watermarks determine how many objects to keep in the buffer, rather than
	// how many bytes or characters.
	function validChunk(stream, state, chunk, cb) {
	  var valid = true;
	  if (!util.isBuffer(chunk) &&
	      !util.isString(chunk) &&
	      !util.isNullOrUndefined(chunk) &&
	      !state.objectMode) {
	    var er = new TypeError('Invalid non-string/buffer chunk');
	    stream.emit('error', er);
	    process.nextTick(function() {
	      cb(er);
	    });
	    valid = false;
	  }
	  return valid;
	}

	Writable.prototype.write = function(chunk, encoding, cb) {
	  var state = this._writableState;
	  var ret = false;

	  if (util.isFunction(encoding)) {
	    cb = encoding;
	    encoding = null;
	  }

	  if (util.isBuffer(chunk))
	    encoding = 'buffer';
	  else if (!encoding)
	    encoding = state.defaultEncoding;

	  if (!util.isFunction(cb))
	    cb = function() {};

	  if (state.ended)
	    writeAfterEnd(this, state, cb);
	  else if (validChunk(this, state, chunk, cb)) {
	    state.pendingcb++;
	    ret = writeOrBuffer(this, state, chunk, encoding, cb);
	  }

	  return ret;
	};

	Writable.prototype.cork = function() {
	  var state = this._writableState;

	  state.corked++;
	};

	Writable.prototype.uncork = function() {
	  var state = this._writableState;

	  if (state.corked) {
	    state.corked--;

	    if (!state.writing &&
	        !state.corked &&
	        !state.finished &&
	        !state.bufferProcessing &&
	        state.buffer.length)
	      clearBuffer(this, state);
	  }
	};

	function decodeChunk(state, chunk, encoding) {
	  if (!state.objectMode &&
	      state.decodeStrings !== false &&
	      util.isString(chunk)) {
	    chunk = new Buffer(chunk, encoding);
	  }
	  return chunk;
	}

	// if we're already writing something, then just put this
	// in the queue, and wait our turn.  Otherwise, call _write
	// If we return false, then we need a drain event, so set that flag.
	function writeOrBuffer(stream, state, chunk, encoding, cb) {
	  chunk = decodeChunk(state, chunk, encoding);
	  if (util.isBuffer(chunk))
	    encoding = 'buffer';
	  var len = state.objectMode ? 1 : chunk.length;

	  state.length += len;

	  var ret = state.length < state.highWaterMark;
	  // we must ensure that previous needDrain will not be reset to false.
	  if (!ret)
	    state.needDrain = true;

	  if (state.writing || state.corked)
	    state.buffer.push(new WriteReq(chunk, encoding, cb));
	  else
	    doWrite(stream, state, false, len, chunk, encoding, cb);

	  return ret;
	}

	function doWrite(stream, state, writev, len, chunk, encoding, cb) {
	  state.writelen = len;
	  state.writecb = cb;
	  state.writing = true;
	  state.sync = true;
	  if (writev)
	    stream._writev(chunk, state.onwrite);
	  else
	    stream._write(chunk, encoding, state.onwrite);
	  state.sync = false;
	}

	function onwriteError(stream, state, sync, er, cb) {
	  if (sync)
	    process.nextTick(function() {
	      state.pendingcb--;
	      cb(er);
	    });
	  else {
	    state.pendingcb--;
	    cb(er);
	  }

	  stream._writableState.errorEmitted = true;
	  stream.emit('error', er);
	}

	function onwriteStateUpdate(state) {
	  state.writing = false;
	  state.writecb = null;
	  state.length -= state.writelen;
	  state.writelen = 0;
	}

	function onwrite(stream, er) {
	  var state = stream._writableState;
	  var sync = state.sync;
	  var cb = state.writecb;

	  onwriteStateUpdate(state);

	  if (er)
	    onwriteError(stream, state, sync, er, cb);
	  else {
	    // Check if we're actually ready to finish, but don't emit yet
	    var finished = needFinish(stream, state);

	    if (!finished &&
	        !state.corked &&
	        !state.bufferProcessing &&
	        state.buffer.length) {
	      clearBuffer(stream, state);
	    }

	    if (sync) {
	      process.nextTick(function() {
	        afterWrite(stream, state, finished, cb);
	      });
	    } else {
	      afterWrite(stream, state, finished, cb);
	    }
	  }
	}

	function afterWrite(stream, state, finished, cb) {
	  if (!finished)
	    onwriteDrain(stream, state);
	  state.pendingcb--;
	  cb();
	  finishMaybe(stream, state);
	}

	// Must force callback to be called on nextTick, so that we don't
	// emit 'drain' before the write() consumer gets the 'false' return
	// value, and has a chance to attach a 'drain' listener.
	function onwriteDrain(stream, state) {
	  if (state.length === 0 && state.needDrain) {
	    state.needDrain = false;
	    stream.emit('drain');
	  }
	}


	// if there's something in the buffer waiting, then process it
	function clearBuffer(stream, state) {
	  state.bufferProcessing = true;

	  if (stream._writev && state.buffer.length > 1) {
	    // Fast case, write everything using _writev()
	    var cbs = [];
	    for (var c = 0; c < state.buffer.length; c++)
	      cbs.push(state.buffer[c].callback);

	    // count the one we are adding, as well.
	    // TODO(isaacs) clean this up
	    state.pendingcb++;
	    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
	      for (var i = 0; i < cbs.length; i++) {
	        state.pendingcb--;
	        cbs[i](err);
	      }
	    });

	    // Clear buffer
	    state.buffer = [];
	  } else {
	    // Slow case, write chunks one-by-one
	    for (var c = 0; c < state.buffer.length; c++) {
	      var entry = state.buffer[c];
	      var chunk = entry.chunk;
	      var encoding = entry.encoding;
	      var cb = entry.callback;
	      var len = state.objectMode ? 1 : chunk.length;

	      doWrite(stream, state, false, len, chunk, encoding, cb);

	      // if we didn't call the onwrite immediately, then
	      // it means that we need to wait until it does.
	      // also, that means that the chunk and cb are currently
	      // being processed, so move the buffer counter past them.
	      if (state.writing) {
	        c++;
	        break;
	      }
	    }

	    if (c < state.buffer.length)
	      state.buffer = state.buffer.slice(c);
	    else
	      state.buffer.length = 0;
	  }

	  state.bufferProcessing = false;
	}

	Writable.prototype._write = function(chunk, encoding, cb) {
	  cb(new Error('not implemented'));

	};

	Writable.prototype._writev = null;

	Writable.prototype.end = function(chunk, encoding, cb) {
	  var state = this._writableState;

	  if (util.isFunction(chunk)) {
	    cb = chunk;
	    chunk = null;
	    encoding = null;
	  } else if (util.isFunction(encoding)) {
	    cb = encoding;
	    encoding = null;
	  }

	  if (!util.isNullOrUndefined(chunk))
	    this.write(chunk, encoding);

	  // .end() fully uncorks
	  if (state.corked) {
	    state.corked = 1;
	    this.uncork();
	  }

	  // ignore unnecessary end() calls.
	  if (!state.ending && !state.finished)
	    endWritable(this, state, cb);
	};


	function needFinish(stream, state) {
	  return (state.ending &&
	          state.length === 0 &&
	          !state.finished &&
	          !state.writing);
	}

	function prefinish(stream, state) {
	  if (!state.prefinished) {
	    state.prefinished = true;
	    stream.emit('prefinish');
	  }
	}

	function finishMaybe(stream, state) {
	  var need = needFinish(stream, state);
	  if (need) {
	    if (state.pendingcb === 0) {
	      prefinish(stream, state);
	      state.finished = true;
	      stream.emit('finish');
	    } else
	      prefinish(stream, state);
	  }
	  return need;
	}

	function endWritable(stream, state, cb) {
	  state.ending = true;
	  finishMaybe(stream, state);
	  if (cb) {
	    if (state.finished)
	      process.nextTick(cb);
	    else
	      stream.once('finish', cb);
	  }
	  state.ended = true;
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 56 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	var Buffer = __webpack_require__(5).Buffer;

	var isBufferEncoding = Buffer.isEncoding
	  || function(encoding) {
	       switch (encoding && encoding.toLowerCase()) {
	         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
	         default: return false;
	       }
	     }


	function assertEncoding(encoding) {
	  if (encoding && !isBufferEncoding(encoding)) {
	    throw new Error('Unknown encoding: ' + encoding);
	  }
	}

	// StringDecoder provides an interface for efficiently splitting a series of
	// buffers into a series of JS strings without breaking apart multi-byte
	// characters. CESU-8 is handled as part of the UTF-8 encoding.
	//
	// @TODO Handling all encodings inside a single object makes it very difficult
	// to reason about this code, so it should be split up in the future.
	// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
	// points as used by CESU-8.
	var StringDecoder = exports.StringDecoder = function(encoding) {
	  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
	  assertEncoding(encoding);
	  switch (this.encoding) {
	    case 'utf8':
	      // CESU-8 represents each of Surrogate Pair by 3-bytes
	      this.surrogateSize = 3;
	      break;
	    case 'ucs2':
	    case 'utf16le':
	      // UTF-16 represents each of Surrogate Pair by 2-bytes
	      this.surrogateSize = 2;
	      this.detectIncompleteChar = utf16DetectIncompleteChar;
	      break;
	    case 'base64':
	      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
	      this.surrogateSize = 3;
	      this.detectIncompleteChar = base64DetectIncompleteChar;
	      break;
	    default:
	      this.write = passThroughWrite;
	      return;
	  }

	  // Enough space to store all bytes of a single character. UTF-8 needs 4
	  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
	  this.charBuffer = new Buffer(6);
	  // Number of bytes received for the current incomplete multi-byte character.
	  this.charReceived = 0;
	  // Number of bytes expected for the current incomplete multi-byte character.
	  this.charLength = 0;
	};


	// write decodes the given buffer and returns it as JS string that is
	// guaranteed to not contain any partial multi-byte characters. Any partial
	// character found at the end of the buffer is buffered up, and will be
	// returned when calling write again with the remaining bytes.
	//
	// Note: Converting a Buffer containing an orphan surrogate to a String
	// currently works, but converting a String to a Buffer (via `new Buffer`, or
	// Buffer#write) will replace incomplete surrogates with the unicode
	// replacement character. See https://codereview.chromium.org/121173009/ .
	StringDecoder.prototype.write = function(buffer) {
	  var charStr = '';
	  // if our last write ended with an incomplete multibyte character
	  while (this.charLength) {
	    // determine how many remaining bytes this buffer has to offer for this char
	    var available = (buffer.length >= this.charLength - this.charReceived) ?
	        this.charLength - this.charReceived :
	        buffer.length;

	    // add the new bytes to the char buffer
	    buffer.copy(this.charBuffer, this.charReceived, 0, available);
	    this.charReceived += available;

	    if (this.charReceived < this.charLength) {
	      // still not enough chars in this buffer? wait for more ...
	      return '';
	    }

	    // remove bytes belonging to the current character from the buffer
	    buffer = buffer.slice(available, buffer.length);

	    // get the character that was split
	    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);

	    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
	    var charCode = charStr.charCodeAt(charStr.length - 1);
	    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
	      this.charLength += this.surrogateSize;
	      charStr = '';
	      continue;
	    }
	    this.charReceived = this.charLength = 0;

	    // if there are no more bytes in this buffer, just emit our char
	    if (buffer.length === 0) {
	      return charStr;
	    }
	    break;
	  }

	  // determine and set charLength / charReceived
	  this.detectIncompleteChar(buffer);

	  var end = buffer.length;
	  if (this.charLength) {
	    // buffer the incomplete character bytes we got
	    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
	    end -= this.charReceived;
	  }

	  charStr += buffer.toString(this.encoding, 0, end);

	  var end = charStr.length - 1;
	  var charCode = charStr.charCodeAt(end);
	  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
	  if (charCode >= 0xD800 && charCode <= 0xDBFF) {
	    var size = this.surrogateSize;
	    this.charLength += size;
	    this.charReceived += size;
	    this.charBuffer.copy(this.charBuffer, size, 0, size);
	    buffer.copy(this.charBuffer, 0, 0, size);
	    return charStr.substring(0, end);
	  }

	  // or just emit the charStr
	  return charStr;
	};

	// detectIncompleteChar determines if there is an incomplete UTF-8 character at
	// the end of the given buffer. If so, it sets this.charLength to the byte
	// length that character, and sets this.charReceived to the number of bytes
	// that are available for this character.
	StringDecoder.prototype.detectIncompleteChar = function(buffer) {
	  // determine how many bytes we have to check at the end of this buffer
	  var i = (buffer.length >= 3) ? 3 : buffer.length;

	  // Figure out if one of the last i bytes of our buffer announces an
	  // incomplete char.
	  for (; i > 0; i--) {
	    var c = buffer[buffer.length - i];

	    // See http://en.wikipedia.org/wiki/UTF-8#Description

	    // 110XXXXX
	    if (i == 1 && c >> 5 == 0x06) {
	      this.charLength = 2;
	      break;
	    }

	    // 1110XXXX
	    if (i <= 2 && c >> 4 == 0x0E) {
	      this.charLength = 3;
	      break;
	    }

	    // 11110XXX
	    if (i <= 3 && c >> 3 == 0x1E) {
	      this.charLength = 4;
	      break;
	    }
	  }
	  this.charReceived = i;
	};

	StringDecoder.prototype.end = function(buffer) {
	  var res = '';
	  if (buffer && buffer.length)
	    res = this.write(buffer);

	  if (this.charReceived) {
	    var cr = this.charReceived;
	    var buf = this.charBuffer;
	    var enc = this.encoding;
	    res += buf.slice(0, cr).toString(enc);
	  }

	  return res;
	};

	function passThroughWrite(buffer) {
	  return buffer.toString(this.encoding);
	}

	function utf16DetectIncompleteChar(buffer) {
	  this.charReceived = buffer.length % 2;
	  this.charLength = this.charReceived ? 2 : 0;
	}

	function base64DetectIncompleteChar(buffer) {
	  this.charReceived = buffer.length % 3;
	  this.charLength = this.charReceived ? 3 : 0;
	}


/***/ },
/* 57 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.


	// a transform stream is a readable/writable stream where you do
	// something with the data.  Sometimes it's called a "filter",
	// but that's not a great name for it, since that implies a thing where
	// some bits pass through, and others are simply ignored.  (That would
	// be a valid example of a transform, of course.)
	//
	// While the output is causally related to the input, it's not a
	// necessarily symmetric or synchronous transformation.  For example,
	// a zlib stream might take multiple plain-text writes(), and then
	// emit a single compressed chunk some time in the future.
	//
	// Here's how this works:
	//
	// The Transform stream has all the aspects of the readable and writable
	// stream classes.  When you write(chunk), that calls _write(chunk,cb)
	// internally, and returns false if there's a lot of pending writes
	// buffered up.  When you call read(), that calls _read(n) until
	// there's enough pending readable data buffered up.
	//
	// In a transform stream, the written data is placed in a buffer.  When
	// _read(n) is called, it transforms the queued up data, calling the
	// buffered _write cb's as it consumes chunks.  If consuming a single
	// written chunk would result in multiple output chunks, then the first
	// outputted bit calls the readcb, and subsequent chunks just go into
	// the read buffer, and will cause it to emit 'readable' if necessary.
	//
	// This way, back-pressure is actually determined by the reading side,
	// since _read has to be called to start processing a new chunk.  However,
	// a pathological inflate type of transform can cause excessive buffering
	// here.  For example, imagine a stream where every byte of input is
	// interpreted as an integer from 0-255, and then results in that many
	// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
	// 1kb of data being output.  In this case, you could write a very small
	// amount of input, and end up with a very large amount of output.  In
	// such a pathological inflating mechanism, there'd be no way to tell
	// the system to stop doing the transform.  A single 4MB write could
	// cause the system to run out of memory.
	//
	// However, even in such a pathological case, only a single written chunk
	// would be consumed, and then the rest would wait (un-transformed) until
	// the results of the previous transformed chunk were consumed.

	module.exports = Transform;

	var Duplex = __webpack_require__(54);

	/*<replacement>*/
	var util = __webpack_require__(51);
	util.inherits = __webpack_require__(52);
	/*</replacement>*/

	util.inherits(Transform, Duplex);


	function TransformState(options, stream) {
	  this.afterTransform = function(er, data) {
	    return afterTransform(stream, er, data);
	  };

	  this.needTransform = false;
	  this.transforming = false;
	  this.writecb = null;
	  this.writechunk = null;
	}

	function afterTransform(stream, er, data) {
	  var ts = stream._transformState;
	  ts.transforming = false;

	  var cb = ts.writecb;

	  if (!cb)
	    return stream.emit('error', new Error('no writecb in Transform class'));

	  ts.writechunk = null;
	  ts.writecb = null;

	  if (!util.isNullOrUndefined(data))
	    stream.push(data);

	  if (cb)
	    cb(er);

	  var rs = stream._readableState;
	  rs.reading = false;
	  if (rs.needReadable || rs.length < rs.highWaterMark) {
	    stream._read(rs.highWaterMark);
	  }
	}


	function Transform(options) {
	  if (!(this instanceof Transform))
	    return new Transform(options);

	  Duplex.call(this, options);

	  this._transformState = new TransformState(options, this);

	  // when the writable side finishes, then flush out anything remaining.
	  var stream = this;

	  // start out asking for a readable event once data is transformed.
	  this._readableState.needReadable = true;

	  // we have implemented the _read method, and done the other things
	  // that Readable wants before the first _read call, so unset the
	  // sync guard flag.
	  this._readableState.sync = false;

	  this.once('prefinish', function() {
	    if (util.isFunction(this._flush))
	      this._flush(function(er) {
	        done(stream, er);
	      });
	    else
	      done(stream);
	  });
	}

	Transform.prototype.push = function(chunk, encoding) {
	  this._transformState.needTransform = false;
	  return Duplex.prototype.push.call(this, chunk, encoding);
	};

	// This is the part where you do stuff!
	// override this function in implementation classes.
	// 'chunk' is an input chunk.
	//
	// Call `push(newChunk)` to pass along transformed output
	// to the readable side.  You may call 'push' zero or more times.
	//
	// Call `cb(err)` when you are done with this chunk.  If you pass
	// an error, then that'll put the hurt on the whole operation.  If you
	// never call cb(), then you'll never get another chunk.
	Transform.prototype._transform = function(chunk, encoding, cb) {
	  throw new Error('not implemented');
	};

	Transform.prototype._write = function(chunk, encoding, cb) {
	  var ts = this._transformState;
	  ts.writecb = cb;
	  ts.writechunk = chunk;
	  ts.writeencoding = encoding;
	  if (!ts.transforming) {
	    var rs = this._readableState;
	    if (ts.needTransform ||
	        rs.needReadable ||
	        rs.length < rs.highWaterMark)
	      this._read(rs.highWaterMark);
	  }
	};

	// Doesn't matter what the args are here.
	// _transform does all the work.
	// That we got here means that the readable side wants more data.
	Transform.prototype._read = function(n) {
	  var ts = this._transformState;

	  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
	    ts.transforming = true;
	    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
	  } else {
	    // mark that we need a transform, so that any data that comes in
	    // will get processed, now that we've asked for it.
	    ts.needTransform = true;
	  }
	};


	function done(stream, er) {
	  if (er)
	    return stream.emit('error', er);

	  // if there's nothing in the write buffer, then that means
	  // that nothing more will ever be provided
	  var ws = stream._writableState;
	  var ts = stream._transformState;

	  if (ws.length)
	    throw new Error('calling transform done when ws.length != 0');

	  if (ts.transforming)
	    throw new Error('calling transform done when still transforming');

	  return stream.push(null);
	}


/***/ },
/* 58 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// a passthrough stream.
	// basically just the most minimal sort of Transform stream.
	// Every written chunk gets output as-is.

	module.exports = PassThrough;

	var Transform = __webpack_require__(57);

	/*<replacement>*/
	var util = __webpack_require__(51);
	util.inherits = __webpack_require__(52);
	/*</replacement>*/

	util.inherits(PassThrough, Transform);

	function PassThrough(options) {
	  if (!(this instanceof PassThrough))
	    return new PassThrough(options);

	  Transform.call(this, options);
	}

	PassThrough.prototype._transform = function(chunk, encoding, cb) {
	  cb(null, chunk);
	};


/***/ },
/* 59 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(55)


/***/ },
/* 60 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(54)


/***/ },
/* 61 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(57)


/***/ },
/* 62 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(58)


/***/ },
/* 63 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {'use strict';

	module.exports = Readable;

	/*<replacement>*/
	var processNextTick = __webpack_require__(64);
	/*</replacement>*/


	/*<replacement>*/
	var isArray = __webpack_require__(65);
	/*</replacement>*/


	/*<replacement>*/
	var Buffer = __webpack_require__(5).Buffer;
	/*</replacement>*/

	Readable.ReadableState = ReadableState;

	var EE = __webpack_require__(46);

	/*<replacement>*/
	var EElistenerCount = function(emitter, type) {
	  return emitter.listeners(type).length;
	};
	/*</replacement>*/



	/*<replacement>*/
	var Stream;
	(function (){try{
	  Stream = __webpack_require__(45);
	}catch(_){}finally{
	  if (!Stream)
	    Stream = __webpack_require__(46).EventEmitter;
	}}())
	/*</replacement>*/

	var Buffer = __webpack_require__(5).Buffer;

	/*<replacement>*/
	var util = __webpack_require__(66);
	util.inherits = __webpack_require__(67);
	/*</replacement>*/



	/*<replacement>*/
	var debugUtil = __webpack_require__(68);
	var debug;
	if (debugUtil && debugUtil.debuglog) {
	  debug = debugUtil.debuglog('stream');
	} else {
	  debug = function () {};
	}
	/*</replacement>*/

	var StringDecoder;

	util.inherits(Readable, Stream);

	var Duplex;
	function ReadableState(options, stream) {
	  Duplex = Duplex || __webpack_require__(69);

	  options = options || {};

	  // object stream flag. Used to make read(n) ignore n and to
	  // make all the buffer merging and length checks go away
	  this.objectMode = !!options.objectMode;

	  if (stream instanceof Duplex)
	    this.objectMode = this.objectMode || !!options.readableObjectMode;

	  // the point at which it stops calling _read() to fill the buffer
	  // Note: 0 is a valid value, means "don't call _read preemptively ever"
	  var hwm = options.highWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;

	  // cast to ints.
	  this.highWaterMark = ~~this.highWaterMark;

	  this.buffer = [];
	  this.length = 0;
	  this.pipes = null;
	  this.pipesCount = 0;
	  this.flowing = null;
	  this.ended = false;
	  this.endEmitted = false;
	  this.reading = false;

	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;

	  // whenever we return null, then we set a flag to say
	  // that we're awaiting a 'readable' event emission.
	  this.needReadable = false;
	  this.emittedReadable = false;
	  this.readableListening = false;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // when piping, we only care about 'readable' events that happen
	  // after read()ing all the bytes and not getting any pushback.
	  this.ranOut = false;

	  // the number of writers that are awaiting a drain event in .pipe()s
	  this.awaitDrain = 0;

	  // if true, a maybeReadMore has been scheduled
	  this.readingMore = false;

	  this.decoder = null;
	  this.encoding = null;
	  if (options.encoding) {
	    if (!StringDecoder)
	      StringDecoder = __webpack_require__(72).StringDecoder;
	    this.decoder = new StringDecoder(options.encoding);
	    this.encoding = options.encoding;
	  }
	}

	var Duplex;
	function Readable(options) {
	  Duplex = Duplex || __webpack_require__(69);

	  if (!(this instanceof Readable))
	    return new Readable(options);

	  this._readableState = new ReadableState(options, this);

	  // legacy
	  this.readable = true;

	  if (options && typeof options.read === 'function')
	    this._read = options.read;

	  Stream.call(this);
	}

	// Manually shove something into the read() buffer.
	// This returns true if the highWaterMark has not been hit yet,
	// similar to how Writable.write() returns true if you should
	// write() some more.
	Readable.prototype.push = function(chunk, encoding) {
	  var state = this._readableState;

	  if (!state.objectMode && typeof chunk === 'string') {
	    encoding = encoding || state.defaultEncoding;
	    if (encoding !== state.encoding) {
	      chunk = new Buffer(chunk, encoding);
	      encoding = '';
	    }
	  }

	  return readableAddChunk(this, state, chunk, encoding, false);
	};

	// Unshift should *always* be something directly out of read()
	Readable.prototype.unshift = function(chunk) {
	  var state = this._readableState;
	  return readableAddChunk(this, state, chunk, '', true);
	};

	Readable.prototype.isPaused = function() {
	  return this._readableState.flowing === false;
	};

	function readableAddChunk(stream, state, chunk, encoding, addToFront) {
	  var er = chunkInvalid(state, chunk);
	  if (er) {
	    stream.emit('error', er);
	  } else if (chunk === null) {
	    state.reading = false;
	    onEofChunk(stream, state);
	  } else if (state.objectMode || chunk && chunk.length > 0) {
	    if (state.ended && !addToFront) {
	      var e = new Error('stream.push() after EOF');
	      stream.emit('error', e);
	    } else if (state.endEmitted && addToFront) {
	      var e = new Error('stream.unshift() after end event');
	      stream.emit('error', e);
	    } else {
	      if (state.decoder && !addToFront && !encoding)
	        chunk = state.decoder.write(chunk);

	      if (!addToFront)
	        state.reading = false;

	      // if we want the data now, just emit it.
	      if (state.flowing && state.length === 0 && !state.sync) {
	        stream.emit('data', chunk);
	        stream.read(0);
	      } else {
	        // update the buffer info.
	        state.length += state.objectMode ? 1 : chunk.length;
	        if (addToFront)
	          state.buffer.unshift(chunk);
	        else
	          state.buffer.push(chunk);

	        if (state.needReadable)
	          emitReadable(stream);
	      }

	      maybeReadMore(stream, state);
	    }
	  } else if (!addToFront) {
	    state.reading = false;
	  }

	  return needMoreData(state);
	}


	// if it's past the high water mark, we can push in some more.
	// Also, if we have no data yet, we can stand some
	// more bytes.  This is to work around cases where hwm=0,
	// such as the repl.  Also, if the push() triggered a
	// readable event, and the user called read(largeNumber) such that
	// needReadable was set, then we ought to push more, so that another
	// 'readable' event will be triggered.
	function needMoreData(state) {
	  return !state.ended &&
	         (state.needReadable ||
	          state.length < state.highWaterMark ||
	          state.length === 0);
	}

	// backwards compatibility.
	Readable.prototype.setEncoding = function(enc) {
	  if (!StringDecoder)
	    StringDecoder = __webpack_require__(72).StringDecoder;
	  this._readableState.decoder = new StringDecoder(enc);
	  this._readableState.encoding = enc;
	  return this;
	};

	// Don't raise the hwm > 8MB
	var MAX_HWM = 0x800000;
	function computeNewHighWaterMark(n) {
	  if (n >= MAX_HWM) {
	    n = MAX_HWM;
	  } else {
	    // Get the next highest power of 2
	    n--;
	    n |= n >>> 1;
	    n |= n >>> 2;
	    n |= n >>> 4;
	    n |= n >>> 8;
	    n |= n >>> 16;
	    n++;
	  }
	  return n;
	}

	function howMuchToRead(n, state) {
	  if (state.length === 0 && state.ended)
	    return 0;

	  if (state.objectMode)
	    return n === 0 ? 0 : 1;

	  if (n === null || isNaN(n)) {
	    // only flow one buffer at a time
	    if (state.flowing && state.buffer.length)
	      return state.buffer[0].length;
	    else
	      return state.length;
	  }

	  if (n <= 0)
	    return 0;

	  // If we're asking for more than the target buffer level,
	  // then raise the water mark.  Bump up to the next highest
	  // power of 2, to prevent increasing it excessively in tiny
	  // amounts.
	  if (n > state.highWaterMark)
	    state.highWaterMark = computeNewHighWaterMark(n);

	  // don't have that much.  return null, unless we've ended.
	  if (n > state.length) {
	    if (!state.ended) {
	      state.needReadable = true;
	      return 0;
	    } else {
	      return state.length;
	    }
	  }

	  return n;
	}

	// you can override either this method, or the async _read(n) below.
	Readable.prototype.read = function(n) {
	  debug('read', n);
	  var state = this._readableState;
	  var nOrig = n;

	  if (typeof n !== 'number' || n > 0)
	    state.emittedReadable = false;

	  // if we're doing read(0) to trigger a readable event, but we
	  // already have a bunch of data in the buffer, then just trigger
	  // the 'readable' event and move on.
	  if (n === 0 &&
	      state.needReadable &&
	      (state.length >= state.highWaterMark || state.ended)) {
	    debug('read: emitReadable', state.length, state.ended);
	    if (state.length === 0 && state.ended)
	      endReadable(this);
	    else
	      emitReadable(this);
	    return null;
	  }

	  n = howMuchToRead(n, state);

	  // if we've ended, and we're now clear, then finish it up.
	  if (n === 0 && state.ended) {
	    if (state.length === 0)
	      endReadable(this);
	    return null;
	  }

	  // All the actual chunk generation logic needs to be
	  // *below* the call to _read.  The reason is that in certain
	  // synthetic stream cases, such as passthrough streams, _read
	  // may be a completely synchronous operation which may change
	  // the state of the read buffer, providing enough data when
	  // before there was *not* enough.
	  //
	  // So, the steps are:
	  // 1. Figure out what the state of things will be after we do
	  // a read from the buffer.
	  //
	  // 2. If that resulting state will trigger a _read, then call _read.
	  // Note that this may be asynchronous, or synchronous.  Yes, it is
	  // deeply ugly to write APIs this way, but that still doesn't mean
	  // that the Readable class should behave improperly, as streams are
	  // designed to be sync/async agnostic.
	  // Take note if the _read call is sync or async (ie, if the read call
	  // has returned yet), so that we know whether or not it's safe to emit
	  // 'readable' etc.
	  //
	  // 3. Actually pull the requested chunks out of the buffer and return.

	  // if we need a readable event, then we need to do some reading.
	  var doRead = state.needReadable;
	  debug('need readable', doRead);

	  // if we currently have less than the highWaterMark, then also read some
	  if (state.length === 0 || state.length - n < state.highWaterMark) {
	    doRead = true;
	    debug('length less than watermark', doRead);
	  }

	  // however, if we've ended, then there's no point, and if we're already
	  // reading, then it's unnecessary.
	  if (state.ended || state.reading) {
	    doRead = false;
	    debug('reading or ended', doRead);
	  }

	  if (doRead) {
	    debug('do read');
	    state.reading = true;
	    state.sync = true;
	    // if the length is currently zero, then we *need* a readable event.
	    if (state.length === 0)
	      state.needReadable = true;
	    // call internal read method
	    this._read(state.highWaterMark);
	    state.sync = false;
	  }

	  // If _read pushed data synchronously, then `reading` will be false,
	  // and we need to re-evaluate how much data we can return to the user.
	  if (doRead && !state.reading)
	    n = howMuchToRead(nOrig, state);

	  var ret;
	  if (n > 0)
	    ret = fromList(n, state);
	  else
	    ret = null;

	  if (ret === null) {
	    state.needReadable = true;
	    n = 0;
	  }

	  state.length -= n;

	  // If we have nothing in the buffer, then we want to know
	  // as soon as we *do* get something into the buffer.
	  if (state.length === 0 && !state.ended)
	    state.needReadable = true;

	  // If we tried to read() past the EOF, then emit end on the next tick.
	  if (nOrig !== n && state.ended && state.length === 0)
	    endReadable(this);

	  if (ret !== null)
	    this.emit('data', ret);

	  return ret;
	};

	function chunkInvalid(state, chunk) {
	  var er = null;
	  if (!(Buffer.isBuffer(chunk)) &&
	      typeof chunk !== 'string' &&
	      chunk !== null &&
	      chunk !== undefined &&
	      !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  return er;
	}


	function onEofChunk(stream, state) {
	  if (state.ended) return;
	  if (state.decoder) {
	    var chunk = state.decoder.end();
	    if (chunk && chunk.length) {
	      state.buffer.push(chunk);
	      state.length += state.objectMode ? 1 : chunk.length;
	    }
	  }
	  state.ended = true;

	  // emit 'readable' now to make sure it gets picked up.
	  emitReadable(stream);
	}

	// Don't emit readable right away in sync mode, because this can trigger
	// another read() call => stack overflow.  This way, it might trigger
	// a nextTick recursion warning, but that's not so bad.
	function emitReadable(stream) {
	  var state = stream._readableState;
	  state.needReadable = false;
	  if (!state.emittedReadable) {
	    debug('emitReadable', state.flowing);
	    state.emittedReadable = true;
	    if (state.sync)
	      processNextTick(emitReadable_, stream);
	    else
	      emitReadable_(stream);
	  }
	}

	function emitReadable_(stream) {
	  debug('emit readable');
	  stream.emit('readable');
	  flow(stream);
	}


	// at this point, the user has presumably seen the 'readable' event,
	// and called read() to consume some data.  that may have triggered
	// in turn another _read(n) call, in which case reading = true if
	// it's in progress.
	// However, if we're not ended, or reading, and the length < hwm,
	// then go ahead and try to read some more preemptively.
	function maybeReadMore(stream, state) {
	  if (!state.readingMore) {
	    state.readingMore = true;
	    processNextTick(maybeReadMore_, stream, state);
	  }
	}

	function maybeReadMore_(stream, state) {
	  var len = state.length;
	  while (!state.reading && !state.flowing && !state.ended &&
	         state.length < state.highWaterMark) {
	    debug('maybeReadMore read 0');
	    stream.read(0);
	    if (len === state.length)
	      // didn't get any data, stop spinning.
	      break;
	    else
	      len = state.length;
	  }
	  state.readingMore = false;
	}

	// abstract method.  to be overridden in specific implementation classes.
	// call cb(er, data) where data is <= n in length.
	// for virtual (non-string, non-buffer) streams, "length" is somewhat
	// arbitrary, and perhaps not very meaningful.
	Readable.prototype._read = function(n) {
	  this.emit('error', new Error('not implemented'));
	};

	Readable.prototype.pipe = function(dest, pipeOpts) {
	  var src = this;
	  var state = this._readableState;

	  switch (state.pipesCount) {
	    case 0:
	      state.pipes = dest;
	      break;
	    case 1:
	      state.pipes = [state.pipes, dest];
	      break;
	    default:
	      state.pipes.push(dest);
	      break;
	  }
	  state.pipesCount += 1;
	  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);

	  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
	              dest !== process.stdout &&
	              dest !== process.stderr;

	  var endFn = doEnd ? onend : cleanup;
	  if (state.endEmitted)
	    processNextTick(endFn);
	  else
	    src.once('end', endFn);

	  dest.on('unpipe', onunpipe);
	  function onunpipe(readable) {
	    debug('onunpipe');
	    if (readable === src) {
	      cleanup();
	    }
	  }

	  function onend() {
	    debug('onend');
	    dest.end();
	  }

	  // when the dest drains, it reduces the awaitDrain counter
	  // on the source.  This would be more elegant with a .once()
	  // handler in flow(), but adding and removing repeatedly is
	  // too slow.
	  var ondrain = pipeOnDrain(src);
	  dest.on('drain', ondrain);

	  var cleanedUp = false;
	  function cleanup() {
	    debug('cleanup');
	    // cleanup event handlers once the pipe is broken
	    dest.removeListener('close', onclose);
	    dest.removeListener('finish', onfinish);
	    dest.removeListener('drain', ondrain);
	    dest.removeListener('error', onerror);
	    dest.removeListener('unpipe', onunpipe);
	    src.removeListener('end', onend);
	    src.removeListener('end', cleanup);
	    src.removeListener('data', ondata);

	    cleanedUp = true;

	    // if the reader is waiting for a drain event from this
	    // specific writer, then it would cause it to never start
	    // flowing again.
	    // So, if this is awaiting a drain, then we just call it now.
	    // If we don't know, then assume that we are waiting for one.
	    if (state.awaitDrain &&
	        (!dest._writableState || dest._writableState.needDrain))
	      ondrain();
	  }

	  src.on('data', ondata);
	  function ondata(chunk) {
	    debug('ondata');
	    var ret = dest.write(chunk);
	    if (false === ret) {
	      // If the user unpiped during `dest.write()`, it is possible
	      // to get stuck in a permanently paused state if that write
	      // also returned false.
	      if (state.pipesCount === 1 &&
	          state.pipes[0] === dest &&
	          src.listenerCount('data') === 1 &&
	          !cleanedUp) {
	        debug('false write response, pause', src._readableState.awaitDrain);
	        src._readableState.awaitDrain++;
	      }
	      src.pause();
	    }
	  }

	  // if the dest has an error, then stop piping into it.
	  // however, don't suppress the throwing behavior for this.
	  function onerror(er) {
	    debug('onerror', er);
	    unpipe();
	    dest.removeListener('error', onerror);
	    if (EElistenerCount(dest, 'error') === 0)
	      dest.emit('error', er);
	  }
	  // This is a brutally ugly hack to make sure that our error handler
	  // is attached before any userland ones.  NEVER DO THIS.
	  if (!dest._events || !dest._events.error)
	    dest.on('error', onerror);
	  else if (isArray(dest._events.error))
	    dest._events.error.unshift(onerror);
	  else
	    dest._events.error = [onerror, dest._events.error];


	  // Both close and finish should trigger unpipe, but only once.
	  function onclose() {
	    dest.removeListener('finish', onfinish);
	    unpipe();
	  }
	  dest.once('close', onclose);
	  function onfinish() {
	    debug('onfinish');
	    dest.removeListener('close', onclose);
	    unpipe();
	  }
	  dest.once('finish', onfinish);

	  function unpipe() {
	    debug('unpipe');
	    src.unpipe(dest);
	  }

	  // tell the dest that it's being piped to
	  dest.emit('pipe', src);

	  // start the flow if it hasn't been started already.
	  if (!state.flowing) {
	    debug('pipe resume');
	    src.resume();
	  }

	  return dest;
	};

	function pipeOnDrain(src) {
	  return function() {
	    var state = src._readableState;
	    debug('pipeOnDrain', state.awaitDrain);
	    if (state.awaitDrain)
	      state.awaitDrain--;
	    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
	      state.flowing = true;
	      flow(src);
	    }
	  };
	}


	Readable.prototype.unpipe = function(dest) {
	  var state = this._readableState;

	  // if we're not piping anywhere, then do nothing.
	  if (state.pipesCount === 0)
	    return this;

	  // just one destination.  most common case.
	  if (state.pipesCount === 1) {
	    // passed in one, but it's not the right one.
	    if (dest && dest !== state.pipes)
	      return this;

	    if (!dest)
	      dest = state.pipes;

	    // got a match.
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    if (dest)
	      dest.emit('unpipe', this);
	    return this;
	  }

	  // slow case. multiple pipe destinations.

	  if (!dest) {
	    // remove all.
	    var dests = state.pipes;
	    var len = state.pipesCount;
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;

	    for (var i = 0; i < len; i++)
	      dests[i].emit('unpipe', this);
	    return this;
	  }

	  // try to find the right one.
	  var i = indexOf(state.pipes, dest);
	  if (i === -1)
	    return this;

	  state.pipes.splice(i, 1);
	  state.pipesCount -= 1;
	  if (state.pipesCount === 1)
	    state.pipes = state.pipes[0];

	  dest.emit('unpipe', this);

	  return this;
	};

	// set up data events if they are asked for
	// Ensure readable listeners eventually get something
	Readable.prototype.on = function(ev, fn) {
	  var res = Stream.prototype.on.call(this, ev, fn);

	  // If listening to data, and it has not explicitly been paused,
	  // then call resume to start the flow of data on the next tick.
	  if (ev === 'data' && false !== this._readableState.flowing) {
	    this.resume();
	  }

	  if (ev === 'readable' && this.readable) {
	    var state = this._readableState;
	    if (!state.readableListening) {
	      state.readableListening = true;
	      state.emittedReadable = false;
	      state.needReadable = true;
	      if (!state.reading) {
	        processNextTick(nReadingNextTick, this);
	      } else if (state.length) {
	        emitReadable(this, state);
	      }
	    }
	  }

	  return res;
	};
	Readable.prototype.addListener = Readable.prototype.on;

	function nReadingNextTick(self) {
	  debug('readable nexttick read 0');
	  self.read(0);
	}

	// pause() and resume() are remnants of the legacy readable stream API
	// If the user uses them, then switch into old mode.
	Readable.prototype.resume = function() {
	  var state = this._readableState;
	  if (!state.flowing) {
	    debug('resume');
	    state.flowing = true;
	    resume(this, state);
	  }
	  return this;
	};

	function resume(stream, state) {
	  if (!state.resumeScheduled) {
	    state.resumeScheduled = true;
	    processNextTick(resume_, stream, state);
	  }
	}

	function resume_(stream, state) {
	  if (!state.reading) {
	    debug('resume read 0');
	    stream.read(0);
	  }

	  state.resumeScheduled = false;
	  stream.emit('resume');
	  flow(stream);
	  if (state.flowing && !state.reading)
	    stream.read(0);
	}

	Readable.prototype.pause = function() {
	  debug('call pause flowing=%j', this._readableState.flowing);
	  if (false !== this._readableState.flowing) {
	    debug('pause');
	    this._readableState.flowing = false;
	    this.emit('pause');
	  }
	  return this;
	};

	function flow(stream) {
	  var state = stream._readableState;
	  debug('flow', state.flowing);
	  if (state.flowing) {
	    do {
	      var chunk = stream.read();
	    } while (null !== chunk && state.flowing);
	  }
	}

	// wrap an old-style stream as the async data source.
	// This is *not* part of the readable stream interface.
	// It is an ugly unfortunate mess of history.
	Readable.prototype.wrap = function(stream) {
	  var state = this._readableState;
	  var paused = false;

	  var self = this;
	  stream.on('end', function() {
	    debug('wrapped end');
	    if (state.decoder && !state.ended) {
	      var chunk = state.decoder.end();
	      if (chunk && chunk.length)
	        self.push(chunk);
	    }

	    self.push(null);
	  });

	  stream.on('data', function(chunk) {
	    debug('wrapped data');
	    if (state.decoder)
	      chunk = state.decoder.write(chunk);

	    // don't skip over falsy values in objectMode
	    if (state.objectMode && (chunk === null || chunk === undefined))
	      return;
	    else if (!state.objectMode && (!chunk || !chunk.length))
	      return;

	    var ret = self.push(chunk);
	    if (!ret) {
	      paused = true;
	      stream.pause();
	    }
	  });

	  // proxy all the other methods.
	  // important when wrapping filters and duplexes.
	  for (var i in stream) {
	    if (this[i] === undefined && typeof stream[i] === 'function') {
	      this[i] = function(method) { return function() {
	        return stream[method].apply(stream, arguments);
	      }; }(i);
	    }
	  }

	  // proxy certain important events.
	  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
	  forEach(events, function(ev) {
	    stream.on(ev, self.emit.bind(self, ev));
	  });

	  // when we try to consume some more bytes, simply unpause the
	  // underlying stream.
	  self._read = function(n) {
	    debug('wrapped _read', n);
	    if (paused) {
	      paused = false;
	      stream.resume();
	    }
	  };

	  return self;
	};


	// exposed for testing purposes only.
	Readable._fromList = fromList;

	// Pluck off n bytes from an array of buffers.
	// Length is the combined lengths of all the buffers in the list.
	function fromList(n, state) {
	  var list = state.buffer;
	  var length = state.length;
	  var stringMode = !!state.decoder;
	  var objectMode = !!state.objectMode;
	  var ret;

	  // nothing in the list, definitely empty.
	  if (list.length === 0)
	    return null;

	  if (length === 0)
	    ret = null;
	  else if (objectMode)
	    ret = list.shift();
	  else if (!n || n >= length) {
	    // read it all, truncate the array.
	    if (stringMode)
	      ret = list.join('');
	    else if (list.length === 1)
	      ret = list[0];
	    else
	      ret = Buffer.concat(list, length);
	    list.length = 0;
	  } else {
	    // read just some of it.
	    if (n < list[0].length) {
	      // just take a part of the first list item.
	      // slice is the same for buffers and strings.
	      var buf = list[0];
	      ret = buf.slice(0, n);
	      list[0] = buf.slice(n);
	    } else if (n === list[0].length) {
	      // first list is a perfect match
	      ret = list.shift();
	    } else {
	      // complex case.
	      // we have enough to cover it, but it spans past the first buffer.
	      if (stringMode)
	        ret = '';
	      else
	        ret = new Buffer(n);

	      var c = 0;
	      for (var i = 0, l = list.length; i < l && c < n; i++) {
	        var buf = list[0];
	        var cpy = Math.min(n - c, buf.length);

	        if (stringMode)
	          ret += buf.slice(0, cpy);
	        else
	          buf.copy(ret, c, 0, cpy);

	        if (cpy < buf.length)
	          list[0] = buf.slice(cpy);
	        else
	          list.shift();

	        c += cpy;
	      }
	    }
	  }

	  return ret;
	}

	function endReadable(stream) {
	  var state = stream._readableState;

	  // If we get here before consuming all the bytes, then that is a
	  // bug in node.  Should never happen.
	  if (state.length > 0)
	    throw new Error('endReadable called on non-empty stream');

	  if (!state.endEmitted) {
	    state.ended = true;
	    processNextTick(endReadableNT, state, stream);
	  }
	}

	function endReadableNT(state, stream) {
	  // Check that we didn't get one last unshift.
	  if (!state.endEmitted && state.length === 0) {
	    state.endEmitted = true;
	    stream.readable = false;
	    stream.emit('end');
	  }
	}

	function forEach (xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}

	function indexOf (xs, x) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    if (xs[i] === x) return i;
	  }
	  return -1;
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 64 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {'use strict';

	if (!process.version ||
	    process.version.indexOf('v0.') === 0 ||
	    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
	  module.exports = nextTick;
	} else {
	  module.exports = process.nextTick;
	}

	function nextTick(fn) {
	  var args = new Array(arguments.length - 1);
	  var i = 0;
	  while (i < args.length) {
	    args[i++] = arguments[i];
	  }
	  process.nextTick(function afterTick() {
	    fn.apply(null, args);
	  });
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))

/***/ },
/* 65 */
/***/ function(module, exports) {

	module.exports = Array.isArray || function (arr) {
	  return Object.prototype.toString.call(arr) == '[object Array]';
	};


/***/ },
/* 66 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.

	function isArray(arg) {
	  if (Array.isArray) {
	    return Array.isArray(arg);
	  }
	  return objectToString(arg) === '[object Array]';
	}
	exports.isArray = isArray;

	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;

	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;

	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;

	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;

	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;

	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;

	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;

	function isRegExp(re) {
	  return objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;

	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;

	function isDate(d) {
	  return objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;

	function isError(e) {
	  return (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;

	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;

	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;

	exports.isBuffer = Buffer.isBuffer;

	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer))

/***/ },
/* 67 */
/***/ function(module, exports) {

	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}


/***/ },
/* 68 */
/***/ function(module, exports) {

	/* (ignored) */

/***/ },
/* 69 */
/***/ function(module, exports, __webpack_require__) {

	// a duplex stream is just a stream that is both readable and writable.
	// Since JS doesn't have multiple prototypal inheritance, this class
	// prototypally inherits from Readable, and then parasitically from
	// Writable.

	'use strict';

	/*<replacement>*/
	var objectKeys = Object.keys || function (obj) {
	  var keys = [];
	  for (var key in obj) keys.push(key);
	  return keys;
	}
	/*</replacement>*/


	module.exports = Duplex;

	/*<replacement>*/
	var processNextTick = __webpack_require__(64);
	/*</replacement>*/



	/*<replacement>*/
	var util = __webpack_require__(66);
	util.inherits = __webpack_require__(67);
	/*</replacement>*/

	var Readable = __webpack_require__(63);
	var Writable = __webpack_require__(70);

	util.inherits(Duplex, Readable);

	var keys = objectKeys(Writable.prototype);
	for (var v = 0; v < keys.length; v++) {
	  var method = keys[v];
	  if (!Duplex.prototype[method])
	    Duplex.prototype[method] = Writable.prototype[method];
	}

	function Duplex(options) {
	  if (!(this instanceof Duplex))
	    return new Duplex(options);

	  Readable.call(this, options);
	  Writable.call(this, options);

	  if (options && options.readable === false)
	    this.readable = false;

	  if (options && options.writable === false)
	    this.writable = false;

	  this.allowHalfOpen = true;
	  if (options && options.allowHalfOpen === false)
	    this.allowHalfOpen = false;

	  this.once('end', onend);
	}

	// the no-half-open enforcer
	function onend() {
	  // if we allow half-open state, or if the writable side ended,
	  // then we're ok.
	  if (this.allowHalfOpen || this._writableState.ended)
	    return;

	  // no more data can be written.
	  // But allow more writes to happen in this tick.
	  processNextTick(onEndNT, this);
	}

	function onEndNT(self) {
	  self.end();
	}

	function forEach (xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}


/***/ },
/* 70 */
/***/ function(module, exports, __webpack_require__) {

	// A bit simpler than readable streams.
	// Implement an async ._write(chunk, encoding, cb), and it'll handle all
	// the drain event emission and buffering.

	'use strict';

	module.exports = Writable;

	/*<replacement>*/
	var processNextTick = __webpack_require__(64);
	/*</replacement>*/


	/*<replacement>*/
	var Buffer = __webpack_require__(5).Buffer;
	/*</replacement>*/

	Writable.WritableState = WritableState;


	/*<replacement>*/
	var util = __webpack_require__(66);
	util.inherits = __webpack_require__(67);
	/*</replacement>*/


	/*<replacement>*/
	var internalUtil = {
	  deprecate: __webpack_require__(71)
	};
	/*</replacement>*/



	/*<replacement>*/
	var Stream;
	(function (){try{
	  Stream = __webpack_require__(45);
	}catch(_){}finally{
	  if (!Stream)
	    Stream = __webpack_require__(46).EventEmitter;
	}}())
	/*</replacement>*/

	var Buffer = __webpack_require__(5).Buffer;

	util.inherits(Writable, Stream);

	function nop() {}

	function WriteReq(chunk, encoding, cb) {
	  this.chunk = chunk;
	  this.encoding = encoding;
	  this.callback = cb;
	  this.next = null;
	}

	var Duplex;
	function WritableState(options, stream) {
	  Duplex = Duplex || __webpack_require__(69);

	  options = options || {};

	  // object stream flag to indicate whether or not this stream
	  // contains buffers or objects.
	  this.objectMode = !!options.objectMode;

	  if (stream instanceof Duplex)
	    this.objectMode = this.objectMode || !!options.writableObjectMode;

	  // the point at which write() starts returning false
	  // Note: 0 is a valid value, means that we always return false if
	  // the entire buffer is not flushed immediately on write()
	  var hwm = options.highWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;

	  // cast to ints.
	  this.highWaterMark = ~~this.highWaterMark;

	  this.needDrain = false;
	  // at the start of calling end()
	  this.ending = false;
	  // when end() has been called, and returned
	  this.ended = false;
	  // when 'finish' is emitted
	  this.finished = false;

	  // should we decode strings into buffers before passing to _write?
	  // this is here so that some node-core streams can optimize string
	  // handling at a lower level.
	  var noDecode = options.decodeStrings === false;
	  this.decodeStrings = !noDecode;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // not an actual buffer we keep track of, but a measurement
	  // of how much we're waiting to get pushed to some underlying
	  // socket or file.
	  this.length = 0;

	  // a flag to see when we're in the middle of a write.
	  this.writing = false;

	  // when true all writes will be buffered until .uncork() call
	  this.corked = 0;

	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;

	  // a flag to know if we're processing previously buffered items, which
	  // may call the _write() callback in the same tick, so that we don't
	  // end up in an overlapped onwrite situation.
	  this.bufferProcessing = false;

	  // the callback that's passed to _write(chunk,cb)
	  this.onwrite = function(er) {
	    onwrite(stream, er);
	  };

	  // the callback that the user supplies to write(chunk,encoding,cb)
	  this.writecb = null;

	  // the amount that is being written when _write is called.
	  this.writelen = 0;

	  this.bufferedRequest = null;
	  this.lastBufferedRequest = null;

	  // number of pending user-supplied write callbacks
	  // this must be 0 before 'finish' can be emitted
	  this.pendingcb = 0;

	  // emit prefinish if the only thing we're waiting for is _write cbs
	  // This is relevant for synchronous Transform streams
	  this.prefinished = false;

	  // True if the error was already emitted and should not be thrown again
	  this.errorEmitted = false;
	}

	WritableState.prototype.getBuffer = function writableStateGetBuffer() {
	  var current = this.bufferedRequest;
	  var out = [];
	  while (current) {
	    out.push(current);
	    current = current.next;
	  }
	  return out;
	};

	(function (){try {
	Object.defineProperty(WritableState.prototype, 'buffer', {
	  get: internalUtil.deprecate(function() {
	    return this.getBuffer();
	  }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' +
	     'instead.')
	});
	}catch(_){}}());


	var Duplex;
	function Writable(options) {
	  Duplex = Duplex || __webpack_require__(69);

	  // Writable ctor is applied to Duplexes, though they're not
	  // instanceof Writable, they're instanceof Readable.
	  if (!(this instanceof Writable) && !(this instanceof Duplex))
	    return new Writable(options);

	  this._writableState = new WritableState(options, this);

	  // legacy.
	  this.writable = true;

	  if (options) {
	    if (typeof options.write === 'function')
	      this._write = options.write;

	    if (typeof options.writev === 'function')
	      this._writev = options.writev;
	  }

	  Stream.call(this);
	}

	// Otherwise people can pipe Writable streams, which is just wrong.
	Writable.prototype.pipe = function() {
	  this.emit('error', new Error('Cannot pipe. Not readable.'));
	};


	function writeAfterEnd(stream, cb) {
	  var er = new Error('write after end');
	  // TODO: defer error events consistently everywhere, not just the cb
	  stream.emit('error', er);
	  processNextTick(cb, er);
	}

	// If we get something that is not a buffer, string, null, or undefined,
	// and we're not in objectMode, then that's an error.
	// Otherwise stream chunks are all considered to be of length=1, and the
	// watermarks determine how many objects to keep in the buffer, rather than
	// how many bytes or characters.
	function validChunk(stream, state, chunk, cb) {
	  var valid = true;

	  if (!(Buffer.isBuffer(chunk)) &&
	      typeof chunk !== 'string' &&
	      chunk !== null &&
	      chunk !== undefined &&
	      !state.objectMode) {
	    var er = new TypeError('Invalid non-string/buffer chunk');
	    stream.emit('error', er);
	    processNextTick(cb, er);
	    valid = false;
	  }
	  return valid;
	}

	Writable.prototype.write = function(chunk, encoding, cb) {
	  var state = this._writableState;
	  var ret = false;

	  if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }

	  if (Buffer.isBuffer(chunk))
	    encoding = 'buffer';
	  else if (!encoding)
	    encoding = state.defaultEncoding;

	  if (typeof cb !== 'function')
	    cb = nop;

	  if (state.ended)
	    writeAfterEnd(this, cb);
	  else if (validChunk(this, state, chunk, cb)) {
	    state.pendingcb++;
	    ret = writeOrBuffer(this, state, chunk, encoding, cb);
	  }

	  return ret;
	};

	Writable.prototype.cork = function() {
	  var state = this._writableState;

	  state.corked++;
	};

	Writable.prototype.uncork = function() {
	  var state = this._writableState;

	  if (state.corked) {
	    state.corked--;

	    if (!state.writing &&
	        !state.corked &&
	        !state.finished &&
	        !state.bufferProcessing &&
	        state.bufferedRequest)
	      clearBuffer(this, state);
	  }
	};

	Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
	  // node::ParseEncoding() requires lower case.
	  if (typeof encoding === 'string')
	    encoding = encoding.toLowerCase();
	  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64',
	'ucs2', 'ucs-2','utf16le', 'utf-16le', 'raw']
	.indexOf((encoding + '').toLowerCase()) > -1))
	    throw new TypeError('Unknown encoding: ' + encoding);
	  this._writableState.defaultEncoding = encoding;
	};

	function decodeChunk(state, chunk, encoding) {
	  if (!state.objectMode &&
	      state.decodeStrings !== false &&
	      typeof chunk === 'string') {
	    chunk = new Buffer(chunk, encoding);
	  }
	  return chunk;
	}

	// if we're already writing something, then just put this
	// in the queue, and wait our turn.  Otherwise, call _write
	// If we return false, then we need a drain event, so set that flag.
	function writeOrBuffer(stream, state, chunk, encoding, cb) {
	  chunk = decodeChunk(state, chunk, encoding);

	  if (Buffer.isBuffer(chunk))
	    encoding = 'buffer';
	  var len = state.objectMode ? 1 : chunk.length;

	  state.length += len;

	  var ret = state.length < state.highWaterMark;
	  // we must ensure that previous needDrain will not be reset to false.
	  if (!ret)
	    state.needDrain = true;

	  if (state.writing || state.corked) {
	    var last = state.lastBufferedRequest;
	    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
	    if (last) {
	      last.next = state.lastBufferedRequest;
	    } else {
	      state.bufferedRequest = state.lastBufferedRequest;
	    }
	  } else {
	    doWrite(stream, state, false, len, chunk, encoding, cb);
	  }

	  return ret;
	}

	function doWrite(stream, state, writev, len, chunk, encoding, cb) {
	  state.writelen = len;
	  state.writecb = cb;
	  state.writing = true;
	  state.sync = true;
	  if (writev)
	    stream._writev(chunk, state.onwrite);
	  else
	    stream._write(chunk, encoding, state.onwrite);
	  state.sync = false;
	}

	function onwriteError(stream, state, sync, er, cb) {
	  --state.pendingcb;
	  if (sync)
	    processNextTick(cb, er);
	  else
	    cb(er);

	  stream._writableState.errorEmitted = true;
	  stream.emit('error', er);
	}

	function onwriteStateUpdate(state) {
	  state.writing = false;
	  state.writecb = null;
	  state.length -= state.writelen;
	  state.writelen = 0;
	}

	function onwrite(stream, er) {
	  var state = stream._writableState;
	  var sync = state.sync;
	  var cb = state.writecb;

	  onwriteStateUpdate(state);

	  if (er)
	    onwriteError(stream, state, sync, er, cb);
	  else {
	    // Check if we're actually ready to finish, but don't emit yet
	    var finished = needFinish(state);

	    if (!finished &&
	        !state.corked &&
	        !state.bufferProcessing &&
	        state.bufferedRequest) {
	      clearBuffer(stream, state);
	    }

	    if (sync) {
	      processNextTick(afterWrite, stream, state, finished, cb);
	    } else {
	      afterWrite(stream, state, finished, cb);
	    }
	  }
	}

	function afterWrite(stream, state, finished, cb) {
	  if (!finished)
	    onwriteDrain(stream, state);
	  state.pendingcb--;
	  cb();
	  finishMaybe(stream, state);
	}

	// Must force callback to be called on nextTick, so that we don't
	// emit 'drain' before the write() consumer gets the 'false' return
	// value, and has a chance to attach a 'drain' listener.
	function onwriteDrain(stream, state) {
	  if (state.length === 0 && state.needDrain) {
	    state.needDrain = false;
	    stream.emit('drain');
	  }
	}


	// if there's something in the buffer waiting, then process it
	function clearBuffer(stream, state) {
	  state.bufferProcessing = true;
	  var entry = state.bufferedRequest;

	  if (stream._writev && entry && entry.next) {
	    // Fast case, write everything using _writev()
	    var buffer = [];
	    var cbs = [];
	    while (entry) {
	      cbs.push(entry.callback);
	      buffer.push(entry);
	      entry = entry.next;
	    }

	    // count the one we are adding, as well.
	    // TODO(isaacs) clean this up
	    state.pendingcb++;
	    state.lastBufferedRequest = null;
	    doWrite(stream, state, true, state.length, buffer, '', function(err) {
	      for (var i = 0; i < cbs.length; i++) {
	        state.pendingcb--;
	        cbs[i](err);
	      }
	    });

	    // Clear buffer
	  } else {
	    // Slow case, write chunks one-by-one
	    while (entry) {
	      var chunk = entry.chunk;
	      var encoding = entry.encoding;
	      var cb = entry.callback;
	      var len = state.objectMode ? 1 : chunk.length;

	      doWrite(stream, state, false, len, chunk, encoding, cb);
	      entry = entry.next;
	      // if we didn't call the onwrite immediately, then
	      // it means that we need to wait until it does.
	      // also, that means that the chunk and cb are currently
	      // being processed, so move the buffer counter past them.
	      if (state.writing) {
	        break;
	      }
	    }

	    if (entry === null)
	      state.lastBufferedRequest = null;
	  }
	  state.bufferedRequest = entry;
	  state.bufferProcessing = false;
	}

	Writable.prototype._write = function(chunk, encoding, cb) {
	  cb(new Error('not implemented'));
	};

	Writable.prototype._writev = null;

	Writable.prototype.end = function(chunk, encoding, cb) {
	  var state = this._writableState;

	  if (typeof chunk === 'function') {
	    cb = chunk;
	    chunk = null;
	    encoding = null;
	  } else if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }

	  if (chunk !== null && chunk !== undefined)
	    this.write(chunk, encoding);

	  // .end() fully uncorks
	  if (state.corked) {
	    state.corked = 1;
	    this.uncork();
	  }

	  // ignore unnecessary end() calls.
	  if (!state.ending && !state.finished)
	    endWritable(this, state, cb);
	};


	function needFinish(state) {
	  return (state.ending &&
	          state.length === 0 &&
	          state.bufferedRequest === null &&
	          !state.finished &&
	          !state.writing);
	}

	function prefinish(stream, state) {
	  if (!state.prefinished) {
	    state.prefinished = true;
	    stream.emit('prefinish');
	  }
	}

	function finishMaybe(stream, state) {
	  var need = needFinish(state);
	  if (need) {
	    if (state.pendingcb === 0) {
	      prefinish(stream, state);
	      state.finished = true;
	      stream.emit('finish');
	    } else {
	      prefinish(stream, state);
	    }
	  }
	  return need;
	}

	function endWritable(stream, state, cb) {
	  state.ending = true;
	  finishMaybe(stream, state);
	  if (cb) {
	    if (state.finished)
	      processNextTick(cb);
	    else
	      stream.once('finish', cb);
	  }
	  state.ended = true;
	}


/***/ },
/* 71 */
/***/ function(module, exports) {

	/* WEBPACK VAR INJECTION */(function(global) {
	/**
	 * Module exports.
	 */

	module.exports = deprecate;

	/**
	 * Mark that a method should not be used.
	 * Returns a modified function which warns once by default.
	 *
	 * If `localStorage.noDeprecation = true` is set, then it is a no-op.
	 *
	 * If `localStorage.throwDeprecation = true` is set, then deprecated functions
	 * will throw an Error when invoked.
	 *
	 * If `localStorage.traceDeprecation = true` is set, then deprecated functions
	 * will invoke `console.trace()` instead of `console.error()`.
	 *
	 * @param {Function} fn - the function to deprecate
	 * @param {String} msg - the string to print to the console when `fn` is invoked
	 * @returns {Function} a new "deprecated" version of `fn`
	 * @api public
	 */

	function deprecate (fn, msg) {
	  if (config('noDeprecation')) {
	    return fn;
	  }

	  var warned = false;
	  function deprecated() {
	    if (!warned) {
	      if (config('throwDeprecation')) {
	        throw new Error(msg);
	      } else if (config('traceDeprecation')) {
	        console.trace(msg);
	      } else {
	        console.warn(msg);
	      }
	      warned = true;
	    }
	    return fn.apply(this, arguments);
	  }

	  return deprecated;
	}

	/**
	 * Checks `localStorage` for boolean values for the given `name`.
	 *
	 * @param {String} name
	 * @returns {Boolean}
	 * @api private
	 */

	function config (name) {
	  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
	  try {
	    if (!global.localStorage) return false;
	  } catch (_) {
	    return false;
	  }
	  var val = global.localStorage[name];
	  if (null == val) return false;
	  return String(val).toLowerCase() === 'true';
	}

	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 72 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	var Buffer = __webpack_require__(5).Buffer;

	var isBufferEncoding = Buffer.isEncoding
	  || function(encoding) {
	       switch (encoding && encoding.toLowerCase()) {
	         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
	         default: return false;
	       }
	     }


	function assertEncoding(encoding) {
	  if (encoding && !isBufferEncoding(encoding)) {
	    throw new Error('Unknown encoding: ' + encoding);
	  }
	}

	// StringDecoder provides an interface for efficiently splitting a series of
	// buffers into a series of JS strings without breaking apart multi-byte
	// characters. CESU-8 is handled as part of the UTF-8 encoding.
	//
	// @TODO Handling all encodings inside a single object makes it very difficult
	// to reason about this code, so it should be split up in the future.
	// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
	// points as used by CESU-8.
	var StringDecoder = exports.StringDecoder = function(encoding) {
	  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
	  assertEncoding(encoding);
	  switch (this.encoding) {
	    case 'utf8':
	      // CESU-8 represents each of Surrogate Pair by 3-bytes
	      this.surrogateSize = 3;
	      break;
	    case 'ucs2':
	    case 'utf16le':
	      // UTF-16 represents each of Surrogate Pair by 2-bytes
	      this.surrogateSize = 2;
	      this.detectIncompleteChar = utf16DetectIncompleteChar;
	      break;
	    case 'base64':
	      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
	      this.surrogateSize = 3;
	      this.detectIncompleteChar = base64DetectIncompleteChar;
	      break;
	    default:
	      this.write = passThroughWrite;
	      return;
	  }

	  // Enough space to store all bytes of a single character. UTF-8 needs 4
	  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
	  this.charBuffer = new Buffer(6);
	  // Number of bytes received for the current incomplete multi-byte character.
	  this.charReceived = 0;
	  // Number of bytes expected for the current incomplete multi-byte character.
	  this.charLength = 0;
	};


	// write decodes the given buffer and returns it as JS string that is
	// guaranteed to not contain any partial multi-byte characters. Any partial
	// character found at the end of the buffer is buffered up, and will be
	// returned when calling write again with the remaining bytes.
	//
	// Note: Converting a Buffer containing an orphan surrogate to a String
	// currently works, but converting a String to a Buffer (via `new Buffer`, or
	// Buffer#write) will replace incomplete surrogates with the unicode
	// replacement character. See https://codereview.chromium.org/121173009/ .
	StringDecoder.prototype.write = function(buffer) {
	  var charStr = '';
	  // if our last write ended with an incomplete multibyte character
	  while (this.charLength) {
	    // determine how many remaining bytes this buffer has to offer for this char
	    var available = (buffer.length >= this.charLength - this.charReceived) ?
	        this.charLength - this.charReceived :
	        buffer.length;

	    // add the new bytes to the char buffer
	    buffer.copy(this.charBuffer, this.charReceived, 0, available);
	    this.charReceived += available;

	    if (this.charReceived < this.charLength) {
	      // still not enough chars in this buffer? wait for more ...
	      return '';
	    }

	    // remove bytes belonging to the current character from the buffer
	    buffer = buffer.slice(available, buffer.length);

	    // get the character that was split
	    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);

	    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
	    var charCode = charStr.charCodeAt(charStr.length - 1);
	    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
	      this.charLength += this.surrogateSize;
	      charStr = '';
	      continue;
	    }
	    this.charReceived = this.charLength = 0;

	    // if there are no more bytes in this buffer, just emit our char
	    if (buffer.length === 0) {
	      return charStr;
	    }
	    break;
	  }

	  // determine and set charLength / charReceived
	  this.detectIncompleteChar(buffer);

	  var end = buffer.length;
	  if (this.charLength) {
	    // buffer the incomplete character bytes we got
	    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
	    end -= this.charReceived;
	  }

	  charStr += buffer.toString(this.encoding, 0, end);

	  var end = charStr.length - 1;
	  var charCode = charStr.charCodeAt(end);
	  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
	  if (charCode >= 0xD800 && charCode <= 0xDBFF) {
	    var size = this.surrogateSize;
	    this.charLength += size;
	    this.charReceived += size;
	    this.charBuffer.copy(this.charBuffer, size, 0, size);
	    buffer.copy(this.charBuffer, 0, 0, size);
	    return charStr.substring(0, end);
	  }

	  // or just emit the charStr
	  return charStr;
	};

	// detectIncompleteChar determines if there is an incomplete UTF-8 character at
	// the end of the given buffer. If so, it sets this.charLength to the byte
	// length that character, and sets this.charReceived to the number of bytes
	// that are available for this character.
	StringDecoder.prototype.detectIncompleteChar = function(buffer) {
	  // determine how many bytes we have to check at the end of this buffer
	  var i = (buffer.length >= 3) ? 3 : buffer.length;

	  // Figure out if one of the last i bytes of our buffer announces an
	  // incomplete char.
	  for (; i > 0; i--) {
	    var c = buffer[buffer.length - i];

	    // See http://en.wikipedia.org/wiki/UTF-8#Description

	    // 110XXXXX
	    if (i == 1 && c >> 5 == 0x06) {
	      this.charLength = 2;
	      break;
	    }

	    // 1110XXXX
	    if (i <= 2 && c >> 4 == 0x0E) {
	      this.charLength = 3;
	      break;
	    }

	    // 11110XXX
	    if (i <= 3 && c >> 3 == 0x1E) {
	      this.charLength = 4;
	      break;
	    }
	  }
	  this.charReceived = i;
	};

	StringDecoder.prototype.end = function(buffer) {
	  var res = '';
	  if (buffer && buffer.length)
	    res = this.write(buffer);

	  if (this.charReceived) {
	    var cr = this.charReceived;
	    var buf = this.charBuffer;
	    var enc = this.encoding;
	    res += buf.slice(0, cr).toString(enc);
	  }

	  return res;
	};

	function passThroughWrite(buffer) {
	  return buffer.toString(this.encoding);
	}

	function utf16DetectIncompleteChar(buffer) {
	  this.charReceived = buffer.length % 2;
	  this.charLength = this.charReceived ? 2 : 0;
	}

	function base64DetectIncompleteChar(buffer) {
	  this.charReceived = buffer.length % 3;
	  this.charLength = this.charReceived ? 3 : 0;
	}


/***/ },
/* 73 */
/***/ function(module, exports, __webpack_require__) {

	// a transform stream is a readable/writable stream where you do
	// something with the data.  Sometimes it's called a "filter",
	// but that's not a great name for it, since that implies a thing where
	// some bits pass through, and others are simply ignored.  (That would
	// be a valid example of a transform, of course.)
	//
	// While the output is causally related to the input, it's not a
	// necessarily symmetric or synchronous transformation.  For example,
	// a zlib stream might take multiple plain-text writes(), and then
	// emit a single compressed chunk some time in the future.
	//
	// Here's how this works:
	//
	// The Transform stream has all the aspects of the readable and writable
	// stream classes.  When you write(chunk), that calls _write(chunk,cb)
	// internally, and returns false if there's a lot of pending writes
	// buffered up.  When you call read(), that calls _read(n) until
	// there's enough pending readable data buffered up.
	//
	// In a transform stream, the written data is placed in a buffer.  When
	// _read(n) is called, it transforms the queued up data, calling the
	// buffered _write cb's as it consumes chunks.  If consuming a single
	// written chunk would result in multiple output chunks, then the first
	// outputted bit calls the readcb, and subsequent chunks just go into
	// the read buffer, and will cause it to emit 'readable' if necessary.
	//
	// This way, back-pressure is actually determined by the reading side,
	// since _read has to be called to start processing a new chunk.  However,
	// a pathological inflate type of transform can cause excessive buffering
	// here.  For example, imagine a stream where every byte of input is
	// interpreted as an integer from 0-255, and then results in that many
	// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
	// 1kb of data being output.  In this case, you could write a very small
	// amount of input, and end up with a very large amount of output.  In
	// such a pathological inflating mechanism, there'd be no way to tell
	// the system to stop doing the transform.  A single 4MB write could
	// cause the system to run out of memory.
	//
	// However, even in such a pathological case, only a single written chunk
	// would be consumed, and then the rest would wait (un-transformed) until
	// the results of the previous transformed chunk were consumed.

	'use strict';

	module.exports = Transform;

	var Duplex = __webpack_require__(69);

	/*<replacement>*/
	var util = __webpack_require__(66);
	util.inherits = __webpack_require__(67);
	/*</replacement>*/

	util.inherits(Transform, Duplex);


	function TransformState(stream) {
	  this.afterTransform = function(er, data) {
	    return afterTransform(stream, er, data);
	  };

	  this.needTransform = false;
	  this.transforming = false;
	  this.writecb = null;
	  this.writechunk = null;
	}

	function afterTransform(stream, er, data) {
	  var ts = stream._transformState;
	  ts.transforming = false;

	  var cb = ts.writecb;

	  if (!cb)
	    return stream.emit('error', new Error('no writecb in Transform class'));

	  ts.writechunk = null;
	  ts.writecb = null;

	  if (data !== null && data !== undefined)
	    stream.push(data);

	  if (cb)
	    cb(er);

	  var rs = stream._readableState;
	  rs.reading = false;
	  if (rs.needReadable || rs.length < rs.highWaterMark) {
	    stream._read(rs.highWaterMark);
	  }
	}


	function Transform(options) {
	  if (!(this instanceof Transform))
	    return new Transform(options);

	  Duplex.call(this, options);

	  this._transformState = new TransformState(this);

	  // when the writable side finishes, then flush out anything remaining.
	  var stream = this;

	  // start out asking for a readable event once data is transformed.
	  this._readableState.needReadable = true;

	  // we have implemented the _read method, and done the other things
	  // that Readable wants before the first _read call, so unset the
	  // sync guard flag.
	  this._readableState.sync = false;

	  if (options) {
	    if (typeof options.transform === 'function')
	      this._transform = options.transform;

	    if (typeof options.flush === 'function')
	      this._flush = options.flush;
	  }

	  this.once('prefinish', function() {
	    if (typeof this._flush === 'function')
	      this._flush(function(er) {
	        done(stream, er);
	      });
	    else
	      done(stream);
	  });
	}

	Transform.prototype.push = function(chunk, encoding) {
	  this._transformState.needTransform = false;
	  return Duplex.prototype.push.call(this, chunk, encoding);
	};

	// This is the part where you do stuff!
	// override this function in implementation classes.
	// 'chunk' is an input chunk.
	//
	// Call `push(newChunk)` to pass along transformed output
	// to the readable side.  You may call 'push' zero or more times.
	//
	// Call `cb(err)` when you are done with this chunk.  If you pass
	// an error, then that'll put the hurt on the whole operation.  If you
	// never call cb(), then you'll never get another chunk.
	Transform.prototype._transform = function(chunk, encoding, cb) {
	  throw new Error('not implemented');
	};

	Transform.prototype._write = function(chunk, encoding, cb) {
	  var ts = this._transformState;
	  ts.writecb = cb;
	  ts.writechunk = chunk;
	  ts.writeencoding = encoding;
	  if (!ts.transforming) {
	    var rs = this._readableState;
	    if (ts.needTransform ||
	        rs.needReadable ||
	        rs.length < rs.highWaterMark)
	      this._read(rs.highWaterMark);
	  }
	};

	// Doesn't matter what the args are here.
	// _transform does all the work.
	// That we got here means that the readable side wants more data.
	Transform.prototype._read = function(n) {
	  var ts = this._transformState;

	  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
	    ts.transforming = true;
	    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
	  } else {
	    // mark that we need a transform, so that any data that comes in
	    // will get processed, now that we've asked for it.
	    ts.needTransform = true;
	  }
	};


	function done(stream, er) {
	  if (er)
	    return stream.emit('error', er);

	  // if there's nothing in the write buffer, then that means
	  // that nothing more will ever be provided
	  var ws = stream._writableState;
	  var ts = stream._transformState;

	  if (ws.length)
	    throw new Error('calling transform done when ws.length != 0');

	  if (ts.transforming)
	    throw new Error('calling transform done when still transforming');

	  return stream.push(null);
	}


/***/ },
/* 74 */
/***/ function(module, exports, __webpack_require__) {

	// a passthrough stream.
	// basically just the most minimal sort of Transform stream.
	// Every written chunk gets output as-is.

	'use strict';

	module.exports = PassThrough;

	var Transform = __webpack_require__(73);

	/*<replacement>*/
	var util = __webpack_require__(66);
	util.inherits = __webpack_require__(67);
	/*</replacement>*/

	util.inherits(PassThrough, Transform);

	function PassThrough(options) {
	  if (!(this instanceof PassThrough))
	    return new PassThrough(options);

	  Transform.call(this, options);
	}

	PassThrough.prototype._transform = function(chunk, encoding, cb) {
	  cb(null, chunk);
	};


/***/ },
/* 75 */
/***/ function(module, exports) {

	var undefined = (void 0); // Paranoia

	// Beyond this value, index getters/setters (i.e. array[0], array[1]) are so slow to
	// create, and consume so much memory, that the browser appears frozen.
	var MAX_ARRAY_LENGTH = 1e5;

	// Approximations of internal ECMAScript conversion functions
	var ECMAScript = (function() {
	  // Stash a copy in case other scripts modify these
	  var opts = Object.prototype.toString,
	      ophop = Object.prototype.hasOwnProperty;

	  return {
	    // Class returns internal [[Class]] property, used to avoid cross-frame instanceof issues:
	    Class: function(v) { return opts.call(v).replace(/^\[object *|\]$/g, ''); },
	    HasProperty: function(o, p) { return p in o; },
	    HasOwnProperty: function(o, p) { return ophop.call(o, p); },
	    IsCallable: function(o) { return typeof o === 'function'; },
	    ToInt32: function(v) { return v >> 0; },
	    ToUint32: function(v) { return v >>> 0; }
	  };
	}());

	// Snapshot intrinsics
	var LN2 = Math.LN2,
	    abs = Math.abs,
	    floor = Math.floor,
	    log = Math.log,
	    min = Math.min,
	    pow = Math.pow,
	    round = Math.round;

	// ES5: lock down object properties
	function configureProperties(obj) {
	  if (getOwnPropNames && defineProp) {
	    var props = getOwnPropNames(obj), i;
	    for (i = 0; i < props.length; i += 1) {
	      defineProp(obj, props[i], {
	        value: obj[props[i]],
	        writable: false,
	        enumerable: false,
	        configurable: false
	      });
	    }
	  }
	}

	// emulate ES5 getter/setter API using legacy APIs
	// http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx
	// (second clause tests for Object.defineProperty() in IE<9 that only supports extending DOM prototypes, but
	// note that IE<9 does not support __defineGetter__ or __defineSetter__ so it just renders the method harmless)
	var defineProp
	if (Object.defineProperty && (function() {
	      try {
	        Object.defineProperty({}, 'x', {});
	        return true;
	      } catch (e) {
	        return false;
	      }
	    })()) {
	  defineProp = Object.defineProperty;
	} else {
	  defineProp = function(o, p, desc) {
	    if (!o === Object(o)) throw new TypeError("Object.defineProperty called on non-object");
	    if (ECMAScript.HasProperty(desc, 'get') && Object.prototype.__defineGetter__) { Object.prototype.__defineGetter__.call(o, p, desc.get); }
	    if (ECMAScript.HasProperty(desc, 'set') && Object.prototype.__defineSetter__) { Object.prototype.__defineSetter__.call(o, p, desc.set); }
	    if (ECMAScript.HasProperty(desc, 'value')) { o[p] = desc.value; }
	    return o;
	  };
	}

	var getOwnPropNames = Object.getOwnPropertyNames || function (o) {
	  if (o !== Object(o)) throw new TypeError("Object.getOwnPropertyNames called on non-object");
	  var props = [], p;
	  for (p in o) {
	    if (ECMAScript.HasOwnProperty(o, p)) {
	      props.push(p);
	    }
	  }
	  return props;
	};

	// ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value)
	// for index in 0 ... obj.length
	function makeArrayAccessors(obj) {
	  if (!defineProp) { return; }

	  if (obj.length > MAX_ARRAY_LENGTH) throw new RangeError("Array too large for polyfill");

	  function makeArrayAccessor(index) {
	    defineProp(obj, index, {
	      'get': function() { return obj._getter(index); },
	      'set': function(v) { obj._setter(index, v); },
	      enumerable: true,
	      configurable: false
	    });
	  }

	  var i;
	  for (i = 0; i < obj.length; i += 1) {
	    makeArrayAccessor(i);
	  }
	}

	// Internal conversion functions:
	//    pack<Type>()   - take a number (interpreted as Type), output a byte array
	//    unpack<Type>() - take a byte array, output a Type-like number

	function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; }
	function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; }

	function packI8(n) { return [n & 0xff]; }
	function unpackI8(bytes) { return as_signed(bytes[0], 8); }

	function packU8(n) { return [n & 0xff]; }
	function unpackU8(bytes) { return as_unsigned(bytes[0], 8); }

	function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; }

	function packI16(n) { return [(n >> 8) & 0xff, n & 0xff]; }
	function unpackI16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); }

	function packU16(n) { return [(n >> 8) & 0xff, n & 0xff]; }
	function unpackU16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); }

	function packI32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; }
	function unpackI32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); }

	function packU32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; }
	function unpackU32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); }

	function packIEEE754(v, ebits, fbits) {

	  var bias = (1 << (ebits - 1)) - 1,
	      s, e, f, ln,
	      i, bits, str, bytes;

	  function roundToEven(n) {
	    var w = floor(n), f = n - w;
	    if (f < 0.5)
	      return w;
	    if (f > 0.5)
	      return w + 1;
	    return w % 2 ? w + 1 : w;
	  }

	  // Compute sign, exponent, fraction
	  if (v !== v) {
	    // NaN
	    // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
	    e = (1 << ebits) - 1; f = pow(2, fbits - 1); s = 0;
	  } else if (v === Infinity || v === -Infinity) {
	    e = (1 << ebits) - 1; f = 0; s = (v < 0) ? 1 : 0;
	  } else if (v === 0) {
	    e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0;
	  } else {
	    s = v < 0;
	    v = abs(v);

	    if (v >= pow(2, 1 - bias)) {
	      e = min(floor(log(v) / LN2), 1023);
	      f = roundToEven(v / pow(2, e) * pow(2, fbits));
	      if (f / pow(2, fbits) >= 2) {
	        e = e + 1;
	        f = 1;
	      }
	      if (e > bias) {
	        // Overflow
	        e = (1 << ebits) - 1;
	        f = 0;
	      } else {
	        // Normalized
	        e = e + bias;
	        f = f - pow(2, fbits);
	      }
	    } else {
	      // Denormalized
	      e = 0;
	      f = roundToEven(v / pow(2, 1 - bias - fbits));
	    }
	  }

	  // Pack sign, exponent, fraction
	  bits = [];
	  for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); }
	  for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); }
	  bits.push(s ? 1 : 0);
	  bits.reverse();
	  str = bits.join('');

	  // Bits to bytes
	  bytes = [];
	  while (str.length) {
	    bytes.push(parseInt(str.substring(0, 8), 2));
	    str = str.substring(8);
	  }
	  return bytes;
	}

	function unpackIEEE754(bytes, ebits, fbits) {

	  // Bytes to bits
	  var bits = [], i, j, b, str,
	      bias, s, e, f;

	  for (i = bytes.length; i; i -= 1) {
	    b = bytes[i - 1];
	    for (j = 8; j; j -= 1) {
	      bits.push(b % 2 ? 1 : 0); b = b >> 1;
	    }
	  }
	  bits.reverse();
	  str = bits.join('');

	  // Unpack sign, exponent, fraction
	  bias = (1 << (ebits - 1)) - 1;
	  s = parseInt(str.substring(0, 1), 2) ? -1 : 1;
	  e = parseInt(str.substring(1, 1 + ebits), 2);
	  f = parseInt(str.substring(1 + ebits), 2);

	  // Produce number
	  if (e === (1 << ebits) - 1) {
	    return f !== 0 ? NaN : s * Infinity;
	  } else if (e > 0) {
	    // Normalized
	    return s * pow(2, e - bias) * (1 + f / pow(2, fbits));
	  } else if (f !== 0) {
	    // Denormalized
	    return s * pow(2, -(bias - 1)) * (f / pow(2, fbits));
	  } else {
	    return s < 0 ? -0 : 0;
	  }
	}

	function unpackF64(b) { return unpackIEEE754(b, 11, 52); }
	function packF64(v) { return packIEEE754(v, 11, 52); }
	function unpackF32(b) { return unpackIEEE754(b, 8, 23); }
	function packF32(v) { return packIEEE754(v, 8, 23); }


	//
	// 3 The ArrayBuffer Type
	//

	(function() {

	  /** @constructor */
	  var ArrayBuffer = function ArrayBuffer(length) {
	    length = ECMAScript.ToInt32(length);
	    if (length < 0) throw new RangeError('ArrayBuffer size is not a small enough positive integer');

	    this.byteLength = length;
	    this._bytes = [];
	    this._bytes.length = length;

	    var i;
	    for (i = 0; i < this.byteLength; i += 1) {
	      this._bytes[i] = 0;
	    }

	    configureProperties(this);
	  };

	  exports.ArrayBuffer = exports.ArrayBuffer || ArrayBuffer;

	  //
	  // 4 The ArrayBufferView Type
	  //

	  // NOTE: this constructor is not exported
	  /** @constructor */
	  var ArrayBufferView = function ArrayBufferView() {
	    //this.buffer = null;
	    //this.byteOffset = 0;
	    //this.byteLength = 0;
	  };

	  //
	  // 5 The Typed Array View Types
	  //

	  function makeConstructor(bytesPerElement, pack, unpack) {
	    // Each TypedArray type requires a distinct constructor instance with
	    // identical logic, which this produces.

	    var ctor;
	    ctor = function(buffer, byteOffset, length) {
	      var array, sequence, i, s;

	      if (!arguments.length || typeof arguments[0] === 'number') {
	        // Constructor(unsigned long length)
	        this.length = ECMAScript.ToInt32(arguments[0]);
	        if (length < 0) throw new RangeError('ArrayBufferView size is not a small enough positive integer');

	        this.byteLength = this.length * this.BYTES_PER_ELEMENT;
	        this.buffer = new ArrayBuffer(this.byteLength);
	        this.byteOffset = 0;
	      } else if (typeof arguments[0] === 'object' && arguments[0].constructor === ctor) {
	        // Constructor(TypedArray array)
	        array = arguments[0];

	        this.length = array.length;
	        this.byteLength = this.length * this.BYTES_PER_ELEMENT;
	        this.buffer = new ArrayBuffer(this.byteLength);
	        this.byteOffset = 0;

	        for (i = 0; i < this.length; i += 1) {
	          this._setter(i, array._getter(i));
	        }
	      } else if (typeof arguments[0] === 'object' &&
	                 !(arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) {
	        // Constructor(sequence<type> array)
	        sequence = arguments[0];

	        this.length = ECMAScript.ToUint32(sequence.length);
	        this.byteLength = this.length * this.BYTES_PER_ELEMENT;
	        this.buffer = new ArrayBuffer(this.byteLength);
	        this.byteOffset = 0;

	        for (i = 0; i < this.length; i += 1) {
	          s = sequence[i];
	          this._setter(i, Number(s));
	        }
	      } else if (typeof arguments[0] === 'object' &&
	                 (arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) {
	        // Constructor(ArrayBuffer buffer,
	        //             optional unsigned long byteOffset, optional unsigned long length)
	        this.buffer = buffer;

	        this.byteOffset = ECMAScript.ToUint32(byteOffset);
	        if (this.byteOffset > this.buffer.byteLength) {
	          throw new RangeError("byteOffset out of range");
	        }

	        if (this.byteOffset % this.BYTES_PER_ELEMENT) {
	          // The given byteOffset must be a multiple of the element
	          // size of the specific type, otherwise an exception is raised.
	          throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.");
	        }

	        if (arguments.length < 3) {
	          this.byteLength = this.buffer.byteLength - this.byteOffset;

	          if (this.byteLength % this.BYTES_PER_ELEMENT) {
	            throw new RangeError("length of buffer minus byteOffset not a multiple of the element size");
	          }
	          this.length = this.byteLength / this.BYTES_PER_ELEMENT;
	        } else {
	          this.length = ECMAScript.ToUint32(length);
	          this.byteLength = this.length * this.BYTES_PER_ELEMENT;
	        }

	        if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) {
	          throw new RangeError("byteOffset and length reference an area beyond the end of the buffer");
	        }
	      } else {
	        throw new TypeError("Unexpected argument type(s)");
	      }

	      this.constructor = ctor;

	      configureProperties(this);
	      makeArrayAccessors(this);
	    };

	    ctor.prototype = new ArrayBufferView();
	    ctor.prototype.BYTES_PER_ELEMENT = bytesPerElement;
	    ctor.prototype._pack = pack;
	    ctor.prototype._unpack = unpack;
	    ctor.BYTES_PER_ELEMENT = bytesPerElement;

	    // getter type (unsigned long index);
	    ctor.prototype._getter = function(index) {
	      if (arguments.length < 1) throw new SyntaxError("Not enough arguments");

	      index = ECMAScript.ToUint32(index);
	      if (index >= this.length) {
	        return undefined;
	      }

	      var bytes = [], i, o;
	      for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT;
	           i < this.BYTES_PER_ELEMENT;
	           i += 1, o += 1) {
	        bytes.push(this.buffer._bytes[o]);
	      }
	      return this._unpack(bytes);
	    };

	    // NONSTANDARD: convenience alias for getter: type get(unsigned long index);
	    ctor.prototype.get = ctor.prototype._getter;

	    // setter void (unsigned long index, type value);
	    ctor.prototype._setter = function(index, value) {
	      if (arguments.length < 2) throw new SyntaxError("Not enough arguments");

	      index = ECMAScript.ToUint32(index);
	      if (index >= this.length) {
	        return undefined;
	      }

	      var bytes = this._pack(value), i, o;
	      for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT;
	           i < this.BYTES_PER_ELEMENT;
	           i += 1, o += 1) {
	        this.buffer._bytes[o] = bytes[i];
	      }
	    };

	    // void set(TypedArray array, optional unsigned long offset);
	    // void set(sequence<type> array, optional unsigned long offset);
	    ctor.prototype.set = function(index, value) {
	      if (arguments.length < 1) throw new SyntaxError("Not enough arguments");
	      var array, sequence, offset, len,
	          i, s, d,
	          byteOffset, byteLength, tmp;

	      if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) {
	        // void set(TypedArray array, optional unsigned long offset);
	        array = arguments[0];
	        offset = ECMAScript.ToUint32(arguments[1]);

	        if (offset + array.length > this.length) {
	          throw new RangeError("Offset plus length of array is out of range");
	        }

	        byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT;
	        byteLength = array.length * this.BYTES_PER_ELEMENT;

	        if (array.buffer === this.buffer) {
	          tmp = [];
	          for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) {
	            tmp[i] = array.buffer._bytes[s];
	          }
	          for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) {
	            this.buffer._bytes[d] = tmp[i];
	          }
	        } else {
	          for (i = 0, s = array.byteOffset, d = byteOffset;
	               i < byteLength; i += 1, s += 1, d += 1) {
	            this.buffer._bytes[d] = array.buffer._bytes[s];
	          }
	        }
	      } else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') {
	        // void set(sequence<type> array, optional unsigned long offset);
	        sequence = arguments[0];
	        len = ECMAScript.ToUint32(sequence.length);
	        offset = ECMAScript.ToUint32(arguments[1]);

	        if (offset + len > this.length) {
	          throw new RangeError("Offset plus length of array is out of range");
	        }

	        for (i = 0; i < len; i += 1) {
	          s = sequence[i];
	          this._setter(offset + i, Number(s));
	        }
	      } else {
	        throw new TypeError("Unexpected argument type(s)");
	      }
	    };

	    // TypedArray subarray(long begin, optional long end);
	    ctor.prototype.subarray = function(start, end) {
	      function clamp(v, min, max) { return v < min ? min : v > max ? max : v; }

	      start = ECMAScript.ToInt32(start);
	      end = ECMAScript.ToInt32(end);

	      if (arguments.length < 1) { start = 0; }
	      if (arguments.length < 2) { end = this.length; }

	      if (start < 0) { start = this.length + start; }
	      if (end < 0) { end = this.length + end; }

	      start = clamp(start, 0, this.length);
	      end = clamp(end, 0, this.length);

	      var len = end - start;
	      if (len < 0) {
	        len = 0;
	      }

	      return new this.constructor(
	        this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len);
	    };

	    return ctor;
	  }

	  var Int8Array = makeConstructor(1, packI8, unpackI8);
	  var Uint8Array = makeConstructor(1, packU8, unpackU8);
	  var Uint8ClampedArray = makeConstructor(1, packU8Clamped, unpackU8);
	  var Int16Array = makeConstructor(2, packI16, unpackI16);
	  var Uint16Array = makeConstructor(2, packU16, unpackU16);
	  var Int32Array = makeConstructor(4, packI32, unpackI32);
	  var Uint32Array = makeConstructor(4, packU32, unpackU32);
	  var Float32Array = makeConstructor(4, packF32, unpackF32);
	  var Float64Array = makeConstructor(8, packF64, unpackF64);

	  exports.Int8Array = exports.Int8Array || Int8Array;
	  exports.Uint8Array = exports.Uint8Array || Uint8Array;
	  exports.Uint8ClampedArray = exports.Uint8ClampedArray || Uint8ClampedArray;
	  exports.Int16Array = exports.Int16Array || Int16Array;
	  exports.Uint16Array = exports.Uint16Array || Uint16Array;
	  exports.Int32Array = exports.Int32Array || Int32Array;
	  exports.Uint32Array = exports.Uint32Array || Uint32Array;
	  exports.Float32Array = exports.Float32Array || Float32Array;
	  exports.Float64Array = exports.Float64Array || Float64Array;
	}());

	//
	// 6 The DataView View Type
	//

	(function() {
	  function r(array, index) {
	    return ECMAScript.IsCallable(array.get) ? array.get(index) : array[index];
	  }

	  var IS_BIG_ENDIAN = (function() {
	    var u16array = new(exports.Uint16Array)([0x1234]),
	        u8array = new(exports.Uint8Array)(u16array.buffer);
	    return r(u8array, 0) === 0x12;
	  }());

	  // Constructor(ArrayBuffer buffer,
	  //             optional unsigned long byteOffset,
	  //             optional unsigned long byteLength)
	  /** @constructor */
	  var DataView = function DataView(buffer, byteOffset, byteLength) {
	    if (arguments.length === 0) {
	      buffer = new exports.ArrayBuffer(0);
	    } else if (!(buffer instanceof exports.ArrayBuffer || ECMAScript.Class(buffer) === 'ArrayBuffer')) {
	      throw new TypeError("TypeError");
	    }

	    this.buffer = buffer || new exports.ArrayBuffer(0);

	    this.byteOffset = ECMAScript.ToUint32(byteOffset);
	    if (this.byteOffset > this.buffer.byteLength) {
	      throw new RangeError("byteOffset out of range");
	    }

	    if (arguments.length < 3) {
	      this.byteLength = this.buffer.byteLength - this.byteOffset;
	    } else {
	      this.byteLength = ECMAScript.ToUint32(byteLength);
	    }

	    if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) {
	      throw new RangeError("byteOffset and length reference an area beyond the end of the buffer");
	    }

	    configureProperties(this);
	  };

	  function makeGetter(arrayType) {
	    return function(byteOffset, littleEndian) {

	      byteOffset = ECMAScript.ToUint32(byteOffset);

	      if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) {
	        throw new RangeError("Array index out of range");
	      }
	      byteOffset += this.byteOffset;

	      var uint8Array = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT),
	          bytes = [], i;
	      for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) {
	        bytes.push(r(uint8Array, i));
	      }

	      if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) {
	        bytes.reverse();
	      }

	      return r(new arrayType(new exports.Uint8Array(bytes).buffer), 0);
	    };
	  }

	  DataView.prototype.getUint8 = makeGetter(exports.Uint8Array);
	  DataView.prototype.getInt8 = makeGetter(exports.Int8Array);
	  DataView.prototype.getUint16 = makeGetter(exports.Uint16Array);
	  DataView.prototype.getInt16 = makeGetter(exports.Int16Array);
	  DataView.prototype.getUint32 = makeGetter(exports.Uint32Array);
	  DataView.prototype.getInt32 = makeGetter(exports.Int32Array);
	  DataView.prototype.getFloat32 = makeGetter(exports.Float32Array);
	  DataView.prototype.getFloat64 = makeGetter(exports.Float64Array);

	  function makeSetter(arrayType) {
	    return function(byteOffset, value, littleEndian) {

	      byteOffset = ECMAScript.ToUint32(byteOffset);
	      if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) {
	        throw new RangeError("Array index out of range");
	      }

	      // Get bytes
	      var typeArray = new arrayType([value]),
	          byteArray = new exports.Uint8Array(typeArray.buffer),
	          bytes = [], i, byteView;

	      for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) {
	        bytes.push(r(byteArray, i));
	      }

	      // Flip if necessary
	      if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) {
	        bytes.reverse();
	      }

	      // Write them
	      byteView = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT);
	      byteView.set(bytes);
	    };
	  }

	  DataView.prototype.setUint8 = makeSetter(exports.Uint8Array);
	  DataView.prototype.setInt8 = makeSetter(exports.Int8Array);
	  DataView.prototype.setUint16 = makeSetter(exports.Uint16Array);
	  DataView.prototype.setInt16 = makeSetter(exports.Int16Array);
	  DataView.prototype.setUint32 = makeSetter(exports.Uint32Array);
	  DataView.prototype.setInt32 = makeSetter(exports.Int32Array);
	  DataView.prototype.setFloat32 = makeSetter(exports.Float32Array);
	  DataView.prototype.setFloat64 = makeSetter(exports.Float64Array);

	  exports.DataView = exports.DataView || DataView;

	}());


/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var Promise = __webpack_require__(77);
	var Response = __webpack_require__(42);
	var handleQs = __webpack_require__(84);

	module.exports = doRequest;
	function doRequest(method, url, options, callback) {
	  var result = new Promise(function (resolve, reject) {
	    var xhr = new window.XMLHttpRequest();

	    // check types of arguments

	    if (typeof method !== 'string') {
	      throw new TypeError('The method must be a string.');
	    }
	    if (typeof url !== 'string') {
	      throw new TypeError('The URL/path must be a string.');
	    }
	    if (typeof options === 'function') {
	      callback = options;
	      options = {};
	    }
	    if (options === null || options === undefined) {
	      options = {};
	    }
	    if (typeof options !== 'object') {
	      throw new TypeError('Options must be an object (or null).');
	    }
	    if (typeof callback !== 'function') {
	      callback = undefined;
	    }

	    method = method.toUpperCase();
	    options.headers = options.headers || {};


	    function attempt(n) {
	      doRequest(method, url, {
	        qs: options.qs,
	        headers: options.headers,
	        timeout: options.timeout
	      }).nodeify(function (err, res) {
	        var retry = err || res.statusCode >= 400;
	        if (typeof options.retry === 'function') {
	          retry = options.retry(err, res, n + 1);
	        }
	        if (n >= (options.maxRetries | 5)) {
	          retry = false;
	        }
	        if (retry) {
	          var delay = options.retryDelay;
	          if (typeof options.retryDelay === 'function') {
	            delay = options.retryDelay(err, res, n + 1);
	          }
	          delay = delay || 200;
	          setTimeout(function () {
	            attempt(n + 1);
	          }, delay);
	        } else {
	          if (err) reject(err);
	          else resolve(res);
	        }
	      });
	    }
	    if (options.retry && method === 'GET') {
	      return attempt(0);
	    }

	    // handle cross domain

	    var match;
	    var crossDomain = !!((match = /^([\w-]+:)?\/\/([^\/]+)/.exec(options.uri)) && (match[2] != window.location.host));
	    if (!crossDomain) options.headers['X-Requested-With'] = 'XMLHttpRequest';

	    // handle query string
	    if (options.qs) {
	      url = handleQs(url, options.qs);
	    }

	    // handle json body
	    if (options.json) {
	      options.body = JSON.stringify(options.json);
	      options.headers['Content-Type'] = 'application/json';
	    }

	    if (options.timeout) {
	      xhr.timeout = options.timeout;
	      var start = Date.now();
	      xhr.ontimeout = function () {
	        var duration = Date.now() - start;
	        var err = new Error('Request timed out after ' + duration + 'ms');
	        err.timeout = true;
	        err.duration = duration;
	        reject(err);
	      };
	    }
	    xhr.onreadystatechange = function () {
	      if (xhr.readyState === 4) {
	        var headers = {};
	        xhr.getAllResponseHeaders().split('\r\n').forEach(function (header) {
	          var h = header.split(':');
	          if (h.length > 1) {
	            headers[h[0].toLowerCase()] = h.slice(1).join(':').trim();
	          }
	        });
	        var res = new Response(xhr.status, headers, xhr.responseText);
	        res.url = url;
	        resolve(res);
	      }
	    };

	    // method, url, async
	    xhr.open(method, url, true);

	    for (var name in options.headers) {
	      xhr.setRequestHeader(name, options.headers[name]);
	    }

	    // avoid sending empty string (#319)
	    xhr.send(options.body ? options.body : null);
	  });
	  result.getBody = function () {
	    return result.then(function (res) { return res.getBody(); });
	  };
	  return result.nodeify(callback);
	}


/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	module.exports = __webpack_require__(78)
	__webpack_require__(81)
	__webpack_require__(82)
	__webpack_require__(83)

/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var asap = __webpack_require__(79)

	module.exports = Promise;
	function Promise(fn) {
	  if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new')
	  if (typeof fn !== 'function') throw new TypeError('not a function')
	  var state = null
	  var value = null
	  var deferreds = []
	  var self = this

	  this.then = function(onFulfilled, onRejected) {
	    return new self.constructor(function(resolve, reject) {
	      handle(new Handler(onFulfilled, onRejected, resolve, reject))
	    })
	  }

	  function handle(deferred) {
	    if (state === null) {
	      deferreds.push(deferred)
	      return
	    }
	    asap(function() {
	      var cb = state ? deferred.onFulfilled : deferred.onRejected
	      if (cb === null) {
	        (state ? deferred.resolve : deferred.reject)(value)
	        return
	      }
	      var ret
	      try {
	        ret = cb(value)
	      }
	      catch (e) {
	        deferred.reject(e)
	        return
	      }
	      deferred.resolve(ret)
	    })
	  }

	  function resolve(newValue) {
	    try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
	      if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.')
	      if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
	        var then = newValue.then
	        if (typeof then === 'function') {
	          doResolve(then.bind(newValue), resolve, reject)
	          return
	        }
	      }
	      state = true
	      value = newValue
	      finale()
	    } catch (e) { reject(e) }
	  }

	  function reject(newValue) {
	    state = false
	    value = newValue
	    finale()
	  }

	  function finale() {
	    for (var i = 0, len = deferreds.length; i < len; i++)
	      handle(deferreds[i])
	    deferreds = null
	  }

	  doResolve(fn, resolve, reject)
	}


	function Handler(onFulfilled, onRejected, resolve, reject){
	  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null
	  this.onRejected = typeof onRejected === 'function' ? onRejected : null
	  this.resolve = resolve
	  this.reject = reject
	}

	/**
	 * Take a potentially misbehaving resolver function and make sure
	 * onFulfilled and onRejected are only called once.
	 *
	 * Makes no guarantees about asynchrony.
	 */
	function doResolve(fn, onFulfilled, onRejected) {
	  var done = false;
	  try {
	    fn(function (value) {
	      if (done) return
	      done = true
	      onFulfilled(value)
	    }, function (reason) {
	      if (done) return
	      done = true
	      onRejected(reason)
	    })
	  } catch (ex) {
	    if (done) return
	    done = true
	    onRejected(ex)
	  }
	}


/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process, setImmediate) {
	// Use the fastest possible means to execute a task in a future turn
	// of the event loop.

	// linked list of tasks (single, with head node)
	var head = {task: void 0, next: null};
	var tail = head;
	var flushing = false;
	var requestFlush = void 0;
	var isNodeJS = false;

	function flush() {
	    /* jshint loopfunc: true */

	    while (head.next) {
	        head = head.next;
	        var task = head.task;
	        head.task = void 0;
	        var domain = head.domain;

	        if (domain) {
	            head.domain = void 0;
	            domain.enter();
	        }

	        try {
	            task();

	        } catch (e) {
	            if (isNodeJS) {
	                // In node, uncaught exceptions are considered fatal errors.
	                // Re-throw them synchronously to interrupt flushing!

	                // Ensure continuation if the uncaught exception is suppressed
	                // listening "uncaughtException" events (as domains does).
	                // Continue in next event to avoid tick recursion.
	                if (domain) {
	                    domain.exit();
	                }
	                setTimeout(flush, 0);
	                if (domain) {
	                    domain.enter();
	                }

	                throw e;

	            } else {
	                // In browsers, uncaught exceptions are not fatal.
	                // Re-throw them asynchronously to avoid slow-downs.
	                setTimeout(function() {
	                   throw e;
	                }, 0);
	            }
	        }

	        if (domain) {
	            domain.exit();
	        }
	    }

	    flushing = false;
	}

	if (typeof process !== "undefined" && process.nextTick) {
	    // Node.js before 0.9. Note that some fake-Node environments, like the
	    // Mocha test runner, introduce a `process` global without a `nextTick`.
	    isNodeJS = true;

	    requestFlush = function () {
	        process.nextTick(flush);
	    };

	} else if (typeof setImmediate === "function") {
	    // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
	    if (typeof window !== "undefined") {
	        requestFlush = setImmediate.bind(window, flush);
	    } else {
	        requestFlush = function () {
	            setImmediate(flush);
	        };
	    }

	} else if (typeof MessageChannel !== "undefined") {
	    // modern browsers
	    // http://www.nonblocking.io/2011/06/windownexttick.html
	    var channel = new MessageChannel();
	    channel.port1.onmessage = flush;
	    requestFlush = function () {
	        channel.port2.postMessage(0);
	    };

	} else {
	    // old browsers
	    requestFlush = function () {
	        setTimeout(flush, 0);
	    };
	}

	function asap(task) {
	    tail = tail.next = {
	        task: task,
	        domain: isNodeJS && process.domain,
	        next: null
	    };

	    if (!flushing) {
	        flushing = true;
	        requestFlush();
	    }
	};

	module.exports = asap;


	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3), __webpack_require__(80).setImmediate))

/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(setImmediate, clearImmediate) {var nextTick = __webpack_require__(3).nextTick;
	var apply = Function.prototype.apply;
	var slice = Array.prototype.slice;
	var immediateIds = {};
	var nextImmediateId = 0;

	// DOM APIs, for completeness

	exports.setTimeout = function() {
	  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
	};
	exports.setInterval = function() {
	  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
	};
	exports.clearTimeout =
	exports.clearInterval = function(timeout) { timeout.close(); };

	function Timeout(id, clearFn) {
	  this._id = id;
	  this._clearFn = clearFn;
	}
	Timeout.prototype.unref = Timeout.prototype.ref = function() {};
	Timeout.prototype.close = function() {
	  this._clearFn.call(window, this._id);
	};

	// Does not start the time, just sets up the members needed.
	exports.enroll = function(item, msecs) {
	  clearTimeout(item._idleTimeoutId);
	  item._idleTimeout = msecs;
	};

	exports.unenroll = function(item) {
	  clearTimeout(item._idleTimeoutId);
	  item._idleTimeout = -1;
	};

	exports._unrefActive = exports.active = function(item) {
	  clearTimeout(item._idleTimeoutId);

	  var msecs = item._idleTimeout;
	  if (msecs >= 0) {
	    item._idleTimeoutId = setTimeout(function onTimeout() {
	      if (item._onTimeout)
	        item._onTimeout();
	    }, msecs);
	  }
	};

	// That's not how node.js implements it but the exposed api is the same.
	exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
	  var id = nextImmediateId++;
	  var args = arguments.length < 2 ? false : slice.call(arguments, 1);

	  immediateIds[id] = true;

	  nextTick(function onNextTick() {
	    if (immediateIds[id]) {
	      // fn.call() is faster so we optimize for the common use-case
	      // @see http://jsperf.com/call-apply-segu
	      if (args) {
	        fn.apply(null, args);
	      } else {
	        fn.call(null);
	      }
	      // Prevent ids from leaking
	      exports.clearImmediate(id);
	    }
	  });

	  return id;
	};

	exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
	  delete immediateIds[id];
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(80).setImmediate, __webpack_require__(80).clearImmediate))

/***/ },
/* 81 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var Promise = __webpack_require__(78)
	var asap = __webpack_require__(79)

	module.exports = Promise
	Promise.prototype.done = function (onFulfilled, onRejected) {
	  var self = arguments.length ? this.then.apply(this, arguments) : this
	  self.then(null, function (err) {
	    asap(function () {
	      throw err
	    })
	  })
	}

/***/ },
/* 82 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	//This file contains the ES6 extensions to the core Promises/A+ API

	var Promise = __webpack_require__(78)
	var asap = __webpack_require__(79)

	module.exports = Promise

	/* Static Functions */

	function ValuePromise(value) {
	  this.then = function (onFulfilled) {
	    if (typeof onFulfilled !== 'function') return this
	    return new Promise(function (resolve, reject) {
	      asap(function () {
	        try {
	          resolve(onFulfilled(value))
	        } catch (ex) {
	          reject(ex);
	        }
	      })
	    })
	  }
	}
	ValuePromise.prototype = Promise.prototype

	var TRUE = new ValuePromise(true)
	var FALSE = new ValuePromise(false)
	var NULL = new ValuePromise(null)
	var UNDEFINED = new ValuePromise(undefined)
	var ZERO = new ValuePromise(0)
	var EMPTYSTRING = new ValuePromise('')

	Promise.resolve = function (value) {
	  if (value instanceof Promise) return value

	  if (value === null) return NULL
	  if (value === undefined) return UNDEFINED
	  if (value === true) return TRUE
	  if (value === false) return FALSE
	  if (value === 0) return ZERO
	  if (value === '') return EMPTYSTRING

	  if (typeof value === 'object' || typeof value === 'function') {
	    try {
	      var then = value.then
	      if (typeof then === 'function') {
	        return new Promise(then.bind(value))
	      }
	    } catch (ex) {
	      return new Promise(function (resolve, reject) {
	        reject(ex)
	      })
	    }
	  }

	  return new ValuePromise(value)
	}

	Promise.all = function (arr) {
	  var args = Array.prototype.slice.call(arr)

	  return new Promise(function (resolve, reject) {
	    if (args.length === 0) return resolve([])
	    var remaining = args.length
	    function res(i, val) {
	      try {
	        if (val && (typeof val === 'object' || typeof val === 'function')) {
	          var then = val.then
	          if (typeof then === 'function') {
	            then.call(val, function (val) { res(i, val) }, reject)
	            return
	          }
	        }
	        args[i] = val
	        if (--remaining === 0) {
	          resolve(args);
	        }
	      } catch (ex) {
	        reject(ex)
	      }
	    }
	    for (var i = 0; i < args.length; i++) {
	      res(i, args[i])
	    }
	  })
	}

	Promise.reject = function (value) {
	  return new Promise(function (resolve, reject) { 
	    reject(value);
	  });
	}

	Promise.race = function (values) {
	  return new Promise(function (resolve, reject) { 
	    values.forEach(function(value){
	      Promise.resolve(value).then(resolve, reject);
	    })
	  });
	}

	/* Prototype Methods */

	Promise.prototype['catch'] = function (onRejected) {
	  return this.then(null, onRejected);
	}


/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	//This file contains then/promise specific extensions that are only useful for node.js interop

	var Promise = __webpack_require__(78)
	var asap = __webpack_require__(79)

	module.exports = Promise

	/* Static Functions */

	Promise.denodeify = function (fn, argumentCount) {
	  argumentCount = argumentCount || Infinity
	  return function () {
	    var self = this
	    var args = Array.prototype.slice.call(arguments)
	    return new Promise(function (resolve, reject) {
	      while (args.length && args.length > argumentCount) {
	        args.pop()
	      }
	      args.push(function (err, res) {
	        if (err) reject(err)
	        else resolve(res)
	      })
	      var res = fn.apply(self, args)
	      if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') {
	        resolve(res)
	      }
	    })
	  }
	}
	Promise.nodeify = function (fn) {
	  return function () {
	    var args = Array.prototype.slice.call(arguments)
	    var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null
	    var ctx = this
	    try {
	      return fn.apply(this, arguments).nodeify(callback, ctx)
	    } catch (ex) {
	      if (callback === null || typeof callback == 'undefined') {
	        return new Promise(function (resolve, reject) { reject(ex) })
	      } else {
	        asap(function () {
	          callback.call(ctx, ex)
	        })
	      }
	    }
	  }
	}

	Promise.prototype.nodeify = function (callback, ctx) {
	  if (typeof callback != 'function') return this

	  this.then(function (value) {
	    asap(function () {
	      callback.call(ctx, null, value)
	    })
	  }, function (err) {
	    asap(function () {
	      callback.call(ctx, err)
	    })
	  })
	}


/***/ },
/* 84 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var parse = __webpack_require__(85).parse;
	var stringify = __webpack_require__(85).stringify;

	module.exports = handleQs;
	function handleQs(url, query) {
	  url = url.split('?');
	  var start = url[0];
	  var qs = (url[1] || '').split('#')[0];
	  var end = url[1] && url[1].split('#').length > 1 ? '#' + url[1].split('#')[1] : '';

	  var baseQs = parse(qs);
	  for (var i in query) {
	    baseQs[i] = query[i];
	  }
	  qs = stringify(baseQs);
	  if (qs !== '') {
	    qs = '?' + qs;
	  }
	  return start + qs + end;
	}


/***/ },
/* 85 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(86);


/***/ },
/* 86 */
/***/ function(module, exports, __webpack_require__) {

	// Load modules

	var Stringify = __webpack_require__(87);
	var Parse = __webpack_require__(89);


	// Declare internals

	var internals = {};


	module.exports = {
	    stringify: Stringify,
	    parse: Parse
	};


/***/ },
/* 87 */
/***/ function(module, exports, __webpack_require__) {

	// Load modules

	var Utils = __webpack_require__(88);


	// Declare internals

	var internals = {
	    delimiter: '&',
	    arrayPrefixGenerators: {
	        brackets: function (prefix, key) {
	            return prefix + '[]';
	        },
	        indices: function (prefix, key) {
	            return prefix + '[' + key + ']';
	        },
	        repeat: function (prefix, key) {
	            return prefix;
	        }
	    }
	};


	internals.stringify = function (obj, prefix, generateArrayPrefix) {

	    if (Utils.isBuffer(obj)) {
	        obj = obj.toString();
	    }
	    else if (obj instanceof Date) {
	        obj = obj.toISOString();
	    }
	    else if (obj === null) {
	        obj = '';
	    }

	    if (typeof obj === 'string' ||
	        typeof obj === 'number' ||
	        typeof obj === 'boolean') {

	        return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)];
	    }

	    var values = [];

	    if (typeof obj === 'undefined') {
	        return values;
	    }

	    var objKeys = Object.keys(obj);
	    for (var i = 0, il = objKeys.length; i < il; ++i) {
	        var key = objKeys[i];
	        if (Array.isArray(obj)) {
	            values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
	        }
	        else {
	            values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
	        }
	    }

	    return values;
	};


	module.exports = function (obj, options) {

	    options = options || {};
	    var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;

	    var keys = [];

	    if (typeof obj !== 'object' ||
	        obj === null) {

	        return '';
	    }

	    var arrayFormat;
	    if (options.arrayFormat in internals.arrayPrefixGenerators) {
	        arrayFormat = options.arrayFormat;
	    }
	    else if ('indices' in options) {
	        arrayFormat = options.indices ? 'indices' : 'repeat';
	    }
	    else {
	        arrayFormat = 'indices';
	    }

	    var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];

	    var objKeys = Object.keys(obj);
	    for (var i = 0, il = objKeys.length; i < il; ++i) {
	        var key = objKeys[i];
	        keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
	    }

	    return keys.join(delimiter);
	};


/***/ },
/* 88 */
/***/ function(module, exports) {

	// Load modules


	// Declare internals

	var internals = {};


	exports.arrayToObject = function (source) {

	    var obj = {};
	    for (var i = 0, il = source.length; i < il; ++i) {
	        if (typeof source[i] !== 'undefined') {

	            obj[i] = source[i];
	        }
	    }

	    return obj;
	};


	exports.merge = function (target, source) {

	    if (!source) {
	        return target;
	    }

	    if (typeof source !== 'object') {
	        if (Array.isArray(target)) {
	            target.push(source);
	        }
	        else {
	            target[source] = true;
	        }

	        return target;
	    }

	    if (typeof target !== 'object') {
	        target = [target].concat(source);
	        return target;
	    }

	    if (Array.isArray(target) &&
	        !Array.isArray(source)) {

	        target = exports.arrayToObject(target);
	    }

	    var keys = Object.keys(source);
	    for (var k = 0, kl = keys.length; k < kl; ++k) {
	        var key = keys[k];
	        var value = source[key];

	        if (!target[key]) {
	            target[key] = value;
	        }
	        else {
	            target[key] = exports.merge(target[key], value);
	        }
	    }

	    return target;
	};


	exports.decode = function (str) {

	    try {
	        return decodeURIComponent(str.replace(/\+/g, ' '));
	    } catch (e) {
	        return str;
	    }
	};


	exports.compact = function (obj, refs) {

	    if (typeof obj !== 'object' ||
	        obj === null) {

	        return obj;
	    }

	    refs = refs || [];
	    var lookup = refs.indexOf(obj);
	    if (lookup !== -1) {
	        return refs[lookup];
	    }

	    refs.push(obj);

	    if (Array.isArray(obj)) {
	        var compacted = [];

	        for (var i = 0, il = obj.length; i < il; ++i) {
	            if (typeof obj[i] !== 'undefined') {
	                compacted.push(obj[i]);
	            }
	        }

	        return compacted;
	    }

	    var keys = Object.keys(obj);
	    for (i = 0, il = keys.length; i < il; ++i) {
	        var key = keys[i];
	        obj[key] = exports.compact(obj[key], refs);
	    }

	    return obj;
	};


	exports.isRegExp = function (obj) {
	    return Object.prototype.toString.call(obj) === '[object RegExp]';
	};


	exports.isBuffer = function (obj) {

	    if (obj === null ||
	        typeof obj === 'undefined') {

	        return false;
	    }

	    return !!(obj.constructor &&
	        obj.constructor.isBuffer &&
	        obj.constructor.isBuffer(obj));
	};


/***/ },
/* 89 */
/***/ function(module, exports, __webpack_require__) {

	// Load modules

	var Utils = __webpack_require__(88);


	// Declare internals

	var internals = {
	    delimiter: '&',
	    depth: 5,
	    arrayLimit: 20,
	    parameterLimit: 1000
	};


	internals.parseValues = function (str, options) {

	    var obj = {};
	    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);

	    for (var i = 0, il = parts.length; i < il; ++i) {
	        var part = parts[i];
	        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;

	        if (pos === -1) {
	            obj[Utils.decode(part)] = '';
	        }
	        else {
	            var key = Utils.decode(part.slice(0, pos));
	            var val = Utils.decode(part.slice(pos + 1));

	            if (!Object.prototype.hasOwnProperty.call(obj, key)) {
	                obj[key] = val;
	            }
	            else {
	                obj[key] = [].concat(obj[key]).concat(val);
	            }
	        }
	    }

	    return obj;
	};


	internals.parseObject = function (chain, val, options) {

	    if (!chain.length) {
	        return val;
	    }

	    var root = chain.shift();

	    var obj = {};
	    if (root === '[]') {
	        obj = [];
	        obj = obj.concat(internals.parseObject(chain, val, options));
	    }
	    else {
	        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
	        var index = parseInt(cleanRoot, 10);
	        var indexString = '' + index;
	        if (!isNaN(index) &&
	            root !== cleanRoot &&
	            indexString === cleanRoot &&
	            index >= 0 &&
	            index <= options.arrayLimit) {

	            obj = [];
	            obj[index] = internals.parseObject(chain, val, options);
	        }
	        else {
	            obj[cleanRoot] = internals.parseObject(chain, val, options);
	        }
	    }

	    return obj;
	};


	internals.parseKeys = function (key, val, options) {

	    if (!key) {
	        return;
	    }

	    // The regex chunks

	    var parent = /^([^\[\]]*)/;
	    var child = /(\[[^\[\]]*\])/g;

	    // Get the parent

	    var segment = parent.exec(key);

	    // Don't allow them to overwrite object prototype properties

	    if (Object.prototype.hasOwnProperty(segment[1])) {
	        return;
	    }

	    // Stash the parent if it exists

	    var keys = [];
	    if (segment[1]) {
	        keys.push(segment[1]);
	    }

	    // Loop through children appending to the array until we hit depth

	    var i = 0;
	    while ((segment = child.exec(key)) !== null && i < options.depth) {

	        ++i;
	        if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
	            keys.push(segment[1]);
	        }
	    }

	    // If there's a remainder, just add whatever is left

	    if (segment) {
	        keys.push('[' + key.slice(segment.index) + ']');
	    }

	    return internals.parseObject(keys, val, options);
	};


	module.exports = function (str, options) {

	    if (str === '' ||
	        str === null ||
	        typeof str === 'undefined') {

	        return {};
	    }

	    options = options || {};
	    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
	    options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
	    options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
	    options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;

	    var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
	    var obj = {};

	    // Iterate over the keys and setup the new object

	    var keys = Object.keys(tempObj);
	    for (var i = 0, il = keys.length; i < il; ++i) {
	        var key = keys[i];
	        var newObj = internals.parseKeys(key, tempObj[key], options);
	        obj = Utils.merge(obj, newObj);
	    }

	    return Utils.compact(obj);
	};


/***/ },
/* 90 */
/***/ function(module, exports) {

	exports.XMLHttpRequest = XMLHttpRequest;

/***/ },
/* 91 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	var punycode = __webpack_require__(92);

	exports.parse = urlParse;
	exports.resolve = urlResolve;
	exports.resolveObject = urlResolveObject;
	exports.format = urlFormat;

	exports.Url = Url;

	function Url() {
	  this.protocol = null;
	  this.slashes = null;
	  this.auth = null;
	  this.host = null;
	  this.port = null;
	  this.hostname = null;
	  this.hash = null;
	  this.search = null;
	  this.query = null;
	  this.pathname = null;
	  this.path = null;
	  this.href = null;
	}

	// Reference: RFC 3986, RFC 1808, RFC 2396

	// define these here so at least they only have to be
	// compiled once on the first module load.
	var protocolPattern = /^([a-z0-9.+-]+:)/i,
	    portPattern = /:[0-9]*$/,

	    // RFC 2396: characters reserved for delimiting URLs.
	    // We actually just auto-escape these.
	    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],

	    // RFC 2396: characters not allowed for various reasons.
	    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),

	    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
	    autoEscape = ['\''].concat(unwise),
	    // Characters that are never ever allowed in a hostname.
	    // Note that any invalid chars are also handled, but these
	    // are the ones that are *expected* to be seen, so we fast-path
	    // them.
	    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
	    hostEndingChars = ['/', '?', '#'],
	    hostnameMaxLen = 255,
	    hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
	    hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
	    // protocols that can allow "unsafe" and "unwise" chars.
	    unsafeProtocol = {
	      'javascript': true,
	      'javascript:': true
	    },
	    // protocols that never have a hostname.
	    hostlessProtocol = {
	      'javascript': true,
	      'javascript:': true
	    },
	    // protocols that always contain a // bit.
	    slashedProtocol = {
	      'http': true,
	      'https': true,
	      'ftp': true,
	      'gopher': true,
	      'file': true,
	      'http:': true,
	      'https:': true,
	      'ftp:': true,
	      'gopher:': true,
	      'file:': true
	    },
	    querystring = __webpack_require__(94);

	function urlParse(url, parseQueryString, slashesDenoteHost) {
	  if (url && isObject(url) && url instanceof Url) return url;

	  var u = new Url;
	  u.parse(url, parseQueryString, slashesDenoteHost);
	  return u;
	}

	Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
	  if (!isString(url)) {
	    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
	  }

	  var rest = url;

	  // trim before proceeding.
	  // This is to support parse stuff like "  http://foo.com  \n"
	  rest = rest.trim();

	  var proto = protocolPattern.exec(rest);
	  if (proto) {
	    proto = proto[0];
	    var lowerProto = proto.toLowerCase();
	    this.protocol = lowerProto;
	    rest = rest.substr(proto.length);
	  }

	  // figure out if it's got a host
	  // user@server is *always* interpreted as a hostname, and url
	  // resolution will treat //foo/bar as host=foo,path=bar because that's
	  // how the browser resolves relative URLs.
	  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
	    var slashes = rest.substr(0, 2) === '//';
	    if (slashes && !(proto && hostlessProtocol[proto])) {
	      rest = rest.substr(2);
	      this.slashes = true;
	    }
	  }

	  if (!hostlessProtocol[proto] &&
	      (slashes || (proto && !slashedProtocol[proto]))) {

	    // there's a hostname.
	    // the first instance of /, ?, ;, or # ends the host.
	    //
	    // If there is an @ in the hostname, then non-host chars *are* allowed
	    // to the left of the last @ sign, unless some host-ending character
	    // comes *before* the @-sign.
	    // URLs are obnoxious.
	    //
	    // ex:
	    // http://a@b@c/ => user:a@b host:c
	    // http://a@b?@c => user:a host:c path:/?@c

	    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
	    // Review our test case against browsers more comprehensively.

	    // find the first instance of any hostEndingChars
	    var hostEnd = -1;
	    for (var i = 0; i < hostEndingChars.length; i++) {
	      var hec = rest.indexOf(hostEndingChars[i]);
	      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
	        hostEnd = hec;
	    }

	    // at this point, either we have an explicit point where the
	    // auth portion cannot go past, or the last @ char is the decider.
	    var auth, atSign;
	    if (hostEnd === -1) {
	      // atSign can be anywhere.
	      atSign = rest.lastIndexOf('@');
	    } else {
	      // atSign must be in auth portion.
	      // http://a@b/c@d => host:b auth:a path:/c@d
	      atSign = rest.lastIndexOf('@', hostEnd);
	    }

	    // Now we have a portion which is definitely the auth.
	    // Pull that off.
	    if (atSign !== -1) {
	      auth = rest.slice(0, atSign);
	      rest = rest.slice(atSign + 1);
	      this.auth = decodeURIComponent(auth);
	    }

	    // the host is the remaining to the left of the first non-host char
	    hostEnd = -1;
	    for (var i = 0; i < nonHostChars.length; i++) {
	      var hec = rest.indexOf(nonHostChars[i]);
	      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
	        hostEnd = hec;
	    }
	    // if we still have not hit it, then the entire thing is a host.
	    if (hostEnd === -1)
	      hostEnd = rest.length;

	    this.host = rest.slice(0, hostEnd);
	    rest = rest.slice(hostEnd);

	    // pull out port.
	    this.parseHost();

	    // we've indicated that there is a hostname,
	    // so even if it's empty, it has to be present.
	    this.hostname = this.hostname || '';

	    // if hostname begins with [ and ends with ]
	    // assume that it's an IPv6 address.
	    var ipv6Hostname = this.hostname[0] === '[' &&
	        this.hostname[this.hostname.length - 1] === ']';

	    // validate a little.
	    if (!ipv6Hostname) {
	      var hostparts = this.hostname.split(/\./);
	      for (var i = 0, l = hostparts.length; i < l; i++) {
	        var part = hostparts[i];
	        if (!part) continue;
	        if (!part.match(hostnamePartPattern)) {
	          var newpart = '';
	          for (var j = 0, k = part.length; j < k; j++) {
	            if (part.charCodeAt(j) > 127) {
	              // we replace non-ASCII char with a temporary placeholder
	              // we need this to make sure size of hostname is not
	              // broken by replacing non-ASCII by nothing
	              newpart += 'x';
	            } else {
	              newpart += part[j];
	            }
	          }
	          // we test again with ASCII char only
	          if (!newpart.match(hostnamePartPattern)) {
	            var validParts = hostparts.slice(0, i);
	            var notHost = hostparts.slice(i + 1);
	            var bit = part.match(hostnamePartStart);
	            if (bit) {
	              validParts.push(bit[1]);
	              notHost.unshift(bit[2]);
	            }
	            if (notHost.length) {
	              rest = '/' + notHost.join('.') + rest;
	            }
	            this.hostname = validParts.join('.');
	            break;
	          }
	        }
	      }
	    }

	    if (this.hostname.length > hostnameMaxLen) {
	      this.hostname = '';
	    } else {
	      // hostnames are always lower case.
	      this.hostname = this.hostname.toLowerCase();
	    }

	    if (!ipv6Hostname) {
	      // IDNA Support: Returns a puny coded representation of "domain".
	      // It only converts the part of the domain name that
	      // has non ASCII characters. I.e. it dosent matter if
	      // you call it with a domain that already is in ASCII.
	      var domainArray = this.hostname.split('.');
	      var newOut = [];
	      for (var i = 0; i < domainArray.length; ++i) {
	        var s = domainArray[i];
	        newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
	            'xn--' + punycode.encode(s) : s);
	      }
	      this.hostname = newOut.join('.');
	    }

	    var p = this.port ? ':' + this.port : '';
	    var h = this.hostname || '';
	    this.host = h + p;
	    this.href += this.host;

	    // strip [ and ] from the hostname
	    // the host field still retains them, though
	    if (ipv6Hostname) {
	      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
	      if (rest[0] !== '/') {
	        rest = '/' + rest;
	      }
	    }
	  }

	  // now rest is set to the post-host stuff.
	  // chop off any delim chars.
	  if (!unsafeProtocol[lowerProto]) {

	    // First, make 100% sure that any "autoEscape" chars get
	    // escaped, even if encodeURIComponent doesn't think they
	    // need to be.
	    for (var i = 0, l = autoEscape.length; i < l; i++) {
	      var ae = autoEscape[i];
	      var esc = encodeURIComponent(ae);
	      if (esc === ae) {
	        esc = escape(ae);
	      }
	      rest = rest.split(ae).join(esc);
	    }
	  }


	  // chop off from the tail first.
	  var hash = rest.indexOf('#');
	  if (hash !== -1) {
	    // got a fragment string.
	    this.hash = rest.substr(hash);
	    rest = rest.slice(0, hash);
	  }
	  var qm = rest.indexOf('?');
	  if (qm !== -1) {
	    this.search = rest.substr(qm);
	    this.query = rest.substr(qm + 1);
	    if (parseQueryString) {
	      this.query = querystring.parse(this.query);
	    }
	    rest = rest.slice(0, qm);
	  } else if (parseQueryString) {
	    // no query string, but parseQueryString still requested
	    this.search = '';
	    this.query = {};
	  }
	  if (rest) this.pathname = rest;
	  if (slashedProtocol[lowerProto] &&
	      this.hostname && !this.pathname) {
	    this.pathname = '/';
	  }

	  //to support http.request
	  if (this.pathname || this.search) {
	    var p = this.pathname || '';
	    var s = this.search || '';
	    this.path = p + s;
	  }

	  // finally, reconstruct the href based on what has been validated.
	  this.href = this.format();
	  return this;
	};

	// format a parsed object into a url string
	function urlFormat(obj) {
	  // ensure it's an object, and not a string url.
	  // If it's an obj, this is a no-op.
	  // this way, you can call url_format() on strings
	  // to clean up potentially wonky urls.
	  if (isString(obj)) obj = urlParse(obj);
	  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
	  return obj.format();
	}

	Url.prototype.format = function() {
	  var auth = this.auth || '';
	  if (auth) {
	    auth = encodeURIComponent(auth);
	    auth = auth.replace(/%3A/i, ':');
	    auth += '@';
	  }

	  var protocol = this.protocol || '',
	      pathname = this.pathname || '',
	      hash = this.hash || '',
	      host = false,
	      query = '';

	  if (this.host) {
	    host = auth + this.host;
	  } else if (this.hostname) {
	    host = auth + (this.hostname.indexOf(':') === -1 ?
	        this.hostname :
	        '[' + this.hostname + ']');
	    if (this.port) {
	      host += ':' + this.port;
	    }
	  }

	  if (this.query &&
	      isObject(this.query) &&
	      Object.keys(this.query).length) {
	    query = querystring.stringify(this.query);
	  }

	  var search = this.search || (query && ('?' + query)) || '';

	  if (protocol && protocol.substr(-1) !== ':') protocol += ':';

	  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
	  // unless they had them to begin with.
	  if (this.slashes ||
	      (!protocol || slashedProtocol[protocol]) && host !== false) {
	    host = '//' + (host || '');
	    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
	  } else if (!host) {
	    host = '';
	  }

	  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
	  if (search && search.charAt(0) !== '?') search = '?' + search;

	  pathname = pathname.replace(/[?#]/g, function(match) {
	    return encodeURIComponent(match);
	  });
	  search = search.replace('#', '%23');

	  return protocol + host + pathname + search + hash;
	};

	function urlResolve(source, relative) {
	  return urlParse(source, false, true).resolve(relative);
	}

	Url.prototype.resolve = function(relative) {
	  return this.resolveObject(urlParse(relative, false, true)).format();
	};

	function urlResolveObject(source, relative) {
	  if (!source) return relative;
	  return urlParse(source, false, true).resolveObject(relative);
	}

	Url.prototype.resolveObject = function(relative) {
	  if (isString(relative)) {
	    var rel = new Url();
	    rel.parse(relative, false, true);
	    relative = rel;
	  }

	  var result = new Url();
	  Object.keys(this).forEach(function(k) {
	    result[k] = this[k];
	  }, this);

	  // hash is always overridden, no matter what.
	  // even href="" will remove it.
	  result.hash = relative.hash;

	  // if the relative url is empty, then there's nothing left to do here.
	  if (relative.href === '') {
	    result.href = result.format();
	    return result;
	  }

	  // hrefs like //foo/bar always cut to the protocol.
	  if (relative.slashes && !relative.protocol) {
	    // take everything except the protocol from relative
	    Object.keys(relative).forEach(function(k) {
	      if (k !== 'protocol')
	        result[k] = relative[k];
	    });

	    //urlParse appends trailing / to urls like http://www.example.com
	    if (slashedProtocol[result.protocol] &&
	        result.hostname && !result.pathname) {
	      result.path = result.pathname = '/';
	    }

	    result.href = result.format();
	    return result;
	  }

	  if (relative.protocol && relative.protocol !== result.protocol) {
	    // if it's a known url protocol, then changing
	    // the protocol does weird things
	    // first, if it's not file:, then we MUST have a host,
	    // and if there was a path
	    // to begin with, then we MUST have a path.
	    // if it is file:, then the host is dropped,
	    // because that's known to be hostless.
	    // anything else is assumed to be absolute.
	    if (!slashedProtocol[relative.protocol]) {
	      Object.keys(relative).forEach(function(k) {
	        result[k] = relative[k];
	      });
	      result.href = result.format();
	      return result;
	    }

	    result.protocol = relative.protocol;
	    if (!relative.host && !hostlessProtocol[relative.protocol]) {
	      var relPath = (relative.pathname || '').split('/');
	      while (relPath.length && !(relative.host = relPath.shift()));
	      if (!relative.host) relative.host = '';
	      if (!relative.hostname) relative.hostname = '';
	      if (relPath[0] !== '') relPath.unshift('');
	      if (relPath.length < 2) relPath.unshift('');
	      result.pathname = relPath.join('/');
	    } else {
	      result.pathname = relative.pathname;
	    }
	    result.search = relative.search;
	    result.query = relative.query;
	    result.host = relative.host || '';
	    result.auth = relative.auth;
	    result.hostname = relative.hostname || relative.host;
	    result.port = relative.port;
	    // to support http.request
	    if (result.pathname || result.search) {
	      var p = result.pathname || '';
	      var s = result.search || '';
	      result.path = p + s;
	    }
	    result.slashes = result.slashes || relative.slashes;
	    result.href = result.format();
	    return result;
	  }

	  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
	      isRelAbs = (
	          relative.host ||
	          relative.pathname && relative.pathname.charAt(0) === '/'
	      ),
	      mustEndAbs = (isRelAbs || isSourceAbs ||
	                    (result.host && relative.pathname)),
	      removeAllDots = mustEndAbs,
	      srcPath = result.pathname && result.pathname.split('/') || [],
	      relPath = relative.pathname && relative.pathname.split('/') || [],
	      psychotic = result.protocol && !slashedProtocol[result.protocol];

	  // if the url is a non-slashed url, then relative
	  // links like ../.. should be able
	  // to crawl up to the hostname, as well.  This is strange.
	  // result.protocol has already been set by now.
	  // Later on, put the first path part into the host field.
	  if (psychotic) {
	    result.hostname = '';
	    result.port = null;
	    if (result.host) {
	      if (srcPath[0] === '') srcPath[0] = result.host;
	      else srcPath.unshift(result.host);
	    }
	    result.host = '';
	    if (relative.protocol) {
	      relative.hostname = null;
	      relative.port = null;
	      if (relative.host) {
	        if (relPath[0] === '') relPath[0] = relative.host;
	        else relPath.unshift(relative.host);
	      }
	      relative.host = null;
	    }
	    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
	  }

	  if (isRelAbs) {
	    // it's absolute.
	    result.host = (relative.host || relative.host === '') ?
	                  relative.host : result.host;
	    result.hostname = (relative.hostname || relative.hostname === '') ?
	                      relative.hostname : result.hostname;
	    result.search = relative.search;
	    result.query = relative.query;
	    srcPath = relPath;
	    // fall through to the dot-handling below.
	  } else if (relPath.length) {
	    // it's relative
	    // throw away the existing file, and take the new path instead.
	    if (!srcPath) srcPath = [];
	    srcPath.pop();
	    srcPath = srcPath.concat(relPath);
	    result.search = relative.search;
	    result.query = relative.query;
	  } else if (!isNullOrUndefined(relative.search)) {
	    // just pull out the search.
	    // like href='?foo'.
	    // Put this after the other two cases because it simplifies the booleans
	    if (psychotic) {
	      result.hostname = result.host = srcPath.shift();
	      //occationaly the auth can get stuck only in host
	      //this especialy happens in cases like
	      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
	      var authInHost = result.host && result.host.indexOf('@') > 0 ?
	                       result.host.split('@') : false;
	      if (authInHost) {
	        result.auth = authInHost.shift();
	        result.host = result.hostname = authInHost.shift();
	      }
	    }
	    result.search = relative.search;
	    result.query = relative.query;
	    //to support http.request
	    if (!isNull(result.pathname) || !isNull(result.search)) {
	      result.path = (result.pathname ? result.pathname : '') +
	                    (result.search ? result.search : '');
	    }
	    result.href = result.format();
	    return result;
	  }

	  if (!srcPath.length) {
	    // no path at all.  easy.
	    // we've already handled the other stuff above.
	    result.pathname = null;
	    //to support http.request
	    if (result.search) {
	      result.path = '/' + result.search;
	    } else {
	      result.path = null;
	    }
	    result.href = result.format();
	    return result;
	  }

	  // if a url ENDs in . or .., then it must get a trailing slash.
	  // however, if it ends in anything else non-slashy,
	  // then it must NOT get a trailing slash.
	  var last = srcPath.slice(-1)[0];
	  var hasTrailingSlash = (
	      (result.host || relative.host) && (last === '.' || last === '..') ||
	      last === '');

	  // strip single dots, resolve double dots to parent dir
	  // if the path tries to go above the root, `up` ends up > 0
	  var up = 0;
	  for (var i = srcPath.length; i >= 0; i--) {
	    last = srcPath[i];
	    if (last == '.') {
	      srcPath.splice(i, 1);
	    } else if (last === '..') {
	      srcPath.splice(i, 1);
	      up++;
	    } else if (up) {
	      srcPath.splice(i, 1);
	      up--;
	    }
	  }

	  // if the path is allowed to go above the root, restore leading ..s
	  if (!mustEndAbs && !removeAllDots) {
	    for (; up--; up) {
	      srcPath.unshift('..');
	    }
	  }

	  if (mustEndAbs && srcPath[0] !== '' &&
	      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
	    srcPath.unshift('');
	  }

	  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
	    srcPath.push('');
	  }

	  var isAbsolute = srcPath[0] === '' ||
	      (srcPath[0] && srcPath[0].charAt(0) === '/');

	  // put the host back
	  if (psychotic) {
	    result.hostname = result.host = isAbsolute ? '' :
	                                    srcPath.length ? srcPath.shift() : '';
	    //occationaly the auth can get stuck only in host
	    //this especialy happens in cases like
	    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
	    var authInHost = result.host && result.host.indexOf('@') > 0 ?
	                     result.host.split('@') : false;
	    if (authInHost) {
	      result.auth = authInHost.shift();
	      result.host = result.hostname = authInHost.shift();
	    }
	  }

	  mustEndAbs = mustEndAbs || (result.host && srcPath.length);

	  if (mustEndAbs && !isAbsolute) {
	    srcPath.unshift('');
	  }

	  if (!srcPath.length) {
	    result.pathname = null;
	    result.path = null;
	  } else {
	    result.pathname = srcPath.join('/');
	  }

	  //to support request.http
	  if (!isNull(result.pathname) || !isNull(result.search)) {
	    result.path = (result.pathname ? result.pathname : '') +
	                  (result.search ? result.search : '');
	  }
	  result.auth = relative.auth || result.auth;
	  result.slashes = result.slashes || relative.slashes;
	  result.href = result.format();
	  return result;
	};

	Url.prototype.parseHost = function() {
	  var host = this.host;
	  var port = portPattern.exec(host);
	  if (port) {
	    port = port[0];
	    if (port !== ':') {
	      this.port = port.substr(1);
	    }
	    host = host.substr(0, host.length - port.length);
	  }
	  if (host) this.hostname = host;
	};

	function isString(arg) {
	  return typeof arg === "string";
	}

	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}

	function isNull(arg) {
	  return arg === null;
	}
	function isNullOrUndefined(arg) {
	  return  arg == null;
	}


/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/punycode v1.3.2 by @mathias */
	;(function(root) {

		/** Detect free variables */
		var freeExports = typeof exports == 'object' && exports &&
			!exports.nodeType && exports;
		var freeModule = typeof module == 'object' && module &&
			!module.nodeType && module;
		var freeGlobal = typeof global == 'object' && global;
		if (
			freeGlobal.global === freeGlobal ||
			freeGlobal.window === freeGlobal ||
			freeGlobal.self === freeGlobal
		) {
			root = freeGlobal;
		}

		/**
		 * The `punycode` object.
		 * @name punycode
		 * @type Object
		 */
		var punycode,

		/** Highest positive signed 32-bit float value */
		maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1

		/** Bootstring parameters */
		base = 36,
		tMin = 1,
		tMax = 26,
		skew = 38,
		damp = 700,
		initialBias = 72,
		initialN = 128, // 0x80
		delimiter = '-', // '\x2D'

		/** Regular expressions */
		regexPunycode = /^xn--/,
		regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
		regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators

		/** Error messages */
		errors = {
			'overflow': 'Overflow: input needs wider integers to process',
			'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
			'invalid-input': 'Invalid input'
		},

		/** Convenience shortcuts */
		baseMinusTMin = base - tMin,
		floor = Math.floor,
		stringFromCharCode = String.fromCharCode,

		/** Temporary variable */
		key;

		/*--------------------------------------------------------------------------*/

		/**
		 * A generic error utility function.
		 * @private
		 * @param {String} type The error type.
		 * @returns {Error} Throws a `RangeError` with the applicable error message.
		 */
		function error(type) {
			throw RangeError(errors[type]);
		}

		/**
		 * A generic `Array#map` utility function.
		 * @private
		 * @param {Array} array The array to iterate over.
		 * @param {Function} callback The function that gets called for every array
		 * item.
		 * @returns {Array} A new array of values returned by the callback function.
		 */
		function map(array, fn) {
			var length = array.length;
			var result = [];
			while (length--) {
				result[length] = fn(array[length]);
			}
			return result;
		}

		/**
		 * A simple `Array#map`-like wrapper to work with domain name strings or email
		 * addresses.
		 * @private
		 * @param {String} domain The domain name or email address.
		 * @param {Function} callback The function that gets called for every
		 * character.
		 * @returns {Array} A new string of characters returned by the callback
		 * function.
		 */
		function mapDomain(string, fn) {
			var parts = string.split('@');
			var result = '';
			if (parts.length > 1) {
				// In email addresses, only the domain name should be punycoded. Leave
				// the local part (i.e. everything up to `@`) intact.
				result = parts[0] + '@';
				string = parts[1];
			}
			// Avoid `split(regex)` for IE8 compatibility. See #17.
			string = string.replace(regexSeparators, '\x2E');
			var labels = string.split('.');
			var encoded = map(labels, fn).join('.');
			return result + encoded;
		}

		/**
		 * Creates an array containing the numeric code points of each Unicode
		 * character in the string. While JavaScript uses UCS-2 internally,
		 * this function will convert a pair of surrogate halves (each of which
		 * UCS-2 exposes as separate characters) into a single code point,
		 * matching UTF-16.
		 * @see `punycode.ucs2.encode`
		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
		 * @memberOf punycode.ucs2
		 * @name decode
		 * @param {String} string The Unicode input string (UCS-2).
		 * @returns {Array} The new array of code points.
		 */
		function ucs2decode(string) {
			var output = [],
			    counter = 0,
			    length = string.length,
			    value,
			    extra;
			while (counter < length) {
				value = string.charCodeAt(counter++);
				if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
					// high surrogate, and there is a next character
					extra = string.charCodeAt(counter++);
					if ((extra & 0xFC00) == 0xDC00) { // low surrogate
						output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
					} else {
						// unmatched surrogate; only append this code unit, in case the next
						// code unit is the high surrogate of a surrogate pair
						output.push(value);
						counter--;
					}
				} else {
					output.push(value);
				}
			}
			return output;
		}

		/**
		 * Creates a string based on an array of numeric code points.
		 * @see `punycode.ucs2.decode`
		 * @memberOf punycode.ucs2
		 * @name encode
		 * @param {Array} codePoints The array of numeric code points.
		 * @returns {String} The new Unicode string (UCS-2).
		 */
		function ucs2encode(array) {
			return map(array, function(value) {
				var output = '';
				if (value > 0xFFFF) {
					value -= 0x10000;
					output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
					value = 0xDC00 | value & 0x3FF;
				}
				output += stringFromCharCode(value);
				return output;
			}).join('');
		}

		/**
		 * Converts a basic code point into a digit/integer.
		 * @see `digitToBasic()`
		 * @private
		 * @param {Number} codePoint The basic numeric code point value.
		 * @returns {Number} The numeric value of a basic code point (for use in
		 * representing integers) in the range `0` to `base - 1`, or `base` if
		 * the code point does not represent a value.
		 */
		function basicToDigit(codePoint) {
			if (codePoint - 48 < 10) {
				return codePoint - 22;
			}
			if (codePoint - 65 < 26) {
				return codePoint - 65;
			}
			if (codePoint - 97 < 26) {
				return codePoint - 97;
			}
			return base;
		}

		/**
		 * Converts a digit/integer into a basic code point.
		 * @see `basicToDigit()`
		 * @private
		 * @param {Number} digit The numeric value of a basic code point.
		 * @returns {Number} The basic code point whose value (when used for
		 * representing integers) is `digit`, which needs to be in the range
		 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
		 * used; else, the lowercase form is used. The behavior is undefined
		 * if `flag` is non-zero and `digit` has no uppercase form.
		 */
		function digitToBasic(digit, flag) {
			//  0..25 map to ASCII a..z or A..Z
			// 26..35 map to ASCII 0..9
			return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
		}

		/**
		 * Bias adaptation function as per section 3.4 of RFC 3492.
		 * http://tools.ietf.org/html/rfc3492#section-3.4
		 * @private
		 */
		function adapt(delta, numPoints, firstTime) {
			var k = 0;
			delta = firstTime ? floor(delta / damp) : delta >> 1;
			delta += floor(delta / numPoints);
			for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
				delta = floor(delta / baseMinusTMin);
			}
			return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
		}

		/**
		 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
		 * symbols.
		 * @memberOf punycode
		 * @param {String} input The Punycode string of ASCII-only symbols.
		 * @returns {String} The resulting string of Unicode symbols.
		 */
		function decode(input) {
			// Don't use UCS-2
			var output = [],
			    inputLength = input.length,
			    out,
			    i = 0,
			    n = initialN,
			    bias = initialBias,
			    basic,
			    j,
			    index,
			    oldi,
			    w,
			    k,
			    digit,
			    t,
			    /** Cached calculation results */
			    baseMinusT;

			// Handle the basic code points: let `basic` be the number of input code
			// points before the last delimiter, or `0` if there is none, then copy
			// the first basic code points to the output.

			basic = input.lastIndexOf(delimiter);
			if (basic < 0) {
				basic = 0;
			}

			for (j = 0; j < basic; ++j) {
				// if it's not a basic code point
				if (input.charCodeAt(j) >= 0x80) {
					error('not-basic');
				}
				output.push(input.charCodeAt(j));
			}

			// Main decoding loop: start just after the last delimiter if any basic code
			// points were copied; start at the beginning otherwise.

			for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {

				// `index` is the index of the next character to be consumed.
				// Decode a generalized variable-length integer into `delta`,
				// which gets added to `i`. The overflow checking is easier
				// if we increase `i` as we go, then subtract off its starting
				// value at the end to obtain `delta`.
				for (oldi = i, w = 1, k = base; /* no condition */; k += base) {

					if (index >= inputLength) {
						error('invalid-input');
					}

					digit = basicToDigit(input.charCodeAt(index++));

					if (digit >= base || digit > floor((maxInt - i) / w)) {
						error('overflow');
					}

					i += digit * w;
					t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);

					if (digit < t) {
						break;
					}

					baseMinusT = base - t;
					if (w > floor(maxInt / baseMinusT)) {
						error('overflow');
					}

					w *= baseMinusT;

				}

				out = output.length + 1;
				bias = adapt(i - oldi, out, oldi == 0);

				// `i` was supposed to wrap around from `out` to `0`,
				// incrementing `n` each time, so we'll fix that now:
				if (floor(i / out) > maxInt - n) {
					error('overflow');
				}

				n += floor(i / out);
				i %= out;

				// Insert `n` at position `i` of the output
				output.splice(i++, 0, n);

			}

			return ucs2encode(output);
		}

		/**
		 * Converts a string of Unicode symbols (e.g. a domain name label) to a
		 * Punycode string of ASCII-only symbols.
		 * @memberOf punycode
		 * @param {String} input The string of Unicode symbols.
		 * @returns {String} The resulting Punycode string of ASCII-only symbols.
		 */
		function encode(input) {
			var n,
			    delta,
			    handledCPCount,
			    basicLength,
			    bias,
			    j,
			    m,
			    q,
			    k,
			    t,
			    currentValue,
			    output = [],
			    /** `inputLength` will hold the number of code points in `input`. */
			    inputLength,
			    /** Cached calculation results */
			    handledCPCountPlusOne,
			    baseMinusT,
			    qMinusT;

			// Convert the input in UCS-2 to Unicode
			input = ucs2decode(input);

			// Cache the length
			inputLength = input.length;

			// Initialize the state
			n = initialN;
			delta = 0;
			bias = initialBias;

			// Handle the basic code points
			for (j = 0; j < inputLength; ++j) {
				currentValue = input[j];
				if (currentValue < 0x80) {
					output.push(stringFromCharCode(currentValue));
				}
			}

			handledCPCount = basicLength = output.length;

			// `handledCPCount` is the number of code points that have been handled;
			// `basicLength` is the number of basic code points.

			// Finish the basic string - if it is not empty - with a delimiter
			if (basicLength) {
				output.push(delimiter);
			}

			// Main encoding loop:
			while (handledCPCount < inputLength) {

				// All non-basic code points < n have been handled already. Find the next
				// larger one:
				for (m = maxInt, j = 0; j < inputLength; ++j) {
					currentValue = input[j];
					if (currentValue >= n && currentValue < m) {
						m = currentValue;
					}
				}

				// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
				// but guard against overflow
				handledCPCountPlusOne = handledCPCount + 1;
				if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
					error('overflow');
				}

				delta += (m - n) * handledCPCountPlusOne;
				n = m;

				for (j = 0; j < inputLength; ++j) {
					currentValue = input[j];

					if (currentValue < n && ++delta > maxInt) {
						error('overflow');
					}

					if (currentValue == n) {
						// Represent delta as a generalized variable-length integer
						for (q = delta, k = base; /* no condition */; k += base) {
							t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
							if (q < t) {
								break;
							}
							qMinusT = q - t;
							baseMinusT = base - t;
							output.push(
								stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
							);
							q = floor(qMinusT / baseMinusT);
						}

						output.push(stringFromCharCode(digitToBasic(q, 0)));
						bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
						delta = 0;
						++handledCPCount;
					}
				}

				++delta;
				++n;

			}
			return output.join('');
		}

		/**
		 * Converts a Punycode string representing a domain name or an email address
		 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
		 * it doesn't matter if you call it on a string that has already been
		 * converted to Unicode.
		 * @memberOf punycode
		 * @param {String} input The Punycoded domain name or email address to
		 * convert to Unicode.
		 * @returns {String} The Unicode representation of the given Punycode
		 * string.
		 */
		function toUnicode(input) {
			return mapDomain(input, function(string) {
				return regexPunycode.test(string)
					? decode(string.slice(4).toLowerCase())
					: string;
			});
		}

		/**
		 * Converts a Unicode string representing a domain name or an email address to
		 * Punycode. Only the non-ASCII parts of the domain name will be converted,
		 * i.e. it doesn't matter if you call it with a domain that's already in
		 * ASCII.
		 * @memberOf punycode
		 * @param {String} input The domain name or email address to convert, as a
		 * Unicode string.
		 * @returns {String} The Punycode representation of the given domain name or
		 * email address.
		 */
		function toASCII(input) {
			return mapDomain(input, function(string) {
				return regexNonASCII.test(string)
					? 'xn--' + encode(string)
					: string;
			});
		}

		/*--------------------------------------------------------------------------*/

		/** Define the public API */
		punycode = {
			/**
			 * A string representing the current Punycode.js version number.
			 * @memberOf punycode
			 * @type String
			 */
			'version': '1.3.2',
			/**
			 * An object of methods to convert from JavaScript's internal character
			 * representation (UCS-2) to Unicode code points, and back.
			 * @see <https://mathiasbynens.be/notes/javascript-encoding>
			 * @memberOf punycode
			 * @type Object
			 */
			'ucs2': {
				'decode': ucs2decode,
				'encode': ucs2encode
			},
			'decode': decode,
			'encode': encode,
			'toASCII': toASCII,
			'toUnicode': toUnicode
		};

		/** Expose `punycode` */
		// Some AMD build optimizers, like r.js, check for specific condition patterns
		// like the following:
		if (
			true
		) {
			!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
				return punycode;
			}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else if (freeExports && freeModule) {
			if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
				freeModule.exports = punycode;
			} else { // in Narwhal or RingoJS v0.7.0-
				for (key in punycode) {
					punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
				}
			}
		} else { // in Rhino or a web browser
			root.punycode = punycode;
		}

	}(this));

	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(93)(module), (function() { return this; }())))

/***/ },
/* 93 */
/***/ function(module, exports) {

	module.exports = function(module) {
		if(!module.webpackPolyfill) {
			module.deprecate = function() {};
			module.paths = [];
			// module.parent = undefined by default
			module.children = [];
			module.webpackPolyfill = 1;
		}
		return module;
	}


/***/ },
/* 94 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	exports.decode = exports.parse = __webpack_require__(95);
	exports.encode = exports.stringify = __webpack_require__(96);


/***/ },
/* 95 */
/***/ function(module, exports) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	'use strict';

	// If obj.hasOwnProperty has been overridden, then calling
	// obj.hasOwnProperty(prop) will break.
	// See: https://github.com/joyent/node/issues/1707
	function hasOwnProperty(obj, prop) {
	  return Object.prototype.hasOwnProperty.call(obj, prop);
	}

	module.exports = function(qs, sep, eq, options) {
	  sep = sep || '&';
	  eq = eq || '=';
	  var obj = {};

	  if (typeof qs !== 'string' || qs.length === 0) {
	    return obj;
	  }

	  var regexp = /\+/g;
	  qs = qs.split(sep);

	  var maxKeys = 1000;
	  if (options && typeof options.maxKeys === 'number') {
	    maxKeys = options.maxKeys;
	  }

	  var len = qs.length;
	  // maxKeys <= 0 means that we should not limit keys count
	  if (maxKeys > 0 && len > maxKeys) {
	    len = maxKeys;
	  }

	  for (var i = 0; i < len; ++i) {
	    var x = qs[i].replace(regexp, '%20'),
	        idx = x.indexOf(eq),
	        kstr, vstr, k, v;

	    if (idx >= 0) {
	      kstr = x.substr(0, idx);
	      vstr = x.substr(idx + 1);
	    } else {
	      kstr = x;
	      vstr = '';
	    }

	    k = decodeURIComponent(kstr);
	    v = decodeURIComponent(vstr);

	    if (!hasOwnProperty(obj, k)) {
	      obj[k] = v;
	    } else if (Array.isArray(obj[k])) {
	      obj[k].push(v);
	    } else {
	      obj[k] = [obj[k], v];
	    }
	  }

	  return obj;
	};


/***/ },
/* 96 */
/***/ function(module, exports) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	'use strict';

	var stringifyPrimitive = function(v) {
	  switch (typeof v) {
	    case 'string':
	      return v;

	    case 'boolean':
	      return v ? 'true' : 'false';

	    case 'number':
	      return isFinite(v) ? v : '';

	    default:
	      return '';
	  }
	};

	module.exports = function(obj, sep, eq, name) {
	  sep = sep || '&';
	  eq = eq || '=';
	  if (obj === null) {
	    obj = undefined;
	  }

	  if (typeof obj === 'object') {
	    return Object.keys(obj).map(function(k) {
	      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
	      if (Array.isArray(obj[k])) {
	        return obj[k].map(function(v) {
	          return ks + encodeURIComponent(stringifyPrimitive(v));
	        }).join(sep);
	      } else {
	        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
	      }
	    }).join(sep);

	  }

	  if (!name) return '';
	  return encodeURIComponent(stringifyPrimitive(name)) + eq +
	         encodeURIComponent(stringifyPrimitive(obj));
	};


/***/ },
/* 97 */
/***/ function(module, exports, __webpack_require__) {

	var json = typeof JSON !== 'undefined' ? JSON : __webpack_require__(98);

	module.exports = function (obj, opts) {
	    if (!opts) opts = {};
	    if (typeof opts === 'function') opts = { cmp: opts };
	    var space = opts.space || '';
	    if (typeof space === 'number') space = Array(space+1).join(' ');
	    var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
	    var replacer = opts.replacer || function(key, value) { return value; };

	    var cmp = opts.cmp && (function (f) {
	        return function (node) {
	            return function (a, b) {
	                var aobj = { key: a, value: node[a] };
	                var bobj = { key: b, value: node[b] };
	                return f(aobj, bobj);
	            };
	        };
	    })(opts.cmp);

	    var seen = [];
	    return (function stringify (parent, key, node, level) {
	        var indent = space ? ('\n' + new Array(level + 1).join(space)) : '';
	        var colonSeparator = space ? ': ' : ':';

	        if (node && node.toJSON && typeof node.toJSON === 'function') {
	            node = node.toJSON();
	        }

	        node = replacer.call(parent, key, node);

	        if (node === undefined) {
	            return;
	        }
	        if (typeof node !== 'object' || node === null) {
	            return json.stringify(node);
	        }
	        if (isArray(node)) {
	            var out = [];
	            for (var i = 0; i < node.length; i++) {
	                var item = stringify(node, i, node[i], level+1) || json.stringify(null);
	                out.push(indent + space + item);
	            }
	            return '[' + out.join(',') + indent + ']';
	        }
	        else {
	            if (seen.indexOf(node) !== -1) {
	                if (cycles) return json.stringify('__cycle__');
	                throw new TypeError('Converting circular structure to JSON');
	            }
	            else seen.push(node);

	            var keys = objectKeys(node).sort(cmp && cmp(node));
	            var out = [];
	            for (var i = 0; i < keys.length; i++) {
	                var key = keys[i];
	                var value = stringify(node, key, node[key], level+1);

	                if(!value) continue;

	                var keyValue = json.stringify(key)
	                    + colonSeparator
	                    + value;
	                ;
	                out.push(indent + space + keyValue);
	            }
	            return '{' + out.join(',') + indent + '}';
	        }
	    })({ '': obj }, '', obj, 0);
	};

	var isArray = Array.isArray || function (x) {
	    return {}.toString.call(x) === '[object Array]';
	};

	var objectKeys = Object.keys || function (obj) {
	    var has = Object.prototype.hasOwnProperty || function () { return true };
	    var keys = [];
	    for (var key in obj) {
	        if (has.call(obj, key)) keys.push(key);
	    }
	    return keys;
	};


/***/ },
/* 98 */
/***/ function(module, exports, __webpack_require__) {

	exports.parse = __webpack_require__(99);
	exports.stringify = __webpack_require__(100);


/***/ },
/* 99 */
/***/ function(module, exports) {

	var at, // The index of the current character
	    ch, // The current character
	    escapee = {
	        '"':  '"',
	        '\\': '\\',
	        '/':  '/',
	        b:    '\b',
	        f:    '\f',
	        n:    '\n',
	        r:    '\r',
	        t:    '\t'
	    },
	    text,

	    error = function (m) {
	        // Call error when something is wrong.
	        throw {
	            name:    'SyntaxError',
	            message: m,
	            at:      at,
	            text:    text
	        };
	    },
	    
	    next = function (c) {
	        // If a c parameter is provided, verify that it matches the current character.
	        if (c && c !== ch) {
	            error("Expected '" + c + "' instead of '" + ch + "'");
	        }
	        
	        // Get the next character. When there are no more characters,
	        // return the empty string.
	        
	        ch = text.charAt(at);
	        at += 1;
	        return ch;
	    },
	    
	    number = function () {
	        // Parse a number value.
	        var number,
	            string = '';
	        
	        if (ch === '-') {
	            string = '-';
	            next('-');
	        }
	        while (ch >= '0' && ch <= '9') {
	            string += ch;
	            next();
	        }
	        if (ch === '.') {
	            string += '.';
	            while (next() && ch >= '0' && ch <= '9') {
	                string += ch;
	            }
	        }
	        if (ch === 'e' || ch === 'E') {
	            string += ch;
	            next();
	            if (ch === '-' || ch === '+') {
	                string += ch;
	                next();
	            }
	            while (ch >= '0' && ch <= '9') {
	                string += ch;
	                next();
	            }
	        }
	        number = +string;
	        if (!isFinite(number)) {
	            error("Bad number");
	        } else {
	            return number;
	        }
	    },
	    
	    string = function () {
	        // Parse a string value.
	        var hex,
	            i,
	            string = '',
	            uffff;
	        
	        // When parsing for string values, we must look for " and \ characters.
	        if (ch === '"') {
	            while (next()) {
	                if (ch === '"') {
	                    next();
	                    return string;
	                } else if (ch === '\\') {
	                    next();
	                    if (ch === 'u') {
	                        uffff = 0;
	                        for (i = 0; i < 4; i += 1) {
	                            hex = parseInt(next(), 16);
	                            if (!isFinite(hex)) {
	                                break;
	                            }
	                            uffff = uffff * 16 + hex;
	                        }
	                        string += String.fromCharCode(uffff);
	                    } else if (typeof escapee[ch] === 'string') {
	                        string += escapee[ch];
	                    } else {
	                        break;
	                    }
	                } else {
	                    string += ch;
	                }
	            }
	        }
	        error("Bad string");
	    },

	    white = function () {

	// Skip whitespace.

	        while (ch && ch <= ' ') {
	            next();
	        }
	    },

	    word = function () {

	// true, false, or null.

	        switch (ch) {
	        case 't':
	            next('t');
	            next('r');
	            next('u');
	            next('e');
	            return true;
	        case 'f':
	            next('f');
	            next('a');
	            next('l');
	            next('s');
	            next('e');
	            return false;
	        case 'n':
	            next('n');
	            next('u');
	            next('l');
	            next('l');
	            return null;
	        }
	        error("Unexpected '" + ch + "'");
	    },

	    value,  // Place holder for the value function.

	    array = function () {

	// Parse an array value.

	        var array = [];

	        if (ch === '[') {
	            next('[');
	            white();
	            if (ch === ']') {
	                next(']');
	                return array;   // empty array
	            }
	            while (ch) {
	                array.push(value());
	                white();
	                if (ch === ']') {
	                    next(']');
	                    return array;
	                }
	                next(',');
	                white();
	            }
	        }
	        error("Bad array");
	    },

	    object = function () {

	// Parse an object value.

	        var key,
	            object = {};

	        if (ch === '{') {
	            next('{');
	            white();
	            if (ch === '}') {
	                next('}');
	                return object;   // empty object
	            }
	            while (ch) {
	                key = string();
	                white();
	                next(':');
	                if (Object.hasOwnProperty.call(object, key)) {
	                    error('Duplicate key "' + key + '"');
	                }
	                object[key] = value();
	                white();
	                if (ch === '}') {
	                    next('}');
	                    return object;
	                }
	                next(',');
	                white();
	            }
	        }
	        error("Bad object");
	    };

	value = function () {

	// Parse a JSON value. It could be an object, an array, a string, a number,
	// or a word.

	    white();
	    switch (ch) {
	    case '{':
	        return object();
	    case '[':
	        return array();
	    case '"':
	        return string();
	    case '-':
	        return number();
	    default:
	        return ch >= '0' && ch <= '9' ? number() : word();
	    }
	};

	// Return the json_parse function. It will have access to all of the above
	// functions and variables.

	module.exports = function (source, reviver) {
	    var result;
	    
	    text = source;
	    at = 0;
	    ch = ' ';
	    result = value();
	    white();
	    if (ch) {
	        error("Syntax error");
	    }

	    // If there is a reviver function, we recursively walk the new structure,
	    // passing each name/value pair to the reviver function for possible
	    // transformation, starting with a temporary root object that holds the result
	    // in an empty key. If there is not a reviver function, we simply return the
	    // result.

	    return typeof reviver === 'function' ? (function walk(holder, key) {
	        var k, v, value = holder[key];
	        if (value && typeof value === 'object') {
	            for (k in value) {
	                if (Object.prototype.hasOwnProperty.call(value, k)) {
	                    v = walk(value, k);
	                    if (v !== undefined) {
	                        value[k] = v;
	                    } else {
	                        delete value[k];
	                    }
	                }
	            }
	        }
	        return reviver.call(holder, key, value);
	    }({'': result}, '')) : result;
	};


/***/ },
/* 100 */
/***/ function(module, exports) {

	var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
	    escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
	    gap,
	    indent,
	    meta = {    // table of character substitutions
	        '\b': '\\b',
	        '\t': '\\t',
	        '\n': '\\n',
	        '\f': '\\f',
	        '\r': '\\r',
	        '"' : '\\"',
	        '\\': '\\\\'
	    },
	    rep;

	function quote(string) {
	    // If the string contains no control characters, no quote characters, and no
	    // backslash characters, then we can safely slap some quotes around it.
	    // Otherwise we must also replace the offending characters with safe escape
	    // sequences.
	    
	    escapable.lastIndex = 0;
	    return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
	        var c = meta[a];
	        return typeof c === 'string' ? c :
	            '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
	    }) + '"' : '"' + string + '"';
	}

	function str(key, holder) {
	    // Produce a string from holder[key].
	    var i,          // The loop counter.
	        k,          // The member key.
	        v,          // The member value.
	        length,
	        mind = gap,
	        partial,
	        value = holder[key];
	    
	    // If the value has a toJSON method, call it to obtain a replacement value.
	    if (value && typeof value === 'object' &&
	            typeof value.toJSON === 'function') {
	        value = value.toJSON(key);
	    }
	    
	    // If we were called with a replacer function, then call the replacer to
	    // obtain a replacement value.
	    if (typeof rep === 'function') {
	        value = rep.call(holder, key, value);
	    }
	    
	    // What happens next depends on the value's type.
	    switch (typeof value) {
	        case 'string':
	            return quote(value);
	        
	        case 'number':
	            // JSON numbers must be finite. Encode non-finite numbers as null.
	            return isFinite(value) ? String(value) : 'null';
	        
	        case 'boolean':
	        case 'null':
	            // If the value is a boolean or null, convert it to a string. Note:
	            // typeof null does not produce 'null'. The case is included here in
	            // the remote chance that this gets fixed someday.
	            return String(value);
	            
	        case 'object':
	            if (!value) return 'null';
	            gap += indent;
	            partial = [];
	            
	            // Array.isArray
	            if (Object.prototype.toString.apply(value) === '[object Array]') {
	                length = value.length;
	                for (i = 0; i < length; i += 1) {
	                    partial[i] = str(i, value) || 'null';
	                }
	                
	                // Join all of the elements together, separated with commas, and
	                // wrap them in brackets.
	                v = partial.length === 0 ? '[]' : gap ?
	                    '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
	                    '[' + partial.join(',') + ']';
	                gap = mind;
	                return v;
	            }
	            
	            // If the replacer is an array, use it to select the members to be
	            // stringified.
	            if (rep && typeof rep === 'object') {
	                length = rep.length;
	                for (i = 0; i < length; i += 1) {
	                    k = rep[i];
	                    if (typeof k === 'string') {
	                        v = str(k, value);
	                        if (v) {
	                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
	                        }
	                    }
	                }
	            }
	            else {
	                // Otherwise, iterate through all of the keys in the object.
	                for (k in value) {
	                    if (Object.prototype.hasOwnProperty.call(value, k)) {
	                        v = str(k, value);
	                        if (v) {
	                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
	                        }
	                    }
	                }
	            }
	            
	        // Join all of the member texts together, separated with commas,
	        // and wrap them in braces.

	        v = partial.length === 0 ? '{}' : gap ?
	            '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
	            '{' + partial.join(',') + '}';
	        gap = mind;
	        return v;
	    }
	}

	module.exports = function (value, replacer, space) {
	    var i;
	    gap = '';
	    indent = '';
	    
	    // If the space parameter is a number, make an indent string containing that
	    // many spaces.
	    if (typeof space === 'number') {
	        for (i = 0; i < space; i += 1) {
	            indent += ' ';
	        }
	    }
	    // If the space parameter is a string, it will be used as the indent string.
	    else if (typeof space === 'string') {
	        indent = space;
	    }

	    // If there is a replacer, it must be a function or an array.
	    // Otherwise, throw an error.
	    rep = replacer;
	    if (replacer && typeof replacer !== 'function'
	    && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
	        throw new Error('JSON.stringify');
	    }
	    
	    // Make a fake root object containing our value under the key of ''.
	    // Return the result of stringifying the value.
	    return str('', {'': value});
	};


/***/ }
/******/ ])
});
;