ace.define('ace/mode/error', function(require, exports, module) {
  const TextMode = require('ace/mode/text').Mode;
  const TextHighlightRules = require('ace/mode/text_highlight_rules')
    .TextHighlightRules;

  class ErrorMode extends TextMode {
    constructor() {
      super();
      this.$id = 'ace/mode/error';
      this.HighlightRules = ErrorHighlightRules;
    }
  }

  class ErrorHighlightRules extends TextHighlightRules {
    constructor() {
      super();
      this.$rules = {
        start: [
          {
            token: 'invalid',
            regex: /^(:?(:?Server|Network) )?Error:$/,
          },
          {
            token: ['markup.bold', 'invalid', 'markup.bold'],
            regex: /^([\w\-\/.~]+:[0-9]*:[0-9]*: )(error:)( .+)$/
          },
          {
            token: 'markup.bold.keyword',
            regex: /~*\^~*$/,
          },
        ],
      };
    }
  }

  exports.Mode = ErrorMode;
});

ace.define('ace/mode/bytes', function(require, exports, module) {
  const TextMode = require('ace/mode/text').Mode;
  const TextHighlightRules = require('ace/mode/text_highlight_rules')
    .TextHighlightRules;

  class BytesMode extends TextMode {
    constructor() {
      super();
      this.$id = 'ace/mode/bytes';
      this.HighlightRules = BytesHighlightRules;
      this.lineCommentStart = '//';
    }
  }

  class BytesHighlightRules extends TextHighlightRules {
    constructor() {
      super();
      this.$rules = {
        start: [
          {
            token: 'comment',
            regex: '//.*$',
          },
          {
            token: 'string',
            regex: /"(?:[^"\\]|\\.)*?"/,
          },
          {
            token: ['text', 'variable'],
            regex: /^(\s*)([0-9a-fA-F]+:)/,
          },
          {
            token: ['constant.numeric', 'keyword.operator'],
            regex: /((?:-)?(?:0b[01]+|0o[0-7]+|0x[0-9a-fA-F]+|[0-9]+))([ui](?:8|16|32|64))\b/,
          },
        ],
      };
    }
  }

  exports.Mode = BytesMode;
});

ace.define('ace/mode/fidl', function(require, exports, module) {
  const TextMode = require('ace/mode/text').Mode;
  const TextHighlightRules = require('ace/mode/text_highlight_rules')
    .TextHighlightRules;
  const MatchingBraceOutdent = require('ace/mode/matching_brace_outdent')
    .MatchingBraceOutdent;
  const CstyleBehaviour = require('ace/mode/behaviour/cstyle').CstyleBehaviour;
  const CstyleFoldMode = require('ace/mode/folding/cstyle').FoldMode;

  class FidlMode extends TextMode {
    constructor() {
      super();
      this.$id = 'ace/mode/fidl';
      this.HighlightRules = FidlHighlightRules;
      this.$outdent = new MatchingBraceOutdent();
      this.$behaviour = new CstyleBehaviour();
      this.foldingRules = new CstyleFoldMode();
      this.lineCommentStart = '//';
    }

    getNextLineIndent(state, line, tab) {
      let indent = line.match(/^\s*/)[0];
      const tokens = this.getTokenizer().getLineTokens(line, state).tokens;
      if (tokens.length && tokens[tokens.length - 1].type === 'comment') {
        return indent;
      }
      if (state === 'start') {
        const match = line.match(/^.*[\{\(\[]\s*$/);
        if (match) {
          indent += tab;
        }
      }
      return indent;
    }

    checkOutdent(state, line, input) {
      return this.$outdent.checkOutdent(line, input);
    }

    autoOutdent(state, doc, row) {
      this.$outdent.autoOutdent(doc, row);
    }
  }

  class FidlHighlightRules extends TextHighlightRules {
    constructor() {
      super();
      this.$rules = {
        start: [
          {
            token: 'comment',
            regex: '//.*$',
          },
          {
            token: 'string',
            regex: /"(?:[^"\\]|\\.)*?"/,
          },
          {
            token: 'keyword',
            regex: /\b(?:as|bits|compose|const|enum|library|protocol|struct|table|union|using|xunion)\b/,
          },
          {
            token: 'support.type',
            regex: /\b(?:bool|int8|int16|int32|int64|uint8|uint16|uint32|uint64|float32|float64|array|vector|string|byte|bytes)\b/,
          },
          {
            token: ['text', 'keyword'],
            regex: /(\)\s*)(error)\b/,
          },
          {
            token: 'keyword.operator',
            regex: /->|:/,
          },
          {
            token: 'support.type',
            regex: /<|>/,
          },
          {
            token: 'constant.language',
            regex: /\b(?:true|false)\b/,
          },
          {
            token: 'constant.numeric',
            regex: /\b0[xX][0-9a-fA-F]+\b/,
          },
          {
            token: 'constant.numeric',
            regex: /\b[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/,
          },
          {
            token: ['entity.name.function', 'text'],
            regex: /([a-zA-Z](?:[a-zA-Z0-9_]*[a-zA-Z0-9])?)(\()/,
          },
        ],
      };
    }
  }

  exports.Mode = FidlMode;
});
