/**
 * Ace Editor Mode for XmlObject Custom Script Language
 * Based on C# mode with custom keywords and functions for CheckXML project
 */
define("ace/mode/doc_comment_highlight_rules_xmlobject", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text_highlight_rules"], function (e, t, n) {
    "use strict";
    var r = e("../lib/oop"),
        i = e("./text_highlight_rules").TextHighlightRules,
        s = function () {
            this.$rules = {
                start: [{
                    token: "comment.doc.tag",
                    regex: "@\\w+(?=\\s|$)"
                }, s.getTagRule(), {
                    defaultToken: "comment.doc",
                    caseInsensitive: !0
                }]
            }
        };
    r.inherits(s, i),
        s.getTagRule = function (e) {
            return {
                token: "comment.doc.tag.storage.type",
                regex: "\\b(?:TODO|FIXME|XXX|HACK)\\b"
            }
        },
        s.getStartRule = function (e) {
            return {
                token: "comment.doc",
                regex: "\\/\\*(?=\\*)",
                next: e
            }
        },
        s.getEndRule = function (e) {
            return {
                token: "comment.doc",
                regex: "\\*\\/",
                next: e
            }
        },
        t.DocCommentHighlightRules = s
}),

define("ace/mode/xmlobject_highlight_rules", ["require", "exports", "module", "ace/lib/oop", "ace/mode/doc_comment_highlight_rules_xmlobject", "ace/mode/text_highlight_rules"], function (e, t, n) {
    "use strict";
    var r = e("../lib/oop"),
        i = e("./doc_comment_highlight_rules_xmlobject").DocCommentHighlightRules,
        s = e("./text_highlight_rules").TextHighlightRules,
        o = function () {
            // Custom XmlObject functions - highlighted as "support.function"
            var xmlObjectFunctions = (
                "TLookUp|StringInStr|StringExist|StringReplace|VlookUp|Sum|SumIf|SumIf2|CountIf|Length|" +
                "Xpath|Xpaths|Val|Execute|Casentive|ToDateTime|Diff|Between|Year|Quater|Mon|Day|Hour|Min|" +
                "Config|IsCheck|ParentId|MaQL|ShowTable|Show|showtable|Text|ReplaceFirst|" +
                "IsPTTT|IsPT|IsTT|IsTruocPT|IsSauPT|Exec|IsNumber"
            );

            // LINQ functions - highlighted as "support.function.linq"
            var linqFunctions = (
                "Any|Where|Select|OrderBy|OrderByDescending|ToL|GroupBy|ToList|FirstOrDefault|LastOrDefault|" +
                "Count|Max|Min|Average|Distinct|Take|Skip|Concat|Union|Intersect|Except|Zip|Join|GroupJoin|" +
                "OfType|Cast|AsEnumerable|AsQueryable|AsParallel|AsSequential|ToDictionary|ToLookup|DefaultIfEmpty"
            );

            // XML variables - highlighted as "variable.xml"
            var xmlVariables = (
                "XML1|XML2|XML3|XML4|XML5|XML6|XML7|XML8|XML9|XML10|XML11|XML13|XML14|XML15|" +
                "XML130|XML4210|HOSO|NodesSet|XmlObject"
            );

            // Color functions - highlighted as "support.function.color"
            var colorFunctions = "Red|Blue|Purple|Orange|Grey|red|blue|purple|orange|grey";

            // C# keywords
            var csharpKeywords = (
                "abstract|async|await|event|new|struct|as|explicit|null|switch|base|extern|object|this|" +
                "bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|" +
                "catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|" +
                "const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|" +
                "delegate|internal|partial|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|" +
                "string|var|dynamic|and|or"
            );

            // Field types from Models
            var fieldTypes = "StringField|DecimalField|IntField";

            // XML element types
            var xmlTypes = (
                "TONG_HOP_130|CHI_TIET_THUOC_130|CHI_TIET_DVKT_130|CHI_TIET_CLS_130|CHI_TIET_DIEN_BIEN_BENH_130|" +
                "HO_SO_BENH_AN_CHAM_SOC_VA_DIEU_TRI_HIV_AIDS|CHI_TIEU_DU_LIEU_GIAY_RA_VIEN|CHI_TIEU_DU_LIEU_TOM_TAT_HO_SO_BENH_AN|" +
                "DU_LIEU_GIAY_CHUNG_SINH|CHI_TIEU_DU_LIEU_GIAY_NGHI_DUONG_THAI|CHI_TIEU_DU_LIEU_GIAY_CHUNG_NHAN_NGHI_VIEC_HUONG_BAO_HIEM_XA_HOI|" +
                "CHI_TIEU_GIAYCHUYENTUYEN|CHI_TIEU_GIAYHEN_KHAMLAI|CHITIET_DIEUTRI_BENHLAO|" +
                "CHI_TIET_THUOC_4210|CHI_TIET_DVKT_4210|HOSO130|HOSO4210"
            );

            var keywordMapper = this.createKeywordMapper({
                "variable.language": "this",
                "keyword": csharpKeywords,
                "constant.language": "null|true|false",
                "support.function": xmlObjectFunctions,
                "support.function.linq": linqFunctions,
                "variable.xml": xmlVariables,
                "support.function.color": colorFunctions,
                "storage.type": fieldTypes,
                "support.type": xmlTypes
            }, "identifier", true);

            this.$rules = {
                start: [
                    // Comments
                    {
                        token: "comment",
                        regex: "\\/\\/.*$"
                    },
                    i.getStartRule("doc-start"),
                    {
                        token: "comment",
                        regex: "\\/\\*",
                        next: "comment"
                    },
                    // XPath expressions - special highlight
                    {
                        token: ["support.function", "paren.lparen", "string.xpath", "paren.rparen"],
                        regex: "(Xpath|Xpaths|xpath|xpaths)(\\()(['\"][^'\"]*['\"])(\\))"
                    },
                    // XML variable access pattern: xml1.FIELD or XML1?.FIELD
                    {
                        token: ["variable.xml", "punctuation.operator", "variable.parameter"],
                        regex: "(xml\\d+\\??|XML\\d+\\??)(\\.)([A-Z_][A-Z0-9_]*)",
                        caseInsensitive: true
                    },
                    // Character literals
                    {
                        token: "string",
                        regex: /'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))?'/
                    },
                    // Regular strings
                    {
                        token: "string",
                        start: '"',
                        end: '"|$',
                        next: [{
                            token: "constant.language.escape",
                            regex: /\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/
                        }, {
                            token: "invalid",
                            regex: /\\./
                        }]
                    },
                    // Verbatim strings
                    {
                        token: "string",
                        start: '@"',
                        end: '"',
                        next: [{
                            token: "constant.language.escape",
                            regex: '""'
                        }]
                    },
                    // Interpolated strings
                    {
                        token: "string",
                        start: /\$"/,
                        end: '"|$',
                        next: [{
                            token: "constant.language.escape",
                            regex: /\\(:?$)|{{/
                        }, {
                            token: "constant.language.escape",
                            regex: /\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/
                        }, {
                            token: "invalid",
                            regex: /\\./
                        }]
                    },
                    // Hexadecimal numbers
                    {
                        token: "constant.numeric",
                        regex: "0[xX][0-9a-fA-F]+\\b"
                    },
                    // Decimal numbers
                    {
                        token: "constant.numeric",
                        regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
                    },
                    // Boolean literals
                    {
                        token: "constant.language.boolean",
                        regex: "(?:true|false)\\b"
                    },
                    // Color function calls: .Red() .Blue() etc
                    {
                        token: ["punctuation.operator", "support.function.color", "paren.lparen", "paren.rparen"],
                        regex: "(\\.)([Rr]ed|[Bb]lue|[Pp]urple|[Oo]range|[Gg]rey)(\\()(\\))"
                    },
                    // Color function with parameters: Red(param)
                    {
                        token: ["support.function.color", "paren.lparen"],
                        regex: "([Rr]ed|[Bb]lue|[Pp]urple|[Oo]range|[Gg]rey)(\\()"
                    },
                    // .Val property/method
                    {
                        token: ["punctuation.operator", "support.function"],
                        regex: "(\\.)([Vv]al)\\b"
                    },
                    // .Length property
                    {
                        token: ["punctuation.operator", "support.function"],
                        regex: "(\\.)([Ll]ength)\\b"
                    },
                    // Keywords and identifiers
                    {
                        token: keywordMapper,
                        regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
                    },
                    // Operators
                    {
                        token: "keyword.operator",
                        regex: "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
                    },
                    // Preprocessor directives
                    {
                        token: "keyword",
                        regex: "^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)"
                    },
                    // Punctuation
                    {
                        token: "punctuation.operator",
                        regex: "\\?|\\:|\\,|\\;|\\."
                    },
                    // Opening brackets
                    {
                        token: "paren.lparen",
                        regex: "[[({]"
                    },
                    // Closing brackets
                    {
                        token: "paren.rparen",
                        regex: "[\\])}]"
                    },
                    // Whitespace
                    {
                        token: "text",
                        regex: "\\s+"
                    }
                ],
                comment: [{
                    token: "comment",
                    regex: "\\*\\/",
                    next: "start"
                }, {
                    defaultToken: "comment"
                }]
            };

            this.embedRules(i, "doc-", [i.getEndRule("start")]);
            this.normalizeRules();
        };

    r.inherits(o, s);
    t.XmlObjectHighlightRules = o;
}),

define("ace/mode/matching_brace_outdent_xmlobject", ["require", "exports", "module", "ace/range"], function (e, t, n) {
    "use strict";
    var r = e("../range").Range,
        i = function () { };
    (function () {
        this.checkOutdent = function (e, t) {
            return /^\s+$/.test(e) ? /^\s*\}/.test(t) : !1
        };
        this.autoOutdent = function (e, t) {
            var n = e.getLine(t),
                i = n.match(/^(\s*\})/);
            if (!i) return 0;
            var s = i[1].length,
                o = e.findMatchingBracket({ row: t, column: s });
            if (!o || o.row == t) return 0;
            var u = this.$getIndent(e.getLine(o.row));
            e.replace(new r(t, 0, t, s - 1), u)
        };
        this.$getIndent = function (e) {
            return e.match(/^\s*/)[0]
        }
    }).call(i.prototype);
    t.MatchingBraceOutdent = i
}),

define("ace/mode/folding/xmlobject", ["require", "exports", "module", "ace/lib/oop", "ace/range", "ace/mode/folding/fold_mode"], function (e, t, n) {
    "use strict";
    var r = e("../../lib/oop"),
        i = e("../../range").Range,
        s = e("./fold_mode").FoldMode,
        o = t.FoldMode = function (e) {
            e && (this.foldingStartMarker = new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + e.start)),
                this.foldingStopMarker = new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + e.end)))
        };

    r.inherits(o, s);

    (function () {
        this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/;
        this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/;
        this.singleLineBlockCommentRe = /^\s*(\/\*).*\*\/\s*$/;
        this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/;
        this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/;

        this._getFoldWidgetBase = this.getFoldWidget;

        this.getFoldWidget = function (e, t, n) {
            var r = e.getLine(n);
            if (this.singleLineBlockCommentRe.test(r) && !this.startRegionRe.test(r) && !this.tripleStarBlockCommentRe.test(r))
                return "";
            var i = this._getFoldWidgetBase(e, t, n);
            return !i && this.startRegionRe.test(r) ? "start" : i
        };

        this.getFoldWidgetRange = function (e, t, n, r) {
            var i = e.getLine(n);
            if (this.startRegionRe.test(i))
                return this.getCommentRegionBlock(e, i, n);
            var s = i.match(this.foldingStartMarker);
            if (s) {
                var o = s.index;
                if (s[1])
                    return this.openingBracketBlock(e, s[1], n, o);
                var u = e.getCommentFoldRange(n, o + s[0].length, 1);
                return u && !u.isMultiLine() && (r ? u = this.getSectionRange(e, n) : t != "all" && (u = null)), u
            }
            if (t === "markbegin") return;
            var s = i.match(this.foldingStopMarker);
            if (s) {
                var o = s.index + s[0].length;
                return s[1] ? this.closingBracketBlock(e, s[1], n, o) : e.getCommentFoldRange(n, o, -1)
            }
        };

        this.getSectionRange = function (e, t) {
            var n = e.getLine(t),
                r = n.search(/\S/),
                s = t,
                o = n.length;
            t += 1;
            var u = t,
                a = e.getLength();
            while (++t < a) {
                n = e.getLine(t);
                var f = n.search(/\S/);
                if (f === -1) continue;
                if (r > f) break;
                var l = this.getFoldWidgetRange(e, "all", t);
                if (l) {
                    if (l.start.row <= s) break;
                    if (l.isMultiLine()) t = l.end.row;
                    else if (r == f) break
                }
                u = t
            }
            return new i(s, o, u, e.getLine(u).length)
        };

        this.getCommentRegionBlock = function (e, t, n) {
            var r = t.search(/\s*$/),
                s = e.getLength(),
                o = n,
                u = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,
                a = 1;
            while (++n < s) {
                t = e.getLine(n);
                var f = u.exec(t);
                if (!f) continue;
                f[1] ? a-- : a++;
                if (!a) break
            }
            var l = n;
            if (l > o) return new i(o, r, l, t.length)
        }
    }).call(o.prototype)
}),

define("ace/mode/xmlobject", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text", "ace/mode/xmlobject_highlight_rules", "ace/mode/matching_brace_outdent_xmlobject", "ace/mode/folding/xmlobject"], function (e, t, n) {
    "use strict";
    var r = e("../lib/oop"),
        i = e("./text").Mode,
        s = e("./xmlobject_highlight_rules").XmlObjectHighlightRules,
        o = e("./matching_brace_outdent_xmlobject").MatchingBraceOutdent,
        u = e("./folding/xmlobject").FoldMode,
        a = function () {
            this.HighlightRules = s;
            this.$outdent = new o;
            this.$behaviour = this.$defaultBehaviour;
            this.foldingRules = new u
        };

    r.inherits(a, i);

    (function () {
        this.lineCommentStart = "//";
        this.blockComment = { start: "/*", end: "*/" };

        this.getNextLineIndent = function (e, t, n) {
            var r = this.$getIndent(t),
                i = this.getTokenizer().getLineTokens(t, e),
                s = i.tokens;
            if (s.length && s[s.length - 1].type == "comment")
                return r;
            if (e == "start") {
                var o = t.match(/^.*[\{\(\[]\s*$/);
                o && (r += n)
            }
            return r
        };

        this.checkOutdent = function (e, t, n) {
            return this.$outdent.checkOutdent(t, n)
        };

        this.autoOutdent = function (e, t, n) {
            this.$outdent.autoOutdent(t, n)
        };

        this.createWorker = function (e) {
            return null
        };

        this.$id = "ace/mode/xmlobject"
    }).call(a.prototype);

    t.Mode = a
});

// Auto-register the mode
(function () {
    window.require(["ace/mode/xmlobject"], function (m) {
        if (typeof module == "object" && typeof exports == "object" && module) {
            module.exports = m;
        }
    });
})();
