text: ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(acequire, exports, module) {
  "use strict";
  
  var oop = acequire("../lib/oop");
  var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
  
  var XmlHighlightRules = function(normalize) {
      var tagRegex = "[_:a-zA-Z\xc0-\uffff][-_:.a-zA-Z0-9\xc0-\uffff]*";
  
      this.$rules = {
          start : [
              {token : "string.cdata.xml", regex : "<\\!\\[CDATA\\[", next : "cdata"},
              {
                  token : ["punctuation.xml-decl.xml", "keyword.xml-decl.xml"],
                  regex : "(<\\?)(xml)(?=[\\s])", next : "xml_decl", caseInsensitive: true
              },
              {
                  token : ["punctuation.instruction.xml", "keyword.instruction.xml"],
                  regex : "(<\\?)(" + tagRegex + ")", next : "processing_instruction"
              },
              {token : "comment.xml", regex : "<\\!--", next : "comment"},
              {
                  token : ["xml-pe.doctype.xml", "xml-pe.doctype.xml"],
                  regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype", caseInsensitive: true
              },
              {include : "tag"},
              {token : "text.end-tag-open.xml", regex: "</"},
              {token : "text.tag-open.xml", regex: "<"},
              {include : "reference"},
              {defaultToken : "text.xml"}
          ],
  
          xml_decl : [{
              token : "entity.other.attribute-name.decl-attribute-name.xml",
              regex : "(?:" + tagRegex + ":)?" + tagRegex + ""
          }, {
              token : "keyword.operator.decl-attribute-equals.xml",
              regex : "="
          }, {
              include: "whitespace"
          }, {
              include: "string"
          }, {
              token : "punctuation.xml-decl.xml",
              regex : "\\?>",
              next : "start"
          }],
  
          processing_instruction : [
              {token : "punctuation.instruction.xml", regex : "\\?>", next : "start"},
              {defaultToken : "instruction.xml"}
          ],
  
          doctype : [
              {include : "whitespace"},
              {include : "string"},
              {token : "xml-pe.doctype.xml", regex : ">", next : "start"},
              {token : "xml-pe.xml", regex : "[-_a-zA-Z0-9:]+"},
              {token : "punctuation.int-subset", regex : "\\[", push : "int_subset"}
          ],
  
          int_subset : [{
              token : "text.xml",
              regex : "\\s+"
          }, {
              token: "punctuation.int-subset.xml",
              regex: "]",
              next: "pop"
          }, {
              token : ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"],
              regex : "(<\\!)(" + tagRegex + ")",
              push : [{
                  token : "text",
                  regex : "\\s+"
              },
              {
                  token : "punctuation.markup-decl.xml",
                  regex : ">",
                  next : "pop"
              },
              {include : "string"}]
          }],
  
          cdata : [
              {token : "string.cdata.xml", regex : "\\]\\]>", next : "start"},
              {token : "text.xml", regex : "\\s+"},
              {token : "text.xml", regex : "(?:[^\\]]|\\](?!\\]>))+"}
          ],
  
          comment : [
              {token : "comment.xml", regex : "-->", next : "start"},
              {defaultToken : "comment.xml"}
          ],
  
          reference : [{
              token : "constant.language.escape.reference.xml",
              regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
          }],
  
          attr_reference : [{
              token : "constant.language.escape.reference.attribute-value.xml",
              regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
          }],
  
          tag : [{
              token : ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"],
              regex : "(?:(<)|(</))((?:" + tagRegex + ":)?" + tagRegex + ")",
              next: [
                  {include : "attributes"},
                  {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : "start"}
              ]
          }],
  
          tag_whitespace : [
              {token : "text.tag-whitespace.xml", regex : "\\s+"}
          ],
          whitespace : [
              {token : "text.whitespace.xml", regex : "\\s+"}
          ],
          string: [{
              token : "string.xml",
              regex : "'",
              push : [
                  {token : "string.xml", regex: "'", next: "pop"},
                  {defaultToken : "string.xml"}
              ]
          }, {
              token : "string.xml",
              regex : '"',
              push : [
                  {token : "string.xml", regex: '"', next: "pop"},
                  {defaultToken : "string.xml"}
              ]
          }],
  
          attributes: [{
              token : "entity.other.attribute-name.xml",
              regex : "(?:" + tagRegex + ":)?" + tagRegex + ""
          }, {
              token : "keyword.operator.attribute-equals.xml",
              regex : "="
          }, {
              include: "tag_whitespace"
          }, {
              include: "attribute_value"
          }],
  
          attribute_value: [{
              token : "string.attribute-value.xml",
              regex : "'",
              push : [
                  {token : "string.attribute-value.xml", regex: "'", next: "pop"},
                  {include : "attr_reference"},
                  {defaultToken : "string.attribute-value.xml"}
              ]
          }, {
              token : "string.attribute-value.xml",
              regex : '"',
              push : [
                  {token : "string.attribute-value.xml", regex: '"', next: "pop"},
                  {include : "attr_reference"},
                  {defaultToken : "string.attribute-value.xml"}
              ]
          }]
      };
  
      if (this.constructor === XmlHighlightRules)
          this.normalizeRules();
  };
  
  
  (function() {
  
      this.embedTagRules = function(HighlightRules, prefix, tag){
          this.$rules.tag.unshift({
              token : ["meta.tag.punctuation.tag-open.xml", "meta.tag." + tag + ".tag-name.xml"],
              regex : "(<)(" + tag + "(?=\\s|>|$))",
              next: [
                  {include : "attributes"},
                  {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : prefix + "start"}
              ]
          });
  
          this.$rules[tag + "-end"] = [
              {include : "attributes"},
              {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>",  next: "start",
                  onMatch : function(value, currentState, stack) {
                      stack.splice(0);
                      return this.token;
              }}
          ]
  
          this.embedRules(HighlightRules, prefix, [{
              token: ["meta.tag.punctuation.end-tag-open.xml", "meta.tag." + tag + ".tag-name.xml"],
              regex : "(</)(" + tag + "(?=\\s|>|$))",
              next: tag + "-end"
          }, {
              token: "string.cdata.xml",
              regex : "<\\!\\[CDATA\\["
          }, {
              token: "string.cdata.xml",
              regex : "\\]\\]>"
          }]);
      };
  
  }).call(TextHighlightRules.prototype);
  
  oop.inherits(XmlHighlightRules, TextHighlightRules);
  
  exports.XmlHighlightRules = XmlHighlightRules;
  });
  
  ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(acequire, exports, module) {
  "use strict";
  
  var oop = acequire("../../lib/oop");
  var Behaviour = acequire("../behaviour").Behaviour;
  var TokenIterator = acequire("../../token_iterator").TokenIterator;
  var lang = acequire("../../lib/lang");
  
  function is(token, type) {
      return token.type.lastIndexOf(type + ".xml") > -1;
  }
  
  var XmlBehaviour = function () {
  
      this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
          if (text == '"' || text == "'") {
              var quote = text;
              var selected = session.doc.getTextRange(editor.getSelectionRange());
              if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
                  return {
                      text: quote + selected + quote,
                      selection: false
                  };
              }
  
              var cursor = editor.getCursorPosition();
              var line = session.doc.getLine(cursor.row);
              var rightChar = line.substring(cursor.column, cursor.column + 1);
              var iterator = new TokenIterator(session, cursor.row, cursor.column);
              var token = iterator.getCurrentToken();
  
              if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) {
                  return {
                      text: "",
                      selection: [1, 1]
                  };
              }
  
              if (!token)
                  token = iterator.stepBackward();
  
              if (!token)
                  return;
  
              while (is(token, "tag-whitespace") || is(token, "whitespace")) {
                  token = iterator.stepBackward();
              }
              var rightSpace = !rightChar || rightChar.match(/\s/);
              if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) {
                  return {
                      text: quote + quote,
                      selection: [1, 1]
                  };
              }
          }
      });
  
      this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
          var selected = session.doc.getTextRange(range);
          if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
              var line = session.doc.getLine(range.start.row);
              var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
              if (rightChar == selected) {
                  range.end.column++;
                  return range;
              }
          }
      });
  
      this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
          if (text == '>') {
              var position = editor.getCursorPosition();
              var iterator = new TokenIterator(session, position.row, position.column);
              var token = iterator.getCurrentToken() || iterator.stepBackward();
              if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value")))
                  return;
              if (is(token, "reference.attribute-value"))
                  return;
              if (is(token, "attribute-value")) {
                  var firstChar = token.value.charAt(0);
                  if (firstChar == '"' || firstChar == "'") {
                      var lastChar = token.value.charAt(token.value.length - 1);
                      var tokenEnd = iterator.getCurrentTokenColumn() + token.value.length;
                      if (tokenEnd > position.column || tokenEnd == position.column && firstChar != lastChar)
                          return;
                  }
              }
              while (!is(token, "tag-name")) {
                  token = iterator.stepBackward();
              }
  
              var tokenRow = iterator.getCurrentTokenRow();
              var tokenColumn = iterator.getCurrentTokenColumn();
              if (is(iterator.stepBackward(), "end-tag-open"))
                  return;
  
              var element = token.value;
              if (tokenRow == position.row)
                  element = element.substring(0, position.column - tokenColumn);
  
              if (this.voidElements.hasOwnProperty(element.toLowerCase()))
                   return;
  
              return {
                 text: ">" + "</" + element + ">",
                 selection: [1, 1]
              };
          }
      });
  
      this.add("autoindent", "insertion", function (state, action, editor, session, text) {
          if (text == "\n") {
              var cursor = editor.getCursorPosition();
              var line = session.getLine(cursor.row);
              var iterator = new TokenIterator(session, cursor.row, cursor.column);
              var token = iterator.getCurrentToken();
  
              if (token && token.type.indexOf("tag-close") !== -1) {
                  if (token.value == "/>")
                      return;
                  while (token && token.type.indexOf("tag-name") === -1) {
                      token = iterator.stepBackward();
                  }
  
                  if (!token) {
                      return;
                  }
  
                  var tag = token.value;
                  var row = iterator.getCurrentTokenRow();
                  token = iterator.stepBackward();
                  if (!token || token.type.indexOf("end-tag") !== -1) {
                      return;
                  }
  
                  if (this.voidElements && !this.voidElements[tag]) {
                      var nextToken = session.getTokenAt(cursor.row, cursor.column+1);
                      var line = session.getLine(row);
                      var nextIndent = this.$getIndent(line);
                      var indent = nextIndent + session.getTabString();
  
                      if (nextToken && nextToken.value === "</") {
                          return {
                              text: "\n" + indent + "\n" + nextIndent,
                              selection: [1, indent.length, 1, indent.length]
                          };
                      } else {
                          return {
                              text: "\n" + indent
                          };
                      }
                  }
              }
          }
      });
  
  };
  
  oop.inherits(XmlBehaviour, Behaviour);
  
  exports.XmlBehaviour = XmlBehaviour;
  });
  
  ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"], function(acequire, exports, module) {
  "use strict";
  
  var oop = acequire("../../lib/oop");
  var lang = acequire("../../lib/lang");
  var Range = acequire("../../range").Range;
  var BaseFoldMode = acequire("./fold_mode").FoldMode;
  var TokenIterator = acequire("../../token_iterator").TokenIterator;
  
  var FoldMode = exports.FoldMode = function(voidElements, optionalEndTags) {
      BaseFoldMode.call(this);
      this.voidElements = voidElements || {};
      this.optionalEndTags = oop.mixin({}, this.voidElements);
      if (optionalEndTags)
          oop.mixin(this.optionalEndTags, optionalEndTags);
      
  };
  oop.inherits(FoldMode, BaseFoldMode);
  
  var Tag = function() {
      this.tagName = "";
      this.closing = false;
      this.selfClosing = false;
      this.start = {row: 0, column: 0};
      this.end = {row: 0, column: 0};
  };
  
  function is(token, type) {
      return token.type.lastIndexOf(type + ".xml") > -1;
  }
  
  (function() {
  
      this.getFoldWidget = function(session, foldStyle, row) {
          var tag = this._getFirstTagInLine(session, row);
  
          if (!tag)
              return "";
  
          if (tag.closing || (!tag.tagName && tag.selfClosing))
              return foldStyle == "markbeginend" ? "end" : "";
  
          if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase()))
              return "";
  
          if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column))
              return "";
  
          return "start";
      };
      this._getFirstTagInLine = function(session, row) {
          var tokens = session.getTokens(row);
          var tag = new Tag();
  
          for (var i = 0; i < tokens.length; i++) {
              var token = tokens[i];
              if (is(token, "tag-open")) {
                  tag.end.column = tag.start.column + token.value.length;
                  tag.closing = is(token, "end-tag-open");
                  token = tokens[++i];
                  if (!token)
                      return null;
                  tag.tagName = token.value;
                  tag.end.column += token.value.length;
                  for (i++; i < tokens.length; i++) {
                      token = tokens[i];
                      tag.end.column += token.value.length;
                      if (is(token, "tag-close")) {
                          tag.selfClosing = token.value == '/>';
                          break;
                      }
                  }
                  return tag;
              } else if (is(token, "tag-close")) {
                  tag.selfClosing = token.value == '/>';
                  return tag;
              }
              tag.start.column += token.value.length;
          }
  
          return null;
      };
  
      this._findEndTagInLine = function(session, row, tagName, startColumn) {
          var tokens = session.getTokens(row);
          var column = 0;
          for (var i = 0; i < tokens.length; i++) {
              var token = tokens[i];
              column += token.value.length;
              if (column < startColumn)
                  continue;
              if (is(token, "end-tag-open")) {
                  token = tokens[i + 1];
                  if (token && token.value == tagName)
                      return true;
              }
          }
          return false;
      };
      this._readTagForward = function(iterator) {
          var token = iterator.getCurrentToken();
          if (!token)
              return null;
  
          var tag = new Tag();
          do {
              if (is(token, "tag-open")) {
                  tag.closing = is(token, "end-tag-open");
                  tag.start.row = iterator.getCurrentTokenRow();
                  tag.start.column = iterator.getCurrentTokenColumn();
              } else if (is(token, "tag-name")) {
                  tag.tagName = token.value;
              } else if (is(token, "tag-close")) {
                  tag.selfClosing = token.value == "/>";
                  tag.end.row = iterator.getCurrentTokenRow();
                  tag.end.column = iterator.getCurrentTokenColumn() + token.value.length;
                  iterator.stepForward();
                  return tag;
              }
          } while(token = iterator.stepForward());
  
          return null;
      };
      
      this._readTagBackward = function(iterator) {
          var token = iterator.getCurrentToken();
          if (!token)
              return null;
  
          var tag = new Tag();
          do {
              if (is(token, "tag-open")) {
                  tag.closing = is(token, "end-tag-open");
                  tag.start.row = iterator.getCurrentTokenRow();
                  tag.start.column = iterator.getCurrentTokenColumn();
                  iterator.stepBackward();
                  return tag;
              } else if (is(token, "tag-name")) {
                  tag.tagName = token.value;
              } else if (is(token, "tag-close")) {
                  tag.selfClosing = token.value == "/>";
                  tag.end.row = iterator.getCurrentTokenRow();
                  tag.end.column = iterator.getCurrentTokenColumn() + token.value.length;
              }
          } while(token = iterator.stepBackward());
  
          return null;
      };
      
      this._pop = function(stack, tag) {
          while (stack.length) {
              
              var top = stack[stack.length-1];
              if (!tag || top.tagName == tag.tagName) {
                  return stack.pop();
              }
              else if (this.optionalEndTags.hasOwnProperty(top.tagName)) {
                  stack.pop();
                  continue;
              } else {
                  return null;
              }
          }
      };
      
      this.getFoldWidgetRange = function(session, foldStyle, row) {
          var firstTag = this._getFirstTagInLine(session, row);
          
          if (!firstTag)
              return null;
          
          var isBackward = firstTag.closing || firstTag.selfClosing;
          var stack = [];
          var tag;
          
          if (!isBackward) {
              var iterator = new TokenIterator(session, row, firstTag.start.column);
              var start = {
                  row: row,
                  column: firstTag.start.column + firstTag.tagName.length + 2
              };
              if (firstTag.start.row == firstTag.end.row)
                  start.column = firstTag.end.column;
              while (tag = this._readTagForward(iterator)) {
                  if (tag.selfClosing) {
                      if (!stack.length) {
                          tag.start.column += tag.tagName.length + 2;
                          tag.end.column -= 2;
                          return Range.fromPoints(tag.start, tag.end);
                      } else
                          continue;
                  }
                  
                  if (tag.closing) {
                      this._pop(stack, tag);
                      if (stack.length == 0)
                          return Range.fromPoints(start, tag.start);
                  }
                  else {
                      stack.push(tag);
                  }
              }
          }
          else {
              var iterator = new TokenIterator(session, row, firstTag.end.column);
              var end = {
                  row: row,
                  column: firstTag.start.column
              };
              
              while (tag = this._readTagBackward(iterator)) {
                  if (tag.selfClosing) {
                      if (!stack.length) {
                          tag.start.column += tag.tagName.length + 2;
                          tag.end.column -= 2;
                          return Range.fromPoints(tag.start, tag.end);
                      } else
                          continue;
                  }
                  
                  if (!tag.closing) {
                      this._pop(stack, tag);
                      if (stack.length == 0) {
                          tag.start.column += tag.tagName.length + 2;
                          if (tag.start.row == tag.end.row && tag.start.column < tag.end.column)
                              tag.start.column = tag.end.column;
                          return Range.fromPoints(tag.start, end);
                      }
                  }
                  else {
                      stack.push(tag);
                  }
              }
          }
          
      };
  
  }).call(FoldMode.prototype);
  
  });
  
  ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml","ace/worker/worker_client"], function(acequire, exports, module) {
  "use strict";
  
  var oop = acequire("../lib/oop");
  var lang = acequire("../lib/lang");
  var TextMode = acequire("./text").Mode;
  var XmlHighlightRules = acequire("./xml_highlight_rules").XmlHighlightRules;
  var XmlBehaviour = acequire("./behaviour/xml").XmlBehaviour;
  var XmlFoldMode = acequire("./folding/xml").FoldMode;
  var WorkerClient = acequire("../worker/worker_client").WorkerClient;
  
  var Mode = function() {
     this.HighlightRules = XmlHighlightRules;
     this.$behaviour = new XmlBehaviour();
     this.foldingRules = new XmlFoldMode();
  };
  
  oop.inherits(Mode, TextMode);
  
  (function() {
  
      this.voidElements = lang.arrayToMap([]);
  
      this.blockComment = {start: "<!--", end: "-->"};
  
      this.createWorker = function(session) {
          var worker = new WorkerClient(["ace"], require("../worker/xml"), "Worker");
          worker.attachToDocument(session.getDocument());
  
          worker.on("error", function(e) {
              session.setAnnotations(e.data);
          });
  
          worker.on("terminate", function() {
              session.clearAnnotations();
          });
  
          return worker;
      };
      
      this.$id = "ace/mode/xml";
  }).call(Mode.prototype);
  
  exports.Mode = Mode;
  });
  