diff options
| author | Priyansh <[email protected]> | 2020-12-22 17:49:59 +0530 |
|---|---|---|
| committer | Priyansh <[email protected]> | 2020-12-22 17:49:59 +0530 |
| commit | e93da8b04da86773247aadb1cbb1912e4f4526b2 (patch) | |
| tree | eb4ef3203a92ed3dbd2252ddb1ea23bd2d670c98 /node_modules/sanitize-filename | |
| parent | a5743c293dcb435e4b159a4df791f8955a4110ec (diff) | |
| download | styx-e93da8b04da86773247aadb1cbb1912e4f4526b2.tar.xz styx-e93da8b04da86773247aadb1cbb1912e4f4526b2.zip | |
Rewriting Project
Diffstat (limited to 'node_modules/sanitize-filename')
| -rw-r--r-- | node_modules/sanitize-filename/.airtap.yml | 16 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/.gitmodules | 3 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/.travis.yml | 55 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/AUTHORS | 2 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/Changelog.md | 6 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/LICENSE.md | 34 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/README.md | 103 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/index.d.ts | 8 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/index.js | 59 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/package.json | 77 | ||||
| -rw-r--r-- | node_modules/sanitize-filename/test.js | 305 |
11 files changed, 668 insertions, 0 deletions
diff --git a/node_modules/sanitize-filename/.airtap.yml b/node_modules/sanitize-filename/.airtap.yml new file mode 100644 index 0000000..eeb4e05 --- /dev/null +++ b/node_modules/sanitize-filename/.airtap.yml @@ -0,0 +1,16 @@ +loopback: airtap.local +browsers: + - name: chrome + version: latest + - name: firefox + version: latest + - name: ie + version: latest + - name: microsoftedge + version: latest + - name: safari + version: latest + - name: iphone + version: latest + - name: android + version: latest diff --git a/node_modules/sanitize-filename/.gitmodules b/node_modules/sanitize-filename/.gitmodules new file mode 100644 index 0000000..23195b0 --- /dev/null +++ b/node_modules/sanitize-filename/.gitmodules @@ -0,0 +1,3 @@ +[submodule "big-list-of-naughty-strings"] + path = vendor/big-list-of-naughty-strings + url = https://github.com/minimaxir/big-list-of-naughty-strings.git diff --git a/node_modules/sanitize-filename/.travis.yml b/node_modules/sanitize-filename/.travis.yml new file mode 100644 index 0000000..0c1df19 --- /dev/null +++ b/node_modules/sanitize-filename/.travis.yml @@ -0,0 +1,55 @@ +language: node_js +node_js: node + +matrix: + include: + # Node versions + - node_js: 0.10 + - node_js: 0.12 + - node_js: 1 + - node_js: 2 + - node_js: 3 + - node_js: 4 + - node_js: 5 + - node_js: 6 + - node_js: 7 + - node_js: 8 + - node_js: 9 + - node_js: 10 + - node_js: 12 + - node_js: node + + # Browser testing + - env: + - AIRTAP_TEST=1 + - SAUCE_USERNAME: parshap + addons: + sauce_connect: true + jwt: + - secure: C7rEgVrfIFovn763aFbXwZrEvTapI1MDDSk8nmU/nseC8Zb++6wCHNbKeGPLaY1kgRNOJbIo9SoHWUoLhGjjHXiNamQfoRPgeD3MXe1qhUskwxOeqpXOFfZv6KEyi3YNjPrjVTgLqK/mfmH2HxHr2HIldP15z40cc5+SLxKS2Fk= + hosts: + - airtap.local + + # Include all possible file systems + # Normal builds use AUFS + # See http://docs.travis-ci.com/user/ci-environment/ + # HFS+ + - os: osx + # ext4 + - sudo: required + dist: trusty + # SIMFS + - sudo: required + # NTFS + - os: windows + +script: | + if [ -n "$AIRTAP_TEST" ] + then + # Work around this logic that doesn't work when using jwt by setting + # TRAVIS_SECURE_ENV_VARS=true. + # https://github.com/airtap/airtap/blob/00cfae3f38b59f5ff4001cb5e131964e72ab6f24/bin/airtap.js#L6 + TRAVIS_SECURE_ENV_VARS=true npm run test-browser-sauce + else + npm test + fi diff --git a/node_modules/sanitize-filename/AUTHORS b/node_modules/sanitize-filename/AUTHORS new file mode 100644 index 0000000..6b8abe4 --- /dev/null +++ b/node_modules/sanitize-filename/AUTHORS @@ -0,0 +1,2 @@ +Parsha Pourkhomami <[email protected]> +Joel Mukuthu <[email protected]> diff --git a/node_modules/sanitize-filename/Changelog.md b/node_modules/sanitize-filename/Changelog.md new file mode 100644 index 0000000..03624c8 --- /dev/null +++ b/node_modules/sanitize-filename/Changelog.md @@ -0,0 +1,6 @@ +## 1.2.0 + +Check for reserved Windows filenames (`CON`, `PRN`, `AUX`, `NUL`, +`COM1`, `LPT1`, etc). See [1]. + +[1] https://github.com/parshap/node-sanitize-filename/issues/9 diff --git a/node_modules/sanitize-filename/LICENSE.md b/node_modules/sanitize-filename/LICENSE.md new file mode 100644 index 0000000..f9c323a --- /dev/null +++ b/node_modules/sanitize-filename/LICENSE.md @@ -0,0 +1,34 @@ +This project is licensed under the [WTFPL][] and [ISC][] licenses. + +[WTFPL]: https://en.wikipedia.org/wiki/WTFPL +[ISC]: https://opensource.org/licenses/ISC + +## WTFPL + +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +Version 2, December 2004 + +Copyright (C) 2004 Sam Hocevar \<[email protected]> + +Everyone is permitted to copy and distribute verbatim or modified copies +of this license document, and changing it is allowed as long as the name +is changed. + +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR +COPYING, DISTRIBUTION AND MODIFICATION + +0. You just DO WHAT THE FUCK YOU WANT TO. + +## ISC + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/sanitize-filename/README.md b/node_modules/sanitize-filename/README.md new file mode 100644 index 0000000..1287d30 --- /dev/null +++ b/node_modules/sanitize-filename/README.md @@ -0,0 +1,103 @@ +# sanitize-filename [](http://travis-ci.org/parshap/node-sanitize-filename) + +Sanitize a string to be safe for use as a filename by removing directory +paths and invalid characters. + +## Install + +[npm: *sanitize-filename*](https://www.npmjs.com/package/sanitize-filename) + +``` +npm install sanitize-filename +``` + +## Example + +```js +var sanitize = require("sanitize-filename"); + +// Some string that may be unsafe or invalid as a filename +var UNSAFE_USER_INPUT = "~/.\u0000ssh/authorized_keys"; + +// Sanitize the string to be safe for use as a filename. +var filename = sanitize(UNSAFE_USER_INPUT); +// -> "~.sshauthorized_keys" +``` + +## Details + +*sanitize-filename* removes the following: + + * [Control characters][] (`0x00`–`0x1f` and `0x80`–`0x9f`) + * [Reserved characters][] (`/`, `?`, `<`, `>`, `\`, `:`, `*`, `|`, and + `"`) + * Unix reserved filenames (`.` and `..`) + * Trailing periods and spaces ([for Windows][windows trailing]) + * Windows reserved filenames (`CON`, `PRN`, `AUX`, `NUL`, `COM1`, + `COM2`, `COM3`, `COM4`, `COM5`, `COM6`, `COM7`, `COM8`, `COM9`, + `LPT1`, `LPT2`, `LPT3`, `LPT4`, `LPT5`, `LPT6`, `LPT7`, `LPT8`, and + `LPT9`) + +[control characters]: https://en.wikipedia.org/wiki/C0_and_C1_control_codes +[reserved characters]: https://kb.acronis.com/content/39790 +[windows trailing]: https://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx#Naming_Conventions + +The resulting string is truncated to [255 bytes in length][255]. The +string will not contain any directory paths and will be safe to use as a +filename. + +[255]: http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs + +### Empty String `""` Result + +An empty string `""` can be returned. For example: + +```js +var sanitize = require("sanitize-filename"); +sanitize("..") +// -> "" + +``` + +### Non-unique Filenames + +Two different inputs can return the same value. For example: + +```js +var sanitize = require("sanitize-filename"); +sanitize("file?") +// -> "file" +sanitize ("*file*") +// -> "file" +``` + +### File Systems + +Sanitized filenames will be safe for use on modern Windows, OS X, and +Unix file systems (`NTFS`, `ext`, etc.). + +[`FAT` 8.3 filenames][8.3] are not supported. + +[8.3]: https://en.wikipedia.org/wiki/8.3_filename + +#### Test Your File System + +The test program will use various strings (including the [Big List of +Naughty Strings][blns]) to create files in the working directory. Run +`npm test` to run tests against your file system. + +[blns]: https://github.com/minimaxir/big-list-of-naughty-strings + +## API + +### `sanitize(inputString, [options])` + +Sanitize `inputString` by removing or replacing invalid characters. + +Options: + + * `options.replacement`: *optional, string/function, default: `""`*. If passed + as a string, it's used as the replacement for invalid characters. If passed as + a function, the function will be called with the invalid characters and it's + return value will be used as the replacement. See [`String.prototype.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) + for more info. diff --git a/node_modules/sanitize-filename/index.d.ts b/node_modules/sanitize-filename/index.d.ts new file mode 100644 index 0000000..fedab92 --- /dev/null +++ b/node_modules/sanitize-filename/index.d.ts @@ -0,0 +1,8 @@ +declare function sanitize( + input: string, + options?: { + replacement?: string | ((substring: string) => string); + } +): string; + +export = sanitize; diff --git a/node_modules/sanitize-filename/index.js b/node_modules/sanitize-filename/index.js new file mode 100644 index 0000000..db3f020 --- /dev/null +++ b/node_modules/sanitize-filename/index.js @@ -0,0 +1,59 @@ +/*jshint node:true*/ +'use strict'; + +/** + * Replaces characters in strings that are illegal/unsafe for filenames. + * Unsafe characters are either removed or replaced by a substitute set + * in the optional `options` object. + * + * Illegal Characters on Various Operating Systems + * / ? < > \ : * | " + * https://kb.acronis.com/content/39790 + * + * Unicode Control codes + * C0 0x00-0x1f & C1 (0x80-0x9f) + * http://en.wikipedia.org/wiki/C0_and_C1_control_codes + * + * Reserved filenames on Unix-based systems (".", "..") + * Reserved filenames in Windows ("CON", "PRN", "AUX", "NUL", "COM1", + * "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", + * "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", and + * "LPT9") case-insesitively and with or without filename extensions. + * + * Capped at 255 characters in length. + * http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs + * + * @param {String} input Original filename + * @param {Object} options {replacement: String | Function } + * @return {String} Sanitized filename + */ + +var truncate = require("truncate-utf8-bytes"); + +var illegalRe = /[\/\?<>\\:\*\|"]/g; +var controlRe = /[\x00-\x1f\x80-\x9f]/g; +var reservedRe = /^\.+$/; +var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; +var windowsTrailingRe = /[\. ]+$/; + +function sanitize(input, replacement) { + if (typeof input !== 'string') { + throw new Error('Input must be string'); + } + var sanitized = input + .replace(illegalRe, replacement) + .replace(controlRe, replacement) + .replace(reservedRe, replacement) + .replace(windowsReservedRe, replacement) + .replace(windowsTrailingRe, replacement); + return truncate(sanitized, 255); +} + +module.exports = function (input, options) { + var replacement = (options && options.replacement) || ''; + var output = sanitize(input, replacement); + if (replacement === '') { + return output; + } + return sanitize(output, ''); +}; diff --git a/node_modules/sanitize-filename/package.json b/node_modules/sanitize-filename/package.json new file mode 100644 index 0000000..0ca9b6c --- /dev/null +++ b/node_modules/sanitize-filename/package.json @@ -0,0 +1,77 @@ +{ + "_from": "sanitize-filename@^1.6.2", + "_id": "[email protected]", + "_inBundle": false, + "_integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "_location": "/sanitize-filename", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "sanitize-filename@^1.6.2", + "name": "sanitize-filename", + "escapedName": "sanitize-filename", + "rawSpec": "^1.6.2", + "saveSpec": null, + "fetchSpec": "^1.6.2" + }, + "_requiredBy": [ + "/@electron/get" + ], + "_resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "_shasum": "755ebd752045931977e30b2025d340d7c9090378", + "_spec": "sanitize-filename@^1.6.2", + "_where": "/Users/lucifer/Documents/styx/node_modules/@electron/get", + "author": { + "name": "Parsha Pourkhomami" + }, + "bugs": { + "url": "https://github.com/parshap/node-sanitize-filename/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Parsha Pourkhomami", + "email": "[email protected]" + }, + { + "name": "Joel Mukuthu", + "email": "[email protected]" + } + ], + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + }, + "deprecated": false, + "description": "Sanitize a string for use as a filename", + "devDependencies": { + "airtap": "^2.0.3", + "browserify": "^14.0.0", + "concat-stream": "^1.5.1", + "mktemp": "^0.4.0", + "tape": "^4.2.2" + }, + "homepage": "https://github.com/parshap/node-sanitize-filename#readme", + "keywords": [ + "file", + "name", + "filename", + "sanitize", + "validate", + "escape" + ], + "license": "WTFPL OR ISC", + "main": "index.js", + "name": "sanitize-filename", + "repository": { + "type": "git", + "url": "git+ssh://[email protected]/parshap/node-sanitize-filename.git" + }, + "scripts": { + "test": "tape test.js", + "test-browser": "airtap --local --open -- test.js", + "test-browser-sauce": "airtap -- test.js" + }, + "types": "index.d.ts", + "version": "1.6.3" +} diff --git a/node_modules/sanitize-filename/test.js b/node_modules/sanitize-filename/test.js new file mode 100644 index 0000000..62acc64 --- /dev/null +++ b/node_modules/sanitize-filename/test.js @@ -0,0 +1,305 @@ +"use strict"; + +var test = require("tape"), + sanitize = require("./"); + +function repeat(string, times) { + return new Array(times + 1).join(string); +} + +var REPLACEMENT_OPTS = { + replacement: "_", +}; + +test("valid names", function(t) { + ["the quick brown fox jumped over the lazy dog.mp3", + "résumé"].forEach(function(name) { + t.equal(sanitize(name), name); + }); + t.end(); +}); + +test("valid names", function(t) { + ["valid name.mp3", "résumé"].forEach(function(name) { + t.equal(sanitize(name, REPLACEMENT_OPTS), name); + }); + t.end(); +}); + +test("null character", function(t) { + t.equal(sanitize("hello\u0000world"), "helloworld"); + t.end(); +}); + +test("null character", function(t) { + t.equal(sanitize("hello\u0000world", REPLACEMENT_OPTS), "hello_world"); + t.end(); +}); + +test("control characters", function(t) { + t.equal(sanitize("hello\nworld"), "helloworld"); + t.end(); +}); + +test("control characters", function(t) { + t.equal(sanitize("hello\nworld", REPLACEMENT_OPTS), "hello_world"); + t.end(); +}); + +test("restricted codes", function(t) { + ["h?w", "h/w", "h*w"].forEach(function(name) { + t.equal(sanitize(name), "hw"); + }); + t.end(); +}); + +test("restricted codes", function(t) { + ["h?w", "h/w", "h*w"].forEach(function(name) { + t.equal(sanitize(name, REPLACEMENT_OPTS), "h_w"); + }); + t.end(); +}); + +// https://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx +test("restricted suffixes", function(t) { + ["mr.", "mr..", "mr ", "mr "].forEach(function(name) { + t.equal(sanitize(name), "mr"); + }); + t.end(); +}); + +test("relative paths", function(t) { + [".", "..", "./", "../", "/..", "/../", "*.|."].forEach(function(name) { + t.equal(sanitize(name), ""); + }); + t.end(); +}); + +test("relative path with replacement", function(t) { + t.equal(sanitize("..", REPLACEMENT_OPTS), "_"); + t.end(); +}); + +test("reserved filename in Windows", function(t) { + t.equal(sanitize("con"), ""); + t.equal(sanitize("COM1"), ""); + t.equal(sanitize("PRN."), ""); + t.equal(sanitize("aux.txt"), ""); + t.equal(sanitize("LPT9.asdfasdf"), ""); + t.equal(sanitize("LPT10.txt"), "LPT10.txt"); + t.end(); +}); + +test("reserved filename in Windows with replacement", function(t) { + t.equal(sanitize("con", REPLACEMENT_OPTS), "_"); + t.equal(sanitize("COM1", REPLACEMENT_OPTS), "_"); + t.equal(sanitize("PRN.", REPLACEMENT_OPTS), "_"); + t.equal(sanitize("aux.txt", REPLACEMENT_OPTS), "_"); + t.equal(sanitize("LPT9.asdfasdf", REPLACEMENT_OPTS), "_"); + t.equal(sanitize("LPT10.txt", REPLACEMENT_OPTS), "LPT10.txt"); + t.end(); +}); + +test("invalid replacement", function (t) { + t.equal(sanitize(".", { replacement: "."}), ""); + t.equal(sanitize("foo?.txt", { replacement: ">"}), "foo.txt"); + t.equal(sanitize("con.txt", { replacement: "aux"}), ""); + t.equal(sanitize("valid.txt", { replacement: "\/:*?\"<>|"}), "valid.txt"); + t.end(); +}); + +test("255 characters max", function(t) { + var string = repeat("a", 300); + t.ok(string.length > 255); + t.ok(sanitize(string).length <= 255); + t.end(); +}); + +// Test the handling of non-BMP chars in UTF-8 +// + +test("non-bmp SADDLES the limit", function(t){ + var str25x = repeat("a", 252), + name = str25x + '\uD800\uDC00'; + t.equal(sanitize(name), str25x); + + t.end(); +}); + +test("non-bmp JUST WITHIN the limit", function(t){ + var str25x = repeat('a', 251), + name = str25x + '\uD800\uDC00'; + t.equal(sanitize(name), name); + + t.end(); +}); + +test("non-bmp JUST OUTSIDE the limit", function(t){ + var str25x = repeat('a', 253), + name = str25x + '\uD800\uDC00'; + t.equal(sanitize(name), str25x); + + t.end(); +}); + +// Test invalid input +// + +test("invalid input", function(t) { + t.throws(function() { + sanitize(); + }, null, 'no arguments'); + + [ + undefined, + null, + false, + true, + {}, + { + replace: function() { + return "foo"; + }, + toString: function() { + return "bar"; + }, + }, + [], + new Buffer('asdf'), + ].forEach(function(input) { + t.throws(function() { + sanitize(input); + }, null, JSON.stringify(input)); + }); + + t.end(); +}); + +function testStringUsingFS(str, t) { + var sanitized = sanitize(str) || "default"; + var filepath = path.join(tempdir, sanitized); + + // Should not contain any directories or relative paths + t.equal(path.dirname(path.resolve("/abs/path", sanitized)), path.resolve("/abs/path")); + + // Should be max 255 bytes + t.assert(Buffer.byteLength(sanitized) <= 255, "max 255 bytes"); + + // Should write and read file to disk + t.equal(path.dirname(path.normalize(filepath)), tempdir); + fs.writeFile(filepath, "foobar", function(err) { + t.ifError(err, "no error writing file"); + fs.readFile(filepath, function(err, data) { + t.ifError(err, "no error reading file"); + t.equal(data.toString(), "foobar", "file contents equals"); + fs.unlink(filepath, function(err) { + t.ifError(err, "no error unlinking file"); + t.end(); + }); + }); + }); +} + +// Don't run these tests in browser environments +if ( ! process.browser) { + // ## Browserify Build + // + // Make sure Buffer is not used when building using browserify. + // + + var browserify = require("browserify"); + var concat = require("concat-stream"); + + test("browserify build", function(t) { + var bundle = browserify(__dirname).bundle(); + bundle.on("error", t.ifError); + bundle.pipe(concat(function(data) { + var source = data.toString(); + t.ok(source.indexOf("Buffer") === -1); + t.end(); + })); + }); + + // ## Filesystem Tests + // + // Test writing files to the local filesystem. + // + + var fs = require("fs"); + var path = require("path"); + var mktemp = require("mktemp"); + var tempdir = mktemp.createDirSync("sanitize-filename-test-XXXXXX"); + + try { + var blns = require("./vendor/big-list-of-naughty-strings/blns.json"); + } + catch (err) { + console.error("Error: Cannot load file './vendor/big-list-of-naughty-strings/blns.json'"); + console.error(); + console.error("Make sure you've initialized git submodules by running"); + console.error(); + console.error(" git submodule update --init"); + console.error(); + process.exit(1); + } + + [].concat( + [ + repeat("a", 300), + "the quick brown fox jumped over the lazy dog", + "résumé", + "hello\u0000world", + "hello\nworld", + "semi;colon.js", + ";leading-semi.js", + "slash\\.js", + "slash/.js", + "col:on.js", + "star*.js", + "question?.js", + "quote\".js", + "singlequote'.js", + "brack<e>ts.js", + "p|pes.js", + "plus+.js", + "'five and six<seven'.js", + " space at front", + "space at end ", + ".period", + "period.", + "relative/path/to/some/dir", + "/abs/path/to/some/dir", + "~/.\u0000notssh/authorized_keys", + "", + "h?w", + "h/w", + "h*w", + ".", + "..", + "./", + "../", + "/..", + "/../", + "*.|.", + "./", + "./foobar", + "../foobar", + "../../foobar", + "./././foobar", + "|*.what", + "LPT9.asdf", + ], + blns + ).forEach(function(str) { + test(JSON.stringify(str), function(t) { + testStringUsingFS(str, t); + }); + }); + + test("remove temp directory", function(t) { + fs.rmdir(tempdir, function(err) { + t.ifError(err); + t.end(); + }); + }); +} |
