├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_zh-CN.md ├── docs ├── api.md ├── api_zh-CN.md ├── examples.md ├── examples_zh-CN.md └── imgs │ └── demo.gif ├── package-lock.json ├── package.json ├── resources ├── code │ └── cpp │ │ ├── leetcode-convert.h │ │ ├── leetcode-definition.h │ │ ├── leetcode-entry.h │ │ ├── leetcode-io.h │ │ ├── leetcode-json.h │ │ ├── leetcode-main.cpp │ │ └── leetcode-types.h └── imgs │ └── icon.png ├── src ├── commands │ └── debug.ts ├── debuggers │ ├── cppDebugger.ts │ ├── debugger.ts │ └── debuggerManager.ts ├── extension.ts ├── leetCodeDebugger.ts └── util │ ├── codeIndentHelper.ts │ ├── config.ts │ ├── ex.ts │ ├── problemFetcher.ts │ ├── stubCodeHelper.ts │ └── stubFileHelper.ts └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/class-name-casing": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.h linguist-language=typescript 2 | *.c linguist-language=typescript 3 | *.hpp linguist-language=typescript 4 | *.cpp linguist-language=typescript 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "${defaultBuildTask}" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | "preLaunchTask": "${defaultBuildTask}" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | .gitignore 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/.eslintrc.json 9 | **/*.map 10 | **/*.ts 11 | .github 12 | docs 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | > Minor version only. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 XavierCai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeetCode Debugger for C++ 2 | 3 | > Debug support for [LeetCode](https://leetcode.com/) with C++ in [VSCode](https://code.visualstudio.com/) 4 | 5 | - **English Document** | [中文文档](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/README_zh-CN.md) 6 | 7 | ## Quick Start 8 | 9 | ![demo](https://raw.githubusercontent.com/xavier-cai/vscode-leetcode-cpp-debug/master/docs/imgs/demo.gif) 10 | 11 | > **Attention**: Before start debugging, you must to check availability of your C++ debugger tools. Get more information from [VSCode documents](https://code.visualstudio.com/docs/cpp/config-mingw#cpp-atricles). 12 | 13 | ## Features 14 | 15 | ### Start Debugging 16 | 17 | - Generate debugging codes and start a debug session for your solution. 18 | 19 | - You can run the `LeetCode Debugger: Start Debugging` command from the command palette (`Ctrl/Cmd + Shift + P`). 20 | 21 | ### Online/Offline Code Template 22 | 23 | - Code template is used to generate the debugging code. 24 | 25 | - Online: Fetching problem from `LeetCode`. Requires your solution file to start with problem ID, for example, `1.two-sum.cpp` (Or you can modify the regular expression for capturing problem ID in extension settings). 26 | 27 | - Offline: Using your solution code as code template. 28 | 29 | ### Input/Output 30 | 31 | - You could use the code below to change the input/output: 32 | 33 | ```cpp 34 | #define INPUT "test_case.txt" // single-input 35 | #define OUTPUT cout, "output.txt" // multi-output 36 | ``` 37 | 38 | - For `INPUT`, both `std::istream` and `std::string` (input from file) are acceptable, but you can only have **ONE** input. 39 | 40 | - For `OUTPUT`, both `std::ostream` and `std::string` (output to file) are acceptable, you can have multiple outputs. 41 | 42 | ### Interactive Problem 43 | 44 | - Interactive problem is **NOT** supported yet. 45 | 46 | - But you can realize the interactive function by yourself! Know more from [API](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/api.md) and [examples](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/examples.md). Here is an example for [problem 278](https://leetcode.com/problems/first-bad-version/). 47 | 48 | ```cpp 49 | #ifdef LEETCODE_DEFINITION // protection 50 | int firstVersion; // the first bad version 51 | bool isBadVersion(int version) { // realization 52 | return version >= firstVersion; 53 | } 54 | #define LAZY_INTERACTION firstVersion // input firstVersion 55 | #endif 56 | ``` 57 | 58 | - `LAZY_INTERACTION` means interactive inputs after function's arguments, `INTERACTION` means interactive inputs before function's arguments, in addition, function with type `void ()` is also acceptable. The example below will help you to understand these stuff. 59 | 60 | ```cpp 61 | #ifdef LEETCODE_DEFINITION // protection 62 | 63 | int value1, value2; // interactive values 64 | void before() { 65 | value1 *= 2; 66 | } 67 | void after() { 68 | value2 *= value1; 69 | } 70 | 71 | #define INTERACTION value1, before // input value1, then call the function 'before()' 72 | #define LAZY_INTERACTION value2, after // input value2, then call the function 'after()' 73 | 74 | #endif 75 | 76 | class Solution { 77 | public: 78 | int exampleFunction(int v) { 79 | return v * value1 * value2; 80 | } 81 | }; 82 | 83 | /* 84 | * input: 85 | * 1 // -> value1 -> value1*=2 -> 2 86 | * 2 // -> v 87 | * 3 // -> value2 -> value2*=value1 -> 6 88 | * output: 89 | * 24 // -> v*value1*value2 -> 2*2*6=24 90 | * / 91 | ``` 92 | 93 | ## Extension Settings 94 | 95 | Setting Name|Description|Default Value 96 | :---|:---|:--- 97 | `Source`|Source of code template for generating debugging code.|`"[online]leetcode.com"` 98 | `Delete Temporary Contents`|Delete temporary codes and files after debugging.|`true` 99 | `Id Match Pattern`|Regular expression for capturing problem ID when fetching problem online.|`"(\\d+).*"` 100 | `Output File Encoding`|Encoding of temporary code files|`"utf8"` 101 | 102 | - The default value of `Id Match Pattern` can match any file name begin with a number. 103 | 104 | ## Release Notes 105 | 106 | Refer to [CHANGELOG](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/CHANGELOG.md). 107 | 108 | ## Tips 109 | 110 | You can solve LeetCode problems in VSCode with another amazing extension [LeetCode](https://marketplace.visualstudio.com/items?itemName=shengchen.vscode-leetcode). 111 | -------------------------------------------------------------------------------- /README_zh-CN.md: -------------------------------------------------------------------------------- 1 | # LeetCode Debugger for C++ 2 | 3 | > 为你的[LeetCode](https://leetcode.com/) C++ 代码在[VSCode](https://code.visualstudio.com/)中提供调试支持. 4 | 5 | - [English Document](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/README.md) | **中文文档** 6 | 7 | ## 快速开始 8 | 9 | ![demo](https://raw.githubusercontent.com/xavier-cai/vscode-leetcode-cpp-debug/master/docs/imgs/demo.gif) 10 | 11 | > **注意**: 在使用此插件启动调试前, 你必须确定你有可用的C++调试工具. 从[官方文档](https://code.visualstudio.com/docs/cpp/config-mingw#cpp-atricles)可以获取更多相关信息. 12 | 13 | ## 特性 14 | 15 | ### 启动调试 16 | 17 | - 为你的题解代码生成调试代码并启动调试. 18 | 19 | - 通过在命令输入板(`Ctrl/Cmd + Shift + P`)输入命令`LeetCode Debugger: Start Debugging`来启动. 20 | 21 | ### 在线/离线 代码模板 22 | 23 | - 代码模板是用来生成调试代码的. 24 | 25 | - 在线: 从`LeetCode`官网获取题目的信息. 要求你的题解代码文件名以该题的ID开始, 例如`1.两数之和.cpp` (或者你可以在插件设置页面中自行设置用于ID匹配的正则表达式). 26 | 27 | - 离线: 直接使用你的题解代码作为代码模板. 28 | 29 | ### 输入/输出 30 | 31 | - 你可以使用以下代码来设置输入/输出 32 | 33 | ```cpp 34 | #define INPUT "test_case.txt" // single-input 35 | #define OUTPUT cout, "output.txt" // multi-output 36 | ``` 37 | 38 | - 对于`INPUT`, `std::istream`和`std::string` (从文件输入) 都是可接受的参数类型, 但是你只能有**一个**输入. 39 | 40 | - 对于`OUTPUT`, `std::ostream`和`std::string` (输出到文件) 都是可接受的参数类型, 你可以同时有多个输出. 41 | 42 | ### 交互题 43 | 44 | - 交互题目前**不**支持. 45 | 46 | - 但是你可以自己实现交互函数! 可以通过[API](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/api_zh-CN.md)和[示例](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/examples_zh-CN.md)了解更多. 这里有一个[题278](https://leetcode-cn.com/problems/first-bad-version/)的例子. 47 | 48 | ```cpp 49 | #ifdef LEETCODE_DEFINITION // protection 50 | int firstVersion; // the first bad version 51 | bool isBadVersion(int version) { // realization 52 | return version >= firstVersion; 53 | } 54 | #define LAZY_INTERACTION firstVersion // input firstVersion 55 | #endif 56 | ``` 57 | 58 | - `LAZY_INTERACTION`指的是在函数参数输入之后的交互输入, 而`INTERACTION`则是在函数参数输入之前的交互输入, 此外, `void ()`类型的函数同样可以作为交互输入. 下面的例子将帮助你理解这些内容. 59 | 60 | ```cpp 61 | #ifdef LEETCODE_DEFINITION // protection 62 | 63 | int value1, value2; // interactive values 64 | void before() { 65 | value1 *= 2; 66 | } 67 | void after() { 68 | value2 *= value1; 69 | } 70 | 71 | #define INTERACTION value1, before // input value1, then call the function 'before()' 72 | #define LAZY_INTERACTION value2, after // input value2, then call the function 'after()' 73 | 74 | #endif 75 | 76 | class Solution { 77 | public: 78 | int exampleFunction(int v) { 79 | return v * value1 * value2; 80 | } 81 | } 82 | 83 | /* 84 | * input: 85 | * 1 // -> value1 -> value1*=2 -> 2 86 | * 2 // -> v 87 | * 3 // -> value2 -> value2*=value1 -> 6 88 | * output: 89 | * 24 // -> v*value1*value2 -> 2*2*6=24 90 | * / 91 | ``` 92 | 93 | ## 插件设置 94 | 95 | 设置项|描述|默认值 96 | :---|:---|:--- 97 | `Source`|用于生成调试代码的代码模板来源.|`"[online]leetcode.com"` 98 | `Delete Temporary Contents`|在调试结束后,是否删除生成的临时文件与代码.|`true` 99 | `Id Match Pattern`|在线获取代码模板时, 用于捕获文件名中问题ID的正则表达式.|`"(\\d+).*"` 100 | `Output File Encoding`|生成的临时代码文件编码|`"utf8"` 101 | 102 | - `Id Match Pattern`的默认值能匹配任何以数字开头的文件名. 103 | - 中文下遇到编码问题如中文头文件无法识别时, 可以尝试将`Ouput File Encoding`设置为`gbk` 104 | 105 | ## 版本日志 106 | 107 | 详细内容请查看[CHANGELOG](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/CHANGELOG.md). 108 | 109 | ## 小贴士 110 | 111 | 你可以使用另外一款很棒的插件[LeetCode](https://marketplace.visualstudio.com/items?itemName=shengchen.vscode-leetcode)来在VS Code中浏览和解决LeetCode问题. 112 | -------------------------------------------------------------------------------- /docs/api.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | - **English Document** | [中文文档](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/api_zh-CN.md) 4 | -------------------------------------------------------------------------------- /docs/api_zh-CN.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | - [English Document](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/api.md) | **中文文档** 4 | -------------------------------------------------------------------------------- /docs/examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | - **English Document** | [中文文档](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/examples_zh-CN.md) 4 | -------------------------------------------------------------------------------- /docs/examples_zh-CN.md: -------------------------------------------------------------------------------- 1 | # 示例文档 2 | 3 | - [English Document](https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/docs/examples.md) | **中文文档** 4 | -------------------------------------------------------------------------------- /docs/imgs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xavier-cai/vscode-leetcode-cpp-debug/8d0a4f13b3c8df814d74895452e02ec21e449416/docs/imgs/demo.gif -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-leetcode-cpp-debug", 3 | "version": "0.0.7", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.10.4", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.10.4", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.10.4", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | } 32 | }, 33 | "@types/caseless": { 34 | "version": "0.12.2", 35 | "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", 36 | "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", 37 | "dev": true 38 | }, 39 | "@types/color-name": { 40 | "version": "1.1.1", 41 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 42 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", 43 | "dev": true 44 | }, 45 | "@types/eslint-visitor-keys": { 46 | "version": "1.0.0", 47 | "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 48 | "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", 49 | "dev": true 50 | }, 51 | "@types/fs-extra": { 52 | "version": "5.0.0", 53 | "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.0.tgz", 54 | "integrity": "sha512-qtxDULQKUenuaDLW003CgC+0T0eiAfH3BrH+vSt87GLzbz5EZ6Ox6mv9rMttvhDOatbb9nYh0E1m7ydoYwUrAg==", 55 | "dev": true, 56 | "requires": { 57 | "@types/node": "*" 58 | } 59 | }, 60 | "@types/glob": { 61 | "version": "7.1.3", 62 | "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", 63 | "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", 64 | "dev": true, 65 | "requires": { 66 | "@types/minimatch": "*", 67 | "@types/node": "*" 68 | } 69 | }, 70 | "@types/json-schema": { 71 | "version": "7.0.5", 72 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", 73 | "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", 74 | "dev": true 75 | }, 76 | "@types/minimatch": { 77 | "version": "3.0.3", 78 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", 79 | "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", 80 | "dev": true 81 | }, 82 | "@types/mocha": { 83 | "version": "7.0.2", 84 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", 85 | "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", 86 | "dev": true 87 | }, 88 | "@types/node": { 89 | "version": "12.12.50", 90 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.50.tgz", 91 | "integrity": "sha512-5ImO01Fb8YsEOYpV+aeyGYztcYcjGsBvN4D7G5r1ef2cuQOpymjWNQi5V0rKHE6PC2ru3HkoUr/Br2/8GUA84w==", 92 | "dev": true 93 | }, 94 | "@types/request": { 95 | "version": "2.48.5", 96 | "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz", 97 | "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==", 98 | "dev": true, 99 | "requires": { 100 | "@types/caseless": "*", 101 | "@types/node": "*", 102 | "@types/tough-cookie": "*", 103 | "form-data": "^2.5.0" 104 | }, 105 | "dependencies": { 106 | "form-data": { 107 | "version": "2.5.1", 108 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", 109 | "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", 110 | "dev": true, 111 | "requires": { 112 | "asynckit": "^0.4.0", 113 | "combined-stream": "^1.0.6", 114 | "mime-types": "^2.1.12" 115 | } 116 | } 117 | } 118 | }, 119 | "@types/tough-cookie": { 120 | "version": "4.0.0", 121 | "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", 122 | "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==", 123 | "dev": true 124 | }, 125 | "@types/vscode": { 126 | "version": "1.47.0", 127 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.47.0.tgz", 128 | "integrity": "sha512-nJA37ykkz9FYA0ZOQUSc3OZnhuzEW2vUhUEo4MiduUo82jGwwcLfyvmgd/Q7b0WrZAAceojGhZybg319L24bTA==", 129 | "dev": true 130 | }, 131 | "@typescript-eslint/eslint-plugin": { 132 | "version": "2.34.0", 133 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", 134 | "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", 135 | "dev": true, 136 | "requires": { 137 | "@typescript-eslint/experimental-utils": "2.34.0", 138 | "functional-red-black-tree": "^1.0.1", 139 | "regexpp": "^3.0.0", 140 | "tsutils": "^3.17.1" 141 | } 142 | }, 143 | "@typescript-eslint/experimental-utils": { 144 | "version": "2.34.0", 145 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", 146 | "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", 147 | "dev": true, 148 | "requires": { 149 | "@types/json-schema": "^7.0.3", 150 | "@typescript-eslint/typescript-estree": "2.34.0", 151 | "eslint-scope": "^5.0.0", 152 | "eslint-utils": "^2.0.0" 153 | } 154 | }, 155 | "@typescript-eslint/parser": { 156 | "version": "2.34.0", 157 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", 158 | "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", 159 | "dev": true, 160 | "requires": { 161 | "@types/eslint-visitor-keys": "^1.0.0", 162 | "@typescript-eslint/experimental-utils": "2.34.0", 163 | "@typescript-eslint/typescript-estree": "2.34.0", 164 | "eslint-visitor-keys": "^1.1.0" 165 | } 166 | }, 167 | "@typescript-eslint/typescript-estree": { 168 | "version": "2.34.0", 169 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", 170 | "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", 171 | "dev": true, 172 | "requires": { 173 | "debug": "^4.1.1", 174 | "eslint-visitor-keys": "^1.1.0", 175 | "glob": "^7.1.6", 176 | "is-glob": "^4.0.1", 177 | "lodash": "^4.17.15", 178 | "semver": "^7.3.2", 179 | "tsutils": "^3.17.1" 180 | } 181 | }, 182 | "acorn": { 183 | "version": "7.3.1", 184 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", 185 | "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", 186 | "dev": true 187 | }, 188 | "acorn-jsx": { 189 | "version": "5.2.0", 190 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", 191 | "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", 192 | "dev": true 193 | }, 194 | "agent-base": { 195 | "version": "4.3.0", 196 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", 197 | "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", 198 | "dev": true, 199 | "requires": { 200 | "es6-promisify": "^5.0.0" 201 | } 202 | }, 203 | "ajv": { 204 | "version": "6.12.3", 205 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", 206 | "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", 207 | "requires": { 208 | "fast-deep-equal": "^3.1.1", 209 | "fast-json-stable-stringify": "^2.0.0", 210 | "json-schema-traverse": "^0.4.1", 211 | "uri-js": "^4.2.2" 212 | } 213 | }, 214 | "ansi-colors": { 215 | "version": "3.2.3", 216 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", 217 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", 218 | "dev": true 219 | }, 220 | "ansi-escapes": { 221 | "version": "4.3.1", 222 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", 223 | "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", 224 | "dev": true, 225 | "requires": { 226 | "type-fest": "^0.11.0" 227 | }, 228 | "dependencies": { 229 | "type-fest": { 230 | "version": "0.11.0", 231 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", 232 | "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", 233 | "dev": true 234 | } 235 | } 236 | }, 237 | "ansi-regex": { 238 | "version": "5.0.0", 239 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 240 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 241 | "dev": true 242 | }, 243 | "ansi-styles": { 244 | "version": "3.2.1", 245 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 246 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 247 | "dev": true, 248 | "requires": { 249 | "color-convert": "^1.9.0" 250 | } 251 | }, 252 | "anymatch": { 253 | "version": "3.1.1", 254 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 255 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 256 | "dev": true, 257 | "requires": { 258 | "normalize-path": "^3.0.0", 259 | "picomatch": "^2.0.4" 260 | } 261 | }, 262 | "argparse": { 263 | "version": "1.0.10", 264 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 265 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 266 | "dev": true, 267 | "requires": { 268 | "sprintf-js": "~1.0.2" 269 | } 270 | }, 271 | "asn1": { 272 | "version": "0.2.4", 273 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 274 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 275 | "requires": { 276 | "safer-buffer": "~2.1.0" 277 | } 278 | }, 279 | "assert-plus": { 280 | "version": "1.0.0", 281 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 282 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 283 | }, 284 | "astral-regex": { 285 | "version": "1.0.0", 286 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 287 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 288 | "dev": true 289 | }, 290 | "asynckit": { 291 | "version": "0.4.0", 292 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 293 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 294 | }, 295 | "at-least-node": { 296 | "version": "1.0.0", 297 | "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", 298 | "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" 299 | }, 300 | "aws-sign2": { 301 | "version": "0.7.0", 302 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 303 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 304 | }, 305 | "aws4": { 306 | "version": "1.10.0", 307 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", 308 | "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" 309 | }, 310 | "balanced-match": { 311 | "version": "1.0.0", 312 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 313 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 314 | }, 315 | "bcrypt-pbkdf": { 316 | "version": "1.0.2", 317 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 318 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 319 | "requires": { 320 | "tweetnacl": "^0.14.3" 321 | } 322 | }, 323 | "binary-extensions": { 324 | "version": "2.1.0", 325 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", 326 | "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", 327 | "dev": true 328 | }, 329 | "brace-expansion": { 330 | "version": "1.1.11", 331 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 332 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 333 | "requires": { 334 | "balanced-match": "^1.0.0", 335 | "concat-map": "0.0.1" 336 | } 337 | }, 338 | "braces": { 339 | "version": "3.0.2", 340 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 341 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 342 | "dev": true, 343 | "requires": { 344 | "fill-range": "^7.0.1" 345 | } 346 | }, 347 | "browser-stdout": { 348 | "version": "1.3.1", 349 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 350 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 351 | "dev": true 352 | }, 353 | "callsites": { 354 | "version": "3.1.0", 355 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 356 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 357 | "dev": true 358 | }, 359 | "camelcase": { 360 | "version": "5.3.1", 361 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 362 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 363 | "dev": true 364 | }, 365 | "caseless": { 366 | "version": "0.12.0", 367 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 368 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 369 | }, 370 | "chalk": { 371 | "version": "2.4.2", 372 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 373 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 374 | "dev": true, 375 | "requires": { 376 | "ansi-styles": "^3.2.1", 377 | "escape-string-regexp": "^1.0.5", 378 | "supports-color": "^5.3.0" 379 | } 380 | }, 381 | "chardet": { 382 | "version": "0.7.0", 383 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 384 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 385 | "dev": true 386 | }, 387 | "chokidar": { 388 | "version": "3.3.0", 389 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", 390 | "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", 391 | "dev": true, 392 | "requires": { 393 | "anymatch": "~3.1.1", 394 | "braces": "~3.0.2", 395 | "fsevents": "~2.1.1", 396 | "glob-parent": "~5.1.0", 397 | "is-binary-path": "~2.1.0", 398 | "is-glob": "~4.0.1", 399 | "normalize-path": "~3.0.0", 400 | "readdirp": "~3.2.0" 401 | } 402 | }, 403 | "cli-cursor": { 404 | "version": "3.1.0", 405 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 406 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", 407 | "dev": true, 408 | "requires": { 409 | "restore-cursor": "^3.1.0" 410 | } 411 | }, 412 | "cli-width": { 413 | "version": "3.0.0", 414 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", 415 | "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", 416 | "dev": true 417 | }, 418 | "cliui": { 419 | "version": "5.0.0", 420 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 421 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 422 | "dev": true, 423 | "requires": { 424 | "string-width": "^3.1.0", 425 | "strip-ansi": "^5.2.0", 426 | "wrap-ansi": "^5.1.0" 427 | }, 428 | "dependencies": { 429 | "emoji-regex": { 430 | "version": "7.0.3", 431 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 432 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 433 | "dev": true 434 | }, 435 | "is-fullwidth-code-point": { 436 | "version": "2.0.0", 437 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 438 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 439 | "dev": true 440 | }, 441 | "string-width": { 442 | "version": "3.1.0", 443 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 444 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 445 | "dev": true, 446 | "requires": { 447 | "emoji-regex": "^7.0.1", 448 | "is-fullwidth-code-point": "^2.0.0", 449 | "strip-ansi": "^5.1.0" 450 | } 451 | } 452 | } 453 | }, 454 | "color-convert": { 455 | "version": "1.9.3", 456 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 457 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 458 | "dev": true, 459 | "requires": { 460 | "color-name": "1.1.3" 461 | } 462 | }, 463 | "color-name": { 464 | "version": "1.1.3", 465 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 466 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 467 | "dev": true 468 | }, 469 | "combined-stream": { 470 | "version": "1.0.8", 471 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 472 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 473 | "requires": { 474 | "delayed-stream": "~1.0.0" 475 | } 476 | }, 477 | "concat-map": { 478 | "version": "0.0.1", 479 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 480 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 481 | }, 482 | "core-util-is": { 483 | "version": "1.0.2", 484 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 485 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 486 | }, 487 | "cross-spawn": { 488 | "version": "6.0.5", 489 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 490 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 491 | "dev": true, 492 | "requires": { 493 | "nice-try": "^1.0.4", 494 | "path-key": "^2.0.1", 495 | "semver": "^5.5.0", 496 | "shebang-command": "^1.2.0", 497 | "which": "^1.2.9" 498 | }, 499 | "dependencies": { 500 | "semver": { 501 | "version": "5.7.1", 502 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 503 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 504 | "dev": true 505 | } 506 | } 507 | }, 508 | "dashdash": { 509 | "version": "1.14.1", 510 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 511 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 512 | "requires": { 513 | "assert-plus": "^1.0.0" 514 | } 515 | }, 516 | "debug": { 517 | "version": "4.1.1", 518 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 519 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 520 | "dev": true, 521 | "requires": { 522 | "ms": "^2.1.1" 523 | } 524 | }, 525 | "decamelize": { 526 | "version": "1.2.0", 527 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 528 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 529 | "dev": true 530 | }, 531 | "deep-is": { 532 | "version": "0.1.3", 533 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 534 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 535 | "dev": true 536 | }, 537 | "define-properties": { 538 | "version": "1.1.3", 539 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 540 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 541 | "dev": true, 542 | "requires": { 543 | "object-keys": "^1.0.12" 544 | } 545 | }, 546 | "delayed-stream": { 547 | "version": "1.0.0", 548 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 549 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 550 | }, 551 | "diff": { 552 | "version": "3.5.0", 553 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 554 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 555 | "dev": true 556 | }, 557 | "doctrine": { 558 | "version": "3.0.0", 559 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 560 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 561 | "dev": true, 562 | "requires": { 563 | "esutils": "^2.0.2" 564 | } 565 | }, 566 | "ecc-jsbn": { 567 | "version": "0.1.2", 568 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 569 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 570 | "requires": { 571 | "jsbn": "~0.1.0", 572 | "safer-buffer": "^2.1.0" 573 | } 574 | }, 575 | "emoji-regex": { 576 | "version": "8.0.0", 577 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 578 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 579 | "dev": true 580 | }, 581 | "es-abstract": { 582 | "version": "1.17.6", 583 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", 584 | "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", 585 | "dev": true, 586 | "requires": { 587 | "es-to-primitive": "^1.2.1", 588 | "function-bind": "^1.1.1", 589 | "has": "^1.0.3", 590 | "has-symbols": "^1.0.1", 591 | "is-callable": "^1.2.0", 592 | "is-regex": "^1.1.0", 593 | "object-inspect": "^1.7.0", 594 | "object-keys": "^1.1.1", 595 | "object.assign": "^4.1.0", 596 | "string.prototype.trimend": "^1.0.1", 597 | "string.prototype.trimstart": "^1.0.1" 598 | } 599 | }, 600 | "es-to-primitive": { 601 | "version": "1.2.1", 602 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 603 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 604 | "dev": true, 605 | "requires": { 606 | "is-callable": "^1.1.4", 607 | "is-date-object": "^1.0.1", 608 | "is-symbol": "^1.0.2" 609 | } 610 | }, 611 | "es6-promise": { 612 | "version": "4.2.8", 613 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", 614 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", 615 | "dev": true 616 | }, 617 | "es6-promisify": { 618 | "version": "5.0.0", 619 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 620 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 621 | "dev": true, 622 | "requires": { 623 | "es6-promise": "^4.0.3" 624 | } 625 | }, 626 | "escape-string-regexp": { 627 | "version": "1.0.5", 628 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 629 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 630 | "dev": true 631 | }, 632 | "eslint": { 633 | "version": "6.8.0", 634 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", 635 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", 636 | "dev": true, 637 | "requires": { 638 | "@babel/code-frame": "^7.0.0", 639 | "ajv": "^6.10.0", 640 | "chalk": "^2.1.0", 641 | "cross-spawn": "^6.0.5", 642 | "debug": "^4.0.1", 643 | "doctrine": "^3.0.0", 644 | "eslint-scope": "^5.0.0", 645 | "eslint-utils": "^1.4.3", 646 | "eslint-visitor-keys": "^1.1.0", 647 | "espree": "^6.1.2", 648 | "esquery": "^1.0.1", 649 | "esutils": "^2.0.2", 650 | "file-entry-cache": "^5.0.1", 651 | "functional-red-black-tree": "^1.0.1", 652 | "glob-parent": "^5.0.0", 653 | "globals": "^12.1.0", 654 | "ignore": "^4.0.6", 655 | "import-fresh": "^3.0.0", 656 | "imurmurhash": "^0.1.4", 657 | "inquirer": "^7.0.0", 658 | "is-glob": "^4.0.0", 659 | "js-yaml": "^3.13.1", 660 | "json-stable-stringify-without-jsonify": "^1.0.1", 661 | "levn": "^0.3.0", 662 | "lodash": "^4.17.14", 663 | "minimatch": "^3.0.4", 664 | "mkdirp": "^0.5.1", 665 | "natural-compare": "^1.4.0", 666 | "optionator": "^0.8.3", 667 | "progress": "^2.0.0", 668 | "regexpp": "^2.0.1", 669 | "semver": "^6.1.2", 670 | "strip-ansi": "^5.2.0", 671 | "strip-json-comments": "^3.0.1", 672 | "table": "^5.2.3", 673 | "text-table": "^0.2.0", 674 | "v8-compile-cache": "^2.0.3" 675 | }, 676 | "dependencies": { 677 | "eslint-utils": { 678 | "version": "1.4.3", 679 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 680 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 681 | "dev": true, 682 | "requires": { 683 | "eslint-visitor-keys": "^1.1.0" 684 | } 685 | }, 686 | "regexpp": { 687 | "version": "2.0.1", 688 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 689 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 690 | "dev": true 691 | }, 692 | "semver": { 693 | "version": "6.3.0", 694 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 695 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 696 | "dev": true 697 | } 698 | } 699 | }, 700 | "eslint-scope": { 701 | "version": "5.1.0", 702 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", 703 | "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", 704 | "dev": true, 705 | "requires": { 706 | "esrecurse": "^4.1.0", 707 | "estraverse": "^4.1.1" 708 | } 709 | }, 710 | "eslint-utils": { 711 | "version": "2.1.0", 712 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", 713 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", 714 | "dev": true, 715 | "requires": { 716 | "eslint-visitor-keys": "^1.1.0" 717 | } 718 | }, 719 | "eslint-visitor-keys": { 720 | "version": "1.3.0", 721 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 722 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 723 | "dev": true 724 | }, 725 | "espree": { 726 | "version": "6.2.1", 727 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", 728 | "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", 729 | "dev": true, 730 | "requires": { 731 | "acorn": "^7.1.1", 732 | "acorn-jsx": "^5.2.0", 733 | "eslint-visitor-keys": "^1.1.0" 734 | } 735 | }, 736 | "esprima": { 737 | "version": "4.0.1", 738 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 739 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 740 | "dev": true 741 | }, 742 | "esquery": { 743 | "version": "1.3.1", 744 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 745 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 746 | "dev": true, 747 | "requires": { 748 | "estraverse": "^5.1.0" 749 | }, 750 | "dependencies": { 751 | "estraverse": { 752 | "version": "5.1.0", 753 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", 754 | "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", 755 | "dev": true 756 | } 757 | } 758 | }, 759 | "esrecurse": { 760 | "version": "4.2.1", 761 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 762 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 763 | "dev": true, 764 | "requires": { 765 | "estraverse": "^4.1.0" 766 | } 767 | }, 768 | "estraverse": { 769 | "version": "4.3.0", 770 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 771 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 772 | "dev": true 773 | }, 774 | "esutils": { 775 | "version": "2.0.3", 776 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 777 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 778 | "dev": true 779 | }, 780 | "extend": { 781 | "version": "3.0.2", 782 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 783 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 784 | }, 785 | "external-editor": { 786 | "version": "3.1.0", 787 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 788 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 789 | "dev": true, 790 | "requires": { 791 | "chardet": "^0.7.0", 792 | "iconv-lite": "^0.4.24", 793 | "tmp": "^0.0.33" 794 | }, 795 | "dependencies": { 796 | "iconv-lite": { 797 | "version": "0.4.24", 798 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 799 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 800 | "dev": true, 801 | "requires": { 802 | "safer-buffer": ">= 2.1.2 < 3" 803 | } 804 | } 805 | } 806 | }, 807 | "extsprintf": { 808 | "version": "1.3.0", 809 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 810 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 811 | }, 812 | "fast-deep-equal": { 813 | "version": "3.1.3", 814 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 815 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 816 | }, 817 | "fast-json-stable-stringify": { 818 | "version": "2.1.0", 819 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 820 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 821 | }, 822 | "fast-levenshtein": { 823 | "version": "2.0.6", 824 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 825 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 826 | "dev": true 827 | }, 828 | "figures": { 829 | "version": "3.2.0", 830 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", 831 | "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", 832 | "dev": true, 833 | "requires": { 834 | "escape-string-regexp": "^1.0.5" 835 | } 836 | }, 837 | "file-entry-cache": { 838 | "version": "5.0.1", 839 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 840 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 841 | "dev": true, 842 | "requires": { 843 | "flat-cache": "^2.0.1" 844 | } 845 | }, 846 | "fill-range": { 847 | "version": "7.0.1", 848 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 849 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 850 | "dev": true, 851 | "requires": { 852 | "to-regex-range": "^5.0.1" 853 | } 854 | }, 855 | "find-up": { 856 | "version": "3.0.0", 857 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 858 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 859 | "dev": true, 860 | "requires": { 861 | "locate-path": "^3.0.0" 862 | } 863 | }, 864 | "flat": { 865 | "version": "4.1.0", 866 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 867 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 868 | "dev": true, 869 | "requires": { 870 | "is-buffer": "~2.0.3" 871 | } 872 | }, 873 | "flat-cache": { 874 | "version": "2.0.1", 875 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 876 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 877 | "dev": true, 878 | "requires": { 879 | "flatted": "^2.0.0", 880 | "rimraf": "2.6.3", 881 | "write": "1.0.3" 882 | } 883 | }, 884 | "flatted": { 885 | "version": "2.0.2", 886 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", 887 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", 888 | "dev": true 889 | }, 890 | "forever-agent": { 891 | "version": "0.6.1", 892 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 893 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 894 | }, 895 | "form-data": { 896 | "version": "2.3.3", 897 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 898 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 899 | "requires": { 900 | "asynckit": "^0.4.0", 901 | "combined-stream": "^1.0.6", 902 | "mime-types": "^2.1.12" 903 | } 904 | }, 905 | "fs-extra": { 906 | "version": "9.0.1", 907 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", 908 | "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", 909 | "requires": { 910 | "at-least-node": "^1.0.0", 911 | "graceful-fs": "^4.2.0", 912 | "jsonfile": "^6.0.1", 913 | "universalify": "^1.0.0" 914 | } 915 | }, 916 | "fs.realpath": { 917 | "version": "1.0.0", 918 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 919 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 920 | }, 921 | "fsevents": { 922 | "version": "2.1.3", 923 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 924 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 925 | "dev": true, 926 | "optional": true 927 | }, 928 | "function-bind": { 929 | "version": "1.1.1", 930 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 931 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 932 | "dev": true 933 | }, 934 | "functional-red-black-tree": { 935 | "version": "1.0.1", 936 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 937 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 938 | "dev": true 939 | }, 940 | "get-caller-file": { 941 | "version": "2.0.5", 942 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 943 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 944 | "dev": true 945 | }, 946 | "getpass": { 947 | "version": "0.1.7", 948 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 949 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 950 | "requires": { 951 | "assert-plus": "^1.0.0" 952 | } 953 | }, 954 | "glob": { 955 | "version": "7.1.6", 956 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 957 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 958 | "requires": { 959 | "fs.realpath": "^1.0.0", 960 | "inflight": "^1.0.4", 961 | "inherits": "2", 962 | "minimatch": "^3.0.4", 963 | "once": "^1.3.0", 964 | "path-is-absolute": "^1.0.0" 965 | } 966 | }, 967 | "glob-parent": { 968 | "version": "5.1.2", 969 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 970 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 971 | "dev": true, 972 | "requires": { 973 | "is-glob": "^4.0.1" 974 | } 975 | }, 976 | "globals": { 977 | "version": "12.4.0", 978 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", 979 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", 980 | "dev": true, 981 | "requires": { 982 | "type-fest": "^0.8.1" 983 | } 984 | }, 985 | "graceful-fs": { 986 | "version": "4.2.4", 987 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 988 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" 989 | }, 990 | "growl": { 991 | "version": "1.10.5", 992 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 993 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 994 | "dev": true 995 | }, 996 | "har-schema": { 997 | "version": "2.0.0", 998 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 999 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 1000 | }, 1001 | "har-validator": { 1002 | "version": "5.1.3", 1003 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 1004 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 1005 | "requires": { 1006 | "ajv": "^6.5.5", 1007 | "har-schema": "^2.0.0" 1008 | } 1009 | }, 1010 | "has": { 1011 | "version": "1.0.3", 1012 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1013 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1014 | "dev": true, 1015 | "requires": { 1016 | "function-bind": "^1.1.1" 1017 | } 1018 | }, 1019 | "has-flag": { 1020 | "version": "3.0.0", 1021 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1022 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1023 | "dev": true 1024 | }, 1025 | "has-symbols": { 1026 | "version": "1.0.1", 1027 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 1028 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 1029 | "dev": true 1030 | }, 1031 | "he": { 1032 | "version": "1.2.0", 1033 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1034 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1035 | "dev": true 1036 | }, 1037 | "http-proxy-agent": { 1038 | "version": "2.1.0", 1039 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", 1040 | "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", 1041 | "dev": true, 1042 | "requires": { 1043 | "agent-base": "4", 1044 | "debug": "3.1.0" 1045 | }, 1046 | "dependencies": { 1047 | "debug": { 1048 | "version": "3.1.0", 1049 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1050 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1051 | "dev": true, 1052 | "requires": { 1053 | "ms": "2.0.0" 1054 | } 1055 | }, 1056 | "ms": { 1057 | "version": "2.0.0", 1058 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1059 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1060 | "dev": true 1061 | } 1062 | } 1063 | }, 1064 | "http-signature": { 1065 | "version": "1.2.0", 1066 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 1067 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 1068 | "requires": { 1069 | "assert-plus": "^1.0.0", 1070 | "jsprim": "^1.2.2", 1071 | "sshpk": "^1.7.0" 1072 | } 1073 | }, 1074 | "https-proxy-agent": { 1075 | "version": "2.2.4", 1076 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", 1077 | "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", 1078 | "dev": true, 1079 | "requires": { 1080 | "agent-base": "^4.3.0", 1081 | "debug": "^3.1.0" 1082 | }, 1083 | "dependencies": { 1084 | "debug": { 1085 | "version": "3.2.6", 1086 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 1087 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 1088 | "dev": true, 1089 | "requires": { 1090 | "ms": "^2.1.1" 1091 | } 1092 | } 1093 | } 1094 | }, 1095 | "iconv-lite": { 1096 | "version": "0.5.2", 1097 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", 1098 | "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", 1099 | "requires": { 1100 | "safer-buffer": ">= 2.1.2 < 3" 1101 | } 1102 | }, 1103 | "ignore": { 1104 | "version": "4.0.6", 1105 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 1106 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 1107 | "dev": true 1108 | }, 1109 | "import-fresh": { 1110 | "version": "3.2.1", 1111 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 1112 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 1113 | "dev": true, 1114 | "requires": { 1115 | "parent-module": "^1.0.0", 1116 | "resolve-from": "^4.0.0" 1117 | } 1118 | }, 1119 | "imurmurhash": { 1120 | "version": "0.1.4", 1121 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1122 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1123 | "dev": true 1124 | }, 1125 | "inflight": { 1126 | "version": "1.0.6", 1127 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1128 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1129 | "requires": { 1130 | "once": "^1.3.0", 1131 | "wrappy": "1" 1132 | } 1133 | }, 1134 | "inherits": { 1135 | "version": "2.0.4", 1136 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1137 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1138 | }, 1139 | "inquirer": { 1140 | "version": "7.3.2", 1141 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.2.tgz", 1142 | "integrity": "sha512-DF4osh1FM6l0RJc5YWYhSDB6TawiBRlbV9Cox8MWlidU218Tb7fm3lQTULyUJDfJ0tjbzl0W4q651mrCCEM55w==", 1143 | "dev": true, 1144 | "requires": { 1145 | "ansi-escapes": "^4.2.1", 1146 | "chalk": "^4.1.0", 1147 | "cli-cursor": "^3.1.0", 1148 | "cli-width": "^3.0.0", 1149 | "external-editor": "^3.0.3", 1150 | "figures": "^3.0.0", 1151 | "lodash": "^4.17.16", 1152 | "mute-stream": "0.0.8", 1153 | "run-async": "^2.4.0", 1154 | "rxjs": "^6.6.0", 1155 | "string-width": "^4.1.0", 1156 | "strip-ansi": "^6.0.0", 1157 | "through": "^2.3.6" 1158 | }, 1159 | "dependencies": { 1160 | "ansi-styles": { 1161 | "version": "4.2.1", 1162 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 1163 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 1164 | "dev": true, 1165 | "requires": { 1166 | "@types/color-name": "^1.1.1", 1167 | "color-convert": "^2.0.1" 1168 | } 1169 | }, 1170 | "chalk": { 1171 | "version": "4.1.0", 1172 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 1173 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 1174 | "dev": true, 1175 | "requires": { 1176 | "ansi-styles": "^4.1.0", 1177 | "supports-color": "^7.1.0" 1178 | } 1179 | }, 1180 | "color-convert": { 1181 | "version": "2.0.1", 1182 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1183 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1184 | "dev": true, 1185 | "requires": { 1186 | "color-name": "~1.1.4" 1187 | } 1188 | }, 1189 | "color-name": { 1190 | "version": "1.1.4", 1191 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1192 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1193 | "dev": true 1194 | }, 1195 | "has-flag": { 1196 | "version": "4.0.0", 1197 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1198 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1199 | "dev": true 1200 | }, 1201 | "strip-ansi": { 1202 | "version": "6.0.0", 1203 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1204 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1205 | "dev": true, 1206 | "requires": { 1207 | "ansi-regex": "^5.0.0" 1208 | } 1209 | }, 1210 | "supports-color": { 1211 | "version": "7.1.0", 1212 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 1213 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 1214 | "dev": true, 1215 | "requires": { 1216 | "has-flag": "^4.0.0" 1217 | } 1218 | } 1219 | } 1220 | }, 1221 | "is-binary-path": { 1222 | "version": "2.1.0", 1223 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1224 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1225 | "dev": true, 1226 | "requires": { 1227 | "binary-extensions": "^2.0.0" 1228 | } 1229 | }, 1230 | "is-buffer": { 1231 | "version": "2.0.4", 1232 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 1233 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 1234 | "dev": true 1235 | }, 1236 | "is-callable": { 1237 | "version": "1.2.0", 1238 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", 1239 | "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", 1240 | "dev": true 1241 | }, 1242 | "is-date-object": { 1243 | "version": "1.0.2", 1244 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 1245 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 1246 | "dev": true 1247 | }, 1248 | "is-extglob": { 1249 | "version": "2.1.1", 1250 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1251 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1252 | "dev": true 1253 | }, 1254 | "is-fullwidth-code-point": { 1255 | "version": "3.0.0", 1256 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1257 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1258 | "dev": true 1259 | }, 1260 | "is-glob": { 1261 | "version": "4.0.1", 1262 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1263 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1264 | "dev": true, 1265 | "requires": { 1266 | "is-extglob": "^2.1.1" 1267 | } 1268 | }, 1269 | "is-number": { 1270 | "version": "7.0.0", 1271 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1272 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1273 | "dev": true 1274 | }, 1275 | "is-regex": { 1276 | "version": "1.1.0", 1277 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", 1278 | "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", 1279 | "dev": true, 1280 | "requires": { 1281 | "has-symbols": "^1.0.1" 1282 | } 1283 | }, 1284 | "is-symbol": { 1285 | "version": "1.0.3", 1286 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 1287 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 1288 | "dev": true, 1289 | "requires": { 1290 | "has-symbols": "^1.0.1" 1291 | } 1292 | }, 1293 | "is-typedarray": { 1294 | "version": "1.0.0", 1295 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1296 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 1297 | }, 1298 | "isexe": { 1299 | "version": "2.0.0", 1300 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1301 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1302 | "dev": true 1303 | }, 1304 | "isstream": { 1305 | "version": "0.1.2", 1306 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1307 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 1308 | }, 1309 | "js-tokens": { 1310 | "version": "4.0.0", 1311 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1312 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1313 | "dev": true 1314 | }, 1315 | "js-yaml": { 1316 | "version": "3.14.0", 1317 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 1318 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 1319 | "dev": true, 1320 | "requires": { 1321 | "argparse": "^1.0.7", 1322 | "esprima": "^4.0.0" 1323 | } 1324 | }, 1325 | "jsbn": { 1326 | "version": "0.1.1", 1327 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1328 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 1329 | }, 1330 | "json-schema": { 1331 | "version": "0.2.3", 1332 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 1333 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 1334 | }, 1335 | "json-schema-traverse": { 1336 | "version": "0.4.1", 1337 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1338 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 1339 | }, 1340 | "json-stable-stringify-without-jsonify": { 1341 | "version": "1.0.1", 1342 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1343 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1344 | "dev": true 1345 | }, 1346 | "json-stringify-safe": { 1347 | "version": "5.0.1", 1348 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1349 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 1350 | }, 1351 | "jsonfile": { 1352 | "version": "6.0.1", 1353 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", 1354 | "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", 1355 | "requires": { 1356 | "graceful-fs": "^4.1.6", 1357 | "universalify": "^1.0.0" 1358 | } 1359 | }, 1360 | "jsprim": { 1361 | "version": "1.4.1", 1362 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 1363 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 1364 | "requires": { 1365 | "assert-plus": "1.0.0", 1366 | "extsprintf": "1.3.0", 1367 | "json-schema": "0.2.3", 1368 | "verror": "1.10.0" 1369 | } 1370 | }, 1371 | "levn": { 1372 | "version": "0.3.0", 1373 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1374 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1375 | "dev": true, 1376 | "requires": { 1377 | "prelude-ls": "~1.1.2", 1378 | "type-check": "~0.3.2" 1379 | } 1380 | }, 1381 | "locate-path": { 1382 | "version": "3.0.0", 1383 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 1384 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 1385 | "dev": true, 1386 | "requires": { 1387 | "p-locate": "^3.0.0", 1388 | "path-exists": "^3.0.0" 1389 | } 1390 | }, 1391 | "lodash": { 1392 | "version": "4.17.21", 1393 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1394 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1395 | "dev": true 1396 | }, 1397 | "log-symbols": { 1398 | "version": "3.0.0", 1399 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", 1400 | "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", 1401 | "dev": true, 1402 | "requires": { 1403 | "chalk": "^2.4.2" 1404 | } 1405 | }, 1406 | "mime-db": { 1407 | "version": "1.44.0", 1408 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 1409 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" 1410 | }, 1411 | "mime-types": { 1412 | "version": "2.1.27", 1413 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 1414 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 1415 | "requires": { 1416 | "mime-db": "1.44.0" 1417 | } 1418 | }, 1419 | "mimic-fn": { 1420 | "version": "2.1.0", 1421 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 1422 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 1423 | "dev": true 1424 | }, 1425 | "minimatch": { 1426 | "version": "3.0.4", 1427 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1428 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1429 | "requires": { 1430 | "brace-expansion": "^1.1.7" 1431 | } 1432 | }, 1433 | "minimist": { 1434 | "version": "1.2.5", 1435 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 1436 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 1437 | "dev": true 1438 | }, 1439 | "mkdirp": { 1440 | "version": "0.5.5", 1441 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 1442 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 1443 | "dev": true, 1444 | "requires": { 1445 | "minimist": "^1.2.5" 1446 | } 1447 | }, 1448 | "mocha": { 1449 | "version": "7.2.0", 1450 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", 1451 | "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", 1452 | "dev": true, 1453 | "requires": { 1454 | "ansi-colors": "3.2.3", 1455 | "browser-stdout": "1.3.1", 1456 | "chokidar": "3.3.0", 1457 | "debug": "3.2.6", 1458 | "diff": "3.5.0", 1459 | "escape-string-regexp": "1.0.5", 1460 | "find-up": "3.0.0", 1461 | "glob": "7.1.3", 1462 | "growl": "1.10.5", 1463 | "he": "1.2.0", 1464 | "js-yaml": "3.13.1", 1465 | "log-symbols": "3.0.0", 1466 | "minimatch": "3.0.4", 1467 | "mkdirp": "0.5.5", 1468 | "ms": "2.1.1", 1469 | "node-environment-flags": "1.0.6", 1470 | "object.assign": "4.1.0", 1471 | "strip-json-comments": "2.0.1", 1472 | "supports-color": "6.0.0", 1473 | "which": "1.3.1", 1474 | "wide-align": "1.1.3", 1475 | "yargs": "13.3.2", 1476 | "yargs-parser": "13.1.2", 1477 | "yargs-unparser": "1.6.0" 1478 | }, 1479 | "dependencies": { 1480 | "debug": { 1481 | "version": "3.2.6", 1482 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 1483 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 1484 | "dev": true, 1485 | "requires": { 1486 | "ms": "^2.1.1" 1487 | } 1488 | }, 1489 | "glob": { 1490 | "version": "7.1.3", 1491 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 1492 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 1493 | "dev": true, 1494 | "requires": { 1495 | "fs.realpath": "^1.0.0", 1496 | "inflight": "^1.0.4", 1497 | "inherits": "2", 1498 | "minimatch": "^3.0.4", 1499 | "once": "^1.3.0", 1500 | "path-is-absolute": "^1.0.0" 1501 | } 1502 | }, 1503 | "js-yaml": { 1504 | "version": "3.13.1", 1505 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1506 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1507 | "dev": true, 1508 | "requires": { 1509 | "argparse": "^1.0.7", 1510 | "esprima": "^4.0.0" 1511 | } 1512 | }, 1513 | "ms": { 1514 | "version": "2.1.1", 1515 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1516 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 1517 | "dev": true 1518 | }, 1519 | "strip-json-comments": { 1520 | "version": "2.0.1", 1521 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1522 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1523 | "dev": true 1524 | }, 1525 | "supports-color": { 1526 | "version": "6.0.0", 1527 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", 1528 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", 1529 | "dev": true, 1530 | "requires": { 1531 | "has-flag": "^3.0.0" 1532 | } 1533 | } 1534 | } 1535 | }, 1536 | "ms": { 1537 | "version": "2.1.2", 1538 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1539 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1540 | "dev": true 1541 | }, 1542 | "mute-stream": { 1543 | "version": "0.0.8", 1544 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", 1545 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", 1546 | "dev": true 1547 | }, 1548 | "natural-compare": { 1549 | "version": "1.4.0", 1550 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1551 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1552 | "dev": true 1553 | }, 1554 | "nice-try": { 1555 | "version": "1.0.5", 1556 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1557 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 1558 | "dev": true 1559 | }, 1560 | "node-environment-flags": { 1561 | "version": "1.0.6", 1562 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", 1563 | "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", 1564 | "dev": true, 1565 | "requires": { 1566 | "object.getownpropertydescriptors": "^2.0.3", 1567 | "semver": "^5.7.0" 1568 | }, 1569 | "dependencies": { 1570 | "semver": { 1571 | "version": "5.7.1", 1572 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1573 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1574 | "dev": true 1575 | } 1576 | } 1577 | }, 1578 | "normalize-path": { 1579 | "version": "3.0.0", 1580 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1581 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1582 | "dev": true 1583 | }, 1584 | "oauth-sign": { 1585 | "version": "0.9.0", 1586 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 1587 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 1588 | }, 1589 | "object-inspect": { 1590 | "version": "1.8.0", 1591 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", 1592 | "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", 1593 | "dev": true 1594 | }, 1595 | "object-keys": { 1596 | "version": "1.1.1", 1597 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1598 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1599 | "dev": true 1600 | }, 1601 | "object.assign": { 1602 | "version": "4.1.0", 1603 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 1604 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1605 | "dev": true, 1606 | "requires": { 1607 | "define-properties": "^1.1.2", 1608 | "function-bind": "^1.1.1", 1609 | "has-symbols": "^1.0.0", 1610 | "object-keys": "^1.0.11" 1611 | } 1612 | }, 1613 | "object.getownpropertydescriptors": { 1614 | "version": "2.1.0", 1615 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", 1616 | "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", 1617 | "dev": true, 1618 | "requires": { 1619 | "define-properties": "^1.1.3", 1620 | "es-abstract": "^1.17.0-next.1" 1621 | } 1622 | }, 1623 | "once": { 1624 | "version": "1.4.0", 1625 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1626 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1627 | "requires": { 1628 | "wrappy": "1" 1629 | } 1630 | }, 1631 | "onetime": { 1632 | "version": "5.1.0", 1633 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", 1634 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", 1635 | "dev": true, 1636 | "requires": { 1637 | "mimic-fn": "^2.1.0" 1638 | } 1639 | }, 1640 | "optionator": { 1641 | "version": "0.8.3", 1642 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1643 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1644 | "dev": true, 1645 | "requires": { 1646 | "deep-is": "~0.1.3", 1647 | "fast-levenshtein": "~2.0.6", 1648 | "levn": "~0.3.0", 1649 | "prelude-ls": "~1.1.2", 1650 | "type-check": "~0.3.2", 1651 | "word-wrap": "~1.2.3" 1652 | } 1653 | }, 1654 | "os-tmpdir": { 1655 | "version": "1.0.2", 1656 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1657 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1658 | "dev": true 1659 | }, 1660 | "p-limit": { 1661 | "version": "2.3.0", 1662 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1663 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1664 | "dev": true, 1665 | "requires": { 1666 | "p-try": "^2.0.0" 1667 | } 1668 | }, 1669 | "p-locate": { 1670 | "version": "3.0.0", 1671 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1672 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1673 | "dev": true, 1674 | "requires": { 1675 | "p-limit": "^2.0.0" 1676 | } 1677 | }, 1678 | "p-try": { 1679 | "version": "2.2.0", 1680 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1681 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1682 | "dev": true 1683 | }, 1684 | "parent-module": { 1685 | "version": "1.0.1", 1686 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1687 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1688 | "dev": true, 1689 | "requires": { 1690 | "callsites": "^3.0.0" 1691 | } 1692 | }, 1693 | "path-exists": { 1694 | "version": "3.0.0", 1695 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1696 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1697 | "dev": true 1698 | }, 1699 | "path-is-absolute": { 1700 | "version": "1.0.1", 1701 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1702 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1703 | }, 1704 | "path-key": { 1705 | "version": "2.0.1", 1706 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1707 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 1708 | "dev": true 1709 | }, 1710 | "performance-now": { 1711 | "version": "2.1.0", 1712 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1713 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 1714 | }, 1715 | "picomatch": { 1716 | "version": "2.2.2", 1717 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 1718 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 1719 | "dev": true 1720 | }, 1721 | "prelude-ls": { 1722 | "version": "1.1.2", 1723 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1724 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1725 | "dev": true 1726 | }, 1727 | "progress": { 1728 | "version": "2.0.3", 1729 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1730 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1731 | "dev": true 1732 | }, 1733 | "psl": { 1734 | "version": "1.8.0", 1735 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 1736 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 1737 | }, 1738 | "punycode": { 1739 | "version": "2.1.1", 1740 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1741 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 1742 | }, 1743 | "qs": { 1744 | "version": "6.5.2", 1745 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1746 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 1747 | }, 1748 | "readdirp": { 1749 | "version": "3.2.0", 1750 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", 1751 | "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", 1752 | "dev": true, 1753 | "requires": { 1754 | "picomatch": "^2.0.4" 1755 | } 1756 | }, 1757 | "regexpp": { 1758 | "version": "3.1.0", 1759 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", 1760 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", 1761 | "dev": true 1762 | }, 1763 | "request": { 1764 | "version": "2.88.2", 1765 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 1766 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 1767 | "requires": { 1768 | "aws-sign2": "~0.7.0", 1769 | "aws4": "^1.8.0", 1770 | "caseless": "~0.12.0", 1771 | "combined-stream": "~1.0.6", 1772 | "extend": "~3.0.2", 1773 | "forever-agent": "~0.6.1", 1774 | "form-data": "~2.3.2", 1775 | "har-validator": "~5.1.3", 1776 | "http-signature": "~1.2.0", 1777 | "is-typedarray": "~1.0.0", 1778 | "isstream": "~0.1.2", 1779 | "json-stringify-safe": "~5.0.1", 1780 | "mime-types": "~2.1.19", 1781 | "oauth-sign": "~0.9.0", 1782 | "performance-now": "^2.1.0", 1783 | "qs": "~6.5.2", 1784 | "safe-buffer": "^5.1.2", 1785 | "tough-cookie": "~2.5.0", 1786 | "tunnel-agent": "^0.6.0", 1787 | "uuid": "^3.3.2" 1788 | } 1789 | }, 1790 | "require-directory": { 1791 | "version": "2.1.1", 1792 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1793 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1794 | "dev": true 1795 | }, 1796 | "require-main-filename": { 1797 | "version": "2.0.0", 1798 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1799 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 1800 | "dev": true 1801 | }, 1802 | "resolve-from": { 1803 | "version": "4.0.0", 1804 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1805 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1806 | "dev": true 1807 | }, 1808 | "restore-cursor": { 1809 | "version": "3.1.0", 1810 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", 1811 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", 1812 | "dev": true, 1813 | "requires": { 1814 | "onetime": "^5.1.0", 1815 | "signal-exit": "^3.0.2" 1816 | } 1817 | }, 1818 | "rimraf": { 1819 | "version": "2.6.3", 1820 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1821 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1822 | "dev": true, 1823 | "requires": { 1824 | "glob": "^7.1.3" 1825 | } 1826 | }, 1827 | "run-async": { 1828 | "version": "2.4.1", 1829 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", 1830 | "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", 1831 | "dev": true 1832 | }, 1833 | "rxjs": { 1834 | "version": "6.6.0", 1835 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", 1836 | "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", 1837 | "dev": true, 1838 | "requires": { 1839 | "tslib": "^1.9.0" 1840 | } 1841 | }, 1842 | "safe-buffer": { 1843 | "version": "5.2.1", 1844 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1845 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 1846 | }, 1847 | "safer-buffer": { 1848 | "version": "2.1.2", 1849 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1850 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1851 | }, 1852 | "semver": { 1853 | "version": "7.3.2", 1854 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", 1855 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", 1856 | "dev": true 1857 | }, 1858 | "set-blocking": { 1859 | "version": "2.0.0", 1860 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1861 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 1862 | "dev": true 1863 | }, 1864 | "shebang-command": { 1865 | "version": "1.2.0", 1866 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1867 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1868 | "dev": true, 1869 | "requires": { 1870 | "shebang-regex": "^1.0.0" 1871 | } 1872 | }, 1873 | "shebang-regex": { 1874 | "version": "1.0.0", 1875 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1876 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1877 | "dev": true 1878 | }, 1879 | "signal-exit": { 1880 | "version": "3.0.3", 1881 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 1882 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", 1883 | "dev": true 1884 | }, 1885 | "slice-ansi": { 1886 | "version": "2.1.0", 1887 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1888 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1889 | "dev": true, 1890 | "requires": { 1891 | "ansi-styles": "^3.2.0", 1892 | "astral-regex": "^1.0.0", 1893 | "is-fullwidth-code-point": "^2.0.0" 1894 | }, 1895 | "dependencies": { 1896 | "is-fullwidth-code-point": { 1897 | "version": "2.0.0", 1898 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1899 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1900 | "dev": true 1901 | } 1902 | } 1903 | }, 1904 | "sprintf-js": { 1905 | "version": "1.0.3", 1906 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1907 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1908 | "dev": true 1909 | }, 1910 | "sshpk": { 1911 | "version": "1.16.1", 1912 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 1913 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 1914 | "requires": { 1915 | "asn1": "~0.2.3", 1916 | "assert-plus": "^1.0.0", 1917 | "bcrypt-pbkdf": "^1.0.0", 1918 | "dashdash": "^1.12.0", 1919 | "ecc-jsbn": "~0.1.1", 1920 | "getpass": "^0.1.1", 1921 | "jsbn": "~0.1.0", 1922 | "safer-buffer": "^2.0.2", 1923 | "tweetnacl": "~0.14.0" 1924 | } 1925 | }, 1926 | "string-width": { 1927 | "version": "4.2.0", 1928 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 1929 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 1930 | "dev": true, 1931 | "requires": { 1932 | "emoji-regex": "^8.0.0", 1933 | "is-fullwidth-code-point": "^3.0.0", 1934 | "strip-ansi": "^6.0.0" 1935 | }, 1936 | "dependencies": { 1937 | "strip-ansi": { 1938 | "version": "6.0.0", 1939 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1940 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1941 | "dev": true, 1942 | "requires": { 1943 | "ansi-regex": "^5.0.0" 1944 | } 1945 | } 1946 | } 1947 | }, 1948 | "string.prototype.trimend": { 1949 | "version": "1.0.1", 1950 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", 1951 | "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", 1952 | "dev": true, 1953 | "requires": { 1954 | "define-properties": "^1.1.3", 1955 | "es-abstract": "^1.17.5" 1956 | } 1957 | }, 1958 | "string.prototype.trimstart": { 1959 | "version": "1.0.1", 1960 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", 1961 | "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", 1962 | "dev": true, 1963 | "requires": { 1964 | "define-properties": "^1.1.3", 1965 | "es-abstract": "^1.17.5" 1966 | } 1967 | }, 1968 | "strip-ansi": { 1969 | "version": "5.2.0", 1970 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1971 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1972 | "dev": true, 1973 | "requires": { 1974 | "ansi-regex": "^4.1.0" 1975 | }, 1976 | "dependencies": { 1977 | "ansi-regex": { 1978 | "version": "4.1.0", 1979 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1980 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1981 | "dev": true 1982 | } 1983 | } 1984 | }, 1985 | "strip-json-comments": { 1986 | "version": "3.1.1", 1987 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1988 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1989 | "dev": true 1990 | }, 1991 | "supports-color": { 1992 | "version": "5.5.0", 1993 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1994 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1995 | "dev": true, 1996 | "requires": { 1997 | "has-flag": "^3.0.0" 1998 | } 1999 | }, 2000 | "table": { 2001 | "version": "5.4.6", 2002 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 2003 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 2004 | "dev": true, 2005 | "requires": { 2006 | "ajv": "^6.10.2", 2007 | "lodash": "^4.17.14", 2008 | "slice-ansi": "^2.1.0", 2009 | "string-width": "^3.0.0" 2010 | }, 2011 | "dependencies": { 2012 | "emoji-regex": { 2013 | "version": "7.0.3", 2014 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2015 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2016 | "dev": true 2017 | }, 2018 | "is-fullwidth-code-point": { 2019 | "version": "2.0.0", 2020 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2021 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2022 | "dev": true 2023 | }, 2024 | "string-width": { 2025 | "version": "3.1.0", 2026 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2027 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2028 | "dev": true, 2029 | "requires": { 2030 | "emoji-regex": "^7.0.1", 2031 | "is-fullwidth-code-point": "^2.0.0", 2032 | "strip-ansi": "^5.1.0" 2033 | } 2034 | } 2035 | } 2036 | }, 2037 | "text-table": { 2038 | "version": "0.2.0", 2039 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2040 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2041 | "dev": true 2042 | }, 2043 | "through": { 2044 | "version": "2.3.8", 2045 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2046 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2047 | "dev": true 2048 | }, 2049 | "tmp": { 2050 | "version": "0.0.33", 2051 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2052 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2053 | "dev": true, 2054 | "requires": { 2055 | "os-tmpdir": "~1.0.2" 2056 | } 2057 | }, 2058 | "to-regex-range": { 2059 | "version": "5.0.1", 2060 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2061 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2062 | "dev": true, 2063 | "requires": { 2064 | "is-number": "^7.0.0" 2065 | } 2066 | }, 2067 | "tough-cookie": { 2068 | "version": "2.5.0", 2069 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 2070 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 2071 | "requires": { 2072 | "psl": "^1.1.28", 2073 | "punycode": "^2.1.1" 2074 | } 2075 | }, 2076 | "tslib": { 2077 | "version": "1.13.0", 2078 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 2079 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", 2080 | "dev": true 2081 | }, 2082 | "tsutils": { 2083 | "version": "3.17.1", 2084 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", 2085 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", 2086 | "dev": true, 2087 | "requires": { 2088 | "tslib": "^1.8.1" 2089 | } 2090 | }, 2091 | "tunnel-agent": { 2092 | "version": "0.6.0", 2093 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2094 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2095 | "requires": { 2096 | "safe-buffer": "^5.0.1" 2097 | } 2098 | }, 2099 | "tweetnacl": { 2100 | "version": "0.14.5", 2101 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 2102 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 2103 | }, 2104 | "type-check": { 2105 | "version": "0.3.2", 2106 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2107 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2108 | "dev": true, 2109 | "requires": { 2110 | "prelude-ls": "~1.1.2" 2111 | } 2112 | }, 2113 | "type-fest": { 2114 | "version": "0.8.1", 2115 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 2116 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 2117 | "dev": true 2118 | }, 2119 | "typescript": { 2120 | "version": "3.9.7", 2121 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", 2122 | "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", 2123 | "dev": true 2124 | }, 2125 | "universalify": { 2126 | "version": "1.0.0", 2127 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", 2128 | "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" 2129 | }, 2130 | "uri-js": { 2131 | "version": "4.2.2", 2132 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 2133 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 2134 | "requires": { 2135 | "punycode": "^2.1.0" 2136 | } 2137 | }, 2138 | "uuid": { 2139 | "version": "3.4.0", 2140 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 2141 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 2142 | }, 2143 | "v8-compile-cache": { 2144 | "version": "2.1.1", 2145 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", 2146 | "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", 2147 | "dev": true 2148 | }, 2149 | "verror": { 2150 | "version": "1.10.0", 2151 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 2152 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 2153 | "requires": { 2154 | "assert-plus": "^1.0.0", 2155 | "core-util-is": "1.0.2", 2156 | "extsprintf": "^1.2.0" 2157 | } 2158 | }, 2159 | "vscode-test": { 2160 | "version": "1.4.0", 2161 | "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", 2162 | "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", 2163 | "dev": true, 2164 | "requires": { 2165 | "http-proxy-agent": "^2.1.0", 2166 | "https-proxy-agent": "^2.2.4", 2167 | "rimraf": "^2.6.3" 2168 | } 2169 | }, 2170 | "which": { 2171 | "version": "1.3.1", 2172 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2173 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2174 | "dev": true, 2175 | "requires": { 2176 | "isexe": "^2.0.0" 2177 | } 2178 | }, 2179 | "which-module": { 2180 | "version": "2.0.0", 2181 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 2182 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 2183 | "dev": true 2184 | }, 2185 | "wide-align": { 2186 | "version": "1.1.3", 2187 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 2188 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 2189 | "dev": true, 2190 | "requires": { 2191 | "string-width": "^1.0.2 || 2" 2192 | }, 2193 | "dependencies": { 2194 | "ansi-regex": { 2195 | "version": "3.0.0", 2196 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 2197 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 2198 | "dev": true 2199 | }, 2200 | "is-fullwidth-code-point": { 2201 | "version": "2.0.0", 2202 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2203 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2204 | "dev": true 2205 | }, 2206 | "string-width": { 2207 | "version": "2.1.1", 2208 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 2209 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 2210 | "dev": true, 2211 | "requires": { 2212 | "is-fullwidth-code-point": "^2.0.0", 2213 | "strip-ansi": "^4.0.0" 2214 | } 2215 | }, 2216 | "strip-ansi": { 2217 | "version": "4.0.0", 2218 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 2219 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 2220 | "dev": true, 2221 | "requires": { 2222 | "ansi-regex": "^3.0.0" 2223 | } 2224 | } 2225 | } 2226 | }, 2227 | "word-wrap": { 2228 | "version": "1.2.3", 2229 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2230 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2231 | "dev": true 2232 | }, 2233 | "wrap-ansi": { 2234 | "version": "5.1.0", 2235 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 2236 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 2237 | "dev": true, 2238 | "requires": { 2239 | "ansi-styles": "^3.2.0", 2240 | "string-width": "^3.0.0", 2241 | "strip-ansi": "^5.0.0" 2242 | }, 2243 | "dependencies": { 2244 | "emoji-regex": { 2245 | "version": "7.0.3", 2246 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2247 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2248 | "dev": true 2249 | }, 2250 | "is-fullwidth-code-point": { 2251 | "version": "2.0.0", 2252 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2253 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2254 | "dev": true 2255 | }, 2256 | "string-width": { 2257 | "version": "3.1.0", 2258 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2259 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2260 | "dev": true, 2261 | "requires": { 2262 | "emoji-regex": "^7.0.1", 2263 | "is-fullwidth-code-point": "^2.0.0", 2264 | "strip-ansi": "^5.1.0" 2265 | } 2266 | } 2267 | } 2268 | }, 2269 | "wrappy": { 2270 | "version": "1.0.2", 2271 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2272 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 2273 | }, 2274 | "write": { 2275 | "version": "1.0.3", 2276 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 2277 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 2278 | "dev": true, 2279 | "requires": { 2280 | "mkdirp": "^0.5.1" 2281 | } 2282 | }, 2283 | "y18n": { 2284 | "version": "4.0.1", 2285 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", 2286 | "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", 2287 | "dev": true 2288 | }, 2289 | "yargs": { 2290 | "version": "13.3.2", 2291 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 2292 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 2293 | "dev": true, 2294 | "requires": { 2295 | "cliui": "^5.0.0", 2296 | "find-up": "^3.0.0", 2297 | "get-caller-file": "^2.0.1", 2298 | "require-directory": "^2.1.1", 2299 | "require-main-filename": "^2.0.0", 2300 | "set-blocking": "^2.0.0", 2301 | "string-width": "^3.0.0", 2302 | "which-module": "^2.0.0", 2303 | "y18n": "^4.0.0", 2304 | "yargs-parser": "^13.1.2" 2305 | }, 2306 | "dependencies": { 2307 | "emoji-regex": { 2308 | "version": "7.0.3", 2309 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2310 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2311 | "dev": true 2312 | }, 2313 | "is-fullwidth-code-point": { 2314 | "version": "2.0.0", 2315 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2316 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2317 | "dev": true 2318 | }, 2319 | "string-width": { 2320 | "version": "3.1.0", 2321 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2322 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2323 | "dev": true, 2324 | "requires": { 2325 | "emoji-regex": "^7.0.1", 2326 | "is-fullwidth-code-point": "^2.0.0", 2327 | "strip-ansi": "^5.1.0" 2328 | } 2329 | } 2330 | } 2331 | }, 2332 | "yargs-parser": { 2333 | "version": "13.1.2", 2334 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 2335 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 2336 | "dev": true, 2337 | "requires": { 2338 | "camelcase": "^5.0.0", 2339 | "decamelize": "^1.2.0" 2340 | } 2341 | }, 2342 | "yargs-unparser": { 2343 | "version": "1.6.0", 2344 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", 2345 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", 2346 | "dev": true, 2347 | "requires": { 2348 | "flat": "^4.1.0", 2349 | "lodash": "^4.17.15", 2350 | "yargs": "^13.3.0" 2351 | } 2352 | } 2353 | } 2354 | } 2355 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-leetcode-cpp-debug", 3 | "displayName": "LeetCode Debugger for C++", 4 | "description": "Debug support for LeetCode with C++", 5 | "version": "0.0.9", 6 | "author": "Xavier Cai", 7 | "publisher": "XavierCai", 8 | "license": "MIT", 9 | "icon": "resources/imgs/icon.png", 10 | "engines": { 11 | "vscode": "^1.43.0" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/xavier-cai/vscode-leetcode-cpp-debug" 16 | }, 17 | "homepage": "https://github.com/xavier-cai/vscode-leetcode-cpp-debug/blob/master/README.md", 18 | "preview": true, 19 | "categories": [ 20 | "Other" 21 | ], 22 | "keywords": [ 23 | "leetcode", 24 | "cpp", 25 | "debug" 26 | ], 27 | "activationEvents": [ 28 | "onCommand:leetcode-cpp-debugger.debug" 29 | ], 30 | "main": "./out/extension.js", 31 | "contributes": { 32 | "commands": [ 33 | { 34 | "command": "leetcode-cpp-debugger.debug", 35 | "title": "LeetCode Debugger: Start Debugging" 36 | } 37 | ], 38 | "configuration": [ 39 | { 40 | "title": "LeetCode Cpp Debugger", 41 | "properties": { 42 | "leetcode-cpp-debugger.source": { 43 | "type": "string", 44 | "enum": [ 45 | "[online]leetcode.com", 46 | "[online]leetcode-cn.com", 47 | "[offline]local" 48 | ], 49 | "scope": "application", 50 | "description": "Source of code template for generating debugging code.", 51 | "default": "[online]leetcode.com" 52 | }, 53 | "leetcode-cpp-debugger.deleteTemporaryContents": { 54 | "type": "boolean", 55 | "default": true, 56 | "scope": "application", 57 | "description": "Delete temporary codes and files after debugging." 58 | }, 59 | "leetcode-cpp-debugger.idMatchPattern": { 60 | "type": "string", 61 | "scope": "application", 62 | "description": "Regular expression for capturing problem ID when fetching problem online.", 63 | "default": "(\\d+).*" 64 | }, 65 | "leetcode-cpp-debugger.outputFileEncoding": { 66 | "type": "string", 67 | "enum": [ 68 | "utf8", 69 | "gbk" 70 | ], 71 | "scope": "application", 72 | "description": "Encoding of temporary code files", 73 | "default": "utf8" 74 | } 75 | } 76 | } 77 | ] 78 | }, 79 | "scripts": { 80 | "vscode:prepublish": "npm run compile", 81 | "compile": "tsc -p ./", 82 | "lint": "eslint src --ext ts", 83 | "watch": "tsc -watch -p ./", 84 | "pretest": "npm run compile && npm run lint", 85 | "test": "node ./out/test/runTest.js" 86 | }, 87 | "devDependencies": { 88 | "minimist": ">=0.2.1", 89 | "@types/glob": "^7.1.1", 90 | "@types/mocha": "^7.0.1", 91 | "@types/node": "^12.11.7", 92 | "@types/vscode": "^1.43.0", 93 | "eslint": "^6.8.0", 94 | "@typescript-eslint/parser": "^2.18.0", 95 | "@typescript-eslint/eslint-plugin": "^2.18.0", 96 | "mocha": "^7.0.1", 97 | "typescript": "^3.7.5", 98 | "vscode-test": "^1.3.0", 99 | "@types/fs-extra": "5.0.0", 100 | "@types/request": "^2.48.4" 101 | }, 102 | "dependencies": { 103 | "fs-extra": "^9.0.0", 104 | "glob": "^7.1.6", 105 | "iconv-lite": "^0.5.1", 106 | "request": "^2.88.2" 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-convert.h: -------------------------------------------------------------------------------- 1 | #ifndef LEETCODE_CONVERT 2 | #define LEETCODE_CONVERT 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "leetcode-json.h" 12 | 13 | namespace lc { 14 | 15 | namespace conv { 16 | 17 | struct ConvertException : public std::exception { 18 | public: 19 | ConvertException(const json::Json& obj, const std::string& info = ""); 20 | const json::Json& GetJson() const; 21 | const char* what() const throw (); 22 | 23 | private: 24 | json::Json obj_; 25 | std::string info_; 26 | }; // struct ConvertException 27 | 28 | ConvertException::ConvertException(const json::Json& obj, const std::string& info) : 29 | obj_(obj), 30 | info_("Convert error. ") 31 | { 32 | this->info_ += info; 33 | } 34 | 35 | const json::Json& ConvertException::GetJson() const { 36 | return this->obj_; 37 | } 38 | 39 | const char* ConvertException::what() const throw () { 40 | return this->info_.c_str(); 41 | } 42 | 43 | 44 | 45 | //common template 46 | template ::value> 47 | struct Convert { 48 | static void FromJson(_T& v, const json::Json& js) { 49 | throw ConvertException(js, std::string("Conversion from JSON to ") + json::_get_name<_T>() + " not implemented."); 50 | } 51 | 52 | static json::Json ToJson(const _T& v) { 53 | throw ConvertException(json::Json(), std::string("Conversion from ") + json::_get_name<_T>() + " to JSON not implemented."); 54 | } 55 | }; 56 | 57 | //object specialization 58 | template 59 | struct Convert<_T, true> { 60 | #define ASSERT_HINT "Hey, this is not a json::Object, right?" 61 | static void FromJson(_T& v, const json::Json& js) { 62 | static_assert(json::_is_object<_T>::value, ASSERT_HINT); 63 | v = *js.GetObject<_T>(); 64 | } 65 | 66 | static json::Json ToJson(const _T& v) { 67 | static_assert(json::_is_object<_T>::value, ASSERT_HINT); 68 | return v; 69 | } 70 | #undef ASSERT_HINT 71 | }; 72 | 73 | //reference type specialization 74 | template 75 | struct Convert<_T&, true> { 76 | static void FromJson(_T& v, const json::Json& js) { 77 | Convert<_T>::FromJson(v, js); 78 | } 79 | 80 | static void FromJson(_T& v, json::Json&& js) { 81 | Convert<_T>::FromJson(v, std::move(js)); 82 | } 83 | 84 | static json::Json ToJson(const _T& v) { 85 | return Convert<_T>::ToJson(v); 86 | } 87 | 88 | static json::Json ToJson(_T&& v) { 89 | return Convert<_T>::ToJson(std::move(v)); 90 | } 91 | }; 92 | 93 | template 94 | struct Convert<_T&, false> { 95 | static void FromJson(_T& v, const json::Json& js) { 96 | Convert<_T>::FromJson(v, js); 97 | } 98 | 99 | static void FromJson(_T& v, json::Json&& js) { 100 | Convert<_T>::FromJson(v, std::move(js)); 101 | } 102 | 103 | static json::Json ToJson(const _T& v) { 104 | return Convert<_T>::ToJson(v); 105 | } 106 | 107 | static json::Json ToJson(_T&& v) { 108 | return Convert<_T>::ToJson(std::move(v)); 109 | } 110 | }; 111 | 112 | template <> 113 | struct Convert { 114 | static void FromJson(json::Json& v, const json::Json& js) { 115 | v = js; 116 | } 117 | 118 | static void FromJson(json::Json& v, json::Json&& js) { 119 | v.Swap(js); 120 | } 121 | 122 | static json::Json ToJson(const json::Json& v) { 123 | return v; 124 | } 125 | 126 | static json::Json ToJson(json::Json&& v) { 127 | return std::move(v); 128 | } 129 | }; 130 | 131 | 132 | 133 | #define QUICK_THROW(js, type) throw ConvertException(js, std::string("Convert from JSON to ") + json::_get_name() + " failed.") 134 | 135 | template <> 136 | struct Convert { 137 | static void FromJson(bool& v, const json::Json& js) { 138 | auto obj = js.GetObject(); 139 | if (obj == NULL) QUICK_THROW(js, bool); 140 | v = obj->GetValue(); 141 | } 142 | static json::Json ToJson(const bool& v) { 143 | return json::JBoolean(v); 144 | } 145 | }; 146 | 147 | 148 | template <> 149 | struct Convert { 150 | static void FromJson(int& v, const json::Json& js) { 151 | auto obj = js.GetObject(); 152 | if (obj == NULL || !obj->IsInteger()) QUICK_THROW(js, int); 153 | v = obj->GetInteger(); 154 | } 155 | static json::Json ToJson(const int& v) { 156 | return json::JNumber((long long)v); 157 | } 158 | }; 159 | 160 | 161 | template <> 162 | struct Convert { 163 | static void FromJson(long long& v, const json::Json& js) { 164 | auto obj = js.GetObject(); 165 | if (obj == NULL || !obj->IsInteger()) QUICK_THROW(js, long long); 166 | v = obj->GetInteger(); 167 | } 168 | static json::Json ToJson(const long long& v) { 169 | return json::JNumber(v); 170 | } 171 | }; 172 | 173 | 174 | template <> 175 | struct Convert { 176 | static void FromJson(double& v, const json::Json& js) { 177 | auto obj = js.GetObject(); 178 | if (obj == NULL) QUICK_THROW(js, double); 179 | v = obj->GetNumber(); 180 | } 181 | 182 | static json::Json ToJson(const double& v) { 183 | return json::JNumber(v); 184 | } 185 | }; 186 | 187 | 188 | 189 | template <> 190 | struct Convert { 191 | static void FromJson(std::string& v, const json::Json& js) { 192 | auto obj = js.GetObject(); 193 | if (obj == NULL) QUICK_THROW(js, std::string); 194 | v = obj->GetString(); 195 | } 196 | 197 | static void FromJson(std::string& v, json::Json&& js) { 198 | auto obj = js.GetObject(); 199 | if (obj == NULL) QUICK_THROW(js, std::string); 200 | v.swap(obj->GetString()); 201 | } 202 | 203 | static json::Json ToJson(const std::string& v) { 204 | return json::Json::Create(v); 205 | } 206 | 207 | static json::Json ToJson(std::string&& v) { 208 | return json::Json::Create(std::move(v)); 209 | } 210 | }; 211 | 212 | 213 | template <> 214 | struct Convert { 215 | static void FromJson(char& v, const json::Json& js) { 216 | auto& str = js.GetObject()->GetString(); 217 | if (str.size() != 1) QUICK_THROW(js, char); 218 | v = str.front(); 219 | } 220 | 221 | static json::Json ToJson(const char& v) { 222 | return json::Json::Create(std::string(1, v)); 223 | } 224 | }; 225 | 226 | 227 | template 228 | struct Convert, false> { 229 | static void FromJson(std::vector<_VAL>& v, const json::Json& js) { 230 | auto obj = js.GetObject(); 231 | if (obj == NULL) QUICK_THROW(js, std::vector<_VAL>); 232 | int n = obj->GetArray().size(); 233 | v.resize(n); 234 | for (int i = 0; i < n; ++i) { 235 | Convert<_VAL>::FromJson(v[i], obj->GetArray()[i]); 236 | } 237 | } 238 | 239 | static json::Json ToJson(const std::vector<_VAL>& v) { 240 | json::Json js = json::Json::Create(); 241 | auto obj = js.GetObject(); 242 | for (auto& sub : v) { 243 | obj->GetArray().emplace_back(Convert<_VAL>::ToJson(sub)); 244 | } 245 | return js; 246 | } 247 | }; 248 | 249 | 250 | 251 | template 252 | struct Convert, false> { 253 | static void FromJson(std::map<_KEY, _VAL>& v, const json::Json& js) { 254 | auto obj = js.GetObject(); 255 | using type = std::map<_KEY, _VAL>; 256 | if (obj == NULL) QUICK_THROW(js, type); 257 | obj->ForEach([&v](const json::Json& key, const json::Json& val) { 258 | _KEY vark; 259 | _VAL varv; 260 | Convert<_KEY>::FromJson(vark, key); 261 | Convert<_VAL>::FromJson(varv, val); 262 | v.emplace(std::move(vark), std::move(varv)); 263 | }); 264 | } 265 | 266 | static json::Json ToJson(const std::map<_KEY, _VAL>& v) { 267 | json::Json js = json::Json::Create(); 268 | auto obj = js.GetObject(); 269 | for (auto& sub : v) { 270 | obj->Add( 271 | Convert<_KEY>::ToJson(sub.first), 272 | Convert<_VAL>::ToJson(sub.second) 273 | ); 274 | } 275 | return js; 276 | } 277 | }; 278 | 279 | 280 | 281 | template 282 | struct Convert, false> { 283 | static void FromJson(std::tuple<_ARGS...>& v, const json::Json& js) { 284 | auto obj = js.GetObject(); 285 | int n = std::tuple_size>::value; 286 | if (obj == NULL || n != obj->GetArray().size()) QUICK_THROW(js, std::tuple<_ARGS...>); 287 | Impl, sizeof...(_ARGS)>::DoFromJson(v, *obj); 288 | } 289 | 290 | static json::Json ToJson(const std::tuple<_ARGS...>& v) { 291 | json::Json js = json::Json::Create(); 292 | auto obj = js.GetObject(); 293 | Impl, sizeof...(_ARGS)>::DoToJson(v, *obj); 294 | return js; 295 | } 296 | 297 | // tuple implementations 298 | private: 299 | template 300 | struct Impl { 301 | static void DoFromJson(_T& v, json::JArray& obj) { 302 | Impl<_T, N-1>::DoFromJson(v, obj); 303 | using SubType = typename std::tuple_element::type; 304 | Convert::FromJson(std::get(v), obj.GetArray()[N-1]); 305 | } 306 | 307 | static void DoToJson(const _T& v, json::JArray& obj) { 308 | Impl<_T, N-1>::DoToJson(v, obj); 309 | using SubType = typename std::tuple_element::type; 310 | obj.GetArray().emplace_back(Convert::ToJson(std::get(v))); 311 | } 312 | }; 313 | 314 | template 315 | struct Impl<_T, 1> { 316 | static void DoFromJson(_T& v, json::JArray& obj) { 317 | using SubType = typename std::tuple_element<0, _T>::type; 318 | Convert::FromJson(std::get<0>(v), obj.GetArray()[0]); 319 | } 320 | 321 | static void DoToJson(const _T& v, json::JArray& obj) { 322 | using SubType = typename std::tuple_element<0, _T>::type; 323 | obj.GetArray().emplace_back(Convert::ToJson(std::get<0>(v))); 324 | } 325 | }; 326 | }; 327 | 328 | #undef QUICK_THROW 329 | 330 | 331 | 332 | template 333 | void FromJson(_T& v, const json::Json& js) { 334 | Convert<_T>::FromJson(v, js); 335 | } 336 | 337 | template 338 | void FromJson(_T& v, json::Json&& js) { 339 | Convert<_T>::FromJson(v, std::move(js)); 340 | } 341 | 342 | template 343 | _T FromJson(const json::Json& js) { 344 | _T v; 345 | FromJson(v, js); 346 | return v; 347 | } 348 | 349 | template 350 | _T FromJson(json::Json&& js) { 351 | _T v; 352 | FromJson(v, std::move(js)); 353 | return v; 354 | } 355 | 356 | template 357 | void FromJson(_T& v, const std::string& raw) { 358 | Convert<_T>::FromJson(v, json::Json(raw)); 359 | } 360 | 361 | template 362 | _T FromJson(const std::string& raw) { 363 | _T v; 364 | FromJson(v, json::Json(raw)); 365 | return v; 366 | } 367 | 368 | template 369 | json::Json ToJson(const _T& v) { 370 | return Convert<_T>::ToJson(v); 371 | } 372 | 373 | template 374 | json::Json ToJson(_T&& v) { 375 | return Convert<_T>::ToJson(std::move(v)); 376 | } 377 | 378 | } // namespace conv 379 | 380 | } // namespace lc 381 | 382 | #endif -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-definition.h: -------------------------------------------------------------------------------- 1 | #ifndef LEETCODE_DEFINITION 2 | #define LEETCODE_DEFINITION 3 | 4 | #include "leetcode-types.h" 5 | 6 | namespace lc { 7 | 8 | class ListNode; 9 | class TreeNode; 10 | 11 | } // namespace lc 12 | 13 | //#include 14 | 15 | //#include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | 77 | #if __cplusplus >= 201402L 78 | #include 79 | #endif 80 | 81 | using namespace std; 82 | using namespace lc; 83 | 84 | #endif -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-entry.h: -------------------------------------------------------------------------------- 1 | #ifndef LEETCODE_ENTRY 2 | #define LEETCODE_ENTRY 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "leetcode-handler.h" 10 | 11 | namespace lc { 12 | 13 | struct EntryException : public std::exception { 14 | public: 15 | EntryException(const std::string& raw, int line, int pos, const std::string& info); 16 | const std::string& GetRaw() const; 17 | int GetLine() const; 18 | int GetPosition() const; 19 | const char* what() const throw (); 20 | 21 | private: 22 | std::string raw_; 23 | int line_; 24 | int pos_; 25 | std::string info_; 26 | }; // struct EntryException 27 | 28 | EntryException::EntryException(const std::string& raw, int line, int pos, const std::string& info) : 29 | raw_(raw), 30 | line_(line), 31 | pos_(pos), 32 | info_("Entry error. ") 33 | { 34 | this->info_ += info; 35 | } 36 | 37 | const std::string& EntryException::GetRaw() const { 38 | return this->raw_; 39 | } 40 | 41 | int EntryException::GetLine() const { 42 | return this->line_ ; 43 | } 44 | 45 | int EntryException::GetPosition() const { 46 | return this->pos_ ; 47 | } 48 | 49 | const char* EntryException::what() const throw () { 50 | return this->info_.c_str(); 51 | } 52 | 53 | 54 | 55 | 56 | class Entry { 57 | public: 58 | static void Run(io::SI& in, io::MO& out); 59 | 60 | private: 61 | static void RunAlgorithm(io::SI& in, io::MO& out); 62 | static void RunSystemDesign(io::SI& in, io::MO& out); 63 | }; 64 | 65 | void Entry::Run(io::SI& in, io::MO& out) { 66 | while (!in.Eof()) { 67 | int startLine = 0; 68 | try { 69 | startLine = in.GetLineCount() + 1; 70 | #ifdef INTERACTION 71 | in.Input(INTERACTION); 72 | #endif 73 | #ifdef SYSTEM_DESIGN 74 | RunSystemDesign(in, out); 75 | #else 76 | RunAlgorithm(in, out); 77 | #endif 78 | } 79 | catch (...) { 80 | if (in.Eof() && startLine == in.GetLineCount()) { 81 | bool blank = true; 82 | for (auto& c : in.GetRaw()) { 83 | if (c != ' ') { 84 | blank = false; 85 | break; 86 | } 87 | } 88 | if (blank) break; 89 | } 90 | throw; 91 | } 92 | 93 | try { 94 | mem::MemoryCleaner::Clean(); 95 | } 96 | catch (...) { 97 | throw std::string("Please only use pointer of [TreeNode] & [ListNode] and do not use [delete]."); 98 | } 99 | } 100 | } 101 | 102 | void Entry::RunAlgorithm(io::SI& in, io::MO& out) { 103 | Handler handler(json::Create()); 104 | handler.Handle(in, out); 105 | } 106 | 107 | void Entry::RunSystemDesign(io::SI& in, io::MO& out) { 108 | json::Json fobj(in.GetLine()); 109 | int fline = in.GetLineCount(); 110 | std::string fraw = in.GetRaw(); 111 | auto quick_throw = [&fline, &fraw, &fobj](int idx, const std::string& info) { 112 | throw EntryException(fraw, fline, fobj.GetObject()->GetArray()[idx].GetObject()->GetPosistion(), info); 113 | }; 114 | 115 | //get functions 116 | std::vector functions; 117 | conv::FromJson(functions, fobj); 118 | int n = functions.size(); 119 | 120 | //get args 121 | json::Json obj(in.GetLine()); 122 | auto args = obj.GetObject(); 123 | if (args == NULL) throw conv::ConvertException(obj, "Input format error."); 124 | if (n != args->GetArray().size()) throw EntryException(in.GetRaw(), in.GetLineCount(), args->GetPosistion(), "Number of functions and arguments not matched."); 125 | 126 | //call functions 127 | json::Json retjs = json::Create(); 128 | json::JArray& ret = *retjs.GetObject(); 129 | if (n > 0) { 130 | if (functions.front() != Handler::GetClassName()) { 131 | quick_throw(0, "The first function need be the constructor."); 132 | } 133 | Handler handler(args->GetArray().front()); 134 | ret.GetArray().emplace_back(json::Create()); 135 | for (int i = 1; i < n; ++i) { 136 | try { 137 | ret.GetArray().emplace_back(handler.Handle(args->GetArray()[i], functions[i])); 138 | } 139 | catch (std::string& e) { 140 | quick_throw(i, e); 141 | } 142 | } 143 | } 144 | out << ret << std::endl; 145 | } 146 | 147 | } // namespace lc 148 | 149 | #endif // LEETCODE_ENTRY -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-io.h: -------------------------------------------------------------------------------- 1 | #ifndef LEETCODE_IO 2 | #define LEETCODE_IO 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #ifdef _WIN32 12 | #include 13 | #else 14 | #include 15 | #endif 16 | 17 | #include "leetcode-convert.h" 18 | #include "leetcode-types.h" 19 | 20 | namespace lc { 21 | 22 | namespace conv { 23 | 24 | template <> 25 | struct Convert { 26 | static void FromJson(ListNode* &v, const json::Json& js) { 27 | auto obj = js.GetObject(); 28 | if (obj == NULL) throw ConvertException(js, "Convert failed. ListNode*."); 29 | int n = obj->GetArray().size(); 30 | if (n <= 0) { v = NULL; return; } 31 | v = new ListNode(conv::FromJson(obj->GetArray().front())); 32 | ListNode* current = v; 33 | for (int i = 1; i < n; ++i) { 34 | current->next = new ListNode(conv::FromJson(obj->GetArray()[i])); 35 | current = current->next; 36 | } 37 | } 38 | 39 | static json::Json ToJson(ListNode* const &v) { 40 | json::Json js = json::Json::Create(); 41 | auto obj = js.GetObject(); 42 | ListNode* current = v; 43 | while (current != NULL) { 44 | obj->GetArray().emplace_back(conv::ToJson(current->val)); 45 | current = current->next; 46 | } 47 | return js; 48 | } 49 | }; 50 | 51 | template <> 52 | struct Convert { 53 | static void FromJson(TreeNode* &v, const json::Json& js) { 54 | auto obj = js.GetObject(); 55 | if (obj == NULL) throw ConvertException(js, "Convert failed. TreeNode*."); 56 | int n = obj->GetArray().size(); 57 | if (n <= 0) { v = NULL; return; } 58 | auto read = [&obj, &n](int idx) -> TreeNode* { 59 | if (idx >= n) return NULL; 60 | auto& js = obj->GetArray()[idx]; 61 | if (js.Is()) return NULL; 62 | return new TreeNode(conv::FromJson(js)); 63 | }; 64 | v = read(0); 65 | std::queue Q; 66 | if (v != NULL) Q.push(v); 67 | for (int i = 1; i < n && !Q.empty();) { 68 | TreeNode* current = Q.front(); Q.pop(); 69 | if ((current->left = read(i++)) != NULL) Q.push(current->left); 70 | if ((current->right = read(i++)) != NULL) Q.push(current->right); 71 | } 72 | } 73 | 74 | static json::Json ToJson(TreeNode* const &v) { 75 | json::Json js = json::Create(); 76 | auto obj = js.GetObject(); 77 | std::queue Q; 78 | if (v != NULL) Q.push(v); 79 | int nullCount = 0; 80 | while (!Q.empty() && nullCount < Q.size()) { 81 | TreeNode* current = Q.front(); Q.pop(); 82 | if (current == NULL) { 83 | obj->GetArray().emplace_back(json::JNull()); 84 | nullCount -= 1; 85 | continue; 86 | } 87 | obj->GetArray().emplace_back(conv::ToJson(current->val)); 88 | Q.push(current->left); 89 | Q.push(current->right); 90 | if (current->left == NULL) nullCount += 1; 91 | if (current->right == NULL) nullCount += 1; 92 | } 93 | return js; 94 | } 95 | }; 96 | 97 | } // namespace conv 98 | 99 | namespace io { 100 | 101 | std::string GetCurrentDirectory() { 102 | char* buffer = getcwd(NULL, 0); 103 | if (buffer == NULL) return ""; 104 | std::string cwd(buffer); 105 | free(buffer); 106 | if (cwd.length() <= 0 || cwd.back() == '/' || cwd.back() == '\\') return cwd; 107 | if (cwd.find('\\') != std::string::npos) return cwd + '\\'; 108 | return cwd + '/'; 109 | } 110 | 111 | class SI { 112 | public: 113 | SI(const std::string& file); 114 | SI(std::istream& is); 115 | ~SI(); 116 | 117 | bool Eof() const; 118 | int GetLineCount() const; 119 | const std::string& GetRaw() const; 120 | json::Json GetLine(); 121 | 122 | template 123 | SI& operator >> (_T& v) { 124 | conv::FromJson(v, GetLine()); 125 | return *this; 126 | } 127 | SI& operator >> (std::function cb) { 128 | cb(); 129 | return *this; 130 | } 131 | SI& operator >> (void (*cb)()) { 132 | cb(); 133 | return *this; 134 | } 135 | 136 | template 137 | void Input(_T& v, _REST& ...r) { 138 | *this >> v; 139 | Input(r...); 140 | } 141 | template 142 | void Input(_T& v) { 143 | *this >> v; 144 | } 145 | 146 | private: 147 | SI(const SI&) = delete; 148 | const SI& operator = (const SI&) = delete; 149 | 150 | std::istream* is_; 151 | bool fromFile_; 152 | int line_; 153 | std::string raw_; 154 | }; // class SI 155 | 156 | SI::SI(const std::string& file) : 157 | is_(NULL), 158 | fromFile_(true), 159 | line_(0) 160 | { 161 | std::cout << "Input from file \"" << file << "\"" << std::endl; 162 | auto ifs = new std::ifstream(file); 163 | if (!ifs->is_open()) { 164 | delete ifs; 165 | throw std::string("Can not open the input file: ") + GetCurrentDirectory() + file; 166 | } 167 | this->is_ = ifs; 168 | } 169 | 170 | SI::SI(std::istream& is) : 171 | is_(&is), 172 | fromFile_(false), 173 | line_(0) 174 | { 175 | std::cout << "Input from [std::cin]" << std::endl; 176 | } 177 | 178 | SI::~SI() { 179 | if (this->fromFile_ && this->is_ != NULL) { 180 | delete dynamic_cast(this->is_); 181 | } 182 | } 183 | 184 | bool SI::Eof() const { 185 | return this->is_->eof(); 186 | } 187 | 188 | int SI::GetLineCount() const { 189 | return this->line_; 190 | } 191 | 192 | const std::string& SI::GetRaw() const { 193 | return this->raw_; 194 | } 195 | 196 | json::Json SI::GetLine() { 197 | this->line_ += 1; 198 | std::getline(*this->is_, this->raw_); 199 | return json::Json(this->raw_); 200 | } 201 | 202 | 203 | 204 | class MO { 205 | public: 206 | template 207 | MO(_ARGS&& ...args) { 208 | this->Init(args...); 209 | } 210 | ~MO(); 211 | 212 | template 213 | MO& operator << (const _T& v) { 214 | auto js = conv::ToJson(v); 215 | std::stringstream ss; 216 | ss << js; 217 | std::string s = ss.str(); 218 | for (auto& os : this->oss_) *os << s; 219 | return *this; 220 | } 221 | MO& operator << (std::ostream& (*v)(std::ostream&)); 222 | 223 | private: 224 | MO(const MO&) = delete; 225 | const MO& operator = (const MO&) = delete; 226 | 227 | void InitOS(std::ostream& os); 228 | void InitOS(const std::string& fname); 229 | 230 | template 231 | void Init(_T&& arg, _REST&& ...r) { 232 | InitOS(arg); 233 | Init(r...); 234 | } 235 | 236 | template 237 | void Init(_T&& arg) { 238 | InitOS(arg); 239 | } 240 | 241 | std::list oss_; 242 | std::list ofs_; 243 | }; // class MO 244 | 245 | MO::~MO() { 246 | for (auto& os : this->oss_) os->flush(); 247 | for (auto& of : this->ofs_) of->close(), delete of; 248 | } 249 | 250 | void MO::InitOS(std::ostream& os) { 251 | this->oss_.push_back(&os); 252 | } 253 | 254 | void MO::InitOS(const std::string& fname) { 255 | auto ofs = new std::ofstream(fname); 256 | if (!ofs->is_open()) { 257 | delete ofs; 258 | throw std::string("Can not open the output file: ") + GetCurrentDirectory() + fname; 259 | } 260 | this->ofs_.push_back(ofs); 261 | this->oss_.push_back(ofs); 262 | } 263 | 264 | MO& MO::operator << (std::ostream& (*v)(std::ostream&)) { 265 | for (auto os : this->oss_) *os << v; 266 | return *this; 267 | } 268 | 269 | } // namespace io 270 | 271 | } // namespace lc 272 | 273 | #endif -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-json.h: -------------------------------------------------------------------------------- 1 | #ifndef LEETCODE_JSON_H 2 | #define LEETCODE_JSON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef __GNUC__ 17 | #include 18 | #include 19 | #endif 20 | 21 | #ifndef NULL 22 | #define NULL 0 23 | #endif 24 | 25 | namespace lc { 26 | 27 | namespace clone { 28 | 29 | class Base { 30 | public: 31 | virtual ~Base() {} 32 | virtual Base* DoClone() const = 0; 33 | 34 | protected: 35 | virtual void DoCopyTo(Base* clone) const {} 36 | }; // class Base 37 | 38 | template 39 | class Template : public _BASE { 40 | public: 41 | Base* DoClone() const override { 42 | if (dynamic_cast(this) == NULL) return NULL; 43 | if (dynamic_cast(this) == NULL) return NULL; 44 | const _THIS* me = dynamic_cast(this); 45 | _THIS* clone = new _THIS(*me); 46 | this->DoCopyTo(dynamic_cast(clone)); 47 | return dynamic_cast(clone); 48 | } 49 | 50 | _THIS* Clone() const { 51 | return dynamic_cast<_THIS*>(DoClone()); 52 | } 53 | 54 | protected: 55 | virtual void DoCopy(_THIS* clnoe) const {} 56 | virtual void DoCopyTo(Base* clone) const override { 57 | _BASE::DoCopyTo(clone); 58 | this->DoCopy(dynamic_cast<_THIS*>(clone)); 59 | } 60 | }; // class Template 61 | 62 | } // namespace clon 63 | 64 | namespace json { 65 | 66 | struct JsonMask { 67 | public: 68 | JsonMask(int mask); 69 | ~JsonMask(); 70 | JsonMask* Next(int mask); 71 | JsonMask* Set(int mask); 72 | int Mask() const; 73 | JsonMask* Next() const; 74 | 75 | private: 76 | int mask_; 77 | JsonMask* next_; 78 | }; // struct JsonMask 79 | 80 | JsonMask::JsonMask(int mask) : mask_(mask), next_(NULL) {} 81 | 82 | JsonMask::~JsonMask() { 83 | if (this->next_ != NULL) delete this->next_; 84 | } 85 | 86 | JsonMask* JsonMask::Next(int mask) { 87 | if (this->next_ == NULL) this->next_ = new JsonMask(mask); 88 | else this->next_->Set(mask); 89 | return this->next_; 90 | } 91 | 92 | JsonMask* JsonMask::Set(int mask) { 93 | this->mask_ = mask; 94 | return this; 95 | } 96 | 97 | int JsonMask::Mask() const { 98 | return this->mask_; 99 | } 100 | 101 | JsonMask* JsonMask::Next() const { 102 | return this->next_; 103 | } 104 | 105 | 106 | 107 | class Object : public clone::Base { 108 | public: 109 | virtual ~Object() {} 110 | 111 | template 112 | bool Is() const { 113 | return dynamic_cast(this) != NULL; 114 | } 115 | const std::string& GetName() const; 116 | int GetPosistion() const; 117 | void SetPosition(int pos); 118 | int Parse(const std::string& raw, int start = 0, JsonMask* mask = NULL); 119 | 120 | friend std::ostream& operator << (std::ostream& os, const Object& obj); 121 | 122 | protected: 123 | Object(); 124 | virtual const std::string& Name() const = 0; 125 | //return length 126 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) = 0; 127 | virtual void Print(std::ostream& os) const = 0; 128 | 129 | //return length 130 | int SkipSpaces(const std::string& raw, int start, bool error = true); 131 | static int SkipSpacesWithoutError(const std::string& raw, int start); 132 | 133 | private: 134 | int pos_; 135 | }; // class Object 136 | 137 | 138 | 139 | template 140 | struct _is_object : public std::is_base_of {}; 141 | 142 | template 143 | std::string _get_name() { 144 | std::string name(typeid(_T).name()); 145 | #ifdef __GNUC__ 146 | char* real = abi::__cxa_demangle(name.c_str(), NULL, NULL, NULL); 147 | name = std::string(real); 148 | free(real); 149 | #endif 150 | return name; 151 | } 152 | 153 | 154 | 155 | class ObjectManager { 156 | public: 157 | typedef std::function Constructor; 158 | typedef std::function Checker; 159 | struct Api { 160 | int mask; 161 | Constructor constructor; 162 | Checker checker; 163 | }; // struct ObjectApi 164 | 165 | template 166 | static void RegistObject(Checker checker, int id) { 167 | GetInstance().apis_[typeid(_T).hash_code()] = { 168 | 1 << id, 169 | []() { return new _T(); }, 170 | checker 171 | }; 172 | } 173 | 174 | template 175 | static const Api& GetApi() { 176 | auto find = GetInstance().apis_.find(typeid(_T).hash_code()); 177 | if (find == GetInstance().apis_.end()) throw std::string("Unregisted type [") + _get_name<_T>() + "]."; 178 | return find->second; 179 | } 180 | 181 | static void Until(std::function cb) { 182 | for (auto& ite : GetInstance().apis_) { 183 | if (cb(ite.second)) break; 184 | } 185 | } 186 | 187 | private: 188 | std::map apis_; 189 | 190 | ObjectManager() {} 191 | static ObjectManager& GetInstance(); 192 | }; // class JsonManager 193 | 194 | ObjectManager& ObjectManager::GetInstance() { 195 | static ObjectManager instance; 196 | return instance; 197 | } 198 | 199 | #define REGIST_JSON_OBJECT(type, checker, id) \ 200 | struct _##type##_ObjectRegister { \ 201 | _##type##_ObjectRegister() { \ 202 | static_assert(std::is_base_of::value, "Only json::Object can be registed."); \ 203 | json::ObjectManager::RegistObject(checker, id); \ 204 | } \ 205 | } _##type##_ObjectRegister_trigger_instance 206 | 207 | 208 | 209 | class Json { 210 | public: 211 | Json(); 212 | Json(const std::string& raw, int start = 0, JsonMask* mask = NULL, bool all = true); 213 | Json(const std::string& raw, int start, int& len, JsonMask* mask = NULL, bool all = true); 214 | Json(const Object& obj); 215 | Json(const Json& js); 216 | Json(Json&& js); 217 | Json& operator = (const Json& js); 218 | ~Json(); 219 | 220 | template 221 | static Json Create(_ARGS&&... args) { 222 | static_assert(_is_object<_T>::value, "Type need be Object."); 223 | Json js; 224 | js.obj_ = new _T(args...); 225 | return js; 226 | } 227 | 228 | template 229 | bool Is() const { 230 | return this->obj_ != NULL && this->obj_->Is<_T>(); 231 | } 232 | Object* GetObject() const; 233 | template 234 | _T* GetObject() const { return dynamic_cast<_T*>(this->obj_); } 235 | template 236 | static int GetMask() { 237 | return ObjectManager::GetApi<_T>().mask; 238 | } 239 | void Swap(Json& js); 240 | 241 | int Parse(const std::string& raw, int start = 0, JsonMask* mask = NULL, bool all = true); 242 | 243 | friend std::ostream& operator << (std::ostream& os, const Json& js); 244 | 245 | private: 246 | Object* obj_; 247 | }; // class Json 248 | 249 | struct JsonException : public std::exception { 250 | public: 251 | JsonException(const Json& obj, const std::string& raw, int pos, const std::string& info = ""); 252 | JsonException(const Json& obj, const std::string& info); 253 | const Json& GetJson() const; 254 | const std::string& GetRaw() const; 255 | int GetPosition() const; 256 | const char* what() const throw (); 257 | 258 | private: 259 | std::string info_; 260 | Json obj_; 261 | std::string raw_; 262 | int pos_; 263 | }; 264 | 265 | JsonException::JsonException(const Json& obj, const std::string& raw, int pos, const std::string& info) : 266 | info_("JSON parse error. "), 267 | obj_(obj), 268 | raw_(raw), 269 | pos_(pos) 270 | { 271 | this->info_ += info; 272 | } 273 | 274 | JsonException::JsonException(const Json& obj, const std::string& info) : 275 | info_("JSON parse error. "), 276 | obj_(obj), 277 | raw_(""), 278 | pos_(-1) 279 | { 280 | this->info_ += info; 281 | } 282 | 283 | const Json& JsonException::GetJson() const { 284 | return this->obj_; 285 | } 286 | 287 | const std::string& JsonException::GetRaw() const { 288 | return this->raw_; 289 | } 290 | 291 | int JsonException::GetPosition() const { 292 | return this->pos_; 293 | } 294 | 295 | const char* JsonException::what() const throw() { 296 | return this->info_.c_str(); 297 | } 298 | 299 | 300 | // implements after JsonException 301 | Object::Object() : pos_(-1) {} 302 | 303 | const std::string& Object::GetName() const { 304 | return this->Name(); 305 | } 306 | 307 | int Object::GetPosistion() const { 308 | return this->pos_; 309 | } 310 | 311 | void Object::SetPosition(int pos) { 312 | this->pos_ = pos; 313 | } 314 | 315 | int Object::Parse(const std::string& raw, int start, JsonMask* mask) { 316 | return this->DoParse(raw, start, mask); 317 | } 318 | 319 | int Object::SkipSpaces(const std::string& raw, int start, bool error) { 320 | int idx = start, n = raw.size(); 321 | while (idx < n && raw[idx] == ' ') ++idx; 322 | if (error && idx >= n) throw JsonException(*this, raw, idx); 323 | return idx - start; 324 | } 325 | 326 | int Object::SkipSpacesWithoutError(const std::string& raw, int start) { 327 | int idx = start, n = raw.size(); 328 | while (idx < n && raw[idx] == ' ') ++idx; 329 | return idx - start; 330 | } 331 | 332 | std::ostream& operator << (std::ostream& os, const Object& obj) { 333 | obj.Print(os); 334 | return os; 335 | } 336 | 337 | 338 | 339 | // implements after JsonException 340 | Json::Json() : obj_(NULL) {} 341 | 342 | Json::Json(const std::string& raw, int start, JsonMask* mask, bool all) : 343 | obj_(NULL) 344 | { 345 | this->Parse(raw, start, mask, all); 346 | } 347 | 348 | Json::Json(const std::string& raw, int start, int& len, JsonMask* mask, bool all) : 349 | obj_(NULL) 350 | { 351 | len = this->Parse(raw, start, mask, all); 352 | } 353 | 354 | Json::Json(const Object& obj) : obj_(dynamic_cast(obj.DoClone())) {} 355 | 356 | Json::Json(const Json& js) : obj_(NULL) { *this = js; } 357 | 358 | Json::Json(Json&& js) : obj_(NULL) { this->Swap(js); } 359 | 360 | Json& Json::operator = (const Json& js) { 361 | if (this->obj_ != NULL) delete this->obj_; 362 | if (js.GetObject() != NULL) this->obj_ = dynamic_cast(js.GetObject()->DoClone()); 363 | else this->obj_ = NULL; 364 | return *this; 365 | } 366 | 367 | Json::~Json() { 368 | if (this->obj_ != NULL) delete this->obj_; 369 | } 370 | 371 | Object* Json::GetObject() const { 372 | return this->obj_; 373 | } 374 | 375 | void Json::Swap(Json& js) { 376 | std::swap(this->obj_, js.obj_); 377 | } 378 | 379 | std::ostream& operator << (std::ostream& os, const Json& js) { 380 | os << *js.obj_; 381 | return os; 382 | } 383 | 384 | 385 | 386 | class JNull : public clone::Template { 387 | public: 388 | JNull(); 389 | 390 | static bool QuickCheck(const std::string& raw, int start); 391 | 392 | protected: 393 | virtual const std::string& Name() const override; 394 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) override; 395 | virtual void Print(std::ostream& os) const override; 396 | 397 | private: 398 | static const std::string text_; 399 | }; // class JNull 400 | 401 | REGIST_JSON_OBJECT(JNull, JNull::QuickCheck, 0); 402 | 403 | const std::string JNull::text_("null"); 404 | 405 | JNull::JNull() {} 406 | 407 | bool JNull::QuickCheck(const std::string& raw, int start) { 408 | int idx = start + SkipSpacesWithoutError(raw, start); 409 | int n = raw.size(), m = text_.size(); 410 | if (idx + m > n) return false; 411 | return std::strncmp(text_.c_str(), raw.c_str() + idx, m) == 0; 412 | } 413 | 414 | const std::string& JNull::Name() const { 415 | static std::string name("Null"); 416 | return name; 417 | } 418 | 419 | int JNull::DoParse(const std::string& raw, int start, JsonMask* mask) { 420 | int idx = start + SkipSpaces(raw, start); 421 | if (!QuickCheck(raw, idx)) { 422 | throw JsonException(*this, raw, idx); 423 | } 424 | return this->text_.size(); 425 | } 426 | 427 | void JNull::Print(std::ostream& os) const { 428 | os << this->text_; 429 | } 430 | 431 | 432 | 433 | class JBoolean : public clone::Template { 434 | public: 435 | JBoolean(); 436 | JBoolean(bool value); 437 | bool GetValue() const; 438 | //<0: not matched, 0: false, >0: true 439 | static int QuickCheck(const std::string& raw, int start); 440 | 441 | protected: 442 | virtual const std::string& Name() const override; 443 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) override; 444 | virtual void Print(std::ostream& os) const override; 445 | 446 | private: 447 | bool value_; 448 | 449 | static const std::string true_; 450 | static const std::string false_; 451 | }; // class JNull 452 | 453 | #define OBJECT_BOOLEAN_CHECKER [](const std::string& raw, int start) { return JBoolean::QuickCheck(raw, start) >= 0; } 454 | REGIST_JSON_OBJECT(JBoolean, OBJECT_BOOLEAN_CHECKER, 1); 455 | #undef OBJECT_BOOLEAN_CHECKER 456 | 457 | const std::string JBoolean::true_("true"); 458 | const std::string JBoolean::false_("false"); 459 | 460 | int JBoolean::QuickCheck(const std::string& raw, int start) { 461 | int idx = start + SkipSpacesWithoutError(raw, start); 462 | int n = raw.size(), mt = true_.size(), mf = false_.size(); 463 | auto check = [&](const std::string& str) -> bool { 464 | int m = str.size(); 465 | if (idx + m > n) return false; 466 | return std::strncmp(str.c_str(), raw.c_str() + idx, m) == 0; 467 | }; 468 | if (check(true_)) return 1; 469 | if (check(false_)) return 0; 470 | return -1; 471 | } 472 | 473 | JBoolean::JBoolean() : value_(false) {} 474 | 475 | JBoolean::JBoolean(bool value) : value_(value) {} 476 | 477 | bool JBoolean::GetValue() const { 478 | return this->value_; 479 | } 480 | 481 | const std::string& JBoolean::Name() const { 482 | static std::string name("Boolean"); 483 | return name; 484 | } 485 | 486 | int JBoolean::DoParse(const std::string& raw, int start, JsonMask* mask) { 487 | int idx = start + this->SkipSpaces(raw, start); 488 | int ret = this->QuickCheck(raw, idx); 489 | if (ret < 0) throw JsonException(*this, raw, idx); 490 | if (ret > 0) { 491 | this->value_ = true; 492 | return this->true_.size(); 493 | } 494 | this->value_ = false; 495 | return this->false_.size(); 496 | } 497 | 498 | void JBoolean::Print(std::ostream& os) const { 499 | os << (this->value_ ? this->true_ : this->false_); 500 | } 501 | 502 | 503 | 504 | class JNumber : public clone::Template { 505 | public: 506 | JNumber(); 507 | JNumber(long long v); 508 | JNumber(double v); 509 | long long GetInteger() const; 510 | double GetNumber() const; 511 | bool IsInteger() const; 512 | void SetValue(long long v); 513 | void SetValue(double v); 514 | 515 | static bool IsNumberCharacter(char c); 516 | 517 | protected: 518 | virtual const std::string& Name() const override; 519 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) override; 520 | virtual void Print(std::ostream& os) const override; 521 | 522 | private: 523 | long long integer_; 524 | double number_; 525 | bool isInteger_; 526 | }; // class JNumber 527 | 528 | #define OBJECT_NUMBER_CHECKER [](const std::string& raw, int start) { return JNumber::IsNumberCharacter(raw[start]); } 529 | REGIST_JSON_OBJECT(JNumber, OBJECT_NUMBER_CHECKER, 2); 530 | #undef OBJECT_NUMBER_CHECKER 531 | 532 | bool JNumber::IsNumberCharacter(char c) { 533 | return (c >= '0' && c <= '9') 534 | || c == '-' 535 | || c == '.'; 536 | } 537 | 538 | JNumber::JNumber() : 539 | integer_(0), 540 | number_(0.0), 541 | isInteger_(true) 542 | {} 543 | 544 | JNumber::JNumber(long long v) { 545 | this->SetValue(v); 546 | } 547 | 548 | JNumber::JNumber(double v) { 549 | this->SetValue(v); 550 | } 551 | 552 | long long JNumber::GetInteger() const { 553 | return this->integer_; 554 | } 555 | 556 | double JNumber::GetNumber() const { 557 | return this->number_; 558 | } 559 | 560 | bool JNumber::IsInteger() const { 561 | return this->isInteger_; 562 | } 563 | 564 | void JNumber::SetValue(long long v) { 565 | this->number_ = this->integer_ = v; 566 | this->isInteger_ = true; 567 | } 568 | 569 | void JNumber::SetValue(double v) { 570 | this->integer_ = this->number_ = v; 571 | this->isInteger_ = false; 572 | } 573 | 574 | const std::string& JNumber::Name() const { 575 | static std::string name("Number"); 576 | return name; 577 | } 578 | 579 | int JNumber::DoParse(const std::string& raw, int start, JsonMask* mask) { 580 | int idx = start + this->SkipSpaces(raw, start), n = raw.size(); 581 | std::stringstream ss1, ss2; 582 | int from = idx; 583 | while (idx < n && this->IsNumberCharacter(raw[idx])) { 584 | ss1 << raw[idx]; 585 | ss2 << raw[idx]; 586 | ++idx; 587 | } 588 | if (idx == from) throw JsonException(*this, raw, idx); 589 | std::string post1, post2; 590 | ss1 >> this->integer_ >> post1; 591 | ss2 >> this->number_ >> post2; 592 | if (post2.size() > 0) throw JsonException(*this, raw, idx - post2.size()); 593 | this->isInteger_ = post1.size() <= 0; 594 | return idx - start; 595 | } 596 | 597 | void JNumber::Print(std::ostream& os) const { 598 | if (this->isInteger_) os << this->integer_; 599 | else os << this->number_; 600 | } 601 | 602 | 603 | 604 | //TODO: escape not supported yet 605 | class JString : public clone::Template { 606 | public: 607 | JString(); 608 | JString(const std::string& s); 609 | JString(std::string&& s); 610 | const std::string& GetString() const; 611 | std::string& GetString(); 612 | void SetString(const std::string& s); 613 | 614 | protected: 615 | virtual const std::string& Name() const override; 616 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) override; 617 | virtual void Print(std::ostream& os) const override; 618 | 619 | private: 620 | std::string string_; 621 | }; // class JString 622 | 623 | #define OBJECT_STRING_CHECKER [](const std::string& raw, int start) { return raw[start] == '\"'; } 624 | REGIST_JSON_OBJECT(JString, OBJECT_STRING_CHECKER, 3); 625 | #undef OBJECT_STRING_CHECKER 626 | 627 | JString::JString() {} 628 | 629 | JString::JString(const std::string& s) : string_(s) {} 630 | 631 | JString::JString(std::string&& s) { 632 | this->string_.swap(s); 633 | } 634 | 635 | const std::string& JString::GetString() const { 636 | return this->string_; 637 | } 638 | 639 | std::string& JString::GetString() { 640 | return this->string_; 641 | } 642 | 643 | void JString::SetString(const std::string& s) { 644 | this->string_ = s; 645 | } 646 | 647 | const std::string& JString::Name() const { 648 | static std::string name("String"); 649 | return name; 650 | } 651 | 652 | int JString::DoParse(const std::string& raw, int start, JsonMask* mask) { 653 | int idx = start + this->SkipSpaces(raw, start), n = raw.size(); 654 | if (raw[idx] != '\"') throw JsonException(*this, raw, idx); 655 | std::stringstream ss; 656 | for (++idx; idx < n && raw[idx] != '\"'; ++idx) ss << raw[idx]; 657 | if (idx >= n) throw JsonException(*this, raw, idx); 658 | this->string_ = ss.str(); 659 | return ++idx - start; 660 | } 661 | 662 | void JString::Print(std::ostream& os) const { 663 | os << '\"' << this->string_ << '\"'; 664 | } 665 | 666 | 667 | 668 | class JArray : public clone::Template { 669 | public: 670 | typedef std::vector Array; 671 | JArray(); 672 | Array& GetArray(); 673 | const Array& GetArray() const; 674 | 675 | protected: 676 | virtual const std::string& Name() const override; 677 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) override; 678 | virtual void Print(std::ostream& os) const override; 679 | 680 | private: 681 | Array array_; 682 | }; // class JString 683 | 684 | #define OBJECT_ARRAY_CHECKER [](const std::string& raw, int start) { return raw[start] == '['; } 685 | REGIST_JSON_OBJECT(JArray, OBJECT_ARRAY_CHECKER, 4); 686 | #undef OBJECT_ARRAY_CHECKER 687 | 688 | JArray::JArray() {} 689 | 690 | JArray::Array& JArray::GetArray() { 691 | return this->array_; 692 | } 693 | 694 | const JArray::Array& JArray::GetArray() const { 695 | return this->array_; 696 | } 697 | 698 | const std::string& JArray::Name() const { 699 | static std::string name("Array"); 700 | return name; 701 | } 702 | 703 | int JArray::DoParse(const std::string& raw, int start, JsonMask* mask) { 704 | int idx = start + this->SkipSpaces(raw, start), n = raw.size(); 705 | if (raw[idx] != '[') throw JsonException(*this, raw, idx); 706 | idx += this->SkipSpaces(raw, idx + 1) + 1; 707 | if (raw[idx] == ']') return ++idx - start; 708 | for (; idx < n; ++idx) { 709 | int len; 710 | this->array_.emplace_back(raw, idx, len, mask, false); 711 | idx += len; 712 | idx += this->SkipSpaces(raw, idx); 713 | if (raw[idx] != ',' && raw[idx] != ']') throw JsonException(*this, raw, idx); 714 | if (raw[idx] == ']') return ++idx - start; 715 | } 716 | throw JsonException(*this, raw, idx); 717 | return idx - start; 718 | } 719 | 720 | void JArray::Print(std::ostream& os) const { 721 | os << '['; 722 | for (int i = 0, n = this->array_.size(); i < n; ++i) { 723 | if (i != 0) os << ','; 724 | os << this->array_[i]; 725 | } 726 | os << ']'; 727 | } 728 | 729 | 730 | 731 | class JDict : public clone::Template { 732 | public: 733 | JDict(); 734 | JDict(JDict&& dict); 735 | JDict(const JDict& dict); 736 | JDict& operator = (const JDict& dict); 737 | 738 | template 739 | bool Have(const _T& key) { 740 | return this->keys_.find(ToString(key)) != this->keys_.end(); 741 | } 742 | template 743 | bool Remove(const _T& key) { 744 | auto k = ToString(key); 745 | auto find = this->keys_.find(k); 746 | if (find == this->keys_.end()) return false; 747 | this->vals_.erase(find->second); 748 | this->keys_.erase(find); 749 | return true; 750 | } 751 | template 752 | bool Add(_T&& key, Json&& v = JNull()) { 753 | auto k = ToString(key); 754 | auto find = this->keys_.find(k); 755 | if (find != this->keys_.end()) return false; 756 | JString jkey(k); 757 | this->keys_.emplace( 758 | std::move(k), 759 | this->vals_.emplace(this->vals_.end(), 760 | std::move(jkey), 761 | std::forward(v) 762 | ) 763 | ); 764 | return true; 765 | } 766 | bool Add(Json&& key, Json&& v = JNull()) { 767 | auto k = ToString(key); 768 | auto find = this->keys_.find(k); 769 | if (find != this->keys_.end()) return false; 770 | this->keys_.emplace( 771 | std::move(k), 772 | this->vals_.emplace(this->vals_.end(), 773 | std::forward(key), 774 | std::forward(v) 775 | ) 776 | ); 777 | return true; 778 | } 779 | template 780 | Json& operator [] (const _T& key) { 781 | auto find = this->keys_.find(ToString(key)); 782 | if (find == this->keys_.end()) throw JsonException(*this, "Key not find."); 783 | return find->second->second; 784 | } 785 | template 786 | const Json& operator [] (const _T& key) const { 787 | auto find = this->keys_.find(ToString(key)); 788 | if (find == this->keys_.end()) throw JsonException(*this, "Key not find."); 789 | return find->second->second; 790 | } 791 | void Until(std::function cb) { 792 | for (auto ite = this->vals_.begin(); ite != this->vals_.end(); ++ite) { 793 | if (cb(ite->first, ite->second)) break; 794 | } 795 | } 796 | void Until(std::function cb) const { 797 | for (auto ite = this->vals_.begin(); ite != this->vals_.end(); ++ite) { 798 | if (cb(ite->first, ite->second)) break; 799 | } 800 | } 801 | void ForEach(std::function cb) { 802 | for (auto ite = this->vals_.begin(); ite != this->vals_.end(); ++ite) { 803 | cb(ite->first, ite->second); 804 | } 805 | } 806 | void ForEach(std::function cb) const { 807 | for (auto ite = this->vals_.begin(); ite != this->vals_.end(); ++ite) { 808 | cb(ite->first, ite->second); 809 | } 810 | } 811 | 812 | protected: 813 | virtual const std::string& Name() const override; 814 | virtual int DoParse(const std::string& raw, int start, JsonMask* mask) override; 815 | virtual void Print(std::ostream& os) const override; 816 | 817 | private: 818 | template 819 | static std::string ToString(const _T& v) { 820 | std::stringstream ss; 821 | ss << v; 822 | return ss.str(); 823 | } 824 | std::string ToString(const std::string& v) { 825 | return v; 826 | } 827 | 828 | std::map>::iterator> keys_; 829 | std::list> vals_; 830 | }; // class JDict 831 | 832 | #define OBJECT_DICT_CHECKER [](const std::string& raw, int start) { return raw[start] == '{'; } 833 | REGIST_JSON_OBJECT(JDict, OBJECT_DICT_CHECKER, 5); 834 | #undef OBJECT_DICT_CHECKER 835 | 836 | JDict::JDict() {} 837 | 838 | JDict::JDict(JDict&& dict) : 839 | keys_(std::move(dict.keys_)), 840 | vals_(std::move(dict.vals_)) 841 | { 842 | this->SetPosition(dict.GetPosistion()); 843 | } 844 | 845 | JDict::JDict(const JDict& dict) { 846 | *this = dict; 847 | } 848 | 849 | JDict& JDict::operator = (const JDict& dict) { 850 | this->SetPosition(dict.GetPosistion()); 851 | this->vals_ = dict.vals_; 852 | for (auto ite = this->vals_.begin(); ite != this->vals_.end(); ++ite) { 853 | this->keys_.emplace(ToString(ite->first), ite); 854 | } 855 | return *this; 856 | } 857 | 858 | const std::string& JDict::Name() const { 859 | static std::string name("Object"); 860 | return name; 861 | } 862 | 863 | int JDict::DoParse(const std::string& raw, int start, JsonMask* mask) { 864 | int idx = start + this->SkipSpaces(raw, start), n = raw.size(); 865 | if (raw[idx] != '{') throw JsonException(*this, raw, idx); 866 | idx += this->SkipSpaces(raw, idx + 1) + 1; 867 | if (raw[idx] == '}') return ++idx - start; 868 | for (; idx < n; ++idx) { 869 | int len; 870 | Json key(raw, idx, len, mask, false); 871 | idx += len; 872 | idx += this->SkipSpaces(raw, idx); 873 | if (raw[idx] == ':') { 874 | ++idx; 875 | Json val(raw, idx, len, mask, false); 876 | if (!this->Add(std::move(key), std::move(val))) throw JsonException(*this, raw, idx - 2, "Existed key."); 877 | idx += len; 878 | } 879 | else if (raw[idx] == ',' || raw[idx] == '}') { 880 | if (!this->Add(std::move(key), JNull())) throw JsonException(*this, raw, idx - 2, "Existed key."); 881 | } 882 | idx += this->SkipSpaces(raw, idx); 883 | if (raw[idx] != ',' && raw[idx] != '}') throw JsonException(*this, raw, idx); 884 | if (raw[idx] == '}') return ++idx - start; 885 | } 886 | throw JsonException(*this, raw, idx); 887 | return idx - start; 888 | } 889 | 890 | void JDict::Print(std::ostream& os) const { 891 | os << '{'; 892 | int idx = 0; 893 | for (auto ite = this->vals_.begin(); ite != this->vals_.end(); ++ite, ++idx) { 894 | if (idx != 0) os << ','; 895 | os << ite->first; 896 | if (!ite->second.Is()) { 897 | os << ':' << ite->second; 898 | } 899 | } 900 | os << '}'; 901 | } 902 | 903 | 904 | // post implemention 905 | int Json::Parse(const std::string& raw, int start, JsonMask* mask, bool all) { 906 | auto flag = [&mask](int m) -> bool { return mask == NULL || (mask->Mask() & m); }; 907 | if (this->obj_ != NULL) delete this->obj_; 908 | this->obj_ = NULL; 909 | int idx = start, n = raw.size(); 910 | while (idx < n && raw[idx] == ' ') ++idx; 911 | if (idx >= n) throw JsonException(*this, raw, idx); 912 | 913 | ObjectManager::Until([&](const ObjectManager::Api& api) -> bool { 914 | if (flag(api.mask) && api.checker(raw, idx)) { 915 | Object* obj = api.constructor(); 916 | try { 917 | obj->SetPosition(idx); 918 | int len = obj->Parse(raw, idx, mask ? mask->Next() : NULL); 919 | if (len <= 0) { 920 | throw JsonException(*this, raw, idx, 921 | std::string("Invalid JSON parse result with parser = ") 922 | + obj->GetName() + "." 923 | ); 924 | } 925 | idx += len; 926 | this->obj_ = obj; 927 | } 928 | catch (JsonException& e) { 929 | delete obj; 930 | throw e; 931 | } 932 | return true; 933 | } 934 | return false; 935 | }); 936 | if (this->obj_ == NULL) throw JsonException(*this, raw, idx, "Invalid JSON format."); 937 | if (all) { 938 | while (idx < n && raw[idx] == ' ') ++idx; 939 | if (idx < n) throw JsonException(*this, raw, idx, "Invalid JSON format."); 940 | } 941 | return idx - start; 942 | } 943 | 944 | 945 | 946 | //quick APIs 947 | template 948 | Json Create(_ARGS&&... args) { 949 | return Json::Create<_T>(args...); 950 | } 951 | 952 | } // namespace json 953 | 954 | } // namespace lc 955 | 956 | #endif -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "leetcode-entry.h" 4 | 5 | #ifndef INPUT 6 | #define INPUT std::cin 7 | #endif 8 | 9 | #ifndef OUTPUT 10 | #define OUTPUT std::cout 11 | #endif 12 | 13 | std::string print_error(const std::string& raw, int line, int pos, const std::string& info); 14 | 15 | int main() { 16 | try { 17 | lc::io::SI in(INPUT); 18 | lc::io::MO out(OUTPUT); 19 | try { 20 | lc::Entry::Run(in, out); 21 | std::cout << "Program compelete." << std::endl; 22 | } 23 | catch (lc::json::JsonException& e) { throw print_error(in.GetRaw(), in.GetLineCount(), e.GetPosition(), e.what()); } 24 | catch (lc::conv::ConvertException& e) { 25 | if (e.GetJson().GetObject() == NULL) throw std::string(e.what()); 26 | throw print_error(in.GetRaw(), in.GetLineCount(), e.GetJson().GetObject()->GetPosistion(), e.what()); 27 | } 28 | catch (lc::EntryException& e) { 29 | throw print_error(e.GetRaw(), e.GetLine(), e.GetPosition(), e.what()); 30 | } 31 | catch (std::string& e) { throw e; } 32 | catch (std::exception& e) { throw std::string("Unhandled error. ") + e.what(); } 33 | catch (...) { throw std::string("Unhandled error."); } 34 | } 35 | catch (std::string& e) { 36 | std::cerr << "\nError: " << e << std::endl; 37 | } 38 | // pause here in terminal 39 | std::cout << "Press Any Key to Continue..." << std::endl; 40 | std::cin.clear(); 41 | std::cin.sync(); 42 | std::cin.get(); // pause 43 | return 0; 44 | } 45 | 46 | std::string print_error(const std::string& raw, int line, int pos, const std::string& info) { 47 | const int lmost = 15, rmost = 15, padding = 6; 48 | std::stringstream ss; 49 | ss << info; 50 | if (pos < 0 || line <= 0) return ss.str(); 51 | 52 | int n = raw.size(); 53 | int l = std::max(0, pos - lmost); 54 | if (l <= padding) l = 0; 55 | int r = std::min(n, pos + rmost); 56 | if (r + padding >= n) r = n; 57 | 58 | ss << " @position=" << line << ':' << pos << '\n'; 59 | int count = ss.str().size(); 60 | ss << "raw string : "; 61 | if (l > 0) ss << "(..." << l << ")"; 62 | count = ss.str().size() - count + pos - l; 63 | ss << raw.substr(l, r - l); 64 | if (r < n) ss << "(" << n - r << "...)"; 65 | ss << "\n"; 66 | while (count-- > 0) ss << ' '; 67 | ss << "^"; 68 | 69 | return ss.str(); 70 | } -------------------------------------------------------------------------------- /resources/code/cpp/leetcode-types.h: -------------------------------------------------------------------------------- 1 | #ifndef LEETCODE_TYPES 2 | #define LEETCODE_TYPES 3 | 4 | #include 5 | #include 6 | 7 | #ifndef NULL 8 | #define NULL 0 9 | #endif 10 | 11 | namespace lc { 12 | 13 | namespace mem { 14 | 15 | class PtrObject { 16 | public: 17 | virtual ~PtrObject() {}; 18 | 19 | protected: 20 | PtrObject(); 21 | }; // class PtrObject 22 | 23 | class MemoryCleaner { 24 | public: 25 | static void Add(PtrObject* obj); 26 | static void Clean(); 27 | MemoryCleaner(MemoryCleaner&) = delete; 28 | MemoryCleaner& operator=(const MemoryCleaner&) = delete; 29 | 30 | private: 31 | MemoryCleaner(); 32 | std::list objs_; 33 | 34 | static MemoryCleaner instance_; 35 | }; // class MemoryCleaner 36 | 37 | MemoryCleaner MemoryCleaner::instance_; 38 | 39 | MemoryCleaner::MemoryCleaner() {} 40 | 41 | void MemoryCleaner::Add(PtrObject* obj) { 42 | instance_.objs_.push_back(obj); 43 | } 44 | 45 | void MemoryCleaner::Clean() { 46 | for (auto& obj : instance_.objs_) { 47 | delete obj; 48 | } 49 | instance_.objs_.clear(); 50 | } 51 | 52 | PtrObject::PtrObject() { 53 | MemoryCleaner::Add(this); 54 | } 55 | 56 | } // namespace mem 57 | 58 | 59 | 60 | class ListNode : public mem::PtrObject { 61 | public: 62 | int val; 63 | ListNode *next; 64 | ListNode(int x) : val(x), next(NULL) {} 65 | }; 66 | 67 | struct TreeNode : public mem::PtrObject { 68 | public: 69 | int val; 70 | TreeNode *left; 71 | TreeNode *right; 72 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 73 | }; 74 | 75 | } // namespace lc 76 | 77 | #endif -------------------------------------------------------------------------------- /resources/imgs/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xavier-cai/vscode-leetcode-cpp-debug/8d0a4f13b3c8df814d74895452e02ec21e449416/resources/imgs/icon.png -------------------------------------------------------------------------------- /src/commands/debug.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { leetCodeDebugger } from "../leetCodeDebugger"; 3 | 4 | export async function debugSolution(uri?: vscode.Uri): Promise { 5 | let textEditor: vscode.TextEditor | undefined; 6 | if (uri) { 7 | textEditor = await vscode.window.showTextDocument(uri, { preview: false }); 8 | } else { 9 | textEditor = vscode.window.activeTextEditor; 10 | } 11 | 12 | if (!textEditor) { 13 | return; 14 | } 15 | 16 | try { 17 | await leetCodeDebugger.startDebugging(textEditor.document.uri.fsPath); 18 | } catch (error) { 19 | if (error instanceof Error) { 20 | await vscode.window.showInformationMessage(`${error}`); 21 | } 22 | else { 23 | await vscode.window.showInformationMessage(`Error: ${error}`); 24 | } 25 | return; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/debuggers/cppDebugger.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import * as fse from "fs-extra"; 3 | import * as path from "path"; 4 | import { Debugger } from "./debugger"; 5 | import { CodeIndentHelper } from "../util/codeIndentHelper"; 6 | import { IQuickItemEx } from "../util/ex"; 7 | 8 | interface IArgumentMetaInfo { 9 | type: string; 10 | name: string; 11 | } 12 | 13 | interface IFunctionMetaInfo { 14 | name: string; 15 | args: IArgumentMetaInfo[]; 16 | type: string; 17 | } 18 | 19 | interface IProblemMetaInfo { 20 | name: string; // class name 21 | functions: IFunctionMetaInfo[]; 22 | isDesignProblem: boolean; 23 | isInteractiveProblem: boolean; 24 | } 25 | 26 | export class CppDebugger extends Debugger { 27 | private readonly definition = "leetcode-definition.h"; 28 | private readonly io = "leetcode-io.h"; 29 | private readonly handler = "leetcode-handler.h"; 30 | private readonly main = "leetcode-main.cpp"; 31 | 32 | public async init(solutionEditor: vscode.TextEditor): Promise { 33 | if (!solutionEditor || solutionEditor.document.isClosed || !this.codeTemplate) { 34 | return; 35 | } 36 | 37 | const insertContent: string = "#include \"" + this.definition + "\""; 38 | if (this.stubCodeHelper.getRaw().indexOf(insertContent) < 0) { 39 | this.stubCodeHelper.setFront(insertContent); 40 | } 41 | 42 | const dir: string = path.dirname(solutionEditor.document.uri.fsPath); 43 | const solution: string = path.basename(solutionEditor.document.uri.fsPath); 44 | 45 | const stub: string | undefined = await this.genStubCode(solution); 46 | if (!stub) { 47 | return; 48 | } 49 | this.stubFileHelper.files.push({ relative: this.handler, content: stub }); 50 | 51 | return path.join(dir, this.main); 52 | } 53 | 54 | public async dispose(solutionEditor: vscode.TextEditor): Promise { 55 | 56 | } 57 | 58 | private getMetaInfo(code: string): IProblemMetaInfo { 59 | const meta: IProblemMetaInfo = { 60 | name: '', 61 | functions: [], 62 | isDesignProblem: false, 63 | isInteractiveProblem: false 64 | } 65 | 66 | const classPattern: RegExp = /class +(Solution|[\w\d]+) *{?/; 67 | const initPattern: RegExp = / *([\w\d]+) *\(((?:[, ]*[\w\d<>, :\*]+[ \*&]+[\w\d]+)*)\)[ \{\}]*/; 68 | const funcPattern: RegExp = / *([\w\d<>, :\*]+) +([\w\d]+) *\(((?:[, ]*[\w\d<>, :\*]+[ \*&]+[\w\d]+)*)\)[ \{\}]*/; 69 | const argPattern: RegExp = / *([\w\d<>, :\*]+[&\* ]+)([\w\d]+) */; 70 | 71 | function getArgMetaInfo(arg: string): IArgumentMetaInfo { 72 | const match: RegExpExecArray | null = argPattern.exec(arg); 73 | if (match) { 74 | return { type: match[1].replace("&", "").trim(), name: match[2].trim() }; 75 | } 76 | (function (): never { 77 | throw new Error(`Can not get meta info from ${arg}.`); 78 | })(); 79 | } 80 | function getFuncMetaInfo(line: string): IFunctionMetaInfo | undefined { 81 | function normalize(type: string, name: string, args: string): IFunctionMetaInfo { 82 | const ret: IFunctionMetaInfo = { 83 | name: name, 84 | args: [], 85 | type: type 86 | }; 87 | if (args.replace(" ", "").length > 0) { 88 | let parts: string[] = []; 89 | let cnt: number = 0; 90 | let index: number = 0; 91 | let start: number = 0; 92 | while (true) { 93 | if (index >= args.length || (args[index] == ',' && cnt == 0)) { 94 | parts.push(args.substr(start, index - start)); 95 | start = index + 1; 96 | if (index >= args.length) { 97 | break; 98 | } 99 | } 100 | if (args[index] == '<') cnt += 1; 101 | if (args[index] == '>') cnt -= 1; 102 | index += 1; 103 | } 104 | ret.args = parts.map((value) => getArgMetaInfo(value)); 105 | } 106 | return ret; 107 | } 108 | 109 | const eol = line.lastIndexOf(";"); 110 | if (eol >= 0 && eol > line.lastIndexOf("}")) { 111 | return; 112 | } 113 | 114 | if (meta.name.length > 0) { 115 | const match: RegExpExecArray | null = initPattern.exec(line); 116 | if (match && match[1] == meta.name) { 117 | return normalize('void', match[1].trim(), match[2]); 118 | } 119 | } 120 | const match: RegExpExecArray | null = funcPattern.exec(line); 121 | if (!match || match[1].trim().length <= 0) { 122 | return; 123 | } 124 | return normalize(match[1].trim(), match[2].trim(), match[3]); 125 | } 126 | 127 | const lines: string[] = code.split('\n'); 128 | for (const line of lines) { 129 | const match: RegExpExecArray | null = classPattern.exec(line); 130 | if (match) { 131 | meta.name = match[1]; 132 | meta.functions = []; 133 | meta.isDesignProblem = meta.name != 'Solution'; 134 | continue; 135 | } 136 | if (meta.name.length > 0) { 137 | const func: IFunctionMetaInfo | undefined = getFuncMetaInfo(line); 138 | if (func) { 139 | meta.functions.push(func); 140 | } 141 | } 142 | } 143 | return meta; 144 | } 145 | 146 | private async genStubCode(solution: string): Promise { 147 | const meta: IProblemMetaInfo = this.getMetaInfo(this.codeTemplate); 148 | if (meta.name.length <= 0) { 149 | throw new Error("Invalid meta info."); 150 | } 151 | if (meta.isInteractiveProblem) { 152 | throw new Error("Unsupported problem type."); 153 | } 154 | if (meta.functions.length <= 0) { 155 | throw new Error("Can not find the entry function."); 156 | } 157 | 158 | function genArgsCode(func: IFunctionMetaInfo): string { 159 | return func.args.map((arg) => arg.name).join(", "); 160 | } 161 | function genInputCode(func: IFunctionMetaInfo, helper: CodeIndentHelper) { 162 | if (func.args.length <= 0) { 163 | return; 164 | } 165 | const tupleCode: string[] = []; 166 | for (const arg of func.args) { 167 | helper.line(arg.type + " " + arg.name + ";"); 168 | tupleCode.push(arg.type + "&"); 169 | } 170 | const tupleName: string = "__tuple__value"; 171 | helper.line(`std::tuple<` + tupleCode.join(", ") + `> ${tupleName} { ` + genArgsCode(func) + ` };`); 172 | helper.line(`conv::FromJson(${tupleName}, in);`); 173 | } 174 | 175 | const code: CodeIndentHelper = new CodeIndentHelper(); 176 | code.append(`#ifndef LEETCODE_HANDLER`) 177 | .line(`#define LEETCODE_HANDLER`) 178 | .line() 179 | .line(`#include "${solution}"`) 180 | .line(`#include "${this.io}"`) 181 | .line() 182 | .line("namespace lc {") 183 | .line() 184 | .line(`class Handler {`) 185 | .line(`public:`).right() 186 | .line(`static std::string GetClassName() { return "${meta.name}"; } `) 187 | .line(`Handler(const json::Json& in) {`).right(); 188 | 189 | // generate constructor 190 | if (!meta.isDesignProblem) { 191 | code.line(`solution_ = new ${meta.name}();`); 192 | } 193 | else { 194 | const ctor: IFunctionMetaInfo | undefined = meta.functions.find((value: IFunctionMetaInfo) => value.name == meta.name && value.type == "void"); 195 | if (ctor && ctor.args.length > 0) { 196 | genInputCode(ctor, code); 197 | code.line(`solution_ = new ${meta.name}(${genArgsCode(ctor)});`); 198 | } 199 | else { 200 | code.line(`solution_ = new ${meta.name}();`); 201 | } 202 | } 203 | code.left().line(`}`) 204 | .line(`~Handler() { delete solution_; }`); 205 | 206 | // generate handler function 207 | if (!meta.isDesignProblem) { 208 | const candidates: Array> = []; 209 | meta.functions.forEach(f => { 210 | //if ( f.type != "void" && f.args.length > 0) { 211 | const args: string[] = f.args.map((a) => a.type); 212 | candidates.push({ 213 | label: `> ${f.name}(${args.join(", ")}) => ${f.type}`, 214 | value: f 215 | }); 216 | //} 217 | }); 218 | if (candidates.length < 1) { 219 | throw new Error(`Can not find entry function in class [${meta.name}].`); 220 | } 221 | 222 | let func = candidates[0].value; 223 | if (candidates.length > 1) { // pick one 224 | const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(candidates, { 225 | placeHolder: "Please choose the entry function. (Press ESC to cancel)", 226 | ignoreFocusOut: true, 227 | }); 228 | if (!choice) { 229 | return; 230 | } 231 | func = choice.value; 232 | } 233 | 234 | code.line(`json::Json Handle(const json::Json& in, const std::string& fname) { return json::Create(); }`); 235 | code.line(`void Handle(io::SI& in, io::MO& out) {`).right(); 236 | for (const arg of func.args) { 237 | code.line(`${arg.type} ${arg.name};`) 238 | .line(`in >> ${arg.name};`); 239 | } 240 | code.line(`#ifdef LAZY_INTERACTION`) 241 | .line(`in.Input(LAZY_INTERACTION);`) 242 | .line(`#endif`); 243 | if (func.type != "void") { 244 | code.line(`out << solution_->${func.name}(${genArgsCode(func)}) << std::endl;`); 245 | } 246 | else { 247 | code.line(`solution_->${func.name}(${genArgsCode(func)});`); 248 | for (const arg of func.args) { 249 | code.line(`out << ${arg.name} << std::endl;`); 250 | } 251 | } 252 | code.left().line('}'); 253 | } 254 | else { 255 | code.line(`void Handle(io::SI& in, io::MO& out) {}`); 256 | code.line(`json::Json Handle(const json::Json& in, const std::string& fname) {`).right() 257 | .line(`if (fname == "") throw std::string("Empty function name.");`) 258 | .line(`#define CASE(func) else if (fname == #func)`); 259 | for (const func of meta.functions) { 260 | if (func.name == meta.name) { 261 | continue; 262 | } 263 | code.line(`CASE (${func.name}) {`).right(); 264 | genInputCode(func, code); 265 | const callCode: string = `solution_->${func.name}(${genArgsCode(func)})`; 266 | if (func.type == "void") { 267 | code.line(`${callCode};`) 268 | .line(`return json::Create();`); 269 | } 270 | else { 271 | code.line(`return conv::ToJson(${callCode});`); 272 | } 273 | code.left().line(`}`); 274 | } 275 | code.line(`#undef CASE`) 276 | .line(`throw std::string("Invalid function name.");`) 277 | .line(`return json::Create();`) 278 | .left().line(`}`); 279 | } 280 | 281 | code.line().left().line(`private:`).right() 282 | .line(`${meta.name}* solution_;`) 283 | .left().line(`};`) 284 | .line() 285 | .line(`} // namespace lc`) 286 | .line(); 287 | if (meta.isDesignProblem) { 288 | code.line(`#define SYSTEM_DESIGN`); 289 | } 290 | code.line(`#endif // LEETCODE_HANDLER`); 291 | return code.str(); 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /src/debuggers/debugger.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { StubFileHelper } from "../util/stubFileHelper" 3 | import { StubCodeHelper } from "../util/stubCodeHelper" 4 | 5 | export abstract class Debugger { 6 | public constructor(protected codeTemplate: string, protected stubCodeHelper: StubCodeHelper, protected stubFileHelper: StubFileHelper) { }; 7 | // return [file path] to start debugging, [undefined] to give up debugging 8 | public abstract init(solutionEditor: vscode.TextEditor): Promise; 9 | // dispose after debugging 10 | public abstract dispose(solutionEditor: vscode.TextEditor): Promise; 11 | } 12 | -------------------------------------------------------------------------------- /src/debuggers/debuggerManager.ts: -------------------------------------------------------------------------------- 1 | import { Debugger } from "./debugger" 2 | import { CppDebugger } from "./cppDebugger" 3 | import { StubFileHelper } from "../util/stubFileHelper"; 4 | import { StubCodeHelper } from "../util/stubCodeHelper"; 5 | 6 | export interface IDebuggerConstructor { 7 | new(codeTemplate: string, stubCodeHelper: StubCodeHelper, stubFileHelper: StubFileHelper): Debugger 8 | } 9 | 10 | export function getDebugger(language: string): IDebuggerConstructor | undefined { 11 | switch (language) { 12 | case "cpp": return CppDebugger; 13 | } 14 | // unsupported yet! 15 | return undefined; 16 | } 17 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as debug from './commands/debug' 3 | import { problemFetcher } from './util/problemFetcher'; 4 | import { stubFileHelperFactory } from './util/stubFileHelper'; 5 | 6 | export function activate(context: vscode.ExtensionContext) { 7 | try { 8 | stubFileHelperFactory.initialize(context); 9 | context.subscriptions.push( 10 | problemFetcher, 11 | vscode.commands.registerCommand("leetcode-cpp-debugger.debug", (uri?: vscode.Uri) => debug.debugSolution(uri)) 12 | ); 13 | } 14 | catch (error) { 15 | vscode.window.showInformationMessage(`LeetCode Cpp Debugger initialization error: ${error}`); 16 | } 17 | } 18 | 19 | export function deactivate() {} 20 | -------------------------------------------------------------------------------- /src/leetCodeDebugger.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import * as fse from "fs-extra"; 3 | import * as path from "path"; 4 | import { IDebuggerConstructor, getDebugger } from "./debuggers/debuggerManager"; 5 | import * as uc from "./util/config"; 6 | import { problemFetcher } from "./util/problemFetcher"; 7 | import { StubFileHelper, stubFileHelperFactory } from "./util/stubFileHelper"; 8 | import { StubCodeHelper } from "./util/stubCodeHelper" 9 | 10 | class LeetCodeDebugger { 11 | public async startDebugging(solutionFilePath: string): Promise { 12 | const language: uc.Language | undefined = uc.languageHelper.getByPath(solutionFilePath); 13 | if (!language) { 14 | vscode.window.showInformationMessage(`Unsupport file type.`); 15 | return; 16 | } 17 | 18 | const ctor: IDebuggerConstructor | undefined = getDebugger(language.name); 19 | if (!ctor) { 20 | vscode.window.showInformationMessage(`Unsupport language: ${language.name}.`); 21 | return; 22 | } 23 | 24 | const source: uc.Source | undefined = uc.getSource(); 25 | if (!source) { 26 | vscode.window.showInformationMessage(`Unknown source.`); 27 | return; 28 | } 29 | 30 | let codeTemplate: string = ""; 31 | if (source == uc.Source.Local) { 32 | codeTemplate = await fse.readFile(solutionFilePath, "utf8"); 33 | } 34 | else { // fetch problem online 35 | const id: string | undefined = uc.getProblemId(solutionFilePath); 36 | if (!id) { 37 | vscode.window.showInformationMessage(`Regular expression non-matched.`); 38 | return; 39 | } 40 | try { 41 | codeTemplate = await vscode.window.withProgress({ 42 | location: vscode.ProgressLocation.Notification 43 | }, async (p: vscode.Progress<{}>) => { 44 | return new Promise(async (resolve, reject): Promise => { 45 | p.report({ message: `Fetching problem...` }); 46 | try { 47 | resolve(await problemFetcher.fetchProblem(id, language)); 48 | } catch (e) { 49 | reject(e); 50 | } 51 | }); 52 | } 53 | ); 54 | } 55 | catch (e) { 56 | vscode.window.showInformationMessage(`Fetch problem failed: ${e}`); 57 | } 58 | } 59 | 60 | const stubFileHelper: StubFileHelper | undefined = await stubFileHelperFactory.create(language, solutionFilePath); 61 | if (!stubFileHelper) { 62 | vscode.window.showInformationMessage(`Can not create entry code.`); 63 | return; 64 | } 65 | 66 | const solutionDocument: vscode.TextDocument = await vscode.workspace.openTextDocument(solutionFilePath); 67 | const stubCodeHelper: StubCodeHelper = new StubCodeHelper(solutionDocument); 68 | 69 | const debuggerInstance = new ctor(codeTemplate, stubCodeHelper, stubFileHelper); 70 | async function switchEditor(filePath: string): Promise { 71 | const textDocument: vscode.TextDocument = await vscode.workspace.openTextDocument(filePath); 72 | return await vscode.window.showTextDocument(textDocument, undefined, true); 73 | } 74 | let listenEvent: vscode.Disposable | undefined; 75 | async function afterDebugging(): Promise { 76 | const editor = await switchEditor(solutionFilePath); 77 | await debuggerInstance.dispose(editor); 78 | if (uc.getIsDeleteTemporaryContents()) { 79 | const stub: Promise[] = []; 80 | if (stubFileHelper) { 81 | stub.push(stubFileHelper.uninstall(path.dirname(editor.document.uri.fsPath))); 82 | } 83 | stub.push(stubCodeHelper.uninstall(editor)); 84 | await Promise.all(stub); 85 | } 86 | await editor.document.save(); 87 | if (listenEvent) { 88 | listenEvent.dispose(); 89 | } 90 | } 91 | try { 92 | const solutionEditor: vscode.TextEditor = await vscode.window.showTextDocument(solutionDocument); 93 | const debugEntry: string | undefined = await debuggerInstance.init(solutionEditor); 94 | if (!debugEntry) { 95 | await afterDebugging(); 96 | return; 97 | } 98 | 99 | const stub: Promise[] = [ 100 | stubCodeHelper.install(solutionEditor), 101 | stubFileHelper.install(path.dirname(solutionEditor.document.uri.fsPath)) 102 | ]; 103 | await Promise.all(stub); 104 | await solutionEditor.document.save(); 105 | 106 | if (!await fse.pathExists(debugEntry)) { 107 | await afterDebugging(); 108 | return; 109 | } 110 | 111 | let entryEditor: vscode.TextEditor | undefined; 112 | if (debugEntry) { 113 | entryEditor = await switchEditor(debugEntry); 114 | } 115 | 116 | listenEvent = vscode.debug.onDidTerminateDebugSession(async () => { await afterDebugging(); }); 117 | if (!await this.launch()) { 118 | await afterDebugging(); 119 | } 120 | 121 | if (entryEditor) { 122 | entryEditor.hide(); 123 | } 124 | } 125 | catch (error) { 126 | vscode.window.showInformationMessage(`Failed to start debugging: ${error}`); 127 | await afterDebugging(); 128 | } 129 | } 130 | 131 | private async launch(): Promise { 132 | let textEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; 133 | if (!textEditor) { 134 | return false; 135 | } 136 | 137 | const config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("launch", textEditor.document.uri); 138 | const folder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder(textEditor.document.uri); 139 | const values: any[] | undefined = config.get("configurations"); 140 | if (!folder || !values) { 141 | return false; 142 | } 143 | 144 | const picks: Array = []; 145 | for (const value of values) { 146 | if (!value.name || !value.request) { 147 | continue; 148 | } 149 | picks.push({ 150 | label: value.name, 151 | detail: value.request, 152 | }); 153 | } 154 | if (picks.length <= 0) { 155 | return false; 156 | } 157 | 158 | let launch: string = picks[0].label; 159 | if (picks.length > 1) { // pick one 160 | const choice: vscode.QuickPickItem | undefined = await vscode.window.showQuickPick(picks, { 161 | placeHolder: "Please choose a launch configuration for your debug session. (Press ESC to cancel)", 162 | ignoreFocusOut: true, 163 | }); 164 | if (!choice) { 165 | return false; 166 | } 167 | launch = choice.label; 168 | } 169 | 170 | return await vscode.debug.startDebugging(folder, launch); 171 | } 172 | } 173 | 174 | export const leetCodeDebugger: LeetCodeDebugger = new LeetCodeDebugger(); 175 | -------------------------------------------------------------------------------- /src/util/codeIndentHelper.ts: -------------------------------------------------------------------------------- 1 | export class CodeIndentHelper { 2 | private count: number; 3 | private codes: string[]; 4 | constructor(private indent: string = " ") { 5 | this.count = 0; 6 | this.codes = [""]; 7 | } 8 | public line(code: string = ""): CodeIndentHelper { 9 | let init: string = ""; 10 | for (var i = 0; i < this.count; ++i) { 11 | init += this.indent; 12 | } 13 | this.codes.push(init + code); 14 | return this; 15 | } 16 | public right(): CodeIndentHelper { 17 | this.count += 1; 18 | return this; 19 | } 20 | public left() : CodeIndentHelper { 21 | this.count -= 1; 22 | return this; 23 | } 24 | public append(code: string): CodeIndentHelper { 25 | this.codes[this.codes.length - 1] += code; 26 | return this; 27 | } 28 | public str(): string { 29 | return this.codes.join('\n'); 30 | } 31 | } -------------------------------------------------------------------------------- /src/util/config.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode' 2 | import * as path from 'path' 3 | 4 | export const configs = { 5 | resourcesPath: "resources", 6 | codePath: "code", 7 | token: "This file is generated by extension [LeetCode C++ Debugger], you can delete it if you want.", 8 | timeout: 5 * 1000, 9 | } 10 | 11 | export enum Source { 12 | LeetCode = "leetcode", 13 | LeetCodeCN = "leetcode-cn", 14 | Local = "local" 15 | } 16 | 17 | const sources = [ 18 | Source.LeetCode, 19 | Source.LeetCodeCN, 20 | Source.Local 21 | ] 22 | 23 | const hosts = { 24 | "leetcode" : "https://leetcode.com/", 25 | "leetcode-cn" : "https://leetcode-cn.com/" 26 | } 27 | 28 | export interface Language { 29 | name: string; 30 | disp: string; 31 | ext: string; 32 | commet: { 33 | begin: string; 34 | end: string 35 | }; 36 | stub: string; //glob expression 37 | } 38 | 39 | const languages: Language[] = [ 40 | { 41 | name: "cpp", 42 | disp: "C++", 43 | ext: "cpp", 44 | commet: { begin: "/*", end: "*/" }, 45 | stub: "**" 46 | } 47 | ] 48 | 49 | function getConfiguration(): vscode.WorkspaceConfiguration { 50 | return vscode.workspace.getConfiguration("leetcode-cpp-debugger"); 51 | } 52 | 53 | export function getSource(): Source | undefined { 54 | const source: string | undefined = getConfiguration().get("source"); 55 | if(!source) { 56 | return; 57 | } 58 | const reg: RegExp = /\[(?:online|offline)\](?:(.+)\.com|(.+))/; 59 | const match: RegExpExecArray | null = reg.exec(source); 60 | if (!match) { 61 | return; 62 | } 63 | const key = match[1] ? match[1] : match[2]; 64 | for (const str of sources) { 65 | if (str == key) { 66 | return str; 67 | } 68 | } 69 | } 70 | 71 | export function getProblemId(file: string): string | undefined { 72 | const pattern: string | undefined = getConfiguration().get("idMatchPattern"); 73 | if (!pattern) { 74 | return; 75 | } 76 | const reg: RegExp = new RegExp(pattern); 77 | const match: RegExpExecArray | null = reg.exec(path.basename(file)); 78 | if (!match || match.length <= 1) { 79 | return; 80 | } 81 | return match[1]; 82 | } 83 | 84 | export function getHost(): string | undefined { 85 | const source: Source | undefined = getSource(); 86 | if (!source || source == Source.Local) { 87 | return; 88 | } 89 | return hosts[source]; 90 | } 91 | 92 | export function getIsDeleteTemporaryContents(): boolean { 93 | return getConfiguration().get("deleteTemporaryContents", true); 94 | } 95 | 96 | export function getEncoding(): string | undefined { 97 | return getConfiguration().get("outputFileEncoding"); 98 | } 99 | 100 | class LanguageHelper { 101 | public getByName(name: string) : Language | undefined { 102 | return languages.find(language => language.name == name); 103 | } 104 | public getByPath(path: string) : Language | undefined { 105 | const parts = path.split("."); 106 | return languages.find(language => language.ext == parts[parts.length-1]); 107 | } 108 | } 109 | 110 | export const languageHelper : LanguageHelper = new LanguageHelper(); 111 | 112 | -------------------------------------------------------------------------------- /src/util/ex.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode' 2 | 3 | export interface IQuickItemEx extends vscode.QuickPickItem { 4 | value: T; 5 | } -------------------------------------------------------------------------------- /src/util/problemFetcher.ts: -------------------------------------------------------------------------------- 1 | import * as request from 'request'; 2 | import {Source, getSource, Language} from './config' 3 | import * as vscode from 'vscode'; 4 | import * as uc from './config'; 5 | 6 | interface IProblem { 7 | id: string; 8 | fid: string; 9 | name: string; 10 | slug: string; 11 | } 12 | 13 | class ProblemFetcher implements vscode.Disposable { 14 | private cacheSource: Source; 15 | private cacheProblems: IProblem[]; 16 | private cacheId: string | undefined; 17 | private cacheContent: any; 18 | private configurationChangeListener: vscode.Disposable; 19 | private readonly leetCodeApiProblems: string = "api/problems/algorithms"; 20 | private readonly leetCodeApiGraphql: string = "graphql"; 21 | 22 | public constructor() { 23 | this.cacheSource = Source.Local; 24 | this.cacheProblems = []; 25 | this.configurationChangeListener = vscode.workspace.onDidChangeConfiguration((event: vscode.ConfigurationChangeEvent) => { 26 | if (event.affectsConfiguration("leetcode-cpp-debugger.source")) { 27 | //this.updateProblems(); 28 | } 29 | }, this); 30 | //this.updateProblems(); 31 | } 32 | 33 | public dispose() { 34 | this.configurationChangeListener.dispose(); 35 | } 36 | 37 | private async request(rq: any, options: any): Promise { 38 | return new Promise((resolve, reject) => { 39 | rq(options, (e: any, resp: any, body: any) => { 40 | if (e || !resp || resp.statusCode != 200) { 41 | reject(`Request connect error.`); 42 | return; 43 | } 44 | resolve(body); 45 | }); 46 | }); 47 | } 48 | 49 | private async updateProblems() { 50 | const source: Source | undefined = getSource(); 51 | if (!source) { 52 | throw new Error("Invalid source."); 53 | } 54 | 55 | if (source == Source.Local || source == this.cacheSource) { 56 | return; 57 | } 58 | 59 | // init 60 | this.cacheSource = Source.Local; 61 | 62 | const body: any = await this.request(request.get, { 63 | uri: uc.getHost() + this.leetCodeApiProblems, 64 | headers: {}, 65 | timeout: uc.configs.timeout 66 | }); 67 | 68 | const json = JSON.parse(body); 69 | this.cacheProblems = (json.stat_status_pairs as any[]) 70 | .filter(p => !p.stat.question__hide) 71 | .map(function(p): IProblem { 72 | return { 73 | id: p.stat.question_id, 74 | fid: p.stat.frontend_question_id, 75 | name: p.stat.question__title, 76 | slug: p.stat.question__title_slug 77 | }; 78 | }); 79 | this.cacheSource = source; 80 | } 81 | 82 | public async fetchProblem(id: string, language: Language) : Promise { 83 | await this.updateProblems(); 84 | const problem: IProblem | undefined = this.cacheProblems.find((v: IProblem) => v.fid == id); 85 | if (!problem) { 86 | throw new Error("Invalid problem ID."); 87 | } 88 | if (!this.cacheId || this.cacheId != id) { 89 | const body: any = await this.request(request.post, { 90 | uri: uc.getHost() + this.leetCodeApiGraphql, 91 | headers: {}, 92 | timeout: uc.configs.timeout, 93 | json: true, 94 | body: { 95 | query: [ 96 | 'query getQuestionDetail($titleSlug: String!) {', 97 | ' question(titleSlug: $titleSlug) {', 98 | ' codeDefinition', 99 | ' sampleTestCase', 100 | ' }', 101 | '}' 102 | ].join('\n'), 103 | variables: {titleSlug: problem.slug}, 104 | operationName: 'getQuestionDetail' 105 | } 106 | }); 107 | const q = body.data.question; 108 | if (!q) { 109 | throw new Error("Invalid problem ID."); 110 | } 111 | this.cacheId = id; 112 | this.cacheContent = { 113 | codeDefinition: JSON.parse(q.codeDefinition), 114 | sampleTestCase: q.sampleTestCase 115 | }; 116 | } 117 | const code: any | undefined = (this.cacheContent.codeDefinition as any[]).find((p) => p.value == language.name); 118 | if (!code || !code.defaultCode) { 119 | throw new Error(`Cant find code definition with language: ${language.disp}.`); 120 | } 121 | return code.defaultCode; 122 | } 123 | } 124 | 125 | export const problemFetcher: ProblemFetcher = new ProblemFetcher(); -------------------------------------------------------------------------------- /src/util/stubCodeHelper.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import * as os from "os"; 3 | 4 | export class StubCodeHelper { 5 | private raw: string; 6 | private path: string; 7 | private front: string; 8 | private back: string; 9 | private installed: boolean; 10 | 11 | public constructor(doc: vscode.TextDocument) { 12 | this.raw = doc.getText(); 13 | this.path = doc.uri.fsPath; 14 | this.front = ""; 15 | this.back = ""; 16 | this.installed = false; 17 | } 18 | public getRaw(): string { 19 | return this.raw; 20 | } 21 | public setFront(front: string): void { 22 | if (this.installed) { 23 | return; 24 | } 25 | 26 | this.front = front; 27 | if (front != "") { 28 | this.front += os.EOL; 29 | } 30 | } 31 | public setBack(back: string): void { 32 | if (this.installed) { 33 | return; 34 | } 35 | 36 | if (back != "") { 37 | this.back = os.EOL + back; 38 | } 39 | else { 40 | this.back = back; 41 | } 42 | } 43 | private getDocumentEnd(editor: vscode.TextEditor): vscode.Position { 44 | return editor.document.lineAt(editor.document.lineCount - 1).range.end; 45 | } 46 | public async install(editor: vscode.TextEditor): Promise { 47 | console.log("front=", this.front); 48 | console.log("back=", this.back); 49 | this.installed = true; 50 | if (!await editor.edit((e: vscode.TextEditorEdit) => { 51 | e.insert(new vscode.Position(0, 0), this.front); 52 | e.insert(this.getDocumentEnd(editor), this.back); 53 | })) { 54 | throw Error(`Can not edit the solution text.`); 55 | } 56 | } 57 | public async uninstall(editor: vscode.TextEditor): Promise { 58 | if (this.installed) { 59 | await editor.edit((e: vscode.TextEditorEdit) => { 60 | const front: vscode.Range = new vscode.Range( 61 | new vscode.Position(0, 0), 62 | editor.document.positionAt(this.front.length) 63 | ); 64 | if (editor.document.getText(front) == this.front) { 65 | e.delete(front); 66 | } 67 | const end: vscode.Position = this.getDocumentEnd(editor); 68 | const back: vscode.Range = new vscode.Range( 69 | editor.document.positionAt(editor.document.offsetAt(end) - this.back.length), 70 | end 71 | ); 72 | if (editor.document.getText(back) == this.back) { 73 | e.delete(back); 74 | } 75 | }); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/util/stubFileHelper.ts: -------------------------------------------------------------------------------- 1 | import { Language } from "./config"; 2 | import * as fse from "fs-extra"; 3 | import * as path from "path" 4 | import * as vscode from "vscode" 5 | import * as uc from "./config" 6 | import * as glob from "glob" 7 | import * as iconv from "iconv-lite" 8 | 9 | export interface StubFile { 10 | relative: string; 11 | content: string; 12 | } 13 | 14 | export class StubFileHelper { 15 | public files: StubFile[]; 16 | constructor(private token: string, public resourcesPath: string, private encoding = "utf8") { 17 | this.files = []; 18 | this.validate(); 19 | } 20 | private validate() { 21 | try { 22 | iconv.encode("", this.encoding); 23 | } 24 | catch { 25 | throw new Error(`Encoding not recognized: '${this.encoding}'`); 26 | } 27 | } 28 | private async check(filePath: string): Promise { 29 | return (iconv.decode(await fse.readFile(filePath), this.encoding)).indexOf(this.token) >= 0; 30 | } 31 | private async foreach(dir: string, cb: (stub: StubFile, filePath: string, exists: boolean) => void) { 32 | for (const stub of this.files) { 33 | const file: string = path.join(dir, stub.relative); 34 | const exists: boolean = fse.existsSync(file); 35 | if (exists) { 36 | if (!await this.check(file)) { 37 | throw new Error(`Token missed in file: ${file}`); 38 | } 39 | } 40 | cb(stub, file, exists); 41 | } 42 | } 43 | public async install(dir: string) { 44 | await this.foreach(dir, async (stub, file) => { 45 | await fse.writeFile(file, iconv.encode(this.token + "\n\n" + stub.content, this.encoding)); 46 | }); 47 | } 48 | public async uninstall(dir: string) { 49 | await this.foreach(dir, async (stub, file, exists) => { 50 | if (exists) { 51 | await fse.remove(file); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | class StubFileHelperFactory { 58 | private context: vscode.ExtensionContext | undefined; 59 | public initialize(context: vscode.ExtensionContext) { 60 | this.context = context; 61 | } 62 | public async create(language: Language, filePath: string): Promise { 63 | if (!this.context) { 64 | return; 65 | } 66 | const res: string = this.context.asAbsolutePath(path.join(uc.configs.resourcesPath, uc.configs.codePath, language.name)); 67 | if (!await fse.pathExists(res)) { 68 | return; 69 | } 70 | //const fileName: string = path.basename(filePath); 71 | //const oEncoding: string = (/.*[\u4e00-\u9fa5]+.*$/.test(fileName)) ? "gbk" : "utf8"; 72 | const oEncoding: string | undefined = uc.getEncoding(); 73 | const stubFileHelper = new StubFileHelper(language.commet.begin + ' ' + uc.configs.token + ' ' + language.commet.end, res, oEncoding ? oEncoding : "utf8"); 74 | const files: string[] = glob.sync(language.stub, { 75 | cwd: res, 76 | nodir: true 77 | }); 78 | for (const file of files) { 79 | stubFileHelper.files.push({ 80 | relative: file, 81 | content: await fse.readFile(path.join(res, file), "utf8") 82 | }) 83 | } 84 | return stubFileHelper; 85 | } 86 | } 87 | 88 | export const stubFileHelperFactory = new StubFileHelperFactory(); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true /* enable all strict type-checking options */ 12 | /* Additional Checks */ 13 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 14 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 15 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".vscode-test" 20 | ] 21 | } 22 | --------------------------------------------------------------------------------