diff --git a/js/chunks/JavaScript.tmLanguage-5b3aef1e.js b/js/chunks/JavaScript.tmLanguage-5b3aef1e.js new file mode 100644 index 0000000..276fdf8 --- /dev/null +++ b/js/chunks/JavaScript.tmLanguage-5b3aef1e.js @@ -0,0 +1,5888 @@ +const information_for_contributors = [ + "This file has been converted from https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage", + "If you want to provide a fix or improvement, please create a pull request against the original repository.", + "Once accepted there, we are happy to receive an update request." +]; +const version = "https://github.com/microsoft/TypeScript-TmLanguage/commit/56b7270f094b036256774702e3b7f96490981190"; +const name = "JavaScript (with React support)"; +const scopeName = "source.js"; +const patterns = [ + { + include: "#directives" + }, + { + include: "#statements" + }, + { + include: "#shebang" + } +]; +const repository = { + shebang: { + name: "comment.line.shebang.js", + match: "\\A(#!).*(?=$)", + captures: { + "1": { + name: "punctuation.definition.comment.js" + } + } + }, + statements: { + patterns: [ + { + include: "#declaration" + }, + { + include: "#control-statement" + }, + { + include: "#after-operator-block-as-object-literal" + }, + { + include: "#decl-block" + }, + { + include: "#label" + }, + { + include: "#expression" + }, + { + include: "#punctuation-semicolon" + }, + { + include: "#string" + }, + { + include: "#comment" + } + ] + }, + declaration: { + patterns: [ + { + include: "#decorator" + }, + { + include: "#var-expr" + }, + { + include: "#function-declaration" + }, + { + include: "#class-declaration" + }, + { + include: "#interface-declaration" + }, + { + include: "#enum-declaration" + }, + { + include: "#namespace-declaration" + }, + { + include: "#type-alias-declaration" + }, + { + include: "#import-equals-declaration" + }, + { + include: "#import-declaration" + }, + { + include: "#export-declaration" + }, + { + name: "storage.modifier.js", + match: "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + beginCaptures: { + "1": { + name: "meta.definition.variable.js entity.name.function.js" + }, + "2": { + name: "keyword.operator.definiteassignment.js" + } + }, + end: "(?=$|^|[;,=}]|((?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + beginCaptures: { + "1": { + name: "meta.definition.variable.js variable.other.constant.js entity.name.function.js" + } + }, + end: "(?=$|^|[;,=}]|((?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "1": { + name: "storage.modifier.js" + }, + "2": { + name: "keyword.operator.rest.js" + }, + "3": { + name: "entity.name.function.js variable.language.this.js" + }, + "4": { + name: "entity.name.function.js" + }, + "5": { + name: "keyword.operator.optional.js" + } + } + }, + { + match: "(?x)(?:(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "1": { + name: "meta.definition.property.js entity.name.function.js" + }, + "2": { + name: "keyword.operator.optional.js" + }, + "3": { + name: "keyword.operator.definiteassignment.js" + } + } + }, + { + name: "meta.definition.property.js variable.object.property.js", + match: "\\#?[_$[:alpha:]][_$[:alnum:]]*" + }, + { + name: "keyword.operator.optional.js", + match: "\\?" + }, + { + name: "keyword.operator.definiteassignment.js", + match: "\\!" + } + ] + }, + "variable-initializer": { + patterns: [ + { + begin: "(?\\s*$)", + beginCaptures: { + "1": { + name: "keyword.operator.assignment.js" + } + }, + end: "(?=$|^|[,);}\\]]|((?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.js" + }, + "2": { + name: "storage.modifier.js" + }, + "3": { + name: "storage.modifier.js" + }, + "4": { + name: "storage.modifier.async.js" + }, + "5": { + name: "keyword.operator.new.js" + }, + "6": { + name: "keyword.generator.asterisk.js" + } + }, + end: "(?=\\}|;|,|$)|(?<=\\})", + patterns: [ + { + include: "#method-declaration-name" + }, + { + include: "#function-body" + } + ] + }, + { + name: "meta.method.declaration.js", + begin: "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.js" + }, + "2": { + name: "storage.modifier.js" + }, + "3": { + name: "storage.modifier.js" + }, + "4": { + name: "storage.modifier.async.js" + }, + "5": { + name: "storage.type.property.js" + }, + "6": { + name: "keyword.generator.asterisk.js" + } + }, + end: "(?=\\}|;|,|$)|(?<=\\})", + patterns: [ + { + include: "#method-declaration-name" + }, + { + include: "#function-body" + } + ] + } + ] + }, + "object-literal-method-declaration": { + name: "meta.method.declaration.js", + begin: "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + }, + "2": { + name: "storage.type.property.js" + }, + "3": { + name: "keyword.generator.asterisk.js" + } + }, + end: "(?=\\}|;|,)|(?<=\\})", + patterns: [ + { + include: "#method-declaration-name" + }, + { + include: "#function-body" + }, + { + begin: "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + }, + "2": { + name: "storage.type.property.js" + }, + "3": { + name: "keyword.generator.asterisk.js" + } + }, + end: "(?=\\(|\\<)", + patterns: [ + { + include: "#method-declaration-name" + } + ] + } + ] + }, + "method-declaration-name": { + begin: "(?x)(?=((\\b(?)", + captures: { + "1": { + name: "storage.modifier.async.js" + }, + "2": { + name: "variable.parameter.js" + } + } + }, + { + name: "meta.arrow.js", + begin: "(?x) (?:\n (? is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + } + }, + end: "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + patterns: [ + { + include: "#comment" + }, + { + include: "#type-parameters" + }, + { + include: "#function-parameters" + }, + { + include: "#arrow-return-type" + }, + { + include: "#possibly-arrow-return-type" + } + ] + }, + { + name: "meta.arrow.js", + begin: "=>", + beginCaptures: { + "0": { + name: "storage.type.function.arrow.js" + } + }, + end: "((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])", + patterns: [ + { + include: "#single-line-comment-consuming-line-ending" + }, + { + include: "#decl-block" + }, + { + include: "#expression" + } + ] + } + ] + }, + "indexer-declaration": { + name: "meta.indexer.declaration.js", + begin: "(?:(?]|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^yield|[^\\._$[:alnum:]]yield|^throw|[^\\._$[:alnum:]]throw|^in|[^\\._$[:alnum:]]in|^of|[^\\._$[:alnum:]]of|^typeof|[^\\._$[:alnum:]]typeof|&&|\\|\\||\\*)\\s*(\\{)", + beginCaptures: { + "1": { + name: "punctuation.definition.block.js" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.block.js" + } + }, + patterns: [ + { + include: "#object-member" + } + ] + }, + "object-literal": { + name: "meta.objectliteral.js", + begin: "\\{", + beginCaptures: { + "0": { + name: "punctuation.definition.block.js" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.block.js" + } + }, + patterns: [ + { + include: "#object-member" + } + ] + }, + "object-member": { + patterns: [ + { + include: "#comment" + }, + { + include: "#object-literal-method-declaration" + }, + { + name: "meta.object.member.js meta.object-literal.key.js", + begin: "(?=\\[)", + end: "(?=:)|((?<=[\\]])(?=\\s*[\\(\\<]))", + patterns: [ + { + include: "#comment" + }, + { + include: "#array-literal" + } + ] + }, + { + name: "meta.object.member.js meta.object-literal.key.js", + begin: "(?=[\\'\\\"\\`])", + end: "(?=:)|((?<=[\\'\\\"\\`])(?=((\\s*[\\(\\<,}])|(\\s+(as)\\s+))))", + patterns: [ + { + include: "#comment" + }, + { + include: "#string" + } + ] + }, + { + name: "meta.object.member.js meta.object-literal.key.js", + begin: "(?x)(?=(\\b(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "0": { + name: "meta.object-literal.key.js" + }, + "1": { + name: "entity.name.function.js" + } + } + }, + { + name: "meta.object.member.js", + match: "(?:[_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*:)", + captures: { + "0": { + name: "meta.object-literal.key.js" + } + } + }, + { + name: "meta.object.member.js", + begin: "\\.\\.\\.", + beginCaptures: { + "0": { + name: "keyword.operator.spread.js" + } + }, + end: "(?=,|\\})", + patterns: [ + { + include: "#expression" + } + ] + }, + { + name: "meta.object.member.js", + match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=,|\\}|$|\\/\\/|\\/\\*)", + captures: { + "1": { + name: "variable.other.readwrite.js" + } + } + }, + { + name: "meta.object.member.js", + match: "(?]|\\|\\||\\&\\&|\\!\\=\\=|$|^|((?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)\\(\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + } + }, + end: "(?<=\\))", + patterns: [ + { + include: "#type-parameters" + }, + { + begin: "\\(", + beginCaptures: { + "0": { + name: "meta.brace.round.js" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.js" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + { + begin: "(?<=:)\\s*(async)?\\s*(\\()(?=\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + }, + "2": { + name: "meta.brace.round.js" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.js" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + begin: "(?<=:)\\s*(async)?\\s*(?=\\<\\s*$)", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + } + }, + end: "(?<=\\>)", + patterns: [ + { + include: "#type-parameters" + } + ] + }, + { + begin: "(?<=\\>)\\s*(\\()(?=\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "meta.brace.round.js" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.js" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + include: "#possibly-arrow-return-type" + }, + { + include: "#expression" + } + ] + }, + { + include: "#punctuation-comma" + } + ] + }, + "ternary-expression": { + begin: "(?!\\?\\.\\s*[^[:digit:]])(\\?)(?!\\?)", + beginCaptures: { + "1": { + name: "keyword.operator.ternary.js" + } + }, + end: "\\s*(:)", + endCaptures: { + "1": { + name: "keyword.operator.ternary.js" + } + }, + patterns: [ + { + include: "#expression" + } + ] + }, + "function-call": { + patterns: [ + { + begin: "(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())", + end: "(?<=\\))(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())", + patterns: [ + { + name: "meta.function-call.js", + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))", + end: "(?=\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())", + patterns: [ + { + include: "#function-call-target" + } + ] + }, + { + include: "#comment" + }, + { + include: "#function-call-optionals" + }, + { + include: "#type-arguments" + }, + { + include: "#paren-expression" + } + ] + }, + { + begin: "(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))(<\\s*[\\{\\[\\(]\\s*$))", + end: "(?<=\\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))(<\\s*[\\{\\[\\(]\\s*$))", + patterns: [ + { + name: "meta.function-call.js", + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))", + end: "(?=(<\\s*[\\{\\[\\(]\\s*$))", + patterns: [ + { + include: "#function-call-target" + } + ] + }, + { + include: "#comment" + }, + { + include: "#function-call-optionals" + }, + { + include: "#type-arguments" + } + ] + } + ] + }, + "function-call-target": { + patterns: [ + { + include: "#support-function-call-identifiers" + }, + { + name: "entity.name.function.js", + match: "(\\#?[_$[:alpha:]][_$[:alnum:]]*)" + } + ] + }, + "function-call-optionals": { + patterns: [ + { + name: "meta.function-call.js punctuation.accessor.optional.js", + match: "\\?\\." + }, + { + name: "meta.function-call.js keyword.operator.definiteassignment.js", + match: "\\!" + } + ] + }, + "support-function-call-identifiers": { + patterns: [ + { + include: "#literal" + }, + { + include: "#support-objects" + }, + { + include: "#object-identifiers" + }, + { + include: "#punctuation-accessor" + }, + { + name: "keyword.operator.expression.import.js", + match: "(?:(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|(([\\&\\~\\^\\|]\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s+instanceof(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))|((?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?\\(\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + } + }, + end: "(?<=\\))", + patterns: [ + { + include: "#paren-expression-possibly-arrow-with-typeparameters" + } + ] + }, + { + begin: "(?<=[(=,]|=>|^return|[^\\._$[:alnum:]]return)\\s*(async)?(?=\\s*((((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?\\()|(<))\\s*$)", + beginCaptures: { + "1": { + name: "storage.modifier.async.js" + } + }, + end: "(?<=\\))", + patterns: [ + { + include: "#paren-expression-possibly-arrow-with-typeparameters" + } + ] + }, + { + include: "#possibly-arrow-return-type" + } + ] + }, + "paren-expression-possibly-arrow-with-typeparameters": { + patterns: [ + { + include: "#type-parameters" + }, + { + begin: "\\(", + beginCaptures: { + "0": { + name: "meta.brace.round.js" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.js" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + "expression-inside-possibly-arrow-parens": { + patterns: [ + { + include: "#expressionWithoutIdentifiers" + }, + { + include: "#comment" + }, + { + include: "#string" + }, + { + include: "#decorator" + }, + { + include: "#destructuring-parameter" + }, + { + match: "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "1": { + name: "storage.modifier.js" + }, + "2": { + name: "keyword.operator.rest.js" + }, + "3": { + name: "entity.name.function.js variable.language.this.js" + }, + "4": { + name: "entity.name.function.js" + }, + "5": { + name: "keyword.operator.optional.js" + } + } + }, + { + match: "(?x)(?:(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?>=|>>>=|\\|=" + }, + { + name: "keyword.operator.bitwise.shift.js", + match: "<<|>>>|>>" + }, + { + name: "keyword.operator.comparison.js", + match: "===|!==|==|!=" + }, + { + name: "keyword.operator.relational.js", + match: "<=|>=|<>|<|>" + }, + { + match: "(?<=[_$[:alnum:]])(\\!)\\s*(?:(/=)|(?:(/)(?![/*])))", + captures: { + "1": { + name: "keyword.operator.logical.js" + }, + "2": { + name: "keyword.operator.assignment.compound.js" + }, + "3": { + name: "keyword.operator.arithmetic.js" + } + } + }, + { + name: "keyword.operator.logical.js", + match: "\\!|&&|\\|\\||\\?\\?" + }, + { + name: "keyword.operator.bitwise.js", + match: "\\&|~|\\^|\\|" + }, + { + name: "keyword.operator.assignment.js", + match: "\\=" + }, + { + name: "keyword.operator.decrement.js", + match: "--" + }, + { + name: "keyword.operator.increment.js", + match: "\\+\\+" + }, + { + name: "keyword.operator.arithmetic.js", + match: "%|\\*|/|-|\\+" + }, + { + begin: "(?<=[_$[:alnum:])\\]])\\s*(?=(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)+(?:(/=)|(?:(/)(?![/*]))))", + end: "(?:(/=)|(?:(/)(?!\\*([^\\*]|(\\*[^\\/]))*\\*\\/)))", + endCaptures: { + "1": { + name: "keyword.operator.assignment.compound.js" + }, + "2": { + name: "keyword.operator.arithmetic.js" + } + }, + patterns: [ + { + include: "#comment" + } + ] + }, + { + match: "(?<=[_$[:alnum:])\\]])\\s*(?:(/=)|(?:(/)(?![/*])))", + captures: { + "1": { + name: "keyword.operator.assignment.compound.js" + }, + "2": { + name: "keyword.operator.arithmetic.js" + } + } + } + ] + }, + "typeof-operator": { + begin: "(?:&|{\\?]|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", + patterns: [ + { + include: "#expression" + } + ] + }, + literal: { + patterns: [ + { + include: "#numeric-literal" + }, + { + include: "#boolean-literal" + }, + { + include: "#null-literal" + }, + { + include: "#undefined-literal" + }, + { + include: "#numericConstant-literal" + }, + { + include: "#array-literal" + }, + { + include: "#this-literal" + }, + { + include: "#super-literal" + } + ] + }, + "array-literal": { + name: "meta.array.literal.js", + begin: "\\s*(\\[)", + beginCaptures: { + "1": { + name: "meta.brace.square.js" + } + }, + end: "\\]", + endCaptures: { + "0": { + name: "meta.brace.square.js" + } + }, + patterns: [ + { + include: "#expression" + }, + { + include: "#punctuation-comma" + } + ] + }, + "numeric-literal": { + patterns: [ + { + name: "constant.numeric.hex.js", + match: "\\b(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\\())\n |\n (?:(EPSILON|MAX_SAFE_INTEGER|MAX_VALUE|MIN_SAFE_INTEGER|MIN_VALUE|NEGATIVE_INFINITY|POSITIVE_INFINITY)\\b(?!\\$)))", + captures: { + "1": { + name: "punctuation.accessor.js" + }, + "2": { + name: "punctuation.accessor.optional.js" + }, + "3": { + name: "support.variable.property.js" + }, + "4": { + name: "support.constant.js" + } + } + }, + { + match: "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", + captures: { + "1": { + name: "punctuation.accessor.js" + }, + "2": { + name: "punctuation.accessor.optional.js" + }, + "3": { + name: "entity.name.function.js" + } + } + }, + { + match: "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])", + captures: { + "1": { + name: "punctuation.accessor.js" + }, + "2": { + name: "punctuation.accessor.optional.js" + }, + "3": { + name: "variable.other.constant.property.js" + } + } + }, + { + match: "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*)", + captures: { + "1": { + name: "punctuation.accessor.js" + }, + "2": { + name: "punctuation.accessor.optional.js" + }, + "3": { + name: "variable.other.property.js" + } + } + }, + { + name: "variable.other.constant.js", + match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + }, + { + name: "variable.other.readwrite.js", + match: "[_$[:alpha:]][_$[:alnum:]]*" + } + ] + }, + "object-identifiers": { + patterns: [ + { + name: "support.class.js", + match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\??\\.\\s*prototype\\b(?!\\$))" + }, + { + match: "(?x)(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(?:\n (\\#?[[:upper:]][_$[:digit:][:upper:]]*) |\n (\\#?[_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*)", + captures: { + "1": { + name: "punctuation.accessor.js" + }, + "2": { + name: "punctuation.accessor.optional.js" + }, + "3": { + name: "variable.other.constant.object.property.js" + }, + "4": { + name: "variable.other.object.property.js" + } + } + }, + { + match: "(?x)(?:\n ([[:upper:]][_$[:digit:][:upper:]]*) |\n ([_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*)", + captures: { + "1": { + name: "variable.other.constant.object.js" + }, + "2": { + name: "variable.other.object.js" + } + } + } + ] + }, + "type-annotation": { + patterns: [ + { + name: "meta.type.annotation.js", + begin: "(:)(?=\\s*\\S)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.js" + } + }, + end: "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + patterns: [ + { + include: "#type" + } + ] + }, + { + name: "meta.type.annotation.js", + begin: "(:)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.js" + } + }, + end: "(?])|(?=^\\s*$)|((?<=\\S)(?=\\s*$))|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + patterns: [ + { + include: "#type" + } + ] + } + ] + }, + "parameter-type-annotation": { + patterns: [ + { + name: "meta.type.annotation.js", + begin: "(:)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.js" + } + }, + end: "(?=[,)])|(?==[^>])", + patterns: [ + { + include: "#type" + } + ] + } + ] + }, + "return-type": { + patterns: [ + { + name: "meta.return.type.js", + begin: "(?<=\\))\\s*(:)(?=\\s*\\S)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.js" + } + }, + end: "(?|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + patterns: [ + { + include: "#arrow-return-type-body" + } + ] + }, + "possibly-arrow-return-type": { + begin: "(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)", + beginCaptures: { + "1": { + name: "meta.arrow.js meta.return.type.arrow.js keyword.operator.type.annotation.js" + } + }, + end: "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + contentName: "meta.arrow.js meta.return.type.arrow.js", + patterns: [ + { + include: "#arrow-return-type-body" + } + ] + }, + "arrow-return-type-body": { + patterns: [ + { + begin: "(?<=[:])(?=\\s*\\{)", + end: "(?<=\\})", + patterns: [ + { + include: "#type-object" + } + ] + }, + { + include: "#type-predicate-operator" + }, + { + include: "#type" + } + ] + }, + "type-parameters": { + name: "meta.type.parameters.js", + begin: "(<)", + beginCaptures: { + "1": { + name: "punctuation.definition.typeparameters.begin.js" + } + }, + end: "(>)", + endCaptures: { + "1": { + name: "punctuation.definition.typeparameters.end.js" + } + }, + patterns: [ + { + include: "#comment" + }, + { + name: "storage.modifier.js", + match: "(?)" + } + ] + }, + "type-arguments": { + name: "meta.type.parameters.js", + begin: "\\<", + beginCaptures: { + "0": { + name: "punctuation.definition.typeparameters.begin.js" + } + }, + end: "\\>", + endCaptures: { + "0": { + name: "punctuation.definition.typeparameters.end.js" + } + }, + patterns: [ + { + include: "#type-arguments-body" + } + ] + }, + "type-arguments-body": { + patterns: [ + { + match: "(?)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))))", + captures: { + "1": { + name: "storage.modifier.js" + }, + "2": { + name: "keyword.operator.rest.js" + }, + "3": { + name: "entity.name.function.js variable.language.this.js" + }, + "4": { + name: "entity.name.function.js" + }, + "5": { + name: "keyword.operator.optional.js" + } + } + }, + { + match: "(?x)(?:(?)", + patterns: [ + { + include: "#comment" + }, + { + include: "#type-parameters" + } + ] + }, + { + name: "meta.type.constructor.js", + begin: "(?)\n ))\n )\n )\n)", + end: "(?<=\\))", + patterns: [ + { + include: "#function-parameters" + } + ] + } + ] + }, + "type-function-return-type": { + patterns: [ + { + name: "meta.type.function.return.js", + begin: "(=>)(?=\\s*\\S)", + beginCaptures: { + "1": { + name: "storage.type.function.arrow.js" + } + }, + end: "(?)(?:\\?]|//|$)", + patterns: [ + { + include: "#type-function-return-type-core" + } + ] + }, + { + name: "meta.type.function.return.js", + begin: "=>", + beginCaptures: { + "0": { + name: "storage.type.function.arrow.js" + } + }, + end: "(?)(?]|//|^\\s*$)|((?<=\\S)(?=\\s*$)))", + patterns: [ + { + include: "#type-function-return-type-core" + } + ] + } + ] + }, + "type-function-return-type-core": { + patterns: [ + { + include: "#comment" + }, + { + begin: "(?<==>)(?=\\s*\\{)", + end: "(?<=\\})", + patterns: [ + { + include: "#type-object" + } + ] + }, + { + include: "#type-predicate-operator" + }, + { + include: "#type" + } + ] + }, + "type-operators": { + patterns: [ + { + include: "#typeof-operator" + }, + { + begin: "([&|])(?=\\s*\\{)", + beginCaptures: { + "0": { + name: "keyword.operator.type.js" + } + }, + end: "(?<=\\})", + patterns: [ + { + include: "#type-object" + } + ] + }, + { + begin: "[&|]", + beginCaptures: { + "0": { + name: "keyword.operator.type.js" + } + }, + end: "(?=\\S)" + }, + { + name: "keyword.operator.expression.keyof.js", + match: "(?)", + endCaptures: { + "1": { + name: "meta.type.parameters.js punctuation.definition.typeparameters.end.js" + } + }, + contentName: "meta.type.parameters.js", + patterns: [ + { + include: "#type-arguments-body" + } + ] + }, + { + begin: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(<)", + beginCaptures: { + "1": { + name: "entity.name.type.js" + }, + "2": { + name: "meta.type.parameters.js punctuation.definition.typeparameters.begin.js" + } + }, + end: "(>)", + endCaptures: { + "1": { + name: "meta.type.parameters.js punctuation.definition.typeparameters.end.js" + } + }, + contentName: "meta.type.parameters.js", + patterns: [ + { + include: "#type-arguments-body" + } + ] + }, + { + match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))", + captures: { + "1": { + name: "entity.name.type.module.js" + }, + "2": { + name: "punctuation.accessor.js" + }, + "3": { + name: "punctuation.accessor.optional.js" + } + } + }, + { + name: "entity.name.type.js", + match: "[_$[:alpha:]][_$[:alnum:]]*" + } + ] + }, + "punctuation-comma": { + name: "punctuation.separator.comma.js", + match: "," + }, + "punctuation-semicolon": { + name: "punctuation.terminator.statement.js", + match: ";" + }, + "punctuation-accessor": { + match: "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))", + captures: { + "1": { + name: "punctuation.accessor.js" + }, + "2": { + name: "punctuation.accessor.optional.js" + } + } + }, + string: { + patterns: [ + { + include: "#qstring-single" + }, + { + include: "#qstring-double" + }, + { + include: "#template" + } + ] + }, + "qstring-double": { + name: "string.quoted.double.js", + begin: '"', + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.js" + } + }, + end: '(")|((?:[^\\\\\\n])$)', + endCaptures: { + "1": { + name: "punctuation.definition.string.end.js" + }, + "2": { + name: "invalid.illegal.newline.js" + } + }, + patterns: [ + { + include: "#string-character-escape" + } + ] + }, + "qstring-single": { + name: "string.quoted.single.js", + begin: "'", + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.js" + } + }, + end: "(\\')|((?:[^\\\\\\n])$)", + endCaptures: { + "1": { + name: "punctuation.definition.string.end.js" + }, + "2": { + name: "invalid.illegal.newline.js" + } + }, + patterns: [ + { + include: "#string-character-escape" + } + ] + }, + "string-character-escape": { + name: "constant.character.escape.js", + match: "\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\\{[0-9A-Fa-f]+\\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)" + }, + template: { + patterns: [ + { + include: "#template-call" + }, + { + name: "string.template.js", + begin: "([_$[:alpha:]][_$[:alnum:]]*)?(`)", + beginCaptures: { + "1": { + name: "entity.name.function.tagged-template.js" + }, + "2": { + name: "punctuation.definition.string.template.begin.js" + } + }, + end: "`", + endCaptures: { + "0": { + name: "punctuation.definition.string.template.end.js" + } + }, + patterns: [ + { + include: "#template-substitution-element" + }, + { + include: "#string-character-escape" + } + ] + } + ] + }, + "template-call": { + patterns: [ + { + name: "string.template.js", + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", + end: "(?=`)", + patterns: [ + { + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", + end: "(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", + patterns: [ + { + include: "#support-function-call-identifiers" + }, + { + name: "entity.name.function.tagged-template.js", + match: "([_$[:alpha:]][_$[:alnum:]]*)" + } + ] + }, + { + include: "#type-arguments" + } + ] + }, + { + name: "string.template.js", + begin: "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", + beginCaptures: { + "1": { + name: "entity.name.function.tagged-template.js" + } + }, + end: "(?=`)", + patterns: [ + { + include: "#type-arguments" + } + ] + } + ] + }, + "template-substitution-element": { + name: "meta.template.expression.js", + begin: "\\$\\{", + beginCaptures: { + "0": { + name: "punctuation.definition.template-expression.begin.js" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.template-expression.end.js" + } + }, + patterns: [ + { + include: "#expression" + } + ], + contentName: "meta.embedded.line.js" + }, + "type-string": { + patterns: [ + { + include: "#qstring-single" + }, + { + include: "#qstring-double" + }, + { + include: "#template-type" + } + ] + }, + "template-type": { + patterns: [ + { + include: "#template-call" + }, + { + name: "string.template.js", + begin: "([_$[:alpha:]][_$[:alnum:]]*)?(`)", + beginCaptures: { + "1": { + name: "entity.name.function.tagged-template.js" + }, + "2": { + name: "punctuation.definition.string.template.begin.js" + } + }, + end: "`", + endCaptures: { + "0": { + name: "punctuation.definition.string.template.end.js" + } + }, + patterns: [ + { + include: "#template-type-substitution-element" + }, + { + include: "#string-character-escape" + } + ] + } + ] + }, + "template-type-substitution-element": { + name: "meta.template.expression.js", + begin: "\\$\\{", + beginCaptures: { + "0": { + name: "punctuation.definition.template-expression.begin.js" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.template-expression.end.js" + } + }, + patterns: [ + { + include: "#type" + } + ], + contentName: "meta.embedded.line.js" + }, + regex: { + patterns: [ + { + name: "string.regexp.js", + begin: "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[\\()]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\]|\\(([^\\)\\\\]|\\\\.)+\\))+\\/([dgimsuy]+|(?![\\/\\*])|(?=\\/\\*))(?!\\s*[a-zA-Z0-9_$]))", + beginCaptures: { + "1": { + name: "punctuation.definition.string.begin.js" + } + }, + end: "(/)([dgimsuy]*)", + endCaptures: { + "1": { + name: "punctuation.definition.string.end.js" + }, + "2": { + name: "keyword.other.js" + } + }, + patterns: [ + { + include: "#regexp" + } + ] + }, + { + name: "string.regexp.js", + begin: "((?", + captures: { + "0": { + name: "keyword.other.back-reference.regexp" + }, + "1": { + name: "variable.other.regexp" + } + } + }, + { + name: "keyword.operator.quantifier.regexp", + match: "[?+*]|\\{(\\d+,\\d+|\\d+,|,\\d+|\\d+)\\}\\??" + }, + { + name: "keyword.operator.or.regexp", + match: "\\|" + }, + { + name: "meta.group.assertion.regexp", + begin: "(\\()((\\?=)|(\\?!)|(\\?<=)|(\\?))?", + beginCaptures: { + "0": { + name: "punctuation.definition.group.regexp" + }, + "1": { + name: "punctuation.definition.group.no-capture.regexp" + }, + "2": { + name: "variable.other.regexp" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "punctuation.definition.group.regexp" + } + }, + patterns: [ + { + include: "#regexp" + } + ] + }, + { + name: "constant.other.character-class.set.regexp", + begin: "(\\[)(\\^)?", + beginCaptures: { + "1": { + name: "punctuation.definition.character-class.regexp" + }, + "2": { + name: "keyword.operator.negation.regexp" + } + }, + end: "(\\])", + endCaptures: { + "1": { + name: "punctuation.definition.character-class.regexp" + } + }, + patterns: [ + { + name: "constant.other.character-class.range.regexp", + match: "(?:.|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))\\-(?:[^\\]\\\\]|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))", + captures: { + "1": { + name: "constant.character.numeric.regexp" + }, + "2": { + name: "constant.character.control.regexp" + }, + "3": { + name: "constant.character.escape.backslash.regexp" + }, + "4": { + name: "constant.character.numeric.regexp" + }, + "5": { + name: "constant.character.control.regexp" + }, + "6": { + name: "constant.character.escape.backslash.regexp" + } + } + }, + { + include: "#regex-character-class" + } + ] + }, + { + include: "#regex-character-class" + } + ] + }, + "regex-character-class": { + patterns: [ + { + name: "constant.other.character-class.regexp", + match: "\\\\[wWsSdDtrnvf]|\\." + }, + { + name: "constant.character.numeric.regexp", + match: "\\\\([0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4})" + }, + { + name: "constant.character.control.regexp", + match: "\\\\c[A-Z]" + }, + { + name: "constant.character.escape.backslash.regexp", + match: "\\\\." + } + ] + }, + comment: { + patterns: [ + { + name: "comment.block.documentation.js", + begin: "/\\*\\*(?!/)", + beginCaptures: { + "0": { + name: "punctuation.definition.comment.js" + } + }, + end: "\\*/", + endCaptures: { + "0": { + name: "punctuation.definition.comment.js" + } + }, + patterns: [ + { + include: "#docblock" + } + ] + }, + { + name: "comment.block.js", + begin: "(/\\*)(?:\\s*((@)internal)(?=\\s|(\\*/)))?", + beginCaptures: { + "1": { + name: "punctuation.definition.comment.js" + }, + "2": { + name: "storage.type.internaldeclaration.js" + }, + "3": { + name: "punctuation.decorator.internaldeclaration.js" + } + }, + end: "\\*/", + endCaptures: { + "0": { + name: "punctuation.definition.comment.js" + } + } + }, + { + begin: "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + beginCaptures: { + "1": { + name: "punctuation.whitespace.comment.leading.js" + }, + "2": { + name: "comment.line.double-slash.js" + }, + "3": { + name: "punctuation.definition.comment.js" + }, + "4": { + name: "storage.type.internaldeclaration.js" + }, + "5": { + name: "punctuation.decorator.internaldeclaration.js" + } + }, + end: "(?=$)", + contentName: "comment.line.double-slash.js" + } + ] + }, + "single-line-comment-consuming-line-ending": { + begin: "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + beginCaptures: { + "1": { + name: "punctuation.whitespace.comment.leading.js" + }, + "2": { + name: "comment.line.double-slash.js" + }, + "3": { + name: "punctuation.definition.comment.js" + }, + "4": { + name: "storage.type.internaldeclaration.js" + }, + "5": { + name: "punctuation.decorator.internaldeclaration.js" + } + }, + end: "(?=^)", + contentName: "comment.line.double-slash.js" + }, + directives: { + name: "comment.line.triple-slash.directive.js", + begin: "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", + beginCaptures: { + "1": { + name: "punctuation.definition.comment.js" + } + }, + end: "(?=$)", + patterns: [ + { + name: "meta.tag.js", + begin: "(<)(reference|amd-dependency|amd-module)", + beginCaptures: { + "1": { + name: "punctuation.definition.tag.directive.js" + }, + "2": { + name: "entity.name.tag.directive.js" + } + }, + end: "/>", + endCaptures: { + "0": { + name: "punctuation.definition.tag.directive.js" + } + }, + patterns: [ + { + name: "entity.other.attribute-name.directive.js", + match: "path|types|no-default-lib|lib|name" + }, + { + name: "keyword.operator.assignment.js", + match: "=" + }, + { + include: "#string" + } + ] + } + ] + }, + docblock: { + patterns: [ + { + match: "(?x)\n((@)(?:access|api))\n\\s+\n(private|protected|public)\n\\b", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "constant.language.access-type.jsdoc" + } + } + }, + { + match: "(?x)\n((@)author)\n\\s+\n(\n [^@\\s<>*/]\n (?:[^@<>*/]|\\*[^/])*\n)\n(?:\n \\s*\n (<)\n ([^>\\s]+)\n (>)\n)?", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "entity.name.type.instance.jsdoc" + }, + "4": { + name: "punctuation.definition.bracket.angle.begin.jsdoc" + }, + "5": { + name: "constant.other.email.link.underline.jsdoc" + }, + "6": { + name: "punctuation.definition.bracket.angle.end.jsdoc" + } + } + }, + { + match: "(?x)\n((@)borrows) \\s+\n((?:[^@\\s*/]|\\*[^/])+) # \n\\s+ (as) \\s+ # as\n((?:[^@\\s*/]|\\*[^/])+) # ", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "entity.name.type.instance.jsdoc" + }, + "4": { + name: "keyword.operator.control.jsdoc" + }, + "5": { + name: "entity.name.type.instance.jsdoc" + } + } + }, + { + name: "meta.example.jsdoc", + begin: "((@)example)\\s+", + end: "(?=@|\\*/)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + patterns: [ + { + match: "^\\s\\*\\s+" + }, + { + contentName: "constant.other.description.jsdoc", + begin: "\\G(<)caption(>)", + beginCaptures: { + "0": { + name: "entity.name.tag.inline.jsdoc" + }, + "1": { + name: "punctuation.definition.bracket.angle.begin.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.angle.end.jsdoc" + } + }, + end: "()|(?=\\*/)", + endCaptures: { + "0": { + name: "entity.name.tag.inline.jsdoc" + }, + "1": { + name: "punctuation.definition.bracket.angle.begin.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.angle.end.jsdoc" + } + } + }, + { + match: "[^\\s@*](?:[^*]|\\*[^/])*", + captures: { + "0": { + name: "source.embedded.js" + } + } + } + ] + }, + { + match: "(?x) ((@)kind) \\s+ (class|constant|event|external|file|function|member|mixin|module|namespace|typedef) \\b", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "constant.language.symbol-type.jsdoc" + } + } + }, + { + match: "(?x)\n((@)see)\n\\s+\n(?:\n # URL\n (\n (?=https?://)\n (?:[^\\s*]|\\*[^/])+\n )\n |\n # JSDoc namepath\n (\n (?!\n # Avoid matching bare URIs (also acceptable as links)\n https?://\n |\n # Avoid matching {@inline tags}; we match those below\n (?:\\[[^\\[\\]]*\\])? # Possible description [preceding]{@tag}\n {@(?:link|linkcode|linkplain|tutorial)\\b\n )\n # Matched namepath\n (?:[^@\\s*/]|\\*[^/])+\n )\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.link.underline.jsdoc" + }, + "4": { + name: "entity.name.type.instance.jsdoc" + } + } + }, + { + match: "(?x)\n((@)template)\n\\s+\n# One or more valid identifiers\n(\n [A-Za-z_$] # First character: non-numeric word character\n [\\w$.\\[\\]]* # Rest of identifier\n (?: # Possible list of additional identifiers\n \\s* , \\s*\n [A-Za-z_$]\n [\\w$.\\[\\]]*\n )*\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + } + } + }, + { + begin: "(?x)((@)template)\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + }, + { + name: "variable.other.jsdoc", + match: "([A-Za-z_$][\\w$.\\[\\]]*)" + } + ] + }, + { + match: "(?x)\n(\n (@)\n (?:arg|argument|const|constant|member|namespace|param|var)\n)\n\\s+\n(\n [A-Za-z_$]\n [\\w$.\\[\\]]*\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + } + } + }, + { + begin: "((@)typedef)\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + }, + { + name: "entity.name.type.instance.jsdoc", + match: "(?:[^@\\s*/]|\\*[^/])+" + } + ] + }, + { + begin: "((@)(?:arg|argument|const|constant|member|namespace|param|prop|property|var))\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + }, + { + name: "variable.other.jsdoc", + match: "([A-Za-z_$][\\w$.\\[\\]]*)" + }, + { + name: "variable.other.jsdoc", + match: `(?x) +(\\[)\\s* +[\\w$]+ +(?: + (?:\\[\\])? # Foo[ ].bar properties within an array + \\. # Foo.Bar namespaced parameter + [\\w$]+ +)* +(?: + \\s* + (=) # [foo=bar] Default parameter value + \\s* + ( + # The inner regexes are to stop the match early at */ and to not stop at escaped quotes + (?> + "(?:(?:\\*(?!/))|(?:\\\\(?!"))|[^*\\\\])*?" | # [foo="bar"] Double-quoted + '(?:(?:\\*(?!/))|(?:\\\\(?!'))|[^*\\\\])*?' | # [foo='bar'] Single-quoted + \\[ (?:(?:\\*(?!/))|[^*])*? \\] | # [foo=[1,2]] Array literal + (?:(?:\\*(?!/))|\\s(?!\\s*\\])|\\[.*?(?:\\]|(?=\\*/))|[^*\\s\\[\\]])* # Everything else + )* + ) +)? +\\s*(?:(\\])((?:[^*\\s]|\\*[^\\s/])+)?|(?=\\*/))`, + captures: { + "1": { + name: "punctuation.definition.optional-value.begin.bracket.square.jsdoc" + }, + "2": { + name: "keyword.operator.assignment.jsdoc" + }, + "3": { + name: "source.embedded.js" + }, + "4": { + name: "punctuation.definition.optional-value.end.bracket.square.jsdoc" + }, + "5": { + name: "invalid.illegal.syntax.jsdoc" + } + } + } + ] + }, + { + begin: "(?x)\n(\n (@)\n (?:define|enum|exception|export|extends|lends|implements|modifies\n |namespace|private|protected|returns?|suppress|this|throws|type\n |yields?)\n)\n\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + } + ] + }, + { + match: "(?x)\n(\n (@)\n (?:alias|augments|callback|constructs|emits|event|fires|exports?\n |extends|external|function|func|host|lends|listens|interface|memberof!?\n |method|module|mixes|mixin|name|requires|see|this|typedef|uses)\n)\n\\s+\n(\n (?:\n [^{}@\\s*] | \\*[^/]\n )+\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "entity.name.type.instance.jsdoc" + } + } + }, + { + contentName: "variable.other.jsdoc", + begin: `((@)(?:default(?:value)?|license|version))\\s+(([''"]))`, + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + }, + "4": { + name: "punctuation.definition.string.begin.jsdoc" + } + }, + end: "(\\3)|(?=$|\\*/)", + endCaptures: { + "0": { + name: "variable.other.jsdoc" + }, + "1": { + name: "punctuation.definition.string.end.jsdoc" + } + } + }, + { + match: "((@)(?:default(?:value)?|license|tutorial|variation|version))\\s+([^\\s*]+)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + } + } + }, + { + name: "storage.type.class.jsdoc", + match: "(?x) (@) (?:abstract|access|alias|api|arg|argument|async|attribute|augments|author|beta|borrows|bubbles |callback|chainable|class|classdesc|code|config|const|constant|constructor|constructs|copyright |default|defaultvalue|define|deprecated|desc|description|dict|emits|enum|event|example|exception |exports?|extends|extension(?:_?for)?|external|externs|file|fileoverview|final|fires|for|func |function|generator|global|hideconstructor|host|ignore|implements|implicitCast|inherit[Dd]oc |inner|instance|interface|internal|kind|lends|license|listens|main|member|memberof!?|method |mixes|mixins?|modifies|module|name|namespace|noalias|nocollapse|nocompile|nosideeffects |override|overview|package|param|polymer(?:Behavior)?|preserve|private|prop|property|protected |public|read[Oo]nly|record|require[ds]|returns?|see|since|static|struct|submodule|summary |suppress|template|this|throws|todo|tutorial|type|typedef|unrestricted|uses|var|variation |version|virtual|writeOnce|yields?) \\b", + captures: { + "1": { + name: "punctuation.definition.block.tag.jsdoc" + } + } + }, + { + include: "#inline-tags" + }, + { + match: "((@)(?:[_$[:alpha:]][_$[:alnum:]]*))(?=\\s+)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + } + } + ] + }, + brackets: { + patterns: [ + { + begin: "{", + end: "}|(?=\\*/)", + patterns: [ + { + include: "#brackets" + } + ] + }, + { + begin: "\\[", + end: "\\]|(?=\\*/)", + patterns: [ + { + include: "#brackets" + } + ] + } + ] + }, + "inline-tags": { + patterns: [ + { + name: "constant.other.description.jsdoc", + match: "(\\[)[^\\]]+(\\])(?={@(?:link|linkcode|linkplain|tutorial))", + captures: { + "1": { + name: "punctuation.definition.bracket.square.begin.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.square.end.jsdoc" + } + } + }, + { + name: "entity.name.type.instance.jsdoc", + begin: "({)((@)(?:link(?:code|plain)?|tutorial))\\s*", + beginCaptures: { + "1": { + name: "punctuation.definition.bracket.curly.begin.jsdoc" + }, + "2": { + name: "storage.type.class.jsdoc" + }, + "3": { + name: "punctuation.definition.inline.tag.jsdoc" + } + }, + end: "}|(?=\\*/)", + endCaptures: { + "0": { + name: "punctuation.definition.bracket.curly.end.jsdoc" + } + }, + patterns: [ + { + match: "\\G((?=https?://)(?:[^|}\\s*]|\\*[/])+)(\\|)?", + captures: { + "1": { + name: "variable.other.link.underline.jsdoc" + }, + "2": { + name: "punctuation.separator.pipe.jsdoc" + } + } + }, + { + match: "\\G((?:[^{}@\\s|*]|\\*[^/])+)(\\|)?", + captures: { + "1": { + name: "variable.other.description.jsdoc" + }, + "2": { + name: "punctuation.separator.pipe.jsdoc" + } + } + } + ] + } + ] + }, + jsdoctype: { + patterns: [ + { + contentName: "entity.name.type.instance.jsdoc", + begin: "\\G({)", + beginCaptures: { + "0": { + name: "entity.name.type.instance.jsdoc" + }, + "1": { + name: "punctuation.definition.bracket.curly.begin.jsdoc" + } + }, + end: "((}))\\s*|(?=\\*/)", + endCaptures: { + "1": { + name: "entity.name.type.instance.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.curly.end.jsdoc" + } + }, + patterns: [ + { + include: "#brackets" + } + ] + } + ] + }, + jsx: { + patterns: [ + { + include: "#jsx-tag-without-attributes-in-expression" + }, + { + include: "#jsx-tag-in-expression" + } + ] + }, + "jsx-tag-without-attributes-in-expression": { + begin: "(?:*]|&&|\\|\\||\\?|\\*\\/|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))", + end: "(?!(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))", + patterns: [ + { + include: "#jsx-tag-without-attributes" + } + ] + }, + "jsx-tag-without-attributes": { + name: "meta.tag.without-attributes.js", + begin: "(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?)", + end: "()", + beginCaptures: { + "1": { + name: "punctuation.definition.tag.begin.js" + }, + "2": { + name: "entity.name.tag.namespace.js" + }, + "3": { + name: "punctuation.separator.namespace.js" + }, + "4": { + name: "entity.name.tag.js" + }, + "5": { + name: "support.class.component.js" + }, + "6": { + name: "punctuation.definition.tag.end.js" + } + }, + endCaptures: { + "1": { + name: "punctuation.definition.tag.begin.js" + }, + "2": { + name: "entity.name.tag.namespace.js" + }, + "3": { + name: "punctuation.separator.namespace.js" + }, + "4": { + name: "entity.name.tag.js" + }, + "5": { + name: "support.class.component.js" + }, + "6": { + name: "punctuation.definition.tag.end.js" + } + }, + contentName: "meta.jsx.children.js", + patterns: [ + { + include: "#jsx-children" + } + ] + }, + "jsx-tag-in-expression": { + begin: "(?x)\n (?:*]|&&|\\|\\||\\?|\\*\\/|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))", + end: "(?!(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))", + patterns: [ + { + include: "#jsx-tag" + } + ] + }, + "jsx-tag": { + name: "meta.tag.js", + begin: "(?=(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))", + end: "(/>)|(?:())", + endCaptures: { + "1": { + name: "punctuation.definition.tag.end.js" + }, + "2": { + name: "punctuation.definition.tag.begin.js" + }, + "3": { + name: "entity.name.tag.namespace.js" + }, + "4": { + name: "punctuation.separator.namespace.js" + }, + "5": { + name: "entity.name.tag.js" + }, + "6": { + name: "support.class.component.js" + }, + "7": { + name: "punctuation.definition.tag.end.js" + } + }, + patterns: [ + { + begin: "(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?)", + beginCaptures: { + "1": { + name: "punctuation.definition.tag.begin.js" + }, + "2": { + name: "entity.name.tag.namespace.js" + }, + "3": { + name: "punctuation.separator.namespace.js" + }, + "4": { + name: "entity.name.tag.js" + }, + "5": { + name: "support.class.component.js" + } + }, + end: "(?=[/]?>)", + patterns: [ + { + include: "#comment" + }, + { + include: "#type-arguments" + }, + { + include: "#jsx-tag-attributes" + } + ] + }, + { + begin: "(>)", + beginCaptures: { + "1": { + name: "punctuation.definition.tag.end.js" + } + }, + end: "(?=)", + patterns: [ + { + include: "#comment" + }, + { + include: "#jsx-tag-attribute-name" + }, + { + include: "#jsx-tag-attribute-assignment" + }, + { + include: "#jsx-string-double-quoted" + }, + { + include: "#jsx-string-single-quoted" + }, + { + include: "#jsx-evaluated-code" + }, + { + include: "#jsx-tag-attributes-illegal" + } + ] + }, + "jsx-tag-attribute-name": { + match: "(?x)\n \\s*\n (?:([_$[:alpha:]][-_$[:alnum:].]*)(:))?\n ([_$[:alpha:]][-_$[:alnum:]]*)\n (?=\\s|=|/?>|/\\*|//)", + captures: { + "1": { + name: "entity.other.attribute-name.namespace.js" + }, + "2": { + name: "punctuation.separator.namespace.js" + }, + "3": { + name: "entity.other.attribute-name.js" + } + } + }, + "jsx-tag-attribute-assignment": { + name: "keyword.operator.assignment.js", + match: `=(?=\\s*(?:'|"|{|/\\*|//|\\n))` + }, + "jsx-string-double-quoted": { + name: "string.quoted.double.js", + begin: '"', + end: '"', + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.js" + } + }, + endCaptures: { + "0": { + name: "punctuation.definition.string.end.js" + } + }, + patterns: [ + { + include: "#jsx-entities" + } + ] + }, + "jsx-string-single-quoted": { + name: "string.quoted.single.js", + begin: "'", + end: "'", + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.js" + } + }, + endCaptures: { + "0": { + name: "punctuation.definition.string.end.js" + } + }, + patterns: [ + { + include: "#jsx-entities" + } + ] + }, + "jsx-tag-attributes-illegal": { + name: "invalid.illegal.attribute.js", + match: "\\S+" + } +}; +const JavaScript_tmLanguage = { + information_for_contributors, + version, + name, + scopeName, + patterns, + repository +}; + +export { JavaScript_tmLanguage as default, information_for_contributors, name, patterns, repository, scopeName, version }; diff --git a/js/chunks/TypeScript.tmLanguage-01b7ed7f.js b/js/chunks/TypeScript.tmLanguage-01b7ed7f.js new file mode 100644 index 0000000..2cea981 --- /dev/null +++ b/js/chunks/TypeScript.tmLanguage-01b7ed7f.js @@ -0,0 +1,5635 @@ +const information_for_contributors = [ + "This file has been converted from https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScript.tmLanguage", + "If you want to provide a fix or improvement, please create a pull request against the original repository.", + "Once accepted there, we are happy to receive an update request." +]; +const version = "https://github.com/microsoft/TypeScript-TmLanguage/commit/56b7270f094b036256774702e3b7f96490981190"; +const name = "TypeScript"; +const scopeName = "source.ts"; +const patterns = [ + { + include: "#directives" + }, + { + include: "#statements" + }, + { + include: "#shebang" + } +]; +const repository = { + shebang: { + name: "comment.line.shebang.ts", + match: "\\A(#!).*(?=$)", + captures: { + "1": { + name: "punctuation.definition.comment.ts" + } + } + }, + statements: { + patterns: [ + { + include: "#declaration" + }, + { + include: "#control-statement" + }, + { + include: "#after-operator-block-as-object-literal" + }, + { + include: "#decl-block" + }, + { + include: "#label" + }, + { + include: "#expression" + }, + { + include: "#punctuation-semicolon" + }, + { + include: "#string" + }, + { + include: "#comment" + } + ] + }, + declaration: { + patterns: [ + { + include: "#decorator" + }, + { + include: "#var-expr" + }, + { + include: "#function-declaration" + }, + { + include: "#class-declaration" + }, + { + include: "#interface-declaration" + }, + { + include: "#enum-declaration" + }, + { + include: "#namespace-declaration" + }, + { + include: "#type-alias-declaration" + }, + { + include: "#import-equals-declaration" + }, + { + include: "#import-declaration" + }, + { + include: "#export-declaration" + }, + { + name: "storage.modifier.ts", + match: "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + beginCaptures: { + "1": { + name: "meta.definition.variable.ts entity.name.function.ts" + }, + "2": { + name: "keyword.operator.definiteassignment.ts" + } + }, + end: "(?=$|^|[;,=}]|((?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + beginCaptures: { + "1": { + name: "meta.definition.variable.ts variable.other.constant.ts entity.name.function.ts" + } + }, + end: "(?=$|^|[;,=}]|((?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "1": { + name: "storage.modifier.ts" + }, + "2": { + name: "keyword.operator.rest.ts" + }, + "3": { + name: "entity.name.function.ts variable.language.this.ts" + }, + "4": { + name: "entity.name.function.ts" + }, + "5": { + name: "keyword.operator.optional.ts" + } + } + }, + { + match: "(?x)(?:(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "1": { + name: "meta.definition.property.ts entity.name.function.ts" + }, + "2": { + name: "keyword.operator.optional.ts" + }, + "3": { + name: "keyword.operator.definiteassignment.ts" + } + } + }, + { + name: "meta.definition.property.ts variable.object.property.ts", + match: "\\#?[_$[:alpha:]][_$[:alnum:]]*" + }, + { + name: "keyword.operator.optional.ts", + match: "\\?" + }, + { + name: "keyword.operator.definiteassignment.ts", + match: "\\!" + } + ] + }, + "variable-initializer": { + patterns: [ + { + begin: "(?\\s*$)", + beginCaptures: { + "1": { + name: "keyword.operator.assignment.ts" + } + }, + end: "(?=$|^|[,);}\\]]|((?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.ts" + }, + "2": { + name: "storage.modifier.ts" + }, + "3": { + name: "storage.modifier.ts" + }, + "4": { + name: "storage.modifier.async.ts" + }, + "5": { + name: "keyword.operator.new.ts" + }, + "6": { + name: "keyword.generator.asterisk.ts" + } + }, + end: "(?=\\}|;|,|$)|(?<=\\})", + patterns: [ + { + include: "#method-declaration-name" + }, + { + include: "#function-body" + } + ] + }, + { + name: "meta.method.declaration.ts", + begin: "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.ts" + }, + "2": { + name: "storage.modifier.ts" + }, + "3": { + name: "storage.modifier.ts" + }, + "4": { + name: "storage.modifier.async.ts" + }, + "5": { + name: "storage.type.property.ts" + }, + "6": { + name: "keyword.generator.asterisk.ts" + } + }, + end: "(?=\\}|;|,|$)|(?<=\\})", + patterns: [ + { + include: "#method-declaration-name" + }, + { + include: "#function-body" + } + ] + } + ] + }, + "object-literal-method-declaration": { + name: "meta.method.declaration.ts", + begin: "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + }, + "2": { + name: "storage.type.property.ts" + }, + "3": { + name: "keyword.generator.asterisk.ts" + } + }, + end: "(?=\\}|;|,)|(?<=\\})", + patterns: [ + { + include: "#method-declaration-name" + }, + { + include: "#function-body" + }, + { + begin: "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + }, + "2": { + name: "storage.type.property.ts" + }, + "3": { + name: "keyword.generator.asterisk.ts" + } + }, + end: "(?=\\(|\\<)", + patterns: [ + { + include: "#method-declaration-name" + } + ] + } + ] + }, + "method-declaration-name": { + begin: "(?x)(?=((\\b(?)", + captures: { + "1": { + name: "storage.modifier.async.ts" + }, + "2": { + name: "variable.parameter.ts" + } + } + }, + { + name: "meta.arrow.ts", + begin: "(?x) (?:\n (? is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + } + }, + end: "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + patterns: [ + { + include: "#comment" + }, + { + include: "#type-parameters" + }, + { + include: "#function-parameters" + }, + { + include: "#arrow-return-type" + }, + { + include: "#possibly-arrow-return-type" + } + ] + }, + { + name: "meta.arrow.ts", + begin: "=>", + beginCaptures: { + "0": { + name: "storage.type.function.arrow.ts" + } + }, + end: "((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])", + patterns: [ + { + include: "#single-line-comment-consuming-line-ending" + }, + { + include: "#decl-block" + }, + { + include: "#expression" + } + ] + } + ] + }, + "indexer-declaration": { + name: "meta.indexer.declaration.ts", + begin: "(?:(?]|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^yield|[^\\._$[:alnum:]]yield|^throw|[^\\._$[:alnum:]]throw|^in|[^\\._$[:alnum:]]in|^of|[^\\._$[:alnum:]]of|^typeof|[^\\._$[:alnum:]]typeof|&&|\\|\\||\\*)\\s*(\\{)", + beginCaptures: { + "1": { + name: "punctuation.definition.block.ts" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.block.ts" + } + }, + patterns: [ + { + include: "#object-member" + } + ] + }, + "object-literal": { + name: "meta.objectliteral.ts", + begin: "\\{", + beginCaptures: { + "0": { + name: "punctuation.definition.block.ts" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.block.ts" + } + }, + patterns: [ + { + include: "#object-member" + } + ] + }, + "object-member": { + patterns: [ + { + include: "#comment" + }, + { + include: "#object-literal-method-declaration" + }, + { + name: "meta.object.member.ts meta.object-literal.key.ts", + begin: "(?=\\[)", + end: "(?=:)|((?<=[\\]])(?=\\s*[\\(\\<]))", + patterns: [ + { + include: "#comment" + }, + { + include: "#array-literal" + } + ] + }, + { + name: "meta.object.member.ts meta.object-literal.key.ts", + begin: "(?=[\\'\\\"\\`])", + end: "(?=:)|((?<=[\\'\\\"\\`])(?=((\\s*[\\(\\<,}])|(\\s+(as)\\s+))))", + patterns: [ + { + include: "#comment" + }, + { + include: "#string" + } + ] + }, + { + name: "meta.object.member.ts meta.object-literal.key.ts", + begin: "(?x)(?=(\\b(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "0": { + name: "meta.object-literal.key.ts" + }, + "1": { + name: "entity.name.function.ts" + } + } + }, + { + name: "meta.object.member.ts", + match: "(?:[_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*:)", + captures: { + "0": { + name: "meta.object-literal.key.ts" + } + } + }, + { + name: "meta.object.member.ts", + begin: "\\.\\.\\.", + beginCaptures: { + "0": { + name: "keyword.operator.spread.ts" + } + }, + end: "(?=,|\\})", + patterns: [ + { + include: "#expression" + } + ] + }, + { + name: "meta.object.member.ts", + match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=,|\\}|$|\\/\\/|\\/\\*)", + captures: { + "1": { + name: "variable.other.readwrite.ts" + } + } + }, + { + name: "meta.object.member.ts", + match: "(?]|\\|\\||\\&\\&|\\!\\=\\=|$|^|((?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)\\(\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + } + }, + end: "(?<=\\))", + patterns: [ + { + include: "#type-parameters" + }, + { + begin: "\\(", + beginCaptures: { + "0": { + name: "meta.brace.round.ts" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.ts" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + { + begin: "(?<=:)\\s*(async)?\\s*(\\()(?=\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + }, + "2": { + name: "meta.brace.round.ts" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.ts" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + begin: "(?<=:)\\s*(async)?\\s*(?=\\<\\s*$)", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + } + }, + end: "(?<=\\>)", + patterns: [ + { + include: "#type-parameters" + } + ] + }, + { + begin: "(?<=\\>)\\s*(\\()(?=\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "meta.brace.round.ts" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.ts" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + include: "#possibly-arrow-return-type" + }, + { + include: "#expression" + } + ] + }, + { + include: "#punctuation-comma" + } + ] + }, + "ternary-expression": { + begin: "(?!\\?\\.\\s*[^[:digit:]])(\\?)(?!\\?)", + beginCaptures: { + "1": { + name: "keyword.operator.ternary.ts" + } + }, + end: "\\s*(:)", + endCaptures: { + "1": { + name: "keyword.operator.ternary.ts" + } + }, + patterns: [ + { + include: "#expression" + } + ] + }, + "function-call": { + patterns: [ + { + begin: "(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())", + end: "(?<=\\))(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())", + patterns: [ + { + name: "meta.function-call.ts", + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))", + end: "(?=\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())", + patterns: [ + { + include: "#function-call-target" + } + ] + }, + { + include: "#comment" + }, + { + include: "#function-call-optionals" + }, + { + include: "#type-arguments" + }, + { + include: "#paren-expression" + } + ] + }, + { + begin: "(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))(<\\s*[\\{\\[\\(]\\s*$))", + end: "(?<=\\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))(<\\s*[\\{\\[\\(]\\s*$))", + patterns: [ + { + name: "meta.function-call.ts", + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))", + end: "(?=(<\\s*[\\{\\[\\(]\\s*$))", + patterns: [ + { + include: "#function-call-target" + } + ] + }, + { + include: "#comment" + }, + { + include: "#function-call-optionals" + }, + { + include: "#type-arguments" + } + ] + } + ] + }, + "function-call-target": { + patterns: [ + { + include: "#support-function-call-identifiers" + }, + { + name: "entity.name.function.ts", + match: "(\\#?[_$[:alpha:]][_$[:alnum:]]*)" + } + ] + }, + "function-call-optionals": { + patterns: [ + { + name: "meta.function-call.ts punctuation.accessor.optional.ts", + match: "\\?\\." + }, + { + name: "meta.function-call.ts keyword.operator.definiteassignment.ts", + match: "\\!" + } + ] + }, + "support-function-call-identifiers": { + patterns: [ + { + include: "#literal" + }, + { + include: "#support-objects" + }, + { + include: "#object-identifiers" + }, + { + include: "#punctuation-accessor" + }, + { + name: "keyword.operator.expression.import.ts", + match: "(?:(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|(([\\&\\~\\^\\|]\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s+instanceof(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))|((?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?\\(\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + } + }, + end: "(?<=\\))", + patterns: [ + { + include: "#paren-expression-possibly-arrow-with-typeparameters" + } + ] + }, + { + begin: "(?<=[(=,]|=>|^return|[^\\._$[:alnum:]]return)\\s*(async)?(?=\\s*((((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?\\()|(<))\\s*$)", + beginCaptures: { + "1": { + name: "storage.modifier.async.ts" + } + }, + end: "(?<=\\))", + patterns: [ + { + include: "#paren-expression-possibly-arrow-with-typeparameters" + } + ] + }, + { + include: "#possibly-arrow-return-type" + } + ] + }, + "paren-expression-possibly-arrow-with-typeparameters": { + patterns: [ + { + include: "#type-parameters" + }, + { + begin: "\\(", + beginCaptures: { + "0": { + name: "meta.brace.round.ts" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "meta.brace.round.ts" + } + }, + patterns: [ + { + include: "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + "expression-inside-possibly-arrow-parens": { + patterns: [ + { + include: "#expressionWithoutIdentifiers" + }, + { + include: "#comment" + }, + { + include: "#string" + }, + { + include: "#decorator" + }, + { + include: "#destructuring-parameter" + }, + { + match: "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + captures: { + "1": { + name: "storage.modifier.ts" + }, + "2": { + name: "keyword.operator.rest.ts" + }, + "3": { + name: "entity.name.function.ts variable.language.this.ts" + }, + "4": { + name: "entity.name.function.ts" + }, + "5": { + name: "keyword.operator.optional.ts" + } + } + }, + { + match: "(?x)(?:(?)", + captures: { + "1": { + name: "meta.brace.angle.ts" + }, + "2": { + name: "storage.modifier.ts" + }, + "3": { + name: "meta.brace.angle.ts" + } + } + }, + { + name: "cast.expr.ts", + begin: "(?:(?*?\\&\\|\\^]|[^_$[:alnum:]](?:\\+\\+|\\-\\-)|[^\\+]\\+|[^\\-]\\-))\\s*(<)(?!)", + endCaptures: { + "1": { + name: "meta.brace.angle.ts" + } + }, + patterns: [ + { + include: "#type" + } + ] + }, + { + name: "cast.expr.ts", + begin: "(?:(?<=^))\\s*(<)(?=[_$[:alpha:]][_$[:alnum:]]*\\s*>)", + beginCaptures: { + "1": { + name: "meta.brace.angle.ts" + } + }, + end: "(\\>)", + endCaptures: { + "1": { + name: "meta.brace.angle.ts" + } + }, + patterns: [ + { + include: "#type" + } + ] + } + ] + }, + "expression-operators": { + patterns: [ + { + name: "keyword.control.flow.ts", + match: "(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?>=|>>>=|\\|=" + }, + { + name: "keyword.operator.bitwise.shift.ts", + match: "<<|>>>|>>" + }, + { + name: "keyword.operator.comparison.ts", + match: "===|!==|==|!=" + }, + { + name: "keyword.operator.relational.ts", + match: "<=|>=|<>|<|>" + }, + { + match: "(?<=[_$[:alnum:]])(\\!)\\s*(?:(/=)|(?:(/)(?![/*])))", + captures: { + "1": { + name: "keyword.operator.logical.ts" + }, + "2": { + name: "keyword.operator.assignment.compound.ts" + }, + "3": { + name: "keyword.operator.arithmetic.ts" + } + } + }, + { + name: "keyword.operator.logical.ts", + match: "\\!|&&|\\|\\||\\?\\?" + }, + { + name: "keyword.operator.bitwise.ts", + match: "\\&|~|\\^|\\|" + }, + { + name: "keyword.operator.assignment.ts", + match: "\\=" + }, + { + name: "keyword.operator.decrement.ts", + match: "--" + }, + { + name: "keyword.operator.increment.ts", + match: "\\+\\+" + }, + { + name: "keyword.operator.arithmetic.ts", + match: "%|\\*|/|-|\\+" + }, + { + begin: "(?<=[_$[:alnum:])\\]])\\s*(?=(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)+(?:(/=)|(?:(/)(?![/*]))))", + end: "(?:(/=)|(?:(/)(?!\\*([^\\*]|(\\*[^\\/]))*\\*\\/)))", + endCaptures: { + "1": { + name: "keyword.operator.assignment.compound.ts" + }, + "2": { + name: "keyword.operator.arithmetic.ts" + } + }, + patterns: [ + { + include: "#comment" + } + ] + }, + { + match: "(?<=[_$[:alnum:])\\]])\\s*(?:(/=)|(?:(/)(?![/*])))", + captures: { + "1": { + name: "keyword.operator.assignment.compound.ts" + }, + "2": { + name: "keyword.operator.arithmetic.ts" + } + } + } + ] + }, + "typeof-operator": { + begin: "(?:&|{\\?]|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", + patterns: [ + { + include: "#expression" + } + ] + }, + literal: { + patterns: [ + { + include: "#numeric-literal" + }, + { + include: "#boolean-literal" + }, + { + include: "#null-literal" + }, + { + include: "#undefined-literal" + }, + { + include: "#numericConstant-literal" + }, + { + include: "#array-literal" + }, + { + include: "#this-literal" + }, + { + include: "#super-literal" + } + ] + }, + "array-literal": { + name: "meta.array.literal.ts", + begin: "\\s*(\\[)", + beginCaptures: { + "1": { + name: "meta.brace.square.ts" + } + }, + end: "\\]", + endCaptures: { + "0": { + name: "meta.brace.square.ts" + } + }, + patterns: [ + { + include: "#expression" + }, + { + include: "#punctuation-comma" + } + ] + }, + "numeric-literal": { + patterns: [ + { + name: "constant.numeric.hex.ts", + match: "\\b(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\\())\n |\n (?:(EPSILON|MAX_SAFE_INTEGER|MAX_VALUE|MIN_SAFE_INTEGER|MIN_VALUE|NEGATIVE_INFINITY|POSITIVE_INFINITY)\\b(?!\\$)))", + captures: { + "1": { + name: "punctuation.accessor.ts" + }, + "2": { + name: "punctuation.accessor.optional.ts" + }, + "3": { + name: "support.variable.property.ts" + }, + "4": { + name: "support.constant.ts" + } + } + }, + { + match: "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\'\\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", + captures: { + "1": { + name: "punctuation.accessor.ts" + }, + "2": { + name: "punctuation.accessor.optional.ts" + }, + "3": { + name: "entity.name.function.ts" + } + } + }, + { + match: "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])", + captures: { + "1": { + name: "punctuation.accessor.ts" + }, + "2": { + name: "punctuation.accessor.optional.ts" + }, + "3": { + name: "variable.other.constant.property.ts" + } + } + }, + { + match: "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*)", + captures: { + "1": { + name: "punctuation.accessor.ts" + }, + "2": { + name: "punctuation.accessor.optional.ts" + }, + "3": { + name: "variable.other.property.ts" + } + } + }, + { + name: "variable.other.constant.ts", + match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + }, + { + name: "variable.other.readwrite.ts", + match: "[_$[:alpha:]][_$[:alnum:]]*" + } + ] + }, + "object-identifiers": { + patterns: [ + { + name: "support.class.ts", + match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\??\\.\\s*prototype\\b(?!\\$))" + }, + { + match: "(?x)(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(?:\n (\\#?[[:upper:]][_$[:digit:][:upper:]]*) |\n (\\#?[_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*)", + captures: { + "1": { + name: "punctuation.accessor.ts" + }, + "2": { + name: "punctuation.accessor.optional.ts" + }, + "3": { + name: "variable.other.constant.object.property.ts" + }, + "4": { + name: "variable.other.object.property.ts" + } + } + }, + { + match: "(?x)(?:\n ([[:upper:]][_$[:digit:][:upper:]]*) |\n ([_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*)", + captures: { + "1": { + name: "variable.other.constant.object.ts" + }, + "2": { + name: "variable.other.object.ts" + } + } + } + ] + }, + "type-annotation": { + patterns: [ + { + name: "meta.type.annotation.ts", + begin: "(:)(?=\\s*\\S)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.ts" + } + }, + end: "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + patterns: [ + { + include: "#type" + } + ] + }, + { + name: "meta.type.annotation.ts", + begin: "(:)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.ts" + } + }, + end: "(?])|(?=^\\s*$)|((?<=\\S)(?=\\s*$))|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + patterns: [ + { + include: "#type" + } + ] + } + ] + }, + "parameter-type-annotation": { + patterns: [ + { + name: "meta.type.annotation.ts", + begin: "(:)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.ts" + } + }, + end: "(?=[,)])|(?==[^>])", + patterns: [ + { + include: "#type" + } + ] + } + ] + }, + "return-type": { + patterns: [ + { + name: "meta.return.type.ts", + begin: "(?<=\\))\\s*(:)(?=\\s*\\S)", + beginCaptures: { + "1": { + name: "keyword.operator.type.annotation.ts" + } + }, + end: "(?|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + patterns: [ + { + include: "#arrow-return-type-body" + } + ] + }, + "possibly-arrow-return-type": { + begin: "(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)", + beginCaptures: { + "1": { + name: "meta.arrow.ts meta.return.type.arrow.ts keyword.operator.type.annotation.ts" + } + }, + end: "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + contentName: "meta.arrow.ts meta.return.type.arrow.ts", + patterns: [ + { + include: "#arrow-return-type-body" + } + ] + }, + "arrow-return-type-body": { + patterns: [ + { + begin: "(?<=[:])(?=\\s*\\{)", + end: "(?<=\\})", + patterns: [ + { + include: "#type-object" + } + ] + }, + { + include: "#type-predicate-operator" + }, + { + include: "#type" + } + ] + }, + "type-parameters": { + name: "meta.type.parameters.ts", + begin: "(<)", + beginCaptures: { + "1": { + name: "punctuation.definition.typeparameters.begin.ts" + } + }, + end: "(>)", + endCaptures: { + "1": { + name: "punctuation.definition.typeparameters.end.ts" + } + }, + patterns: [ + { + include: "#comment" + }, + { + name: "storage.modifier.ts", + match: "(?)" + } + ] + }, + "type-arguments": { + name: "meta.type.parameters.ts", + begin: "\\<", + beginCaptures: { + "0": { + name: "punctuation.definition.typeparameters.begin.ts" + } + }, + end: "\\>", + endCaptures: { + "0": { + name: "punctuation.definition.typeparameters.end.ts" + } + }, + patterns: [ + { + include: "#type-arguments-body" + } + ] + }, + "type-arguments-body": { + patterns: [ + { + match: "(?)\n ))\n ))\n)) |\n(:\\s*(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?[\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))))", + captures: { + "1": { + name: "storage.modifier.ts" + }, + "2": { + name: "keyword.operator.rest.ts" + }, + "3": { + name: "entity.name.function.ts variable.language.this.ts" + }, + "4": { + name: "entity.name.function.ts" + }, + "5": { + name: "keyword.operator.optional.ts" + } + } + }, + { + match: "(?x)(?:(?)", + patterns: [ + { + include: "#comment" + }, + { + include: "#type-parameters" + } + ] + }, + { + name: "meta.type.constructor.ts", + begin: "(?)\n ))\n )\n )\n)", + end: "(?<=\\))", + patterns: [ + { + include: "#function-parameters" + } + ] + } + ] + }, + "type-function-return-type": { + patterns: [ + { + name: "meta.type.function.return.ts", + begin: "(=>)(?=\\s*\\S)", + beginCaptures: { + "1": { + name: "storage.type.function.arrow.ts" + } + }, + end: "(?)(?:\\?]|//|$)", + patterns: [ + { + include: "#type-function-return-type-core" + } + ] + }, + { + name: "meta.type.function.return.ts", + begin: "=>", + beginCaptures: { + "0": { + name: "storage.type.function.arrow.ts" + } + }, + end: "(?)(?]|//|^\\s*$)|((?<=\\S)(?=\\s*$)))", + patterns: [ + { + include: "#type-function-return-type-core" + } + ] + } + ] + }, + "type-function-return-type-core": { + patterns: [ + { + include: "#comment" + }, + { + begin: "(?<==>)(?=\\s*\\{)", + end: "(?<=\\})", + patterns: [ + { + include: "#type-object" + } + ] + }, + { + include: "#type-predicate-operator" + }, + { + include: "#type" + } + ] + }, + "type-operators": { + patterns: [ + { + include: "#typeof-operator" + }, + { + begin: "([&|])(?=\\s*\\{)", + beginCaptures: { + "0": { + name: "keyword.operator.type.ts" + } + }, + end: "(?<=\\})", + patterns: [ + { + include: "#type-object" + } + ] + }, + { + begin: "[&|]", + beginCaptures: { + "0": { + name: "keyword.operator.type.ts" + } + }, + end: "(?=\\S)" + }, + { + name: "keyword.operator.expression.keyof.ts", + match: "(?)", + endCaptures: { + "1": { + name: "meta.type.parameters.ts punctuation.definition.typeparameters.end.ts" + } + }, + contentName: "meta.type.parameters.ts", + patterns: [ + { + include: "#type-arguments-body" + } + ] + }, + { + begin: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(<)", + beginCaptures: { + "1": { + name: "entity.name.type.ts" + }, + "2": { + name: "meta.type.parameters.ts punctuation.definition.typeparameters.begin.ts" + } + }, + end: "(>)", + endCaptures: { + "1": { + name: "meta.type.parameters.ts punctuation.definition.typeparameters.end.ts" + } + }, + contentName: "meta.type.parameters.ts", + patterns: [ + { + include: "#type-arguments-body" + } + ] + }, + { + match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))", + captures: { + "1": { + name: "entity.name.type.module.ts" + }, + "2": { + name: "punctuation.accessor.ts" + }, + "3": { + name: "punctuation.accessor.optional.ts" + } + } + }, + { + name: "entity.name.type.ts", + match: "[_$[:alpha:]][_$[:alnum:]]*" + } + ] + }, + "punctuation-comma": { + name: "punctuation.separator.comma.ts", + match: "," + }, + "punctuation-semicolon": { + name: "punctuation.terminator.statement.ts", + match: ";" + }, + "punctuation-accessor": { + match: "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))", + captures: { + "1": { + name: "punctuation.accessor.ts" + }, + "2": { + name: "punctuation.accessor.optional.ts" + } + } + }, + string: { + patterns: [ + { + include: "#qstring-single" + }, + { + include: "#qstring-double" + }, + { + include: "#template" + } + ] + }, + "qstring-double": { + name: "string.quoted.double.ts", + begin: '"', + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.ts" + } + }, + end: '(")|((?:[^\\\\\\n])$)', + endCaptures: { + "1": { + name: "punctuation.definition.string.end.ts" + }, + "2": { + name: "invalid.illegal.newline.ts" + } + }, + patterns: [ + { + include: "#string-character-escape" + } + ] + }, + "qstring-single": { + name: "string.quoted.single.ts", + begin: "'", + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.ts" + } + }, + end: "(\\')|((?:[^\\\\\\n])$)", + endCaptures: { + "1": { + name: "punctuation.definition.string.end.ts" + }, + "2": { + name: "invalid.illegal.newline.ts" + } + }, + patterns: [ + { + include: "#string-character-escape" + } + ] + }, + "string-character-escape": { + name: "constant.character.escape.ts", + match: "\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\\{[0-9A-Fa-f]+\\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)" + }, + template: { + patterns: [ + { + include: "#template-call" + }, + { + name: "string.template.ts", + begin: "([_$[:alpha:]][_$[:alnum:]]*)?(`)", + beginCaptures: { + "1": { + name: "entity.name.function.tagged-template.ts" + }, + "2": { + name: "punctuation.definition.string.template.begin.ts" + } + }, + end: "`", + endCaptures: { + "0": { + name: "punctuation.definition.string.template.end.ts" + } + }, + patterns: [ + { + include: "#template-substitution-element" + }, + { + include: "#string-character-escape" + } + ] + } + ] + }, + "template-call": { + patterns: [ + { + name: "string.template.ts", + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", + end: "(?=`)", + patterns: [ + { + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", + end: "(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", + patterns: [ + { + include: "#support-function-call-identifiers" + }, + { + name: "entity.name.function.tagged-template.ts", + match: "([_$[:alpha:]][_$[:alnum:]]*)" + } + ] + }, + { + include: "#type-arguments" + } + ] + }, + { + name: "string.template.ts", + begin: "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", + beginCaptures: { + "1": { + name: "entity.name.function.tagged-template.ts" + } + }, + end: "(?=`)", + patterns: [ + { + include: "#type-arguments" + } + ] + } + ] + }, + "template-substitution-element": { + name: "meta.template.expression.ts", + begin: "\\$\\{", + beginCaptures: { + "0": { + name: "punctuation.definition.template-expression.begin.ts" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.template-expression.end.ts" + } + }, + patterns: [ + { + include: "#expression" + } + ], + contentName: "meta.embedded.line.ts" + }, + "type-string": { + patterns: [ + { + include: "#qstring-single" + }, + { + include: "#qstring-double" + }, + { + include: "#template-type" + } + ] + }, + "template-type": { + patterns: [ + { + include: "#template-call" + }, + { + name: "string.template.ts", + begin: "([_$[:alpha:]][_$[:alnum:]]*)?(`)", + beginCaptures: { + "1": { + name: "entity.name.function.tagged-template.ts" + }, + "2": { + name: "punctuation.definition.string.template.begin.ts" + } + }, + end: "`", + endCaptures: { + "0": { + name: "punctuation.definition.string.template.end.ts" + } + }, + patterns: [ + { + include: "#template-type-substitution-element" + }, + { + include: "#string-character-escape" + } + ] + } + ] + }, + "template-type-substitution-element": { + name: "meta.template.expression.ts", + begin: "\\$\\{", + beginCaptures: { + "0": { + name: "punctuation.definition.template-expression.begin.ts" + } + }, + end: "\\}", + endCaptures: { + "0": { + name: "punctuation.definition.template-expression.end.ts" + } + }, + patterns: [ + { + include: "#type" + } + ], + contentName: "meta.embedded.line.ts" + }, + regex: { + patterns: [ + { + name: "string.regexp.ts", + begin: "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[\\()]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\]|\\(([^\\)\\\\]|\\\\.)+\\))+\\/([dgimsuy]+|(?![\\/\\*])|(?=\\/\\*))(?!\\s*[a-zA-Z0-9_$]))", + beginCaptures: { + "1": { + name: "punctuation.definition.string.begin.ts" + } + }, + end: "(/)([dgimsuy]*)", + endCaptures: { + "1": { + name: "punctuation.definition.string.end.ts" + }, + "2": { + name: "keyword.other.ts" + } + }, + patterns: [ + { + include: "#regexp" + } + ] + }, + { + name: "string.regexp.ts", + begin: "((?", + captures: { + "0": { + name: "keyword.other.back-reference.regexp" + }, + "1": { + name: "variable.other.regexp" + } + } + }, + { + name: "keyword.operator.quantifier.regexp", + match: "[?+*]|\\{(\\d+,\\d+|\\d+,|,\\d+|\\d+)\\}\\??" + }, + { + name: "keyword.operator.or.regexp", + match: "\\|" + }, + { + name: "meta.group.assertion.regexp", + begin: "(\\()((\\?=)|(\\?!)|(\\?<=)|(\\?))?", + beginCaptures: { + "0": { + name: "punctuation.definition.group.regexp" + }, + "1": { + name: "punctuation.definition.group.no-capture.regexp" + }, + "2": { + name: "variable.other.regexp" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "punctuation.definition.group.regexp" + } + }, + patterns: [ + { + include: "#regexp" + } + ] + }, + { + name: "constant.other.character-class.set.regexp", + begin: "(\\[)(\\^)?", + beginCaptures: { + "1": { + name: "punctuation.definition.character-class.regexp" + }, + "2": { + name: "keyword.operator.negation.regexp" + } + }, + end: "(\\])", + endCaptures: { + "1": { + name: "punctuation.definition.character-class.regexp" + } + }, + patterns: [ + { + name: "constant.other.character-class.range.regexp", + match: "(?:.|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))\\-(?:[^\\]\\\\]|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))", + captures: { + "1": { + name: "constant.character.numeric.regexp" + }, + "2": { + name: "constant.character.control.regexp" + }, + "3": { + name: "constant.character.escape.backslash.regexp" + }, + "4": { + name: "constant.character.numeric.regexp" + }, + "5": { + name: "constant.character.control.regexp" + }, + "6": { + name: "constant.character.escape.backslash.regexp" + } + } + }, + { + include: "#regex-character-class" + } + ] + }, + { + include: "#regex-character-class" + } + ] + }, + "regex-character-class": { + patterns: [ + { + name: "constant.other.character-class.regexp", + match: "\\\\[wWsSdDtrnvf]|\\." + }, + { + name: "constant.character.numeric.regexp", + match: "\\\\([0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4})" + }, + { + name: "constant.character.control.regexp", + match: "\\\\c[A-Z]" + }, + { + name: "constant.character.escape.backslash.regexp", + match: "\\\\." + } + ] + }, + comment: { + patterns: [ + { + name: "comment.block.documentation.ts", + begin: "/\\*\\*(?!/)", + beginCaptures: { + "0": { + name: "punctuation.definition.comment.ts" + } + }, + end: "\\*/", + endCaptures: { + "0": { + name: "punctuation.definition.comment.ts" + } + }, + patterns: [ + { + include: "#docblock" + } + ] + }, + { + name: "comment.block.ts", + begin: "(/\\*)(?:\\s*((@)internal)(?=\\s|(\\*/)))?", + beginCaptures: { + "1": { + name: "punctuation.definition.comment.ts" + }, + "2": { + name: "storage.type.internaldeclaration.ts" + }, + "3": { + name: "punctuation.decorator.internaldeclaration.ts" + } + }, + end: "\\*/", + endCaptures: { + "0": { + name: "punctuation.definition.comment.ts" + } + } + }, + { + begin: "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + beginCaptures: { + "1": { + name: "punctuation.whitespace.comment.leading.ts" + }, + "2": { + name: "comment.line.double-slash.ts" + }, + "3": { + name: "punctuation.definition.comment.ts" + }, + "4": { + name: "storage.type.internaldeclaration.ts" + }, + "5": { + name: "punctuation.decorator.internaldeclaration.ts" + } + }, + end: "(?=$)", + contentName: "comment.line.double-slash.ts" + } + ] + }, + "single-line-comment-consuming-line-ending": { + begin: "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + beginCaptures: { + "1": { + name: "punctuation.whitespace.comment.leading.ts" + }, + "2": { + name: "comment.line.double-slash.ts" + }, + "3": { + name: "punctuation.definition.comment.ts" + }, + "4": { + name: "storage.type.internaldeclaration.ts" + }, + "5": { + name: "punctuation.decorator.internaldeclaration.ts" + } + }, + end: "(?=^)", + contentName: "comment.line.double-slash.ts" + }, + directives: { + name: "comment.line.triple-slash.directive.ts", + begin: "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", + beginCaptures: { + "1": { + name: "punctuation.definition.comment.ts" + } + }, + end: "(?=$)", + patterns: [ + { + name: "meta.tag.ts", + begin: "(<)(reference|amd-dependency|amd-module)", + beginCaptures: { + "1": { + name: "punctuation.definition.tag.directive.ts" + }, + "2": { + name: "entity.name.tag.directive.ts" + } + }, + end: "/>", + endCaptures: { + "0": { + name: "punctuation.definition.tag.directive.ts" + } + }, + patterns: [ + { + name: "entity.other.attribute-name.directive.ts", + match: "path|types|no-default-lib|lib|name" + }, + { + name: "keyword.operator.assignment.ts", + match: "=" + }, + { + include: "#string" + } + ] + } + ] + }, + docblock: { + patterns: [ + { + match: "(?x)\n((@)(?:access|api))\n\\s+\n(private|protected|public)\n\\b", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "constant.language.access-type.jsdoc" + } + } + }, + { + match: "(?x)\n((@)author)\n\\s+\n(\n [^@\\s<>*/]\n (?:[^@<>*/]|\\*[^/])*\n)\n(?:\n \\s*\n (<)\n ([^>\\s]+)\n (>)\n)?", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "entity.name.type.instance.jsdoc" + }, + "4": { + name: "punctuation.definition.bracket.angle.begin.jsdoc" + }, + "5": { + name: "constant.other.email.link.underline.jsdoc" + }, + "6": { + name: "punctuation.definition.bracket.angle.end.jsdoc" + } + } + }, + { + match: "(?x)\n((@)borrows) \\s+\n((?:[^@\\s*/]|\\*[^/])+) # \n\\s+ (as) \\s+ # as\n((?:[^@\\s*/]|\\*[^/])+) # ", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "entity.name.type.instance.jsdoc" + }, + "4": { + name: "keyword.operator.control.jsdoc" + }, + "5": { + name: "entity.name.type.instance.jsdoc" + } + } + }, + { + name: "meta.example.jsdoc", + begin: "((@)example)\\s+", + end: "(?=@|\\*/)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + patterns: [ + { + match: "^\\s\\*\\s+" + }, + { + contentName: "constant.other.description.jsdoc", + begin: "\\G(<)caption(>)", + beginCaptures: { + "0": { + name: "entity.name.tag.inline.jsdoc" + }, + "1": { + name: "punctuation.definition.bracket.angle.begin.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.angle.end.jsdoc" + } + }, + end: "()|(?=\\*/)", + endCaptures: { + "0": { + name: "entity.name.tag.inline.jsdoc" + }, + "1": { + name: "punctuation.definition.bracket.angle.begin.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.angle.end.jsdoc" + } + } + }, + { + match: "[^\\s@*](?:[^*]|\\*[^/])*", + captures: { + "0": { + name: "source.embedded.ts" + } + } + } + ] + }, + { + match: "(?x) ((@)kind) \\s+ (class|constant|event|external|file|function|member|mixin|module|namespace|typedef) \\b", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "constant.language.symbol-type.jsdoc" + } + } + }, + { + match: "(?x)\n((@)see)\n\\s+\n(?:\n # URL\n (\n (?=https?://)\n (?:[^\\s*]|\\*[^/])+\n )\n |\n # JSDoc namepath\n (\n (?!\n # Avoid matching bare URIs (also acceptable as links)\n https?://\n |\n # Avoid matching {@inline tags}; we match those below\n (?:\\[[^\\[\\]]*\\])? # Possible description [preceding]{@tag}\n {@(?:link|linkcode|linkplain|tutorial)\\b\n )\n # Matched namepath\n (?:[^@\\s*/]|\\*[^/])+\n )\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.link.underline.jsdoc" + }, + "4": { + name: "entity.name.type.instance.jsdoc" + } + } + }, + { + match: "(?x)\n((@)template)\n\\s+\n# One or more valid identifiers\n(\n [A-Za-z_$] # First character: non-numeric word character\n [\\w$.\\[\\]]* # Rest of identifier\n (?: # Possible list of additional identifiers\n \\s* , \\s*\n [A-Za-z_$]\n [\\w$.\\[\\]]*\n )*\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + } + } + }, + { + begin: "(?x)((@)template)\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + }, + { + name: "variable.other.jsdoc", + match: "([A-Za-z_$][\\w$.\\[\\]]*)" + } + ] + }, + { + match: "(?x)\n(\n (@)\n (?:arg|argument|const|constant|member|namespace|param|var)\n)\n\\s+\n(\n [A-Za-z_$]\n [\\w$.\\[\\]]*\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + } + } + }, + { + begin: "((@)typedef)\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + }, + { + name: "entity.name.type.instance.jsdoc", + match: "(?:[^@\\s*/]|\\*[^/])+" + } + ] + }, + { + begin: "((@)(?:arg|argument|const|constant|member|namespace|param|prop|property|var))\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + }, + { + name: "variable.other.jsdoc", + match: "([A-Za-z_$][\\w$.\\[\\]]*)" + }, + { + name: "variable.other.jsdoc", + match: `(?x) +(\\[)\\s* +[\\w$]+ +(?: + (?:\\[\\])? # Foo[ ].bar properties within an array + \\. # Foo.Bar namespaced parameter + [\\w$]+ +)* +(?: + \\s* + (=) # [foo=bar] Default parameter value + \\s* + ( + # The inner regexes are to stop the match early at */ and to not stop at escaped quotes + (?> + "(?:(?:\\*(?!/))|(?:\\\\(?!"))|[^*\\\\])*?" | # [foo="bar"] Double-quoted + '(?:(?:\\*(?!/))|(?:\\\\(?!'))|[^*\\\\])*?' | # [foo='bar'] Single-quoted + \\[ (?:(?:\\*(?!/))|[^*])*? \\] | # [foo=[1,2]] Array literal + (?:(?:\\*(?!/))|\\s(?!\\s*\\])|\\[.*?(?:\\]|(?=\\*/))|[^*\\s\\[\\]])* # Everything else + )* + ) +)? +\\s*(?:(\\])((?:[^*\\s]|\\*[^\\s/])+)?|(?=\\*/))`, + captures: { + "1": { + name: "punctuation.definition.optional-value.begin.bracket.square.jsdoc" + }, + "2": { + name: "keyword.operator.assignment.jsdoc" + }, + "3": { + name: "source.embedded.ts" + }, + "4": { + name: "punctuation.definition.optional-value.end.bracket.square.jsdoc" + }, + "5": { + name: "invalid.illegal.syntax.jsdoc" + } + } + } + ] + }, + { + begin: "(?x)\n(\n (@)\n (?:define|enum|exception|export|extends|lends|implements|modifies\n |namespace|private|protected|returns?|suppress|this|throws|type\n |yields?)\n)\n\\s+(?={)", + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + }, + end: "(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])", + patterns: [ + { + include: "#jsdoctype" + } + ] + }, + { + match: "(?x)\n(\n (@)\n (?:alias|augments|callback|constructs|emits|event|fires|exports?\n |extends|external|function|func|host|lends|listens|interface|memberof!?\n |method|module|mixes|mixin|name|requires|see|this|typedef|uses)\n)\n\\s+\n(\n (?:\n [^{}@\\s*] | \\*[^/]\n )+\n)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "entity.name.type.instance.jsdoc" + } + } + }, + { + contentName: "variable.other.jsdoc", + begin: `((@)(?:default(?:value)?|license|version))\\s+(([''"]))`, + beginCaptures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + }, + "4": { + name: "punctuation.definition.string.begin.jsdoc" + } + }, + end: "(\\3)|(?=$|\\*/)", + endCaptures: { + "0": { + name: "variable.other.jsdoc" + }, + "1": { + name: "punctuation.definition.string.end.jsdoc" + } + } + }, + { + match: "((@)(?:default(?:value)?|license|tutorial|variation|version))\\s+([^\\s*]+)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + }, + "3": { + name: "variable.other.jsdoc" + } + } + }, + { + name: "storage.type.class.jsdoc", + match: "(?x) (@) (?:abstract|access|alias|api|arg|argument|async|attribute|augments|author|beta|borrows|bubbles |callback|chainable|class|classdesc|code|config|const|constant|constructor|constructs|copyright |default|defaultvalue|define|deprecated|desc|description|dict|emits|enum|event|example|exception |exports?|extends|extension(?:_?for)?|external|externs|file|fileoverview|final|fires|for|func |function|generator|global|hideconstructor|host|ignore|implements|implicitCast|inherit[Dd]oc |inner|instance|interface|internal|kind|lends|license|listens|main|member|memberof!?|method |mixes|mixins?|modifies|module|name|namespace|noalias|nocollapse|nocompile|nosideeffects |override|overview|package|param|polymer(?:Behavior)?|preserve|private|prop|property|protected |public|read[Oo]nly|record|require[ds]|returns?|see|since|static|struct|submodule|summary |suppress|template|this|throws|todo|tutorial|type|typedef|unrestricted|uses|var|variation |version|virtual|writeOnce|yields?) \\b", + captures: { + "1": { + name: "punctuation.definition.block.tag.jsdoc" + } + } + }, + { + include: "#inline-tags" + }, + { + match: "((@)(?:[_$[:alpha:]][_$[:alnum:]]*))(?=\\s+)", + captures: { + "1": { + name: "storage.type.class.jsdoc" + }, + "2": { + name: "punctuation.definition.block.tag.jsdoc" + } + } + } + ] + }, + brackets: { + patterns: [ + { + begin: "{", + end: "}|(?=\\*/)", + patterns: [ + { + include: "#brackets" + } + ] + }, + { + begin: "\\[", + end: "\\]|(?=\\*/)", + patterns: [ + { + include: "#brackets" + } + ] + } + ] + }, + "inline-tags": { + patterns: [ + { + name: "constant.other.description.jsdoc", + match: "(\\[)[^\\]]+(\\])(?={@(?:link|linkcode|linkplain|tutorial))", + captures: { + "1": { + name: "punctuation.definition.bracket.square.begin.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.square.end.jsdoc" + } + } + }, + { + name: "entity.name.type.instance.jsdoc", + begin: "({)((@)(?:link(?:code|plain)?|tutorial))\\s*", + beginCaptures: { + "1": { + name: "punctuation.definition.bracket.curly.begin.jsdoc" + }, + "2": { + name: "storage.type.class.jsdoc" + }, + "3": { + name: "punctuation.definition.inline.tag.jsdoc" + } + }, + end: "}|(?=\\*/)", + endCaptures: { + "0": { + name: "punctuation.definition.bracket.curly.end.jsdoc" + } + }, + patterns: [ + { + match: "\\G((?=https?://)(?:[^|}\\s*]|\\*[/])+)(\\|)?", + captures: { + "1": { + name: "variable.other.link.underline.jsdoc" + }, + "2": { + name: "punctuation.separator.pipe.jsdoc" + } + } + }, + { + match: "\\G((?:[^{}@\\s|*]|\\*[^/])+)(\\|)?", + captures: { + "1": { + name: "variable.other.description.jsdoc" + }, + "2": { + name: "punctuation.separator.pipe.jsdoc" + } + } + } + ] + } + ] + }, + jsdoctype: { + patterns: [ + { + contentName: "entity.name.type.instance.jsdoc", + begin: "\\G({)", + beginCaptures: { + "0": { + name: "entity.name.type.instance.jsdoc" + }, + "1": { + name: "punctuation.definition.bracket.curly.begin.jsdoc" + } + }, + end: "((}))\\s*|(?=\\*/)", + endCaptures: { + "1": { + name: "entity.name.type.instance.jsdoc" + }, + "2": { + name: "punctuation.definition.bracket.curly.end.jsdoc" + } + }, + patterns: [ + { + include: "#brackets" + } + ] + } + ] + } +}; +const TypeScript_tmLanguage = { + information_for_contributors, + version, + name, + scopeName, + patterns, + repository +}; + +export { TypeScript_tmLanguage as default, information_for_contributors, name, patterns, repository, scopeName, version }; diff --git a/js/chunks/_commonjsHelpers-24198af3.js b/js/chunks/_commonjsHelpers-24198af3.js new file mode 100644 index 0000000..85dd4f2 --- /dev/null +++ b/js/chunks/_commonjsHelpers-24198af3.js @@ -0,0 +1,35 @@ +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +function getAugmentedNamespace(n) { + if (n.__esModule) return n; + var f = n.default; + if (typeof f == "function") { + var a = function a () { + if (this instanceof a) { + var args = [null]; + args.push.apply(args, arguments); + var Ctor = Function.bind.apply(f, args); + return new Ctor(); + } + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else a = {}; + Object.defineProperty(a, '__esModule', {value: true}); + Object.keys(n).forEach(function (k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function () { + return n[k]; + } + }); + }); + return a; +} + +export { getAugmentedNamespace as a, commonjsGlobal as c, getDefaultExportFromCjs as g }; diff --git a/js/chunks/css.tmLanguage-b56789b8.js b/js/chunks/css.tmLanguage-b56789b8.js new file mode 100644 index 0000000..dec4d9a --- /dev/null +++ b/js/chunks/css.tmLanguage-b56789b8.js @@ -0,0 +1,1875 @@ +const information_for_contributors = [ + "This file has been converted from https://github.com/atom/language-css/blob/master/grammars/css.cson", + "If you want to provide a fix or improvement, please create a pull request against the original repository.", + "Once accepted there, we are happy to receive an update request." +]; +const version = "https://github.com/atom/language-css/commit/672168274c7b457f3c118788b5171ae888c1bf07"; +const name = "CSS"; +const scopeName = "source.css"; +const patterns = [ + { + include: "#comment-block" + }, + { + include: "#escapes" + }, + { + include: "#combinators" + }, + { + include: "#selector" + }, + { + include: "#at-rules" + }, + { + include: "#rule-list" + } +]; +const repository = { + "at-rules": { + patterns: [ + { + begin: "\\A(?:\\xEF\\xBB\\xBF)?(?i:(?=\\s*@charset\\b))", + end: ";|(?=$)", + endCaptures: { + "0": { + name: "punctuation.terminator.rule.css" + } + }, + name: "meta.at-rule.charset.css", + patterns: [ + { + captures: { + "1": { + name: "invalid.illegal.not-lowercase.charset.css" + }, + "2": { + name: "invalid.illegal.leading-whitespace.charset.css" + }, + "3": { + name: "invalid.illegal.no-whitespace.charset.css" + }, + "4": { + name: "invalid.illegal.whitespace.charset.css" + }, + "5": { + name: "invalid.illegal.not-double-quoted.charset.css" + }, + "6": { + name: "invalid.illegal.unclosed-string.charset.css" + }, + "7": { + name: "invalid.illegal.unexpected-characters.charset.css" + } + }, + match: '(?x) # Possible errors:\n\\G\n((?!@charset)@\\w+) # Not lowercase (@charset is case-sensitive)\n|\n\\G(\\s+) # Preceding whitespace\n|\n(@charset\\S[^;]*) # No whitespace after @charset\n|\n(?<=@charset) # Before quoted charset name\n(\\x20{2,}|\\t+) # More than one space used, or a tab\n|\n(?<=@charset\\x20) # Beginning of charset name\n([^";]+) # Not double-quoted\n|\n("[^"]+$) # Unclosed quote\n|\n(?<=") # After charset name\n([^;]+) # Unexpected junk instead of semicolon' + }, + { + captures: { + "1": { + name: "keyword.control.at-rule.charset.css" + }, + "2": { + name: "punctuation.definition.keyword.css" + } + }, + match: "((@)charset)(?=\\s)" + }, + { + begin: '"', + beginCaptures: { + "0": { + name: "punctuation.definition.string.begin.css" + } + }, + end: '"|$', + endCaptures: { + "0": { + name: "punctuation.definition.string.end.css" + } + }, + name: "string.quoted.double.css", + patterns: [ + { + begin: '(?:\\G|^)(?=(?:[^"])+$)', + end: "$", + name: "invalid.illegal.unclosed.string.css" + } + ] + } + ] + }, + { + begin: `(?i)((@)import)(?:\\s+|$|(?=['"]|/\\*))`, + beginCaptures: { + "1": { + name: "keyword.control.at-rule.import.css" + }, + "2": { + name: "punctuation.definition.keyword.css" + } + }, + end: ";", + endCaptures: { + "0": { + name: "punctuation.terminator.rule.css" + } + }, + name: "meta.at-rule.import.css", + patterns: [ + { + begin: "\\G\\s*(?=/\\*)", + end: "(?<=\\*/)\\s*", + patterns: [ + { + include: "#comment-block" + } + ] + }, + { + include: "#string" + }, + { + include: "#url" + }, + { + include: "#media-query-list" + } + ] + }, + { + begin: "(?i)((@)font-face)(?=\\s*|{|/\\*|$)", + beginCaptures: { + "1": { + name: "keyword.control.at-rule.font-face.css" + }, + "2": { + name: "punctuation.definition.keyword.css" + } + }, + end: "(?!\\G)", + name: "meta.at-rule.font-face.css", + patterns: [ + { + include: "#comment-block" + }, + { + include: "#escapes" + }, + { + include: "#rule-list" + } + ] + }, + { + begin: "(?i)(@)page(?=[\\s:{]|/\\*|$)", + captures: { + "0": { + name: "keyword.control.at-rule.page.css" + }, + "1": { + name: "punctuation.definition.keyword.css" + } + }, + end: "(?=\\s*($|[:{;]))", + name: "meta.at-rule.page.css", + patterns: [ + { + include: "#rule-list" + } + ] + }, + { + begin: "(?i)(?=@media(\\s|\\(|/\\*|$))", + end: "(?<=})(?!\\G)", + patterns: [ + { + begin: "(?i)\\G(@)media", + beginCaptures: { + "0": { + name: "keyword.control.at-rule.media.css" + }, + "1": { + name: "punctuation.definition.keyword.css" + } + }, + end: "(?=\\s*[{;])", + name: "meta.at-rule.media.header.css", + patterns: [ + { + include: "#media-query-list" + } + ] + }, + { + begin: "{", + beginCaptures: { + "0": { + name: "punctuation.section.media.begin.bracket.curly.css" + } + }, + end: "}", + endCaptures: { + "0": { + name: "punctuation.section.media.end.bracket.curly.css" + } + }, + name: "meta.at-rule.media.body.css", + patterns: [ + { + include: "$self" + } + ] + } + ] + }, + { + begin: `(?i)(?=@counter-style([\\s'"{;]|/\\*|$))`, + end: "(?<=})(?!\\G)", + patterns: [ + { + begin: "(?i)\\G(@)counter-style", + beginCaptures: { + "0": { + name: "keyword.control.at-rule.counter-style.css" + }, + "1": { + name: "punctuation.definition.keyword.css" + } + }, + end: "(?=\\s*{)", + name: "meta.at-rule.counter-style.header.css", + patterns: [ + { + include: "#comment-block" + }, + { + include: "#escapes" + }, + { + captures: { + "0": { + patterns: [ + { + include: "#escapes" + } + ] + } + }, + match: "(?x)\n(?:[-a-zA-Z_] | [^\\x00-\\x7F]) # First letter\n(?:[-a-zA-Z0-9_] | [^\\x00-\\x7F] # Remainder of identifier\n |\\\\(?:[0-9a-fA-F]{1,6}|.)\n)*", + name: "variable.parameter.style-name.css" + } + ] + }, + { + begin: "{", + beginCaptures: { + "0": { + name: "punctuation.section.property-list.begin.bracket.curly.css" + } + }, + end: "}", + endCaptures: { + "0": { + name: "punctuation.section.property-list.end.bracket.curly.css" + } + }, + name: "meta.at-rule.counter-style.body.css", + patterns: [ + { + include: "#comment-block" + }, + { + include: "#escapes" + }, + { + include: "#rule-list-innards" + } + ] + } + ] + }, + { + begin: `(?i)(?=@document([\\s'"{;]|/\\*|$))`, + end: "(?<=})(?!\\G)", + patterns: [ + { + begin: "(?i)\\G(@)document", + beginCaptures: { + "0": { + name: "keyword.control.at-rule.document.css" + }, + "1": { + name: "punctuation.definition.keyword.css" + } + }, + end: "(?=\\s*[{;])", + name: "meta.at-rule.document.header.css", + patterns: [ + { + begin: "(?i)(?>>", + name: "invalid.deprecated.combinator.css" + }, + { + match: ">>|>|\\+|~", + name: "keyword.operator.combinator.css" + } + ] + }, + commas: { + match: ",", + name: "punctuation.separator.list.comma.css" + }, + "comment-block": { + begin: "/\\*", + beginCaptures: { + "0": { + name: "punctuation.definition.comment.begin.css" + } + }, + end: "\\*/", + endCaptures: { + "0": { + name: "punctuation.definition.comment.end.css" + } + }, + name: "comment.block.css" + }, + escapes: { + patterns: [ + { + match: "\\\\[0-9a-fA-F]{1,6}", + name: "constant.character.escape.codepoint.css" + }, + { + begin: "\\\\$\\s*", + end: "^(?<:=]|\\)|/\\*) # Terminates cleanly" + }, + "media-feature-keywords": { + match: "(?xi)\n(?<=^|\\s|:|\\*/)\n(?: portrait # Orientation\n | landscape\n | progressive # Scan types\n | interlace\n | fullscreen # Display modes\n | standalone\n | minimal-ui\n | browser\n | hover\n)\n(?=\\s|\\)|$)", + name: "support.constant.property-value.css" + }, + "media-query": { + begin: "\\G", + end: "(?=\\s*[{;])", + patterns: [ + { + include: "#comment-block" + }, + { + include: "#escapes" + }, + { + include: "#media-types" + }, + { + match: "(?i)(?<=\\s|^|,|\\*/)(only|not)(?=\\s|{|/\\*|$)", + name: "keyword.operator.logical.$1.media.css" + }, + { + match: "(?i)(?<=\\s|^|\\*/|\\))and(?=\\s|/\\*|$)", + name: "keyword.operator.logical.and.media.css" + }, + { + match: ",(?:(?:\\s*,)+|(?=\\s*[;){]))", + name: "invalid.illegal.comma.css" + }, + { + include: "#commas" + }, + { + begin: "\\(", + beginCaptures: { + "0": { + name: "punctuation.definition.parameters.begin.bracket.round.css" + } + }, + end: "\\)", + endCaptures: { + "0": { + name: "punctuation.definition.parameters.end.bracket.round.css" + } + }, + patterns: [ + { + include: "#media-features" + }, + { + include: "#media-feature-keywords" + }, + { + match: ":", + name: "punctuation.separator.key-value.css" + }, + { + match: ">=|<=|=|<|>", + name: "keyword.operator.comparison.css" + }, + { + captures: { + "1": { + name: "constant.numeric.css" + }, + "2": { + name: "keyword.operator.arithmetic.css" + }, + "3": { + name: "constant.numeric.css" + } + }, + match: "(\\d+)\\s*(/)\\s*(\\d+)", + name: "meta.ratio.css" + }, + { + include: "#numeric-values" + }, + { + include: "#comment-block" + } + ] + } + ] + }, + "media-query-list": { + begin: "(?=\\s*[^{;])", + end: "(?=\\s*[{;])", + patterns: [ + { + include: "#media-query" + } + ] + }, + "media-types": { + captures: { + "1": { + name: "support.constant.media.css" + }, + "2": { + name: "invalid.deprecated.constant.media.css" + } + }, + match: "(?xi)\n(?<=^|\\s|,|\\*/)\n(?:\n # Valid media types\n (all|print|screen|speech)\n |\n # Deprecated in Media Queries 4: http://dev.w3.org/csswg/mediaqueries/#media-types\n (aural|braille|embossed|handheld|projection|tty|tv)\n)\n(?=$|[{,\\s;]|/\\*)" + }, + "numeric-values": { + patterns: [ + { + captures: { + "1": { + name: "punctuation.definition.constant.css" + } + }, + match: "(#)(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\\b", + name: "constant.other.color.rgb-value.hex.css" + }, + { + captures: { + "1": { + name: "keyword.other.unit.percentage.css" + }, + "2": { + name: "keyword.other.unit.${2:/downcase}.css" + } + }, + match: "(?xi) (?+~|] # - Followed by another selector\n | /\\* # - Followed by a block comment\n )\n |\n # Name contains unescaped ASCII symbol\n (?: # Check for acceptable preceding characters\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # - Valid selector character\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # - Escape sequence\n )*\n (?: # Invalid punctuation\n [!\"'%&(*;+~|] # - Another selector\n | /\\* # - A block comment\n)", + name: "entity.other.attribute-name.class.css" + }, + { + captures: { + "1": { + name: "punctuation.definition.entity.css" + }, + "2": { + patterns: [ + { + include: "#escapes" + } + ] + } + }, + match: "(?x)\n(\\#)\n(\n -?\n (?![0-9])\n (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n)\n(?=$|[\\s,.\\#)\\[:{>+~|]|/\\*)", + name: "entity.other.attribute-name.id.css" + }, + { + begin: "\\[", + beginCaptures: { + "0": { + name: "punctuation.definition.entity.begin.bracket.square.css" + } + }, + end: "\\]", + endCaptures: { + "0": { + name: "punctuation.definition.entity.end.bracket.square.css" + } + }, + name: "meta.attribute-selector.css", + patterns: [ + { + include: "#comment-block" + }, + { + include: "#string" + }, + { + captures: { + "1": { + name: "storage.modifier.ignore-case.css" + } + }, + match: `(?<=["'\\s]|^|\\*/)\\s*([iI])\\s*(?=[\\s\\]]|/\\*|$)` + }, + { + captures: { + "1": { + name: "string.unquoted.attribute-value.css", + patterns: [ + { + include: "#escapes" + } + ] + } + }, + match: `(?x)(?<==)\\s*((?!/\\*)(?:[^\\\\"'\\s\\]]|\\\\.)+)` + }, + { + include: "#escapes" + }, + { + match: "[~|^$*]?=", + name: "keyword.operator.pattern.css" + }, + { + match: "\\|", + name: "punctuation.separator.css" + }, + { + captures: { + "1": { + name: "entity.other.namespace-prefix.css", + patterns: [ + { + include: "#escapes" + } + ] + } + }, + match: "(?x)\n# Qualified namespace prefix\n( -?(?!\\d)(?:[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n| \\*\n)\n# Lookahead to ensure there's a valid identifier ahead\n(?=\n \\| (?!\\s|=|$|\\])\n (?: -?(?!\\d)\n | [\\\\\\w-]\n | [^\\x00-\\x7F]\n )\n)" + }, + { + captures: { + "1": { + name: "entity.other.attribute-name.css", + patterns: [ + { + include: "#escapes" + } + ] + } + }, + match: "(?x)\n(-?(?!\\d)(?>[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+)\n\\s*\n(?=[~|^\\]$*=]|/\\*)" + } + ] + }, + { + include: "#pseudo-classes" + }, + { + include: "#pseudo-elements" + }, + { + include: "#functional-pseudo-classes" + }, + { + match: "(?x) (?\\s,.\\#|){:\\[]|/\\*|$)", + name: "entity.name.tag.css" + }, + "unicode-range": { + captures: { + "0": { + name: "constant.other.unicode-range.css" + }, + "1": { + name: "punctuation.separator.dash.unicode-range.css" + } + }, + match: "(?= 0); +function _format$2(message, args) { + let result; + if (args.length === 0) { + result = message; + } + else { + result = message.replace(/\{(\d+)\}/g, (match, rest) => { + const index = rest[0]; + const arg = args[index]; + let result = match; + if (typeof arg === 'string') { + result = arg; + } + else if (typeof arg === 'number' || typeof arg === 'boolean' || arg === void 0 || arg === null) { + result = String(arg); + } + return result; + }); + } + if (isPseudo) { + // FF3B and FF3D is the Unicode zenkaku representation for [ and ] + result = '\uFF3B' + result.replace(/[aouei]/g, '$&$&') + '\uFF3D'; + } + return result; +} +function localize$2(data, message, ...args) { + return _format$2(message, args); +} +function getConfiguredDefaultLocale(_) { + // This returns undefined because this implementation isn't used and is overwritten by the loader + // when loaded. + return undefined; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Avoid circular dependency on EventEmitter by implementing a subset of the interface. +class ErrorHandler { + constructor() { + this.listeners = []; + this.unexpectedErrorHandler = function (e) { + setTimeout(() => { + if (e.stack) { + if (ErrorNoTelemetry.isErrorNoTelemetry(e)) { + throw new ErrorNoTelemetry(e.message + '\n\n' + e.stack); + } + throw new Error(e.message + '\n\n' + e.stack); + } + throw e; + }, 0); + }; + } + emit(e) { + this.listeners.forEach((listener) => { + listener(e); + }); + } + onUnexpectedError(e) { + this.unexpectedErrorHandler(e); + this.emit(e); + } + // For external errors, we don't want the listeners to be called + onUnexpectedExternalError(e) { + this.unexpectedErrorHandler(e); + } +} +const errorHandler = new ErrorHandler(); +function onUnexpectedError(e) { + // ignore errors from cancelled promises + if (!isCancellationError(e)) { + errorHandler.onUnexpectedError(e); + } + return undefined; +} +function onUnexpectedExternalError(e) { + // ignore errors from cancelled promises + if (!isCancellationError(e)) { + errorHandler.onUnexpectedExternalError(e); + } + return undefined; +} +function transformErrorForSerialization(error) { + if (error instanceof Error) { + const { name, message } = error; + const stack = error.stacktrace || error.stack; + return { + $isError: true, + name, + message, + stack, + noTelemetry: ErrorNoTelemetry.isErrorNoTelemetry(error) + }; + } + // return as is + return error; +} +const canceledName = 'Canceled'; +/** + * Checks if the given error is a promise in canceled state + */ +function isCancellationError(error) { + if (error instanceof CancellationError) { + return true; + } + return error instanceof Error && error.name === canceledName && error.message === canceledName; +} +// !!!IMPORTANT!!! +// Do NOT change this class because it is also used as an API-type. +class CancellationError extends Error { + constructor() { + super(canceledName); + this.name = this.message; + } +} +/** + * @deprecated use {@link CancellationError `new CancellationError()`} instead + */ +function canceled() { + const error = new Error(canceledName); + error.name = error.message; + return error; +} +function illegalArgument(name) { + if (name) { + return new Error(`Illegal argument: ${name}`); + } + else { + return new Error('Illegal argument'); + } +} +function illegalState(name) { + if (name) { + return new Error(`Illegal state: ${name}`); + } + else { + return new Error('Illegal state'); + } +} +class NotSupportedError extends Error { + constructor(message) { + super('NotSupported'); + if (message) { + this.message = message; + } + } +} +/** + * Error that when thrown won't be logged in telemetry as an unhandled error. + */ +class ErrorNoTelemetry extends Error { + constructor(msg) { + super(msg); + this.name = 'CodeExpectedError'; + } + static fromError(err) { + if (err instanceof ErrorNoTelemetry) { + return err; + } + const result = new ErrorNoTelemetry(); + result.message = err.message; + result.stack = err.stack; + return result; + } + static isErrorNoTelemetry(err) { + return err.name === 'CodeExpectedError'; + } +} +/** + * This error indicates a bug. + * Do not throw this for invalid user input. + * Only catch this error to recover gracefully from bugs. + */ +class BugIndicatingError extends Error { + constructor(message) { + super(message || 'An unexpected bug occurred.'); + Object.setPrototypeOf(this, BugIndicatingError.prototype); + // Because we know for sure only buggy code throws this, + // we definitely want to break here and fix the bug. + // eslint-disable-next-line no-debugger + debugger; + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +function once$1(fn) { + const _this = this; + let didCall = false; + let result; + return function () { + if (didCall) { + return result; + } + didCall = true; + result = fn.apply(_this, arguments); + return result; + }; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +var Iterable; +(function (Iterable) { + function is(thing) { + return thing && typeof thing === 'object' && typeof thing[Symbol.iterator] === 'function'; + } + Iterable.is = is; + const _empty = Object.freeze([]); + function empty() { + return _empty; + } + Iterable.empty = empty; + function* single(element) { + yield element; + } + Iterable.single = single; + function wrap(iterableOrElement) { + if (is(iterableOrElement)) { + return iterableOrElement; + } + else { + return single(iterableOrElement); + } + } + Iterable.wrap = wrap; + function from(iterable) { + return iterable || _empty; + } + Iterable.from = from; + function isEmpty(iterable) { + return !iterable || iterable[Symbol.iterator]().next().done === true; + } + Iterable.isEmpty = isEmpty; + function first(iterable) { + return iterable[Symbol.iterator]().next().value; + } + Iterable.first = first; + function some(iterable, predicate) { + for (const element of iterable) { + if (predicate(element)) { + return true; + } + } + return false; + } + Iterable.some = some; + function find(iterable, predicate) { + for (const element of iterable) { + if (predicate(element)) { + return element; + } + } + return undefined; + } + Iterable.find = find; + function* filter(iterable, predicate) { + for (const element of iterable) { + if (predicate(element)) { + yield element; + } + } + } + Iterable.filter = filter; + function* map(iterable, fn) { + let index = 0; + for (const element of iterable) { + yield fn(element, index++); + } + } + Iterable.map = map; + function* concat(...iterables) { + for (const iterable of iterables) { + for (const element of iterable) { + yield element; + } + } + } + Iterable.concat = concat; + function reduce(iterable, reducer, initialValue) { + let value = initialValue; + for (const element of iterable) { + value = reducer(value, element); + } + return value; + } + Iterable.reduce = reduce; + /** + * Returns an iterable slice of the array, with the same semantics as `array.slice()`. + */ + function* slice(arr, from, to = arr.length) { + if (from < 0) { + from += arr.length; + } + if (to < 0) { + to += arr.length; + } + else if (to > arr.length) { + to = arr.length; + } + for (; from < to; from++) { + yield arr[from]; + } + } + Iterable.slice = slice; + /** + * Consumes `atMost` elements from iterable and returns the consumed elements, + * and an iterable for the rest of the elements. + */ + function consume(iterable, atMost = Number.POSITIVE_INFINITY) { + const consumed = []; + if (atMost === 0) { + return [consumed, iterable]; + } + const iterator = iterable[Symbol.iterator](); + for (let i = 0; i < atMost; i++) { + const next = iterator.next(); + if (next.done) { + return [consumed, Iterable.empty()]; + } + consumed.push(next.value); + } + return [consumed, { [Symbol.iterator]() { return iterator; } }]; + } + Iterable.consume = consume; +})(Iterable || (Iterable = {})); + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +function trackDisposable(x) { + return x; +} +function setParentOfDisposable(child, parent) { +} +/** + * Indicates that the given object is a singleton which does not need to be disposed. +*/ +function markAsSingleton(singleton) { + return singleton; +} +/** + * Check if `thing` is {@link IDisposable disposable}. + */ +function isDisposable(thing) { + return typeof thing.dispose === 'function' && thing.dispose.length === 0; +} +function dispose(arg) { + if (Iterable.is(arg)) { + const errors = []; + for (const d of arg) { + if (d) { + try { + d.dispose(); + } + catch (e) { + errors.push(e); + } + } + } + if (errors.length === 1) { + throw errors[0]; + } + else if (errors.length > 1) { + throw new AggregateError(errors, 'Encountered errors while disposing of store'); + } + return Array.isArray(arg) ? [] : arg; + } + else if (arg) { + arg.dispose(); + return arg; + } +} +/** + * Combine multiple disposable values into a single {@link IDisposable}. + */ +function combinedDisposable(...disposables) { + const parent = toDisposable(() => dispose(disposables)); + return parent; +} +/** + * Turn a function that implements dispose into an {@link IDisposable}. + */ +function toDisposable(fn) { + const self = trackDisposable({ + dispose: once$1(() => { + fn(); + }) + }); + return self; +} +/** + * Manages a collection of disposable values. + * + * This is the preferred way to manage multiple disposables. A `DisposableStore` is safer to work with than an + * `IDisposable[]` as it considers edge cases, such as registering the same value multiple times or adding an item to a + * store that has already been disposed of. + */ +class DisposableStore { + constructor() { + this._toDispose = new Set(); + this._isDisposed = false; + } + /** + * Dispose of all registered disposables and mark this object as disposed. + * + * Any future disposables added to this object will be disposed of on `add`. + */ + dispose() { + if (this._isDisposed) { + return; + } + this._isDisposed = true; + this.clear(); + } + /** + * @return `true` if this object has been disposed of. + */ + get isDisposed() { + return this._isDisposed; + } + /** + * Dispose of all registered disposables but do not mark this object as disposed. + */ + clear() { + if (this._toDispose.size === 0) { + return; + } + try { + dispose(this._toDispose); + } + finally { + this._toDispose.clear(); + } + } + /** + * Add a new {@link IDisposable disposable} to the collection. + */ + add(o) { + if (!o) { + return o; + } + if (o === this) { + throw new Error('Cannot register a disposable on itself!'); + } + if (this._isDisposed) { + if (!DisposableStore.DISABLE_DISPOSED_WARNING) { + console.warn(new Error('Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!').stack); + } + } + else { + this._toDispose.add(o); + } + return o; + } +} +DisposableStore.DISABLE_DISPOSED_WARNING = false; +/** + * Abstract base class for a {@link IDisposable disposable} object. + * + * Subclasses can {@linkcode _register} disposables that will be automatically cleaned up when this object is disposed of. + */ +class Disposable { + constructor() { + this._store = new DisposableStore(); + setParentOfDisposable(this._store); + } + dispose() { + this._store.dispose(); + } + /** + * Adds `o` to the collection of disposables managed by this object. + */ + _register(o) { + if (o === this) { + throw new Error('Cannot register a disposable on itself!'); + } + return this._store.add(o); + } +} +/** + * A disposable that does nothing when it is disposed of. + * + * TODO: This should not be a static property. + */ +Disposable.None = Object.freeze({ dispose() { } }); +/** + * Manages the lifecycle of a disposable value that may be changed. + * + * This ensures that when the disposable value is changed, the previously held disposable is disposed of. You can + * also register a `MutableDisposable` on a `Disposable` to ensure it is automatically cleaned up. + */ +class MutableDisposable { + constructor() { + this._isDisposed = false; + } + get value() { + return this._isDisposed ? undefined : this._value; + } + set value(value) { + var _a; + if (this._isDisposed || value === this._value) { + return; + } + (_a = this._value) === null || _a === void 0 ? void 0 : _a.dispose(); + this._value = value; + } + /** + * Resets the stored value and disposed of the previously stored value. + */ + clear() { + this.value = undefined; + } + dispose() { + var _a; + this._isDisposed = true; + (_a = this._value) === null || _a === void 0 ? void 0 : _a.dispose(); + this._value = undefined; + } +} +class RefCountedDisposable { + constructor(_disposable) { + this._disposable = _disposable; + this._counter = 1; + } + acquire() { + this._counter++; + return this; + } + release() { + if (--this._counter === 0) { + this._disposable.dispose(); + } + return this; + } +} +/** + * A safe disposable can be `unset` so that a leaked reference (listener) + * can be cut-off. + */ +class SafeDisposable { + constructor() { + this.dispose = () => { }; + this.unset = () => { }; + this.isset = () => false; + } + set(fn) { + let callback = fn; + this.unset = () => callback = undefined; + this.isset = () => callback !== undefined; + this.dispose = () => { + if (callback) { + callback(); + callback = undefined; + } + }; + return this; + } +} +class ImmortalReference { + constructor(object) { + this.object = object; + } + dispose() { } +} +/** + * A map the manages the lifecycle of the values that it stores. + */ +class DisposableMap { + constructor() { + this._store = new Map(); + this._isDisposed = false; + } + /** + * Disposes of all stored values and mark this object as disposed. + * + * Trying to use this object after it has been disposed of is an error. + */ + dispose() { + this._isDisposed = true; + this.clearAndDisposeAll(); + } + /** + * Disposes of all stored values and clear the map, but DO NOT mark this object as disposed. + */ + clearAndDisposeAll() { + if (!this._store.size) { + return; + } + try { + dispose(this._store.values()); + } + finally { + this._store.clear(); + } + } + get(key) { + return this._store.get(key); + } + set(key, value, skipDisposeOnOverwrite = false) { + var _a; + if (this._isDisposed) { + console.warn(new Error('Trying to add a disposable to a DisposableMap that has already been disposed of. The added object will be leaked!').stack); + } + if (!skipDisposeOnOverwrite) { + (_a = this._store.get(key)) === null || _a === void 0 ? void 0 : _a.dispose(); + } + this._store.set(key, value); + } + /** + * Delete the value stored for `key` from this map and also dispose of it. + */ + deleteAndDispose(key) { + var _a; + (_a = this._store.get(key)) === null || _a === void 0 ? void 0 : _a.dispose(); + this._store.delete(key); + } + [Symbol.iterator]() { + return this._store[Symbol.iterator](); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +let Node$4 = class Node { + constructor(element) { + this.element = element; + this.next = Node.Undefined; + this.prev = Node.Undefined; + } +}; +Node$4.Undefined = new Node$4(undefined); +class LinkedList { + constructor() { + this._first = Node$4.Undefined; + this._last = Node$4.Undefined; + this._size = 0; + } + get size() { + return this._size; + } + isEmpty() { + return this._first === Node$4.Undefined; + } + clear() { + let node = this._first; + while (node !== Node$4.Undefined) { + const next = node.next; + node.prev = Node$4.Undefined; + node.next = Node$4.Undefined; + node = next; + } + this._first = Node$4.Undefined; + this._last = Node$4.Undefined; + this._size = 0; + } + unshift(element) { + return this._insert(element, false); + } + push(element) { + return this._insert(element, true); + } + _insert(element, atTheEnd) { + const newNode = new Node$4(element); + if (this._first === Node$4.Undefined) { + this._first = newNode; + this._last = newNode; + } + else if (atTheEnd) { + // push + const oldLast = this._last; + this._last = newNode; + newNode.prev = oldLast; + oldLast.next = newNode; + } + else { + // unshift + const oldFirst = this._first; + this._first = newNode; + newNode.next = oldFirst; + oldFirst.prev = newNode; + } + this._size += 1; + let didRemove = false; + return () => { + if (!didRemove) { + didRemove = true; + this._remove(newNode); + } + }; + } + shift() { + if (this._first === Node$4.Undefined) { + return undefined; + } + else { + const res = this._first.element; + this._remove(this._first); + return res; + } + } + pop() { + if (this._last === Node$4.Undefined) { + return undefined; + } + else { + const res = this._last.element; + this._remove(this._last); + return res; + } + } + _remove(node) { + if (node.prev !== Node$4.Undefined && node.next !== Node$4.Undefined) { + // middle + const anchor = node.prev; + anchor.next = node.next; + node.next.prev = anchor; + } + else if (node.prev === Node$4.Undefined && node.next === Node$4.Undefined) { + // only node + this._first = Node$4.Undefined; + this._last = Node$4.Undefined; + } + else if (node.next === Node$4.Undefined) { + // last + this._last = this._last.prev; + this._last.next = Node$4.Undefined; + } + else if (node.prev === Node$4.Undefined) { + // first + this._first = this._first.next; + this._first.prev = Node$4.Undefined; + } + // done + this._size -= 1; + } + *[Symbol.iterator]() { + let node = this._first; + while (node !== Node$4.Undefined) { + yield node.element; + node = node.next; + } + } +} + +var _a$d; +const LANGUAGE_DEFAULT = 'en'; +let _isWindows = false; +let _isMacintosh = false; +let _isLinux = false; +let _isNative = false; +let _isWeb = false; +let _isIOS = false; +let _isMobile = false; +let _locale = undefined; +let _language = LANGUAGE_DEFAULT; +let _platformLocale = LANGUAGE_DEFAULT; +let _translationsConfigFile = undefined; +let _userAgent = undefined; +/** + * @deprecated use `globalThis` instead + */ +const globals = (typeof self === 'object' ? self : typeof global === 'object' ? global : {}); +let nodeProcess = undefined; +if (typeof globals.vscode !== 'undefined' && typeof globals.vscode.process !== 'undefined') { + // Native environment (sandboxed) + nodeProcess = globals.vscode.process; +} +else if (typeof process !== 'undefined') { + // Native environment (non-sandboxed) + nodeProcess = process; +} +const isElectronProcess = typeof ((_a$d = nodeProcess === null || nodeProcess === void 0 ? void 0 : nodeProcess.versions) === null || _a$d === void 0 ? void 0 : _a$d.electron) === 'string'; +const isElectronRenderer = isElectronProcess && (nodeProcess === null || nodeProcess === void 0 ? void 0 : nodeProcess.type) === 'renderer'; +// Web environment +if (typeof navigator === 'object' && !isElectronRenderer) { + _userAgent = navigator.userAgent; + _isWindows = _userAgent.indexOf('Windows') >= 0; + _isMacintosh = _userAgent.indexOf('Macintosh') >= 0; + _isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0; + _isLinux = _userAgent.indexOf('Linux') >= 0; + _isMobile = (_userAgent === null || _userAgent === void 0 ? void 0 : _userAgent.indexOf('Mobi')) >= 0; + _isWeb = true; + getConfiguredDefaultLocale( + // This call _must_ be done in the file that calls `nls.getConfiguredDefaultLocale` + // to ensure that the NLS AMD Loader plugin has been loaded and configured. + // This is because the loader plugin decides what the default locale is based on + // how it's able to resolve the strings. + localize$2({ key: 'ensureLoaderPluginIsLoaded', comment: ['{Locked}'] }, '_')); + _locale = LANGUAGE_DEFAULT; + _language = _locale; + _platformLocale = navigator.language; +} +// Native environment +else if (typeof nodeProcess === 'object') { + _isWindows = (nodeProcess.platform === 'win32'); + _isMacintosh = (nodeProcess.platform === 'darwin'); + _isLinux = (nodeProcess.platform === 'linux'); + _isLinux && !!nodeProcess.env['SNAP'] && !!nodeProcess.env['SNAP_REVISION']; + !!nodeProcess.env['CI'] || !!nodeProcess.env['BUILD_ARTIFACTSTAGINGDIRECTORY']; + _locale = LANGUAGE_DEFAULT; + _language = LANGUAGE_DEFAULT; + const rawNlsConfig = nodeProcess.env['VSCODE_NLS_CONFIG']; + if (rawNlsConfig) { + try { + const nlsConfig = JSON.parse(rawNlsConfig); + const resolved = nlsConfig.availableLanguages['*']; + _locale = nlsConfig.locale; + _platformLocale = nlsConfig.osLocale; + // VSCode's default language is 'en' + _language = resolved ? resolved : LANGUAGE_DEFAULT; + _translationsConfigFile = nlsConfig._translationsConfigFile; + } + catch (e) { + } + } + _isNative = true; +} +// Unknown environment +else { + console.error('Unable to resolve platform.'); +} +const isWindows = _isWindows; +const isMacintosh = _isMacintosh; +const isLinux = _isLinux; +const isNative = _isNative; +const isWeb = _isWeb; +const isWebWorker = (_isWeb && typeof globals.importScripts === 'function'); +const isIOS = _isIOS; +const isMobile = _isMobile; +const userAgent$1 = _userAgent; +/** + * The language used for the user interface. The format of + * the string is all lower case (e.g. zh-tw for Traditional + * Chinese) + */ +const language = _language; +const setTimeout0IsFaster = (typeof globals.postMessage === 'function' && !globals.importScripts); +/** + * See https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#:~:text=than%204%2C%20then-,set%20timeout%20to%204,-. + * + * Works similarly to `setTimeout(0)` but doesn't suffer from the 4ms artificial delay + * that browsers set when the nesting level is > 5. + */ +const setTimeout0 = (() => { + if (setTimeout0IsFaster) { + const pending = []; + globals.addEventListener('message', (e) => { + if (e.data && e.data.vscodeScheduleAsyncWork) { + for (let i = 0, len = pending.length; i < len; i++) { + const candidate = pending[i]; + if (candidate.id === e.data.vscodeScheduleAsyncWork) { + pending.splice(i, 1); + candidate.callback(); + return; + } + } + } + }); + let lastId = 0; + return (callback) => { + const myId = ++lastId; + pending.push({ + id: myId, + callback: callback + }); + globals.postMessage({ vscodeScheduleAsyncWork: myId }, '*'); + }; + } + return (callback) => setTimeout(callback); +})(); +const OS = (_isMacintosh || _isIOS ? 2 /* OperatingSystem.Macintosh */ : (_isWindows ? 1 /* OperatingSystem.Windows */ : 3 /* OperatingSystem.Linux */)); +let _isLittleEndian = true; +let _isLittleEndianComputed = false; +function isLittleEndian() { + if (!_isLittleEndianComputed) { + _isLittleEndianComputed = true; + const test = new Uint8Array(2); + test[0] = 1; + test[1] = 2; + const view = new Uint16Array(test.buffer); + _isLittleEndian = (view[0] === (2 << 8) + 1); + } + return _isLittleEndian; +} +const isChrome$1 = !!(userAgent$1 && userAgent$1.indexOf('Chrome') >= 0); +const isFirefox$1 = !!(userAgent$1 && userAgent$1.indexOf('Firefox') >= 0); +const isSafari$1 = !!(!isChrome$1 && (userAgent$1 && userAgent$1.indexOf('Safari') >= 0)); +const isEdge = !!(userAgent$1 && userAgent$1.indexOf('Edg/') >= 0); +!!(userAgent$1 && userAgent$1.indexOf('Android') >= 0); + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const hasPerformanceNow = (globals.performance && typeof globals.performance.now === 'function'); +class StopWatch { + static create(highResolution = true) { + return new StopWatch(highResolution); + } + constructor(highResolution) { + this._highResolution = hasPerformanceNow && highResolution; + this._startTime = this._now(); + this._stopTime = -1; + } + stop() { + this._stopTime = this._now(); + } + elapsed() { + if (this._stopTime !== -1) { + return this._stopTime - this._startTime; + } + return this._now() - this._startTime; + } + _now() { + return this._highResolution ? globals.performance.now() : Date.now(); + } +} + +var Event; +(function (Event) { + Event.None = () => Disposable.None; + /** + * Given an event, returns another event which debounces calls and defers the listeners to a later task via a shared + * `setTimeout`. The event is converted into a signal (`Event`) to avoid additional object creation as a + * result of merging events and to try prevent race conditions that could arise when using related deferred and + * non-deferred events. + * + * This is useful for deferring non-critical work (eg. general UI updates) to ensure it does not block critical work + * (eg. latency of keypress to text rendered). + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param disposable A disposable store to add the new EventEmitter to. + */ + function defer(event, disposable) { + return debounce(event, () => void 0, 0, undefined, true, undefined, disposable); + } + Event.defer = defer; + /** + * Given an event, returns another event which only fires once. + * + * @param event The event source for the new event. + */ + function once(event) { + return (listener, thisArgs = null, disposables) => { + // we need this, in case the event fires during the listener call + let didFire = false; + let result = undefined; + result = event(e => { + if (didFire) { + return; + } + else if (result) { + result.dispose(); + } + else { + didFire = true; + } + return listener.call(thisArgs, e); + }, null, disposables); + if (didFire) { + result.dispose(); + } + return result; + }; + } + Event.once = once; + /** + * Maps an event of one type into an event of another type using a mapping function, similar to how + * `Array.prototype.map` works. + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param map The mapping function. + * @param disposable A disposable store to add the new EventEmitter to. + */ + function map(event, map, disposable) { + return snapshot((listener, thisArgs = null, disposables) => event(i => listener.call(thisArgs, map(i)), null, disposables), disposable); + } + Event.map = map; + /** + * Wraps an event in another event that performs some function on the event object before firing. + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param each The function to perform on the event object. + * @param disposable A disposable store to add the new EventEmitter to. + */ + function forEach(event, each, disposable) { + return snapshot((listener, thisArgs = null, disposables) => event(i => { each(i); listener.call(thisArgs, i); }, null, disposables), disposable); + } + Event.forEach = forEach; + function filter(event, filter, disposable) { + return snapshot((listener, thisArgs = null, disposables) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables), disposable); + } + Event.filter = filter; + /** + * Given an event, returns the same event but typed as `Event`. + */ + function signal(event) { + return event; + } + Event.signal = signal; + function any(...events) { + return (listener, thisArgs = null, disposables) => combinedDisposable(...events.map(event => event(e => listener.call(thisArgs, e), null, disposables))); + } + Event.any = any; + /** + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + */ + function reduce(event, merge, initial, disposable) { + let output = initial; + return map(event, e => { + output = merge(output, e); + return output; + }, disposable); + } + Event.reduce = reduce; + function snapshot(event, disposable) { + let listener; + const options = { + onWillAddFirstListener() { + listener = event(emitter.fire, emitter); + }, + onDidRemoveLastListener() { + listener === null || listener === void 0 ? void 0 : listener.dispose(); + } + }; + const emitter = new Emitter$1(options); + disposable === null || disposable === void 0 ? void 0 : disposable.add(emitter); + return emitter.event; + } + function debounce(event, merge, delay = 100, leading = false, flushOnListenerRemove = false, leakWarningThreshold, disposable) { + let subscription; + let output = undefined; + let handle = undefined; + let numDebouncedCalls = 0; + let doFire; + const options = { + leakWarningThreshold, + onWillAddFirstListener() { + subscription = event(cur => { + numDebouncedCalls++; + output = merge(output, cur); + if (leading && !handle) { + emitter.fire(output); + output = undefined; + } + doFire = () => { + const _output = output; + output = undefined; + handle = undefined; + if (!leading || numDebouncedCalls > 1) { + emitter.fire(_output); + } + numDebouncedCalls = 0; + }; + if (typeof delay === 'number') { + clearTimeout(handle); + handle = setTimeout(doFire, delay); + } + else { + if (handle === undefined) { + handle = 0; + queueMicrotask(doFire); + } + } + }); + }, + onWillRemoveListener() { + if (flushOnListenerRemove && numDebouncedCalls > 0) { + doFire === null || doFire === void 0 ? void 0 : doFire(); + } + }, + onDidRemoveLastListener() { + doFire = undefined; + subscription.dispose(); + } + }; + const emitter = new Emitter$1(options); + disposable === null || disposable === void 0 ? void 0 : disposable.add(emitter); + return emitter.event; + } + Event.debounce = debounce; + /** + * Debounces an event, firing after some delay (default=0) with an array of all event original objects. + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + */ + function accumulate(event, delay = 0, disposable) { + return Event.debounce(event, (last, e) => { + if (!last) { + return [e]; + } + last.push(e); + return last; + }, delay, undefined, true, undefined, disposable); + } + Event.accumulate = accumulate; + /** + * Filters an event such that some condition is _not_ met more than once in a row, effectively ensuring duplicate + * event objects from different sources do not fire the same event object. + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param equals The equality condition. + * @param disposable A disposable store to add the new EventEmitter to. + * + * @example + * ``` + * // Fire only one time when a single window is opened or focused + * Event.latch(Event.any(onDidOpenWindow, onDidFocusWindow)) + * ``` + */ + function latch(event, equals = (a, b) => a === b, disposable) { + let firstCall = true; + let cache; + return filter(event, value => { + const shouldEmit = firstCall || !equals(value, cache); + firstCall = false; + cache = value; + return shouldEmit; + }, disposable); + } + Event.latch = latch; + /** + * Splits an event whose parameter is a union type into 2 separate events for each type in the union. + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + * + * @example + * ``` + * const event = new EventEmitter().event; + * const [numberEvent, undefinedEvent] = Event.split(event, isUndefined); + * ``` + * + * @param event The event source for the new event. + * @param isT A function that determines what event is of the first type. + * @param disposable A disposable store to add the new EventEmitter to. + */ + function split(event, isT, disposable) { + return [ + Event.filter(event, isT, disposable), + Event.filter(event, e => !isT(e), disposable), + ]; + } + Event.split = split; + /** + * Buffers an event until it has a listener attached. + * + * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned + * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the + * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param flushAfterTimeout Determines whether to flush the buffer after a timeout immediately or after a + * `setTimeout` when the first event listener is added. + * @param _buffer Internal: A source event array used for tests. + * + * @example + * ``` + * // Start accumulating events, when the first listener is attached, flush + * // the event after a timeout such that multiple listeners attached before + * // the timeout would receive the event + * this.onInstallExtension = Event.buffer(service.onInstallExtension, true); + * ``` + */ + function buffer(event, flushAfterTimeout = false, _buffer = []) { + let buffer = _buffer.slice(); + let listener = event(e => { + if (buffer) { + buffer.push(e); + } + else { + emitter.fire(e); + } + }); + const flush = () => { + buffer === null || buffer === void 0 ? void 0 : buffer.forEach(e => emitter.fire(e)); + buffer = null; + }; + const emitter = new Emitter$1({ + onWillAddFirstListener() { + if (!listener) { + listener = event(e => emitter.fire(e)); + } + }, + onDidAddFirstListener() { + if (buffer) { + if (flushAfterTimeout) { + setTimeout(flush); + } + else { + flush(); + } + } + }, + onDidRemoveLastListener() { + if (listener) { + listener.dispose(); + } + listener = null; + } + }); + return emitter.event; + } + Event.buffer = buffer; + class ChainableEvent { + constructor(event) { + this.event = event; + this.disposables = new DisposableStore(); + } + /** @see {@link Event.map} */ + map(fn) { + return new ChainableEvent(map(this.event, fn, this.disposables)); + } + /** @see {@link Event.forEach} */ + forEach(fn) { + return new ChainableEvent(forEach(this.event, fn, this.disposables)); + } + filter(fn) { + return new ChainableEvent(filter(this.event, fn, this.disposables)); + } + /** @see {@link Event.reduce} */ + reduce(merge, initial) { + return new ChainableEvent(reduce(this.event, merge, initial, this.disposables)); + } + /** @see {@link Event.reduce} */ + latch() { + return new ChainableEvent(latch(this.event, undefined, this.disposables)); + } + debounce(merge, delay = 100, leading = false, flushOnListenerRemove = false, leakWarningThreshold) { + return new ChainableEvent(debounce(this.event, merge, delay, leading, flushOnListenerRemove, leakWarningThreshold, this.disposables)); + } + /** + * Attach a listener to the event. + */ + on(listener, thisArgs, disposables) { + return this.event(listener, thisArgs, disposables); + } + /** @see {@link Event.once} */ + once(listener, thisArgs, disposables) { + return once(this.event)(listener, thisArgs, disposables); + } + dispose() { + this.disposables.dispose(); + } + } + /** + * Wraps the event in an {@link IChainableEvent}, allowing a more functional programming style. + * + * @example + * ``` + * // Normal + * const onEnterPressNormal = Event.filter( + * Event.map(onKeyPress.event, e => new StandardKeyboardEvent(e)), + * e.keyCode === KeyCode.Enter + * ).event; + * + * // Using chain + * const onEnterPressChain = Event.chain(onKeyPress.event) + * .map(e => new StandardKeyboardEvent(e)) + * .filter(e => e.keyCode === KeyCode.Enter) + * .event; + * ``` + */ + function chain(event) { + return new ChainableEvent(event); + } + Event.chain = chain; + /** + * Creates an {@link Event} from a node event emitter. + */ + function fromNodeEventEmitter(emitter, eventName, map = id => id) { + const fn = (...args) => result.fire(map(...args)); + const onFirstListenerAdd = () => emitter.on(eventName, fn); + const onLastListenerRemove = () => emitter.removeListener(eventName, fn); + const result = new Emitter$1({ onWillAddFirstListener: onFirstListenerAdd, onDidRemoveLastListener: onLastListenerRemove }); + return result.event; + } + Event.fromNodeEventEmitter = fromNodeEventEmitter; + /** + * Creates an {@link Event} from a DOM event emitter. + */ + function fromDOMEventEmitter(emitter, eventName, map = id => id) { + const fn = (...args) => result.fire(map(...args)); + const onFirstListenerAdd = () => emitter.addEventListener(eventName, fn); + const onLastListenerRemove = () => emitter.removeEventListener(eventName, fn); + const result = new Emitter$1({ onWillAddFirstListener: onFirstListenerAdd, onDidRemoveLastListener: onLastListenerRemove }); + return result.event; + } + Event.fromDOMEventEmitter = fromDOMEventEmitter; + /** + * Creates a promise out of an event, using the {@link Event.once} helper. + */ + function toPromise(event) { + return new Promise(resolve => once(event)(resolve)); + } + Event.toPromise = toPromise; + /** + * Adds a listener to an event and calls the listener immediately with undefined as the event object. + * + * @example + * ``` + * // Initialize the UI and update it when dataChangeEvent fires + * runAndSubscribe(dataChangeEvent, () => this._updateUI()); + * ``` + */ + function runAndSubscribe(event, handler) { + handler(undefined); + return event(e => handler(e)); + } + Event.runAndSubscribe = runAndSubscribe; + /** + * Adds a listener to an event and calls the listener immediately with undefined as the event object. A new + * {@link DisposableStore} is passed to the listener which is disposed when the returned disposable is disposed. + */ + function runAndSubscribeWithStore(event, handler) { + let store = null; + function run(e) { + store === null || store === void 0 ? void 0 : store.dispose(); + store = new DisposableStore(); + handler(e, store); + } + run(undefined); + const disposable = event(e => run(e)); + return toDisposable(() => { + disposable.dispose(); + store === null || store === void 0 ? void 0 : store.dispose(); + }); + } + Event.runAndSubscribeWithStore = runAndSubscribeWithStore; + class EmitterObserver { + constructor(_observable, store) { + this._observable = _observable; + this._counter = 0; + this._hasChanged = false; + const options = { + onWillAddFirstListener: () => { + _observable.addObserver(this); + }, + onDidRemoveLastListener: () => { + _observable.removeObserver(this); + } + }; + this.emitter = new Emitter$1(options); + if (store) { + store.add(this.emitter); + } + } + beginUpdate(_observable) { + // assert(_observable === this.obs); + this._counter++; + } + handlePossibleChange(_observable) { + // assert(_observable === this.obs); + } + handleChange(_observable, _change) { + // assert(_observable === this.obs); + this._hasChanged = true; + } + endUpdate(_observable) { + // assert(_observable === this.obs); + this._counter--; + if (this._counter === 0) { + this._observable.reportChanges(); + if (this._hasChanged) { + this._hasChanged = false; + this.emitter.fire(this._observable.get()); + } + } + } + } + /** + * Creates an event emitter that is fired when the observable changes. + * Each listeners subscribes to the emitter. + */ + function fromObservable(obs, store) { + const observer = new EmitterObserver(obs, store); + return observer.emitter.event; + } + Event.fromObservable = fromObservable; + /** + * Each listener is attached to the observable directly. + */ + function fromObservableLight(observable) { + return (listener) => { + let count = 0; + let didChange = false; + const observer = { + beginUpdate() { + count++; + }, + endUpdate() { + count--; + if (count === 0) { + observable.reportChanges(); + if (didChange) { + didChange = false; + listener(); + } + } + }, + handlePossibleChange() { + // noop + }, + handleChange() { + didChange = true; + } + }; + observable.addObserver(observer); + return { + dispose() { + observable.removeObserver(observer); + } + }; + }; + } + Event.fromObservableLight = fromObservableLight; +})(Event || (Event = {})); +class EventProfiling { + constructor(name) { + this.listenerCount = 0; + this.invocationCount = 0; + this.elapsedOverall = 0; + this.durations = []; + this.name = `${name}_${EventProfiling._idPool++}`; + EventProfiling.all.add(this); + } + start(listenerCount) { + this._stopWatch = new StopWatch(true); + this.listenerCount = listenerCount; + } + stop() { + if (this._stopWatch) { + const elapsed = this._stopWatch.elapsed(); + this.durations.push(elapsed); + this.elapsedOverall += elapsed; + this.invocationCount += 1; + this._stopWatch = undefined; + } + } +} +EventProfiling.all = new Set(); +EventProfiling._idPool = 0; +let _globalLeakWarningThreshold = -1; +class LeakageMonitor { + constructor(threshold, name = Math.random().toString(18).slice(2, 5)) { + this.threshold = threshold; + this.name = name; + this._warnCountdown = 0; + } + dispose() { + var _a; + (_a = this._stacks) === null || _a === void 0 ? void 0 : _a.clear(); + } + check(stack, listenerCount) { + const threshold = this.threshold; + if (threshold <= 0 || listenerCount < threshold) { + return undefined; + } + if (!this._stacks) { + this._stacks = new Map(); + } + const count = (this._stacks.get(stack.value) || 0); + this._stacks.set(stack.value, count + 1); + this._warnCountdown -= 1; + if (this._warnCountdown <= 0) { + // only warn on first exceed and then every time the limit + // is exceeded by 50% again + this._warnCountdown = threshold * 0.5; + // find most frequent listener and print warning + let topStack; + let topCount = 0; + for (const [stack, count] of this._stacks) { + if (!topStack || topCount < count) { + topStack = stack; + topCount = count; + } + } + console.warn(`[${this.name}] potential listener LEAK detected, having ${listenerCount} listeners already. MOST frequent listener (${topCount}):`); + console.warn(topStack); + } + return () => { + const count = (this._stacks.get(stack.value) || 0); + this._stacks.set(stack.value, count - 1); + }; + } +} +class Stacktrace { + static create() { + var _a; + return new Stacktrace((_a = new Error().stack) !== null && _a !== void 0 ? _a : ''); + } + constructor(value) { + this.value = value; + } + print() { + console.warn(this.value.split('\n').slice(2).join('\n')); + } +} +class Listener { + constructor(callback, callbackThis, stack) { + this.callback = callback; + this.callbackThis = callbackThis; + this.stack = stack; + this.subscription = new SafeDisposable(); + } + invoke(e) { + this.callback.call(this.callbackThis, e); + } +} +/** + * The Emitter can be used to expose an Event to the public + * to fire it from the insides. + * Sample: + class Document { + + private readonly _onDidChange = new Emitter<(value:string)=>any>(); + + public onDidChange = this._onDidChange.event; + + // getter-style + // get onDidChange(): Event<(value:string)=>any> { + // return this._onDidChange.event; + // } + + private _doIt() { + //... + this._onDidChange.fire(value); + } + } + */ +let Emitter$1 = class Emitter { + constructor(options) { + var _a, _b, _c, _d, _e; + this._disposed = false; + this._options = options; + this._leakageMon = ((_a = this._options) === null || _a === void 0 ? void 0 : _a.leakWarningThreshold) ? new LeakageMonitor((_c = (_b = this._options) === null || _b === void 0 ? void 0 : _b.leakWarningThreshold) !== null && _c !== void 0 ? _c : _globalLeakWarningThreshold) : undefined; + this._perfMon = ((_d = this._options) === null || _d === void 0 ? void 0 : _d._profName) ? new EventProfiling(this._options._profName) : undefined; + this._deliveryQueue = (_e = this._options) === null || _e === void 0 ? void 0 : _e.deliveryQueue; + } + dispose() { + var _a, _b, _c, _d; + if (!this._disposed) { + this._disposed = true; + // It is bad to have listeners at the time of disposing an emitter, it is worst to have listeners keep the emitter + // alive via the reference that's embedded in their disposables. Therefore we loop over all remaining listeners and + // unset their subscriptions/disposables. Looping and blaming remaining listeners is done on next tick because the + // the following programming pattern is very popular: + // + // const someModel = this._disposables.add(new ModelObject()); // (1) create and register model + // this._disposables.add(someModel.onDidChange(() => { ... }); // (2) subscribe and register model-event listener + // ...later... + // this._disposables.dispose(); disposes (1) then (2): don't warn after (1) but after the "overall dispose" is done + if (this._listeners) { + this._listeners.clear(); + } + (_a = this._deliveryQueue) === null || _a === void 0 ? void 0 : _a.clear(this); + (_c = (_b = this._options) === null || _b === void 0 ? void 0 : _b.onDidRemoveLastListener) === null || _c === void 0 ? void 0 : _c.call(_b); + (_d = this._leakageMon) === null || _d === void 0 ? void 0 : _d.dispose(); + } + } + /** + * For the public to allow to subscribe + * to events from this Emitter + */ + get event() { + if (!this._event) { + this._event = (callback, thisArgs, disposables) => { + var _a, _b, _c; + if (!this._listeners) { + this._listeners = new LinkedList(); + } + if (this._leakageMon && this._listeners.size > this._leakageMon.threshold * 3) { + console.warn(`[${this._leakageMon.name}] REFUSES to accept new listeners because it exceeded its threshold by far`); + return Disposable.None; + } + const firstListener = this._listeners.isEmpty(); + if (firstListener && ((_a = this._options) === null || _a === void 0 ? void 0 : _a.onWillAddFirstListener)) { + this._options.onWillAddFirstListener(this); + } + let removeMonitor; + let stack; + if (this._leakageMon && this._listeners.size >= Math.ceil(this._leakageMon.threshold * 0.2)) { + // check and record this emitter for potential leakage + stack = Stacktrace.create(); + removeMonitor = this._leakageMon.check(stack, this._listeners.size + 1); + } + const listener = new Listener(callback, thisArgs, stack); + const removeListener = this._listeners.push(listener); + if (firstListener && ((_b = this._options) === null || _b === void 0 ? void 0 : _b.onDidAddFirstListener)) { + this._options.onDidAddFirstListener(this); + } + if ((_c = this._options) === null || _c === void 0 ? void 0 : _c.onDidAddListener) { + this._options.onDidAddListener(this, callback, thisArgs); + } + const result = listener.subscription.set(() => { + var _a, _b; + removeMonitor === null || removeMonitor === void 0 ? void 0 : removeMonitor(); + if (!this._disposed) { + (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.onWillRemoveListener) === null || _b === void 0 ? void 0 : _b.call(_a, this); + removeListener(); + if (this._options && this._options.onDidRemoveLastListener) { + const hasListeners = (this._listeners && !this._listeners.isEmpty()); + if (!hasListeners) { + this._options.onDidRemoveLastListener(this); + } + } + } + }); + if (disposables instanceof DisposableStore) { + disposables.add(result); + } + else if (Array.isArray(disposables)) { + disposables.push(result); + } + return result; + }; + } + return this._event; + } + /** + * To be kept private to fire an event to + * subscribers + */ + fire(event) { + var _a, _b, _c; + if (this._listeners) { + // put all [listener,event]-pairs into delivery queue + // then emit all event. an inner/nested event might be + // the driver of this + if (!this._deliveryQueue) { + this._deliveryQueue = new PrivateEventDeliveryQueue((_a = this._options) === null || _a === void 0 ? void 0 : _a.onListenerError); + } + for (const listener of this._listeners) { + this._deliveryQueue.push(this, listener, event); + } + // start/stop performance insight collection + (_b = this._perfMon) === null || _b === void 0 ? void 0 : _b.start(this._deliveryQueue.size); + this._deliveryQueue.deliver(); + (_c = this._perfMon) === null || _c === void 0 ? void 0 : _c.stop(); + } + } + hasListeners() { + if (!this._listeners) { + return false; + } + return !this._listeners.isEmpty(); + } +}; +class EventDeliveryQueue { + constructor(_onListenerError = onUnexpectedError) { + this._onListenerError = _onListenerError; + this._queue = new LinkedList(); + } + get size() { + return this._queue.size; + } + push(emitter, listener, event) { + this._queue.push(new EventDeliveryQueueElement(emitter, listener, event)); + } + clear(emitter) { + const newQueue = new LinkedList(); + for (const element of this._queue) { + if (element.emitter !== emitter) { + newQueue.push(element); + } + } + this._queue = newQueue; + } + deliver() { + while (this._queue.size > 0) { + const element = this._queue.shift(); + try { + element.listener.invoke(element.event); + } + catch (e) { + this._onListenerError(e); + } + } + } +} +/** + * An `EventDeliveryQueue` that is guaranteed to be used by a single `Emitter`. + */ +class PrivateEventDeliveryQueue extends EventDeliveryQueue { + clear(emitter) { + // Here we can just clear the entire linked list because + // all elements are guaranteed to belong to this emitter + this._queue.clear(); + } +} +class EventDeliveryQueueElement { + constructor(emitter, listener, event) { + this.emitter = emitter; + this.listener = listener; + this.event = event; + } +} +class PauseableEmitter extends Emitter$1 { + constructor(options) { + super(options); + this._isPaused = 0; + this._eventQueue = new LinkedList(); + this._mergeFn = options === null || options === void 0 ? void 0 : options.merge; + } + pause() { + this._isPaused++; + } + resume() { + if (this._isPaused !== 0 && --this._isPaused === 0) { + if (this._mergeFn) { + // use the merge function to create a single composite + // event. make a copy in case firing pauses this emitter + if (this._eventQueue.size > 0) { + const events = Array.from(this._eventQueue); + this._eventQueue.clear(); + super.fire(this._mergeFn(events)); + } + } + else { + // no merging, fire each event individually and test + // that this emitter isn't paused halfway through + while (!this._isPaused && this._eventQueue.size !== 0) { + super.fire(this._eventQueue.shift()); + } + } + } + } + fire(event) { + if (this._listeners) { + if (this._isPaused !== 0) { + this._eventQueue.push(event); + } + else { + super.fire(event); + } + } + } +} +class DebounceEmitter extends PauseableEmitter { + constructor(options) { + var _a; + super(options); + this._delay = (_a = options.delay) !== null && _a !== void 0 ? _a : 100; + } + fire(event) { + if (!this._handle) { + this.pause(); + this._handle = setTimeout(() => { + this._handle = undefined; + this.resume(); + }, this._delay); + } + super.fire(event); + } +} +/** + * An emitter which queue all events and then process them at the + * end of the event loop. + */ +class MicrotaskEmitter extends Emitter$1 { + constructor(options) { + super(options); + this._queuedEvents = []; + this._mergeFn = options === null || options === void 0 ? void 0 : options.merge; + } + fire(event) { + if (!this.hasListeners()) { + return; + } + this._queuedEvents.push(event); + if (this._queuedEvents.length === 1) { + queueMicrotask(() => { + if (this._mergeFn) { + super.fire(this._mergeFn(this._queuedEvents)); + } + else { + this._queuedEvents.forEach(e => super.fire(e)); + } + this._queuedEvents = []; + }); + } + } +} +class EventMultiplexer { + constructor() { + this.hasListeners = false; + this.events = []; + this.emitter = new Emitter$1({ + onWillAddFirstListener: () => this.onFirstListenerAdd(), + onDidRemoveLastListener: () => this.onLastListenerRemove() + }); + } + get event() { + return this.emitter.event; + } + add(event) { + const e = { event: event, listener: null }; + this.events.push(e); + if (this.hasListeners) { + this.hook(e); + } + const dispose = () => { + if (this.hasListeners) { + this.unhook(e); + } + const idx = this.events.indexOf(e); + this.events.splice(idx, 1); + }; + return toDisposable(once$1(dispose)); + } + onFirstListenerAdd() { + this.hasListeners = true; + this.events.forEach(e => this.hook(e)); + } + onLastListenerRemove() { + this.hasListeners = false; + this.events.forEach(e => this.unhook(e)); + } + hook(e) { + e.listener = e.event(r => this.emitter.fire(r)); + } + unhook(e) { + if (e.listener) { + e.listener.dispose(); + } + e.listener = null; + } + dispose() { + this.emitter.dispose(); + } +} +/** + * The EventBufferer is useful in situations in which you want + * to delay firing your events during some code. + * You can wrap that code and be sure that the event will not + * be fired during that wrap. + * + * ``` + * const emitter: Emitter; + * const delayer = new EventDelayer(); + * const delayedEvent = delayer.wrapEvent(emitter.event); + * + * delayedEvent(console.log); + * + * delayer.bufferEvents(() => { + * emitter.fire(); // event will not be fired yet + * }); + * + * // event will only be fired at this point + * ``` + */ +class EventBufferer { + constructor() { + this.buffers = []; + } + wrapEvent(event) { + return (listener, thisArgs, disposables) => { + return event(i => { + const buffer = this.buffers[this.buffers.length - 1]; + if (buffer) { + buffer.push(() => listener.call(thisArgs, i)); + } + else { + listener.call(thisArgs, i); + } + }, undefined, disposables); + }; + } + bufferEvents(fn) { + const buffer = []; + this.buffers.push(buffer); + const r = fn(); + this.buffers.pop(); + buffer.forEach(flush => flush()); + return r; + } +} +/** + * A Relay is an event forwarder which functions as a replugabble event pipe. + * Once created, you can connect an input event to it and it will simply forward + * events from that input event through its own `event` property. The `input` + * can be changed at any point in time. + */ +class Relay { + constructor() { + this.listening = false; + this.inputEvent = Event.None; + this.inputEventListener = Disposable.None; + this.emitter = new Emitter$1({ + onDidAddFirstListener: () => { + this.listening = true; + this.inputEventListener = this.inputEvent(this.emitter.fire, this.emitter); + }, + onDidRemoveLastListener: () => { + this.listening = false; + this.inputEventListener.dispose(); + } + }); + this.event = this.emitter.event; + } + set input(event) { + this.inputEvent = event; + if (this.listening) { + this.inputEventListener.dispose(); + this.inputEventListener = event(this.emitter.fire, this.emitter); + } + } + dispose() { + this.inputEventListener.dispose(); + this.emitter.dispose(); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class WindowManager { + constructor() { + // --- Zoom Factor + this._zoomFactor = 1; + } + getZoomFactor() { + return this._zoomFactor; + } +} +WindowManager.INSTANCE = new WindowManager(); +/** + * See https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes + */ +class DevicePixelRatioMonitor extends Disposable { + constructor() { + super(); + this._onDidChange = this._register(new Emitter$1()); + this.onDidChange = this._onDidChange.event; + this._listener = () => this._handleChange(true); + this._mediaQueryList = null; + this._handleChange(false); + } + _handleChange(fireEvent) { + var _a; + (_a = this._mediaQueryList) === null || _a === void 0 ? void 0 : _a.removeEventListener('change', this._listener); + this._mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`); + this._mediaQueryList.addEventListener('change', this._listener); + if (fireEvent) { + this._onDidChange.fire(); + } + } +} +class PixelRatioImpl extends Disposable { + get value() { + return this._value; + } + constructor() { + super(); + this._onDidChange = this._register(new Emitter$1()); + this.onDidChange = this._onDidChange.event; + this._value = this._getPixelRatio(); + const dprMonitor = this._register(new DevicePixelRatioMonitor()); + this._register(dprMonitor.onDidChange(() => { + this._value = this._getPixelRatio(); + this._onDidChange.fire(this._value); + })); + } + _getPixelRatio() { + const ctx = document.createElement('canvas').getContext('2d'); + const dpr = window.devicePixelRatio || 1; + const bsr = ctx.webkitBackingStorePixelRatio || + ctx.mozBackingStorePixelRatio || + ctx.msBackingStorePixelRatio || + ctx.oBackingStorePixelRatio || + ctx.backingStorePixelRatio || 1; + return dpr / bsr; + } +} +class PixelRatioFacade { + constructor() { + this._pixelRatioMonitor = null; + } + _getOrCreatePixelRatioMonitor() { + if (!this._pixelRatioMonitor) { + this._pixelRatioMonitor = markAsSingleton(new PixelRatioImpl()); + } + return this._pixelRatioMonitor; + } + /** + * Get the current value. + */ + get value() { + return this._getOrCreatePixelRatioMonitor().value; + } + /** + * Listen for changes. + */ + get onDidChange() { + return this._getOrCreatePixelRatioMonitor().onDidChange; + } +} +function addMatchMediaChangeListener(query, callback) { + if (typeof query === 'string') { + query = window.matchMedia(query); + } + query.addEventListener('change', callback); +} +/** + * Returns the pixel ratio. + * + * This is useful for rendering elements at native screen resolution or for being used as + * a cache key when storing font measurements. Fonts might render differently depending on resolution + * and any measurements need to be discarded for example when a window is moved from a monitor to another. + */ +const PixelRatio = new PixelRatioFacade(); +/** The zoom scale for an index, e.g. 1, 1.2, 1.4 */ +function getZoomFactor() { + return WindowManager.INSTANCE.getZoomFactor(); +} +const userAgent = navigator.userAgent; +const isFirefox = (userAgent.indexOf('Firefox') >= 0); +const isWebKit = (userAgent.indexOf('AppleWebKit') >= 0); +const isChrome = (userAgent.indexOf('Chrome') >= 0); +const isSafari = (!isChrome && (userAgent.indexOf('Safari') >= 0)); +const isWebkitWebView = (!isChrome && !isSafari && isWebKit); +const isElectron = (userAgent.indexOf('Electron/') >= 0); +const isAndroid = (userAgent.indexOf('Android') >= 0); +let standalone = false; +if (window.matchMedia) { + const standaloneMatchMedia = window.matchMedia('(display-mode: standalone) or (display-mode: window-controls-overlay)'); + const fullScreenMatchMedia = window.matchMedia('(display-mode: fullscreen)'); + standalone = standaloneMatchMedia.matches; + addMatchMediaChangeListener(standaloneMatchMedia, ({ matches }) => { + // entering fullscreen would change standaloneMatchMedia.matches to false + // if standalone is true (running as PWA) and entering fullscreen, skip this change + if (standalone && fullScreenMatchMedia.matches) { + return; + } + // otherwise update standalone (browser to PWA or PWA to browser) + standalone = matches; + }); +} +function isStandalone() { + return standalone; +} + +const browser = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + PixelRatio, + addMatchMediaChangeListener, + getZoomFactor, + isAndroid, + isChrome, + isElectron, + isFirefox, + isSafari, + isStandalone, + isWebKit, + isWebkitWebView +}, Symbol.toStringTag, { value: 'Module' })); + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * @returns whether the provided parameter is a JavaScript String or not. + */ +function isString$1(str) { + return (typeof str === 'string'); +} +/** + * @returns whether the provided parameter is of type `object` but **not** + * `null`, an `array`, a `regexp`, nor a `date`. + */ +function isObject(obj) { + // The method can't do a type cast since there are type (like strings) which + // are subclasses of any put not positvely matched by the function. Hence type + // narrowing results in wrong results. + return typeof obj === 'object' + && obj !== null + && !Array.isArray(obj) + && !(obj instanceof RegExp) + && !(obj instanceof Date); +} +/** + * @returns whether the provided parameter is of type `Buffer` or Uint8Array dervived type + */ +function isTypedArray(obj) { + const TypedArray = Object.getPrototypeOf(Uint8Array); + return typeof obj === 'object' + && obj instanceof TypedArray; +} +/** + * In **contrast** to just checking `typeof` this will return `false` for `NaN`. + * @returns whether the provided parameter is a JavaScript Number or not. + */ +function isNumber$1(obj) { + return (typeof obj === 'number' && !isNaN(obj)); +} +/** + * @returns whether the provided parameter is an Iterable, casting to the given generic + */ +function isIterable(obj) { + return !!obj && typeof obj[Symbol.iterator] === 'function'; +} +/** + * @returns whether the provided parameter is a JavaScript Boolean or not. + */ +function isBoolean(obj) { + return (obj === true || obj === false); +} +/** + * @returns whether the provided parameter is undefined. + */ +function isUndefined(obj) { + return (typeof obj === 'undefined'); +} +/** + * @returns whether the provided parameter is defined. + */ +function isDefined(arg) { + return !isUndefinedOrNull(arg); +} +/** + * @returns whether the provided parameter is undefined or null. + */ +function isUndefinedOrNull(obj) { + return (isUndefined(obj) || obj === null); +} +function assertType(condition, type) { + if (!condition) { + throw new Error(type ? `Unexpected type, expected '${type}'` : 'Unexpected type'); + } +} +/** + * Asserts that the argument passed in is neither undefined nor null. + */ +function assertIsDefined(arg) { + if (isUndefinedOrNull(arg)) { + throw new Error('Assertion Failed: argument is undefined or null'); + } + return arg; +} +/** + * @returns whether the provided parameter is a JavaScript Function or not. + */ +function isFunction(obj) { + return (typeof obj === 'function'); +} +function validateConstraints(args, constraints) { + const len = Math.min(args.length, constraints.length); + for (let i = 0; i < len; i++) { + validateConstraint(args[i], constraints[i]); + } +} +function validateConstraint(arg, constraint) { + if (isString$1(constraint)) { + if (typeof arg !== constraint) { + throw new Error(`argument does not match constraint: typeof ${constraint}`); + } + } + else if (isFunction(constraint)) { + try { + if (arg instanceof constraint) { + return; + } + } + catch (_a) { + // ignore + } + if (!isUndefinedOrNull(arg) && arg.constructor === constraint) { + return; + } + if (constraint.length === 1 && constraint.call(undefined, arg) === true) { + return; + } + throw new Error(`argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true`); + } +} +/** + * Converts null to undefined, passes all other values through. + */ +function withNullAsUndefined(x) { + return x === null ? undefined : x; +} +/** + * Converts undefined to null, passes all other values through. + */ +function withUndefinedAsNull(x) { + return typeof x === 'undefined' ? null : x; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * Browser feature we can support in current platform, browser and environment. + */ +const BrowserFeatures = { + clipboard: { + writeText: (isNative + || (document.queryCommandSupported && document.queryCommandSupported('copy')) + || !!(navigator && navigator.clipboard && navigator.clipboard.writeText)), + readText: (isNative + || !!(navigator && navigator.clipboard && navigator.clipboard.readText)) + }, + keyboard: (() => { + if (isNative || isStandalone()) { + return 0 /* KeyboardSupport.Always */; + } + if (navigator.keyboard || isSafari) { + return 1 /* KeyboardSupport.FullScreen */; + } + return 2 /* KeyboardSupport.None */; + })(), + // 'ontouchstart' in window always evaluates to true with typescript's modern typings. This causes `window` to be + // `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast + touch: 'ontouchstart' in window || navigator.maxTouchPoints > 0, + pointerEvents: window.PointerEvent && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0 || navigator.maxTouchPoints > 0) +}; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class KeyCodeStrMap { + constructor() { + this._keyCodeToStr = []; + this._strToKeyCode = Object.create(null); + } + define(keyCode, str) { + this._keyCodeToStr[keyCode] = str; + this._strToKeyCode[str.toLowerCase()] = keyCode; + } + keyCodeToStr(keyCode) { + return this._keyCodeToStr[keyCode]; + } + strToKeyCode(str) { + return this._strToKeyCode[str.toLowerCase()] || 0 /* KeyCode.Unknown */; + } +} +const uiMap = new KeyCodeStrMap(); +const userSettingsUSMap = new KeyCodeStrMap(); +const userSettingsGeneralMap = new KeyCodeStrMap(); +const EVENT_KEY_CODE_MAP = new Array(230); +const scanCodeStrToInt = Object.create(null); +const scanCodeLowerCaseStrToInt = Object.create(null); +/** + * -1 if a ScanCode => KeyCode mapping depends on kb layout. + */ +const IMMUTABLE_CODE_TO_KEY_CODE = []; +for (let i = 0; i <= 193 /* ScanCode.MAX_VALUE */; i++) { + IMMUTABLE_CODE_TO_KEY_CODE[i] = -1 /* KeyCode.DependsOnKbLayout */; +} +(function () { + // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx + // See https://github.com/microsoft/node-native-keymap/blob/master/deps/chromium/keyboard_codes_win.h + const empty = ''; + const mappings = [ + // immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel + [1, 0 /* ScanCode.None */, 'None', 0 /* KeyCode.Unknown */, 'unknown', 0, 'VK_UNKNOWN', empty, empty], + [1, 1 /* ScanCode.Hyper */, 'Hyper', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 2 /* ScanCode.Super */, 'Super', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 3 /* ScanCode.Fn */, 'Fn', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 4 /* ScanCode.FnLock */, 'FnLock', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 5 /* ScanCode.Suspend */, 'Suspend', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 6 /* ScanCode.Resume */, 'Resume', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 7 /* ScanCode.Turbo */, 'Turbo', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 8 /* ScanCode.Sleep */, 'Sleep', 0 /* KeyCode.Unknown */, empty, 0, 'VK_SLEEP', empty, empty], + [1, 9 /* ScanCode.WakeUp */, 'WakeUp', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [0, 10 /* ScanCode.KeyA */, 'KeyA', 31 /* KeyCode.KeyA */, 'A', 65, 'VK_A', empty, empty], + [0, 11 /* ScanCode.KeyB */, 'KeyB', 32 /* KeyCode.KeyB */, 'B', 66, 'VK_B', empty, empty], + [0, 12 /* ScanCode.KeyC */, 'KeyC', 33 /* KeyCode.KeyC */, 'C', 67, 'VK_C', empty, empty], + [0, 13 /* ScanCode.KeyD */, 'KeyD', 34 /* KeyCode.KeyD */, 'D', 68, 'VK_D', empty, empty], + [0, 14 /* ScanCode.KeyE */, 'KeyE', 35 /* KeyCode.KeyE */, 'E', 69, 'VK_E', empty, empty], + [0, 15 /* ScanCode.KeyF */, 'KeyF', 36 /* KeyCode.KeyF */, 'F', 70, 'VK_F', empty, empty], + [0, 16 /* ScanCode.KeyG */, 'KeyG', 37 /* KeyCode.KeyG */, 'G', 71, 'VK_G', empty, empty], + [0, 17 /* ScanCode.KeyH */, 'KeyH', 38 /* KeyCode.KeyH */, 'H', 72, 'VK_H', empty, empty], + [0, 18 /* ScanCode.KeyI */, 'KeyI', 39 /* KeyCode.KeyI */, 'I', 73, 'VK_I', empty, empty], + [0, 19 /* ScanCode.KeyJ */, 'KeyJ', 40 /* KeyCode.KeyJ */, 'J', 74, 'VK_J', empty, empty], + [0, 20 /* ScanCode.KeyK */, 'KeyK', 41 /* KeyCode.KeyK */, 'K', 75, 'VK_K', empty, empty], + [0, 21 /* ScanCode.KeyL */, 'KeyL', 42 /* KeyCode.KeyL */, 'L', 76, 'VK_L', empty, empty], + [0, 22 /* ScanCode.KeyM */, 'KeyM', 43 /* KeyCode.KeyM */, 'M', 77, 'VK_M', empty, empty], + [0, 23 /* ScanCode.KeyN */, 'KeyN', 44 /* KeyCode.KeyN */, 'N', 78, 'VK_N', empty, empty], + [0, 24 /* ScanCode.KeyO */, 'KeyO', 45 /* KeyCode.KeyO */, 'O', 79, 'VK_O', empty, empty], + [0, 25 /* ScanCode.KeyP */, 'KeyP', 46 /* KeyCode.KeyP */, 'P', 80, 'VK_P', empty, empty], + [0, 26 /* ScanCode.KeyQ */, 'KeyQ', 47 /* KeyCode.KeyQ */, 'Q', 81, 'VK_Q', empty, empty], + [0, 27 /* ScanCode.KeyR */, 'KeyR', 48 /* KeyCode.KeyR */, 'R', 82, 'VK_R', empty, empty], + [0, 28 /* ScanCode.KeyS */, 'KeyS', 49 /* KeyCode.KeyS */, 'S', 83, 'VK_S', empty, empty], + [0, 29 /* ScanCode.KeyT */, 'KeyT', 50 /* KeyCode.KeyT */, 'T', 84, 'VK_T', empty, empty], + [0, 30 /* ScanCode.KeyU */, 'KeyU', 51 /* KeyCode.KeyU */, 'U', 85, 'VK_U', empty, empty], + [0, 31 /* ScanCode.KeyV */, 'KeyV', 52 /* KeyCode.KeyV */, 'V', 86, 'VK_V', empty, empty], + [0, 32 /* ScanCode.KeyW */, 'KeyW', 53 /* KeyCode.KeyW */, 'W', 87, 'VK_W', empty, empty], + [0, 33 /* ScanCode.KeyX */, 'KeyX', 54 /* KeyCode.KeyX */, 'X', 88, 'VK_X', empty, empty], + [0, 34 /* ScanCode.KeyY */, 'KeyY', 55 /* KeyCode.KeyY */, 'Y', 89, 'VK_Y', empty, empty], + [0, 35 /* ScanCode.KeyZ */, 'KeyZ', 56 /* KeyCode.KeyZ */, 'Z', 90, 'VK_Z', empty, empty], + [0, 36 /* ScanCode.Digit1 */, 'Digit1', 22 /* KeyCode.Digit1 */, '1', 49, 'VK_1', empty, empty], + [0, 37 /* ScanCode.Digit2 */, 'Digit2', 23 /* KeyCode.Digit2 */, '2', 50, 'VK_2', empty, empty], + [0, 38 /* ScanCode.Digit3 */, 'Digit3', 24 /* KeyCode.Digit3 */, '3', 51, 'VK_3', empty, empty], + [0, 39 /* ScanCode.Digit4 */, 'Digit4', 25 /* KeyCode.Digit4 */, '4', 52, 'VK_4', empty, empty], + [0, 40 /* ScanCode.Digit5 */, 'Digit5', 26 /* KeyCode.Digit5 */, '5', 53, 'VK_5', empty, empty], + [0, 41 /* ScanCode.Digit6 */, 'Digit6', 27 /* KeyCode.Digit6 */, '6', 54, 'VK_6', empty, empty], + [0, 42 /* ScanCode.Digit7 */, 'Digit7', 28 /* KeyCode.Digit7 */, '7', 55, 'VK_7', empty, empty], + [0, 43 /* ScanCode.Digit8 */, 'Digit8', 29 /* KeyCode.Digit8 */, '8', 56, 'VK_8', empty, empty], + [0, 44 /* ScanCode.Digit9 */, 'Digit9', 30 /* KeyCode.Digit9 */, '9', 57, 'VK_9', empty, empty], + [0, 45 /* ScanCode.Digit0 */, 'Digit0', 21 /* KeyCode.Digit0 */, '0', 48, 'VK_0', empty, empty], + [1, 46 /* ScanCode.Enter */, 'Enter', 3 /* KeyCode.Enter */, 'Enter', 13, 'VK_RETURN', empty, empty], + [1, 47 /* ScanCode.Escape */, 'Escape', 9 /* KeyCode.Escape */, 'Escape', 27, 'VK_ESCAPE', empty, empty], + [1, 48 /* ScanCode.Backspace */, 'Backspace', 1 /* KeyCode.Backspace */, 'Backspace', 8, 'VK_BACK', empty, empty], + [1, 49 /* ScanCode.Tab */, 'Tab', 2 /* KeyCode.Tab */, 'Tab', 9, 'VK_TAB', empty, empty], + [1, 50 /* ScanCode.Space */, 'Space', 10 /* KeyCode.Space */, 'Space', 32, 'VK_SPACE', empty, empty], + [0, 51 /* ScanCode.Minus */, 'Minus', 88 /* KeyCode.Minus */, '-', 189, 'VK_OEM_MINUS', '-', 'OEM_MINUS'], + [0, 52 /* ScanCode.Equal */, 'Equal', 86 /* KeyCode.Equal */, '=', 187, 'VK_OEM_PLUS', '=', 'OEM_PLUS'], + [0, 53 /* ScanCode.BracketLeft */, 'BracketLeft', 92 /* KeyCode.BracketLeft */, '[', 219, 'VK_OEM_4', '[', 'OEM_4'], + [0, 54 /* ScanCode.BracketRight */, 'BracketRight', 94 /* KeyCode.BracketRight */, ']', 221, 'VK_OEM_6', ']', 'OEM_6'], + [0, 55 /* ScanCode.Backslash */, 'Backslash', 93 /* KeyCode.Backslash */, '\\', 220, 'VK_OEM_5', '\\', 'OEM_5'], + [0, 56 /* ScanCode.IntlHash */, 'IntlHash', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [0, 57 /* ScanCode.Semicolon */, 'Semicolon', 85 /* KeyCode.Semicolon */, ';', 186, 'VK_OEM_1', ';', 'OEM_1'], + [0, 58 /* ScanCode.Quote */, 'Quote', 95 /* KeyCode.Quote */, '\'', 222, 'VK_OEM_7', '\'', 'OEM_7'], + [0, 59 /* ScanCode.Backquote */, 'Backquote', 91 /* KeyCode.Backquote */, '`', 192, 'VK_OEM_3', '`', 'OEM_3'], + [0, 60 /* ScanCode.Comma */, 'Comma', 87 /* KeyCode.Comma */, ',', 188, 'VK_OEM_COMMA', ',', 'OEM_COMMA'], + [0, 61 /* ScanCode.Period */, 'Period', 89 /* KeyCode.Period */, '.', 190, 'VK_OEM_PERIOD', '.', 'OEM_PERIOD'], + [0, 62 /* ScanCode.Slash */, 'Slash', 90 /* KeyCode.Slash */, '/', 191, 'VK_OEM_2', '/', 'OEM_2'], + [1, 63 /* ScanCode.CapsLock */, 'CapsLock', 8 /* KeyCode.CapsLock */, 'CapsLock', 20, 'VK_CAPITAL', empty, empty], + [1, 64 /* ScanCode.F1 */, 'F1', 59 /* KeyCode.F1 */, 'F1', 112, 'VK_F1', empty, empty], + [1, 65 /* ScanCode.F2 */, 'F2', 60 /* KeyCode.F2 */, 'F2', 113, 'VK_F2', empty, empty], + [1, 66 /* ScanCode.F3 */, 'F3', 61 /* KeyCode.F3 */, 'F3', 114, 'VK_F3', empty, empty], + [1, 67 /* ScanCode.F4 */, 'F4', 62 /* KeyCode.F4 */, 'F4', 115, 'VK_F4', empty, empty], + [1, 68 /* ScanCode.F5 */, 'F5', 63 /* KeyCode.F5 */, 'F5', 116, 'VK_F5', empty, empty], + [1, 69 /* ScanCode.F6 */, 'F6', 64 /* KeyCode.F6 */, 'F6', 117, 'VK_F6', empty, empty], + [1, 70 /* ScanCode.F7 */, 'F7', 65 /* KeyCode.F7 */, 'F7', 118, 'VK_F7', empty, empty], + [1, 71 /* ScanCode.F8 */, 'F8', 66 /* KeyCode.F8 */, 'F8', 119, 'VK_F8', empty, empty], + [1, 72 /* ScanCode.F9 */, 'F9', 67 /* KeyCode.F9 */, 'F9', 120, 'VK_F9', empty, empty], + [1, 73 /* ScanCode.F10 */, 'F10', 68 /* KeyCode.F10 */, 'F10', 121, 'VK_F10', empty, empty], + [1, 74 /* ScanCode.F11 */, 'F11', 69 /* KeyCode.F11 */, 'F11', 122, 'VK_F11', empty, empty], + [1, 75 /* ScanCode.F12 */, 'F12', 70 /* KeyCode.F12 */, 'F12', 123, 'VK_F12', empty, empty], + [1, 76 /* ScanCode.PrintScreen */, 'PrintScreen', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 77 /* ScanCode.ScrollLock */, 'ScrollLock', 84 /* KeyCode.ScrollLock */, 'ScrollLock', 145, 'VK_SCROLL', empty, empty], + [1, 78 /* ScanCode.Pause */, 'Pause', 7 /* KeyCode.PauseBreak */, 'PauseBreak', 19, 'VK_PAUSE', empty, empty], + [1, 79 /* ScanCode.Insert */, 'Insert', 19 /* KeyCode.Insert */, 'Insert', 45, 'VK_INSERT', empty, empty], + [1, 80 /* ScanCode.Home */, 'Home', 14 /* KeyCode.Home */, 'Home', 36, 'VK_HOME', empty, empty], + [1, 81 /* ScanCode.PageUp */, 'PageUp', 11 /* KeyCode.PageUp */, 'PageUp', 33, 'VK_PRIOR', empty, empty], + [1, 82 /* ScanCode.Delete */, 'Delete', 20 /* KeyCode.Delete */, 'Delete', 46, 'VK_DELETE', empty, empty], + [1, 83 /* ScanCode.End */, 'End', 13 /* KeyCode.End */, 'End', 35, 'VK_END', empty, empty], + [1, 84 /* ScanCode.PageDown */, 'PageDown', 12 /* KeyCode.PageDown */, 'PageDown', 34, 'VK_NEXT', empty, empty], + [1, 85 /* ScanCode.ArrowRight */, 'ArrowRight', 17 /* KeyCode.RightArrow */, 'RightArrow', 39, 'VK_RIGHT', 'Right', empty], + [1, 86 /* ScanCode.ArrowLeft */, 'ArrowLeft', 15 /* KeyCode.LeftArrow */, 'LeftArrow', 37, 'VK_LEFT', 'Left', empty], + [1, 87 /* ScanCode.ArrowDown */, 'ArrowDown', 18 /* KeyCode.DownArrow */, 'DownArrow', 40, 'VK_DOWN', 'Down', empty], + [1, 88 /* ScanCode.ArrowUp */, 'ArrowUp', 16 /* KeyCode.UpArrow */, 'UpArrow', 38, 'VK_UP', 'Up', empty], + [1, 89 /* ScanCode.NumLock */, 'NumLock', 83 /* KeyCode.NumLock */, 'NumLock', 144, 'VK_NUMLOCK', empty, empty], + [1, 90 /* ScanCode.NumpadDivide */, 'NumpadDivide', 113 /* KeyCode.NumpadDivide */, 'NumPad_Divide', 111, 'VK_DIVIDE', empty, empty], + [1, 91 /* ScanCode.NumpadMultiply */, 'NumpadMultiply', 108 /* KeyCode.NumpadMultiply */, 'NumPad_Multiply', 106, 'VK_MULTIPLY', empty, empty], + [1, 92 /* ScanCode.NumpadSubtract */, 'NumpadSubtract', 111 /* KeyCode.NumpadSubtract */, 'NumPad_Subtract', 109, 'VK_SUBTRACT', empty, empty], + [1, 93 /* ScanCode.NumpadAdd */, 'NumpadAdd', 109 /* KeyCode.NumpadAdd */, 'NumPad_Add', 107, 'VK_ADD', empty, empty], + [1, 94 /* ScanCode.NumpadEnter */, 'NumpadEnter', 3 /* KeyCode.Enter */, empty, 0, empty, empty, empty], + [1, 95 /* ScanCode.Numpad1 */, 'Numpad1', 99 /* KeyCode.Numpad1 */, 'NumPad1', 97, 'VK_NUMPAD1', empty, empty], + [1, 96 /* ScanCode.Numpad2 */, 'Numpad2', 100 /* KeyCode.Numpad2 */, 'NumPad2', 98, 'VK_NUMPAD2', empty, empty], + [1, 97 /* ScanCode.Numpad3 */, 'Numpad3', 101 /* KeyCode.Numpad3 */, 'NumPad3', 99, 'VK_NUMPAD3', empty, empty], + [1, 98 /* ScanCode.Numpad4 */, 'Numpad4', 102 /* KeyCode.Numpad4 */, 'NumPad4', 100, 'VK_NUMPAD4', empty, empty], + [1, 99 /* ScanCode.Numpad5 */, 'Numpad5', 103 /* KeyCode.Numpad5 */, 'NumPad5', 101, 'VK_NUMPAD5', empty, empty], + [1, 100 /* ScanCode.Numpad6 */, 'Numpad6', 104 /* KeyCode.Numpad6 */, 'NumPad6', 102, 'VK_NUMPAD6', empty, empty], + [1, 101 /* ScanCode.Numpad7 */, 'Numpad7', 105 /* KeyCode.Numpad7 */, 'NumPad7', 103, 'VK_NUMPAD7', empty, empty], + [1, 102 /* ScanCode.Numpad8 */, 'Numpad8', 106 /* KeyCode.Numpad8 */, 'NumPad8', 104, 'VK_NUMPAD8', empty, empty], + [1, 103 /* ScanCode.Numpad9 */, 'Numpad9', 107 /* KeyCode.Numpad9 */, 'NumPad9', 105, 'VK_NUMPAD9', empty, empty], + [1, 104 /* ScanCode.Numpad0 */, 'Numpad0', 98 /* KeyCode.Numpad0 */, 'NumPad0', 96, 'VK_NUMPAD0', empty, empty], + [1, 105 /* ScanCode.NumpadDecimal */, 'NumpadDecimal', 112 /* KeyCode.NumpadDecimal */, 'NumPad_Decimal', 110, 'VK_DECIMAL', empty, empty], + [0, 106 /* ScanCode.IntlBackslash */, 'IntlBackslash', 97 /* KeyCode.IntlBackslash */, 'OEM_102', 226, 'VK_OEM_102', empty, empty], + [1, 107 /* ScanCode.ContextMenu */, 'ContextMenu', 58 /* KeyCode.ContextMenu */, 'ContextMenu', 93, empty, empty, empty], + [1, 108 /* ScanCode.Power */, 'Power', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 109 /* ScanCode.NumpadEqual */, 'NumpadEqual', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 110 /* ScanCode.F13 */, 'F13', 71 /* KeyCode.F13 */, 'F13', 124, 'VK_F13', empty, empty], + [1, 111 /* ScanCode.F14 */, 'F14', 72 /* KeyCode.F14 */, 'F14', 125, 'VK_F14', empty, empty], + [1, 112 /* ScanCode.F15 */, 'F15', 73 /* KeyCode.F15 */, 'F15', 126, 'VK_F15', empty, empty], + [1, 113 /* ScanCode.F16 */, 'F16', 74 /* KeyCode.F16 */, 'F16', 127, 'VK_F16', empty, empty], + [1, 114 /* ScanCode.F17 */, 'F17', 75 /* KeyCode.F17 */, 'F17', 128, 'VK_F17', empty, empty], + [1, 115 /* ScanCode.F18 */, 'F18', 76 /* KeyCode.F18 */, 'F18', 129, 'VK_F18', empty, empty], + [1, 116 /* ScanCode.F19 */, 'F19', 77 /* KeyCode.F19 */, 'F19', 130, 'VK_F19', empty, empty], + [1, 117 /* ScanCode.F20 */, 'F20', 78 /* KeyCode.F20 */, 'F20', 0, 'VK_F20', empty, empty], + [1, 118 /* ScanCode.F21 */, 'F21', 79 /* KeyCode.F21 */, 'F21', 0, 'VK_F21', empty, empty], + [1, 119 /* ScanCode.F22 */, 'F22', 80 /* KeyCode.F22 */, 'F22', 0, 'VK_F22', empty, empty], + [1, 120 /* ScanCode.F23 */, 'F23', 81 /* KeyCode.F23 */, 'F23', 0, 'VK_F23', empty, empty], + [1, 121 /* ScanCode.F24 */, 'F24', 82 /* KeyCode.F24 */, 'F24', 0, 'VK_F24', empty, empty], + [1, 122 /* ScanCode.Open */, 'Open', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 123 /* ScanCode.Help */, 'Help', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 124 /* ScanCode.Select */, 'Select', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 125 /* ScanCode.Again */, 'Again', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 126 /* ScanCode.Undo */, 'Undo', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 127 /* ScanCode.Cut */, 'Cut', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 128 /* ScanCode.Copy */, 'Copy', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 129 /* ScanCode.Paste */, 'Paste', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 130 /* ScanCode.Find */, 'Find', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 131 /* ScanCode.AudioVolumeMute */, 'AudioVolumeMute', 117 /* KeyCode.AudioVolumeMute */, 'AudioVolumeMute', 173, 'VK_VOLUME_MUTE', empty, empty], + [1, 132 /* ScanCode.AudioVolumeUp */, 'AudioVolumeUp', 118 /* KeyCode.AudioVolumeUp */, 'AudioVolumeUp', 175, 'VK_VOLUME_UP', empty, empty], + [1, 133 /* ScanCode.AudioVolumeDown */, 'AudioVolumeDown', 119 /* KeyCode.AudioVolumeDown */, 'AudioVolumeDown', 174, 'VK_VOLUME_DOWN', empty, empty], + [1, 134 /* ScanCode.NumpadComma */, 'NumpadComma', 110 /* KeyCode.NUMPAD_SEPARATOR */, 'NumPad_Separator', 108, 'VK_SEPARATOR', empty, empty], + [0, 135 /* ScanCode.IntlRo */, 'IntlRo', 115 /* KeyCode.ABNT_C1 */, 'ABNT_C1', 193, 'VK_ABNT_C1', empty, empty], + [1, 136 /* ScanCode.KanaMode */, 'KanaMode', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [0, 137 /* ScanCode.IntlYen */, 'IntlYen', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 138 /* ScanCode.Convert */, 'Convert', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 139 /* ScanCode.NonConvert */, 'NonConvert', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 140 /* ScanCode.Lang1 */, 'Lang1', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 141 /* ScanCode.Lang2 */, 'Lang2', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 142 /* ScanCode.Lang3 */, 'Lang3', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 143 /* ScanCode.Lang4 */, 'Lang4', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 144 /* ScanCode.Lang5 */, 'Lang5', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 145 /* ScanCode.Abort */, 'Abort', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 146 /* ScanCode.Props */, 'Props', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 147 /* ScanCode.NumpadParenLeft */, 'NumpadParenLeft', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 148 /* ScanCode.NumpadParenRight */, 'NumpadParenRight', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 149 /* ScanCode.NumpadBackspace */, 'NumpadBackspace', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 150 /* ScanCode.NumpadMemoryStore */, 'NumpadMemoryStore', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 151 /* ScanCode.NumpadMemoryRecall */, 'NumpadMemoryRecall', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 152 /* ScanCode.NumpadMemoryClear */, 'NumpadMemoryClear', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 153 /* ScanCode.NumpadMemoryAdd */, 'NumpadMemoryAdd', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 154 /* ScanCode.NumpadMemorySubtract */, 'NumpadMemorySubtract', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 155 /* ScanCode.NumpadClear */, 'NumpadClear', 131 /* KeyCode.Clear */, 'Clear', 12, 'VK_CLEAR', empty, empty], + [1, 156 /* ScanCode.NumpadClearEntry */, 'NumpadClearEntry', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 0 /* ScanCode.None */, empty, 5 /* KeyCode.Ctrl */, 'Ctrl', 17, 'VK_CONTROL', empty, empty], + [1, 0 /* ScanCode.None */, empty, 4 /* KeyCode.Shift */, 'Shift', 16, 'VK_SHIFT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 6 /* KeyCode.Alt */, 'Alt', 18, 'VK_MENU', empty, empty], + [1, 0 /* ScanCode.None */, empty, 57 /* KeyCode.Meta */, 'Meta', 91, 'VK_COMMAND', empty, empty], + [1, 157 /* ScanCode.ControlLeft */, 'ControlLeft', 5 /* KeyCode.Ctrl */, empty, 0, 'VK_LCONTROL', empty, empty], + [1, 158 /* ScanCode.ShiftLeft */, 'ShiftLeft', 4 /* KeyCode.Shift */, empty, 0, 'VK_LSHIFT', empty, empty], + [1, 159 /* ScanCode.AltLeft */, 'AltLeft', 6 /* KeyCode.Alt */, empty, 0, 'VK_LMENU', empty, empty], + [1, 160 /* ScanCode.MetaLeft */, 'MetaLeft', 57 /* KeyCode.Meta */, empty, 0, 'VK_LWIN', empty, empty], + [1, 161 /* ScanCode.ControlRight */, 'ControlRight', 5 /* KeyCode.Ctrl */, empty, 0, 'VK_RCONTROL', empty, empty], + [1, 162 /* ScanCode.ShiftRight */, 'ShiftRight', 4 /* KeyCode.Shift */, empty, 0, 'VK_RSHIFT', empty, empty], + [1, 163 /* ScanCode.AltRight */, 'AltRight', 6 /* KeyCode.Alt */, empty, 0, 'VK_RMENU', empty, empty], + [1, 164 /* ScanCode.MetaRight */, 'MetaRight', 57 /* KeyCode.Meta */, empty, 0, 'VK_RWIN', empty, empty], + [1, 165 /* ScanCode.BrightnessUp */, 'BrightnessUp', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 166 /* ScanCode.BrightnessDown */, 'BrightnessDown', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 167 /* ScanCode.MediaPlay */, 'MediaPlay', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 168 /* ScanCode.MediaRecord */, 'MediaRecord', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 169 /* ScanCode.MediaFastForward */, 'MediaFastForward', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 170 /* ScanCode.MediaRewind */, 'MediaRewind', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 171 /* ScanCode.MediaTrackNext */, 'MediaTrackNext', 124 /* KeyCode.MediaTrackNext */, 'MediaTrackNext', 176, 'VK_MEDIA_NEXT_TRACK', empty, empty], + [1, 172 /* ScanCode.MediaTrackPrevious */, 'MediaTrackPrevious', 125 /* KeyCode.MediaTrackPrevious */, 'MediaTrackPrevious', 177, 'VK_MEDIA_PREV_TRACK', empty, empty], + [1, 173 /* ScanCode.MediaStop */, 'MediaStop', 126 /* KeyCode.MediaStop */, 'MediaStop', 178, 'VK_MEDIA_STOP', empty, empty], + [1, 174 /* ScanCode.Eject */, 'Eject', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 175 /* ScanCode.MediaPlayPause */, 'MediaPlayPause', 127 /* KeyCode.MediaPlayPause */, 'MediaPlayPause', 179, 'VK_MEDIA_PLAY_PAUSE', empty, empty], + [1, 176 /* ScanCode.MediaSelect */, 'MediaSelect', 128 /* KeyCode.LaunchMediaPlayer */, 'LaunchMediaPlayer', 181, 'VK_MEDIA_LAUNCH_MEDIA_SELECT', empty, empty], + [1, 177 /* ScanCode.LaunchMail */, 'LaunchMail', 129 /* KeyCode.LaunchMail */, 'LaunchMail', 180, 'VK_MEDIA_LAUNCH_MAIL', empty, empty], + [1, 178 /* ScanCode.LaunchApp2 */, 'LaunchApp2', 130 /* KeyCode.LaunchApp2 */, 'LaunchApp2', 183, 'VK_MEDIA_LAUNCH_APP2', empty, empty], + [1, 179 /* ScanCode.LaunchApp1 */, 'LaunchApp1', 0 /* KeyCode.Unknown */, empty, 0, 'VK_MEDIA_LAUNCH_APP1', empty, empty], + [1, 180 /* ScanCode.SelectTask */, 'SelectTask', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 181 /* ScanCode.LaunchScreenSaver */, 'LaunchScreenSaver', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 182 /* ScanCode.BrowserSearch */, 'BrowserSearch', 120 /* KeyCode.BrowserSearch */, 'BrowserSearch', 170, 'VK_BROWSER_SEARCH', empty, empty], + [1, 183 /* ScanCode.BrowserHome */, 'BrowserHome', 121 /* KeyCode.BrowserHome */, 'BrowserHome', 172, 'VK_BROWSER_HOME', empty, empty], + [1, 184 /* ScanCode.BrowserBack */, 'BrowserBack', 122 /* KeyCode.BrowserBack */, 'BrowserBack', 166, 'VK_BROWSER_BACK', empty, empty], + [1, 185 /* ScanCode.BrowserForward */, 'BrowserForward', 123 /* KeyCode.BrowserForward */, 'BrowserForward', 167, 'VK_BROWSER_FORWARD', empty, empty], + [1, 186 /* ScanCode.BrowserStop */, 'BrowserStop', 0 /* KeyCode.Unknown */, empty, 0, 'VK_BROWSER_STOP', empty, empty], + [1, 187 /* ScanCode.BrowserRefresh */, 'BrowserRefresh', 0 /* KeyCode.Unknown */, empty, 0, 'VK_BROWSER_REFRESH', empty, empty], + [1, 188 /* ScanCode.BrowserFavorites */, 'BrowserFavorites', 0 /* KeyCode.Unknown */, empty, 0, 'VK_BROWSER_FAVORITES', empty, empty], + [1, 189 /* ScanCode.ZoomToggle */, 'ZoomToggle', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 190 /* ScanCode.MailReply */, 'MailReply', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 191 /* ScanCode.MailForward */, 'MailForward', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + [1, 192 /* ScanCode.MailSend */, 'MailSend', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty], + // See https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html + // If an Input Method Editor is processing key input and the event is keydown, return 229. + [1, 0 /* ScanCode.None */, empty, 114 /* KeyCode.KEY_IN_COMPOSITION */, 'KeyInComposition', 229, empty, empty, empty], + [1, 0 /* ScanCode.None */, empty, 116 /* KeyCode.ABNT_C2 */, 'ABNT_C2', 194, 'VK_ABNT_C2', empty, empty], + [1, 0 /* ScanCode.None */, empty, 96 /* KeyCode.OEM_8 */, 'OEM_8', 223, 'VK_OEM_8', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_KANA', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_HANGUL', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_JUNJA', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_FINAL', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_HANJA', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_KANJI', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_CONVERT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_NONCONVERT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_ACCEPT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_MODECHANGE', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_SELECT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PRINT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_EXECUTE', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_SNAPSHOT', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_HELP', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_APPS', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PROCESSKEY', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PACKET', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_DBE_SBCSCHAR', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_DBE_DBCSCHAR', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_ATTN', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_CRSEL', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_EXSEL', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_EREOF', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PLAY', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_ZOOM', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_NONAME', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PA1', empty, empty], + [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_OEM_CLEAR', empty, empty], + ]; + const seenKeyCode = []; + const seenScanCode = []; + for (const mapping of mappings) { + const [immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel] = mapping; + if (!seenScanCode[scanCode]) { + seenScanCode[scanCode] = true; + scanCodeStrToInt[scanCodeStr] = scanCode; + scanCodeLowerCaseStrToInt[scanCodeStr.toLowerCase()] = scanCode; + if (immutable) { + IMMUTABLE_CODE_TO_KEY_CODE[scanCode] = keyCode; + } + } + if (!seenKeyCode[keyCode]) { + seenKeyCode[keyCode] = true; + if (!keyCodeStr) { + throw new Error(`String representation missing for key code ${keyCode} around scan code ${scanCodeStr}`); + } + uiMap.define(keyCode, keyCodeStr); + userSettingsUSMap.define(keyCode, usUserSettingsLabel || keyCodeStr); + userSettingsGeneralMap.define(keyCode, generalUserSettingsLabel || usUserSettingsLabel || keyCodeStr); + } + if (eventKeyCode) { + EVENT_KEY_CODE_MAP[eventKeyCode] = keyCode; + } + } +})(); +var KeyCodeUtils; +(function (KeyCodeUtils) { + function toString(keyCode) { + return uiMap.keyCodeToStr(keyCode); + } + KeyCodeUtils.toString = toString; + function fromString(key) { + return uiMap.strToKeyCode(key); + } + KeyCodeUtils.fromString = fromString; + function toUserSettingsUS(keyCode) { + return userSettingsUSMap.keyCodeToStr(keyCode); + } + KeyCodeUtils.toUserSettingsUS = toUserSettingsUS; + function toUserSettingsGeneral(keyCode) { + return userSettingsGeneralMap.keyCodeToStr(keyCode); + } + KeyCodeUtils.toUserSettingsGeneral = toUserSettingsGeneral; + function fromUserSettings(key) { + return userSettingsUSMap.strToKeyCode(key) || userSettingsGeneralMap.strToKeyCode(key); + } + KeyCodeUtils.fromUserSettings = fromUserSettings; + function toElectronAccelerator(keyCode) { + if (keyCode >= 98 /* KeyCode.Numpad0 */ && keyCode <= 113 /* KeyCode.NumpadDivide */) { + // [Electron Accelerators] Electron is able to parse numpad keys, but unfortunately it + // renders them just as regular keys in menus. For example, num0 is rendered as "0", + // numdiv is rendered as "/", numsub is rendered as "-". + // + // This can lead to incredible confusion, as it makes numpad based keybindings indistinguishable + // from keybindings based on regular keys. + // + // We therefore need to fall back to custom rendering for numpad keys. + return null; + } + switch (keyCode) { + case 16 /* KeyCode.UpArrow */: + return 'Up'; + case 18 /* KeyCode.DownArrow */: + return 'Down'; + case 15 /* KeyCode.LeftArrow */: + return 'Left'; + case 17 /* KeyCode.RightArrow */: + return 'Right'; + } + return uiMap.keyCodeToStr(keyCode); + } + KeyCodeUtils.toElectronAccelerator = toElectronAccelerator; +})(KeyCodeUtils || (KeyCodeUtils = {})); +function KeyChord(firstPart, secondPart) { + const chordPart = ((secondPart & 0x0000FFFF) << 16) >>> 0; + return (firstPart | chordPart) >>> 0; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +function decodeKeybinding(keybinding, OS) { + if (typeof keybinding === 'number') { + if (keybinding === 0) { + return null; + } + const firstChord = (keybinding & 0x0000FFFF) >>> 0; + const secondChord = (keybinding & 0xFFFF0000) >>> 16; + if (secondChord !== 0) { + return new Keybinding([ + createSimpleKeybinding(firstChord, OS), + createSimpleKeybinding(secondChord, OS) + ]); + } + return new Keybinding([createSimpleKeybinding(firstChord, OS)]); + } + else { + const chords = []; + for (let i = 0; i < keybinding.length; i++) { + chords.push(createSimpleKeybinding(keybinding[i], OS)); + } + return new Keybinding(chords); + } +} +function createSimpleKeybinding(keybinding, OS) { + const ctrlCmd = (keybinding & 2048 /* BinaryKeybindingsMask.CtrlCmd */ ? true : false); + const winCtrl = (keybinding & 256 /* BinaryKeybindingsMask.WinCtrl */ ? true : false); + const ctrlKey = (OS === 2 /* OperatingSystem.Macintosh */ ? winCtrl : ctrlCmd); + const shiftKey = (keybinding & 1024 /* BinaryKeybindingsMask.Shift */ ? true : false); + const altKey = (keybinding & 512 /* BinaryKeybindingsMask.Alt */ ? true : false); + const metaKey = (OS === 2 /* OperatingSystem.Macintosh */ ? ctrlCmd : winCtrl); + const keyCode = (keybinding & 255 /* BinaryKeybindingsMask.KeyCode */); + return new KeyCodeChord(ctrlKey, shiftKey, altKey, metaKey, keyCode); +} +/** + * Represents a chord which uses the `keyCode` field of keyboard events. + * A chord is a combination of keys pressed simultaneously. + */ +class KeyCodeChord { + constructor(ctrlKey, shiftKey, altKey, metaKey, keyCode) { + this.ctrlKey = ctrlKey; + this.shiftKey = shiftKey; + this.altKey = altKey; + this.metaKey = metaKey; + this.keyCode = keyCode; + } + equals(other) { + return (other instanceof KeyCodeChord + && this.ctrlKey === other.ctrlKey + && this.shiftKey === other.shiftKey + && this.altKey === other.altKey + && this.metaKey === other.metaKey + && this.keyCode === other.keyCode); + } + isModifierKey() { + return (this.keyCode === 0 /* KeyCode.Unknown */ + || this.keyCode === 5 /* KeyCode.Ctrl */ + || this.keyCode === 57 /* KeyCode.Meta */ + || this.keyCode === 6 /* KeyCode.Alt */ + || this.keyCode === 4 /* KeyCode.Shift */); + } + /** + * Does this keybinding refer to the key code of a modifier and it also has the modifier flag? + */ + isDuplicateModifierCase() { + return ((this.ctrlKey && this.keyCode === 5 /* KeyCode.Ctrl */) + || (this.shiftKey && this.keyCode === 4 /* KeyCode.Shift */) + || (this.altKey && this.keyCode === 6 /* KeyCode.Alt */) + || (this.metaKey && this.keyCode === 57 /* KeyCode.Meta */)); + } +} +/** + * A keybinding is a sequence of chords. + */ +class Keybinding { + constructor(chords) { + if (chords.length === 0) { + throw illegalArgument(`chords`); + } + this.chords = chords; + } +} +class ResolvedChord { + constructor(ctrlKey, shiftKey, altKey, metaKey, keyLabel, keyAriaLabel) { + this.ctrlKey = ctrlKey; + this.shiftKey = shiftKey; + this.altKey = altKey; + this.metaKey = metaKey; + this.keyLabel = keyLabel; + this.keyAriaLabel = keyAriaLabel; + } +} +/** + * A resolved keybinding. Consists of one or multiple chords. + */ +class ResolvedKeybinding { +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +function extractKeyCode(e) { + if (e.charCode) { + // "keypress" events mostly + const char = String.fromCharCode(e.charCode).toUpperCase(); + return KeyCodeUtils.fromString(char); + } + const keyCode = e.keyCode; + // browser quirks + if (keyCode === 3) { + return 7 /* KeyCode.PauseBreak */; + } + else if (isFirefox) { + switch (keyCode) { + case 59: return 85 /* KeyCode.Semicolon */; + case 60: + if (isLinux) { + return 97 /* KeyCode.IntlBackslash */; + } + break; + case 61: return 86 /* KeyCode.Equal */; + // based on: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#numpad_keys + case 107: return 109 /* KeyCode.NumpadAdd */; + case 109: return 111 /* KeyCode.NumpadSubtract */; + case 173: return 88 /* KeyCode.Minus */; + case 224: + if (isMacintosh) { + return 57 /* KeyCode.Meta */; + } + break; + } + } + else if (isWebKit) { + if (isMacintosh && keyCode === 93) { + // the two meta keys in the Mac have different key codes (91 and 93) + return 57 /* KeyCode.Meta */; + } + else if (!isMacintosh && keyCode === 92) { + return 57 /* KeyCode.Meta */; + } + } + // cross browser keycodes: + return EVENT_KEY_CODE_MAP[keyCode] || 0 /* KeyCode.Unknown */; +} +const ctrlKeyMod$1 = (isMacintosh ? 256 /* KeyMod.WinCtrl */ : 2048 /* KeyMod.CtrlCmd */); +const altKeyMod = 512 /* KeyMod.Alt */; +const shiftKeyMod = 1024 /* KeyMod.Shift */; +const metaKeyMod = (isMacintosh ? 2048 /* KeyMod.CtrlCmd */ : 256 /* KeyMod.WinCtrl */); +class StandardKeyboardEvent { + constructor(source) { + this._standardKeyboardEventBrand = true; + const e = source; + this.browserEvent = e; + this.target = e.target; + this.ctrlKey = e.ctrlKey; + this.shiftKey = e.shiftKey; + this.altKey = e.altKey; + this.metaKey = e.metaKey; + this.altGraphKey = e.getModifierState('AltGraph'); + this.keyCode = extractKeyCode(e); + this.code = e.code; + // console.info(e.type + ": keyCode: " + e.keyCode + ", which: " + e.which + ", charCode: " + e.charCode + ", detail: " + e.detail + " ====> " + this.keyCode + ' -- ' + KeyCode[this.keyCode]); + this.ctrlKey = this.ctrlKey || this.keyCode === 5 /* KeyCode.Ctrl */; + this.altKey = this.altKey || this.keyCode === 6 /* KeyCode.Alt */; + this.shiftKey = this.shiftKey || this.keyCode === 4 /* KeyCode.Shift */; + this.metaKey = this.metaKey || this.keyCode === 57 /* KeyCode.Meta */; + this._asKeybinding = this._computeKeybinding(); + this._asKeyCodeChord = this._computeKeyCodeChord(); + // console.log(`code: ${e.code}, keyCode: ${e.keyCode}, key: ${e.key}`); + } + preventDefault() { + if (this.browserEvent && this.browserEvent.preventDefault) { + this.browserEvent.preventDefault(); + } + } + stopPropagation() { + if (this.browserEvent && this.browserEvent.stopPropagation) { + this.browserEvent.stopPropagation(); + } + } + toKeyCodeChord() { + return this._asKeyCodeChord; + } + equals(other) { + return this._asKeybinding === other; + } + _computeKeybinding() { + let key = 0 /* KeyCode.Unknown */; + if (this.keyCode !== 5 /* KeyCode.Ctrl */ && this.keyCode !== 4 /* KeyCode.Shift */ && this.keyCode !== 6 /* KeyCode.Alt */ && this.keyCode !== 57 /* KeyCode.Meta */) { + key = this.keyCode; + } + let result = 0; + if (this.ctrlKey) { + result |= ctrlKeyMod$1; + } + if (this.altKey) { + result |= altKeyMod; + } + if (this.shiftKey) { + result |= shiftKeyMod; + } + if (this.metaKey) { + result |= metaKeyMod; + } + result |= key; + return result; + } + _computeKeyCodeChord() { + let key = 0 /* KeyCode.Unknown */; + if (this.keyCode !== 5 /* KeyCode.Ctrl */ && this.keyCode !== 4 /* KeyCode.Shift */ && this.keyCode !== 6 /* KeyCode.Alt */ && this.keyCode !== 57 /* KeyCode.Meta */) { + key = this.keyCode; + } + return new KeyCodeChord(this.ctrlKey, this.shiftKey, this.altKey, this.metaKey, key); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +let hasDifferentOriginAncestorFlag = false; +let sameOriginWindowChainCache = null; +function getParentWindowIfSameOrigin(w) { + if (!w.parent || w.parent === w) { + return null; + } + // Cannot really tell if we have access to the parent window unless we try to access something in it + try { + const location = w.location; + const parentLocation = w.parent.location; + if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) { + hasDifferentOriginAncestorFlag = true; + return null; + } + } + catch (e) { + hasDifferentOriginAncestorFlag = true; + return null; + } + return w.parent; +} +class IframeUtils { + /** + * Returns a chain of embedded windows with the same origin (which can be accessed programmatically). + * Having a chain of length 1 might mean that the current execution environment is running outside of an iframe or inside an iframe embedded in a window with a different origin. + * To distinguish if at one point the current execution environment is running inside a window with a different origin, see hasDifferentOriginAncestor() + */ + static getSameOriginWindowChain() { + if (!sameOriginWindowChainCache) { + sameOriginWindowChainCache = []; + let w = window; + let parent; + do { + parent = getParentWindowIfSameOrigin(w); + if (parent) { + sameOriginWindowChainCache.push({ + window: w, + iframeElement: w.frameElement || null + }); + } + else { + sameOriginWindowChainCache.push({ + window: w, + iframeElement: null + }); + } + w = parent; + } while (w); + } + return sameOriginWindowChainCache.slice(0); + } + /** + * Returns the position of `childWindow` relative to `ancestorWindow` + */ + static getPositionOfChildWindowRelativeToAncestorWindow(childWindow, ancestorWindow) { + if (!ancestorWindow || childWindow === ancestorWindow) { + return { + top: 0, + left: 0 + }; + } + let top = 0, left = 0; + const windowChain = this.getSameOriginWindowChain(); + for (const windowChainEl of windowChain) { + top += windowChainEl.window.scrollY; + left += windowChainEl.window.scrollX; + if (windowChainEl.window === ancestorWindow) { + break; + } + if (!windowChainEl.iframeElement) { + break; + } + const boundingRect = windowChainEl.iframeElement.getBoundingClientRect(); + top += boundingRect.top; + left += boundingRect.left; + } + return { + top: top, + left: left + }; + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class StandardMouseEvent { + constructor(e) { + this.timestamp = Date.now(); + this.browserEvent = e; + this.leftButton = e.button === 0; + this.middleButton = e.button === 1; + this.rightButton = e.button === 2; + this.buttons = e.buttons; + this.target = e.target; + this.detail = e.detail || 1; + if (e.type === 'dblclick') { + this.detail = 2; + } + this.ctrlKey = e.ctrlKey; + this.shiftKey = e.shiftKey; + this.altKey = e.altKey; + this.metaKey = e.metaKey; + if (typeof e.pageX === 'number') { + this.posx = e.pageX; + this.posy = e.pageY; + } + else { + // Probably hit by MSGestureEvent + this.posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + this.posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + // Find the position of the iframe this code is executing in relative to the iframe where the event was captured. + const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(window, e.view); + this.posx -= iframeOffsets.left; + this.posy -= iframeOffsets.top; + } + preventDefault() { + this.browserEvent.preventDefault(); + } + stopPropagation() { + this.browserEvent.stopPropagation(); + } +} +class StandardWheelEvent { + constructor(e, deltaX = 0, deltaY = 0) { + this.browserEvent = e || null; + this.target = e ? (e.target || e.targetNode || e.srcElement) : null; + this.deltaY = deltaY; + this.deltaX = deltaX; + if (e) { + // Old (deprecated) wheel events + const e1 = e; + const e2 = e; + // vertical delta scroll + if (typeof e1.wheelDeltaY !== 'undefined') { + this.deltaY = e1.wheelDeltaY / 120; + } + else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) { + this.deltaY = -e2.detail / 3; + } + else if (e.type === 'wheel') { + // Modern wheel event + // https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent + const ev = e; + if (ev.deltaMode === ev.DOM_DELTA_LINE) { + // the deltas are expressed in lines + if (isFirefox && !isMacintosh) { + this.deltaY = -e.deltaY / 3; + } + else { + this.deltaY = -e.deltaY; + } + } + else { + this.deltaY = -e.deltaY / 40; + } + } + // horizontal delta scroll + if (typeof e1.wheelDeltaX !== 'undefined') { + if (isSafari && isWindows) { + this.deltaX = -(e1.wheelDeltaX / 120); + } + else { + this.deltaX = e1.wheelDeltaX / 120; + } + } + else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) { + this.deltaX = -e.detail / 3; + } + else if (e.type === 'wheel') { + // Modern wheel event + // https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent + const ev = e; + if (ev.deltaMode === ev.DOM_DELTA_LINE) { + // the deltas are expressed in lines + if (isFirefox && !isMacintosh) { + this.deltaX = -e.deltaX / 3; + } + else { + this.deltaX = -e.deltaX; + } + } + else { + this.deltaX = -e.deltaX / 40; + } + } + // Assume a vertical scroll if nothing else worked + if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) { + this.deltaY = e.wheelDelta / 120; + } + } + } + preventDefault() { + var _a; + (_a = this.browserEvent) === null || _a === void 0 ? void 0 : _a.preventDefault(); + } + stopPropagation() { + var _a; + (_a = this.browserEvent) === null || _a === void 0 ? void 0 : _a.stopPropagation(); + } +} + +/*! @license DOMPurify 2.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.1/LICENSE */ + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var hasOwnProperty$2 = Object.hasOwnProperty, + setPrototypeOf = Object.setPrototypeOf, + isFrozen = Object.isFrozen, + getPrototypeOf = Object.getPrototypeOf, + getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var freeze$1 = Object.freeze, + seal = Object.seal, + create$1 = Object.create; // eslint-disable-line import/no-mutable-exports + +var _ref = typeof Reflect !== 'undefined' && Reflect, + apply = _ref.apply, + construct = _ref.construct; + +if (!apply) { + apply = function apply(fun, thisValue, args) { + return fun.apply(thisValue, args); + }; +} + +if (!freeze$1) { + freeze$1 = function freeze(x) { + return x; + }; +} + +if (!seal) { + seal = function seal(x) { + return x; + }; +} + +if (!construct) { + construct = function construct(Func, args) { + return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))(); + }; +} + +var arrayForEach = unapply(Array.prototype.forEach); +var arrayPop = unapply(Array.prototype.pop); +var arrayPush = unapply(Array.prototype.push); + +var stringToLowerCase = unapply(String.prototype.toLowerCase); +var stringMatch = unapply(String.prototype.match); +var stringReplace = unapply(String.prototype.replace); +var stringIndexOf = unapply(String.prototype.indexOf); +var stringTrim = unapply(String.prototype.trim); + +var regExpTest = unapply(RegExp.prototype.test); + +var typeErrorCreate = unconstruct(TypeError); + +function unapply(func) { + return function (thisArg) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return apply(func, thisArg, args); + }; +} + +function unconstruct(func) { + return function () { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return construct(func, args); + }; +} + +/* Add properties to a lookup table */ +function addToSet(set, array) { + if (setPrototypeOf) { + // Make 'in' and truthy checks like Boolean(set.constructor) + // independent of any properties defined on Object.prototype. + // Prevent prototype setters from intercepting set as a this value. + setPrototypeOf(set, null); + } + + var l = array.length; + while (l--) { + var element = array[l]; + if (typeof element === 'string') { + var lcElement = stringToLowerCase(element); + if (lcElement !== element) { + // Config presets (e.g. tags.js, attrs.js) are immutable. + if (!isFrozen(array)) { + array[l] = lcElement; + } + + element = lcElement; + } + } + + set[element] = true; + } + + return set; +} + +/* Shallow clone an object */ +function clone(object) { + var newObject = create$1(null); + + var property = void 0; + for (property in object) { + if (apply(hasOwnProperty$2, object, [property])) { + newObject[property] = object[property]; + } + } + + return newObject; +} + +/* IE10 doesn't support __lookupGetter__ so lets' + * simulate it. It also automatically checks + * if the prop is function or getter and behaves + * accordingly. */ +function lookupGetter(object, prop) { + while (object !== null) { + var desc = getOwnPropertyDescriptor(object, prop); + if (desc) { + if (desc.get) { + return unapply(desc.get); + } + + if (typeof desc.value === 'function') { + return unapply(desc.value); + } + } + + object = getPrototypeOf(object); + } + + function fallbackValue(element) { + console.warn('fallback value for', element); + return null; + } + + return fallbackValue; +} + +var html = freeze$1(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); + +// SVG +var svg = freeze$1(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); + +var svgFilters = freeze$1(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); + +// List of SVG elements that are disallowed by default. +// We still need to know them so that we can do namespace +// checks properly in case one wants to add them to +// allow-list. +var svgDisallowed = freeze$1(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'feimage', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); + +var mathMl = freeze$1(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']); + +// Similarly to SVG, we want to know all MathML elements, +// even those that we disallow by default. +var mathMlDisallowed = freeze$1(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); + +var text = freeze$1(['#text']); + +var html$1 = freeze$1(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']); + +var svg$1 = freeze$1(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); + +var mathMl$1 = freeze$1(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); + +var xml = freeze$1(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); + +// eslint-disable-next-line unicorn/better-regex +var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode +var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm); +var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape +var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape +var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape +); +var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); +var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex +); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var getGlobal = function getGlobal() { + return typeof window === 'undefined' ? null : window; +}; + +/** + * Creates a no-op policy for internal use only. + * Don't export this function outside this module! + * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory. + * @param {Document} document The document object (to determine policy name suffix) + * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types + * are not supported). + */ +var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) { + if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') { + return null; + } + + // Allow the callers to control the unique policy name + // by adding a data-tt-policy-suffix to the script element with the DOMPurify. + // Policy creation with duplicate names throws in Trusted Types. + var suffix = null; + var ATTR_NAME = 'data-tt-policy-suffix'; + if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) { + suffix = document.currentScript.getAttribute(ATTR_NAME); + } + + var policyName = 'dompurify' + (suffix ? '#' + suffix : ''); + + try { + return trustedTypes.createPolicy(policyName, { + createHTML: function createHTML(html$$1) { + return html$$1; + } + }); + } catch (_) { + // Policy creation failed (most likely another DOMPurify script has + // already run). Skip creating the policy, as this will only cause errors + // if TT are enforced. + console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); + return null; + } +}; + +function createDOMPurify() { + var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); + + var DOMPurify = function DOMPurify(root) { + return createDOMPurify(root); + }; + + /** + * Version label, exposed for easier checks + * if DOMPurify is up to date or not + */ + DOMPurify.version = '2.3.1'; + + /** + * Array of elements that DOMPurify removed during sanitation. + * Empty if nothing was removed. + */ + DOMPurify.removed = []; + + if (!window || !window.document || window.document.nodeType !== 9) { + // Not running in a browser, provide a factory function + // so that you can pass your own Window + DOMPurify.isSupported = false; + + return DOMPurify; + } + + var originalDocument = window.document; + + var document = window.document; + var DocumentFragment = window.DocumentFragment, + HTMLTemplateElement = window.HTMLTemplateElement, + Node = window.Node, + Element = window.Element, + NodeFilter = window.NodeFilter, + _window$NamedNodeMap = window.NamedNodeMap, + NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap, + Text = window.Text, + Comment = window.Comment, + DOMParser = window.DOMParser, + trustedTypes = window.trustedTypes; + + + var ElementPrototype = Element.prototype; + + var cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); + var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); + var getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); + var getParentNode = lookupGetter(ElementPrototype, 'parentNode'); + + // As per issue #47, the web-components registry is inherited by a + // new document created via createHTMLDocument. As per the spec + // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) + // a new empty registry is used when creating a template contents owner + // document, so we use that as our parent document to ensure nothing + // is inherited. + if (typeof HTMLTemplateElement === 'function') { + var template = document.createElement('template'); + if (template.content && template.content.ownerDocument) { + document = template.content.ownerDocument; + } + } + + var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument); + var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : ''; + + var _document = document, + implementation = _document.implementation, + createNodeIterator = _document.createNodeIterator, + createDocumentFragment = _document.createDocumentFragment, + getElementsByTagName = _document.getElementsByTagName; + var importNode = originalDocument.importNode; + + + var documentMode = {}; + try { + documentMode = clone(document).documentMode ? document.documentMode : {}; + } catch (_) {} + + var hooks = {}; + + /** + * Expose whether this browser supports running the full DOMPurify. + */ + DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9; + + var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR, + ERB_EXPR$$1 = ERB_EXPR, + DATA_ATTR$$1 = DATA_ATTR, + ARIA_ATTR$$1 = ARIA_ATTR, + IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA, + ATTR_WHITESPACE$$1 = ATTR_WHITESPACE; + var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI; + + /** + * We consider the elements and attributes below to be safe. Ideally + * don't add any new ones but feel free to remove unwanted ones. + */ + + /* allowed element names */ + + var ALLOWED_TAGS = null; + var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text))); + + /* Allowed attribute names */ + var ALLOWED_ATTR = null; + var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml))); + + /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ + var FORBID_TAGS = null; + + /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ + var FORBID_ATTR = null; + + /* Decide if ARIA attributes are okay */ + var ALLOW_ARIA_ATTR = true; + + /* Decide if custom data attributes are okay */ + var ALLOW_DATA_ATTR = true; + + /* Decide if unknown protocols are okay */ + var ALLOW_UNKNOWN_PROTOCOLS = false; + + /* Output should be safe for common template engines. + * This means, DOMPurify removes data attributes, mustaches and ERB + */ + var SAFE_FOR_TEMPLATES = false; + + /* Decide if document with ... should be returned */ + var WHOLE_DOCUMENT = false; + + /* Track whether config is already set on this instance of DOMPurify. */ + var SET_CONFIG = false; + + /* Decide if all elements (e.g. style, script) must be children of + * document.body. By default, browsers might move them to document.head */ + var FORCE_BODY = false; + + /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html + * string (or a TrustedHTML object if Trusted Types are supported). + * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead + */ + var RETURN_DOM = false; + + /* Decide if a DOM `DocumentFragment` should be returned, instead of a html + * string (or a TrustedHTML object if Trusted Types are supported) */ + var RETURN_DOM_FRAGMENT = false; + + /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM + * `Node` is imported into the current `Document`. If this flag is not enabled the + * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by + * DOMPurify. + * + * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false` + * might cause XSS from attacks hidden in closed shadowroots in case the browser + * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/ + */ + var RETURN_DOM_IMPORT = true; + + /* Try to return a Trusted Type object instead of a string, return a string in + * case Trusted Types are not supported */ + var RETURN_TRUSTED_TYPE = false; + + /* Output should be free from DOM clobbering attacks? */ + var SANITIZE_DOM = true; + + /* Keep element content when removing element? */ + var KEEP_CONTENT = true; + + /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead + * of importing it into a new Document and returning a sanitized copy */ + var IN_PLACE = false; + + /* Allow usage of profiles like html, svg and mathMl */ + var USE_PROFILES = {}; + + /* Tags to ignore content of when KEEP_CONTENT is true */ + var FORBID_CONTENTS = null; + var DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); + + /* Tags that are safe for data: URIs */ + var DATA_URI_TAGS = null; + var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); + + /* Attributes safe for values like "javascript:" */ + var URI_SAFE_ATTRIBUTES = null; + var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); + + var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; + var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; + var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; + /* Document namespace */ + var NAMESPACE = HTML_NAMESPACE; + var IS_EMPTY_INPUT = false; + + /* Keep a reference to config to pass to hooks */ + var CONFIG = null; + + /* Ideally, do not touch anything below this line */ + /* ______________________________________________ */ + + var formElement = document.createElement('form'); + + /** + * _parseConfig + * + * @param {Object} cfg optional config literal + */ + // eslint-disable-next-line complexity + var _parseConfig = function _parseConfig(cfg) { + if (CONFIG && CONFIG === cfg) { + return; + } + + /* Shield configuration object from tampering */ + if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') { + cfg = {}; + } + + /* Shield configuration object from prototype pollution */ + cfg = clone(cfg); + + /* Set configuration parameters */ + ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS; + ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR; + URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES; + DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS; + FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS; + FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {}; + FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {}; + USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false; + ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true + ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true + ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false + SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false + WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false + RETURN_DOM = cfg.RETURN_DOM || false; // Default false + RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false + RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true + RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false + FORCE_BODY = cfg.FORCE_BODY || false; // Default false + SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true + KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true + IN_PLACE = cfg.IN_PLACE || false; // Default false + IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1; + NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; + if (SAFE_FOR_TEMPLATES) { + ALLOW_DATA_ATTR = false; + } + + if (RETURN_DOM_FRAGMENT) { + RETURN_DOM = true; + } + + /* Parse profile info */ + if (USE_PROFILES) { + ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text))); + ALLOWED_ATTR = []; + if (USE_PROFILES.html === true) { + addToSet(ALLOWED_TAGS, html); + addToSet(ALLOWED_ATTR, html$1); + } + + if (USE_PROFILES.svg === true) { + addToSet(ALLOWED_TAGS, svg); + addToSet(ALLOWED_ATTR, svg$1); + addToSet(ALLOWED_ATTR, xml); + } + + if (USE_PROFILES.svgFilters === true) { + addToSet(ALLOWED_TAGS, svgFilters); + addToSet(ALLOWED_ATTR, svg$1); + addToSet(ALLOWED_ATTR, xml); + } + + if (USE_PROFILES.mathMl === true) { + addToSet(ALLOWED_TAGS, mathMl); + addToSet(ALLOWED_ATTR, mathMl$1); + addToSet(ALLOWED_ATTR, xml); + } + } + + /* Merge configuration parameters */ + if (cfg.ADD_TAGS) { + if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { + ALLOWED_TAGS = clone(ALLOWED_TAGS); + } + + addToSet(ALLOWED_TAGS, cfg.ADD_TAGS); + } + + if (cfg.ADD_ATTR) { + if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { + ALLOWED_ATTR = clone(ALLOWED_ATTR); + } + + addToSet(ALLOWED_ATTR, cfg.ADD_ATTR); + } + + if (cfg.ADD_URI_SAFE_ATTR) { + addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR); + } + + if (cfg.FORBID_CONTENTS) { + if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { + FORBID_CONTENTS = clone(FORBID_CONTENTS); + } + + addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS); + } + + /* Add #text in case KEEP_CONTENT is set to true */ + if (KEEP_CONTENT) { + ALLOWED_TAGS['#text'] = true; + } + + /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ + if (WHOLE_DOCUMENT) { + addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); + } + + /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ + if (ALLOWED_TAGS.table) { + addToSet(ALLOWED_TAGS, ['tbody']); + delete FORBID_TAGS.tbody; + } + + // Prevent further manipulation of configuration. + // Not available in IE8, Safari 5, etc. + if (freeze$1) { + freeze$1(cfg); + } + + CONFIG = cfg; + }; + + var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); + + var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); + + /* Keep track of all possible SVG and MathML tags + * so that we can perform the namespace checks + * correctly. */ + var ALL_SVG_TAGS = addToSet({}, svg); + addToSet(ALL_SVG_TAGS, svgFilters); + addToSet(ALL_SVG_TAGS, svgDisallowed); + + var ALL_MATHML_TAGS = addToSet({}, mathMl); + addToSet(ALL_MATHML_TAGS, mathMlDisallowed); + + /** + * + * + * @param {Element} element a DOM element whose namespace is being checked + * @returns {boolean} Return false if the element has a + * namespace that a spec-compliant parser would never + * return. Return true otherwise. + */ + var _checkValidNamespace = function _checkValidNamespace(element) { + var parent = getParentNode(element); + + // In JSDOM, if we're inside shadow DOM, then parentNode + // can be null. We just simulate parent in this case. + if (!parent || !parent.tagName) { + parent = { + namespaceURI: HTML_NAMESPACE, + tagName: 'template' + }; + } + + var tagName = stringToLowerCase(element.tagName); + var parentTagName = stringToLowerCase(parent.tagName); + + if (element.namespaceURI === SVG_NAMESPACE) { + // The only way to switch from HTML namespace to SVG + // is via . If it happens via any other tag, then + // it should be killed. + if (parent.namespaceURI === HTML_NAMESPACE) { + return tagName === 'svg'; + } + + // The only way to switch from MathML to SVG is via + // svg if parent is either or MathML + // text integration points. + if (parent.namespaceURI === MATHML_NAMESPACE) { + return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); + } + + // We only allow elements that are defined in SVG + // spec. All others are disallowed in SVG namespace. + return Boolean(ALL_SVG_TAGS[tagName]); + } + + if (element.namespaceURI === MATHML_NAMESPACE) { + // The only way to switch from HTML namespace to MathML + // is via . If it happens via any other tag, then + // it should be killed. + if (parent.namespaceURI === HTML_NAMESPACE) { + return tagName === 'math'; + } + + // The only way to switch from SVG to MathML is via + // and HTML integration points + if (parent.namespaceURI === SVG_NAMESPACE) { + return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; + } + + // We only allow elements that are defined in MathML + // spec. All others are disallowed in MathML namespace. + return Boolean(ALL_MATHML_TAGS[tagName]); + } + + if (element.namespaceURI === HTML_NAMESPACE) { + // The only way to switch from SVG to HTML is via + // HTML integration points, and from MathML to HTML + // is via MathML text integration points + if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { + return false; + } + + if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { + return false; + } + + // Certain elements are allowed in both SVG and HTML + // namespace. We need to specify them explicitly + // so that they don't get erronously deleted from + // HTML namespace. + var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']); + + // We disallow tags that are specific for MathML + // or SVG and should never appear in HTML namespace + return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]); + } + + // The code should never reach this place (this means + // that the element somehow got namespace that is not + // HTML, SVG or MathML). Return false just in case. + return false; + }; + + /** + * _forceRemove + * + * @param {Node} node a DOM node + */ + var _forceRemove = function _forceRemove(node) { + arrayPush(DOMPurify.removed, { element: node }); + try { + // eslint-disable-next-line unicorn/prefer-dom-node-remove + node.parentNode.removeChild(node); + } catch (_) { + try { + node.outerHTML = emptyHTML; + } catch (_) { + node.remove(); + } + } + }; + + /** + * _removeAttribute + * + * @param {String} name an Attribute name + * @param {Node} node a DOM node + */ + var _removeAttribute = function _removeAttribute(name, node) { + try { + arrayPush(DOMPurify.removed, { + attribute: node.getAttributeNode(name), + from: node + }); + } catch (_) { + arrayPush(DOMPurify.removed, { + attribute: null, + from: node + }); + } + + node.removeAttribute(name); + + // We void attribute values for unremovable "is"" attributes + if (name === 'is' && !ALLOWED_ATTR[name]) { + if (RETURN_DOM || RETURN_DOM_FRAGMENT) { + try { + _forceRemove(node); + } catch (_) {} + } else { + try { + node.setAttribute(name, ''); + } catch (_) {} + } + } + }; + + /** + * _initDocument + * + * @param {String} dirty a string of dirty markup + * @return {Document} a DOM, filled with the dirty markup + */ + var _initDocument = function _initDocument(dirty) { + /* Create a HTML document */ + var doc = void 0; + var leadingWhitespace = void 0; + + if (FORCE_BODY) { + dirty = '' + dirty; + } else { + /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ + var matches = stringMatch(dirty, /^[\r\n\t ]+/); + leadingWhitespace = matches && matches[0]; + } + + var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; + /* + * Use the DOMParser API by default, fallback later if needs be + * DOMParser not work for svg when has multiple root element. + */ + if (NAMESPACE === HTML_NAMESPACE) { + try { + doc = new DOMParser().parseFromString(dirtyPayload, 'text/html'); + } catch (_) {} + } + + /* Use createHTMLDocument in case DOMParser is not available */ + if (!doc || !doc.documentElement) { + doc = implementation.createDocument(NAMESPACE, 'template', null); + try { + doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload; + } catch (_) { + // Syntax error if dirtyPayload is invalid xml + } + } + + var body = doc.body || doc.documentElement; + + if (dirty && leadingWhitespace) { + body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); + } + + /* Work on whole document or just its body */ + if (NAMESPACE === HTML_NAMESPACE) { + return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; + } + + return WHOLE_DOCUMENT ? doc.documentElement : body; + }; + + /** + * _createIterator + * + * @param {Document} root document/fragment to create iterator for + * @return {Iterator} iterator instance + */ + var _createIterator = function _createIterator(root) { + return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false); + }; + + /** + * _isClobbered + * + * @param {Node} elm element to check for clobbering attacks + * @return {Boolean} true if clobbered, false if safe + */ + var _isClobbered = function _isClobbered(elm) { + if (elm instanceof Text || elm instanceof Comment) { + return false; + } + + if (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function') { + return true; + } + + return false; + }; + + /** + * _isNode + * + * @param {Node} obj object to check whether it's a DOM node + * @return {Boolean} true is object is a DOM node + */ + var _isNode = function _isNode(object) { + return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'; + }; + + /** + * _executeHook + * Execute user configurable hooks + * + * @param {String} entryPoint Name of the hook's entry point + * @param {Node} currentNode node to work on with the hook + * @param {Object} data additional hook parameters + */ + var _executeHook = function _executeHook(entryPoint, currentNode, data) { + if (!hooks[entryPoint]) { + return; + } + + arrayForEach(hooks[entryPoint], function (hook) { + hook.call(DOMPurify, currentNode, data, CONFIG); + }); + }; + + /** + * _sanitizeElements + * + * @protect nodeName + * @protect textContent + * @protect removeChild + * + * @param {Node} currentNode to check for permission to exist + * @return {Boolean} true if node was killed, false if left alive + */ + var _sanitizeElements = function _sanitizeElements(currentNode) { + var content = void 0; + + /* Execute a hook if present */ + _executeHook('beforeSanitizeElements', currentNode, null); + + /* Check if element is clobbered or can clobber */ + if (_isClobbered(currentNode)) { + _forceRemove(currentNode); + return true; + } + + /* Check if tagname contains Unicode */ + if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) { + _forceRemove(currentNode); + return true; + } + + /* Now let's check the element's type and name */ + var tagName = stringToLowerCase(currentNode.nodeName); + + /* Execute a hook if present */ + _executeHook('uponSanitizeElement', currentNode, { + tagName: tagName, + allowedTags: ALLOWED_TAGS + }); + + /* Detect mXSS attempts abusing namespace confusion */ + if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { + _forceRemove(currentNode); + return true; + } + + /* Mitigate a problem with templates inside select */ + if (tagName === 'select' && regExpTest(/ + // To cover cases of empty s, avoid using a range and use the 's bounding box + const clientRects = domNode.children[startChildIndex].getClientRects(); + context.markDidDomLayout(); + return this._createHorizontalRangesFromClientRects(clientRects, context.clientRectDeltaLeft, context.clientRectScale); + } + // If crossing over to a span only to select offset 0, then use the previous span's maximum offset + // Chrome is buggy and doesn't handle 0 offsets well sometimes. + if (startChildIndex !== endChildIndex) { + if (endChildIndex > 0 && endOffset === 0) { + endChildIndex--; + endOffset = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */; + } + } + let startElement = domNode.children[startChildIndex].firstChild; + let endElement = domNode.children[endChildIndex].firstChild; + if (!startElement || !endElement) { + // When having an empty (without any text content), try to move to the previous + if (!startElement && startOffset === 0 && startChildIndex > 0) { + startElement = domNode.children[startChildIndex - 1].firstChild; + startOffset = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */; + } + if (!endElement && endOffset === 0 && endChildIndex > 0) { + endElement = domNode.children[endChildIndex - 1].firstChild; + endOffset = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */; + } + } + if (!startElement || !endElement) { + return null; + } + startOffset = Math.min(startElement.textContent.length, Math.max(0, startOffset)); + endOffset = Math.min(endElement.textContent.length, Math.max(0, endOffset)); + const clientRects = this._readClientRects(startElement, startOffset, endElement, endOffset, context.endNode); + context.markDidDomLayout(); + return this._createHorizontalRangesFromClientRects(clientRects, context.clientRectDeltaLeft, context.clientRectScale); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class LineDecoration { + constructor(startColumn, endColumn, className, type) { + this.startColumn = startColumn; + this.endColumn = endColumn; + this.className = className; + this.type = type; + this._lineDecorationBrand = undefined; + } + static _equals(a, b) { + return (a.startColumn === b.startColumn + && a.endColumn === b.endColumn + && a.className === b.className + && a.type === b.type); + } + static equalsArr(a, b) { + const aLen = a.length; + const bLen = b.length; + if (aLen !== bLen) { + return false; + } + for (let i = 0; i < aLen; i++) { + if (!LineDecoration._equals(a[i], b[i])) { + return false; + } + } + return true; + } + static extractWrapped(arr, startOffset, endOffset) { + if (arr.length === 0) { + return arr; + } + const startColumn = startOffset + 1; + const endColumn = endOffset + 1; + const lineLength = endOffset - startOffset; + const r = []; + let rLength = 0; + for (const dec of arr) { + if (dec.endColumn <= startColumn || dec.startColumn >= endColumn) { + continue; + } + r[rLength++] = new LineDecoration(Math.max(1, dec.startColumn - startColumn + 1), Math.min(lineLength + 1, dec.endColumn - startColumn + 1), dec.className, dec.type); + } + return r; + } + static filter(lineDecorations, lineNumber, minLineColumn, maxLineColumn) { + if (lineDecorations.length === 0) { + return []; + } + const result = []; + let resultLen = 0; + for (let i = 0, len = lineDecorations.length; i < len; i++) { + const d = lineDecorations[i]; + const range = d.range; + if (range.endLineNumber < lineNumber || range.startLineNumber > lineNumber) { + // Ignore decorations that sit outside this line + continue; + } + if (range.isEmpty() && (d.type === 0 /* InlineDecorationType.Regular */ || d.type === 3 /* InlineDecorationType.RegularAffectingLetterSpacing */)) { + // Ignore empty range decorations + continue; + } + const startColumn = (range.startLineNumber === lineNumber ? range.startColumn : minLineColumn); + const endColumn = (range.endLineNumber === lineNumber ? range.endColumn : maxLineColumn); + result[resultLen++] = new LineDecoration(startColumn, endColumn, d.inlineClassName, d.type); + } + return result; + } + static _typeCompare(a, b) { + const ORDER = [2, 0, 1, 3]; + return ORDER[a] - ORDER[b]; + } + static compare(a, b) { + if (a.startColumn !== b.startColumn) { + return a.startColumn - b.startColumn; + } + if (a.endColumn !== b.endColumn) { + return a.endColumn - b.endColumn; + } + const typeCmp = LineDecoration._typeCompare(a.type, b.type); + if (typeCmp !== 0) { + return typeCmp; + } + if (a.className !== b.className) { + return a.className < b.className ? -1 : 1; + } + return 0; + } +} +class DecorationSegment { + constructor(startOffset, endOffset, className, metadata) { + this.startOffset = startOffset; + this.endOffset = endOffset; + this.className = className; + this.metadata = metadata; + } +} +class Stack { + constructor() { + this.stopOffsets = []; + this.classNames = []; + this.metadata = []; + this.count = 0; + } + static _metadata(metadata) { + let result = 0; + for (let i = 0, len = metadata.length; i < len; i++) { + result |= metadata[i]; + } + return result; + } + consumeLowerThan(maxStopOffset, nextStartOffset, result) { + while (this.count > 0 && this.stopOffsets[0] < maxStopOffset) { + let i = 0; + // Take all equal stopping offsets + while (i + 1 < this.count && this.stopOffsets[i] === this.stopOffsets[i + 1]) { + i++; + } + // Basically we are consuming the first i + 1 elements of the stack + result.push(new DecorationSegment(nextStartOffset, this.stopOffsets[i], this.classNames.join(' '), Stack._metadata(this.metadata))); + nextStartOffset = this.stopOffsets[i] + 1; + // Consume them + this.stopOffsets.splice(0, i + 1); + this.classNames.splice(0, i + 1); + this.metadata.splice(0, i + 1); + this.count -= (i + 1); + } + if (this.count > 0 && nextStartOffset < maxStopOffset) { + result.push(new DecorationSegment(nextStartOffset, maxStopOffset - 1, this.classNames.join(' '), Stack._metadata(this.metadata))); + nextStartOffset = maxStopOffset; + } + return nextStartOffset; + } + insert(stopOffset, className, metadata) { + if (this.count === 0 || this.stopOffsets[this.count - 1] <= stopOffset) { + // Insert at the end + this.stopOffsets.push(stopOffset); + this.classNames.push(className); + this.metadata.push(metadata); + } + else { + // Find the insertion position for `stopOffset` + for (let i = 0; i < this.count; i++) { + if (this.stopOffsets[i] >= stopOffset) { + this.stopOffsets.splice(i, 0, stopOffset); + this.classNames.splice(i, 0, className); + this.metadata.splice(i, 0, metadata); + break; + } + } + } + this.count++; + return; + } +} +class LineDecorationsNormalizer { + /** + * Normalize line decorations. Overlapping decorations will generate multiple segments + */ + static normalize(lineContent, lineDecorations) { + if (lineDecorations.length === 0) { + return []; + } + const result = []; + const stack = new Stack(); + let nextStartOffset = 0; + for (let i = 0, len = lineDecorations.length; i < len; i++) { + const d = lineDecorations[i]; + let startColumn = d.startColumn; + let endColumn = d.endColumn; + const className = d.className; + const metadata = (d.type === 1 /* InlineDecorationType.Before */ + ? 2 /* LinePartMetadata.PSEUDO_BEFORE */ + : d.type === 2 /* InlineDecorationType.After */ + ? 4 /* LinePartMetadata.PSEUDO_AFTER */ + : 0); + // If the position would end up in the middle of a high-low surrogate pair, we move it to before the pair + if (startColumn > 1) { + const charCodeBefore = lineContent.charCodeAt(startColumn - 2); + if (isHighSurrogate(charCodeBefore)) { + startColumn--; + } + } + if (endColumn > 1) { + const charCodeBefore = lineContent.charCodeAt(endColumn - 2); + if (isHighSurrogate(charCodeBefore)) { + endColumn--; + } + } + const currentStartOffset = startColumn - 1; + const currentEndOffset = endColumn - 2; + nextStartOffset = stack.consumeLowerThan(currentStartOffset, nextStartOffset, result); + if (stack.count === 0) { + nextStartOffset = currentStartOffset; + } + stack.insert(currentEndOffset, className, metadata); + } + stack.consumeLowerThan(1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, nextStartOffset, result); + return result; + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class LinePart { + constructor( + /** + * last char index of this token (not inclusive). + */ + endIndex, type, metadata, containsRTL) { + this.endIndex = endIndex; + this.type = type; + this.metadata = metadata; + this.containsRTL = containsRTL; + this._linePartBrand = undefined; + } + isWhitespace() { + return (this.metadata & 1 /* LinePartMetadata.IS_WHITESPACE_MASK */ ? true : false); + } + isPseudoAfter() { + return (this.metadata & 4 /* LinePartMetadata.PSEUDO_AFTER_MASK */ ? true : false); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +let LineRange$1 = class LineRange { + constructor(startIndex, endIndex) { + this.startOffset = startIndex; + this.endOffset = endIndex; + } + equals(otherLineRange) { + return this.startOffset === otherLineRange.startOffset + && this.endOffset === otherLineRange.endOffset; + } +}; +class RenderLineInput { + constructor(useMonospaceOptimizations, canUseHalfwidthRightwardsArrow, lineContent, continuesWithWrappedLine, isBasicASCII, containsRTL, fauxIndentLength, lineTokens, lineDecorations, tabSize, startVisibleColumn, spaceWidth, middotWidth, wsmiddotWidth, stopRenderingLineAfter, renderWhitespace, renderControlCharacters, fontLigatures, selectionsOnLine) { + this.useMonospaceOptimizations = useMonospaceOptimizations; + this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow; + this.lineContent = lineContent; + this.continuesWithWrappedLine = continuesWithWrappedLine; + this.isBasicASCII = isBasicASCII; + this.containsRTL = containsRTL; + this.fauxIndentLength = fauxIndentLength; + this.lineTokens = lineTokens; + this.lineDecorations = lineDecorations.sort(LineDecoration.compare); + this.tabSize = tabSize; + this.startVisibleColumn = startVisibleColumn; + this.spaceWidth = spaceWidth; + this.stopRenderingLineAfter = stopRenderingLineAfter; + this.renderWhitespace = (renderWhitespace === 'all' + ? 4 /* RenderWhitespace.All */ + : renderWhitespace === 'boundary' + ? 1 /* RenderWhitespace.Boundary */ + : renderWhitespace === 'selection' + ? 2 /* RenderWhitespace.Selection */ + : renderWhitespace === 'trailing' + ? 3 /* RenderWhitespace.Trailing */ + : 0 /* RenderWhitespace.None */); + this.renderControlCharacters = renderControlCharacters; + this.fontLigatures = fontLigatures; + this.selectionsOnLine = selectionsOnLine && selectionsOnLine.sort((a, b) => a.startOffset < b.startOffset ? -1 : 1); + const wsmiddotDiff = Math.abs(wsmiddotWidth - spaceWidth); + const middotDiff = Math.abs(middotWidth - spaceWidth); + if (wsmiddotDiff < middotDiff) { + this.renderSpaceWidth = wsmiddotWidth; + this.renderSpaceCharCode = 0x2E31; // U+2E31 - WORD SEPARATOR MIDDLE DOT + } + else { + this.renderSpaceWidth = middotWidth; + this.renderSpaceCharCode = 0xB7; // U+00B7 - MIDDLE DOT + } + } + sameSelection(otherSelections) { + if (this.selectionsOnLine === null) { + return otherSelections === null; + } + if (otherSelections === null) { + return false; + } + if (otherSelections.length !== this.selectionsOnLine.length) { + return false; + } + for (let i = 0; i < this.selectionsOnLine.length; i++) { + if (!this.selectionsOnLine[i].equals(otherSelections[i])) { + return false; + } + } + return true; + } + equals(other) { + return (this.useMonospaceOptimizations === other.useMonospaceOptimizations + && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow + && this.lineContent === other.lineContent + && this.continuesWithWrappedLine === other.continuesWithWrappedLine + && this.isBasicASCII === other.isBasicASCII + && this.containsRTL === other.containsRTL + && this.fauxIndentLength === other.fauxIndentLength + && this.tabSize === other.tabSize + && this.startVisibleColumn === other.startVisibleColumn + && this.spaceWidth === other.spaceWidth + && this.renderSpaceWidth === other.renderSpaceWidth + && this.renderSpaceCharCode === other.renderSpaceCharCode + && this.stopRenderingLineAfter === other.stopRenderingLineAfter + && this.renderWhitespace === other.renderWhitespace + && this.renderControlCharacters === other.renderControlCharacters + && this.fontLigatures === other.fontLigatures + && LineDecoration.equalsArr(this.lineDecorations, other.lineDecorations) + && this.lineTokens.equals(other.lineTokens) + && this.sameSelection(other.selectionsOnLine)); + } +} +class DomPosition { + constructor(partIndex, charIndex) { + this.partIndex = partIndex; + this.charIndex = charIndex; + } +} +/** + * Provides a both direction mapping between a line's character and its rendered position. + */ +class CharacterMapping { + static getPartIndex(partData) { + return (partData & 4294901760 /* CharacterMappingConstants.PART_INDEX_MASK */) >>> 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */; + } + static getCharIndex(partData) { + return (partData & 65535 /* CharacterMappingConstants.CHAR_INDEX_MASK */) >>> 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */; + } + constructor(length, partCount) { + this.length = length; + this._data = new Uint32Array(this.length); + this._horizontalOffset = new Uint32Array(this.length); + } + setColumnInfo(column, partIndex, charIndex, horizontalOffset) { + const partData = ((partIndex << 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */) + | (charIndex << 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */)) >>> 0; + this._data[column - 1] = partData; + this._horizontalOffset[column - 1] = horizontalOffset; + } + getHorizontalOffset(column) { + if (this._horizontalOffset.length === 0) { + // No characters on this line + return 0; + } + return this._horizontalOffset[column - 1]; + } + charOffsetToPartData(charOffset) { + if (this.length === 0) { + return 0; + } + if (charOffset < 0) { + return this._data[0]; + } + if (charOffset >= this.length) { + return this._data[this.length - 1]; + } + return this._data[charOffset]; + } + getDomPosition(column) { + const partData = this.charOffsetToPartData(column - 1); + const partIndex = CharacterMapping.getPartIndex(partData); + const charIndex = CharacterMapping.getCharIndex(partData); + return new DomPosition(partIndex, charIndex); + } + getColumn(domPosition, partLength) { + const charOffset = this.partDataToCharOffset(domPosition.partIndex, partLength, domPosition.charIndex); + return charOffset + 1; + } + partDataToCharOffset(partIndex, partLength, charIndex) { + if (this.length === 0) { + return 0; + } + const searchEntry = ((partIndex << 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */) + | (charIndex << 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */)) >>> 0; + let min = 0; + let max = this.length - 1; + while (min + 1 < max) { + const mid = ((min + max) >>> 1); + const midEntry = this._data[mid]; + if (midEntry === searchEntry) { + return mid; + } + else if (midEntry > searchEntry) { + max = mid; + } + else { + min = mid; + } + } + if (min === max) { + return min; + } + const minEntry = this._data[min]; + const maxEntry = this._data[max]; + if (minEntry === searchEntry) { + return min; + } + if (maxEntry === searchEntry) { + return max; + } + const minPartIndex = CharacterMapping.getPartIndex(minEntry); + const minCharIndex = CharacterMapping.getCharIndex(minEntry); + const maxPartIndex = CharacterMapping.getPartIndex(maxEntry); + let maxCharIndex; + if (minPartIndex !== maxPartIndex) { + // sitting between parts + maxCharIndex = partLength; + } + else { + maxCharIndex = CharacterMapping.getCharIndex(maxEntry); + } + const minEntryDistance = charIndex - minCharIndex; + const maxEntryDistance = maxCharIndex - charIndex; + if (minEntryDistance <= maxEntryDistance) { + return min; + } + return max; + } +} +class RenderLineOutput { + constructor(characterMapping, containsRTL, containsForeignElements) { + this._renderLineOutputBrand = undefined; + this.characterMapping = characterMapping; + this.containsRTL = containsRTL; + this.containsForeignElements = containsForeignElements; + } +} +function renderViewLine(input, sb) { + if (input.lineContent.length === 0) { + if (input.lineDecorations.length > 0) { + // This line is empty, but it contains inline decorations + sb.appendString(``); + let beforeCount = 0; + let afterCount = 0; + let containsForeignElements = 0 /* ForeignElementType.None */; + for (const lineDecoration of input.lineDecorations) { + if (lineDecoration.type === 1 /* InlineDecorationType.Before */ || lineDecoration.type === 2 /* InlineDecorationType.After */) { + sb.appendString(``); + if (lineDecoration.type === 1 /* InlineDecorationType.Before */) { + containsForeignElements |= 1 /* ForeignElementType.Before */; + beforeCount++; + } + if (lineDecoration.type === 2 /* InlineDecorationType.After */) { + containsForeignElements |= 2 /* ForeignElementType.After */; + afterCount++; + } + } + } + sb.appendString(``); + const characterMapping = new CharacterMapping(1, beforeCount + afterCount); + characterMapping.setColumnInfo(1, beforeCount, 0, 0); + return new RenderLineOutput(characterMapping, false, containsForeignElements); + } + // completely empty line + sb.appendString(''); + return new RenderLineOutput(new CharacterMapping(0, 0), false, 0 /* ForeignElementType.None */); + } + return _renderLine(resolveRenderLineInput(input), sb); +} +class RenderLineOutput2 { + constructor(characterMapping, html, containsRTL, containsForeignElements) { + this.characterMapping = characterMapping; + this.html = html; + this.containsRTL = containsRTL; + this.containsForeignElements = containsForeignElements; + } +} +function renderViewLine2(input) { + const sb = new StringBuilder(10000); + const out = renderViewLine(input, sb); + return new RenderLineOutput2(out.characterMapping, sb.build(), out.containsRTL, out.containsForeignElements); +} +class ResolvedRenderLineInput { + constructor(fontIsMonospace, canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, overflowingCharCount, parts, containsForeignElements, fauxIndentLength, tabSize, startVisibleColumn, containsRTL, spaceWidth, renderSpaceCharCode, renderWhitespace, renderControlCharacters) { + this.fontIsMonospace = fontIsMonospace; + this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow; + this.lineContent = lineContent; + this.len = len; + this.isOverflowing = isOverflowing; + this.overflowingCharCount = overflowingCharCount; + this.parts = parts; + this.containsForeignElements = containsForeignElements; + this.fauxIndentLength = fauxIndentLength; + this.tabSize = tabSize; + this.startVisibleColumn = startVisibleColumn; + this.containsRTL = containsRTL; + this.spaceWidth = spaceWidth; + this.renderSpaceCharCode = renderSpaceCharCode; + this.renderWhitespace = renderWhitespace; + this.renderControlCharacters = renderControlCharacters; + // + } +} +function resolveRenderLineInput(input) { + const lineContent = input.lineContent; + let isOverflowing; + let overflowingCharCount; + let len; + if (input.stopRenderingLineAfter !== -1 && input.stopRenderingLineAfter < lineContent.length) { + isOverflowing = true; + overflowingCharCount = lineContent.length - input.stopRenderingLineAfter; + len = input.stopRenderingLineAfter; + } + else { + isOverflowing = false; + overflowingCharCount = 0; + len = lineContent.length; + } + let tokens = transformAndRemoveOverflowing(lineContent, input.containsRTL, input.lineTokens, input.fauxIndentLength, len); + if (input.renderControlCharacters && !input.isBasicASCII) { + // Calling `extractControlCharacters` before adding (possibly empty) line parts + // for inline decorations. `extractControlCharacters` removes empty line parts. + tokens = extractControlCharacters(lineContent, tokens); + } + if (input.renderWhitespace === 4 /* RenderWhitespace.All */ || + input.renderWhitespace === 1 /* RenderWhitespace.Boundary */ || + (input.renderWhitespace === 2 /* RenderWhitespace.Selection */ && !!input.selectionsOnLine) || + (input.renderWhitespace === 3 /* RenderWhitespace.Trailing */ && !input.continuesWithWrappedLine)) { + tokens = _applyRenderWhitespace(input, lineContent, len, tokens); + } + let containsForeignElements = 0 /* ForeignElementType.None */; + if (input.lineDecorations.length > 0) { + for (let i = 0, len = input.lineDecorations.length; i < len; i++) { + const lineDecoration = input.lineDecorations[i]; + if (lineDecoration.type === 3 /* InlineDecorationType.RegularAffectingLetterSpacing */) { + // Pretend there are foreign elements... although not 100% accurate. + containsForeignElements |= 1 /* ForeignElementType.Before */; + } + else if (lineDecoration.type === 1 /* InlineDecorationType.Before */) { + containsForeignElements |= 1 /* ForeignElementType.Before */; + } + else if (lineDecoration.type === 2 /* InlineDecorationType.After */) { + containsForeignElements |= 2 /* ForeignElementType.After */; + } + } + tokens = _applyInlineDecorations(lineContent, len, tokens, input.lineDecorations); + } + if (!input.containsRTL) { + // We can never split RTL text, as it ruins the rendering + tokens = splitLargeTokens(lineContent, tokens, !input.isBasicASCII || input.fontLigatures); + } + return new ResolvedRenderLineInput(input.useMonospaceOptimizations, input.canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, overflowingCharCount, tokens, containsForeignElements, input.fauxIndentLength, input.tabSize, input.startVisibleColumn, input.containsRTL, input.spaceWidth, input.renderSpaceCharCode, input.renderWhitespace, input.renderControlCharacters); +} +/** + * In the rendering phase, characters are always looped until token.endIndex. + * Ensure that all tokens end before `len` and the last one ends precisely at `len`. + */ +function transformAndRemoveOverflowing(lineContent, lineContainsRTL, tokens, fauxIndentLength, len) { + const result = []; + let resultLen = 0; + // The faux indent part of the line should have no token type + if (fauxIndentLength > 0) { + result[resultLen++] = new LinePart(fauxIndentLength, '', 0, false); + } + let startOffset = fauxIndentLength; + for (let tokenIndex = 0, tokensLen = tokens.getCount(); tokenIndex < tokensLen; tokenIndex++) { + const endIndex = tokens.getEndOffset(tokenIndex); + if (endIndex <= fauxIndentLength) { + // The faux indent part of the line should have no token type + continue; + } + const type = tokens.getClassName(tokenIndex); + if (endIndex >= len) { + const tokenContainsRTL = (lineContainsRTL ? containsRTL(lineContent.substring(startOffset, len)) : false); + result[resultLen++] = new LinePart(len, type, 0, tokenContainsRTL); + break; + } + const tokenContainsRTL = (lineContainsRTL ? containsRTL(lineContent.substring(startOffset, endIndex)) : false); + result[resultLen++] = new LinePart(endIndex, type, 0, tokenContainsRTL); + startOffset = endIndex; + } + return result; +} +/** + * See https://github.com/microsoft/vscode/issues/6885. + * It appears that having very large spans causes very slow reading of character positions. + * So here we try to avoid that. + */ +function splitLargeTokens(lineContent, tokens, onlyAtSpaces) { + let lastTokenEndIndex = 0; + const result = []; + let resultLen = 0; + if (onlyAtSpaces) { + // Split only at spaces => we need to walk each character + for (let i = 0, len = tokens.length; i < len; i++) { + const token = tokens[i]; + const tokenEndIndex = token.endIndex; + if (lastTokenEndIndex + 50 /* Constants.LongToken */ < tokenEndIndex) { + const tokenType = token.type; + const tokenMetadata = token.metadata; + const tokenContainsRTL = token.containsRTL; + let lastSpaceOffset = -1; + let currTokenStart = lastTokenEndIndex; + for (let j = lastTokenEndIndex; j < tokenEndIndex; j++) { + if (lineContent.charCodeAt(j) === 32 /* CharCode.Space */) { + lastSpaceOffset = j; + } + if (lastSpaceOffset !== -1 && j - currTokenStart >= 50 /* Constants.LongToken */) { + // Split at `lastSpaceOffset` + 1 + result[resultLen++] = new LinePart(lastSpaceOffset + 1, tokenType, tokenMetadata, tokenContainsRTL); + currTokenStart = lastSpaceOffset + 1; + lastSpaceOffset = -1; + } + } + if (currTokenStart !== tokenEndIndex) { + result[resultLen++] = new LinePart(tokenEndIndex, tokenType, tokenMetadata, tokenContainsRTL); + } + } + else { + result[resultLen++] = token; + } + lastTokenEndIndex = tokenEndIndex; + } + } + else { + // Split anywhere => we don't need to walk each character + for (let i = 0, len = tokens.length; i < len; i++) { + const token = tokens[i]; + const tokenEndIndex = token.endIndex; + const diff = (tokenEndIndex - lastTokenEndIndex); + if (diff > 50 /* Constants.LongToken */) { + const tokenType = token.type; + const tokenMetadata = token.metadata; + const tokenContainsRTL = token.containsRTL; + const piecesCount = Math.ceil(diff / 50 /* Constants.LongToken */); + for (let j = 1; j < piecesCount; j++) { + const pieceEndIndex = lastTokenEndIndex + (j * 50 /* Constants.LongToken */); + result[resultLen++] = new LinePart(pieceEndIndex, tokenType, tokenMetadata, tokenContainsRTL); + } + result[resultLen++] = new LinePart(tokenEndIndex, tokenType, tokenMetadata, tokenContainsRTL); + } + else { + result[resultLen++] = token; + } + lastTokenEndIndex = tokenEndIndex; + } + } + return result; +} +function isControlCharacter(charCode) { + if (charCode < 32) { + return (charCode !== 9 /* CharCode.Tab */); + } + if (charCode === 127) { + // DEL + return true; + } + if ((charCode >= 0x202A && charCode <= 0x202E) + || (charCode >= 0x2066 && charCode <= 0x2069) + || (charCode >= 0x200E && charCode <= 0x200F) + || charCode === 0x061C) { + // Unicode Directional Formatting Characters + // LRE U+202A LEFT-TO-RIGHT EMBEDDING + // RLE U+202B RIGHT-TO-LEFT EMBEDDING + // PDF U+202C POP DIRECTIONAL FORMATTING + // LRO U+202D LEFT-TO-RIGHT OVERRIDE + // RLO U+202E RIGHT-TO-LEFT OVERRIDE + // LRI U+2066 LEFT-TO-RIGHT ISOLATE + // RLI U+2067 RIGHT-TO-LEFT ISOLATE + // FSI U+2068 FIRST STRONG ISOLATE + // PDI U+2069 POP DIRECTIONAL ISOLATE + // LRM U+200E LEFT-TO-RIGHT MARK + // RLM U+200F RIGHT-TO-LEFT MARK + // ALM U+061C ARABIC LETTER MARK + return true; + } + return false; +} +function extractControlCharacters(lineContent, tokens) { + const result = []; + let lastLinePart = new LinePart(0, '', 0, false); + let charOffset = 0; + for (const token of tokens) { + const tokenEndIndex = token.endIndex; + for (; charOffset < tokenEndIndex; charOffset++) { + const charCode = lineContent.charCodeAt(charOffset); + if (isControlCharacter(charCode)) { + if (charOffset > lastLinePart.endIndex) { + // emit previous part if it has text + lastLinePart = new LinePart(charOffset, token.type, token.metadata, token.containsRTL); + result.push(lastLinePart); + } + lastLinePart = new LinePart(charOffset + 1, 'mtkcontrol', token.metadata, false); + result.push(lastLinePart); + } + } + if (charOffset > lastLinePart.endIndex) { + // emit previous part if it has text + lastLinePart = new LinePart(tokenEndIndex, token.type, token.metadata, token.containsRTL); + result.push(lastLinePart); + } + } + return result; +} +/** + * Whitespace is rendered by "replacing" tokens with a special-purpose `mtkw` type that is later recognized in the rendering phase. + * Moreover, a token is created for every visual indent because on some fonts the glyphs used for rendering whitespace (→ or ·) do not have the same width as  . + * The rendering phase will generate `style="width:..."` for these tokens. + */ +function _applyRenderWhitespace(input, lineContent, len, tokens) { + const continuesWithWrappedLine = input.continuesWithWrappedLine; + const fauxIndentLength = input.fauxIndentLength; + const tabSize = input.tabSize; + const startVisibleColumn = input.startVisibleColumn; + const useMonospaceOptimizations = input.useMonospaceOptimizations; + const selections = input.selectionsOnLine; + const onlyBoundary = (input.renderWhitespace === 1 /* RenderWhitespace.Boundary */); + const onlyTrailing = (input.renderWhitespace === 3 /* RenderWhitespace.Trailing */); + const generateLinePartForEachWhitespace = (input.renderSpaceWidth !== input.spaceWidth); + const result = []; + let resultLen = 0; + let tokenIndex = 0; + let tokenType = tokens[tokenIndex].type; + let tokenContainsRTL = tokens[tokenIndex].containsRTL; + let tokenEndIndex = tokens[tokenIndex].endIndex; + const tokensLength = tokens.length; + let lineIsEmptyOrWhitespace = false; + let firstNonWhitespaceIndex$1 = firstNonWhitespaceIndex(lineContent); + let lastNonWhitespaceIndex$1; + if (firstNonWhitespaceIndex$1 === -1) { + lineIsEmptyOrWhitespace = true; + firstNonWhitespaceIndex$1 = len; + lastNonWhitespaceIndex$1 = len; + } + else { + lastNonWhitespaceIndex$1 = lastNonWhitespaceIndex(lineContent); + } + let wasInWhitespace = false; + let currentSelectionIndex = 0; + let currentSelection = selections && selections[currentSelectionIndex]; + let tmpIndent = startVisibleColumn % tabSize; + for (let charIndex = fauxIndentLength; charIndex < len; charIndex++) { + const chCode = lineContent.charCodeAt(charIndex); + if (currentSelection && charIndex >= currentSelection.endOffset) { + currentSelectionIndex++; + currentSelection = selections && selections[currentSelectionIndex]; + } + let isInWhitespace; + if (charIndex < firstNonWhitespaceIndex$1 || charIndex > lastNonWhitespaceIndex$1) { + // in leading or trailing whitespace + isInWhitespace = true; + } + else if (chCode === 9 /* CharCode.Tab */) { + // a tab character is rendered both in all and boundary cases + isInWhitespace = true; + } + else if (chCode === 32 /* CharCode.Space */) { + // hit a space character + if (onlyBoundary) { + // rendering only boundary whitespace + if (wasInWhitespace) { + isInWhitespace = true; + } + else { + const nextChCode = (charIndex + 1 < len ? lineContent.charCodeAt(charIndex + 1) : 0 /* CharCode.Null */); + isInWhitespace = (nextChCode === 32 /* CharCode.Space */ || nextChCode === 9 /* CharCode.Tab */); + } + } + else { + isInWhitespace = true; + } + } + else { + isInWhitespace = false; + } + // If rendering whitespace on selection, check that the charIndex falls within a selection + if (isInWhitespace && selections) { + isInWhitespace = !!currentSelection && currentSelection.startOffset <= charIndex && currentSelection.endOffset > charIndex; + } + // If rendering only trailing whitespace, check that the charIndex points to trailing whitespace. + if (isInWhitespace && onlyTrailing) { + isInWhitespace = lineIsEmptyOrWhitespace || charIndex > lastNonWhitespaceIndex$1; + } + if (isInWhitespace && tokenContainsRTL) { + // If the token contains RTL text, breaking it up into multiple line parts + // to render whitespace might affect the browser's bidi layout. + // + // We render whitespace in such tokens only if the whitespace + // is the leading or the trailing whitespace of the line, + // which doesn't affect the browser's bidi layout. + if (charIndex >= firstNonWhitespaceIndex$1 && charIndex <= lastNonWhitespaceIndex$1) { + isInWhitespace = false; + } + } + if (wasInWhitespace) { + // was in whitespace token + if (!isInWhitespace || (!useMonospaceOptimizations && tmpIndent >= tabSize)) { + // leaving whitespace token or entering a new indent + if (generateLinePartForEachWhitespace) { + const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength); + for (let i = lastEndIndex + 1; i <= charIndex; i++) { + result[resultLen++] = new LinePart(i, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false); + } + } + else { + result[resultLen++] = new LinePart(charIndex, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false); + } + tmpIndent = tmpIndent % tabSize; + } + } + else { + // was in regular token + if (charIndex === tokenEndIndex || (isInWhitespace && charIndex > fauxIndentLength)) { + result[resultLen++] = new LinePart(charIndex, tokenType, 0, tokenContainsRTL); + tmpIndent = tmpIndent % tabSize; + } + } + if (chCode === 9 /* CharCode.Tab */) { + tmpIndent = tabSize; + } + else if (isFullWidthCharacter(chCode)) { + tmpIndent += 2; + } + else { + tmpIndent++; + } + wasInWhitespace = isInWhitespace; + while (charIndex === tokenEndIndex) { + tokenIndex++; + if (tokenIndex < tokensLength) { + tokenType = tokens[tokenIndex].type; + tokenContainsRTL = tokens[tokenIndex].containsRTL; + tokenEndIndex = tokens[tokenIndex].endIndex; + } + else { + break; + } + } + } + let generateWhitespace = false; + if (wasInWhitespace) { + // was in whitespace token + if (continuesWithWrappedLine && onlyBoundary) { + const lastCharCode = (len > 0 ? lineContent.charCodeAt(len - 1) : 0 /* CharCode.Null */); + const prevCharCode = (len > 1 ? lineContent.charCodeAt(len - 2) : 0 /* CharCode.Null */); + const isSingleTrailingSpace = (lastCharCode === 32 /* CharCode.Space */ && (prevCharCode !== 32 /* CharCode.Space */ && prevCharCode !== 9 /* CharCode.Tab */)); + if (!isSingleTrailingSpace) { + generateWhitespace = true; + } + } + else { + generateWhitespace = true; + } + } + if (generateWhitespace) { + if (generateLinePartForEachWhitespace) { + const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength); + for (let i = lastEndIndex + 1; i <= len; i++) { + result[resultLen++] = new LinePart(i, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false); + } + } + else { + result[resultLen++] = new LinePart(len, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false); + } + } + else { + result[resultLen++] = new LinePart(len, tokenType, 0, tokenContainsRTL); + } + return result; +} +/** + * Inline decorations are "merged" on top of tokens. + * Special care must be taken when multiple inline decorations are at play and they overlap. + */ +function _applyInlineDecorations(lineContent, len, tokens, _lineDecorations) { + _lineDecorations.sort(LineDecoration.compare); + const lineDecorations = LineDecorationsNormalizer.normalize(lineContent, _lineDecorations); + const lineDecorationsLen = lineDecorations.length; + let lineDecorationIndex = 0; + const result = []; + let resultLen = 0; + let lastResultEndIndex = 0; + for (let tokenIndex = 0, len = tokens.length; tokenIndex < len; tokenIndex++) { + const token = tokens[tokenIndex]; + const tokenEndIndex = token.endIndex; + const tokenType = token.type; + const tokenMetadata = token.metadata; + const tokenContainsRTL = token.containsRTL; + while (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset < tokenEndIndex) { + const lineDecoration = lineDecorations[lineDecorationIndex]; + if (lineDecoration.startOffset > lastResultEndIndex) { + lastResultEndIndex = lineDecoration.startOffset; + result[resultLen++] = new LinePart(lastResultEndIndex, tokenType, tokenMetadata, tokenContainsRTL); + } + if (lineDecoration.endOffset + 1 <= tokenEndIndex) { + // This line decoration ends before this token ends + lastResultEndIndex = lineDecoration.endOffset + 1; + result[resultLen++] = new LinePart(lastResultEndIndex, tokenType + ' ' + lineDecoration.className, tokenMetadata | lineDecoration.metadata, tokenContainsRTL); + lineDecorationIndex++; + } + else { + // This line decoration continues on to the next token + lastResultEndIndex = tokenEndIndex; + result[resultLen++] = new LinePart(lastResultEndIndex, tokenType + ' ' + lineDecoration.className, tokenMetadata | lineDecoration.metadata, tokenContainsRTL); + break; + } + } + if (tokenEndIndex > lastResultEndIndex) { + lastResultEndIndex = tokenEndIndex; + result[resultLen++] = new LinePart(lastResultEndIndex, tokenType, tokenMetadata, tokenContainsRTL); + } + } + const lastTokenEndIndex = tokens[tokens.length - 1].endIndex; + if (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset === lastTokenEndIndex) { + while (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset === lastTokenEndIndex) { + const lineDecoration = lineDecorations[lineDecorationIndex]; + result[resultLen++] = new LinePart(lastResultEndIndex, lineDecoration.className, lineDecoration.metadata, false); + lineDecorationIndex++; + } + } + return result; +} +/** + * This function is on purpose not split up into multiple functions to allow runtime type inference (i.e. performance reasons). + * Notice how all the needed data is fully resolved and passed in (i.e. no other calls). + */ +function _renderLine(input, sb) { + const fontIsMonospace = input.fontIsMonospace; + const canUseHalfwidthRightwardsArrow = input.canUseHalfwidthRightwardsArrow; + const containsForeignElements = input.containsForeignElements; + const lineContent = input.lineContent; + const len = input.len; + const isOverflowing = input.isOverflowing; + const overflowingCharCount = input.overflowingCharCount; + const parts = input.parts; + const fauxIndentLength = input.fauxIndentLength; + const tabSize = input.tabSize; + const startVisibleColumn = input.startVisibleColumn; + const containsRTL = input.containsRTL; + const spaceWidth = input.spaceWidth; + const renderSpaceCharCode = input.renderSpaceCharCode; + const renderWhitespace = input.renderWhitespace; + const renderControlCharacters = input.renderControlCharacters; + const characterMapping = new CharacterMapping(len + 1, parts.length); + let lastCharacterMappingDefined = false; + let charIndex = 0; + let visibleColumn = startVisibleColumn; + let charOffsetInPart = 0; // the character offset in the current part + let charHorizontalOffset = 0; // the character horizontal position in terms of chars relative to line start + let partDisplacement = 0; + if (containsRTL) { + sb.appendString(''); + } + else { + sb.appendString(''); + } + for (let partIndex = 0, tokensLen = parts.length; partIndex < tokensLen; partIndex++) { + const part = parts[partIndex]; + const partEndIndex = part.endIndex; + const partType = part.type; + const partContainsRTL = part.containsRTL; + const partRendersWhitespace = (renderWhitespace !== 0 /* RenderWhitespace.None */ && part.isWhitespace()); + const partRendersWhitespaceWithWidth = partRendersWhitespace && !fontIsMonospace && (partType === 'mtkw' /*only whitespace*/ || !containsForeignElements); + const partIsEmptyAndHasPseudoAfter = (charIndex === partEndIndex && part.isPseudoAfter()); + charOffsetInPart = 0; + sb.appendString(' 1) { + sb.appendCharCode(0x2192); // RIGHTWARDS ARROW + } + else { + sb.appendCharCode(0xFFEB); // HALFWIDTH RIGHTWARDS ARROW + } + for (let space = 2; space <= charWidth; space++) { + sb.appendCharCode(0xA0); //   + } + } + else { // must be CharCode.Space + producedCharacters = 2; + charWidth = 1; + sb.appendCharCode(renderSpaceCharCode); // · or word separator middle dot + sb.appendCharCode(0x200C); // ZERO WIDTH NON-JOINER + } + charOffsetInPart += producedCharacters; + charHorizontalOffset += charWidth; + if (charIndex >= fauxIndentLength) { + visibleColumn += charWidth; + } + } + } + else { + sb.appendASCIICharCode(62 /* CharCode.GreaterThan */); + for (; charIndex < partEndIndex; charIndex++) { + characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, charHorizontalOffset); + partDisplacement = 0; + const charCode = lineContent.charCodeAt(charIndex); + let producedCharacters = 1; + let charWidth = 1; + switch (charCode) { + case 9 /* CharCode.Tab */: + producedCharacters = (tabSize - (visibleColumn % tabSize)); + charWidth = producedCharacters; + for (let space = 1; space <= producedCharacters; space++) { + sb.appendCharCode(0xA0); //   + } + break; + case 32 /* CharCode.Space */: + sb.appendCharCode(0xA0); //   + break; + case 60 /* CharCode.LessThan */: + sb.appendString('<'); + break; + case 62 /* CharCode.GreaterThan */: + sb.appendString('>'); + break; + case 38 /* CharCode.Ampersand */: + sb.appendString('&'); + break; + case 0 /* CharCode.Null */: + if (renderControlCharacters) { + // See https://unicode-table.com/en/blocks/control-pictures/ + sb.appendCharCode(9216); + } + else { + sb.appendString('�'); + } + break; + case 65279 /* CharCode.UTF8_BOM */: + case 8232 /* CharCode.LINE_SEPARATOR */: + case 8233 /* CharCode.PARAGRAPH_SEPARATOR */: + case 133 /* CharCode.NEXT_LINE */: + sb.appendCharCode(0xFFFD); + break; + default: + if (isFullWidthCharacter(charCode)) { + charWidth++; + } + // See https://unicode-table.com/en/blocks/control-pictures/ + if (renderControlCharacters && charCode < 32) { + sb.appendCharCode(9216 + charCode); + } + else if (renderControlCharacters && charCode === 127) { + // DEL + sb.appendCharCode(9249); + } + else if (renderControlCharacters && isControlCharacter(charCode)) { + sb.appendString('[U+'); + sb.appendString(to4CharHex(charCode)); + sb.appendString(']'); + producedCharacters = 8; + charWidth = producedCharacters; + } + else { + sb.appendCharCode(charCode); + } + } + charOffsetInPart += producedCharacters; + charHorizontalOffset += charWidth; + if (charIndex >= fauxIndentLength) { + visibleColumn += charWidth; + } + } + } + if (partIsEmptyAndHasPseudoAfter) { + partDisplacement++; + } + else { + partDisplacement = 0; + } + if (charIndex >= len && !lastCharacterMappingDefined && part.isPseudoAfter()) { + lastCharacterMappingDefined = true; + characterMapping.setColumnInfo(charIndex + 1, partIndex, charOffsetInPart, charHorizontalOffset); + } + sb.appendString(''); + } + if (!lastCharacterMappingDefined) { + // When getting client rects for the last character, we will position the + // text range at the end of the span, insteaf of at the beginning of next span + characterMapping.setColumnInfo(len + 1, parts.length - 1, charOffsetInPart, charHorizontalOffset); + } + if (isOverflowing) { + sb.appendString(''); + sb.appendString(localize$2('showMore', "Show more ({0})", renderOverflowingCharCount(overflowingCharCount))); + sb.appendString(''); + } + sb.appendString(''); + return new RenderLineOutput(characterMapping, containsRTL, containsForeignElements); +} +function to4CharHex(n) { + return n.toString(16).toUpperCase().padStart(4, '0'); +} +function renderOverflowingCharCount(n) { + if (n < 1024) { + return localize$2('overflow.chars', "{0} chars", n); + } + if (n < 1024 * 1024) { + return `${(n / 1024).toFixed(1)} KB`; + } + return `${(n / 1024 / 1024).toFixed(1)} MB`; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * Color scheme used by the OS and by color themes. + */ +var ColorScheme; +(function (ColorScheme) { + ColorScheme["DARK"] = "dark"; + ColorScheme["LIGHT"] = "light"; + ColorScheme["HIGH_CONTRAST_DARK"] = "hcDark"; + ColorScheme["HIGH_CONTRAST_LIGHT"] = "hcLight"; +})(ColorScheme || (ColorScheme = {})); +function isHighContrast(scheme) { + return scheme === ColorScheme.HIGH_CONTRAST_DARK || scheme === ColorScheme.HIGH_CONTRAST_LIGHT; +} +function isDark(scheme) { + return scheme === ColorScheme.DARK || scheme === ColorScheme.HIGH_CONTRAST_DARK; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const canUseFastRenderedViewLine = (function () { + if (isNative) { + // In VSCode we know very well when the zoom level changes + return true; + } + if (isLinux || isFirefox || isSafari) { + // On Linux, it appears that zooming affects char widths (in pixels), which is unexpected. + // -- + // Even though we read character widths correctly, having read them at a specific zoom level + // does not mean they are the same at the current zoom level. + // -- + // This could be improved if we ever figure out how to get an event when browsers zoom, + // but until then we have to stick with reading client rects. + // -- + // The same has been observed with Firefox on Windows7 + // -- + // The same has been oversved with Safari + return false; + } + return true; +})(); +let monospaceAssumptionsAreValid = true; +class ViewLineOptions { + constructor(config, themeType) { + this.themeType = themeType; + const options = config.options; + const fontInfo = options.get(48 /* EditorOption.fontInfo */); + const experimentalWhitespaceRendering = options.get(36 /* EditorOption.experimentalWhitespaceRendering */); + if (experimentalWhitespaceRendering === 'off') { + this.renderWhitespace = options.get(94 /* EditorOption.renderWhitespace */); + } + else { + // whitespace is rendered in a different layer + this.renderWhitespace = 'none'; + } + this.renderControlCharacters = options.get(89 /* EditorOption.renderControlCharacters */); + this.spaceWidth = fontInfo.spaceWidth; + this.middotWidth = fontInfo.middotWidth; + this.wsmiddotWidth = fontInfo.wsmiddotWidth; + this.useMonospaceOptimizations = (fontInfo.isMonospace + && !options.get(31 /* EditorOption.disableMonospaceOptimizations */)); + this.canUseHalfwidthRightwardsArrow = fontInfo.canUseHalfwidthRightwardsArrow; + this.lineHeight = options.get(64 /* EditorOption.lineHeight */); + this.stopRenderingLineAfter = options.get(112 /* EditorOption.stopRenderingLineAfter */); + this.fontLigatures = options.get(49 /* EditorOption.fontLigatures */); + } + equals(other) { + return (this.themeType === other.themeType + && this.renderWhitespace === other.renderWhitespace + && this.renderControlCharacters === other.renderControlCharacters + && this.spaceWidth === other.spaceWidth + && this.middotWidth === other.middotWidth + && this.wsmiddotWidth === other.wsmiddotWidth + && this.useMonospaceOptimizations === other.useMonospaceOptimizations + && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow + && this.lineHeight === other.lineHeight + && this.stopRenderingLineAfter === other.stopRenderingLineAfter + && this.fontLigatures === other.fontLigatures); + } +} +class ViewLine { + constructor(options) { + this._options = options; + this._isMaybeInvalid = true; + this._renderedViewLine = null; + } + // --- begin IVisibleLineData + getDomNode() { + if (this._renderedViewLine && this._renderedViewLine.domNode) { + return this._renderedViewLine.domNode.domNode; + } + return null; + } + setDomNode(domNode) { + if (this._renderedViewLine) { + this._renderedViewLine.domNode = createFastDomNode(domNode); + } + else { + throw new Error('I have no rendered view line to set the dom node to...'); + } + } + onContentChanged() { + this._isMaybeInvalid = true; + } + onTokensChanged() { + this._isMaybeInvalid = true; + } + onDecorationsChanged() { + this._isMaybeInvalid = true; + } + onOptionsChanged(newOptions) { + this._isMaybeInvalid = true; + this._options = newOptions; + } + onSelectionChanged() { + if (isHighContrast(this._options.themeType) || this._options.renderWhitespace === 'selection') { + this._isMaybeInvalid = true; + return true; + } + return false; + } + renderLine(lineNumber, deltaTop, viewportData, sb) { + if (this._isMaybeInvalid === false) { + // it appears that nothing relevant has changed + return false; + } + this._isMaybeInvalid = false; + const lineData = viewportData.getViewLineRenderingData(lineNumber); + const options = this._options; + const actualInlineDecorations = LineDecoration.filter(lineData.inlineDecorations, lineNumber, lineData.minColumn, lineData.maxColumn); + // Only send selection information when needed for rendering whitespace + let selectionsOnLine = null; + if (isHighContrast(options.themeType) || this._options.renderWhitespace === 'selection') { + const selections = viewportData.selections; + for (const selection of selections) { + if (selection.endLineNumber < lineNumber || selection.startLineNumber > lineNumber) { + // Selection does not intersect line + continue; + } + const startColumn = (selection.startLineNumber === lineNumber ? selection.startColumn : lineData.minColumn); + const endColumn = (selection.endLineNumber === lineNumber ? selection.endColumn : lineData.maxColumn); + if (startColumn < endColumn) { + if (isHighContrast(options.themeType)) { + actualInlineDecorations.push(new LineDecoration(startColumn, endColumn, 'inline-selected-text', 0 /* InlineDecorationType.Regular */)); + } + if (this._options.renderWhitespace === 'selection') { + if (!selectionsOnLine) { + selectionsOnLine = []; + } + selectionsOnLine.push(new LineRange$1(startColumn - 1, endColumn - 1)); + } + } + } + } + const renderLineInput = new RenderLineInput(options.useMonospaceOptimizations, options.canUseHalfwidthRightwardsArrow, lineData.content, lineData.continuesWithWrappedLine, lineData.isBasicASCII, lineData.containsRTL, lineData.minColumn - 1, lineData.tokens, actualInlineDecorations, lineData.tabSize, lineData.startVisibleColumn, options.spaceWidth, options.middotWidth, options.wsmiddotWidth, options.stopRenderingLineAfter, options.renderWhitespace, options.renderControlCharacters, options.fontLigatures !== EditorFontLigatures.OFF, selectionsOnLine); + if (this._renderedViewLine && this._renderedViewLine.input.equals(renderLineInput)) { + // no need to do anything, we have the same render input + return false; + } + sb.appendString('
'); + const output = renderViewLine(renderLineInput, sb); + sb.appendString('
'); + let renderedViewLine = null; + if (monospaceAssumptionsAreValid && canUseFastRenderedViewLine && lineData.isBasicASCII && options.useMonospaceOptimizations && output.containsForeignElements === 0 /* ForeignElementType.None */) { + renderedViewLine = new FastRenderedViewLine(this._renderedViewLine ? this._renderedViewLine.domNode : null, renderLineInput, output.characterMapping); + } + if (!renderedViewLine) { + renderedViewLine = createRenderedLine(this._renderedViewLine ? this._renderedViewLine.domNode : null, renderLineInput, output.characterMapping, output.containsRTL, output.containsForeignElements); + } + this._renderedViewLine = renderedViewLine; + return true; + } + layoutLine(lineNumber, deltaTop) { + if (this._renderedViewLine && this._renderedViewLine.domNode) { + this._renderedViewLine.domNode.setTop(deltaTop); + this._renderedViewLine.domNode.setHeight(this._options.lineHeight); + } + } + // --- end IVisibleLineData + getWidth(context) { + if (!this._renderedViewLine) { + return 0; + } + return this._renderedViewLine.getWidth(context); + } + getWidthIsFast() { + if (!this._renderedViewLine) { + return true; + } + return this._renderedViewLine.getWidthIsFast(); + } + needsMonospaceFontCheck() { + if (!this._renderedViewLine) { + return false; + } + return (this._renderedViewLine instanceof FastRenderedViewLine); + } + monospaceAssumptionsAreValid() { + if (!this._renderedViewLine) { + return monospaceAssumptionsAreValid; + } + if (this._renderedViewLine instanceof FastRenderedViewLine) { + return this._renderedViewLine.monospaceAssumptionsAreValid(); + } + return monospaceAssumptionsAreValid; + } + onMonospaceAssumptionsInvalidated() { + if (this._renderedViewLine && this._renderedViewLine instanceof FastRenderedViewLine) { + this._renderedViewLine = this._renderedViewLine.toSlowRenderedLine(); + } + } + getVisibleRangesForRange(lineNumber, startColumn, endColumn, context) { + if (!this._renderedViewLine) { + return null; + } + startColumn = Math.min(this._renderedViewLine.input.lineContent.length + 1, Math.max(1, startColumn)); + endColumn = Math.min(this._renderedViewLine.input.lineContent.length + 1, Math.max(1, endColumn)); + const stopRenderingLineAfter = this._renderedViewLine.input.stopRenderingLineAfter; + if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter + 1 && endColumn > stopRenderingLineAfter + 1) { + // This range is obviously not visible + return new VisibleRanges(true, [new FloatHorizontalRange(this.getWidth(context), 0)]); + } + if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter + 1) { + startColumn = stopRenderingLineAfter + 1; + } + if (stopRenderingLineAfter !== -1 && endColumn > stopRenderingLineAfter + 1) { + endColumn = stopRenderingLineAfter + 1; + } + const horizontalRanges = this._renderedViewLine.getVisibleRangesForRange(lineNumber, startColumn, endColumn, context); + if (horizontalRanges && horizontalRanges.length > 0) { + return new VisibleRanges(false, horizontalRanges); + } + return null; + } + getColumnOfNodeOffset(lineNumber, spanNode, offset) { + if (!this._renderedViewLine) { + return 1; + } + return this._renderedViewLine.getColumnOfNodeOffset(lineNumber, spanNode, offset); + } +} +ViewLine.CLASS_NAME = 'view-line'; +/** + * A rendered line which is guaranteed to contain only regular ASCII and is rendered with a monospace font. + */ +class FastRenderedViewLine { + constructor(domNode, renderLineInput, characterMapping) { + this._cachedWidth = -1; + this.domNode = domNode; + this.input = renderLineInput; + const keyColumnCount = Math.floor(renderLineInput.lineContent.length / 300 /* Constants.MaxMonospaceDistance */); + if (keyColumnCount > 0) { + this._keyColumnPixelOffsetCache = new Float32Array(keyColumnCount); + for (let i = 0; i < keyColumnCount; i++) { + this._keyColumnPixelOffsetCache[i] = -1; + } + } + else { + this._keyColumnPixelOffsetCache = null; + } + this._characterMapping = characterMapping; + this._charWidth = renderLineInput.spaceWidth; + } + getWidth(context) { + if (!this.domNode || this.input.lineContent.length < 300 /* Constants.MaxMonospaceDistance */) { + const horizontalOffset = this._characterMapping.getHorizontalOffset(this._characterMapping.length); + return Math.round(this._charWidth * horizontalOffset); + } + if (this._cachedWidth === -1) { + this._cachedWidth = this._getReadingTarget(this.domNode).offsetWidth; + context === null || context === void 0 ? void 0 : context.markDidDomLayout(); + } + return this._cachedWidth; + } + getWidthIsFast() { + return (this.input.lineContent.length < 300 /* Constants.MaxMonospaceDistance */) || this._cachedWidth !== -1; + } + monospaceAssumptionsAreValid() { + if (!this.domNode) { + return monospaceAssumptionsAreValid; + } + if (this.input.lineContent.length < 300 /* Constants.MaxMonospaceDistance */) { + const expectedWidth = this.getWidth(null); + const actualWidth = this.domNode.domNode.firstChild.offsetWidth; + if (Math.abs(expectedWidth - actualWidth) >= 2) { + // more than 2px off + console.warn(`monospace assumptions have been violated, therefore disabling monospace optimizations!`); + monospaceAssumptionsAreValid = false; + } + } + return monospaceAssumptionsAreValid; + } + toSlowRenderedLine() { + return createRenderedLine(this.domNode, this.input, this._characterMapping, false, 0 /* ForeignElementType.None */); + } + getVisibleRangesForRange(lineNumber, startColumn, endColumn, context) { + const startPosition = this._getColumnPixelOffset(lineNumber, startColumn, context); + const endPosition = this._getColumnPixelOffset(lineNumber, endColumn, context); + return [new FloatHorizontalRange(startPosition, endPosition - startPosition)]; + } + _getColumnPixelOffset(lineNumber, column, context) { + if (column <= 300 /* Constants.MaxMonospaceDistance */) { + const horizontalOffset = this._characterMapping.getHorizontalOffset(column); + return this._charWidth * horizontalOffset; + } + const keyColumnOrdinal = Math.floor((column - 1) / 300 /* Constants.MaxMonospaceDistance */) - 1; + const keyColumn = (keyColumnOrdinal + 1) * 300 /* Constants.MaxMonospaceDistance */ + 1; + let keyColumnPixelOffset = -1; + if (this._keyColumnPixelOffsetCache) { + keyColumnPixelOffset = this._keyColumnPixelOffsetCache[keyColumnOrdinal]; + if (keyColumnPixelOffset === -1) { + keyColumnPixelOffset = this._actualReadPixelOffset(lineNumber, keyColumn, context); + this._keyColumnPixelOffsetCache[keyColumnOrdinal] = keyColumnPixelOffset; + } + } + if (keyColumnPixelOffset === -1) { + // Could not read actual key column pixel offset + const horizontalOffset = this._characterMapping.getHorizontalOffset(column); + return this._charWidth * horizontalOffset; + } + const keyColumnHorizontalOffset = this._characterMapping.getHorizontalOffset(keyColumn); + const horizontalOffset = this._characterMapping.getHorizontalOffset(column); + return keyColumnPixelOffset + this._charWidth * (horizontalOffset - keyColumnHorizontalOffset); + } + _getReadingTarget(myDomNode) { + return myDomNode.domNode.firstChild; + } + _actualReadPixelOffset(lineNumber, column, context) { + if (!this.domNode) { + return -1; + } + const domPosition = this._characterMapping.getDomPosition(column); + const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(this.domNode), domPosition.partIndex, domPosition.charIndex, domPosition.partIndex, domPosition.charIndex, context); + if (!r || r.length === 0) { + return -1; + } + return r[0].left; + } + getColumnOfNodeOffset(lineNumber, spanNode, offset) { + const spanNodeTextContentLength = spanNode.textContent.length; + let spanIndex = -1; + while (spanNode) { + spanNode = spanNode.previousSibling; + spanIndex++; + } + return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); + } +} +/** + * Every time we render a line, we save what we have rendered in an instance of this class. + */ +class RenderedViewLine { + constructor(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements) { + this.domNode = domNode; + this.input = renderLineInput; + this._characterMapping = characterMapping; + this._isWhitespaceOnly = /^\s*$/.test(renderLineInput.lineContent); + this._containsForeignElements = containsForeignElements; + this._cachedWidth = -1; + this._pixelOffsetCache = null; + if (!containsRTL || this._characterMapping.length === 0 /* the line is empty */) { + this._pixelOffsetCache = new Float32Array(Math.max(2, this._characterMapping.length + 1)); + for (let column = 0, len = this._characterMapping.length; column <= len; column++) { + this._pixelOffsetCache[column] = -1; + } + } + } + // --- Reading from the DOM methods + _getReadingTarget(myDomNode) { + return myDomNode.domNode.firstChild; + } + /** + * Width of the line in pixels + */ + getWidth(context) { + if (!this.domNode) { + return 0; + } + if (this._cachedWidth === -1) { + this._cachedWidth = this._getReadingTarget(this.domNode).offsetWidth; + context === null || context === void 0 ? void 0 : context.markDidDomLayout(); + } + return this._cachedWidth; + } + getWidthIsFast() { + if (this._cachedWidth === -1) { + return false; + } + return true; + } + /** + * Visible ranges for a model range + */ + getVisibleRangesForRange(lineNumber, startColumn, endColumn, context) { + if (!this.domNode) { + return null; + } + if (this._pixelOffsetCache !== null) { + // the text is LTR + const startOffset = this._readPixelOffset(this.domNode, lineNumber, startColumn, context); + if (startOffset === -1) { + return null; + } + const endOffset = this._readPixelOffset(this.domNode, lineNumber, endColumn, context); + if (endOffset === -1) { + return null; + } + return [new FloatHorizontalRange(startOffset, endOffset - startOffset)]; + } + return this._readVisibleRangesForRange(this.domNode, lineNumber, startColumn, endColumn, context); + } + _readVisibleRangesForRange(domNode, lineNumber, startColumn, endColumn, context) { + if (startColumn === endColumn) { + const pixelOffset = this._readPixelOffset(domNode, lineNumber, startColumn, context); + if (pixelOffset === -1) { + return null; + } + else { + return [new FloatHorizontalRange(pixelOffset, 0)]; + } + } + else { + return this._readRawVisibleRangesForRange(domNode, startColumn, endColumn, context); + } + } + _readPixelOffset(domNode, lineNumber, column, context) { + if (this._characterMapping.length === 0) { + // This line has no content + if (this._containsForeignElements === 0 /* ForeignElementType.None */) { + // We can assume the line is really empty + return 0; + } + if (this._containsForeignElements === 2 /* ForeignElementType.After */) { + // We have foreign elements after the (empty) line + return 0; + } + if (this._containsForeignElements === 1 /* ForeignElementType.Before */) { + // We have foreign elements before the (empty) line + return this.getWidth(context); + } + // We have foreign elements before & after the (empty) line + const readingTarget = this._getReadingTarget(domNode); + if (readingTarget.firstChild) { + context.markDidDomLayout(); + return readingTarget.firstChild.offsetWidth; + } + else { + return 0; + } + } + if (this._pixelOffsetCache !== null) { + // the text is LTR + const cachedPixelOffset = this._pixelOffsetCache[column]; + if (cachedPixelOffset !== -1) { + return cachedPixelOffset; + } + const result = this._actualReadPixelOffset(domNode, lineNumber, column, context); + this._pixelOffsetCache[column] = result; + return result; + } + return this._actualReadPixelOffset(domNode, lineNumber, column, context); + } + _actualReadPixelOffset(domNode, lineNumber, column, context) { + if (this._characterMapping.length === 0) { + // This line has no content + const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), 0, 0, 0, 0, context); + if (!r || r.length === 0) { + return -1; + } + return r[0].left; + } + if (column === this._characterMapping.length && this._isWhitespaceOnly && this._containsForeignElements === 0 /* ForeignElementType.None */) { + // This branch helps in the case of whitespace only lines which have a width set + return this.getWidth(context); + } + const domPosition = this._characterMapping.getDomPosition(column); + const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), domPosition.partIndex, domPosition.charIndex, domPosition.partIndex, domPosition.charIndex, context); + if (!r || r.length === 0) { + return -1; + } + const result = r[0].left; + if (this.input.isBasicASCII) { + const horizontalOffset = this._characterMapping.getHorizontalOffset(column); + const expectedResult = Math.round(this.input.spaceWidth * horizontalOffset); + if (Math.abs(expectedResult - result) <= 1) { + return expectedResult; + } + } + return result; + } + _readRawVisibleRangesForRange(domNode, startColumn, endColumn, context) { + if (startColumn === 1 && endColumn === this._characterMapping.length) { + // This branch helps IE with bidi text & gives a performance boost to other browsers when reading visible ranges for an entire line + return [new FloatHorizontalRange(0, this.getWidth(context))]; + } + const startDomPosition = this._characterMapping.getDomPosition(startColumn); + const endDomPosition = this._characterMapping.getDomPosition(endColumn); + return RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), startDomPosition.partIndex, startDomPosition.charIndex, endDomPosition.partIndex, endDomPosition.charIndex, context); + } + /** + * Returns the column for the text found at a specific offset inside a rendered dom node + */ + getColumnOfNodeOffset(lineNumber, spanNode, offset) { + const spanNodeTextContentLength = spanNode.textContent.length; + let spanIndex = -1; + while (spanNode) { + spanNode = spanNode.previousSibling; + spanIndex++; + } + return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); + } +} +class WebKitRenderedViewLine extends RenderedViewLine { + _readVisibleRangesForRange(domNode, lineNumber, startColumn, endColumn, context) { + const output = super._readVisibleRangesForRange(domNode, lineNumber, startColumn, endColumn, context); + if (!output || output.length === 0 || startColumn === endColumn || (startColumn === 1 && endColumn === this._characterMapping.length)) { + return output; + } + // WebKit is buggy and returns an expanded range (to contain words in some cases) + // The last client rect is enlarged (I think) + if (!this.input.containsRTL) { + // This is an attempt to patch things up + // Find position of last column + const endPixelOffset = this._readPixelOffset(domNode, lineNumber, endColumn, context); + if (endPixelOffset !== -1) { + const lastRange = output[output.length - 1]; + if (lastRange.left < endPixelOffset) { + // Trim down the width of the last visible range to not go after the last column's position + lastRange.width = endPixelOffset - lastRange.left; + } + } + } + return output; + } +} +const createRenderedLine = (function () { + if (isWebKit) { + return createWebKitRenderedLine; + } + return createNormalRenderedLine; +})(); +function createWebKitRenderedLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements) { + return new WebKitRenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements); +} +function createNormalRenderedLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements) { + return new RenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements); +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class UnknownHitTestResult { + constructor(hitTarget = null) { + this.hitTarget = hitTarget; + this.type = 0 /* HitTestResultType.Unknown */; + } +} +class ContentHitTestResult { + constructor(position, spanNode, injectedText) { + this.position = position; + this.spanNode = spanNode; + this.injectedText = injectedText; + this.type = 1 /* HitTestResultType.Content */; + } +} +var HitTestResult; +(function (HitTestResult) { + function createFromDOMInfo(ctx, spanNode, offset) { + const position = ctx.getPositionFromDOMInfo(spanNode, offset); + if (position) { + return new ContentHitTestResult(position, spanNode, null); + } + return new UnknownHitTestResult(spanNode); + } + HitTestResult.createFromDOMInfo = createFromDOMInfo; +})(HitTestResult || (HitTestResult = {})); +class PointerHandlerLastRenderData { + constructor(lastViewCursorsRenderData, lastTextareaPosition) { + this.lastViewCursorsRenderData = lastViewCursorsRenderData; + this.lastTextareaPosition = lastTextareaPosition; + } +} +class MouseTarget { + static _deduceRage(position, range = null) { + if (!range && position) { + return new Range$c(position.lineNumber, position.column, position.lineNumber, position.column); + } + return range !== null && range !== void 0 ? range : null; + } + static createUnknown(element, mouseColumn, position) { + return { type: 0 /* MouseTargetType.UNKNOWN */, element, mouseColumn, position, range: this._deduceRage(position) }; + } + static createTextarea(element, mouseColumn) { + return { type: 1 /* MouseTargetType.TEXTAREA */, element, mouseColumn, position: null, range: null }; + } + static createMargin(type, element, mouseColumn, position, range, detail) { + return { type, element, mouseColumn, position, range, detail }; + } + static createViewZone(type, element, mouseColumn, position, detail) { + return { type, element, mouseColumn, position, range: this._deduceRage(position), detail }; + } + static createContentText(element, mouseColumn, position, range, detail) { + return { type: 6 /* MouseTargetType.CONTENT_TEXT */, element, mouseColumn, position, range: this._deduceRage(position, range), detail }; + } + static createContentEmpty(element, mouseColumn, position, detail) { + return { type: 7 /* MouseTargetType.CONTENT_EMPTY */, element, mouseColumn, position, range: this._deduceRage(position), detail }; + } + static createContentWidget(element, mouseColumn, detail) { + return { type: 9 /* MouseTargetType.CONTENT_WIDGET */, element, mouseColumn, position: null, range: null, detail }; + } + static createScrollbar(element, mouseColumn, position) { + return { type: 11 /* MouseTargetType.SCROLLBAR */, element, mouseColumn, position, range: this._deduceRage(position) }; + } + static createOverlayWidget(element, mouseColumn, detail) { + return { type: 12 /* MouseTargetType.OVERLAY_WIDGET */, element, mouseColumn, position: null, range: null, detail }; + } + static createOutsideEditor(mouseColumn, position, outsidePosition, outsideDistance) { + return { type: 13 /* MouseTargetType.OUTSIDE_EDITOR */, element: null, mouseColumn, position, range: this._deduceRage(position), outsidePosition, outsideDistance }; + } + static _typeToString(type) { + if (type === 1 /* MouseTargetType.TEXTAREA */) { + return 'TEXTAREA'; + } + if (type === 2 /* MouseTargetType.GUTTER_GLYPH_MARGIN */) { + return 'GUTTER_GLYPH_MARGIN'; + } + if (type === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */) { + return 'GUTTER_LINE_NUMBERS'; + } + if (type === 4 /* MouseTargetType.GUTTER_LINE_DECORATIONS */) { + return 'GUTTER_LINE_DECORATIONS'; + } + if (type === 5 /* MouseTargetType.GUTTER_VIEW_ZONE */) { + return 'GUTTER_VIEW_ZONE'; + } + if (type === 6 /* MouseTargetType.CONTENT_TEXT */) { + return 'CONTENT_TEXT'; + } + if (type === 7 /* MouseTargetType.CONTENT_EMPTY */) { + return 'CONTENT_EMPTY'; + } + if (type === 8 /* MouseTargetType.CONTENT_VIEW_ZONE */) { + return 'CONTENT_VIEW_ZONE'; + } + if (type === 9 /* MouseTargetType.CONTENT_WIDGET */) { + return 'CONTENT_WIDGET'; + } + if (type === 10 /* MouseTargetType.OVERVIEW_RULER */) { + return 'OVERVIEW_RULER'; + } + if (type === 11 /* MouseTargetType.SCROLLBAR */) { + return 'SCROLLBAR'; + } + if (type === 12 /* MouseTargetType.OVERLAY_WIDGET */) { + return 'OVERLAY_WIDGET'; + } + return 'UNKNOWN'; + } + static toString(target) { + return this._typeToString(target.type) + ': ' + target.position + ' - ' + target.range + ' - ' + JSON.stringify(target.detail); + } +} +class ElementPath { + static isTextArea(path) { + return (path.length === 2 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[1] === 6 /* PartFingerprint.TextArea */); + } + static isChildOfViewLines(path) { + return (path.length >= 4 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[3] === 7 /* PartFingerprint.ViewLines */); + } + static isStrictChildOfViewLines(path) { + return (path.length > 4 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[3] === 7 /* PartFingerprint.ViewLines */); + } + static isChildOfScrollableElement(path) { + return (path.length >= 2 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[1] === 5 /* PartFingerprint.ScrollableElement */); + } + static isChildOfMinimap(path) { + return (path.length >= 2 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[1] === 8 /* PartFingerprint.Minimap */); + } + static isChildOfContentWidgets(path) { + return (path.length >= 4 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[3] === 1 /* PartFingerprint.ContentWidgets */); + } + static isChildOfOverflowingContentWidgets(path) { + return (path.length >= 1 + && path[0] === 2 /* PartFingerprint.OverflowingContentWidgets */); + } + static isChildOfOverlayWidgets(path) { + return (path.length >= 2 + && path[0] === 3 /* PartFingerprint.OverflowGuard */ + && path[1] === 4 /* PartFingerprint.OverlayWidgets */); + } +} +class HitTestContext { + constructor(context, viewHelper, lastRenderData) { + this.viewModel = context.viewModel; + const options = context.configuration.options; + this.layoutInfo = options.get(139 /* EditorOption.layoutInfo */); + this.viewDomNode = viewHelper.viewDomNode; + this.lineHeight = options.get(64 /* EditorOption.lineHeight */); + this.stickyTabStops = options.get(111 /* EditorOption.stickyTabStops */); + this.typicalHalfwidthCharacterWidth = options.get(48 /* EditorOption.fontInfo */).typicalHalfwidthCharacterWidth; + this.lastRenderData = lastRenderData; + this._context = context; + this._viewHelper = viewHelper; + } + getZoneAtCoord(mouseVerticalOffset) { + return HitTestContext.getZoneAtCoord(this._context, mouseVerticalOffset); + } + static getZoneAtCoord(context, mouseVerticalOffset) { + // The target is either a view zone or the empty space after the last view-line + const viewZoneWhitespace = context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset); + if (viewZoneWhitespace) { + const viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2; + const lineCount = context.viewModel.getLineCount(); + let positionBefore = null; + let position; + let positionAfter = null; + if (viewZoneWhitespace.afterLineNumber !== lineCount) { + // There are more lines after this view zone + positionAfter = new Position$1(viewZoneWhitespace.afterLineNumber + 1, 1); + } + if (viewZoneWhitespace.afterLineNumber > 0) { + // There are more lines above this view zone + positionBefore = new Position$1(viewZoneWhitespace.afterLineNumber, context.viewModel.getLineMaxColumn(viewZoneWhitespace.afterLineNumber)); + } + if (positionAfter === null) { + position = positionBefore; + } + else if (positionBefore === null) { + position = positionAfter; + } + else if (mouseVerticalOffset < viewZoneMiddle) { + position = positionBefore; + } + else { + position = positionAfter; + } + return { + viewZoneId: viewZoneWhitespace.id, + afterLineNumber: viewZoneWhitespace.afterLineNumber, + positionBefore: positionBefore, + positionAfter: positionAfter, + position: position + }; + } + return null; + } + getFullLineRangeAtCoord(mouseVerticalOffset) { + if (this._context.viewLayout.isAfterLines(mouseVerticalOffset)) { + // Below the last line + const lineNumber = this._context.viewModel.getLineCount(); + const maxLineColumn = this._context.viewModel.getLineMaxColumn(lineNumber); + return { + range: new Range$c(lineNumber, maxLineColumn, lineNumber, maxLineColumn), + isAfterLines: true + }; + } + const lineNumber = this._context.viewLayout.getLineNumberAtVerticalOffset(mouseVerticalOffset); + const maxLineColumn = this._context.viewModel.getLineMaxColumn(lineNumber); + return { + range: new Range$c(lineNumber, 1, lineNumber, maxLineColumn), + isAfterLines: false + }; + } + getLineNumberAtVerticalOffset(mouseVerticalOffset) { + return this._context.viewLayout.getLineNumberAtVerticalOffset(mouseVerticalOffset); + } + isAfterLines(mouseVerticalOffset) { + return this._context.viewLayout.isAfterLines(mouseVerticalOffset); + } + isInTopPadding(mouseVerticalOffset) { + return this._context.viewLayout.isInTopPadding(mouseVerticalOffset); + } + isInBottomPadding(mouseVerticalOffset) { + return this._context.viewLayout.isInBottomPadding(mouseVerticalOffset); + } + getVerticalOffsetForLineNumber(lineNumber) { + return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber); + } + findAttribute(element, attr) { + return HitTestContext._findAttribute(element, attr, this._viewHelper.viewDomNode); + } + static _findAttribute(element, attr, stopAt) { + while (element && element !== document.body) { + if (element.hasAttribute && element.hasAttribute(attr)) { + return element.getAttribute(attr); + } + if (element === stopAt) { + return null; + } + element = element.parentNode; + } + return null; + } + getLineWidth(lineNumber) { + return this._viewHelper.getLineWidth(lineNumber); + } + visibleRangeForPosition(lineNumber, column) { + return this._viewHelper.visibleRangeForPosition(lineNumber, column); + } + getPositionFromDOMInfo(spanNode, offset) { + return this._viewHelper.getPositionFromDOMInfo(spanNode, offset); + } + getCurrentScrollTop() { + return this._context.viewLayout.getCurrentScrollTop(); + } + getCurrentScrollLeft() { + return this._context.viewLayout.getCurrentScrollLeft(); + } +} +class BareHitTestRequest { + constructor(ctx, editorPos, pos, relativePos) { + this.editorPos = editorPos; + this.pos = pos; + this.relativePos = relativePos; + this.mouseVerticalOffset = Math.max(0, ctx.getCurrentScrollTop() + this.relativePos.y); + this.mouseContentHorizontalOffset = ctx.getCurrentScrollLeft() + this.relativePos.x - ctx.layoutInfo.contentLeft; + this.isInMarginArea = (this.relativePos.x < ctx.layoutInfo.contentLeft && this.relativePos.x >= ctx.layoutInfo.glyphMarginLeft); + this.isInContentArea = !this.isInMarginArea; + this.mouseColumn = Math.max(0, MouseTargetFactory._getMouseColumn(this.mouseContentHorizontalOffset, ctx.typicalHalfwidthCharacterWidth)); + } +} +class HitTestRequest extends BareHitTestRequest { + constructor(ctx, editorPos, pos, relativePos, target) { + super(ctx, editorPos, pos, relativePos); + this._ctx = ctx; + if (target) { + this.target = target; + this.targetPath = PartFingerprints.collect(target, ctx.viewDomNode); + } + else { + this.target = null; + this.targetPath = new Uint8Array(0); + } + } + toString() { + return `pos(${this.pos.x},${this.pos.y}), editorPos(${this.editorPos.x},${this.editorPos.y}), relativePos(${this.relativePos.x},${this.relativePos.y}), mouseVerticalOffset: ${this.mouseVerticalOffset}, mouseContentHorizontalOffset: ${this.mouseContentHorizontalOffset}\n\ttarget: ${this.target ? this.target.outerHTML : null}`; + } + _getMouseColumn(position = null) { + if (position && position.column < this._ctx.viewModel.getLineMaxColumn(position.lineNumber)) { + // Most likely, the line contains foreign decorations... + return CursorColumns.visibleColumnFromColumn(this._ctx.viewModel.getLineContent(position.lineNumber), position.column, this._ctx.viewModel.model.getOptions().tabSize) + 1; + } + return this.mouseColumn; + } + fulfillUnknown(position = null) { + return MouseTarget.createUnknown(this.target, this._getMouseColumn(position), position); + } + fulfillTextarea() { + return MouseTarget.createTextarea(this.target, this._getMouseColumn()); + } + fulfillMargin(type, position, range, detail) { + return MouseTarget.createMargin(type, this.target, this._getMouseColumn(position), position, range, detail); + } + fulfillViewZone(type, position, detail) { + return MouseTarget.createViewZone(type, this.target, this._getMouseColumn(position), position, detail); + } + fulfillContentText(position, range, detail) { + return MouseTarget.createContentText(this.target, this._getMouseColumn(position), position, range, detail); + } + fulfillContentEmpty(position, detail) { + return MouseTarget.createContentEmpty(this.target, this._getMouseColumn(position), position, detail); + } + fulfillContentWidget(detail) { + return MouseTarget.createContentWidget(this.target, this._getMouseColumn(), detail); + } + fulfillScrollbar(position) { + return MouseTarget.createScrollbar(this.target, this._getMouseColumn(position), position); + } + fulfillOverlayWidget(detail) { + return MouseTarget.createOverlayWidget(this.target, this._getMouseColumn(), detail); + } + withTarget(target) { + return new HitTestRequest(this._ctx, this.editorPos, this.pos, this.relativePos, target); + } +} +const EMPTY_CONTENT_AFTER_LINES = { isAfterLines: true }; +function createEmptyContentDataInLines(horizontalDistanceToText) { + return { + isAfterLines: false, + horizontalDistanceToText: horizontalDistanceToText + }; +} +class MouseTargetFactory { + constructor(context, viewHelper) { + this._context = context; + this._viewHelper = viewHelper; + } + mouseTargetIsWidget(e) { + const t = e.target; + const path = PartFingerprints.collect(t, this._viewHelper.viewDomNode); + // Is it a content widget? + if (ElementPath.isChildOfContentWidgets(path) || ElementPath.isChildOfOverflowingContentWidgets(path)) { + return true; + } + // Is it an overlay widget? + if (ElementPath.isChildOfOverlayWidgets(path)) { + return true; + } + return false; + } + createMouseTarget(lastRenderData, editorPos, pos, relativePos, target) { + const ctx = new HitTestContext(this._context, this._viewHelper, lastRenderData); + const request = new HitTestRequest(ctx, editorPos, pos, relativePos, target); + try { + const r = MouseTargetFactory._createMouseTarget(ctx, request, false); + if (r.type === 6 /* MouseTargetType.CONTENT_TEXT */) { + // Snap to the nearest soft tab boundary if atomic soft tabs are enabled. + if (ctx.stickyTabStops && r.position !== null) { + const position = MouseTargetFactory._snapToSoftTabBoundary(r.position, ctx.viewModel); + const range = Range$c.fromPositions(position, position).plusRange(r.range); + return request.fulfillContentText(position, range, r.detail); + } + } + // console.log(MouseTarget.toString(r)); + return r; + } + catch (err) { + // console.log(err); + return request.fulfillUnknown(); + } + } + static _createMouseTarget(ctx, request, domHitTestExecuted) { + // console.log(`${domHitTestExecuted ? '=>' : ''}CAME IN REQUEST: ${request}`); + // First ensure the request has a target + if (request.target === null) { + if (domHitTestExecuted) { + // Still no target... and we have already executed hit test... + return request.fulfillUnknown(); + } + const hitTestResult = MouseTargetFactory._doHitTest(ctx, request); + if (hitTestResult.type === 1 /* HitTestResultType.Content */) { + return MouseTargetFactory.createMouseTargetFromHitTestPosition(ctx, request, hitTestResult.spanNode, hitTestResult.position, hitTestResult.injectedText); + } + return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true); + } + // we know for a fact that request.target is not null + const resolvedRequest = request; + let result = null; + result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestViewZone(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestMargin(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestViewCursor(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestTextArea(ctx, resolvedRequest); + result = result || MouseTargetFactory._hitTestViewLines(ctx, resolvedRequest, domHitTestExecuted); + result = result || MouseTargetFactory._hitTestScrollbar(ctx, resolvedRequest); + return (result || request.fulfillUnknown()); + } + static _hitTestContentWidget(ctx, request) { + // Is it a content widget? + if (ElementPath.isChildOfContentWidgets(request.targetPath) || ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) { + const widgetId = ctx.findAttribute(request.target, 'widgetId'); + if (widgetId) { + return request.fulfillContentWidget(widgetId); + } + else { + return request.fulfillUnknown(); + } + } + return null; + } + static _hitTestOverlayWidget(ctx, request) { + // Is it an overlay widget? + if (ElementPath.isChildOfOverlayWidgets(request.targetPath)) { + const widgetId = ctx.findAttribute(request.target, 'widgetId'); + if (widgetId) { + return request.fulfillOverlayWidget(widgetId); + } + else { + return request.fulfillUnknown(); + } + } + return null; + } + static _hitTestViewCursor(ctx, request) { + if (request.target) { + // Check if we've hit a painted cursor + const lastViewCursorsRenderData = ctx.lastRenderData.lastViewCursorsRenderData; + for (const d of lastViewCursorsRenderData) { + if (request.target === d.domNode) { + return request.fulfillContentText(d.position, null, { mightBeForeignElement: false, injectedText: null }); + } + } + } + if (request.isInContentArea) { + // Edge has a bug when hit-testing the exact position of a cursor, + // instead of returning the correct dom node, it returns the + // first or last rendered view line dom node, therefore help it out + // and first check if we are on top of a cursor + const lastViewCursorsRenderData = ctx.lastRenderData.lastViewCursorsRenderData; + const mouseContentHorizontalOffset = request.mouseContentHorizontalOffset; + const mouseVerticalOffset = request.mouseVerticalOffset; + for (const d of lastViewCursorsRenderData) { + if (mouseContentHorizontalOffset < d.contentLeft) { + // mouse position is to the left of the cursor + continue; + } + if (mouseContentHorizontalOffset > d.contentLeft + d.width) { + // mouse position is to the right of the cursor + continue; + } + const cursorVerticalOffset = ctx.getVerticalOffsetForLineNumber(d.position.lineNumber); + if (cursorVerticalOffset <= mouseVerticalOffset + && mouseVerticalOffset <= cursorVerticalOffset + d.height) { + return request.fulfillContentText(d.position, null, { mightBeForeignElement: false, injectedText: null }); + } + } + } + return null; + } + static _hitTestViewZone(ctx, request) { + const viewZoneData = ctx.getZoneAtCoord(request.mouseVerticalOffset); + if (viewZoneData) { + const mouseTargetType = (request.isInContentArea ? 8 /* MouseTargetType.CONTENT_VIEW_ZONE */ : 5 /* MouseTargetType.GUTTER_VIEW_ZONE */); + return request.fulfillViewZone(mouseTargetType, viewZoneData.position, viewZoneData); + } + return null; + } + static _hitTestTextArea(ctx, request) { + // Is it the textarea? + if (ElementPath.isTextArea(request.targetPath)) { + if (ctx.lastRenderData.lastTextareaPosition) { + return request.fulfillContentText(ctx.lastRenderData.lastTextareaPosition, null, { mightBeForeignElement: false, injectedText: null }); + } + return request.fulfillTextarea(); + } + return null; + } + static _hitTestMargin(ctx, request) { + if (request.isInMarginArea) { + const res = ctx.getFullLineRangeAtCoord(request.mouseVerticalOffset); + const pos = res.range.getStartPosition(); + let offset = Math.abs(request.relativePos.x); + const detail = { + isAfterLines: res.isAfterLines, + glyphMarginLeft: ctx.layoutInfo.glyphMarginLeft, + glyphMarginWidth: ctx.layoutInfo.glyphMarginWidth, + lineNumbersWidth: ctx.layoutInfo.lineNumbersWidth, + offsetX: offset + }; + offset -= ctx.layoutInfo.glyphMarginLeft; + if (offset <= ctx.layoutInfo.glyphMarginWidth) { + // On the glyph margin + return request.fulfillMargin(2 /* MouseTargetType.GUTTER_GLYPH_MARGIN */, pos, res.range, detail); + } + offset -= ctx.layoutInfo.glyphMarginWidth; + if (offset <= ctx.layoutInfo.lineNumbersWidth) { + // On the line numbers + return request.fulfillMargin(3 /* MouseTargetType.GUTTER_LINE_NUMBERS */, pos, res.range, detail); + } + offset -= ctx.layoutInfo.lineNumbersWidth; + // On the line decorations + return request.fulfillMargin(4 /* MouseTargetType.GUTTER_LINE_DECORATIONS */, pos, res.range, detail); + } + return null; + } + static _hitTestViewLines(ctx, request, domHitTestExecuted) { + if (!ElementPath.isChildOfViewLines(request.targetPath)) { + return null; + } + if (ctx.isInTopPadding(request.mouseVerticalOffset)) { + return request.fulfillContentEmpty(new Position$1(1, 1), EMPTY_CONTENT_AFTER_LINES); + } + // Check if it is below any lines and any view zones + if (ctx.isAfterLines(request.mouseVerticalOffset) || ctx.isInBottomPadding(request.mouseVerticalOffset)) { + // This most likely indicates it happened after the last view-line + const lineCount = ctx.viewModel.getLineCount(); + const maxLineColumn = ctx.viewModel.getLineMaxColumn(lineCount); + return request.fulfillContentEmpty(new Position$1(lineCount, maxLineColumn), EMPTY_CONTENT_AFTER_LINES); + } + if (domHitTestExecuted) { + // Check if we are hitting a view-line (can happen in the case of inline decorations on empty lines) + // See https://github.com/microsoft/vscode/issues/46942 + if (ElementPath.isStrictChildOfViewLines(request.targetPath)) { + const lineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); + if (ctx.viewModel.getLineLength(lineNumber) === 0) { + const lineWidth = ctx.getLineWidth(lineNumber); + const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth); + return request.fulfillContentEmpty(new Position$1(lineNumber, 1), detail); + } + const lineWidth = ctx.getLineWidth(lineNumber); + if (request.mouseContentHorizontalOffset >= lineWidth) { + const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth); + const pos = new Position$1(lineNumber, ctx.viewModel.getLineMaxColumn(lineNumber)); + return request.fulfillContentEmpty(pos, detail); + } + } + // We have already executed hit test... + return request.fulfillUnknown(); + } + const hitTestResult = MouseTargetFactory._doHitTest(ctx, request); + if (hitTestResult.type === 1 /* HitTestResultType.Content */) { + return MouseTargetFactory.createMouseTargetFromHitTestPosition(ctx, request, hitTestResult.spanNode, hitTestResult.position, hitTestResult.injectedText); + } + return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true); + } + static _hitTestMinimap(ctx, request) { + if (ElementPath.isChildOfMinimap(request.targetPath)) { + const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); + const maxColumn = ctx.viewModel.getLineMaxColumn(possibleLineNumber); + return request.fulfillScrollbar(new Position$1(possibleLineNumber, maxColumn)); + } + return null; + } + static _hitTestScrollbarSlider(ctx, request) { + if (ElementPath.isChildOfScrollableElement(request.targetPath)) { + if (request.target && request.target.nodeType === 1) { + const className = request.target.className; + if (className && /\b(slider|scrollbar)\b/.test(className)) { + const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); + const maxColumn = ctx.viewModel.getLineMaxColumn(possibleLineNumber); + return request.fulfillScrollbar(new Position$1(possibleLineNumber, maxColumn)); + } + } + } + return null; + } + static _hitTestScrollbar(ctx, request) { + // Is it the overview ruler? + // Is it a child of the scrollable element? + if (ElementPath.isChildOfScrollableElement(request.targetPath)) { + const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); + const maxColumn = ctx.viewModel.getLineMaxColumn(possibleLineNumber); + return request.fulfillScrollbar(new Position$1(possibleLineNumber, maxColumn)); + } + return null; + } + getMouseColumn(relativePos) { + const options = this._context.configuration.options; + const layoutInfo = options.get(139 /* EditorOption.layoutInfo */); + const mouseContentHorizontalOffset = this._context.viewLayout.getCurrentScrollLeft() + relativePos.x - layoutInfo.contentLeft; + return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, options.get(48 /* EditorOption.fontInfo */).typicalHalfwidthCharacterWidth); + } + static _getMouseColumn(mouseContentHorizontalOffset, typicalHalfwidthCharacterWidth) { + if (mouseContentHorizontalOffset < 0) { + return 1; + } + const chars = Math.round(mouseContentHorizontalOffset / typicalHalfwidthCharacterWidth); + return (chars + 1); + } + static createMouseTargetFromHitTestPosition(ctx, request, spanNode, pos, injectedText) { + const lineNumber = pos.lineNumber; + const column = pos.column; + const lineWidth = ctx.getLineWidth(lineNumber); + if (request.mouseContentHorizontalOffset > lineWidth) { + const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth); + return request.fulfillContentEmpty(pos, detail); + } + const visibleRange = ctx.visibleRangeForPosition(lineNumber, column); + if (!visibleRange) { + return request.fulfillUnknown(pos); + } + const columnHorizontalOffset = visibleRange.left; + if (Math.abs(request.mouseContentHorizontalOffset - columnHorizontalOffset) < 1) { + return request.fulfillContentText(pos, null, { mightBeForeignElement: !!injectedText, injectedText }); + } + const points = []; + points.push({ offset: visibleRange.left, column: column }); + if (column > 1) { + const visibleRange = ctx.visibleRangeForPosition(lineNumber, column - 1); + if (visibleRange) { + points.push({ offset: visibleRange.left, column: column - 1 }); + } + } + const lineMaxColumn = ctx.viewModel.getLineMaxColumn(lineNumber); + if (column < lineMaxColumn) { + const visibleRange = ctx.visibleRangeForPosition(lineNumber, column + 1); + if (visibleRange) { + points.push({ offset: visibleRange.left, column: column + 1 }); + } + } + points.sort((a, b) => a.offset - b.offset); + const mouseCoordinates = request.pos.toClientCoordinates(); + const spanNodeClientRect = spanNode.getBoundingClientRect(); + const mouseIsOverSpanNode = (spanNodeClientRect.left <= mouseCoordinates.clientX && mouseCoordinates.clientX <= spanNodeClientRect.right); + let rng = null; + for (let i = 1; i < points.length; i++) { + const prev = points[i - 1]; + const curr = points[i]; + if (prev.offset <= request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset <= curr.offset) { + rng = new Range$c(lineNumber, prev.column, lineNumber, curr.column); + // See https://github.com/microsoft/vscode/issues/152819 + // Due to the use of zwj, the browser's hit test result is skewed towards the left + // Here we try to correct that if the mouse horizontal offset is closer to the right than the left + const prevDelta = Math.abs(prev.offset - request.mouseContentHorizontalOffset); + const nextDelta = Math.abs(curr.offset - request.mouseContentHorizontalOffset); + pos = (prevDelta < nextDelta + ? new Position$1(lineNumber, prev.column) + : new Position$1(lineNumber, curr.column)); + break; + } + } + return request.fulfillContentText(pos, rng, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText }); + } + /** + * Most probably WebKit browsers and Edge + */ + static _doHitTestWithCaretRangeFromPoint(ctx, request) { + // In Chrome, especially on Linux it is possible to click between lines, + // so try to adjust the `hity` below so that it lands in the center of a line + const lineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); + const lineStartVerticalOffset = ctx.getVerticalOffsetForLineNumber(lineNumber); + const lineEndVerticalOffset = lineStartVerticalOffset + ctx.lineHeight; + const isBelowLastLine = (lineNumber === ctx.viewModel.getLineCount() + && request.mouseVerticalOffset > lineEndVerticalOffset); + if (!isBelowLastLine) { + const lineCenteredVerticalOffset = Math.floor((lineStartVerticalOffset + lineEndVerticalOffset) / 2); + let adjustedPageY = request.pos.y + (lineCenteredVerticalOffset - request.mouseVerticalOffset); + if (adjustedPageY <= request.editorPos.y) { + adjustedPageY = request.editorPos.y + 1; + } + if (adjustedPageY >= request.editorPos.y + request.editorPos.height) { + adjustedPageY = request.editorPos.y + request.editorPos.height - 1; + } + const adjustedPage = new PageCoordinates(request.pos.x, adjustedPageY); + const r = this._actualDoHitTestWithCaretRangeFromPoint(ctx, adjustedPage.toClientCoordinates()); + if (r.type === 1 /* HitTestResultType.Content */) { + return r; + } + } + // Also try to hit test without the adjustment (for the edge cases that we are near the top or bottom) + return this._actualDoHitTestWithCaretRangeFromPoint(ctx, request.pos.toClientCoordinates()); + } + static _actualDoHitTestWithCaretRangeFromPoint(ctx, coords) { + const shadowRoot = getShadowRoot(ctx.viewDomNode); + let range; + if (shadowRoot) { + if (typeof shadowRoot.caretRangeFromPoint === 'undefined') { + range = shadowCaretRangeFromPoint(shadowRoot, coords.clientX, coords.clientY); + } + else { + range = shadowRoot.caretRangeFromPoint(coords.clientX, coords.clientY); + } + } + else { + range = document.caretRangeFromPoint(coords.clientX, coords.clientY); + } + if (!range || !range.startContainer) { + return new UnknownHitTestResult(); + } + // Chrome always hits a TEXT_NODE, while Edge sometimes hits a token span + const startContainer = range.startContainer; + if (startContainer.nodeType === startContainer.TEXT_NODE) { + // startContainer is expected to be the token text + const parent1 = startContainer.parentNode; // expected to be the token span + const parent2 = parent1 ? parent1.parentNode : null; // expected to be the view line container span + const parent3 = parent2 ? parent2.parentNode : null; // expected to be the view line div + const parent3ClassName = parent3 && parent3.nodeType === parent3.ELEMENT_NODE ? parent3.className : null; + if (parent3ClassName === ViewLine.CLASS_NAME) { + return HitTestResult.createFromDOMInfo(ctx, parent1, range.startOffset); + } + else { + return new UnknownHitTestResult(startContainer.parentNode); + } + } + else if (startContainer.nodeType === startContainer.ELEMENT_NODE) { + // startContainer is expected to be the token span + const parent1 = startContainer.parentNode; // expected to be the view line container span + const parent2 = parent1 ? parent1.parentNode : null; // expected to be the view line div + const parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? parent2.className : null; + if (parent2ClassName === ViewLine.CLASS_NAME) { + return HitTestResult.createFromDOMInfo(ctx, startContainer, startContainer.textContent.length); + } + else { + return new UnknownHitTestResult(startContainer); + } + } + return new UnknownHitTestResult(); + } + /** + * Most probably Gecko + */ + static _doHitTestWithCaretPositionFromPoint(ctx, coords) { + const hitResult = document.caretPositionFromPoint(coords.clientX, coords.clientY); + if (hitResult.offsetNode.nodeType === hitResult.offsetNode.TEXT_NODE) { + // offsetNode is expected to be the token text + const parent1 = hitResult.offsetNode.parentNode; // expected to be the token span + const parent2 = parent1 ? parent1.parentNode : null; // expected to be the view line container span + const parent3 = parent2 ? parent2.parentNode : null; // expected to be the view line div + const parent3ClassName = parent3 && parent3.nodeType === parent3.ELEMENT_NODE ? parent3.className : null; + if (parent3ClassName === ViewLine.CLASS_NAME) { + return HitTestResult.createFromDOMInfo(ctx, hitResult.offsetNode.parentNode, hitResult.offset); + } + else { + return new UnknownHitTestResult(hitResult.offsetNode.parentNode); + } + } + // For inline decorations, Gecko sometimes returns the `` of the line and the offset is the `` with the inline decoration + // Some other times, it returns the `` with the inline decoration + if (hitResult.offsetNode.nodeType === hitResult.offsetNode.ELEMENT_NODE) { + const parent1 = hitResult.offsetNode.parentNode; + const parent1ClassName = parent1 && parent1.nodeType === parent1.ELEMENT_NODE ? parent1.className : null; + const parent2 = parent1 ? parent1.parentNode : null; + const parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? parent2.className : null; + if (parent1ClassName === ViewLine.CLASS_NAME) { + // it returned the `` of the line and the offset is the `` with the inline decoration + const tokenSpan = hitResult.offsetNode.childNodes[Math.min(hitResult.offset, hitResult.offsetNode.childNodes.length - 1)]; + if (tokenSpan) { + return HitTestResult.createFromDOMInfo(ctx, tokenSpan, 0); + } + } + else if (parent2ClassName === ViewLine.CLASS_NAME) { + // it returned the `` with the inline decoration + return HitTestResult.createFromDOMInfo(ctx, hitResult.offsetNode, 0); + } + } + return new UnknownHitTestResult(hitResult.offsetNode); + } + static _snapToSoftTabBoundary(position, viewModel) { + const lineContent = viewModel.getLineContent(position.lineNumber); + const { tabSize } = viewModel.model.getOptions(); + const newPosition = AtomicTabMoveOperations.atomicPosition(lineContent, position.column - 1, tabSize, 2 /* Direction.Nearest */); + if (newPosition !== -1) { + return new Position$1(position.lineNumber, newPosition + 1); + } + return position; + } + static _doHitTest(ctx, request) { + let result = new UnknownHitTestResult(); + if (typeof document.caretRangeFromPoint === 'function') { + result = this._doHitTestWithCaretRangeFromPoint(ctx, request); + } + else if (document.caretPositionFromPoint) { + result = this._doHitTestWithCaretPositionFromPoint(ctx, request.pos.toClientCoordinates()); + } + if (result.type === 1 /* HitTestResultType.Content */) { + const injectedText = ctx.viewModel.getInjectedTextAt(result.position); + const normalizedPosition = ctx.viewModel.normalizePosition(result.position, 2 /* PositionAffinity.None */); + if (injectedText || !normalizedPosition.equals(result.position)) { + result = new ContentHitTestResult(normalizedPosition, result.spanNode, injectedText); + } + } + return result; + } +} +function shadowCaretRangeFromPoint(shadowRoot, x, y) { + const range = document.createRange(); + // Get the element under the point + let el = shadowRoot.elementFromPoint(x, y); + if (el !== null) { + // Get the last child of the element until its firstChild is a text node + // This assumes that the pointer is on the right of the line, out of the tokens + // and that we want to get the offset of the last token of the line + while (el && el.firstChild && el.firstChild.nodeType !== el.firstChild.TEXT_NODE && el.lastChild && el.lastChild.firstChild) { + el = el.lastChild; + } + // Grab its rect + const rect = el.getBoundingClientRect(); + // And its font (the computed shorthand font property might be empty, see #3217) + const fontStyle = window.getComputedStyle(el, null).getPropertyValue('font-style'); + const fontVariant = window.getComputedStyle(el, null).getPropertyValue('font-variant'); + const fontWeight = window.getComputedStyle(el, null).getPropertyValue('font-weight'); + const fontSize = window.getComputedStyle(el, null).getPropertyValue('font-size'); + const lineHeight = window.getComputedStyle(el, null).getPropertyValue('line-height'); + const fontFamily = window.getComputedStyle(el, null).getPropertyValue('font-family'); + const font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`; + // And also its txt content + const text = el.innerText; + // Position the pixel cursor at the left of the element + let pixelCursor = rect.left; + let offset = 0; + let step; + // If the point is on the right of the box put the cursor after the last character + if (x > rect.left + rect.width) { + offset = text.length; + } + else { + const charWidthReader = CharWidthReader.getInstance(); + // Goes through all the characters of the innerText, and checks if the x of the point + // belongs to the character. + for (let i = 0; i < text.length + 1; i++) { + // The step is half the width of the character + step = charWidthReader.getCharWidth(text.charAt(i), font) / 2; + // Move to the center of the character + pixelCursor += step; + // If the x of the point is smaller that the position of the cursor, the point is over that character + if (x < pixelCursor) { + offset = i; + break; + } + // Move between the current character and the next + pixelCursor += step; + } + } + // Creates a range with the text node of the element and set the offset found + range.setStart(el.firstChild, offset); + range.setEnd(el.firstChild, offset); + } + return range; +} +class CharWidthReader { + static getInstance() { + if (!CharWidthReader._INSTANCE) { + CharWidthReader._INSTANCE = new CharWidthReader(); + } + return CharWidthReader._INSTANCE; + } + constructor() { + this._cache = {}; + this._canvas = document.createElement('canvas'); + } + getCharWidth(char, font) { + const cacheKey = char + font; + if (this._cache[cacheKey]) { + return this._cache[cacheKey]; + } + const context = this._canvas.getContext('2d'); + context.font = font; + const metrics = context.measureText(char); + const width = metrics.width; + this._cache[cacheKey] = width; + return width; + } +} +CharWidthReader._INSTANCE = null; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +let Widget$1 = class Widget extends Disposable { + onclick(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.CLICK, (e) => listener(new StandardMouseEvent(e)))); + } + onmousedown(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.MOUSE_DOWN, (e) => listener(new StandardMouseEvent(e)))); + } + onmouseover(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.MOUSE_OVER, (e) => listener(new StandardMouseEvent(e)))); + } + onmouseleave(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.MOUSE_LEAVE, (e) => listener(new StandardMouseEvent(e)))); + } + onkeydown(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.KEY_DOWN, (e) => listener(new StandardKeyboardEvent(e)))); + } + onkeyup(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.KEY_UP, (e) => listener(new StandardKeyboardEvent(e)))); + } + oninput(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.INPUT, listener)); + } + onblur(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.BLUR, listener)); + } + onfocus(domNode, listener) { + this._register(addDisposableListener(domNode, EventType$1.FOCUS, listener)); + } + ignoreGesture(domNode) { + return Gesture.ignoreTarget(domNode); + } +}; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * The arrow image size. + */ +const ARROW_IMG_SIZE = 11; +class ScrollbarArrow extends Widget$1 { + constructor(opts) { + super(); + this._onActivate = opts.onActivate; + this.bgDomNode = document.createElement('div'); + this.bgDomNode.className = 'arrow-background'; + this.bgDomNode.style.position = 'absolute'; + this.bgDomNode.style.width = opts.bgWidth + 'px'; + this.bgDomNode.style.height = opts.bgHeight + 'px'; + if (typeof opts.top !== 'undefined') { + this.bgDomNode.style.top = '0px'; + } + if (typeof opts.left !== 'undefined') { + this.bgDomNode.style.left = '0px'; + } + if (typeof opts.bottom !== 'undefined') { + this.bgDomNode.style.bottom = '0px'; + } + if (typeof opts.right !== 'undefined') { + this.bgDomNode.style.right = '0px'; + } + this.domNode = document.createElement('div'); + this.domNode.className = opts.className; + this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon)); + this.domNode.style.position = 'absolute'; + this.domNode.style.width = ARROW_IMG_SIZE + 'px'; + this.domNode.style.height = ARROW_IMG_SIZE + 'px'; + if (typeof opts.top !== 'undefined') { + this.domNode.style.top = opts.top + 'px'; + } + if (typeof opts.left !== 'undefined') { + this.domNode.style.left = opts.left + 'px'; + } + if (typeof opts.bottom !== 'undefined') { + this.domNode.style.bottom = opts.bottom + 'px'; + } + if (typeof opts.right !== 'undefined') { + this.domNode.style.right = opts.right + 'px'; + } + this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); + this._register(addStandardDisposableListener(this.bgDomNode, EventType$1.POINTER_DOWN, (e) => this._arrowPointerDown(e))); + this._register(addStandardDisposableListener(this.domNode, EventType$1.POINTER_DOWN, (e) => this._arrowPointerDown(e))); + this._pointerdownRepeatTimer = this._register(new IntervalTimer()); + this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer()); + } + _arrowPointerDown(e) { + if (!e.target || !(e.target instanceof Element)) { + return; + } + const scheduleRepeater = () => { + this._pointerdownRepeatTimer.cancelAndSet(() => this._onActivate(), 1000 / 24); + }; + this._onActivate(); + this._pointerdownRepeatTimer.cancel(); + this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200); + this._pointerMoveMonitor.startMonitoring(e.target, e.pointerId, e.buttons, (pointerMoveData) => { }, () => { + this._pointerdownRepeatTimer.cancel(); + this._pointerdownScheduleRepeatTimer.cancel(); + }); + e.preventDefault(); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class ScrollbarVisibilityController extends Disposable { + constructor(visibility, visibleClassName, invisibleClassName) { + super(); + this._visibility = visibility; + this._visibleClassName = visibleClassName; + this._invisibleClassName = invisibleClassName; + this._domNode = null; + this._isVisible = false; + this._isNeeded = false; + this._rawShouldBeVisible = false; + this._shouldBeVisible = false; + this._revealTimer = this._register(new TimeoutTimer()); + } + setVisibility(visibility) { + if (this._visibility !== visibility) { + this._visibility = visibility; + this._updateShouldBeVisible(); + } + } + // ----------------- Hide / Reveal + setShouldBeVisible(rawShouldBeVisible) { + this._rawShouldBeVisible = rawShouldBeVisible; + this._updateShouldBeVisible(); + } + _applyVisibilitySetting() { + if (this._visibility === 2 /* ScrollbarVisibility.Hidden */) { + return false; + } + if (this._visibility === 3 /* ScrollbarVisibility.Visible */) { + return true; + } + return this._rawShouldBeVisible; + } + _updateShouldBeVisible() { + const shouldBeVisible = this._applyVisibilitySetting(); + if (this._shouldBeVisible !== shouldBeVisible) { + this._shouldBeVisible = shouldBeVisible; + this.ensureVisibility(); + } + } + setIsNeeded(isNeeded) { + if (this._isNeeded !== isNeeded) { + this._isNeeded = isNeeded; + this.ensureVisibility(); + } + } + setDomNode(domNode) { + this._domNode = domNode; + this._domNode.setClassName(this._invisibleClassName); + // Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration + this.setShouldBeVisible(false); + } + ensureVisibility() { + if (!this._isNeeded) { + // Nothing to be rendered + this._hide(false); + return; + } + if (this._shouldBeVisible) { + this._reveal(); + } + else { + this._hide(true); + } + } + _reveal() { + if (this._isVisible) { + return; + } + this._isVisible = true; + // The CSS animation doesn't play otherwise + this._revealTimer.setIfNotSet(() => { + var _a; + (_a = this._domNode) === null || _a === void 0 ? void 0 : _a.setClassName(this._visibleClassName); + }, 0); + } + _hide(withFadeAway) { + var _a; + this._revealTimer.cancel(); + if (!this._isVisible) { + return; + } + this._isVisible = false; + (_a = this._domNode) === null || _a === void 0 ? void 0 : _a.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : '')); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * The orthogonal distance to the slider at which dragging "resets". This implements "snapping" + */ +const POINTER_DRAG_RESET_DISTANCE$1 = 140; +class AbstractScrollbar extends Widget$1 { + constructor(opts) { + super(); + this._lazyRender = opts.lazyRender; + this._host = opts.host; + this._scrollable = opts.scrollable; + this._scrollByPage = opts.scrollByPage; + this._scrollbarState = opts.scrollbarState; + this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName)); + this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); + this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); + this._shouldRender = true; + this.domNode = createFastDomNode(document.createElement('div')); + this.domNode.setAttribute('role', 'presentation'); + this.domNode.setAttribute('aria-hidden', 'true'); + this._visibilityController.setDomNode(this.domNode); + this.domNode.setPosition('absolute'); + this._register(addDisposableListener(this.domNode.domNode, EventType$1.POINTER_DOWN, (e) => this._domNodePointerDown(e))); + } + // ----------------- creation + /** + * Creates the dom node for an arrow & adds it to the container + */ + _createArrow(opts) { + const arrow = this._register(new ScrollbarArrow(opts)); + this.domNode.domNode.appendChild(arrow.bgDomNode); + this.domNode.domNode.appendChild(arrow.domNode); + } + /** + * Creates the slider dom node, adds it to the container & hooks up the events + */ + _createSlider(top, left, width, height) { + this.slider = createFastDomNode(document.createElement('div')); + this.slider.setClassName('slider'); + this.slider.setPosition('absolute'); + this.slider.setTop(top); + this.slider.setLeft(left); + if (typeof width === 'number') { + this.slider.setWidth(width); + } + if (typeof height === 'number') { + this.slider.setHeight(height); + } + this.slider.setLayerHinting(true); + this.slider.setContain('strict'); + this.domNode.domNode.appendChild(this.slider.domNode); + this._register(addDisposableListener(this.slider.domNode, EventType$1.POINTER_DOWN, (e) => { + if (e.button === 0) { + e.preventDefault(); + this._sliderPointerDown(e); + } + })); + this.onclick(this.slider.domNode, e => { + if (e.leftButton) { + e.stopPropagation(); + } + }); + } + // ----------------- Update state + _onElementSize(visibleSize) { + if (this._scrollbarState.setVisibleSize(visibleSize)) { + this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); + this._shouldRender = true; + if (!this._lazyRender) { + this.render(); + } + } + return this._shouldRender; + } + _onElementScrollSize(elementScrollSize) { + if (this._scrollbarState.setScrollSize(elementScrollSize)) { + this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); + this._shouldRender = true; + if (!this._lazyRender) { + this.render(); + } + } + return this._shouldRender; + } + _onElementScrollPosition(elementScrollPosition) { + if (this._scrollbarState.setScrollPosition(elementScrollPosition)) { + this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); + this._shouldRender = true; + if (!this._lazyRender) { + this.render(); + } + } + return this._shouldRender; + } + // ----------------- rendering + beginReveal() { + this._visibilityController.setShouldBeVisible(true); + } + beginHide() { + this._visibilityController.setShouldBeVisible(false); + } + render() { + if (!this._shouldRender) { + return; + } + this._shouldRender = false; + this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize()); + this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition()); + } + // ----------------- DOM events + _domNodePointerDown(e) { + if (e.target !== this.domNode.domNode) { + return; + } + this._onPointerDown(e); + } + delegatePointerDown(e) { + const domTop = this.domNode.domNode.getClientRects()[0].top; + const sliderStart = domTop + this._scrollbarState.getSliderPosition(); + const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize(); + const pointerPos = this._sliderPointerPosition(e); + if (sliderStart <= pointerPos && pointerPos <= sliderStop) { + // Act as if it was a pointer down on the slider + if (e.button === 0) { + e.preventDefault(); + this._sliderPointerDown(e); + } + } + else { + // Act as if it was a pointer down on the scrollbar + this._onPointerDown(e); + } + } + _onPointerDown(e) { + let offsetX; + let offsetY; + if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') { + offsetX = e.offsetX; + offsetY = e.offsetY; + } + else { + const domNodePosition = getDomNodePagePosition(this.domNode.domNode); + offsetX = e.pageX - domNodePosition.left; + offsetY = e.pageY - domNodePosition.top; + } + const offset = this._pointerDownRelativePosition(offsetX, offsetY); + this._setDesiredScrollPositionNow(this._scrollByPage + ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset) + : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)); + if (e.button === 0) { + // left button + e.preventDefault(); + this._sliderPointerDown(e); + } + } + _sliderPointerDown(e) { + if (!e.target || !(e.target instanceof Element)) { + return; + } + const initialPointerPosition = this._sliderPointerPosition(e); + const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e); + const initialScrollbarState = this._scrollbarState.clone(); + this.slider.toggleClassName('active', true); + this._pointerMoveMonitor.startMonitoring(e.target, e.pointerId, e.buttons, (pointerMoveData) => { + const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData); + const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition); + if (isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE$1) { + // The pointer has wondered away from the scrollbar => reset dragging + this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition()); + return; + } + const pointerPosition = this._sliderPointerPosition(pointerMoveData); + const pointerDelta = pointerPosition - initialPointerPosition; + this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta)); + }, () => { + this.slider.toggleClassName('active', false); + this._host.onDragEnd(); + }); + this._host.onDragStart(); + } + _setDesiredScrollPositionNow(_desiredScrollPosition) { + const desiredScrollPosition = {}; + this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition); + this._scrollable.setScrollPositionNow(desiredScrollPosition); + } + updateScrollbarSize(scrollbarSize) { + this._updateScrollbarSize(scrollbarSize); + this._scrollbarState.setScrollbarSize(scrollbarSize); + this._shouldRender = true; + if (!this._lazyRender) { + this.render(); + } + } + isNeeded() { + return this._scrollbarState.isNeeded(); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * The minimal size of the slider (such that it can still be clickable) -- it is artificially enlarged. + */ +const MINIMUM_SLIDER_SIZE = 20; +class ScrollbarState { + constructor(arrowSize, scrollbarSize, oppositeScrollbarSize, visibleSize, scrollSize, scrollPosition) { + this._scrollbarSize = Math.round(scrollbarSize); + this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize); + this._arrowSize = Math.round(arrowSize); + this._visibleSize = visibleSize; + this._scrollSize = scrollSize; + this._scrollPosition = scrollPosition; + this._computedAvailableSize = 0; + this._computedIsNeeded = false; + this._computedSliderSize = 0; + this._computedSliderRatio = 0; + this._computedSliderPosition = 0; + this._refreshComputedValues(); + } + clone() { + return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition); + } + setVisibleSize(visibleSize) { + const iVisibleSize = Math.round(visibleSize); + if (this._visibleSize !== iVisibleSize) { + this._visibleSize = iVisibleSize; + this._refreshComputedValues(); + return true; + } + return false; + } + setScrollSize(scrollSize) { + const iScrollSize = Math.round(scrollSize); + if (this._scrollSize !== iScrollSize) { + this._scrollSize = iScrollSize; + this._refreshComputedValues(); + return true; + } + return false; + } + setScrollPosition(scrollPosition) { + const iScrollPosition = Math.round(scrollPosition); + if (this._scrollPosition !== iScrollPosition) { + this._scrollPosition = iScrollPosition; + this._refreshComputedValues(); + return true; + } + return false; + } + setScrollbarSize(scrollbarSize) { + this._scrollbarSize = Math.round(scrollbarSize); + } + setOppositeScrollbarSize(oppositeScrollbarSize) { + this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize); + } + static _computeValues(oppositeScrollbarSize, arrowSize, visibleSize, scrollSize, scrollPosition) { + const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize); + const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize); + const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize); + if (!computedIsNeeded) { + // There is no need for a slider + return { + computedAvailableSize: Math.round(computedAvailableSize), + computedIsNeeded: computedIsNeeded, + computedSliderSize: Math.round(computedRepresentableSize), + computedSliderRatio: 0, + computedSliderPosition: 0, + }; + } + // We must artificially increase the size of the slider if needed, since the slider would be too small to grab with the mouse otherwise + const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize))); + // The slider can move from 0 to `computedRepresentableSize` - `computedSliderSize` + // in the same way `scrollPosition` can move from 0 to `scrollSize` - `visibleSize`. + const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize); + const computedSliderPosition = (scrollPosition * computedSliderRatio); + return { + computedAvailableSize: Math.round(computedAvailableSize), + computedIsNeeded: computedIsNeeded, + computedSliderSize: Math.round(computedSliderSize), + computedSliderRatio: computedSliderRatio, + computedSliderPosition: Math.round(computedSliderPosition), + }; + } + _refreshComputedValues() { + const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition); + this._computedAvailableSize = r.computedAvailableSize; + this._computedIsNeeded = r.computedIsNeeded; + this._computedSliderSize = r.computedSliderSize; + this._computedSliderRatio = r.computedSliderRatio; + this._computedSliderPosition = r.computedSliderPosition; + } + getArrowSize() { + return this._arrowSize; + } + getScrollPosition() { + return this._scrollPosition; + } + getRectangleLargeSize() { + return this._computedAvailableSize; + } + getRectangleSmallSize() { + return this._scrollbarSize; + } + isNeeded() { + return this._computedIsNeeded; + } + getSliderSize() { + return this._computedSliderSize; + } + getSliderPosition() { + return this._computedSliderPosition; + } + /** + * Compute a desired `scrollPosition` such that `offset` ends up in the center of the slider. + * `offset` is based on the same coordinate system as the `sliderPosition`. + */ + getDesiredScrollPositionFromOffset(offset) { + if (!this._computedIsNeeded) { + // no need for a slider + return 0; + } + const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2; + return Math.round(desiredSliderPosition / this._computedSliderRatio); + } + /** + * Compute a desired `scrollPosition` from if offset is before or after the slider position. + * If offset is before slider, treat as a page up (or left). If after, page down (or right). + * `offset` and `_computedSliderPosition` are based on the same coordinate system. + * `_visibleSize` corresponds to a "page" of lines in the returned coordinate system. + */ + getDesiredScrollPositionFromOffsetPaged(offset) { + if (!this._computedIsNeeded) { + // no need for a slider + return 0; + } + const correctedOffset = offset - this._arrowSize; // compensate if has arrows + let desiredScrollPosition = this._scrollPosition; + if (correctedOffset < this._computedSliderPosition) { + desiredScrollPosition -= this._visibleSize; // page up/left + } + else { + desiredScrollPosition += this._visibleSize; // page down/right + } + return desiredScrollPosition; + } + /** + * Compute a desired `scrollPosition` such that the slider moves by `delta`. + */ + getDesiredScrollPositionFromDelta(delta) { + if (!this._computedIsNeeded) { + // no need for a slider + return 0; + } + const desiredSliderPosition = this._computedSliderPosition + delta; + return Math.round(desiredSliderPosition / this._computedSliderRatio); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class HorizontalScrollbar extends AbstractScrollbar { + constructor(scrollable, options, host) { + const scrollDimensions = scrollable.getScrollDimensions(); + const scrollPosition = scrollable.getCurrentScrollPosition(); + super({ + lazyRender: options.lazyRender, + host: host, + scrollbarState: new ScrollbarState((options.horizontalHasArrows ? options.arrowSize : 0), (options.horizontal === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.horizontalScrollbarSize), (options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize), scrollDimensions.width, scrollDimensions.scrollWidth, scrollPosition.scrollLeft), + visibility: options.horizontal, + extraScrollbarClassName: 'horizontal', + scrollable: scrollable, + scrollByPage: options.scrollByPage + }); + if (options.horizontalHasArrows) { + const arrowDelta = (options.arrowSize - ARROW_IMG_SIZE) / 2; + const scrollbarDelta = (options.horizontalScrollbarSize - ARROW_IMG_SIZE) / 2; + this._createArrow({ + className: 'scra', + icon: Codicon.scrollbarButtonLeft, + top: scrollbarDelta, + left: arrowDelta, + bottom: undefined, + right: undefined, + bgWidth: options.arrowSize, + bgHeight: options.horizontalScrollbarSize, + onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, 1, 0)), + }); + this._createArrow({ + className: 'scra', + icon: Codicon.scrollbarButtonRight, + top: scrollbarDelta, + left: undefined, + bottom: undefined, + right: arrowDelta, + bgWidth: options.arrowSize, + bgHeight: options.horizontalScrollbarSize, + onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, -1, 0)), + }); + } + this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize); + } + _updateSlider(sliderSize, sliderPosition) { + this.slider.setWidth(sliderSize); + this.slider.setLeft(sliderPosition); + } + _renderDomNode(largeSize, smallSize) { + this.domNode.setWidth(largeSize); + this.domNode.setHeight(smallSize); + this.domNode.setLeft(0); + this.domNode.setBottom(0); + } + onDidScroll(e) { + this._shouldRender = this._onElementScrollSize(e.scrollWidth) || this._shouldRender; + this._shouldRender = this._onElementScrollPosition(e.scrollLeft) || this._shouldRender; + this._shouldRender = this._onElementSize(e.width) || this._shouldRender; + return this._shouldRender; + } + _pointerDownRelativePosition(offsetX, offsetY) { + return offsetX; + } + _sliderPointerPosition(e) { + return e.pageX; + } + _sliderOrthogonalPointerPosition(e) { + return e.pageY; + } + _updateScrollbarSize(size) { + this.slider.setHeight(size); + } + writeScrollPosition(target, scrollPosition) { + target.scrollLeft = scrollPosition; + } + updateOptions(options) { + this.updateScrollbarSize(options.horizontal === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.horizontalScrollbarSize); + this._scrollbarState.setOppositeScrollbarSize(options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize); + this._visibilityController.setVisibility(options.horizontal); + this._scrollByPage = options.scrollByPage; + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class VerticalScrollbar extends AbstractScrollbar { + constructor(scrollable, options, host) { + const scrollDimensions = scrollable.getScrollDimensions(); + const scrollPosition = scrollable.getCurrentScrollPosition(); + super({ + lazyRender: options.lazyRender, + host: host, + scrollbarState: new ScrollbarState((options.verticalHasArrows ? options.arrowSize : 0), (options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize), + // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom + 0, scrollDimensions.height, scrollDimensions.scrollHeight, scrollPosition.scrollTop), + visibility: options.vertical, + extraScrollbarClassName: 'vertical', + scrollable: scrollable, + scrollByPage: options.scrollByPage + }); + if (options.verticalHasArrows) { + const arrowDelta = (options.arrowSize - ARROW_IMG_SIZE) / 2; + const scrollbarDelta = (options.verticalScrollbarSize - ARROW_IMG_SIZE) / 2; + this._createArrow({ + className: 'scra', + icon: Codicon.scrollbarButtonUp, + top: arrowDelta, + left: scrollbarDelta, + bottom: undefined, + right: undefined, + bgWidth: options.verticalScrollbarSize, + bgHeight: options.arrowSize, + onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, 0, 1)), + }); + this._createArrow({ + className: 'scra', + icon: Codicon.scrollbarButtonDown, + top: undefined, + left: scrollbarDelta, + bottom: arrowDelta, + right: undefined, + bgWidth: options.verticalScrollbarSize, + bgHeight: options.arrowSize, + onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, 0, -1)), + }); + } + this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined); + } + _updateSlider(sliderSize, sliderPosition) { + this.slider.setHeight(sliderSize); + this.slider.setTop(sliderPosition); + } + _renderDomNode(largeSize, smallSize) { + this.domNode.setWidth(smallSize); + this.domNode.setHeight(largeSize); + this.domNode.setRight(0); + this.domNode.setTop(0); + } + onDidScroll(e) { + this._shouldRender = this._onElementScrollSize(e.scrollHeight) || this._shouldRender; + this._shouldRender = this._onElementScrollPosition(e.scrollTop) || this._shouldRender; + this._shouldRender = this._onElementSize(e.height) || this._shouldRender; + return this._shouldRender; + } + _pointerDownRelativePosition(offsetX, offsetY) { + return offsetY; + } + _sliderPointerPosition(e) { + return e.pageY; + } + _sliderOrthogonalPointerPosition(e) { + return e.pageX; + } + _updateScrollbarSize(size) { + this.slider.setWidth(size); + } + writeScrollPosition(target, scrollPosition) { + target.scrollTop = scrollPosition; + } + updateOptions(options) { + this.updateScrollbarSize(options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize); + // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom + this._scrollbarState.setOppositeScrollbarSize(0); + this._visibilityController.setVisibility(options.vertical); + this._scrollByPage = options.scrollByPage; + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class ScrollState { + constructor(_forceIntegerValues, width, scrollWidth, scrollLeft, height, scrollHeight, scrollTop) { + this._forceIntegerValues = _forceIntegerValues; + this._scrollStateBrand = undefined; + if (this._forceIntegerValues) { + width = width | 0; + scrollWidth = scrollWidth | 0; + scrollLeft = scrollLeft | 0; + height = height | 0; + scrollHeight = scrollHeight | 0; + scrollTop = scrollTop | 0; + } + this.rawScrollLeft = scrollLeft; // before validation + this.rawScrollTop = scrollTop; // before validation + if (width < 0) { + width = 0; + } + if (scrollLeft + width > scrollWidth) { + scrollLeft = scrollWidth - width; + } + if (scrollLeft < 0) { + scrollLeft = 0; + } + if (height < 0) { + height = 0; + } + if (scrollTop + height > scrollHeight) { + scrollTop = scrollHeight - height; + } + if (scrollTop < 0) { + scrollTop = 0; + } + this.width = width; + this.scrollWidth = scrollWidth; + this.scrollLeft = scrollLeft; + this.height = height; + this.scrollHeight = scrollHeight; + this.scrollTop = scrollTop; + } + equals(other) { + return (this.rawScrollLeft === other.rawScrollLeft + && this.rawScrollTop === other.rawScrollTop + && this.width === other.width + && this.scrollWidth === other.scrollWidth + && this.scrollLeft === other.scrollLeft + && this.height === other.height + && this.scrollHeight === other.scrollHeight + && this.scrollTop === other.scrollTop); + } + withScrollDimensions(update, useRawScrollPositions) { + return new ScrollState(this._forceIntegerValues, (typeof update.width !== 'undefined' ? update.width : this.width), (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth), useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft, (typeof update.height !== 'undefined' ? update.height : this.height), (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight), useRawScrollPositions ? this.rawScrollTop : this.scrollTop); + } + withScrollPosition(update) { + return new ScrollState(this._forceIntegerValues, this.width, this.scrollWidth, (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft), this.height, this.scrollHeight, (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)); + } + createScrollEvent(previous, inSmoothScrolling) { + const widthChanged = (this.width !== previous.width); + const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth); + const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft); + const heightChanged = (this.height !== previous.height); + const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight); + const scrollTopChanged = (this.scrollTop !== previous.scrollTop); + return { + inSmoothScrolling: inSmoothScrolling, + oldWidth: previous.width, + oldScrollWidth: previous.scrollWidth, + oldScrollLeft: previous.scrollLeft, + width: this.width, + scrollWidth: this.scrollWidth, + scrollLeft: this.scrollLeft, + oldHeight: previous.height, + oldScrollHeight: previous.scrollHeight, + oldScrollTop: previous.scrollTop, + height: this.height, + scrollHeight: this.scrollHeight, + scrollTop: this.scrollTop, + widthChanged: widthChanged, + scrollWidthChanged: scrollWidthChanged, + scrollLeftChanged: scrollLeftChanged, + heightChanged: heightChanged, + scrollHeightChanged: scrollHeightChanged, + scrollTopChanged: scrollTopChanged, + }; + } +} +class Scrollable extends Disposable { + constructor(options) { + super(); + this._scrollableBrand = undefined; + this._onScroll = this._register(new Emitter$1()); + this.onScroll = this._onScroll.event; + this._smoothScrollDuration = options.smoothScrollDuration; + this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame; + this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0); + this._smoothScrolling = null; + } + dispose() { + if (this._smoothScrolling) { + this._smoothScrolling.dispose(); + this._smoothScrolling = null; + } + super.dispose(); + } + setSmoothScrollDuration(smoothScrollDuration) { + this._smoothScrollDuration = smoothScrollDuration; + } + validateScrollPosition(scrollPosition) { + return this._state.withScrollPosition(scrollPosition); + } + getScrollDimensions() { + return this._state; + } + setScrollDimensions(dimensions, useRawScrollPositions) { + var _a; + const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions); + this._setState(newState, Boolean(this._smoothScrolling)); + // Validate outstanding animated scroll position target + (_a = this._smoothScrolling) === null || _a === void 0 ? void 0 : _a.acceptScrollDimensions(this._state); + } + /** + * Returns the final scroll position that the instance will have once the smooth scroll animation concludes. + * If no scroll animation is occurring, it will return the current scroll position instead. + */ + getFutureScrollPosition() { + if (this._smoothScrolling) { + return this._smoothScrolling.to; + } + return this._state; + } + /** + * Returns the current scroll position. + * Note: This result might be an intermediate scroll position, as there might be an ongoing smooth scroll animation. + */ + getCurrentScrollPosition() { + return this._state; + } + setScrollPositionNow(update) { + // no smooth scrolling requested + const newState = this._state.withScrollPosition(update); + // Terminate any outstanding smooth scrolling + if (this._smoothScrolling) { + this._smoothScrolling.dispose(); + this._smoothScrolling = null; + } + this._setState(newState, false); + } + setScrollPositionSmooth(update, reuseAnimation) { + if (this._smoothScrollDuration === 0) { + // Smooth scrolling not supported. + return this.setScrollPositionNow(update); + } + if (this._smoothScrolling) { + // Combine our pending scrollLeft/scrollTop with incoming scrollLeft/scrollTop + update = { + scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft), + scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop) + }; + // Validate `update` + const validTarget = this._state.withScrollPosition(update); + if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) { + // No need to interrupt or extend the current animation since we're going to the same place + return; + } + let newSmoothScrolling; + if (reuseAnimation) { + newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration); + } + else { + newSmoothScrolling = this._smoothScrolling.combine(this._state, validTarget, this._smoothScrollDuration); + } + this._smoothScrolling.dispose(); + this._smoothScrolling = newSmoothScrolling; + } + else { + // Validate `update` + const validTarget = this._state.withScrollPosition(update); + this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration); + } + // Begin smooth scrolling animation + this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => { + if (!this._smoothScrolling) { + return; + } + this._smoothScrolling.animationFrameDisposable = null; + this._performSmoothScrolling(); + }); + } + hasPendingScrollAnimation() { + return Boolean(this._smoothScrolling); + } + _performSmoothScrolling() { + if (!this._smoothScrolling) { + return; + } + const update = this._smoothScrolling.tick(); + const newState = this._state.withScrollPosition(update); + this._setState(newState, true); + if (!this._smoothScrolling) { + // Looks like someone canceled the smooth scrolling + // from the scroll event handler + return; + } + if (update.isDone) { + this._smoothScrolling.dispose(); + this._smoothScrolling = null; + return; + } + // Continue smooth scrolling animation + this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => { + if (!this._smoothScrolling) { + return; + } + this._smoothScrolling.animationFrameDisposable = null; + this._performSmoothScrolling(); + }); + } + _setState(newState, inSmoothScrolling) { + const oldState = this._state; + if (oldState.equals(newState)) { + // no change + return; + } + this._state = newState; + this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling)); + } +} +class SmoothScrollingUpdate { + constructor(scrollLeft, scrollTop, isDone) { + this.scrollLeft = scrollLeft; + this.scrollTop = scrollTop; + this.isDone = isDone; + } +} +function createEaseOutCubic(from, to) { + const delta = to - from; + return function (completion) { + return from + delta * easeOutCubic(completion); + }; +} +function createComposed(a, b, cut) { + return function (completion) { + if (completion < cut) { + return a(completion / cut); + } + return b((completion - cut) / (1 - cut)); + }; +} +class SmoothScrollingOperation { + constructor(from, to, startTime, duration) { + this.from = from; + this.to = to; + this.duration = duration; + this.startTime = startTime; + this.animationFrameDisposable = null; + this._initAnimations(); + } + _initAnimations() { + this.scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width); + this.scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height); + } + _initAnimation(from, to, viewportSize) { + const delta = Math.abs(from - to); + if (delta > 2.5 * viewportSize) { + let stop1, stop2; + if (from < to) { + // scroll to 75% of the viewportSize + stop1 = from + 0.75 * viewportSize; + stop2 = to - 0.75 * viewportSize; + } + else { + stop1 = from - 0.75 * viewportSize; + stop2 = to + 0.75 * viewportSize; + } + return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33); + } + return createEaseOutCubic(from, to); + } + dispose() { + if (this.animationFrameDisposable !== null) { + this.animationFrameDisposable.dispose(); + this.animationFrameDisposable = null; + } + } + acceptScrollDimensions(state) { + this.to = state.withScrollPosition(this.to); + this._initAnimations(); + } + tick() { + return this._tick(Date.now()); + } + _tick(now) { + const completion = (now - this.startTime) / this.duration; + if (completion < 1) { + const newScrollLeft = this.scrollLeft(completion); + const newScrollTop = this.scrollTop(completion); + return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false); + } + return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true); + } + combine(from, to, duration) { + return SmoothScrollingOperation.start(from, to, duration); + } + static start(from, to, duration) { + // +10 / -10 : pretend the animation already started for a quicker response to a scroll request + duration = duration + 10; + const startTime = Date.now() - 10; + return new SmoothScrollingOperation(from, to, startTime, duration); + } +} +function easeInCubic(t) { + return Math.pow(t, 3); +} +function easeOutCubic(t) { + return 1 - easeInCubic(1 - t); +} + +const scrollbars = ''; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const HIDE_TIMEOUT = 500; +const SCROLL_WHEEL_SENSITIVITY = 50; +class MouseWheelClassifierItem { + constructor(timestamp, deltaX, deltaY) { + this.timestamp = timestamp; + this.deltaX = deltaX; + this.deltaY = deltaY; + this.score = 0; + } +} +class MouseWheelClassifier { + constructor() { + this._capacity = 5; + this._memory = []; + this._front = -1; + this._rear = -1; + } + isPhysicalMouseWheel() { + if (this._front === -1 && this._rear === -1) { + // no elements + return false; + } + // 0.5 * last + 0.25 * 2nd last + 0.125 * 3rd last + ... + let remainingInfluence = 1; + let score = 0; + let iteration = 1; + let index = this._rear; + do { + const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration)); + remainingInfluence -= influence; + score += this._memory[index].score * influence; + if (index === this._front) { + break; + } + index = (this._capacity + index - 1) % this._capacity; + iteration++; + } while (true); + return (score <= 0.5); + } + acceptStandardWheelEvent(e) { + const osZoomFactor = window.devicePixelRatio / getZoomFactor(); + if (isWindows || isLinux) { + // On Windows and Linux, the incoming delta events are multiplied with the OS zoom factor. + // The OS zoom factor can be reverse engineered by using the device pixel ratio and the configured zoom factor into account. + this.accept(Date.now(), e.deltaX / osZoomFactor, e.deltaY / osZoomFactor); + } + else { + this.accept(Date.now(), e.deltaX, e.deltaY); + } + } + accept(timestamp, deltaX, deltaY) { + const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY); + item.score = this._computeScore(item); + if (this._front === -1 && this._rear === -1) { + this._memory[0] = item; + this._front = 0; + this._rear = 0; + } + else { + this._rear = (this._rear + 1) % this._capacity; + if (this._rear === this._front) { + // Drop oldest + this._front = (this._front + 1) % this._capacity; + } + this._memory[this._rear] = item; + } + } + /** + * A score between 0 and 1 for `item`. + * - a score towards 0 indicates that the source appears to be a physical mouse wheel + * - a score towards 1 indicates that the source appears to be a touchpad or magic mouse, etc. + */ + _computeScore(item) { + if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) { + // both axes exercised => definitely not a physical mouse wheel + return 1; + } + let score = 0.5; + (this._front === -1 && this._rear === -1 ? null : this._memory[this._rear]); + if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) { + // non-integer deltas => indicator that this is not a physical mouse wheel + score += 0.25; + } + return Math.min(Math.max(score, 0), 1); + } + _isAlmostInt(value) { + const delta = Math.abs(Math.round(value) - value); + return (delta < 0.01); + } +} +MouseWheelClassifier.INSTANCE = new MouseWheelClassifier(); +class AbstractScrollableElement extends Widget$1 { + get options() { + return this._options; + } + constructor(element, options, scrollable) { + super(); + this._onScroll = this._register(new Emitter$1()); + this.onScroll = this._onScroll.event; + this._onWillScroll = this._register(new Emitter$1()); + element.style.overflow = 'hidden'; + this._options = resolveOptions$1(options); + this._scrollable = scrollable; + this._register(this._scrollable.onScroll((e) => { + this._onWillScroll.fire(e); + this._onDidScroll(e); + this._onScroll.fire(e); + })); + const scrollbarHost = { + onMouseWheel: (mouseWheelEvent) => this._onMouseWheel(mouseWheelEvent), + onDragStart: () => this._onDragStart(), + onDragEnd: () => this._onDragEnd(), + }; + this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost)); + this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost)); + this._domNode = document.createElement('div'); + this._domNode.className = 'monaco-scrollable-element ' + this._options.className; + this._domNode.setAttribute('role', 'presentation'); + this._domNode.style.position = 'relative'; + this._domNode.style.overflow = 'hidden'; + this._domNode.appendChild(element); + this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode); + this._domNode.appendChild(this._verticalScrollbar.domNode.domNode); + if (this._options.useShadows) { + this._leftShadowDomNode = createFastDomNode(document.createElement('div')); + this._leftShadowDomNode.setClassName('shadow'); + this._domNode.appendChild(this._leftShadowDomNode.domNode); + this._topShadowDomNode = createFastDomNode(document.createElement('div')); + this._topShadowDomNode.setClassName('shadow'); + this._domNode.appendChild(this._topShadowDomNode.domNode); + this._topLeftShadowDomNode = createFastDomNode(document.createElement('div')); + this._topLeftShadowDomNode.setClassName('shadow'); + this._domNode.appendChild(this._topLeftShadowDomNode.domNode); + } + else { + this._leftShadowDomNode = null; + this._topShadowDomNode = null; + this._topLeftShadowDomNode = null; + } + this._listenOnDomNode = this._options.listenOnDomNode || this._domNode; + this._mouseWheelToDispose = []; + this._setListeningToMouseWheel(this._options.handleMouseWheel); + this.onmouseover(this._listenOnDomNode, (e) => this._onMouseOver(e)); + this.onmouseleave(this._listenOnDomNode, (e) => this._onMouseLeave(e)); + this._hideTimeout = this._register(new TimeoutTimer()); + this._isDragging = false; + this._mouseIsOver = false; + this._shouldRender = true; + this._revealOnScroll = true; + } + dispose() { + this._mouseWheelToDispose = dispose(this._mouseWheelToDispose); + super.dispose(); + } + /** + * Get the generated 'scrollable' dom node + */ + getDomNode() { + return this._domNode; + } + getOverviewRulerLayoutInfo() { + return { + parent: this._domNode, + insertBefore: this._verticalScrollbar.domNode.domNode, + }; + } + /** + * Delegate a pointer down event to the vertical scrollbar. + * This is to help with clicking somewhere else and having the scrollbar react. + */ + delegateVerticalScrollbarPointerDown(browserEvent) { + this._verticalScrollbar.delegatePointerDown(browserEvent); + } + getScrollDimensions() { + return this._scrollable.getScrollDimensions(); + } + setScrollDimensions(dimensions) { + this._scrollable.setScrollDimensions(dimensions, false); + } + /** + * Update the class name of the scrollable element. + */ + updateClassName(newClassName) { + this._options.className = newClassName; + // Defaults are different on Macs + if (isMacintosh) { + this._options.className += ' mac'; + } + this._domNode.className = 'monaco-scrollable-element ' + this._options.className; + } + /** + * Update configuration options for the scrollbar. + */ + updateOptions(newOptions) { + if (typeof newOptions.handleMouseWheel !== 'undefined') { + this._options.handleMouseWheel = newOptions.handleMouseWheel; + this._setListeningToMouseWheel(this._options.handleMouseWheel); + } + if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') { + this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity; + } + if (typeof newOptions.fastScrollSensitivity !== 'undefined') { + this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity; + } + if (typeof newOptions.scrollPredominantAxis !== 'undefined') { + this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis; + } + if (typeof newOptions.horizontal !== 'undefined') { + this._options.horizontal = newOptions.horizontal; + } + if (typeof newOptions.vertical !== 'undefined') { + this._options.vertical = newOptions.vertical; + } + if (typeof newOptions.horizontalScrollbarSize !== 'undefined') { + this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize; + } + if (typeof newOptions.verticalScrollbarSize !== 'undefined') { + this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize; + } + if (typeof newOptions.scrollByPage !== 'undefined') { + this._options.scrollByPage = newOptions.scrollByPage; + } + this._horizontalScrollbar.updateOptions(this._options); + this._verticalScrollbar.updateOptions(this._options); + if (!this._options.lazyRender) { + this._render(); + } + } + delegateScrollFromMouseWheelEvent(browserEvent) { + this._onMouseWheel(new StandardWheelEvent(browserEvent)); + } + // -------------------- mouse wheel scrolling -------------------- + _setListeningToMouseWheel(shouldListen) { + const isListening = (this._mouseWheelToDispose.length > 0); + if (isListening === shouldListen) { + // No change + return; + } + // Stop listening (if necessary) + this._mouseWheelToDispose = dispose(this._mouseWheelToDispose); + // Start listening (if necessary) + if (shouldListen) { + const onMouseWheel = (browserEvent) => { + this._onMouseWheel(new StandardWheelEvent(browserEvent)); + }; + this._mouseWheelToDispose.push(addDisposableListener(this._listenOnDomNode, EventType$1.MOUSE_WHEEL, onMouseWheel, { passive: false })); + } + } + _onMouseWheel(e) { + const classifier = MouseWheelClassifier.INSTANCE; + { + classifier.acceptStandardWheelEvent(e); + } + // console.log(`${Date.now()}, ${e.deltaY}, ${e.deltaX}`); + let didScroll = false; + if (e.deltaY || e.deltaX) { + let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity; + let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity; + if (this._options.scrollPredominantAxis) { + if (Math.abs(deltaY) >= Math.abs(deltaX)) { + deltaX = 0; + } + else { + deltaY = 0; + } + } + if (this._options.flipAxes) { + [deltaY, deltaX] = [deltaX, deltaY]; + } + // Convert vertical scrolling to horizontal if shift is held, this + // is handled at a higher level on Mac + const shiftConvert = !isMacintosh && e.browserEvent && e.browserEvent.shiftKey; + if ((this._options.scrollYToX || shiftConvert) && !deltaX) { + deltaX = deltaY; + deltaY = 0; + } + if (e.browserEvent && e.browserEvent.altKey) { + // fastScrolling + deltaX = deltaX * this._options.fastScrollSensitivity; + deltaY = deltaY * this._options.fastScrollSensitivity; + } + const futureScrollPosition = this._scrollable.getFutureScrollPosition(); + let desiredScrollPosition = {}; + if (deltaY) { + const deltaScrollTop = SCROLL_WHEEL_SENSITIVITY * deltaY; + // Here we convert values such as -0.3 to -1 or 0.3 to 1, otherwise low speed scrolling will never scroll + const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop)); + this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop); + } + if (deltaX) { + const deltaScrollLeft = SCROLL_WHEEL_SENSITIVITY * deltaX; + // Here we convert values such as -0.3 to -1 or 0.3 to 1, otherwise low speed scrolling will never scroll + const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft)); + this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft); + } + // Check that we are scrolling towards a location which is valid + desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition); + if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) { + const canPerformSmoothScroll = (this._options.mouseWheelSmoothScroll + && classifier.isPhysicalMouseWheel()); + if (canPerformSmoothScroll) { + this._scrollable.setScrollPositionSmooth(desiredScrollPosition); + } + else { + this._scrollable.setScrollPositionNow(desiredScrollPosition); + } + didScroll = true; + } + } + let consumeMouseWheel = didScroll; + if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) { + consumeMouseWheel = true; + } + if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) { + consumeMouseWheel = true; + } + if (consumeMouseWheel) { + e.preventDefault(); + e.stopPropagation(); + } + } + _onDidScroll(e) { + this._shouldRender = this._horizontalScrollbar.onDidScroll(e) || this._shouldRender; + this._shouldRender = this._verticalScrollbar.onDidScroll(e) || this._shouldRender; + if (this._options.useShadows) { + this._shouldRender = true; + } + if (this._revealOnScroll) { + this._reveal(); + } + if (!this._options.lazyRender) { + this._render(); + } + } + /** + * Render / mutate the DOM now. + * Should be used together with the ctor option `lazyRender`. + */ + renderNow() { + if (!this._options.lazyRender) { + throw new Error('Please use `lazyRender` together with `renderNow`!'); + } + this._render(); + } + _render() { + if (!this._shouldRender) { + return; + } + this._shouldRender = false; + this._horizontalScrollbar.render(); + this._verticalScrollbar.render(); + if (this._options.useShadows) { + const scrollState = this._scrollable.getCurrentScrollPosition(); + const enableTop = scrollState.scrollTop > 0; + const enableLeft = scrollState.scrollLeft > 0; + const leftClassName = (enableLeft ? ' left' : ''); + const topClassName = (enableTop ? ' top' : ''); + const topLeftClassName = (enableLeft || enableTop ? ' top-left-corner' : ''); + this._leftShadowDomNode.setClassName(`shadow${leftClassName}`); + this._topShadowDomNode.setClassName(`shadow${topClassName}`); + this._topLeftShadowDomNode.setClassName(`shadow${topLeftClassName}${topClassName}${leftClassName}`); + } + } + // -------------------- fade in / fade out -------------------- + _onDragStart() { + this._isDragging = true; + this._reveal(); + } + _onDragEnd() { + this._isDragging = false; + this._hide(); + } + _onMouseLeave(e) { + this._mouseIsOver = false; + this._hide(); + } + _onMouseOver(e) { + this._mouseIsOver = true; + this._reveal(); + } + _reveal() { + this._verticalScrollbar.beginReveal(); + this._horizontalScrollbar.beginReveal(); + this._scheduleHide(); + } + _hide() { + if (!this._mouseIsOver && !this._isDragging) { + this._verticalScrollbar.beginHide(); + this._horizontalScrollbar.beginHide(); + } + } + _scheduleHide() { + if (!this._mouseIsOver && !this._isDragging) { + this._hideTimeout.cancelAndSet(() => this._hide(), HIDE_TIMEOUT); + } + } +} +class ScrollableElement extends AbstractScrollableElement { + constructor(element, options) { + options = options || {}; + options.mouseWheelSmoothScroll = false; + const scrollable = new Scrollable({ + forceIntegerValues: true, + smoothScrollDuration: 0, + scheduleAtNextAnimationFrame: (callback) => scheduleAtNextAnimationFrame(callback) + }); + super(element, options, scrollable); + this._register(scrollable); + } + setScrollPosition(update) { + this._scrollable.setScrollPositionNow(update); + } +} +class SmoothScrollableElement extends AbstractScrollableElement { + constructor(element, options, scrollable) { + super(element, options, scrollable); + } + setScrollPosition(update) { + if (update.reuseAnimation) { + this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation); + } + else { + this._scrollable.setScrollPositionNow(update); + } + } + getScrollPosition() { + return this._scrollable.getCurrentScrollPosition(); + } +} +class DomScrollableElement extends AbstractScrollableElement { + constructor(element, options) { + options = options || {}; + options.mouseWheelSmoothScroll = false; + const scrollable = new Scrollable({ + forceIntegerValues: false, + smoothScrollDuration: 0, + scheduleAtNextAnimationFrame: (callback) => scheduleAtNextAnimationFrame(callback) + }); + super(element, options, scrollable); + this._register(scrollable); + this._element = element; + this.onScroll((e) => { + if (e.scrollTopChanged) { + this._element.scrollTop = e.scrollTop; + } + if (e.scrollLeftChanged) { + this._element.scrollLeft = e.scrollLeft; + } + }); + this.scanDomNode(); + } + setScrollPosition(update) { + this._scrollable.setScrollPositionNow(update); + } + getScrollPosition() { + return this._scrollable.getCurrentScrollPosition(); + } + scanDomNode() { + // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight + this.setScrollDimensions({ + width: this._element.clientWidth, + scrollWidth: this._element.scrollWidth, + height: this._element.clientHeight, + scrollHeight: this._element.scrollHeight + }); + this.setScrollPosition({ + scrollLeft: this._element.scrollLeft, + scrollTop: this._element.scrollTop, + }); + } +} +function resolveOptions$1(opts) { + const result = { + lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false), + className: (typeof opts.className !== 'undefined' ? opts.className : ''), + useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true), + handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true), + flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false), + consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false), + alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false), + scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false), + mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1), + fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5), + scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true), + mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true), + arrowSize: (typeof opts.arrowSize !== 'undefined' ? opts.arrowSize : 11), + listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null), + horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : 1 /* ScrollbarVisibility.Auto */), + horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10), + horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0), + horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false), + vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : 1 /* ScrollbarVisibility.Auto */), + verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10), + verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false), + verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0), + scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false) + }; + result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize); + result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize); + // Defaults are different on Macs + if (isMacintosh) { + result.className += ' mac'; + } + return result; +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class MouseHandler extends ViewEventHandler { + constructor(context, viewController, viewHelper) { + super(); + this._mouseLeaveMonitor = null; + this._context = context; + this.viewController = viewController; + this.viewHelper = viewHelper; + this.mouseTargetFactory = new MouseTargetFactory(this._context, viewHelper); + this._mouseDownOperation = this._register(new MouseDownOperation(this._context, this.viewController, this.viewHelper, this.mouseTargetFactory, (e, testEventTarget) => this._createMouseTarget(e, testEventTarget), (e) => this._getMouseColumn(e))); + this.lastMouseLeaveTime = -1; + this._height = this._context.configuration.options.get(139 /* EditorOption.layoutInfo */).height; + const mouseEvents = new EditorMouseEventFactory(this.viewHelper.viewDomNode); + this._register(mouseEvents.onContextMenu(this.viewHelper.viewDomNode, (e) => this._onContextMenu(e, true))); + this._register(mouseEvents.onMouseMove(this.viewHelper.viewDomNode, (e) => { + this._onMouseMove(e); + // See https://github.com/microsoft/vscode/issues/138789 + // When moving the mouse really quickly, the browser sometimes forgets to + // send us a `mouseleave` or `mouseout` event. We therefore install here + // a global `mousemove` listener to manually recover if the mouse goes outside + // the editor. As soon as the mouse leaves outside of the editor, we + // remove this listener + if (!this._mouseLeaveMonitor) { + this._mouseLeaveMonitor = addDisposableListener(document, 'mousemove', (e) => { + if (!this.viewHelper.viewDomNode.contains(e.target)) { + // went outside the editor! + this._onMouseLeave(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode)); + } + }); + } + })); + this._register(mouseEvents.onMouseUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e))); + this._register(mouseEvents.onMouseLeave(this.viewHelper.viewDomNode, (e) => this._onMouseLeave(e))); + // `pointerdown` events can't be used to determine if there's a double click, or triple click + // because their `e.detail` is always 0. + // We will therefore save the pointer id for the mouse and then reuse it in the `mousedown` event + // for `element.setPointerCapture`. + let capturePointerId = 0; + this._register(mouseEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => { + capturePointerId = pointerId; + })); + // The `pointerup` listener registered by `GlobalEditorPointerMoveMonitor` does not get invoked 100% of the times. + // I speculate that this is because the `pointerup` listener is only registered during the `mousedown` event, and perhaps + // the `pointerup` event is already queued for dispatching, which makes it that the new listener doesn't get fired. + // See https://github.com/microsoft/vscode/issues/146486 for repro steps. + // To compensate for that, we simply register here a `pointerup` listener and just communicate it. + this._register(addDisposableListener(this.viewHelper.viewDomNode, EventType$1.POINTER_UP, (e) => { + this._mouseDownOperation.onPointerUp(); + })); + this._register(mouseEvents.onMouseDown(this.viewHelper.viewDomNode, (e) => this._onMouseDown(e, capturePointerId))); + this._setupMouseWheelZoomListener(); + this._context.addEventHandler(this); + } + _setupMouseWheelZoomListener() { + const classifier = MouseWheelClassifier.INSTANCE; + let prevMouseWheelTime = 0; + let gestureStartZoomLevel = EditorZoom.getZoomLevel(); + let gestureHasZoomModifiers = false; + let gestureAccumulatedDelta = 0; + const onMouseWheel = (browserEvent) => { + this.viewController.emitMouseWheel(browserEvent); + if (!this._context.configuration.options.get(73 /* EditorOption.mouseWheelZoom */)) { + return; + } + const e = new StandardWheelEvent(browserEvent); + classifier.acceptStandardWheelEvent(e); + if (classifier.isPhysicalMouseWheel()) { + if (hasMouseWheelZoomModifiers(browserEvent)) { + const zoomLevel = EditorZoom.getZoomLevel(); + const delta = e.deltaY > 0 ? 1 : -1; + EditorZoom.setZoomLevel(zoomLevel + delta); + e.preventDefault(); + e.stopPropagation(); + } + } + else { + // we consider mousewheel events that occur within 50ms of each other to be part of the same gesture + // we don't want to consider mouse wheel events where ctrl/cmd is pressed during the inertia phase + // we also want to accumulate deltaY values from the same gesture and use that to set the zoom level + if (Date.now() - prevMouseWheelTime > 50) { + // reset if more than 50ms have passed + gestureStartZoomLevel = EditorZoom.getZoomLevel(); + gestureHasZoomModifiers = hasMouseWheelZoomModifiers(browserEvent); + gestureAccumulatedDelta = 0; + } + prevMouseWheelTime = Date.now(); + gestureAccumulatedDelta += e.deltaY; + if (gestureHasZoomModifiers) { + EditorZoom.setZoomLevel(gestureStartZoomLevel + gestureAccumulatedDelta / 5); + e.preventDefault(); + e.stopPropagation(); + } + } + }; + this._register(addDisposableListener(this.viewHelper.viewDomNode, EventType$1.MOUSE_WHEEL, onMouseWheel, { capture: true, passive: false })); + function hasMouseWheelZoomModifiers(browserEvent) { + return (isMacintosh + // on macOS we support cmd + two fingers scroll (`metaKey` set) + // and also the two fingers pinch gesture (`ctrKey` set) + ? ((browserEvent.metaKey || browserEvent.ctrlKey) && !browserEvent.shiftKey && !browserEvent.altKey) + : (browserEvent.ctrlKey && !browserEvent.metaKey && !browserEvent.shiftKey && !browserEvent.altKey)); + } + } + dispose() { + this._context.removeEventHandler(this); + if (this._mouseLeaveMonitor) { + this._mouseLeaveMonitor.dispose(); + this._mouseLeaveMonitor = null; + } + super.dispose(); + } + // --- begin event handlers + onConfigurationChanged(e) { + if (e.hasChanged(139 /* EditorOption.layoutInfo */)) { + // layout change + const height = this._context.configuration.options.get(139 /* EditorOption.layoutInfo */).height; + if (this._height !== height) { + this._height = height; + this._mouseDownOperation.onHeightChanged(); + } + } + return false; + } + onCursorStateChanged(e) { + this._mouseDownOperation.onCursorStateChanged(e); + return false; + } + onFocusChanged(e) { + return false; + } + // --- end event handlers + getTargetAtClientPoint(clientX, clientY) { + const clientPos = new ClientCoordinates(clientX, clientY); + const pos = clientPos.toPageCoordinates(); + const editorPos = createEditorPagePosition(this.viewHelper.viewDomNode); + if (pos.y < editorPos.y || pos.y > editorPos.y + editorPos.height || pos.x < editorPos.x || pos.x > editorPos.x + editorPos.width) { + return null; + } + const relativePos = createCoordinatesRelativeToEditor(this.viewHelper.viewDomNode, editorPos, pos); + return this.mouseTargetFactory.createMouseTarget(this.viewHelper.getLastRenderData(), editorPos, pos, relativePos, null); + } + _createMouseTarget(e, testEventTarget) { + let target = e.target; + if (!this.viewHelper.viewDomNode.contains(target)) { + const shadowRoot = getShadowRoot(this.viewHelper.viewDomNode); + if (shadowRoot) { + target = shadowRoot.elementsFromPoint(e.posx, e.posy).find((el) => this.viewHelper.viewDomNode.contains(el)); + } + } + return this.mouseTargetFactory.createMouseTarget(this.viewHelper.getLastRenderData(), e.editorPos, e.pos, e.relativePos, testEventTarget ? target : null); + } + _getMouseColumn(e) { + return this.mouseTargetFactory.getMouseColumn(e.relativePos); + } + _onContextMenu(e, testEventTarget) { + this.viewController.emitContextMenu({ + event: e, + target: this._createMouseTarget(e, testEventTarget) + }); + } + _onMouseMove(e) { + const targetIsWidget = this.mouseTargetFactory.mouseTargetIsWidget(e); + if (!targetIsWidget) { + e.preventDefault(); + } + if (this._mouseDownOperation.isActive()) { + // In selection/drag operation + return; + } + const actualMouseMoveTime = e.timestamp; + if (actualMouseMoveTime < this.lastMouseLeaveTime) { + // Due to throttling, this event occurred before the mouse left the editor, therefore ignore it. + return; + } + this.viewController.emitMouseMove({ + event: e, + target: this._createMouseTarget(e, true) + }); + } + _onMouseLeave(e) { + if (this._mouseLeaveMonitor) { + this._mouseLeaveMonitor.dispose(); + this._mouseLeaveMonitor = null; + } + this.lastMouseLeaveTime = (new Date()).getTime(); + this.viewController.emitMouseLeave({ + event: e, + target: null + }); + } + _onMouseUp(e) { + this.viewController.emitMouseUp({ + event: e, + target: this._createMouseTarget(e, true) + }); + } + _onMouseDown(e, pointerId) { + const t = this._createMouseTarget(e, true); + const targetIsContent = (t.type === 6 /* MouseTargetType.CONTENT_TEXT */ || t.type === 7 /* MouseTargetType.CONTENT_EMPTY */); + const targetIsGutter = (t.type === 2 /* MouseTargetType.GUTTER_GLYPH_MARGIN */ || t.type === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */ || t.type === 4 /* MouseTargetType.GUTTER_LINE_DECORATIONS */); + const targetIsLineNumbers = (t.type === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */); + const selectOnLineNumbers = this._context.configuration.options.get(104 /* EditorOption.selectOnLineNumbers */); + const targetIsViewZone = (t.type === 8 /* MouseTargetType.CONTENT_VIEW_ZONE */ || t.type === 5 /* MouseTargetType.GUTTER_VIEW_ZONE */); + const targetIsWidget = (t.type === 9 /* MouseTargetType.CONTENT_WIDGET */); + let shouldHandle = e.leftButton || e.middleButton; + if (isMacintosh && e.leftButton && e.ctrlKey) { + shouldHandle = false; + } + const focus = () => { + e.preventDefault(); + this.viewHelper.focusTextArea(); + }; + if (shouldHandle && (targetIsContent || (targetIsLineNumbers && selectOnLineNumbers))) { + focus(); + this._mouseDownOperation.start(t.type, e, pointerId); + } + else if (targetIsGutter) { + // Do not steal focus + e.preventDefault(); + } + else if (targetIsViewZone) { + const viewZoneData = t.detail; + if (shouldHandle && this.viewHelper.shouldSuppressMouseDownOnViewZone(viewZoneData.viewZoneId)) { + focus(); + this._mouseDownOperation.start(t.type, e, pointerId); + e.preventDefault(); + } + } + else if (targetIsWidget && this.viewHelper.shouldSuppressMouseDownOnWidget(t.detail)) { + focus(); + e.preventDefault(); + } + this.viewController.emitMouseDown({ + event: e, + target: t + }); + } +} +class MouseDownOperation extends Disposable { + constructor(_context, _viewController, _viewHelper, _mouseTargetFactory, createMouseTarget, getMouseColumn) { + super(); + this._context = _context; + this._viewController = _viewController; + this._viewHelper = _viewHelper; + this._mouseTargetFactory = _mouseTargetFactory; + this._createMouseTarget = createMouseTarget; + this._getMouseColumn = getMouseColumn; + this._mouseMoveMonitor = this._register(new GlobalEditorPointerMoveMonitor(this._viewHelper.viewDomNode)); + this._topBottomDragScrolling = this._register(new TopBottomDragScrolling(this._context, this._viewHelper, this._mouseTargetFactory, (position, inSelectionMode, revealType) => this._dispatchMouse(position, inSelectionMode, revealType))); + this._mouseState = new MouseDownState(); + this._currentSelection = new Selection$1(1, 1, 1, 1); + this._isActive = false; + this._lastMouseEvent = null; + } + dispose() { + super.dispose(); + } + isActive() { + return this._isActive; + } + _onMouseDownThenMove(e) { + this._lastMouseEvent = e; + this._mouseState.setModifiers(e); + const position = this._findMousePosition(e, false); + if (!position) { + // Ignoring because position is unknown + return; + } + if (this._mouseState.isDragAndDrop) { + this._viewController.emitMouseDrag({ + event: e, + target: position + }); + } + else { + if (position.type === 13 /* MouseTargetType.OUTSIDE_EDITOR */ && (position.outsidePosition === 'above' || position.outsidePosition === 'below')) { + this._topBottomDragScrolling.start(position, e); + } + else { + this._topBottomDragScrolling.stop(); + this._dispatchMouse(position, true, 1 /* NavigationCommandRevealType.Minimal */); + } + } + } + start(targetType, e, pointerId) { + this._lastMouseEvent = e; + this._mouseState.setStartedOnLineNumbers(targetType === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */); + this._mouseState.setStartButtons(e); + this._mouseState.setModifiers(e); + const position = this._findMousePosition(e, true); + if (!position || !position.position) { + // Ignoring because position is unknown + return; + } + this._mouseState.trySetCount(e.detail, position.position); + // Overwrite the detail of the MouseEvent, as it will be sent out in an event and contributions might rely on it. + e.detail = this._mouseState.count; + const options = this._context.configuration.options; + if (!options.get(87 /* EditorOption.readOnly */) + && options.get(33 /* EditorOption.dragAndDrop */) + && !options.get(20 /* EditorOption.columnSelection */) + && !this._mouseState.altKey // we don't support multiple mouse + && e.detail < 2 // only single click on a selection can work + && !this._isActive // the mouse is not down yet + && !this._currentSelection.isEmpty() // we don't drag single cursor + && (position.type === 6 /* MouseTargetType.CONTENT_TEXT */) // single click on text + && position.position && this._currentSelection.containsPosition(position.position) // single click on a selection + ) { + this._mouseState.isDragAndDrop = true; + this._isActive = true; + this._mouseMoveMonitor.startMonitoring(this._viewHelper.viewLinesDomNode, pointerId, e.buttons, (e) => this._onMouseDownThenMove(e), (browserEvent) => { + const position = this._findMousePosition(this._lastMouseEvent, false); + if (browserEvent && browserEvent instanceof KeyboardEvent) { + // cancel + this._viewController.emitMouseDropCanceled(); + } + else { + this._viewController.emitMouseDrop({ + event: this._lastMouseEvent, + target: (position ? this._createMouseTarget(this._lastMouseEvent, true) : null) // Ignoring because position is unknown, e.g., Content View Zone + }); + } + this._stop(); + }); + return; + } + this._mouseState.isDragAndDrop = false; + this._dispatchMouse(position, e.shiftKey, 1 /* NavigationCommandRevealType.Minimal */); + if (!this._isActive) { + this._isActive = true; + this._mouseMoveMonitor.startMonitoring(this._viewHelper.viewLinesDomNode, pointerId, e.buttons, (e) => this._onMouseDownThenMove(e), () => this._stop()); + } + } + _stop() { + this._isActive = false; + this._topBottomDragScrolling.stop(); + } + onHeightChanged() { + this._mouseMoveMonitor.stopMonitoring(); + } + onPointerUp() { + this._mouseMoveMonitor.stopMonitoring(); + } + onCursorStateChanged(e) { + this._currentSelection = e.selections[0]; + } + _getPositionOutsideEditor(e) { + const editorContent = e.editorPos; + const model = this._context.viewModel; + const viewLayout = this._context.viewLayout; + const mouseColumn = this._getMouseColumn(e); + if (e.posy < editorContent.y) { + const outsideDistance = editorContent.y - e.posy; + const verticalOffset = Math.max(viewLayout.getCurrentScrollTop() - outsideDistance, 0); + const viewZoneData = HitTestContext.getZoneAtCoord(this._context, verticalOffset); + if (viewZoneData) { + const newPosition = this._helpPositionJumpOverViewZone(viewZoneData); + if (newPosition) { + return MouseTarget.createOutsideEditor(mouseColumn, newPosition, 'above', outsideDistance); + } + } + const aboveLineNumber = viewLayout.getLineNumberAtVerticalOffset(verticalOffset); + return MouseTarget.createOutsideEditor(mouseColumn, new Position$1(aboveLineNumber, 1), 'above', outsideDistance); + } + if (e.posy > editorContent.y + editorContent.height) { + const outsideDistance = e.posy - editorContent.y - editorContent.height; + const verticalOffset = viewLayout.getCurrentScrollTop() + e.relativePos.y; + const viewZoneData = HitTestContext.getZoneAtCoord(this._context, verticalOffset); + if (viewZoneData) { + const newPosition = this._helpPositionJumpOverViewZone(viewZoneData); + if (newPosition) { + return MouseTarget.createOutsideEditor(mouseColumn, newPosition, 'below', outsideDistance); + } + } + const belowLineNumber = viewLayout.getLineNumberAtVerticalOffset(verticalOffset); + return MouseTarget.createOutsideEditor(mouseColumn, new Position$1(belowLineNumber, model.getLineMaxColumn(belowLineNumber)), 'below', outsideDistance); + } + const possibleLineNumber = viewLayout.getLineNumberAtVerticalOffset(viewLayout.getCurrentScrollTop() + e.relativePos.y); + if (e.posx < editorContent.x) { + const outsideDistance = editorContent.x - e.posx; + return MouseTarget.createOutsideEditor(mouseColumn, new Position$1(possibleLineNumber, 1), 'left', outsideDistance); + } + if (e.posx > editorContent.x + editorContent.width) { + const outsideDistance = e.posx - editorContent.x - editorContent.width; + return MouseTarget.createOutsideEditor(mouseColumn, new Position$1(possibleLineNumber, model.getLineMaxColumn(possibleLineNumber)), 'right', outsideDistance); + } + return null; + } + _findMousePosition(e, testEventTarget) { + const positionOutsideEditor = this._getPositionOutsideEditor(e); + if (positionOutsideEditor) { + return positionOutsideEditor; + } + const t = this._createMouseTarget(e, testEventTarget); + const hintedPosition = t.position; + if (!hintedPosition) { + return null; + } + if (t.type === 8 /* MouseTargetType.CONTENT_VIEW_ZONE */ || t.type === 5 /* MouseTargetType.GUTTER_VIEW_ZONE */) { + const newPosition = this._helpPositionJumpOverViewZone(t.detail); + if (newPosition) { + return MouseTarget.createViewZone(t.type, t.element, t.mouseColumn, newPosition, t.detail); + } + } + return t; + } + _helpPositionJumpOverViewZone(viewZoneData) { + // Force position on view zones to go above or below depending on where selection started from + const selectionStart = new Position$1(this._currentSelection.selectionStartLineNumber, this._currentSelection.selectionStartColumn); + const positionBefore = viewZoneData.positionBefore; + const positionAfter = viewZoneData.positionAfter; + if (positionBefore && positionAfter) { + if (positionBefore.isBefore(selectionStart)) { + return positionBefore; + } + else { + return positionAfter; + } + } + return null; + } + _dispatchMouse(position, inSelectionMode, revealType) { + if (!position.position) { + return; + } + this._viewController.dispatchMouse({ + position: position.position, + mouseColumn: position.mouseColumn, + startedOnLineNumbers: this._mouseState.startedOnLineNumbers, + revealType, + inSelectionMode: inSelectionMode, + mouseDownCount: this._mouseState.count, + altKey: this._mouseState.altKey, + ctrlKey: this._mouseState.ctrlKey, + metaKey: this._mouseState.metaKey, + shiftKey: this._mouseState.shiftKey, + leftButton: this._mouseState.leftButton, + middleButton: this._mouseState.middleButton, + onInjectedText: position.type === 6 /* MouseTargetType.CONTENT_TEXT */ && position.detail.injectedText !== null + }); + } +} +class TopBottomDragScrolling extends Disposable { + constructor(_context, _viewHelper, _mouseTargetFactory, _dispatchMouse) { + super(); + this._context = _context; + this._viewHelper = _viewHelper; + this._mouseTargetFactory = _mouseTargetFactory; + this._dispatchMouse = _dispatchMouse; + this._operation = null; + } + dispose() { + super.dispose(); + this.stop(); + } + start(position, mouseEvent) { + if (this._operation) { + this._operation.setPosition(position, mouseEvent); + } + else { + this._operation = new TopBottomDragScrollingOperation(this._context, this._viewHelper, this._mouseTargetFactory, this._dispatchMouse, position, mouseEvent); + } + } + stop() { + if (this._operation) { + this._operation.dispose(); + this._operation = null; + } + } +} +class TopBottomDragScrollingOperation extends Disposable { + constructor(_context, _viewHelper, _mouseTargetFactory, _dispatchMouse, position, mouseEvent) { + super(); + this._context = _context; + this._viewHelper = _viewHelper; + this._mouseTargetFactory = _mouseTargetFactory; + this._dispatchMouse = _dispatchMouse; + this._position = position; + this._mouseEvent = mouseEvent; + this._lastTime = Date.now(); + this._animationFrameDisposable = scheduleAtNextAnimationFrame(() => this._execute()); + } + dispose() { + this._animationFrameDisposable.dispose(); + } + setPosition(position, mouseEvent) { + this._position = position; + this._mouseEvent = mouseEvent; + } + /** + * update internal state and return elapsed ms since last time + */ + _tick() { + const now = Date.now(); + const elapsed = now - this._lastTime; + this._lastTime = now; + return elapsed; + } + /** + * get the number of lines per second to auto-scroll + */ + _getScrollSpeed() { + const lineHeight = this._context.configuration.options.get(64 /* EditorOption.lineHeight */); + const viewportInLines = this._context.configuration.options.get(139 /* EditorOption.layoutInfo */).height / lineHeight; + const outsideDistanceInLines = this._position.outsideDistance / lineHeight; + if (outsideDistanceInLines <= 1.5) { + return Math.max(30, viewportInLines * (1 + outsideDistanceInLines)); + } + if (outsideDistanceInLines <= 3) { + return Math.max(60, viewportInLines * (2 + outsideDistanceInLines)); + } + return Math.max(200, viewportInLines * (7 + outsideDistanceInLines)); + } + _execute() { + const lineHeight = this._context.configuration.options.get(64 /* EditorOption.lineHeight */); + const scrollSpeedInLines = this._getScrollSpeed(); + const elapsed = this._tick(); + const scrollInPixels = scrollSpeedInLines * (elapsed / 1000) * lineHeight; + const scrollValue = (this._position.outsidePosition === 'above' ? -scrollInPixels : scrollInPixels); + this._context.viewModel.viewLayout.deltaScrollNow(0, scrollValue); + this._viewHelper.renderNow(); + const viewportData = this._context.viewLayout.getLinesViewportData(); + const edgeLineNumber = (this._position.outsidePosition === 'above' ? viewportData.startLineNumber : viewportData.endLineNumber); + // First, try to find a position that matches the horizontal position of the mouse + let mouseTarget; + { + const editorPos = createEditorPagePosition(this._viewHelper.viewDomNode); + const horizontalScrollbarHeight = this._context.configuration.options.get(139 /* EditorOption.layoutInfo */).horizontalScrollbarHeight; + const pos = new PageCoordinates(this._mouseEvent.pos.x, editorPos.y + editorPos.height - horizontalScrollbarHeight - 0.1); + const relativePos = createCoordinatesRelativeToEditor(this._viewHelper.viewDomNode, editorPos, pos); + mouseTarget = this._mouseTargetFactory.createMouseTarget(this._viewHelper.getLastRenderData(), editorPos, pos, relativePos, null); + } + if (!mouseTarget.position || mouseTarget.position.lineNumber !== edgeLineNumber) { + if (this._position.outsidePosition === 'above') { + mouseTarget = MouseTarget.createOutsideEditor(this._position.mouseColumn, new Position$1(edgeLineNumber, 1), 'above', this._position.outsideDistance); + } + else { + mouseTarget = MouseTarget.createOutsideEditor(this._position.mouseColumn, new Position$1(edgeLineNumber, this._context.viewModel.getLineMaxColumn(edgeLineNumber)), 'below', this._position.outsideDistance); + } + } + this._dispatchMouse(mouseTarget, true, 2 /* NavigationCommandRevealType.None */); + this._animationFrameDisposable = scheduleAtNextAnimationFrame(() => this._execute()); + } +} +class MouseDownState { + get altKey() { return this._altKey; } + get ctrlKey() { return this._ctrlKey; } + get metaKey() { return this._metaKey; } + get shiftKey() { return this._shiftKey; } + get leftButton() { return this._leftButton; } + get middleButton() { return this._middleButton; } + get startedOnLineNumbers() { return this._startedOnLineNumbers; } + constructor() { + this._altKey = false; + this._ctrlKey = false; + this._metaKey = false; + this._shiftKey = false; + this._leftButton = false; + this._middleButton = false; + this._startedOnLineNumbers = false; + this._lastMouseDownPosition = null; + this._lastMouseDownPositionEqualCount = 0; + this._lastMouseDownCount = 0; + this._lastSetMouseDownCountTime = 0; + this.isDragAndDrop = false; + } + get count() { + return this._lastMouseDownCount; + } + setModifiers(source) { + this._altKey = source.altKey; + this._ctrlKey = source.ctrlKey; + this._metaKey = source.metaKey; + this._shiftKey = source.shiftKey; + } + setStartButtons(source) { + this._leftButton = source.leftButton; + this._middleButton = source.middleButton; + } + setStartedOnLineNumbers(startedOnLineNumbers) { + this._startedOnLineNumbers = startedOnLineNumbers; + } + trySetCount(setMouseDownCount, newMouseDownPosition) { + // a. Invalidate multiple clicking if too much time has passed (will be hit by IE because the detail field of mouse events contains garbage in IE10) + const currentTime = (new Date()).getTime(); + if (currentTime - this._lastSetMouseDownCountTime > MouseDownState.CLEAR_MOUSE_DOWN_COUNT_TIME) { + setMouseDownCount = 1; + } + this._lastSetMouseDownCountTime = currentTime; + // b. Ensure that we don't jump from single click to triple click in one go (will be hit by IE because the detail field of mouse events contains garbage in IE10) + if (setMouseDownCount > this._lastMouseDownCount + 1) { + setMouseDownCount = this._lastMouseDownCount + 1; + } + // c. Invalidate multiple clicking if the logical position is different + if (this._lastMouseDownPosition && this._lastMouseDownPosition.equals(newMouseDownPosition)) { + this._lastMouseDownPositionEqualCount++; + } + else { + this._lastMouseDownPositionEqualCount = 1; + } + this._lastMouseDownPosition = newMouseDownPosition; + // Finally set the lastMouseDownCount + this._lastMouseDownCount = Math.min(setMouseDownCount, this._lastMouseDownPositionEqualCount); + } +} +MouseDownState.CLEAR_MOUSE_DOWN_COUNT_TIME = 400; // ms + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class DomEmitter { + get event() { + return this.emitter.event; + } + constructor(element, type, useCapture) { + const fn = (e) => this.emitter.fire(e); + this.emitter = new Emitter$1({ + onWillAddFirstListener: () => element.addEventListener(type, fn, useCapture), + onDidRemoveLastListener: () => element.removeEventListener(type, fn, useCapture) + }); + } + dispose() { + this.emitter.dispose(); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +var inputLatency; +(function (inputLatency) { + const totalKeydownTime = { total: 0, min: Number.MAX_VALUE, max: 0 }; + const totalInputTime = Object.assign({}, totalKeydownTime); + const totalRenderTime = Object.assign({}, totalKeydownTime); + const totalInputLatencyTime = Object.assign({}, totalKeydownTime); + let measurementsCount = 0; + const state = { + keydown: 0 /* EventPhase.Before */, + input: 0 /* EventPhase.Before */, + render: 0 /* EventPhase.Before */, + }; + /** + * Record the start of the keydown event. + */ + function onKeyDown() { + /** Direct Check C. See explanation in {@link recordIfFinished} */ + recordIfFinished(); + performance.mark('inputlatency/start'); + performance.mark('keydown/start'); + state.keydown = 1 /* EventPhase.InProgress */; + queueMicrotask(markKeyDownEnd); + } + inputLatency.onKeyDown = onKeyDown; + /** + * Mark the end of the keydown event. + */ + function markKeyDownEnd() { + if (state.keydown === 1 /* EventPhase.InProgress */) { + performance.mark('keydown/end'); + state.keydown = 2 /* EventPhase.Finished */; + } + } + /** + * Record the start of the beforeinput event. + */ + function onBeforeInput() { + performance.mark('input/start'); + state.input = 1 /* EventPhase.InProgress */; + /** Schedule Task A. See explanation in {@link recordIfFinished} */ + scheduleRecordIfFinishedTask(); + } + inputLatency.onBeforeInput = onBeforeInput; + /** + * Record the start of the input event. + */ + function onInput() { + if (state.input === 0 /* EventPhase.Before */) { + // it looks like we didn't receive a `beforeinput` + onBeforeInput(); + } + queueMicrotask(markInputEnd); + } + inputLatency.onInput = onInput; + function markInputEnd() { + if (state.input === 1 /* EventPhase.InProgress */) { + performance.mark('input/end'); + state.input = 2 /* EventPhase.Finished */; + } + } + /** + * Record the start of the keyup event. + */ + function onKeyUp() { + /** Direct Check D. See explanation in {@link recordIfFinished} */ + recordIfFinished(); + } + inputLatency.onKeyUp = onKeyUp; + /** + * Record the start of the selectionchange event. + */ + function onSelectionChange() { + /** Direct Check E. See explanation in {@link recordIfFinished} */ + recordIfFinished(); + } + inputLatency.onSelectionChange = onSelectionChange; + /** + * Record the start of the animation frame performing the rendering. + */ + function onRenderStart() { + // Render may be triggered during input, but we only measure the following animation frame + if (state.keydown === 2 /* EventPhase.Finished */ && state.input === 2 /* EventPhase.Finished */ && state.render === 0 /* EventPhase.Before */) { + // Only measure the first render after keyboard input + performance.mark('render/start'); + state.render = 1 /* EventPhase.InProgress */; + queueMicrotask(markRenderEnd); + /** Schedule Task B. See explanation in {@link recordIfFinished} */ + scheduleRecordIfFinishedTask(); + } + } + inputLatency.onRenderStart = onRenderStart; + /** + * Mark the end of the animation frame performing the rendering. + */ + function markRenderEnd() { + if (state.render === 1 /* EventPhase.InProgress */) { + performance.mark('render/end'); + state.render = 2 /* EventPhase.Finished */; + } + } + function scheduleRecordIfFinishedTask() { + // Here we can safely assume that the `setTimeout` will not be + // artificially delayed by 4ms because we schedule it from + // event handlers + setTimeout(recordIfFinished); + } + /** + * Record the input latency sample if input handling and rendering are finished. + * + * The challenge here is that we want to record the latency in such a way that it includes + * also the layout and painting work the browser does during the animation frame task. + * + * Simply scheduling a new task (via `setTimeout`) from the animation frame task would + * schedule the new task at the end of the task queue (after other code that uses `setTimeout`), + * so we need to use multiple strategies to make sure our task runs before others: + * + * We schedule tasks (A and B): + * - we schedule a task A (via a `setTimeout` call) when the input starts in `markInputStart`. + * If the animation frame task is scheduled quickly by the browser, then task A has a very good + * chance of being the very first task after the animation frame and thus will record the input latency. + * - however, if the animation frame task is scheduled a bit later, then task A might execute + * before the animation frame task. We therefore schedule another task B from `markRenderStart`. + * + * We do direct checks in browser event handlers (C, D, E): + * - if the browser has multiple keydown events queued up, they will be scheduled before the `setTimeout` tasks, + * so we do a direct check in the keydown event handler (C). + * - depending on timing, sometimes the animation frame is scheduled even before the `keyup` event, so we + * do a direct check there too (E). + * - the browser oftentimes emits a `selectionchange` event after an `input`, so we do a direct check there (D). + */ + function recordIfFinished() { + if (state.keydown === 2 /* EventPhase.Finished */ && state.input === 2 /* EventPhase.Finished */ && state.render === 2 /* EventPhase.Finished */) { + performance.mark('inputlatency/end'); + performance.measure('keydown', 'keydown/start', 'keydown/end'); + performance.measure('input', 'input/start', 'input/end'); + performance.measure('render', 'render/start', 'render/end'); + performance.measure('inputlatency', 'inputlatency/start', 'inputlatency/end'); + addMeasure('keydown', totalKeydownTime); + addMeasure('input', totalInputTime); + addMeasure('render', totalRenderTime); + addMeasure('inputlatency', totalInputLatencyTime); + // console.info( + // `input latency=${performance.getEntriesByName('inputlatency')[0].duration.toFixed(1)} [` + + // `keydown=${performance.getEntriesByName('keydown')[0].duration.toFixed(1)}, ` + + // `input=${performance.getEntriesByName('input')[0].duration.toFixed(1)}, ` + + // `render=${performance.getEntriesByName('render')[0].duration.toFixed(1)}` + + // `]` + // ); + measurementsCount++; + reset(); + } + } + function addMeasure(entryName, cumulativeMeasurement) { + const duration = performance.getEntriesByName(entryName)[0].duration; + cumulativeMeasurement.total += duration; + cumulativeMeasurement.min = Math.min(cumulativeMeasurement.min, duration); + cumulativeMeasurement.max = Math.max(cumulativeMeasurement.max, duration); + } + /** + * Clear the current sample. + */ + function reset() { + performance.clearMarks('keydown/start'); + performance.clearMarks('keydown/end'); + performance.clearMarks('input/start'); + performance.clearMarks('input/end'); + performance.clearMarks('render/start'); + performance.clearMarks('render/end'); + performance.clearMarks('inputlatency/start'); + performance.clearMarks('inputlatency/end'); + performance.clearMeasures('keydown'); + performance.clearMeasures('input'); + performance.clearMeasures('render'); + performance.clearMeasures('inputlatency'); + state.keydown = 0 /* EventPhase.Before */; + state.input = 0 /* EventPhase.Before */; + state.render = 0 /* EventPhase.Before */; + } + /** + * Gets all input latency samples and clears the internal buffers to start recording a new set + * of samples. + */ + function getAndClearMeasurements() { + if (measurementsCount === 0) { + return undefined; + } + // Assemble the result + const result = { + keydown: cumulativeToFinalMeasurement(totalKeydownTime), + input: cumulativeToFinalMeasurement(totalInputTime), + render: cumulativeToFinalMeasurement(totalRenderTime), + total: cumulativeToFinalMeasurement(totalInputLatencyTime), + sampleCount: measurementsCount + }; + // Clear the cumulative measurements + clearCumulativeMeasurement(totalKeydownTime); + clearCumulativeMeasurement(totalInputTime); + clearCumulativeMeasurement(totalRenderTime); + clearCumulativeMeasurement(totalInputLatencyTime); + measurementsCount = 0; + return result; + } + inputLatency.getAndClearMeasurements = getAndClearMeasurements; + function cumulativeToFinalMeasurement(cumulative) { + return { + average: cumulative.total / measurementsCount, + max: cumulative.max, + min: cumulative.min, + }; + } + function clearCumulativeMeasurement(cumulative) { + cumulative.total = 0; + cumulative.min = Number.MAX_VALUE; + cumulative.max = 0; + } +})(inputLatency || (inputLatency = {})); + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +class TextAreaState { + constructor(value, + /** the offset where selection starts inside `value` */ + selectionStart, + /** the offset where selection ends inside `value` */ + selectionEnd, + /** the editor range in the view coordinate system that matches the selection inside `value` */ + selection, + /** the visible line count (wrapped, not necessarily matching \n characters) for the text in `value` before `selectionStart` */ + newlineCountBeforeSelection) { + this.value = value; + this.selectionStart = selectionStart; + this.selectionEnd = selectionEnd; + this.selection = selection; + this.newlineCountBeforeSelection = newlineCountBeforeSelection; + } + toString() { + return `[ <${this.value}>, selectionStart: ${this.selectionStart}, selectionEnd: ${this.selectionEnd}]`; + } + static readFromTextArea(textArea, previousState) { + const value = textArea.getValue(); + const selectionStart = textArea.getSelectionStart(); + const selectionEnd = textArea.getSelectionEnd(); + let newlineCountBeforeSelection = undefined; + if (previousState) { + const valueBeforeSelectionStart = value.substring(0, selectionStart); + const previousValueBeforeSelectionStart = previousState.value.substring(0, previousState.selectionStart); + if (valueBeforeSelectionStart === previousValueBeforeSelectionStart) { + newlineCountBeforeSelection = previousState.newlineCountBeforeSelection; + } + } + return new TextAreaState(value, selectionStart, selectionEnd, null, newlineCountBeforeSelection); + } + collapseSelection() { + if (this.selectionStart === this.value.length) { + return this; + } + return new TextAreaState(this.value, this.value.length, this.value.length, null, undefined); + } + writeToTextArea(reason, textArea, select) { + textArea.setValue(reason, this.value); + if (select) { + textArea.setSelectionRange(reason, this.selectionStart, this.selectionEnd); + } + } + deduceEditorPosition(offset) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (offset <= this.selectionStart) { + const str = this.value.substring(offset, this.selectionStart); + return this._finishDeduceEditorPosition((_b = (_a = this.selection) === null || _a === void 0 ? void 0 : _a.getStartPosition()) !== null && _b !== void 0 ? _b : null, str, -1); + } + if (offset >= this.selectionEnd) { + const str = this.value.substring(this.selectionEnd, offset); + return this._finishDeduceEditorPosition((_d = (_c = this.selection) === null || _c === void 0 ? void 0 : _c.getEndPosition()) !== null && _d !== void 0 ? _d : null, str, 1); + } + const str1 = this.value.substring(this.selectionStart, offset); + if (str1.indexOf(String.fromCharCode(8230)) === -1) { + return this._finishDeduceEditorPosition((_f = (_e = this.selection) === null || _e === void 0 ? void 0 : _e.getStartPosition()) !== null && _f !== void 0 ? _f : null, str1, 1); + } + const str2 = this.value.substring(offset, this.selectionEnd); + return this._finishDeduceEditorPosition((_h = (_g = this.selection) === null || _g === void 0 ? void 0 : _g.getEndPosition()) !== null && _h !== void 0 ? _h : null, str2, -1); + } + _finishDeduceEditorPosition(anchor, deltaText, signum) { + let lineFeedCnt = 0; + let lastLineFeedIndex = -1; + while ((lastLineFeedIndex = deltaText.indexOf('\n', lastLineFeedIndex + 1)) !== -1) { + lineFeedCnt++; + } + return [anchor, signum * deltaText.length, lineFeedCnt]; + } + static deduceInput(previousState, currentState, couldBeEmojiInput) { + if (!previousState) { + // This is the EMPTY state + return { + text: '', + replacePrevCharCnt: 0, + replaceNextCharCnt: 0, + positionDelta: 0 + }; + } + const prefixLength = Math.min(commonPrefixLength(previousState.value, currentState.value), previousState.selectionStart, currentState.selectionStart); + const suffixLength = Math.min(commonSuffixLength(previousState.value, currentState.value), previousState.value.length - previousState.selectionEnd, currentState.value.length - currentState.selectionEnd); + previousState.value.substring(prefixLength, previousState.value.length - suffixLength); + const currentValue = currentState.value.substring(prefixLength, currentState.value.length - suffixLength); + const previousSelectionStart = previousState.selectionStart - prefixLength; + const previousSelectionEnd = previousState.selectionEnd - prefixLength; + const currentSelectionStart = currentState.selectionStart - prefixLength; + const currentSelectionEnd = currentState.selectionEnd - prefixLength; + if (currentSelectionStart === currentSelectionEnd) { + // no current selection + const replacePreviousCharacters = (previousState.selectionStart - prefixLength); + return { + text: currentValue, + replacePrevCharCnt: replacePreviousCharacters, + replaceNextCharCnt: 0, + positionDelta: 0 + }; + } + // there is a current selection => composition case + const replacePreviousCharacters = previousSelectionEnd - previousSelectionStart; + return { + text: currentValue, + replacePrevCharCnt: replacePreviousCharacters, + replaceNextCharCnt: 0, + positionDelta: 0 + }; + } + static deduceAndroidCompositionInput(previousState, currentState) { + if (!previousState) { + // This is the EMPTY state + return { + text: '', + replacePrevCharCnt: 0, + replaceNextCharCnt: 0, + positionDelta: 0 + }; + } + if (previousState.value === currentState.value) { + return { + text: '', + replacePrevCharCnt: 0, + replaceNextCharCnt: 0, + positionDelta: currentState.selectionEnd - previousState.selectionEnd + }; + } + const prefixLength = Math.min(commonPrefixLength(previousState.value, currentState.value), previousState.selectionEnd); + const suffixLength = Math.min(commonSuffixLength(previousState.value, currentState.value), previousState.value.length - previousState.selectionEnd); + const previousValue = previousState.value.substring(prefixLength, previousState.value.length - suffixLength); + const currentValue = currentState.value.substring(prefixLength, currentState.value.length - suffixLength); + previousState.selectionStart - prefixLength; + const previousSelectionEnd = previousState.selectionEnd - prefixLength; + currentState.selectionStart - prefixLength; + const currentSelectionEnd = currentState.selectionEnd - prefixLength; + return { + text: currentValue, + replacePrevCharCnt: previousSelectionEnd, + replaceNextCharCnt: previousValue.length - previousSelectionEnd, + positionDelta: currentSelectionEnd - currentValue.length + }; + } +} +TextAreaState.EMPTY = new TextAreaState('', 0, 0, null, undefined); +class PagedScreenReaderStrategy { + static _getPageOfLine(lineNumber, linesPerPage) { + return Math.floor((lineNumber - 1) / linesPerPage); + } + static _getRangeForPage(page, linesPerPage) { + const offset = page * linesPerPage; + const startLineNumber = offset + 1; + const endLineNumber = offset + linesPerPage; + return new Range$c(startLineNumber, 1, endLineNumber + 1, 1); + } + static fromEditorSelection(model, selection, linesPerPage, trimLongText) { + // Chromium handles very poorly text even of a few thousand chars + // Cut text to avoid stalling the entire UI + const LIMIT_CHARS = 500; + const selectionStartPage = PagedScreenReaderStrategy._getPageOfLine(selection.startLineNumber, linesPerPage); + const selectionStartPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionStartPage, linesPerPage); + const selectionEndPage = PagedScreenReaderStrategy._getPageOfLine(selection.endLineNumber, linesPerPage); + const selectionEndPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionEndPage, linesPerPage); + let pretextRange = selectionStartPageRange.intersectRanges(new Range$c(1, 1, selection.startLineNumber, selection.startColumn)); + if (trimLongText && model.getValueLengthInRange(pretextRange, 1 /* EndOfLinePreference.LF */) > LIMIT_CHARS) { + const pretextStart = model.modifyPosition(pretextRange.getEndPosition(), -LIMIT_CHARS); + pretextRange = Range$c.fromPositions(pretextStart, pretextRange.getEndPosition()); + } + const pretext = model.getValueInRange(pretextRange, 1 /* EndOfLinePreference.LF */); + const lastLine = model.getLineCount(); + const lastLineMaxColumn = model.getLineMaxColumn(lastLine); + let posttextRange = selectionEndPageRange.intersectRanges(new Range$c(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn)); + if (trimLongText && model.getValueLengthInRange(posttextRange, 1 /* EndOfLinePreference.LF */) > LIMIT_CHARS) { + const posttextEnd = model.modifyPosition(posttextRange.getStartPosition(), LIMIT_CHARS); + posttextRange = Range$c.fromPositions(posttextRange.getStartPosition(), posttextEnd); + } + const posttext = model.getValueInRange(posttextRange, 1 /* EndOfLinePreference.LF */); + let text; + if (selectionStartPage === selectionEndPage || selectionStartPage + 1 === selectionEndPage) { + // take full selection + text = model.getValueInRange(selection, 1 /* EndOfLinePreference.LF */); + } + else { + const selectionRange1 = selectionStartPageRange.intersectRanges(selection); + const selectionRange2 = selectionEndPageRange.intersectRanges(selection); + text = (model.getValueInRange(selectionRange1, 1 /* EndOfLinePreference.LF */) + + String.fromCharCode(8230) + + model.getValueInRange(selectionRange2, 1 /* EndOfLinePreference.LF */)); + } + if (trimLongText && text.length > 2 * LIMIT_CHARS) { + text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length); + } + return new TextAreaState(pretext + text + posttext, pretext.length, pretext.length + text.length, selection, pretextRange.endLineNumber - pretextRange.startLineNumber); + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +var TextAreaSyntethicEvents; +(function (TextAreaSyntethicEvents) { + TextAreaSyntethicEvents.Tap = '-monaco-textarea-synthetic-tap'; +})(TextAreaSyntethicEvents || (TextAreaSyntethicEvents = {})); +const CopyOptions = { + forceCopyWithSyntaxHighlighting: false +}; +/** + * Every time we write to the clipboard, we record a bit of extra metadata here. + * Every time we read from the cipboard, if the text matches our last written text, + * we can fetch the previous metadata. + */ +class InMemoryClipboardMetadataManager { + constructor() { + this._lastState = null; + } + set(lastCopiedValue, data) { + this._lastState = { lastCopiedValue, data }; + } + get(pastedText) { + if (this._lastState && this._lastState.lastCopiedValue === pastedText) { + // match! + return this._lastState.data; + } + this._lastState = null; + return null; + } +} +InMemoryClipboardMetadataManager.INSTANCE = new InMemoryClipboardMetadataManager(); +class CompositionContext { + constructor() { + this._lastTypeTextLength = 0; + } + handleCompositionUpdate(text) { + text = text || ''; + const typeInput = { + text: text, + replacePrevCharCnt: this._lastTypeTextLength, + replaceNextCharCnt: 0, + positionDelta: 0 + }; + this._lastTypeTextLength = text.length; + return typeInput; + } +} +/** + * Writes screen reader content to the textarea and is able to analyze its input events to generate: + * - onCut + * - onPaste + * - onType + * + * Composition events are generated for presentation purposes (composition input is reflected in onType). + */ +class TextAreaInput extends Disposable { + get textAreaState() { + return this._textAreaState; + } + constructor(_host, _textArea, _OS, _browser) { + super(); + this._host = _host; + this._textArea = _textArea; + this._OS = _OS; + this._browser = _browser; + this._onFocus = this._register(new Emitter$1()); + this.onFocus = this._onFocus.event; + this._onBlur = this._register(new Emitter$1()); + this.onBlur = this._onBlur.event; + this._onKeyDown = this._register(new Emitter$1()); + this.onKeyDown = this._onKeyDown.event; + this._onKeyUp = this._register(new Emitter$1()); + this.onKeyUp = this._onKeyUp.event; + this._onCut = this._register(new Emitter$1()); + this.onCut = this._onCut.event; + this._onPaste = this._register(new Emitter$1()); + this.onPaste = this._onPaste.event; + this._onType = this._register(new Emitter$1()); + this.onType = this._onType.event; + this._onCompositionStart = this._register(new Emitter$1()); + this.onCompositionStart = this._onCompositionStart.event; + this._onCompositionUpdate = this._register(new Emitter$1()); + this.onCompositionUpdate = this._onCompositionUpdate.event; + this._onCompositionEnd = this._register(new Emitter$1()); + this.onCompositionEnd = this._onCompositionEnd.event; + this._onSelectionChangeRequest = this._register(new Emitter$1()); + this.onSelectionChangeRequest = this._onSelectionChangeRequest.event; + this._asyncTriggerCut = this._register(new RunOnceScheduler(() => this._onCut.fire(), 0)); + this._asyncFocusGainWriteScreenReaderContent = this._register(new RunOnceScheduler(() => this.writeScreenReaderContent('asyncFocusGain'), 0)); + this._textAreaState = TextAreaState.EMPTY; + this._selectionChangeListener = null; + this.writeScreenReaderContent('ctor'); + this._hasFocus = false; + this._currentComposition = null; + let lastKeyDown = null; + this._register(this._textArea.onKeyDown((_e) => { + const e = new StandardKeyboardEvent(_e); + if (e.keyCode === 114 /* KeyCode.KEY_IN_COMPOSITION */ + || (this._currentComposition && e.keyCode === 1 /* KeyCode.Backspace */)) { + // Stop propagation for keyDown events if the IME is processing key input + e.stopPropagation(); + } + if (e.equals(9 /* KeyCode.Escape */)) { + // Prevent default always for `Esc`, otherwise it will generate a keypress + // See https://msdn.microsoft.com/en-us/library/ie/ms536939(v=vs.85).aspx + e.preventDefault(); + } + lastKeyDown = e; + this._onKeyDown.fire(e); + })); + this._register(this._textArea.onKeyUp((_e) => { + const e = new StandardKeyboardEvent(_e); + this._onKeyUp.fire(e); + })); + this._register(this._textArea.onCompositionStart((e) => { + const currentComposition = new CompositionContext(); + if (this._currentComposition) { + // simply reset the composition context + this._currentComposition = currentComposition; + return; + } + this._currentComposition = currentComposition; + if (this._OS === 2 /* OperatingSystem.Macintosh */ + && lastKeyDown + && lastKeyDown.equals(114 /* KeyCode.KEY_IN_COMPOSITION */) + && this._textAreaState.selectionStart === this._textAreaState.selectionEnd + && this._textAreaState.selectionStart > 0 + && this._textAreaState.value.substr(this._textAreaState.selectionStart - 1, 1) === e.data + && (lastKeyDown.code === 'ArrowRight' || lastKeyDown.code === 'ArrowLeft')) { + // Pretend the previous character was composed (in order to get it removed by subsequent compositionupdate events) + currentComposition.handleCompositionUpdate('x'); + this._onCompositionStart.fire({ data: e.data }); + return; + } + if (this._browser.isAndroid) { + // when tapping on the editor, Android enters composition mode to edit the current word + // so we cannot clear the textarea on Android and we must pretend the current word was selected + this._onCompositionStart.fire({ data: e.data }); + return; + } + this._onCompositionStart.fire({ data: e.data }); + })); + this._register(this._textArea.onCompositionUpdate((e) => { + const currentComposition = this._currentComposition; + if (!currentComposition) { + // should not be possible to receive a 'compositionupdate' without a 'compositionstart' + return; + } + if (this._browser.isAndroid) { + // On Android, the data sent with the composition update event is unusable. + // For example, if the cursor is in the middle of a word like Mic|osoft + // and Microsoft is chosen from the keyboard's suggestions, the e.data will contain "Microsoft". + // This is not really usable because it doesn't tell us where the edit began and where it ended. + const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState); + const typeInput = TextAreaState.deduceAndroidCompositionInput(this._textAreaState, newState); + this._textAreaState = newState; + this._onType.fire(typeInput); + this._onCompositionUpdate.fire(e); + return; + } + const typeInput = currentComposition.handleCompositionUpdate(e.data); + this._textAreaState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState); + this._onType.fire(typeInput); + this._onCompositionUpdate.fire(e); + })); + this._register(this._textArea.onCompositionEnd((e) => { + const currentComposition = this._currentComposition; + if (!currentComposition) { + // https://github.com/microsoft/monaco-editor/issues/1663 + // On iOS 13.2, Chinese system IME randomly trigger an additional compositionend event with empty data + return; + } + this._currentComposition = null; + if (this._browser.isAndroid) { + // On Android, the data sent with the composition update event is unusable. + // For example, if the cursor is in the middle of a word like Mic|osoft + // and Microsoft is chosen from the keyboard's suggestions, the e.data will contain "Microsoft". + // This is not really usable because it doesn't tell us where the edit began and where it ended. + const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState); + const typeInput = TextAreaState.deduceAndroidCompositionInput(this._textAreaState, newState); + this._textAreaState = newState; + this._onType.fire(typeInput); + this._onCompositionEnd.fire(); + return; + } + const typeInput = currentComposition.handleCompositionUpdate(e.data); + this._textAreaState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState); + this._onType.fire(typeInput); + this._onCompositionEnd.fire(); + })); + this._register(this._textArea.onInput((e) => { + // Pretend here we touched the text area, as the `input` event will most likely + // result in a `selectionchange` event which we want to ignore + this._textArea.setIgnoreSelectionChangeTime('received input event'); + if (this._currentComposition) { + return; + } + const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState); + const typeInput = TextAreaState.deduceInput(this._textAreaState, newState, /*couldBeEmojiInput*/ this._OS === 2 /* OperatingSystem.Macintosh */); + if (typeInput.replacePrevCharCnt === 0 && typeInput.text.length === 1) { + // one character was typed + if (isHighSurrogate(typeInput.text.charCodeAt(0)) + || typeInput.text.charCodeAt(0) === 0x7f /* Delete */) { + // Ignore invalid input but keep it around for next time + return; + } + } + this._textAreaState = newState; + if (typeInput.text !== '' + || typeInput.replacePrevCharCnt !== 0 + || typeInput.replaceNextCharCnt !== 0 + || typeInput.positionDelta !== 0) { + this._onType.fire(typeInput); + } + })); + // --- Clipboard operations + this._register(this._textArea.onCut((e) => { + // Pretend here we touched the text area, as the `cut` event will most likely + // result in a `selectionchange` event which we want to ignore + this._textArea.setIgnoreSelectionChangeTime('received cut event'); + this._ensureClipboardGetsEditorSelection(e); + this._asyncTriggerCut.schedule(); + })); + this._register(this._textArea.onCopy((e) => { + this._ensureClipboardGetsEditorSelection(e); + })); + this._register(this._textArea.onPaste((e) => { + // Pretend here we touched the text area, as the `paste` event will most likely + // result in a `selectionchange` event which we want to ignore + this._textArea.setIgnoreSelectionChangeTime('received paste event'); + e.preventDefault(); + if (!e.clipboardData) { + return; + } + let [text, metadata] = ClipboardEventUtils.getTextData(e.clipboardData); + if (!text) { + return; + } + // try the in-memory store + metadata = metadata || InMemoryClipboardMetadataManager.INSTANCE.get(text); + this._onPaste.fire({ + text: text, + metadata: metadata + }); + })); + this._register(this._textArea.onFocus(() => { + const hadFocus = this._hasFocus; + this._setHasFocus(true); + if (this._browser.isSafari && !hadFocus && this._hasFocus) { + // When "tabbing into" the textarea, immediately after dispatching the 'focus' event, + // Safari will always move the selection at offset 0 in the textarea + this._asyncFocusGainWriteScreenReaderContent.schedule(); + } + })); + this._register(this._textArea.onBlur(() => { + if (this._currentComposition) { + // See https://github.com/microsoft/vscode/issues/112621 + // where compositionend is not triggered when the editor + // is taken off-dom during a composition + // Clear the flag to be able to write to the textarea + this._currentComposition = null; + // Clear the textarea to avoid an unwanted cursor type + this.writeScreenReaderContent('blurWithoutCompositionEnd'); + // Fire artificial composition end + this._onCompositionEnd.fire(); + } + this._setHasFocus(false); + })); + this._register(this._textArea.onSyntheticTap(() => { + if (this._browser.isAndroid && this._currentComposition) { + // on Android, tapping does not cancel the current composition, so the + // textarea is stuck showing the old composition + // Clear the flag to be able to write to the textarea + this._currentComposition = null; + // Clear the textarea to avoid an unwanted cursor type + this.writeScreenReaderContent('tapWithoutCompositionEnd'); + // Fire artificial composition end + this._onCompositionEnd.fire(); + } + })); + } + _installSelectionChangeListener() { + // See https://github.com/microsoft/vscode/issues/27216 and https://github.com/microsoft/vscode/issues/98256 + // When using a Braille display, it is possible for users to reposition the + // system caret. This is reflected in Chrome as a `selectionchange` event. + // + // The `selectionchange` event appears to be emitted under numerous other circumstances, + // so it is quite a challenge to distinguish a `selectionchange` coming in from a user + // using a Braille display from all the other cases. + // + // The problems with the `selectionchange` event are: + // * the event is emitted when the textarea is focused programmatically -- textarea.focus() + // * the event is emitted when the selection is changed in the textarea programmatically -- textarea.setSelectionRange(...) + // * the event is emitted when the value of the textarea is changed programmatically -- textarea.value = '...' + // * the event is emitted when tabbing into the textarea + // * the event is emitted asynchronously (sometimes with a delay as high as a few tens of ms) + // * the event sometimes comes in bursts for a single logical textarea operation + // `selectionchange` events often come multiple times for a single logical change + // so throttle multiple `selectionchange` events that burst in a short period of time. + let previousSelectionChangeEventTime = 0; + return addDisposableListener(document, 'selectionchange', (e) => { + inputLatency.onSelectionChange(); + if (!this._hasFocus) { + return; + } + if (this._currentComposition) { + return; + } + if (!this._browser.isChrome) { + // Support only for Chrome until testing happens on other browsers + return; + } + const now = Date.now(); + const delta1 = now - previousSelectionChangeEventTime; + previousSelectionChangeEventTime = now; + if (delta1 < 5) { + // received another `selectionchange` event within 5ms of the previous `selectionchange` event + // => ignore it + return; + } + const delta2 = now - this._textArea.getIgnoreSelectionChangeTime(); + this._textArea.resetSelectionChangeTime(); + if (delta2 < 100) { + // received a `selectionchange` event within 100ms since we touched the textarea + // => ignore it, since we caused it + return; + } + if (!this._textAreaState.selection) { + // Cannot correlate a position in the textarea with a position in the editor... + return; + } + const newValue = this._textArea.getValue(); + if (this._textAreaState.value !== newValue) { + // Cannot correlate a position in the textarea with a position in the editor... + return; + } + const newSelectionStart = this._textArea.getSelectionStart(); + const newSelectionEnd = this._textArea.getSelectionEnd(); + if (this._textAreaState.selectionStart === newSelectionStart && this._textAreaState.selectionEnd === newSelectionEnd) { + // Nothing to do... + return; + } + const _newSelectionStartPosition = this._textAreaState.deduceEditorPosition(newSelectionStart); + const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0], _newSelectionStartPosition[1], _newSelectionStartPosition[2]); + const _newSelectionEndPosition = this._textAreaState.deduceEditorPosition(newSelectionEnd); + const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0], _newSelectionEndPosition[1], _newSelectionEndPosition[2]); + const newSelection = new Selection$1(newSelectionStartPosition.lineNumber, newSelectionStartPosition.column, newSelectionEndPosition.lineNumber, newSelectionEndPosition.column); + this._onSelectionChangeRequest.fire(newSelection); + }); + } + dispose() { + super.dispose(); + if (this._selectionChangeListener) { + this._selectionChangeListener.dispose(); + this._selectionChangeListener = null; + } + } + focusTextArea() { + // Setting this._hasFocus and writing the screen reader content + // will result in a focus() and setSelectionRange() in the textarea + this._setHasFocus(true); + // If the editor is off DOM, focus cannot be really set, so let's double check that we have managed to set the focus + this.refreshFocusState(); + } + isFocused() { + return this._hasFocus; + } + refreshFocusState() { + this._setHasFocus(this._textArea.hasFocus()); + } + _setHasFocus(newHasFocus) { + if (this._hasFocus === newHasFocus) { + // no change + return; + } + this._hasFocus = newHasFocus; + if (this._selectionChangeListener) { + this._selectionChangeListener.dispose(); + this._selectionChangeListener = null; + } + if (this._hasFocus) { + this._selectionChangeListener = this._installSelectionChangeListener(); + } + if (this._hasFocus) { + this.writeScreenReaderContent('focusgain'); + } + if (this._hasFocus) { + this._onFocus.fire(); + } + else { + this._onBlur.fire(); + } + } + _setAndWriteTextAreaState(reason, textAreaState) { + if (!this._hasFocus) { + textAreaState = textAreaState.collapseSelection(); + } + textAreaState.writeToTextArea(reason, this._textArea, this._hasFocus); + this._textAreaState = textAreaState; + } + writeScreenReaderContent(reason) { + if (this._currentComposition) { + // Do not write to the text area when doing composition + return; + } + this._setAndWriteTextAreaState(reason, this._host.getScreenReaderContent()); + } + _ensureClipboardGetsEditorSelection(e) { + const dataToCopy = this._host.getDataToCopy(); + const storedMetadata = { + version: 1, + isFromEmptySelection: dataToCopy.isFromEmptySelection, + multicursorText: dataToCopy.multicursorText, + mode: dataToCopy.mode + }; + InMemoryClipboardMetadataManager.INSTANCE.set( + // When writing "LINE\r\n" to the clipboard and then pasting, + // Firefox pastes "LINE\n", so let's work around this quirk + (this._browser.isFirefox ? dataToCopy.text.replace(/\r\n/g, '\n') : dataToCopy.text), storedMetadata); + e.preventDefault(); + if (e.clipboardData) { + ClipboardEventUtils.setTextData(e.clipboardData, dataToCopy.text, dataToCopy.html, storedMetadata); + } + } +} +class ClipboardEventUtils { + static getTextData(clipboardData) { + const text = clipboardData.getData(Mimes.text); + let metadata = null; + const rawmetadata = clipboardData.getData('vscode-editor-data'); + if (typeof rawmetadata === 'string') { + try { + metadata = JSON.parse(rawmetadata); + if (metadata.version !== 1) { + metadata = null; + } + } + catch (err) { + // no problem! + } + } + if (text.length === 0 && metadata === null && clipboardData.files.length > 0) { + // no textual data pasted, generate text from file names + const files = Array.prototype.slice.call(clipboardData.files, 0); + return [files.map(file => file.name).join('\n'), null]; + } + return [text, metadata]; + } + static setTextData(clipboardData, text, html, metadata) { + clipboardData.setData(Mimes.text, text); + if (typeof html === 'string') { + clipboardData.setData('text/html', html); + } + clipboardData.setData('vscode-editor-data', JSON.stringify(metadata)); + } +} +class TextAreaWrapper extends Disposable { + constructor(_actual) { + super(); + this._actual = _actual; + this.onKeyDown = this._register(new DomEmitter(this._actual, 'keydown')).event; + this.onKeyUp = this._register(new DomEmitter(this._actual, 'keyup')).event; + this.onCompositionStart = this._register(new DomEmitter(this._actual, 'compositionstart')).event; + this.onCompositionUpdate = this._register(new DomEmitter(this._actual, 'compositionupdate')).event; + this.onCompositionEnd = this._register(new DomEmitter(this._actual, 'compositionend')).event; + this.onBeforeInput = this._register(new DomEmitter(this._actual, 'beforeinput')).event; + this.onInput = this._register(new DomEmitter(this._actual, 'input')).event; + this.onCut = this._register(new DomEmitter(this._actual, 'cut')).event; + this.onCopy = this._register(new DomEmitter(this._actual, 'copy')).event; + this.onPaste = this._register(new DomEmitter(this._actual, 'paste')).event; + this.onFocus = this._register(new DomEmitter(this._actual, 'focus')).event; + this.onBlur = this._register(new DomEmitter(this._actual, 'blur')).event; + this._onSyntheticTap = this._register(new Emitter$1()); + this.onSyntheticTap = this._onSyntheticTap.event; + this._ignoreSelectionChangeTime = 0; + this._register(this.onKeyDown(() => inputLatency.onKeyDown())); + this._register(this.onBeforeInput(() => inputLatency.onBeforeInput())); + this._register(this.onInput(() => inputLatency.onInput())); + this._register(this.onKeyUp(() => inputLatency.onKeyUp())); + this._register(addDisposableListener(this._actual, TextAreaSyntethicEvents.Tap, () => this._onSyntheticTap.fire())); + } + hasFocus() { + const shadowRoot = getShadowRoot(this._actual); + if (shadowRoot) { + return shadowRoot.activeElement === this._actual; + } + else if (isInDOM(this._actual)) { + return document.activeElement === this._actual; + } + else { + return false; + } + } + setIgnoreSelectionChangeTime(reason) { + this._ignoreSelectionChangeTime = Date.now(); + } + getIgnoreSelectionChangeTime() { + return this._ignoreSelectionChangeTime; + } + resetSelectionChangeTime() { + this._ignoreSelectionChangeTime = 0; + } + getValue() { + // console.log('current value: ' + this._textArea.value); + return this._actual.value; + } + setValue(reason, value) { + const textArea = this._actual; + if (textArea.value === value) { + // No change + return; + } + // console.log('reason: ' + reason + ', current value: ' + textArea.value + ' => new value: ' + value); + this.setIgnoreSelectionChangeTime('setValue'); + textArea.value = value; + } + getSelectionStart() { + return this._actual.selectionDirection === 'backward' ? this._actual.selectionEnd : this._actual.selectionStart; + } + getSelectionEnd() { + return this._actual.selectionDirection === 'backward' ? this._actual.selectionStart : this._actual.selectionEnd; + } + setSelectionRange(reason, selectionStart, selectionEnd) { + const textArea = this._actual; + let activeElement = null; + const shadowRoot = getShadowRoot(textArea); + if (shadowRoot) { + activeElement = shadowRoot.activeElement; + } + else { + activeElement = document.activeElement; + } + const currentIsFocused = (activeElement === textArea); + const currentSelectionStart = textArea.selectionStart; + const currentSelectionEnd = textArea.selectionEnd; + if (currentIsFocused && currentSelectionStart === selectionStart && currentSelectionEnd === selectionEnd) { + // No change + // Firefox iframe bug https://github.com/microsoft/monaco-editor/issues/643#issuecomment-367871377 + if (isFirefox && window.parent !== window) { + textArea.focus(); + } + return; + } + // console.log('reason: ' + reason + ', setSelectionRange: ' + selectionStart + ' -> ' + selectionEnd); + if (currentIsFocused) { + // No need to focus, only need to change the selection range + this.setIgnoreSelectionChangeTime('setSelectionRange'); + textArea.setSelectionRange(selectionStart, selectionEnd); + if (isFirefox && window.parent !== window) { + textArea.focus(); + } + return; + } + // If the focus is outside the textarea, browsers will try really hard to reveal the textarea. + // Here, we try to undo the browser's desperate reveal. + try { + const scrollState = saveParentsScrollTop(textArea); + this.setIgnoreSelectionChangeTime('setSelectionRange'); + textArea.focus(); + textArea.setSelectionRange(selectionStart, selectionEnd); + restoreParentsScrollTop(textArea, scrollState); + } + catch (e) { + // Sometimes IE throws when setting selection (e.g. textarea is off-DOM) + } + } +} + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/** + * Currently only tested on iOS 13/ iPadOS. + */ +class PointerEventHandler extends MouseHandler { + constructor(context, viewController, viewHelper) { + super(context, viewController, viewHelper); + this._register(Gesture.addTarget(this.viewHelper.linesContentDomNode)); + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e))); + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e))); + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e) => this._onContextMenu(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode), false))); + this._lastPointerType = 'mouse'; + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, 'pointerdown', (e) => { + const pointerType = e.pointerType; + if (pointerType === 'mouse') { + this._lastPointerType = 'mouse'; + return; + } + else if (pointerType === 'touch') { + this._lastPointerType = 'touch'; + } + else { + this._lastPointerType = 'pen'; + } + })); + // PonterEvents + const pointerEvents = new EditorPointerEventFactory(this.viewHelper.viewDomNode); + this._register(pointerEvents.onPointerMove(this.viewHelper.viewDomNode, (e) => this._onMouseMove(e))); + this._register(pointerEvents.onPointerUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e))); + this._register(pointerEvents.onPointerLeave(this.viewHelper.viewDomNode, (e) => this._onMouseLeave(e))); + this._register(pointerEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => this._onMouseDown(e, pointerId))); + } + onTap(event) { + if (!event.initialTarget || !this.viewHelper.linesContentDomNode.contains(event.initialTarget)) { + return; + } + event.preventDefault(); + this.viewHelper.focusTextArea(); + const target = this._createMouseTarget(new EditorMouseEvent(event, false, this.viewHelper.viewDomNode), false); + if (target.position) { + // this.viewController.moveTo(target.position); + this.viewController.dispatchMouse({ + position: target.position, + mouseColumn: target.position.column, + startedOnLineNumbers: false, + revealType: 1 /* NavigationCommandRevealType.Minimal */, + mouseDownCount: event.tapCount, + inSelectionMode: false, + altKey: false, + ctrlKey: false, + metaKey: false, + shiftKey: false, + leftButton: false, + middleButton: false, + onInjectedText: target.type === 6 /* MouseTargetType.CONTENT_TEXT */ && target.detail.injectedText !== null + }); + } + } + onChange(e) { + if (this._lastPointerType === 'touch') { + this._context.viewModel.viewLayout.deltaScrollNow(-e.translationX, -e.translationY); + } + } + _onMouseDown(e, pointerId) { + if (e.browserEvent.pointerType === 'touch') { + return; + } + super._onMouseDown(e, pointerId); + } +} +class TouchHandler extends MouseHandler { + constructor(context, viewController, viewHelper) { + super(context, viewController, viewHelper); + this._register(Gesture.addTarget(this.viewHelper.linesContentDomNode)); + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e))); + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e))); + this._register(addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e) => this._onContextMenu(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode), false))); + } + onTap(event) { + event.preventDefault(); + this.viewHelper.focusTextArea(); + const target = this._createMouseTarget(new EditorMouseEvent(event, false, this.viewHelper.viewDomNode), false); + if (target.position) { + // Send the tap event also to the