mirror of
https://code.forgejo.org/actions/setup-node.git
synced 2025-05-20 05:14:44 +00:00
.
This commit is contained in:
parent
fc725ba36b
commit
422b9fdb15
7395 changed files with 1786235 additions and 3476 deletions
20
node_modules/jsesc/LICENSE-MIT.txt
generated
vendored
Normal file
20
node_modules/jsesc/LICENSE-MIT.txt
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
Copyright Mathias Bynens <https://mathiasbynens.be/>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
421
node_modules/jsesc/README.md
generated
vendored
Normal file
421
node_modules/jsesc/README.md
generated
vendored
Normal file
|
@ -0,0 +1,421 @@
|
|||
# jsesc [](https://travis-ci.org/mathiasbynens/jsesc) [](https://coveralls.io/r/mathiasbynens/jsesc) [](https://gemnasium.com/mathiasbynens/jsesc)
|
||||
|
||||
Given some data, _jsesc_ returns a stringified representation of that data. jsesc is similar to `JSON.stringify()` except:
|
||||
|
||||
1. it outputs JavaScript instead of JSON [by default](#json), enabling support for data structures like ES6 maps and sets;
|
||||
2. it offers [many options](#api) to customize the output;
|
||||
3. its output is ASCII-safe [by default](#minimal), thanks to its use of [escape sequences](https://mathiasbynens.be/notes/javascript-escapes) where needed.
|
||||
|
||||
For any input, jsesc generates the shortest possible valid printable-ASCII-only output. [Here’s an online demo.](https://mothereff.in/js-escapes)
|
||||
|
||||
jsesc’s output can be used instead of `JSON.stringify`’s to avoid [mojibake](https://en.wikipedia.org/wiki/Mojibake) and other encoding issues, or even to [avoid errors](https://twitter.com/annevk/status/380000829643571200) when passing JSON-formatted data (which may contain U+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATOR, or [lone surrogates](https://esdiscuss.org/topic/code-points-vs-unicode-scalar-values#content-14)) to a JavaScript parser or an UTF-8 encoder.
|
||||
|
||||
## Installation
|
||||
|
||||
Via [npm](https://www.npmjs.com/):
|
||||
|
||||
```bash
|
||||
npm install jsesc
|
||||
```
|
||||
|
||||
In [Node.js](https://nodejs.org/):
|
||||
|
||||
```js
|
||||
const jsesc = require('jsesc');
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `jsesc(value, options)`
|
||||
|
||||
This function takes a value and returns an escaped version of the value where any characters that are not printable ASCII symbols are escaped using the shortest possible (but valid) [escape sequences for use in JavaScript strings](https://mathiasbynens.be/notes/javascript-escapes). The first supported value type is strings:
|
||||
|
||||
```js
|
||||
jsesc('Ich ♥ Bücher');
|
||||
// → 'Ich \\u2665 B\\xFCcher'
|
||||
|
||||
jsesc('foo 𝌆 bar');
|
||||
// → 'foo \\uD834\\uDF06 bar'
|
||||
```
|
||||
|
||||
Instead of a string, the `value` can also be an array, an object, a map, a set, or a buffer. In such cases, `jsesc` returns a stringified version of the value where any characters that are not printable ASCII symbols are escaped in the same way.
|
||||
|
||||
```js
|
||||
// Escaping an array
|
||||
jsesc([
|
||||
'Ich ♥ Bücher', 'foo 𝌆 bar'
|
||||
]);
|
||||
// → '[\'Ich \\u2665 B\\xFCcher\',\'foo \\uD834\\uDF06 bar\']'
|
||||
|
||||
// Escaping an object
|
||||
jsesc({
|
||||
'Ich ♥ Bücher': 'foo 𝌆 bar'
|
||||
});
|
||||
// → '{\'Ich \\u2665 B\\xFCcher\':\'foo \\uD834\\uDF06 bar\'}'
|
||||
```
|
||||
|
||||
The optional `options` argument accepts an object with the following options:
|
||||
|
||||
#### `quotes`
|
||||
|
||||
The default value for the `quotes` option is `'single'`. This means that any occurrences of `'` in the input string are escaped as `\'`, so that the output can be used in a string literal wrapped in single quotes.
|
||||
|
||||
```js
|
||||
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.');
|
||||
// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.'
|
||||
|
||||
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
|
||||
'quotes': 'single'
|
||||
});
|
||||
// → '`Lorem` ipsum "dolor" sit \\\'amet\\\' etc.'
|
||||
// → "`Lorem` ipsum \"dolor\" sit \\'amet\\' etc."
|
||||
```
|
||||
|
||||
If you want to use the output as part of a string literal wrapped in double quotes, set the `quotes` option to `'double'`.
|
||||
|
||||
```js
|
||||
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
|
||||
'quotes': 'double'
|
||||
});
|
||||
// → '`Lorem` ipsum \\"dolor\\" sit \'amet\' etc.'
|
||||
// → "`Lorem` ipsum \\\"dolor\\\" sit 'amet' etc."
|
||||
```
|
||||
|
||||
If you want to use the output as part of a template literal (i.e. wrapped in backticks), set the `quotes` option to `'backtick'`.
|
||||
|
||||
```js
|
||||
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
|
||||
'quotes': 'backtick'
|
||||
});
|
||||
// → '\\`Lorem\\` ipsum "dolor" sit \'amet\' etc.'
|
||||
// → "\\`Lorem\\` ipsum \"dolor\" sit 'amet' etc."
|
||||
// → `\\\`Lorem\\\` ipsum "dolor" sit 'amet' etc.`
|
||||
```
|
||||
|
||||
This setting also affects the output for arrays and objects:
|
||||
|
||||
```js
|
||||
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
|
||||
'quotes': 'double'
|
||||
});
|
||||
// → '{"Ich \\u2665 B\\xFCcher":"foo \\uD834\\uDF06 bar"}'
|
||||
|
||||
jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
|
||||
'quotes': 'double'
|
||||
});
|
||||
// → '["Ich \\u2665 B\\xFCcher","foo \\uD834\\uDF06 bar"]'
|
||||
```
|
||||
|
||||
#### `numbers`
|
||||
|
||||
The default value for the `numbers` option is `'decimal'`. This means that any numeric values are represented using decimal integer literals. Other valid options are `binary`, `octal`, and `hexadecimal`, which result in binary integer literals, octal integer literals, and hexadecimal integer literals, respectively.
|
||||
|
||||
```js
|
||||
jsesc(42, {
|
||||
'numbers': 'binary'
|
||||
});
|
||||
// → '0b101010'
|
||||
|
||||
jsesc(42, {
|
||||
'numbers': 'octal'
|
||||
});
|
||||
// → '0o52'
|
||||
|
||||
jsesc(42, {
|
||||
'numbers': 'decimal'
|
||||
});
|
||||
// → '42'
|
||||
|
||||
jsesc(42, {
|
||||
'numbers': 'hexadecimal'
|
||||
});
|
||||
// → '0x2A'
|
||||
```
|
||||
|
||||
#### `wrap`
|
||||
|
||||
The `wrap` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, the output is a valid JavaScript string literal wrapped in quotes. The type of quotes can be specified through the `quotes` setting.
|
||||
|
||||
```js
|
||||
jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
|
||||
'quotes': 'single',
|
||||
'wrap': true
|
||||
});
|
||||
// → '\'Lorem ipsum "dolor" sit \\\'amet\\\' etc.\''
|
||||
// → "\'Lorem ipsum \"dolor\" sit \\\'amet\\\' etc.\'"
|
||||
|
||||
jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
|
||||
'quotes': 'double',
|
||||
'wrap': true
|
||||
});
|
||||
// → '"Lorem ipsum \\"dolor\\" sit \'amet\' etc."'
|
||||
// → "\"Lorem ipsum \\\"dolor\\\" sit \'amet\' etc.\""
|
||||
```
|
||||
|
||||
#### `es6`
|
||||
|
||||
The `es6` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, any astral Unicode symbols in the input are escaped using [ECMAScript 6 Unicode code point escape sequences](https://mathiasbynens.be/notes/javascript-escapes#unicode-code-point) instead of using separate escape sequences for each surrogate half. If backwards compatibility with ES5 environments is a concern, don’t enable this setting. If the `json` setting is enabled, the value for the `es6` setting is ignored (as if it was `false`).
|
||||
|
||||
```js
|
||||
// By default, the `es6` option is disabled:
|
||||
jsesc('foo 𝌆 bar 💩 baz');
|
||||
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz'
|
||||
|
||||
// To explicitly disable it:
|
||||
jsesc('foo 𝌆 bar 💩 baz', {
|
||||
'es6': false
|
||||
});
|
||||
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz'
|
||||
|
||||
// To enable it:
|
||||
jsesc('foo 𝌆 bar 💩 baz', {
|
||||
'es6': true
|
||||
});
|
||||
// → 'foo \\u{1D306} bar \\u{1F4A9} baz'
|
||||
```
|
||||
|
||||
#### `escapeEverything`
|
||||
|
||||
The `escapeEverything` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, all the symbols in the output are escaped — even printable ASCII symbols.
|
||||
|
||||
```js
|
||||
jsesc('lolwat"foo\'bar', {
|
||||
'escapeEverything': true
|
||||
});
|
||||
// → '\\x6C\\x6F\\x6C\\x77\\x61\\x74\\"\\x66\\x6F\\x6F\\\'\\x62\\x61\\x72'
|
||||
// → "\\x6C\\x6F\\x6C\\x77\\x61\\x74\\\"\\x66\\x6F\\x6F\\'\\x62\\x61\\x72"
|
||||
```
|
||||
|
||||
This setting also affects the output for string literals within arrays and objects.
|
||||
|
||||
#### `minimal`
|
||||
|
||||
The `minimal` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, only a limited set of symbols in the output are escaped:
|
||||
|
||||
* U+0000 `\0`
|
||||
* U+0008 `\b`
|
||||
* U+0009 `\t`
|
||||
* U+000A `\n`
|
||||
* U+000C `\f`
|
||||
* U+000D `\r`
|
||||
* U+005C `\\`
|
||||
* U+2028 `\u2028`
|
||||
* U+2029 `\u2029`
|
||||
* whatever symbol is being used for wrapping string literals (based on [the `quotes` option](#quotes))
|
||||
|
||||
Note: with this option enabled, jsesc output is no longer guaranteed to be ASCII-safe.
|
||||
|
||||
```js
|
||||
jsesc('foo\u2029bar\nbaz©qux𝌆flops', {
|
||||
'minimal': false
|
||||
});
|
||||
// → 'foo\\u2029bar\\nbaz©qux𝌆flops'
|
||||
```
|
||||
|
||||
#### `isScriptContext`
|
||||
|
||||
The `isScriptContext` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, occurrences of [`</script` and `</style`](https://mathiasbynens.be/notes/etago) in the output are escaped as `<\/script` and `<\/style`, and [`<!--`](https://mathiasbynens.be/notes/etago#comment-8) is escaped as `\x3C!--` (or `\u003C!--` when the `json` option is enabled). This setting is useful when jsesc’s output ends up as part of a `<script>` or `<style>` element in an HTML document.
|
||||
|
||||
```js
|
||||
jsesc('foo</script>bar', {
|
||||
'isScriptContext': true
|
||||
});
|
||||
// → 'foo<\\/script>bar'
|
||||
```
|
||||
|
||||
#### `compact`
|
||||
|
||||
The `compact` option takes a boolean value (`true` or `false`), and defaults to `true` (enabled). When enabled, the output for arrays and objects is as compact as possible; it’s not formatted nicely.
|
||||
|
||||
```js
|
||||
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
|
||||
'compact': true // this is the default
|
||||
});
|
||||
// → '{\'Ich \u2665 B\xFCcher\':\'foo \uD834\uDF06 bar\'}'
|
||||
|
||||
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
|
||||
'compact': false
|
||||
});
|
||||
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'
|
||||
|
||||
jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
|
||||
'compact': false
|
||||
});
|
||||
// → '[\n\t\'Ich \u2665 B\xFCcher\',\n\t\'foo \uD834\uDF06 bar\'\n]'
|
||||
```
|
||||
|
||||
This setting has no effect on the output for strings.
|
||||
|
||||
#### `indent`
|
||||
|
||||
The `indent` option takes a string value, and defaults to `'\t'`. When the `compact` setting is enabled (`true`), the value of the `indent` option is used to format the output for arrays and objects.
|
||||
|
||||
```js
|
||||
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
|
||||
'compact': false,
|
||||
'indent': '\t' // this is the default
|
||||
});
|
||||
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'
|
||||
|
||||
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
|
||||
'compact': false,
|
||||
'indent': ' '
|
||||
});
|
||||
// → '{\n \'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'
|
||||
|
||||
jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
|
||||
'compact': false,
|
||||
'indent': ' '
|
||||
});
|
||||
// → '[\n \'Ich \u2665 B\xFCcher\',\n\ t\'foo \uD834\uDF06 bar\'\n]'
|
||||
```
|
||||
|
||||
This setting has no effect on the output for strings.
|
||||
|
||||
#### `indentLevel`
|
||||
|
||||
The `indentLevel` option takes a numeric value, and defaults to `0`. It represents the current indentation level, i.e. the number of times the value of [the `indent` option](#indent) is repeated.
|
||||
|
||||
```js
|
||||
jsesc(['a', 'b', 'c'], {
|
||||
'compact': false,
|
||||
'indentLevel': 1
|
||||
});
|
||||
// → '[\n\t\t\'a\',\n\t\t\'b\',\n\t\t\'c\'\n\t]'
|
||||
|
||||
jsesc(['a', 'b', 'c'], {
|
||||
'compact': false,
|
||||
'indentLevel': 2
|
||||
});
|
||||
// → '[\n\t\t\t\'a\',\n\t\t\t\'b\',\n\t\t\t\'c\'\n\t\t]'
|
||||
```
|
||||
|
||||
#### `json`
|
||||
|
||||
The `json` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, the output is valid JSON. [Hexadecimal character escape sequences](https://mathiasbynens.be/notes/javascript-escapes#hexadecimal) and [the `\v` or `\0` escape sequences](https://mathiasbynens.be/notes/javascript-escapes#single) are not used. Setting `json: true` implies `quotes: 'double', wrap: true, es6: false`, although these values can still be overridden if needed — but in such cases, the output won’t be valid JSON anymore.
|
||||
|
||||
```js
|
||||
jsesc('foo\x00bar\xFF\uFFFDbaz', {
|
||||
'json': true
|
||||
});
|
||||
// → '"foo\\u0000bar\\u00FF\\uFFFDbaz"'
|
||||
|
||||
jsesc({ 'foo\x00bar\xFF\uFFFDbaz': 'foo\x00bar\xFF\uFFFDbaz' }, {
|
||||
'json': true
|
||||
});
|
||||
// → '{"foo\\u0000bar\\u00FF\\uFFFDbaz":"foo\\u0000bar\\u00FF\\uFFFDbaz"}'
|
||||
|
||||
jsesc([ 'foo\x00bar\xFF\uFFFDbaz', 'foo\x00bar\xFF\uFFFDbaz' ], {
|
||||
'json': true
|
||||
});
|
||||
// → '["foo\\u0000bar\\u00FF\\uFFFDbaz","foo\\u0000bar\\u00FF\\uFFFDbaz"]'
|
||||
|
||||
// Values that are acceptable in JSON but aren’t strings, arrays, or object
|
||||
// literals can’t be escaped, so they’ll just be preserved:
|
||||
jsesc([ 'foo\x00bar', [1, '©', { 'foo': true, 'qux': null }], 42 ], {
|
||||
'json': true
|
||||
});
|
||||
// → '["foo\\u0000bar",[1,"\\u00A9",{"foo":true,"qux":null}],42]'
|
||||
// Values that aren’t allowed in JSON are run through `JSON.stringify()`:
|
||||
jsesc([ undefined, -Infinity ], {
|
||||
'json': true
|
||||
});
|
||||
// → '[null,null]'
|
||||
```
|
||||
|
||||
**Note:** Using this option on objects or arrays that contain non-string values relies on `JSON.stringify()`. For legacy environments like IE ≤ 7, use [a `JSON` polyfill](http://bestiejs.github.io/json3/).
|
||||
|
||||
#### `lowercaseHex`
|
||||
|
||||
The `lowercaseHex` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, any alphabetical hexadecimal digits in escape sequences as well as any hexadecimal integer literals (see [the `numbers` option](#numbers)) in the output are in lowercase.
|
||||
|
||||
```js
|
||||
jsesc('Ich ♥ Bücher', {
|
||||
'lowercaseHex': true
|
||||
});
|
||||
// → 'Ich \\u2665 B\\xfccher'
|
||||
// ^^
|
||||
|
||||
jsesc(42, {
|
||||
'numbers': 'hexadecimal',
|
||||
'lowercaseHex': true
|
||||
});
|
||||
// → '0x2a'
|
||||
// ^^
|
||||
```
|
||||
|
||||
### `jsesc.version`
|
||||
|
||||
A string representing the semantic version number.
|
||||
|
||||
### Using the `jsesc` binary
|
||||
|
||||
To use the `jsesc` binary in your shell, simply install jsesc globally using npm:
|
||||
|
||||
```bash
|
||||
npm install -g jsesc
|
||||
```
|
||||
|
||||
After that you’re able to escape strings from the command line:
|
||||
|
||||
```bash
|
||||
$ jsesc 'föo ♥ bår 𝌆 baz'
|
||||
f\xF6o \u2665 b\xE5r \uD834\uDF06 baz
|
||||
```
|
||||
|
||||
To escape arrays or objects containing string values, use the `-o`/`--object` option:
|
||||
|
||||
```bash
|
||||
$ jsesc --object '{ "föo": "♥", "bår": "𝌆 baz" }'
|
||||
{'f\xF6o':'\u2665','b\xE5r':'\uD834\uDF06 baz'}
|
||||
```
|
||||
|
||||
To prettify the output in such cases, use the `-p`/`--pretty` option:
|
||||
|
||||
```bash
|
||||
$ jsesc --pretty '{ "föo": "♥", "bår": "𝌆 baz" }'
|
||||
{
|
||||
'f\xF6o': '\u2665',
|
||||
'b\xE5r': '\uD834\uDF06 baz'
|
||||
}
|
||||
```
|
||||
|
||||
For valid JSON output, use the `-j`/`--json` option:
|
||||
|
||||
```bash
|
||||
$ jsesc --json --pretty '{ "föo": "♥", "bår": "𝌆 baz" }'
|
||||
{
|
||||
"f\u00F6o": "\u2665",
|
||||
"b\u00E5r": "\uD834\uDF06 baz"
|
||||
}
|
||||
```
|
||||
|
||||
Read a local JSON file, escape any non-ASCII symbols, and save the result to a new file:
|
||||
|
||||
```bash
|
||||
$ jsesc --json --object < data-raw.json > data-escaped.json
|
||||
```
|
||||
|
||||
Or do the same with an online JSON file:
|
||||
|
||||
```bash
|
||||
$ curl -sL "http://git.io/aorKgQ" | jsesc --json --object > data-escaped.json
|
||||
```
|
||||
|
||||
See `jsesc --help` for the full list of options.
|
||||
|
||||
## Support
|
||||
|
||||
As of v2.0.0, jsesc supports Node.js v4+ only.
|
||||
|
||||
Older versions (up to jsesc v1.3.0) support Chrome 27, Firefox 3, Safari 4, Opera 10, IE 6, Node.js v6.0.0, Narwhal 0.3.2, RingoJS 0.8-0.11, PhantomJS 1.9.0, and Rhino 1.7RC4. **Note:** Using the `json` option on objects or arrays that contain non-string values relies on `JSON.parse()`. For legacy environments like IE ≤ 7, use [a `JSON` polyfill](https://bestiejs.github.io/json3/).
|
||||
|
||||
## Author
|
||||
|
||||
| [](https://twitter.com/mathias "Follow @mathias on Twitter") |
|
||||
|---|
|
||||
| [Mathias Bynens](https://mathiasbynens.be/) |
|
||||
|
||||
## License
|
||||
|
||||
This library is available under the [MIT](https://mths.be/mit) license.
|
148
node_modules/jsesc/bin/jsesc
generated
vendored
Executable file
148
node_modules/jsesc/bin/jsesc
generated
vendored
Executable file
|
@ -0,0 +1,148 @@
|
|||
#!/usr/bin/env node
|
||||
(function() {
|
||||
|
||||
var fs = require('fs');
|
||||
var stringEscape = require('../jsesc.js');
|
||||
var strings = process.argv.splice(2);
|
||||
var stdin = process.stdin;
|
||||
var data;
|
||||
var timeout;
|
||||
var isObject = false;
|
||||
var options = {};
|
||||
var log = console.log;
|
||||
|
||||
var main = function() {
|
||||
var option = strings[0];
|
||||
|
||||
if (/^(?:-h|--help|undefined)$/.test(option)) {
|
||||
log(
|
||||
'jsesc v%s - https://mths.be/jsesc',
|
||||
stringEscape.version
|
||||
);
|
||||
log([
|
||||
'\nUsage:\n',
|
||||
'\tjsesc [string]',
|
||||
'\tjsesc [-s | --single-quotes] [string]',
|
||||
'\tjsesc [-d | --double-quotes] [string]',
|
||||
'\tjsesc [-w | --wrap] [string]',
|
||||
'\tjsesc [-e | --escape-everything] [string]',
|
||||
'\tjsesc [-t | --escape-etago] [string]',
|
||||
'\tjsesc [-6 | --es6] [string]',
|
||||
'\tjsesc [-l | --lowercase-hex] [string]',
|
||||
'\tjsesc [-j | --json] [string]',
|
||||
'\tjsesc [-o | --object] [stringified_object]', // `JSON.parse()` the argument
|
||||
'\tjsesc [-p | --pretty] [string]', // `compact: false`
|
||||
'\tjsesc [-v | --version]',
|
||||
'\tjsesc [-h | --help]',
|
||||
'\nExamples:\n',
|
||||
'\tjsesc \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'',
|
||||
'\tjsesc --json \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'',
|
||||
'\tjsesc --json --escape-everything \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'',
|
||||
'\tjsesc --double-quotes --wrap \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'',
|
||||
'\techo \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\' | jsesc'
|
||||
].join('\n'));
|
||||
return process.exit(1);
|
||||
}
|
||||
|
||||
if (/^(?:-v|--version)$/.test(option)) {
|
||||
log('v%s', stringEscape.version);
|
||||
return process.exit(1);
|
||||
}
|
||||
|
||||
strings.forEach(function(string) {
|
||||
// Process options
|
||||
if (/^(?:-s|--single-quotes)$/.test(string)) {
|
||||
options.quotes = 'single';
|
||||
return;
|
||||
}
|
||||
if (/^(?:-d|--double-quotes)$/.test(string)) {
|
||||
options.quotes = 'double';
|
||||
return;
|
||||
}
|
||||
if (/^(?:-w|--wrap)$/.test(string)) {
|
||||
options.wrap = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-e|--escape-everything)$/.test(string)) {
|
||||
options.escapeEverything = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-t|--escape-etago)$/.test(string)) {
|
||||
options.escapeEtago = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-6|--es6)$/.test(string)) {
|
||||
options.es6 = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-l|--lowercase-hex)$/.test(string)) {
|
||||
options.lowercaseHex = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-j|--json)$/.test(string)) {
|
||||
options.json = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-o|--object)$/.test(string)) {
|
||||
isObject = true;
|
||||
return;
|
||||
}
|
||||
if (/^(?:-p|--pretty)$/.test(string)) {
|
||||
isObject = true;
|
||||
options.compact = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Process string(s)
|
||||
var result;
|
||||
try {
|
||||
if (isObject) {
|
||||
string = JSON.parse(string);
|
||||
}
|
||||
result = stringEscape(string, options);
|
||||
log(result);
|
||||
} catch(error) {
|
||||
log(error.message + '\n');
|
||||
log('Error: failed to escape.');
|
||||
log('If you think this is a bug in jsesc, please report it:');
|
||||
log('https://github.com/mathiasbynens/jsesc/issues/new');
|
||||
log(
|
||||
'\nStack trace using jsesc@%s:\n',
|
||||
stringEscape.version
|
||||
);
|
||||
log(error.stack);
|
||||
return process.exit(1);
|
||||
}
|
||||
});
|
||||
// Return with exit status 0 outside of the `forEach` loop, in case
|
||||
// multiple strings were passed in.
|
||||
return process.exit(0);
|
||||
|
||||
};
|
||||
|
||||
if (stdin.isTTY) {
|
||||
// handle shell arguments
|
||||
main();
|
||||
} else {
|
||||
// Either the script is called from within a non-TTY context,
|
||||
// or `stdin` content is being piped in.
|
||||
if (!process.stdout.isTTY) { // called from a non-TTY context
|
||||
timeout = setTimeout(function() {
|
||||
// if no piped data arrived after a while, handle shell arguments
|
||||
main();
|
||||
}, 250);
|
||||
}
|
||||
|
||||
data = '';
|
||||
stdin.on('data', function(chunk) {
|
||||
clearTimeout(timeout);
|
||||
data += chunk;
|
||||
});
|
||||
stdin.on('end', function() {
|
||||
strings.push(data.trim());
|
||||
main();
|
||||
});
|
||||
stdin.resume();
|
||||
}
|
||||
|
||||
}());
|
329
node_modules/jsesc/jsesc.js
generated
vendored
Normal file
329
node_modules/jsesc/jsesc.js
generated
vendored
Normal file
|
@ -0,0 +1,329 @@
|
|||
'use strict';
|
||||
|
||||
const object = {};
|
||||
const hasOwnProperty = object.hasOwnProperty;
|
||||
const forOwn = (object, callback) => {
|
||||
for (const key in object) {
|
||||
if (hasOwnProperty.call(object, key)) {
|
||||
callback(key, object[key]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const extend = (destination, source) => {
|
||||
if (!source) {
|
||||
return destination;
|
||||
}
|
||||
forOwn(source, (key, value) => {
|
||||
destination[key] = value;
|
||||
});
|
||||
return destination;
|
||||
};
|
||||
|
||||
const forEach = (array, callback) => {
|
||||
const length = array.length;
|
||||
let index = -1;
|
||||
while (++index < length) {
|
||||
callback(array[index]);
|
||||
}
|
||||
};
|
||||
|
||||
const toString = object.toString;
|
||||
const isArray = Array.isArray;
|
||||
const isBuffer = Buffer.isBuffer;
|
||||
const isObject = (value) => {
|
||||
// This is a very simple check, but it’s good enough for what we need.
|
||||
return toString.call(value) == '[object Object]';
|
||||
};
|
||||
const isString = (value) => {
|
||||
return typeof value == 'string' ||
|
||||
toString.call(value) == '[object String]';
|
||||
};
|
||||
const isNumber = (value) => {
|
||||
return typeof value == 'number' ||
|
||||
toString.call(value) == '[object Number]';
|
||||
};
|
||||
const isFunction = (value) => {
|
||||
return typeof value == 'function';
|
||||
};
|
||||
const isMap = (value) => {
|
||||
return toString.call(value) == '[object Map]';
|
||||
};
|
||||
const isSet = (value) => {
|
||||
return toString.call(value) == '[object Set]';
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// https://mathiasbynens.be/notes/javascript-escapes#single
|
||||
const singleEscapes = {
|
||||
'"': '\\"',
|
||||
'\'': '\\\'',
|
||||
'\\': '\\\\',
|
||||
'\b': '\\b',
|
||||
'\f': '\\f',
|
||||
'\n': '\\n',
|
||||
'\r': '\\r',
|
||||
'\t': '\\t'
|
||||
// `\v` is omitted intentionally, because in IE < 9, '\v' == 'v'.
|
||||
// '\v': '\\x0B'
|
||||
};
|
||||
const regexSingleEscape = /["'\\\b\f\n\r\t]/;
|
||||
|
||||
const regexDigit = /[0-9]/;
|
||||
const regexWhitelist = /[ !#-&\(-\[\]-_a-~]/;
|
||||
|
||||
const jsesc = (argument, options) => {
|
||||
const increaseIndentation = () => {
|
||||
oldIndent = indent;
|
||||
++options.indentLevel;
|
||||
indent = options.indent.repeat(options.indentLevel)
|
||||
};
|
||||
// Handle options
|
||||
const defaults = {
|
||||
'escapeEverything': false,
|
||||
'minimal': false,
|
||||
'isScriptContext': false,
|
||||
'quotes': 'single',
|
||||
'wrap': false,
|
||||
'es6': false,
|
||||
'json': false,
|
||||
'compact': true,
|
||||
'lowercaseHex': false,
|
||||
'numbers': 'decimal',
|
||||
'indent': '\t',
|
||||
'indentLevel': 0,
|
||||
'__inline1__': false,
|
||||
'__inline2__': false
|
||||
};
|
||||
const json = options && options.json;
|
||||
if (json) {
|
||||
defaults.quotes = 'double';
|
||||
defaults.wrap = true;
|
||||
}
|
||||
options = extend(defaults, options);
|
||||
if (
|
||||
options.quotes != 'single' &&
|
||||
options.quotes != 'double' &&
|
||||
options.quotes != 'backtick'
|
||||
) {
|
||||
options.quotes = 'single';
|
||||
}
|
||||
const quote = options.quotes == 'double' ?
|
||||
'"' :
|
||||
(options.quotes == 'backtick' ?
|
||||
'`' :
|
||||
'\''
|
||||
);
|
||||
const compact = options.compact;
|
||||
const lowercaseHex = options.lowercaseHex;
|
||||
let indent = options.indent.repeat(options.indentLevel);
|
||||
let oldIndent = '';
|
||||
const inline1 = options.__inline1__;
|
||||
const inline2 = options.__inline2__;
|
||||
const newLine = compact ? '' : '\n';
|
||||
let result;
|
||||
let isEmpty = true;
|
||||
const useBinNumbers = options.numbers == 'binary';
|
||||
const useOctNumbers = options.numbers == 'octal';
|
||||
const useDecNumbers = options.numbers == 'decimal';
|
||||
const useHexNumbers = options.numbers == 'hexadecimal';
|
||||
|
||||
if (json && argument && isFunction(argument.toJSON)) {
|
||||
argument = argument.toJSON();
|
||||
}
|
||||
|
||||
if (!isString(argument)) {
|
||||
if (isMap(argument)) {
|
||||
if (argument.size == 0) {
|
||||
return 'new Map()';
|
||||
}
|
||||
if (!compact) {
|
||||
options.__inline1__ = true;
|
||||
options.__inline2__ = false;
|
||||
}
|
||||
return 'new Map(' + jsesc(Array.from(argument), options) + ')';
|
||||
}
|
||||
if (isSet(argument)) {
|
||||
if (argument.size == 0) {
|
||||
return 'new Set()';
|
||||
}
|
||||
return 'new Set(' + jsesc(Array.from(argument), options) + ')';
|
||||
}
|
||||
if (isBuffer(argument)) {
|
||||
if (argument.length == 0) {
|
||||
return 'Buffer.from([])';
|
||||
}
|
||||
return 'Buffer.from(' + jsesc(Array.from(argument), options) + ')';
|
||||
}
|
||||
if (isArray(argument)) {
|
||||
result = [];
|
||||
options.wrap = true;
|
||||
if (inline1) {
|
||||
options.__inline1__ = false;
|
||||
options.__inline2__ = true;
|
||||
}
|
||||
if (!inline2) {
|
||||
increaseIndentation();
|
||||
}
|
||||
forEach(argument, (value) => {
|
||||
isEmpty = false;
|
||||
if (inline2) {
|
||||
options.__inline2__ = false;
|
||||
}
|
||||
result.push(
|
||||
(compact || inline2 ? '' : indent) +
|
||||
jsesc(value, options)
|
||||
);
|
||||
});
|
||||
if (isEmpty) {
|
||||
return '[]';
|
||||
}
|
||||
if (inline2) {
|
||||
return '[' + result.join(', ') + ']';
|
||||
}
|
||||
return '[' + newLine + result.join(',' + newLine) + newLine +
|
||||
(compact ? '' : oldIndent) + ']';
|
||||
} else if (isNumber(argument)) {
|
||||
if (json) {
|
||||
// Some number values (e.g. `Infinity`) cannot be represented in JSON.
|
||||
return JSON.stringify(argument);
|
||||
}
|
||||
if (useDecNumbers) {
|
||||
return String(argument);
|
||||
}
|
||||
if (useHexNumbers) {
|
||||
let hexadecimal = argument.toString(16);
|
||||
if (!lowercaseHex) {
|
||||
hexadecimal = hexadecimal.toUpperCase();
|
||||
}
|
||||
return '0x' + hexadecimal;
|
||||
}
|
||||
if (useBinNumbers) {
|
||||
return '0b' + argument.toString(2);
|
||||
}
|
||||
if (useOctNumbers) {
|
||||
return '0o' + argument.toString(8);
|
||||
}
|
||||
} else if (!isObject(argument)) {
|
||||
if (json) {
|
||||
// For some values (e.g. `undefined`, `function` objects),
|
||||
// `JSON.stringify(value)` returns `undefined` (which isn’t valid
|
||||
// JSON) instead of `'null'`.
|
||||
return JSON.stringify(argument) || 'null';
|
||||
}
|
||||
return String(argument);
|
||||
} else { // it’s an object
|
||||
result = [];
|
||||
options.wrap = true;
|
||||
increaseIndentation();
|
||||
forOwn(argument, (key, value) => {
|
||||
isEmpty = false;
|
||||
result.push(
|
||||
(compact ? '' : indent) +
|
||||
jsesc(key, options) + ':' +
|
||||
(compact ? '' : ' ') +
|
||||
jsesc(value, options)
|
||||
);
|
||||
});
|
||||
if (isEmpty) {
|
||||
return '{}';
|
||||
}
|
||||
return '{' + newLine + result.join(',' + newLine) + newLine +
|
||||
(compact ? '' : oldIndent) + '}';
|
||||
}
|
||||
}
|
||||
|
||||
const string = argument;
|
||||
// Loop over each code unit in the string and escape it
|
||||
let index = -1;
|
||||
const length = string.length;
|
||||
result = '';
|
||||
while (++index < length) {
|
||||
const character = string.charAt(index);
|
||||
if (options.es6) {
|
||||
const first = string.charCodeAt(index);
|
||||
if ( // check if it’s the start of a surrogate pair
|
||||
first >= 0xD800 && first <= 0xDBFF && // high surrogate
|
||||
length > index + 1 // there is a next code unit
|
||||
) {
|
||||
const second = string.charCodeAt(index + 1);
|
||||
if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
|
||||
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
const codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
|
||||
let hexadecimal = codePoint.toString(16);
|
||||
if (!lowercaseHex) {
|
||||
hexadecimal = hexadecimal.toUpperCase();
|
||||
}
|
||||
result += '\\u{' + hexadecimal + '}';
|
||||
++index;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!options.escapeEverything) {
|
||||
if (regexWhitelist.test(character)) {
|
||||
// It’s a printable ASCII character that is not `"`, `'` or `\`,
|
||||
// so don’t escape it.
|
||||
result += character;
|
||||
continue;
|
||||
}
|
||||
if (character == '"') {
|
||||
result += quote == character ? '\\"' : character;
|
||||
continue;
|
||||
}
|
||||
if (character == '`') {
|
||||
result += quote == character ? '\\`' : character;
|
||||
continue;
|
||||
}
|
||||
if (character == '\'') {
|
||||
result += quote == character ? '\\\'' : character;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (
|
||||
character == '\0' &&
|
||||
!json &&
|
||||
!regexDigit.test(string.charAt(index + 1))
|
||||
) {
|
||||
result += '\\0';
|
||||
continue;
|
||||
}
|
||||
if (regexSingleEscape.test(character)) {
|
||||
// no need for a `hasOwnProperty` check here
|
||||
result += singleEscapes[character];
|
||||
continue;
|
||||
}
|
||||
const charCode = character.charCodeAt(0);
|
||||
if (options.minimal && charCode != 0x2028 && charCode != 0x2029) {
|
||||
result += character;
|
||||
continue;
|
||||
}
|
||||
let hexadecimal = charCode.toString(16);
|
||||
if (!lowercaseHex) {
|
||||
hexadecimal = hexadecimal.toUpperCase();
|
||||
}
|
||||
const longhand = hexadecimal.length > 2 || json;
|
||||
const escaped = '\\' + (longhand ? 'u' : 'x') +
|
||||
('0000' + hexadecimal).slice(longhand ? -4 : -2);
|
||||
result += escaped;
|
||||
continue;
|
||||
}
|
||||
if (options.wrap) {
|
||||
result = quote + result + quote;
|
||||
}
|
||||
if (quote == '`') {
|
||||
result = result.replace(/\$\{/g, '\\\$\{');
|
||||
}
|
||||
if (options.isScriptContext) {
|
||||
// https://mathiasbynens.be/notes/etago
|
||||
return result
|
||||
.replace(/<\/(script|style)/gi, '<\\/$1')
|
||||
.replace(/<!--/g, json ? '\\u003C!--' : '\\x3C!--');
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
jsesc.version = '2.5.2';
|
||||
|
||||
module.exports = jsesc;
|
94
node_modules/jsesc/man/jsesc.1
generated
vendored
Normal file
94
node_modules/jsesc/man/jsesc.1
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
.Dd May 13, 2016
|
||||
.Dt jsesc 1
|
||||
.Sh NAME
|
||||
.Nm jsesc
|
||||
.Nd escape strings for use in JavaScript string literals
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl s | -single-quotes Ar string
|
||||
.br
|
||||
.Op Fl d | -double-quotes Ar string
|
||||
.br
|
||||
.Op Fl w | -wrap Ar string
|
||||
.br
|
||||
.Op Fl e | -escape-everything Ar string
|
||||
.br
|
||||
.Op Fl 6 | -es6 Ar string
|
||||
.br
|
||||
.Op Fl l | -lowercase-hex Ar string
|
||||
.br
|
||||
.Op Fl j | -json Ar string
|
||||
.br
|
||||
.Op Fl p | -object Ar string
|
||||
.br
|
||||
.Op Fl p | -pretty Ar string
|
||||
.br
|
||||
.Op Fl v | -version
|
||||
.br
|
||||
.Op Fl h | -help
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
escapes strings for use in JavaScript string literals while generating the shortest possible valid ASCII-only output.
|
||||
.Sh OPTIONS
|
||||
.Bl -ohang -offset
|
||||
.It Sy "-s, --single-quotes"
|
||||
Escape any occurrences of ' in the input string as \\', so that the output can be used in a JavaScript string literal wrapped in single quotes.
|
||||
.It Sy "-d, --double-quotes"
|
||||
Escape any occurrences of " in the input string as \\", so that the output can be used in a JavaScript string literal wrapped in double quotes.
|
||||
.It Sy "-w, --wrap"
|
||||
Make sure the output is a valid JavaScript string literal wrapped in quotes. The type of quotes can be specified using the
|
||||
.Ar -s | --single-quotes
|
||||
or
|
||||
.Ar -d | --double-quotes
|
||||
settings.
|
||||
.It Sy "-6, --es6"
|
||||
Escape any astral Unicode symbols using ECMAScript 6 Unicode code point escape sequences.
|
||||
.It Sy "-e, --escape-everything"
|
||||
Escape all the symbols in the output, even printable ASCII symbols.
|
||||
.It Sy "-j, --json"
|
||||
Make sure the output is valid JSON. Hexadecimal character escape sequences and the \\v or \\0 escape sequences will not be used. Setting this flag enables the
|
||||
.Ar -d | --double-quotes
|
||||
and
|
||||
.Ar -w | --wrap
|
||||
settings.
|
||||
.It Sy "-o, --object"
|
||||
Treat the input as a JavaScript object rather than a string. Accepted values are flat arrays containing only string values, and flat objects containing only string values.
|
||||
.It Sy "-p, --pretty"
|
||||
Pretty-print the output for objects, using whitespace to make it more readable. Setting this flag enables the
|
||||
.It Sy "-l, --lowercase-hex"
|
||||
Use lowercase for alphabetical hexadecimal digits in escape sequences.
|
||||
.Ar -o | --object
|
||||
setting.
|
||||
.It Sy "-v, --version"
|
||||
Print jsesc's version.
|
||||
.It Sy "-h, --help"
|
||||
Show the help screen.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm jsesc
|
||||
utility exits with one of the following values:
|
||||
.Pp
|
||||
.Bl -tag -width flag -compact
|
||||
.It Li 0
|
||||
.Nm
|
||||
successfully escaped the given string and printed the result.
|
||||
.It Li 1
|
||||
.Nm
|
||||
wasn't instructed to escape anything (for example, the
|
||||
.Ar --help
|
||||
flag was set); or, an error occurred.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Bl -ohang -offset
|
||||
.It Sy "jsesc 'foo bar baz'"
|
||||
Print an escaped version of the given string.
|
||||
.It Sy echo\ 'foo bar baz'\ |\ jsesc
|
||||
Print an escaped version of the string that gets piped in.
|
||||
.El
|
||||
.Sh BUGS
|
||||
jsesc's bug tracker is located at <https://github.com/mathiasbynens/jsesc/issues>.
|
||||
.Sh AUTHOR
|
||||
Mathias Bynens <https://mathiasbynens.be/>
|
||||
.Sh WWW
|
||||
<https://mths.be/jsesc>
|
58
node_modules/jsesc/package.json
generated
vendored
Normal file
58
node_modules/jsesc/package.json
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"name": "jsesc",
|
||||
"version": "2.5.2",
|
||||
"description": "Given some data, jsesc returns the shortest possible stringified & ASCII-safe representation of that data.",
|
||||
"homepage": "https://mths.be/jsesc",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
},
|
||||
"main": "jsesc.js",
|
||||
"bin": "bin/jsesc",
|
||||
"man": "man/jsesc.1",
|
||||
"keywords": [
|
||||
"buffer",
|
||||
"escape",
|
||||
"javascript",
|
||||
"json",
|
||||
"map",
|
||||
"set",
|
||||
"string",
|
||||
"stringify",
|
||||
"tool"
|
||||
],
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Mathias Bynens",
|
||||
"url": "https://mathiasbynens.be/"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mathiasbynens/jsesc.git"
|
||||
},
|
||||
"bugs": "https://github.com/mathiasbynens/jsesc/issues",
|
||||
"files": [
|
||||
"LICENSE-MIT.txt",
|
||||
"jsesc.js",
|
||||
"bin/",
|
||||
"man/"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "grunt template",
|
||||
"coveralls": "istanbul cover --verbose --dir 'coverage' 'tests/tests.js' && coveralls < coverage/lcov.info'",
|
||||
"cover": "istanbul cover --report 'html' --verbose --dir 'coverage' 'tests/tests.js'",
|
||||
"test": "mocha tests"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.6",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-template": "^0.2.3",
|
||||
"istanbul": "^0.4.2",
|
||||
"mocha": "*",
|
||||
"regenerate": "^1.3.0",
|
||||
"requirejs": "^2.1.22"
|
||||
}
|
||||
|
||||
,"_resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
|
||||
,"_integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
||||
,"_from": "jsesc@2.5.2"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue