( function ( mod ) { mod ( window . CodeMirror ) ; } ) ( function ( CodeMirror ) { "use strict" ; CodeMirror . defineMode ( "javascript" , function ( config , parserConfig ) { var indentUnit = config . indentUnit ; var statementIndent = parserConfig . statementIndent ; var jsonldMode = parserConfig . jsonld ; var jsonMode = parserConfig . json || jsonldMode ; var trackScope = parserConfig . trackScope !== false ; var isTS = parserConfig . typescript ; var wordRE = parserConfig . wordCharacters || /[\w$\xa1-\uffff]/ ; var keywords = ( function ( ) { function kw ( type ) { return { type : type , style : "keyword" } ; } var A = kw ( "keyword a" ) , B = kw ( "keyword b" ) , C = kw ( "keyword c" ) , D = kw ( "keyword d" ) ; var operator = kw ( "operator" ) , atom = { type : "atom" , style : "atom" } ; return { if : kw ( "if" ) , while : A , with : A , else : B , do : B , try : B , finally : B , return : D , break : D , continue : D , new : kw ( "new" ) , delete : C , void : C , throw : C , debugger : kw ( "debugger" ) , 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" ) , class : kw ( "class" ) , super : kw ( "atom" ) , yield : C , export : kw ( "export" ) , import : kw ( "import" ) , extends : C , await : C , } ; } ) ( ) ; var isOperatorChar = /[+\-*&%=<>!?|~^@]/ ; var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/ ; function readRegexp ( stream ) { var escaped = false , next , inSet = false ; while ( ( next = stream . next ( ) ) != null ) { if ( ! escaped ) { if ( next == "/" && ! inSet ) return ; if ( next == "[" ) inSet = true ; else if ( inSet && next == "]" ) inSet = false ; } escaped = ! escaped && next == "\\" ; } } var type , content ; function ret ( tp , style , cont ) { type = tp ; content = cont ; return style ; } function tokenBase ( stream , state ) { var ch = stream . next ( ) ; if ( ch == '"' || ch == "'" ) { state . tokenize = tokenString ( ch ) ; return state . tokenize ( stream , state ) ; } else if ( ch == "." && stream . match ( /^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/ ) ) { return ret ( "number" , "number" ) ; } else if ( ch == "." && stream . match ( ".." ) ) { return ret ( "spread" , "meta" ) ; } else if ( /[\[\]{}\(\),;\:\.]/ . test ( ch ) ) { return ret ( ch ) ; } else if ( ch == "=" && stream . eat ( ">" ) ) { return ret ( "=>" , "operator" ) ; } else if ( ch == "0" && stream . match ( /^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/ ) ) { return ret ( "number" , "number" ) ; } else if ( /\d/ . test ( ch ) ) { stream . match ( /^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/ ) ; return ret ( "number" , "number" ) ; } else if ( ch == "/" ) { if ( stream . eat ( "*" ) ) { state . tokenize = tokenComment ; return tokenComment ( stream , state ) ; } else if ( stream . eat ( "/" ) ) { stream . skipToEnd ( ) ; return ret ( "comment" , "comment" ) ; } else if ( expressionAllowed ( stream , state , 1 ) ) { readRegexp ( stream ) ; stream . match ( /^\b(([gimyus])(?![gimyus]*\2))+\b/ ) ; return ret ( "regexp" , "string-2" ) ; } else { stream . eat ( "=" ) ; return ret ( "operator" , "operator" , stream . current ( ) ) ; } } else if ( ch == "`" ) { state . tokenize = tokenQuasi ; return tokenQuasi ( stream , state ) ; } else if ( ch == "#" && stream . peek ( ) == "!" ) { stream . skipToEnd ( ) ; return ret ( "meta" , "meta" ) ; } else if ( ch == "#" && stream . eatWhile ( wordRE ) ) { return ret ( "variable" , "property" ) ; } else if ( ( ch == "<" && stream . match ( "!--" ) ) || ( ch == "-" && stream . match ( "->" ) && ! /\S/ . test ( stream . string . slice ( 0 , stream . start ) ) ) ) { stream . skipToEnd ( ) ; return ret ( "comment" , "comment" ) ; } else if ( isOperatorChar . test ( ch ) ) { if ( ch != ">" || ! state . lexical || state . lexical . type != ">" ) { if ( stream . eat ( "=" ) ) { if ( ch == "!" || ch == "=" ) stream . eat ( "=" ) ; } else if ( /[<>*+\-|&?]/ . test ( ch ) ) { stream . eat ( ch ) ; if ( ch == ">" ) stream . eat ( ch ) ; } } if ( ch == "?" && stream . eat ( "." ) ) return ret ( "." ) ; return ret ( "operator" , "operator" , stream . current ( ) ) ; } else if ( wordRE . test ( ch ) ) { stream . eatWhile ( wordRE ) ; var word = stream . current ( ) ; if ( state . lastType != "." ) { if ( keywords . propertyIsEnumerable ( word ) ) { var kw = keywords [ word ] ; return ret ( kw . type , kw . style , word ) ; } if ( word == "async" && stream . match ( /^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/ , false ) ) return ret ( "async" , "keyword" , word ) ; } return ret ( "variable" , "variable" , word ) ; } } function tokenString ( quote ) { return function ( stream , state ) { var escaped = false , next ; if ( jsonldMode && stream . peek ( ) == "@" && stream . match ( isJsonldKeyword ) ) { state . tokenize = tokenBase ; return ret ( "jsonld-keyword" , "meta" ) ; } while ( ( next = stream . next ( ) ) != null ) { if ( next == quote && ! escaped ) break ; escaped = ! escaped && next == "\\" ; } if ( ! escaped ) state . tokenize = tokenBase ; return ret ( "string" , "string" ) ; } ; } function tokenComment ( stream , state ) { var maybeEnd = false , ch ; while ( ( ch = stream . next ( ) ) ) { if ( ch == "/" && maybeEnd ) { state . tokenize = tokenBase ; break ; } maybeEnd = ch == "*" ; } return ret ( "comment" , "comment" ) ; } function tokenQuasi ( stream , state ) { var escaped = false , next ; while ( ( next = stream . next ( ) ) != null ) { if ( ! escaped && ( next == "`" || ( next == "$" && stream . eat ( "{" ) ) ) ) { state . tokenize = tokenBase ; break ; } escaped = ! escaped && next == "\\" ; } return ret ( "quasi" , "string-2" , stream . current ( ) ) ; } var brackets = "([{}])" ; function findFatArrow ( stream , state ) { if ( state . fatArrowAt ) state . fatArrowAt = null ; var arrow = stream . string . indexOf ( "=>" , stream . start ) ; if ( arrow < 0 ) return ; if ( isTS ) { var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/ . exec ( stream . string . slice ( stream . start , arrow ) ) ; if ( m ) arrow = m . index ; } var depth = 0 , sawSomething = false ; for ( var pos = arrow - 1 ; pos >= 0 ; -- pos ) { var ch = stream . string . charAt ( pos ) ; var bracket = brackets . indexOf ( ch ) ; if ( bracket >= 0 && bracket < 3 ) { if ( ! depth ) { ++ pos ; break ; } if ( -- depth == 0 ) { if ( ch == "(" ) sawSomething = true ; break ; } } else if ( bracket >= 3 && bracket < 6 ) { ++ depth ; } else if ( wordRE . test ( ch ) ) { sawSomething = true ; } else if ( /["'\/`]/ . test ( ch ) ) { for ( ; ; -- pos ) { if ( pos == 0 ) return ; var next = stream . string . charAt ( pos - 1 ) ; if ( next == ch && stream . string . charAt ( pos - 2 ) != "\\" ) { pos -- ; break ; } } } else if ( sawSomething && ! depth ) { ++ pos ; break ; } } if ( sawSomething && ! depth ) state . fatArrowAt = pos ; } var atomicTypes = { atom : true , number : true , variable : true , string : true , regexp : true , this : true , import : true , "jsonld-keyword" : 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 ) { if ( ! trackScope ) return false ; for ( var v = state . localVars ; v ; v = v . next ) if ( v . name == varname ) return true ; for ( var cx = state . context ; cx ; cx = cx . prev ) { for ( var v = cx . vars ; v ; v = v . next ) if ( v . name == varname ) return true ; } } function parseJS ( state , style , type , content , stream ) { var cc = state . cc ; cx . state = state ; cx . stream = stream ; ( cx . marked = null ) , ( cx . cc = cc ) ; cx . style = style ; 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 ; } } } 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 inList ( name , list ) { for ( var v = list ; v ; v = v . next ) if ( v . name == name ) return true ; return false ; } function register ( varname ) { var state = cx . state ; cx . marked = "def" ; if ( ! trackScope ) return ; if ( state . context ) { if ( state . lexical . info == "var" && state . context && state . context . block ) { var newContext = registerVarScoped ( varname , state . context ) ; if ( newContext != null ) { state . context = newContext ; return ; } } else if ( ! inList ( varname , state . localVars ) ) { state . localVars = new Var ( varname , state . localVars ) ; return ; } } if ( parserConfig . globalVars && ! inList ( varname , state . globalVars ) ) state . globalVars = new Var ( varname , state . globalVars ) ; } function registerVarScoped ( varname , context ) { if ( ! context ) { return null ; } else if ( context . block ) { var inner = registerVarScoped ( varname , context . prev ) ; if ( ! inner ) return null ; if ( inner == context . prev ) return context ; return new Context ( inner , context . vars , true ) ; } else if ( inList ( varname , context . vars ) ) { return context ; } else { return new Context ( context . prev , new Var ( varname , context . vars ) , false ) ; } } function isModifier ( name ) { return ( name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly" ) ; } function Context ( prev , vars , block ) { this . prev = prev ; this . vars = vars ; this . block = block ; } function Var ( name , next ) { this . name = name ; this . next = next ; } var defaultVars = new Var ( "this" , new Var ( "arguments" , null ) ) ; function pushcontext ( ) { cx . state . context = new Context ( cx . state . context , cx . state . localVars , false ) ; cx . state . localVars = defaultVars ; } function pushblockcontext ( ) { cx . state . context = new Context ( cx . state . context , cx . state . localVars , true ) ; cx . state . localVars = null ; } function popcontext ( ) { cx . state . localVars = cx . state . context . vars ; cx . state . context = cx . state . context . prev ; } popcontext . lex = true ; function pushlex ( type , info ) { var result = function ( ) { var state = cx . state , indent = state . indented ; if ( state . lexical . type == "stat" ) indent = state . lexical . indented ; else for ( var outer = state . lexical ; outer && outer . type == ")" && outer . align ; outer = outer . prev ) indent = outer . 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 ) { function exp ( type ) { if ( type == wanted ) return cont ( ) ; else if ( wanted == ";" || type == "}" || type == ")" || type == "]" ) return pass ( ) ; else return cont ( exp ) ; } return exp ; } function statement ( type , value ) { if ( type == "var" ) return cont ( pushlex ( "vardef" , value ) , vardef , expect ( ";" ) , poplex ) ; if ( type == "keyword a" ) return cont ( pushlex ( "form" ) , parenExpr , statement , poplex ) ; if ( type == "keyword b" ) return cont ( pushlex ( "form" ) , statement , poplex ) ; if ( type == "keyword d" ) return cx . stream . match ( /^\s*$/ , false ) ? cont ( ) : cont ( pushlex ( "stat" ) , maybeexpression , expect ( ";" ) , poplex ) ; if ( type == "debugger" ) return cont ( expect ( ";" ) ) ; if ( type == "{" ) return cont ( pushlex ( "}" ) , pushblockcontext , block , poplex , popcontext ) ; if ( type == ";" ) return cont ( ) ; if ( type == "if" ) { if ( cx . state . lexical . info == "else" && cx . state . cc [ cx . state . cc . length - 1 ] == poplex ) cx . state . cc . pop ( ) ( ) ; return cont ( pushlex ( "form" ) , parenExpr , statement , poplex , maybeelse ) ; } if ( type == "function" ) return cont ( functiondef ) ; if ( type == "for" ) return cont ( pushlex ( "form" ) , pushblockcontext , forspec , statement , popcontext , poplex ) ; if ( type == "class" || ( isTS && value == "interface" ) ) { cx . marked = "keyword" ; return cont ( pushlex ( "form" , type == "class" ? type : value ) , className , poplex ) ; } if ( type == "variable" ) { if ( isTS && value == "declare" ) { cx . marked = "keyword" ; return cont ( statement ) ; } else if ( isTS && ( value == "module" || value == "enum" || value == "type" ) && cx . stream . match ( /^\s*\w/ , false ) ) { cx . marked = "keyword" ; if ( value == "enum" ) return cont ( enumdef ) ; else if ( value == "type" ) return cont ( typename , expect ( "operator" ) , typeexpr , expect ( ";" ) ) ; else return cont ( pushlex ( "form" ) , pattern , expect ( "{" ) , pushlex ( "}" ) , block , poplex , poplex ) ; } else if ( isTS && value == "namespace" ) { cx . marked = "keyword" ; return cont ( pushlex ( "form" ) , expression , statement , poplex ) ; } else if ( isTS && value == "abstract" ) { cx . marked = "keyword" ; return cont ( statement ) ; } else { return cont ( pushlex ( "stat" ) , maybelabel ) ; } } if ( type == "switch" ) return cont ( pushlex ( "form" ) , parenExpr , expect ( "{" ) , pushlex ( "}" , "switch" ) , pushblockcontext , block , poplex , poplex , popcontext ) ; if ( type == "case" ) return cont ( expression , expect ( ":" ) ) ; if ( type == "default" ) return cont ( expect ( ":" ) ) ; if ( type == "catch" ) return cont ( pushlex ( "form" ) , pushcontext , maybeCatchBinding , statement , poplex , popcontext ) ; if ( type == "export" ) return cont ( pushlex ( "stat" ) , afterExport , poplex ) ; if ( type == "import" ) return cont ( pushlex ( "stat" ) , afterImport , poplex ) ; if ( type == "async" ) return cont ( statement ) ; if ( value == "@" ) return cont ( expression , statement ) ; return pass ( pushlex ( "stat" ) , expression , expect ( ";" ) , poplex ) ; } function maybeCatchBinding ( type ) { if ( type == "(" ) return cont ( funarg , expect ( ")" ) ) ; } function expression ( type , value ) { return expressionInner ( type , value , false ) ; } function expressionNoComma ( type , value ) { return expressionInner ( type , value , true ) ; } function parenExpr ( type ) { if ( type != "(" ) return pass ( ) ; return cont ( pushlex ( ")" ) , maybeexpression , expect ( ")" ) , poplex ) ; } function expressionInner ( type , value , noComma ) { if ( cx . state . fatArrowAt == cx . stream . start ) { var body = noComma ? arrowBodyNoComma : arrowBody ; if ( type == "(" ) return cont ( pushcontext , pushlex ( ")" ) , commasep ( funarg , ")" ) , poplex , expect ( "=>" ) , body , popcontext ) ; else if ( type == "variable" ) return pass ( pushcontext , pattern , expect ( "=>" ) , body , popcontext ) ; } var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma ; if ( atomicTypes . hasOwnProperty ( type ) ) return cont ( maybeop ) ; if ( type == "function" ) return cont ( functiondef , maybeop ) ; if ( type == "class" || ( isTS && value == "interface" ) ) { cx . marked = "keyword" ; return cont ( pushlex ( "form" ) , classExpression , poplex ) ; } if ( type == "keyword c" || type == "async" ) return cont ( noComma ? expressionNoComma : expression ) ; if ( type == "(" ) return cont ( pushlex ( ")" ) , maybeexpression , expect ( ")" ) , poplex , maybeop ) ; if ( type == "operator" || type == "spread" ) return cont ( noComma ? expressionNoComma : expression ) ; if ( type == "[" ) return cont ( pushlex ( "]" ) , arrayLiteral , poplex , maybeop ) ; if ( type == "{" ) return contCommasep ( objprop , "}" , null , maybeop ) ; if ( type == "quasi" ) return pass ( quasi , maybeop ) ; if ( type == "new" ) return cont ( maybeTarget ( noComma ) ) ; return cont ( ) ; } function maybeexpression ( type ) { if ( type . match ( /[;\}\)\],]/ ) ) return pass ( ) ; return pass ( expression ) ; } function maybeoperatorComma ( type , value ) { if ( type == "," ) return cont ( maybeexpression ) ; return maybeoperatorNoComma ( type , value , false ) ; } function maybeoperatorNoComma ( type , value , noComma ) { var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma ; var expr = noComma == false ? expression : expressionNoComma ; if ( type == "=>" ) return cont ( pushcontext , noComma ? arrowBodyNoComma : arrowBody , popcontext ) ; if ( type == "operator" ) { if ( /\+\+|--/ . test ( value ) || ( isTS && value == "!" ) ) return cont ( me ) ; if ( isTS && value == "<" && cx . stream . match ( /^([^<>]|<[^<>]*>)*>\s*\(/ , false ) ) return cont ( pushlex ( ">" ) , commasep ( typeexpr , ">" ) , poplex , me ) ; if ( value == "?" ) return cont ( expression , expect ( ":" ) , expr ) ; return cont ( expr ) ; } if ( type == "quasi" ) { return pass ( quasi , me ) ; } if ( type == ";" ) return ; if ( type == "(" ) return contCommasep ( expressionNoComma , ")" , "call" , me ) ; if ( type == "." ) return cont ( property , me ) ; if ( type == "[" ) return cont ( pushlex ( "]" ) , maybeexpression , expect ( "]" ) , poplex , me ) ; if ( isTS && value == "as" ) { cx . marked = "keyword" ; return cont ( typeexpr , me ) ; } if ( type == "regexp" ) { cx . state . lastType = cx . marked = "operator" ; cx . stream . backUp ( cx . stream . pos - cx . stream . start - 1 ) ; return cont ( expr ) ; } } function quasi ( type , value ) { if ( type != "quasi" ) return pass ( ) ; if ( value . slice ( value . length - 2 ) != "${" ) return cont ( quasi ) ; return cont ( maybeexpression , continueQuasi ) ; } function continueQuasi ( type ) { if ( type == "}" ) { cx . marked = "string-2" ; cx . state . tokenize = tokenQuasi ; return cont ( quasi ) ; } } function arrowBody ( type ) { findFatArrow ( cx . stream , cx . state ) ; return pass ( type == "{" ? statement : expression ) ; } function arrowBodyNoComma ( type ) { findFatArrow ( cx . stream , cx . state ) ; return pass ( type == "{" ? statement : expressionNoComma ) ; } function maybeTarget ( noComma ) { return function ( type ) { if ( type == "." ) return cont ( noComma ? targetNoComma : target ) ; else if ( type == "variable" && isTS ) return cont ( maybeTypeArgs , noComma ? maybeoperatorNoComma : maybeoperatorComma ) ; else return pass ( noComma ? expressionNoComma : expression ) ; } ; } function target ( _ , value ) { if ( value == "target" ) { cx . marked = "keyword" ; return cont ( maybeoperatorComma ) ; } } function targetNoComma ( _ , value ) { if ( value == "target" ) { cx . marked = "keyword" ; return cont ( maybeoperatorNoComma ) ; } } 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 == "async" ) { cx . marked = "property" ; return cont ( objprop ) ; } else if ( type == "variable" || cx . style == "keyword" ) { cx . marked = "property" ; if ( value == "get" || value == "set" ) return cont ( getterSetter ) ; var m ; if ( isTS && cx . state . fatArrowAt == cx . stream . start && ( m = cx . stream . match ( /^\s*:\s*/ , false ) ) ) cx . state . fatArrowAt = cx . stream . pos + m [ 0 ] . length ; return cont ( afterprop ) ; } else if ( type == "number" || type == "string" ) { cx . marked = jsonldMode ? "property" : cx . style + " property" ; return cont ( afterprop ) ; } else if ( type == "jsonld-keyword" ) { return cont ( afterprop ) ; } else if ( isTS && isModifier ( value ) ) { cx . marked = "keyword" ; return cont ( objprop ) ; } else if ( type == "[" ) { return cont ( expression , maybetype , expect ( "]" ) , afterprop ) ; } else if ( type == "spread" ) { return cont ( expressionNoComma , afterprop ) ; } else if ( value == "*" ) { cx . marked = "keyword" ; return cont ( objprop ) ; } else if ( type == ":" ) { return pass ( afterprop ) ; } } function getterSetter ( type ) { if ( type != "variable" ) return pass ( afterprop ) ; cx . marked = "property" ; return cont ( functiondef ) ; } function afterprop ( type ) { if ( type == ":" ) return cont ( expressionNoComma ) ; if ( type == "(" ) return pass ( functiondef ) ; } function commasep ( what , end , sep ) { function proceed ( type , value ) { if ( sep ? sep . indexOf ( type ) > - 1 : type == "," ) { var lex = cx . state . lexical ; if ( lex . info == "call" ) lex . pos = ( lex . pos || 0 ) + 1 ; return cont ( function ( type , value ) { if ( type == end || value == end ) return pass ( ) ; return pass ( what ) ; } , proceed ) ; } if ( type == end || value == end ) return cont ( ) ; if ( sep && sep . indexOf ( ";" ) > - 1 ) return pass ( what ) ; return cont ( expect ( end ) ) ; } return function ( type , value ) { if ( type == end || value == end ) return cont ( ) ; return pass ( what , proceed ) ; } ; } function contCommasep ( what , end , info ) { for ( var i = 3 ; i < arguments . length ; i ++ ) cx . cc . push ( arguments [ i ] ) ; return cont ( pushlex ( end , info ) , commasep ( what , end ) , poplex ) ; } function block ( type ) { if ( type == "}" ) return cont ( ) ; return pass ( statement , block ) ; } function maybetype ( type , value ) { if ( isTS ) { if ( type == ":" ) return cont ( typeexpr ) ; if ( value == "?" ) return cont ( maybetype ) ; } } function maybetypeOrIn ( type , value ) { if ( isTS && ( type == ":" || value == "in" ) ) return cont ( typeexpr ) ; } function mayberettype ( type ) { if ( isTS && type == ":" ) { if ( cx . stream . match ( /^\s*\w+\s+is\b/ , false ) ) return cont ( expression , isKW , typeexpr ) ; else return cont ( typeexpr ) ; } } function isKW ( _ , value ) { if ( value == "is" ) { cx . marked = "keyword" ; return cont ( ) ; } } function typeexpr ( type , value ) { if ( value == "keyof" || value == "typeof" || value == "infer" || value == "readonly" ) { cx . marked = "keyword" ; return cont ( value == "typeof" ? expressionNoComma : typeexpr ) ; } if ( type == "variable" || value == "void" ) { cx . marked = "type" ; return cont ( afterType ) ; } if ( value == "|" || value == "&" ) return cont ( typeexpr ) ; if ( type == "string" || type == "number" || type == "atom" ) return cont ( afterType ) ; if ( type == "[" ) return cont ( pushlex ( "]" ) , commasep ( typeexpr , "]" , "," ) , poplex , afterType ) ; if ( type == "{" ) return cont ( pushlex ( "}" ) , typeprops , poplex , afterType ) ; if ( type == "(" ) return cont ( commasep ( typearg , ")" ) , maybeReturnType , afterType ) ; if ( type == "<" ) return cont ( commasep ( typeexpr , ">" ) , typeexpr ) ; if ( type == "quasi" ) { return pass ( quasiType , afterType ) ; } } function maybeReturnType ( type ) { if ( type == "=>" ) return cont ( typeexpr ) ; } function typeprops ( type ) { if ( type . match ( /[\}\)\]]/ ) ) return cont ( ) ; if ( type == "," || type == ";" ) return cont ( typeprops ) ; return pass ( typeprop , typeprops ) ; } function typeprop ( type , value ) { if ( type == "variable" || cx . style == "keyword" ) { cx . marked = "property" ; return cont ( typeprop ) ; } else if ( value == "?" || type == "number" || type == "string" ) { return cont ( typeprop ) ; } else if ( type == ":" ) { return cont ( typeexpr ) ; } else if ( type == "[" ) { return cont ( expect ( "variable" ) , maybetypeOrIn , expect ( "]" ) , typeprop ) ; } else if ( type == "(" ) { return pass ( functiondecl , typeprop ) ; } else if ( ! type . match ( /[;\}\)\],]/ ) ) { return cont ( ) ; } } function quasiType ( type , value ) { if ( type != "quasi" ) return pass ( ) ; if ( value . slice ( value . length - 2 ) != "${" ) return cont ( quasiType ) ; return cont ( typeexpr , continueQuasiType ) ; } function continueQuasiType ( type ) { if ( type == "}" ) { cx . marked = "string-2" ; cx . state . tokenize = tokenQuasi ; return cont ( quasiType ) ; } } function typearg ( type , value ) { if ( ( type == "variable" && cx . stream . match ( /^\s*[?:]/ , false ) ) || value == "?" ) return cont ( typearg ) ; if ( type == ":" ) return cont ( typeexpr ) ; if ( type == "spread" ) return cont ( typearg ) ; return pass ( typeexpr ) ; } function afterType ( type , value ) { if ( value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeexpr , ">" ) , poplex , afterType ) ; if ( value == "|" || type == "." || value == "&" ) return cont ( typeexpr ) ; if ( type == "[" ) return cont ( typeexpr , expect ( "]" ) , afterType ) ; if ( value == "extends" || value == "implements" ) { cx . marked = "keyword" ; return cont ( typeexpr ) ; } if ( value == "?" ) return cont ( typeexpr , expect ( ":" ) , typeexpr ) ; } function maybeTypeArgs ( _ , value ) { if ( value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeexpr , ">" ) , poplex , afterType ) ; } function typeparam ( ) { return pass ( typeexpr , maybeTypeDefault ) ; } function maybeTypeDefault ( _ , value ) { if ( value == "=" ) return cont ( typeexpr ) ; } function vardef ( _ , value ) { if ( value == "enum" ) { cx . marked = "keyword" ; return cont ( enumdef ) ; } return pass ( pattern , maybetype , maybeAssign , vardefCont ) ; } function pattern ( type , value ) { if ( isTS && isModifier ( value ) ) { cx . marked = "keyword" ; return cont ( pattern ) ; } if ( type == "variable" ) { register ( value ) ; return cont ( ) ; } if ( type == "spread" ) return cont ( pattern ) ; if ( type == "[" ) return contCommasep ( eltpattern , "]" ) ; if ( type == "{" ) return contCommasep ( proppattern , "}" ) ; } function proppattern ( type , value ) { if ( type == "variable" && ! cx . stream . match ( /^\s*:/ , false ) ) { register ( value ) ; return cont ( maybeAssign ) ; } if ( type == "variable" ) cx . marked = "property" ; if ( type == "spread" ) return cont ( pattern ) ; if ( type == "}" ) return pass ( ) ; if ( type == "[" ) return cont ( expression , expect ( "]" ) , expect ( ":" ) , proppattern ) ; return cont ( expect ( ":" ) , pattern , maybeAssign ) ; } function eltpattern ( ) { return pass ( pattern , maybeAssign ) ; } function maybeAssign ( _type , value ) { if ( value == "=" ) return cont ( expressionNoComma ) ; } function vardefCont ( type ) { if ( type == "," ) return cont ( vardef ) ; } function maybeelse ( type , value ) { if ( type == "keyword b" && value == "else" ) return cont ( pushlex ( "form" , "else" ) , statement , poplex ) ; } function forspec ( type , value ) { if ( value == "await" ) return cont ( forspec ) ; if ( type == "(" ) return cont ( pushlex ( ")" ) , forspec1 , poplex ) ; } function forspec1 ( type ) { if ( type == "var" ) return cont ( vardef , forspec2 ) ; if ( type == "variable" ) return cont ( forspec2 ) ; return pass ( forspec2 ) ; } function forspec2 ( type , value ) { if ( type == ")" ) return cont ( ) ; if ( type == ";" ) return cont ( forspec2 ) ; if ( value == "in" || value == "of" ) { cx . marked = "keyword" ; return cont ( expression , forspec2 ) ; } return pass ( expression , forspec2 ) ; } function functiondef ( type , value ) { if ( value == "*" ) { cx . marked = "keyword" ; return cont ( functiondef ) ; } if ( type == "variable" ) { register ( value ) ; return cont ( functiondef ) ; } if ( type == "(" ) return cont ( pushcontext , pushlex ( ")" ) , commasep ( funarg , ")" ) , poplex , mayberettype , statement , popcontext ) ; if ( isTS && value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex , functiondef ) ; } function functiondecl ( type , value ) { if ( value == "*" ) { cx . marked = "keyword" ; return cont ( functiondecl ) ; } if ( type == "variable" ) { register ( value ) ; return cont ( functiondecl ) ; } if ( type == "(" ) return cont ( pushcontext , pushlex ( ")" ) , commasep ( funarg , ")" ) , poplex , mayberettype , popcontext ) ; if ( isTS && value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex , functiondecl ) ; } function typename ( type , value ) { if ( type == "keyword" || type == "variable" ) { cx . marked = "type" ; return cont ( typename ) ; } else if ( value == "<" ) { return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex ) ; } } function funarg ( type , value ) { if ( value == "@" ) cont ( expression , funarg ) ; if ( type == "spread" ) return cont ( funarg ) ; if ( isTS && isModifier ( value ) ) { cx . marked = "keyword" ; return cont ( funarg ) ; } if ( isTS && type == "this" ) return cont ( maybetype , maybeAssign ) ; return pass ( pattern , maybetype , maybeAssign ) ; } function classExpression ( type , value ) { if ( type == "variable" ) return className ( type , value ) ; return classNameAfter ( type , value ) ; } function className ( type , value ) { if ( type == "variable" ) { register ( value ) ; return cont ( classNameAfter ) ; } } function classNameAfter ( type , value ) { if ( value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex , classNameAfter ) ; if ( value == "extends" || value == "implements" || ( isTS && type == "," ) ) { if ( value == "implements" ) cx . marked = "keyword" ; return cont ( isTS ? typeexpr : expression , classNameAfter ) ; } if ( type == "{" ) return cont ( pushlex ( "}" ) , classBody , poplex ) ; } function classBody ( type , value ) { if ( type == "async" || ( type == "variable" && ( value == "static" || value == "get" || value == "set" || ( isTS && isModifier ( value ) ) ) && cx . stream . match ( /^\s+[\w$\xa1-\uffff]/ , false ) ) ) { cx . marked = "keyword" ; return cont ( classBody ) ; } if ( type == "variable" || cx . style == "keyword" ) { cx . marked = "property" ; return cont ( classfield , classBody ) ; } if ( type == "number" || type == "string" ) return cont ( classfield , classBody ) ; if ( type == "[" ) return cont ( expression , maybetype , expect ( "]" ) , classfield , classBody ) ; if ( value == "*" ) { cx . marked = "keyword" ; return cont ( classBody ) ; } if ( isTS && type == "(" ) return pass ( functiondecl , classBody ) ; if ( type == ";" || type == "," ) return cont ( classBody ) ; if ( type == "}" ) return cont ( ) ; if ( value == "@" ) return cont ( expression , classBody ) ; } function classfield ( type , value ) { if ( value == "!" ) return cont ( classfield ) ; if ( value == "?" ) return cont ( classfield ) ; if ( type == ":" ) return cont ( typeexpr , maybeAssign ) ; if ( value == "=" ) return cont ( expressionNoComma ) ; var context = cx . state . lexical . prev , isInterface = context && context . info == "interface" ; return pass ( isInterface ? functiondecl : functiondef ) ; } function afterExport ( type , value ) { if ( value == "*" ) { cx . marked = "keyword" ; return cont ( maybeFrom , expect ( ";" ) ) ; } if ( value == "default" ) { cx . marked = "keyword" ; return cont ( expression , expect ( ";" ) ) ; } if ( type == "{" ) return cont ( commasep ( exportField , "}" ) , maybeFrom , expect ( ";" ) ) ; return pass ( statement ) ; } function exportField ( type , value ) { if ( value == "as" ) { cx . marked = "keyword" ; return cont ( expect ( "variable" ) ) ; } if ( type == "variable" ) return pass ( expressionNoComma , exportField ) ; } function afterImport ( type ) { if ( type == "string" ) return cont ( ) ; if ( type == "(" ) return pass ( expression ) ; if ( type == "." ) return pass ( maybeoperatorComma ) ; return pass ( importSpec , maybeMoreImports , maybeFrom ) ; } function importSpec ( type , value ) { if ( type == "{" ) return contCommasep ( importSpec , "}" ) ; if ( type == "variable" ) register ( value ) ; if ( value == "*" ) cx . marked = "keyword" ; return cont ( maybeAs ) ; } function maybeMoreImports ( type ) { if ( type == "," ) return cont ( importSpec , maybeMoreImports ) ; } function maybeAs ( _type , value ) { if ( value == "as" ) { cx . marked = "keyword" ; return cont ( importSpec ) ; } } function maybeFrom ( _type , value ) { if ( value == "from" ) { cx . marked = "keyword" ; return cont ( expression ) ; } } function arrayLiteral ( type ) { if ( type == "]" ) return cont ( ) ; return pass ( commasep ( expressionNoComma , "]" ) ) ; } function enumdef ( ) { return pass ( pushlex ( "form" ) , pattern , expect ( "{" ) , pushlex ( "}" ) , commasep ( enummember , "}" ) , poplex , poplex ) ; } function enummember ( ) { return pass ( pattern , maybeAssign ) ; } function isContinuedStatement ( state , textAfter ) { return ( state . lastType == "operator" || state . lastType == "," || isOperatorChar . test ( textAfter . charAt ( 0 ) ) || /[,.]/ . test ( textAfter . charAt ( 0 ) ) ) ; } function expressionAllowed ( stream , state , backUp ) { return ( ( state . tokenize == tokenBase && /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/ . test ( state . lastType ) ) || ( state . lastType == "quasi" && /\{\s*$/ . test ( stream . string . slice ( 0 , stream . pos - ( backUp || 0 ) ) ) ) ) ; } return { startState : function ( basecolumn ) { var state = { tokenize : tokenBase , lastType : "sof" , cc : [ ] , lexical : new JSLexical ( ( basecolumn || 0 ) - indentUnit , 0 , "block" , false ) , localVars : parserConfig . localVars , context : parserConfig . localVars && new Context ( null , null , false ) , indented : basecolumn || 0 , } ; if ( parserConfig . globalVars && typeof parserConfig . globalVars == "object" ) state . globalVars = parserConfig . globalVars ; return state ; } , token : function ( stream , state ) { if ( stream . sol ( ) ) { if ( ! state . lexical . hasOwnProperty ( "align" ) ) state . lexical . align = false ; state . indented = stream . indentation ( ) ; findFatArrow ( stream , state ) ; } if ( state . tokenize != tokenComment && 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 == tokenComment || state . tokenize == tokenQuasi ) return CodeMirror . Pass ; if ( state . tokenize != tokenBase ) return 0 ; var firstChar = textAfter && textAfter . charAt ( 0 ) , lexical = state . lexical , top ; if ( ! /^\s*else\b/ . test ( textAfter ) ) 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 && c != popcontext ) break ; } while ( ( lexical . type == "stat" || lexical . type == "form" ) && ( firstChar == "}" || ( ( top = state . cc [ state . cc . length - 1 ] ) && ( top == maybeoperatorComma || top == maybeoperatorNoComma ) && ! /^[,\.=+\-*:?[\(]/ . test ( textAfter ) ) ) ) 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 == "," ? lexical . info . length + 1 : 0 ) ) ; else if ( type == "form" && firstChar == "{" ) return lexical . indented ; else if ( type == "form" ) return lexical . indented + indentUnit ; else if ( type == "stat" ) return ( lexical . indented + ( isContinuedStatement ( state , textAfter ) ? 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 ) ; } , electricInput : /^\s*(?:case .*?:|default:|\{|\})$/ , blockCommentStart : jsonMode ? null : "/*" , blockCommentEnd : jsonMode ? null : "*/" , blockCommentContinue : jsonMode ? null : " * " , lineComment : jsonMode ? null : "//" , fold : "brace" , closeBrackets : "()[]{}''\"\"``" , helperType : jsonMode ? "json" : "javascript" , jsonldMode : jsonldMode , jsonMode : jsonMode , expressionAllowed : expressionAllowed , skipExpression : function ( state ) { parseJS ( state , "atom" , "atom" , "true" , new CodeMirror . StringStream ( "" , 2 , null ) ) ; } , } ; } ) ; CodeMirror . registerHelper ( "wordChars" , "javascript" , /[\w$]/ ) ; CodeMirror . defineMIME ( "text/javascript" , "javascript" ) ; CodeMirror . defineMIME ( "text/ecmascript" , "javascript" ) ; CodeMirror . defineMIME ( "application/javascript" , "javascript" ) ; CodeMirror . defineMIME ( "application/x-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 ( "application/manifest+json" , { name : "javascript" , json : true , } ) ; CodeMirror . defineMIME ( "application/ld+json" , { name : "javascript" , jsonld : true , } ) ; CodeMirror . defineMIME ( "text/typescript" , { name : "javascript" , typescript : true , } ) ; CodeMirror . defineMIME ( "application/typescript" , { name : "javascript" , typescript : true , } ) ; } ) ;