mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69e12b1067 | ||
|
|
fef446687a | ||
|
|
3affce8f98 | ||
|
|
0b91468edc | ||
|
|
127364e8a4 | ||
|
|
52426bc1a4 | ||
|
|
cbab995c6d | ||
|
|
45a9da5b30 | ||
|
|
aed22aebb2 | ||
|
|
369d213da5 | ||
|
|
e92775eec2 | ||
|
|
a5f1c430a3 | ||
|
|
e4a91b5397 | ||
|
|
cbcd45cd70 | ||
|
|
0968912954 | ||
|
|
3bfe22c0f7 | ||
|
|
6cf64d794f | ||
|
|
6741ba0783 | ||
|
|
f1e7bc3363 | ||
|
|
2dbe2d044e | ||
|
|
ea3630e018 | ||
|
|
c6391d958d | ||
|
|
71aa4033a4 | ||
|
|
57dcd961d5 | ||
|
|
83878d6b05 | ||
|
|
9055fc72d2 | ||
|
|
fb4ab56b47 | ||
|
|
51e195ed17 | ||
|
|
9947c574d2 | ||
|
|
693abdacf6 | ||
|
|
dd3b42fb53 | ||
|
|
8e72d7d0d6 | ||
|
|
a6317212d9 | ||
|
|
347adf688a | ||
|
|
3ee67927a5 | ||
|
|
7ecd36efcf | ||
|
|
714ce8a8a3 | ||
|
|
7b18a2f46f | ||
|
|
19103a64e5 | ||
|
|
a13f1d27e2 | ||
|
|
9a6e4b1e85 | ||
|
|
67b78fc230 | ||
|
|
5e79187176 | ||
|
|
491a82cd67 | ||
|
|
87c2ec678f | ||
|
|
70135ab3ea | ||
|
|
ad18d84f14 | ||
|
|
77e47e3fa4 | ||
|
|
04432385b3 | ||
|
|
cbdc24d869 | ||
|
|
2b3e471f96 | ||
|
|
488d54493a | ||
|
|
a418f63a44 | ||
|
|
0e285151f3 | ||
|
|
e4ad7768d5 | ||
|
|
f800fab1a3 | ||
|
|
dc61aeeeb8 | ||
|
|
4b1d0fd011 | ||
|
|
2b7ba594fc | ||
|
|
d87b14af13 | ||
|
|
83623d23cf | ||
|
|
07fba53b73 | ||
|
|
823b276ef5 | ||
|
|
0e72d78731 | ||
|
|
768609e357 | ||
|
|
526a157421 | ||
|
|
62154309fb | ||
|
|
ad74e6c475 | ||
|
|
82d28242cc | ||
|
|
60fddf837d | ||
|
|
ee25df0c28 | ||
|
|
478af40359 | ||
|
|
6bf06a9629 | ||
|
|
3c15bd9e29 | ||
|
|
71796e3dbf | ||
|
|
280f1ee2df | ||
|
|
0dc72d8301 | ||
|
|
c43b67ea90 | ||
|
|
244421b69e | ||
|
|
1adedff61a | ||
|
|
6abd10f9e2 | ||
|
|
a85096ea11 | ||
|
|
f67157f0ad | ||
|
|
5efe9bd91d | ||
|
|
dc7a7267c9 | ||
|
|
17188b1e38 | ||
|
|
e9c3bebfff | ||
|
|
03fc22d3da | ||
|
|
5d52c49c31 | ||
|
|
d53da4cfb5 | ||
|
|
76204f5f47 | ||
|
|
b68adbd9a8 | ||
|
|
951b168f3a | ||
|
|
53d89af459 | ||
|
|
4f844ea837 | ||
|
|
59a36e77bd | ||
|
|
61d8d4473c | ||
|
|
508a371175 | ||
|
|
b010fd88e8 | ||
|
|
66a93b81c6 | ||
|
|
274e1139fa | ||
|
|
6122e33f4f | ||
|
|
b365ce3195 | ||
|
|
0a3233d289 | ||
|
|
15aea9e9ea | ||
|
|
5b03a84be8 | ||
|
|
80cdf0c014 | ||
|
|
d41d56e670 | ||
|
|
7e4e1f1a0d | ||
|
|
463b06f508 | ||
|
|
d3377d56b4 | ||
|
|
c7611fbc05 | ||
|
|
67ee218f69 | ||
|
|
d1d394eec7 | ||
|
|
98bc68c2bf | ||
|
|
116c0680a2 | ||
|
|
1b8a25ec88 | ||
|
|
d5def01a9d | ||
|
|
ee07b72415 | ||
|
|
f7547db272 | ||
|
|
5d271687ec | ||
|
|
d05543db30 | ||
|
|
b33f73ac9a | ||
|
|
31e5d785fe | ||
|
|
8096fd20a7 | ||
|
|
addd45ae8e | ||
|
|
d6895537ac | ||
|
|
2e4076bb75 | ||
|
|
d71ac2e894 | ||
|
|
50784f2600 | ||
|
|
21c0fed833 | ||
|
|
e3f41fea9c | ||
|
|
a13e2468db | ||
|
|
3fb660d816 | ||
|
|
9f60dc3dd6 | ||
|
|
02f855ff09 | ||
|
|
c39622ed1e | ||
|
|
a4d93f23d6 | ||
|
|
e0e5670d0e | ||
|
|
e120422b05 |
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
src/core/lib/**
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaVersion": 8,
|
||||
"ecmaFeatures": {
|
||||
"impliedStrict": true
|
||||
},
|
||||
@@ -84,7 +84,8 @@
|
||||
}],
|
||||
"no-whitespace-before-property": "error",
|
||||
"operator-linebreak": ["error", "after"],
|
||||
"space-in-parens": "error"
|
||||
"space-in-parens": "error",
|
||||
"no-var": "error"
|
||||
},
|
||||
"globals": {
|
||||
"$": false,
|
||||
@@ -5,3 +5,4 @@ build/*
|
||||
!build/node
|
||||
docs
|
||||
.vscode
|
||||
.github
|
||||
|
||||
@@ -9,7 +9,7 @@ script:
|
||||
- grunt test
|
||||
- grunt docs
|
||||
- grunt node
|
||||
- grunt prod
|
||||
- grunt prod --msg="$COMPILE_MSG"
|
||||
before_deploy:
|
||||
- grunt copy:ghPages
|
||||
deploy:
|
||||
@@ -19,6 +19,7 @@ deploy:
|
||||
local_dir: build/prod/
|
||||
target_branch: gh-pages
|
||||
on:
|
||||
repo: gchq/CyberChef
|
||||
branch: master
|
||||
- provider: releases
|
||||
skip_cleaup: true
|
||||
|
||||
48
Gruntfile.js
48
Gruntfile.js
@@ -1,7 +1,7 @@
|
||||
var webpack = require("webpack"),
|
||||
ExtractTextPlugin = require("extract-text-webpack-plugin"),
|
||||
HtmlWebpackPlugin = require("html-webpack-plugin"),
|
||||
Inliner = require("web-resource-inliner");
|
||||
const webpack = require("webpack");
|
||||
const ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const Inliner = require("web-resource-inliner");
|
||||
|
||||
module.exports = function (grunt) {
|
||||
grunt.file.defaultEncoding = "utf8";
|
||||
@@ -54,7 +54,7 @@ module.exports = function (grunt) {
|
||||
|
||||
|
||||
// Project configuration
|
||||
var compileTime = grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC",
|
||||
const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
|
||||
banner = "/**\n" +
|
||||
"* CyberChef - The Cyber Swiss Army Knife\n" +
|
||||
"*\n" +
|
||||
@@ -74,13 +74,14 @@ module.exports = function (grunt) {
|
||||
"* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
|
||||
"* See the License for the specific language governing permissions and\n" +
|
||||
"* limitations under the License.\n" +
|
||||
"*/\n";
|
||||
"*/\n",
|
||||
pkg = grunt.file.readJSON("package.json");
|
||||
|
||||
/**
|
||||
* Compiles a production build of CyberChef into a single, portable web page.
|
||||
*/
|
||||
function runInliner() {
|
||||
var inlinerError = false;
|
||||
const done = this.async();
|
||||
Inliner.html({
|
||||
relativeTo: "build/prod/",
|
||||
fileContent: grunt.file.read("build/prod/cyberchef.htm"),
|
||||
@@ -91,14 +92,16 @@ module.exports = function (grunt) {
|
||||
strict: true
|
||||
}, function(error, result) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
inlinerError = true;
|
||||
return false;
|
||||
if (error instanceof Error) {
|
||||
done(error);
|
||||
} else {
|
||||
done(new Error(error));
|
||||
}
|
||||
} else {
|
||||
grunt.file.write("build/prod/cyberchef.htm", result);
|
||||
done(true);
|
||||
}
|
||||
grunt.file.write("build/prod/cyberchef.htm", result);
|
||||
});
|
||||
|
||||
return !inlinerError;
|
||||
}
|
||||
|
||||
grunt.initConfig({
|
||||
@@ -111,7 +114,7 @@ module.exports = function (grunt) {
|
||||
},
|
||||
eslint: {
|
||||
options: {
|
||||
configFile: "src/.eslintrc.json"
|
||||
configFile: "./.eslintrc.json"
|
||||
},
|
||||
configs: ["Gruntfile.js"],
|
||||
core: ["src/core/**/*.js", "!src/core/lib/**/*"],
|
||||
@@ -180,7 +183,10 @@ module.exports = function (grunt) {
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
use: "css-loader?minimize"
|
||||
use: [
|
||||
{ loader: "css-loader?minimize" },
|
||||
{ loader: "postcss-loader" },
|
||||
]
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -188,6 +194,7 @@ module.exports = function (grunt) {
|
||||
use: ExtractTextPlugin.extract({
|
||||
use: [
|
||||
{ loader: "css-loader?minimize" },
|
||||
{ loader: "postcss-loader" },
|
||||
{ loader: "less-loader" }
|
||||
]
|
||||
})
|
||||
@@ -218,7 +225,8 @@ module.exports = function (grunt) {
|
||||
]
|
||||
},
|
||||
stats: {
|
||||
children: false
|
||||
children: false,
|
||||
warningsFilter: /source-map/
|
||||
}
|
||||
},
|
||||
webDev: {
|
||||
@@ -232,7 +240,8 @@ module.exports = function (grunt) {
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "index.html",
|
||||
template: "./src/web/html/index.html",
|
||||
compileTime: compileTime
|
||||
compileTime: compileTime,
|
||||
version: pkg.version,
|
||||
})
|
||||
],
|
||||
watch: true
|
||||
@@ -258,6 +267,7 @@ module.exports = function (grunt) {
|
||||
filename: "index.html",
|
||||
template: "./src/web/html/index.html",
|
||||
compileTime: compileTime,
|
||||
version: pkg.version,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
@@ -269,6 +279,7 @@ module.exports = function (grunt) {
|
||||
filename: "cyberchef.htm",
|
||||
template: "./src/web/html/index.html",
|
||||
compileTime: compileTime,
|
||||
version: pkg.version,
|
||||
inline: true,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
@@ -301,7 +312,7 @@ module.exports = function (grunt) {
|
||||
copy: {
|
||||
ghPages: {
|
||||
options: {
|
||||
process: function (content, srcpath) {
|
||||
process: function (content) {
|
||||
// Add Google Analytics code to index.html
|
||||
content = content.replace("</body></html>",
|
||||
grunt.file.read("src/web/static/ga.html") + "</body></html>");
|
||||
@@ -342,5 +353,4 @@ module.exports = function (grunt) {
|
||||
test: "build/test/index.js"
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# CyberChef
|
||||
|
||||
[](https://travis-ci.org/gchq/CyberChef)
|
||||
[](https://www.npmjs.com/package/cyberchef)
|
||||

|
||||
|
||||
#### *The Cyber Swiss Army Knife*
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
"tags": {
|
||||
"allowUnknownTags": true
|
||||
},
|
||||
"plugins": ["plugins/markdown"],
|
||||
"plugins": [
|
||||
"plugins/markdown",
|
||||
"node_modules/jsdoc-babel"
|
||||
],
|
||||
"templates": {
|
||||
"systemName": "CyberChef",
|
||||
"footer": "",
|
||||
|
||||
17
package.json
17
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "5.2.4",
|
||||
"version": "5.9.1",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -19,13 +19,16 @@
|
||||
"hex",
|
||||
"encoding",
|
||||
"format",
|
||||
"cybersecurity"
|
||||
"cybersecurity",
|
||||
"data manipulation",
|
||||
"data analysis"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/gchq/CyberChef/"
|
||||
},
|
||||
"main": "build/node/CyberChef.js",
|
||||
"bugs": "https://github.com/gchq/CyberChef/issues",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.24.0",
|
||||
"babel-loader": "^6.4.0",
|
||||
@@ -48,8 +51,12 @@
|
||||
"html-webpack-plugin": "^2.28.0",
|
||||
"imports-loader": "^0.7.1",
|
||||
"ink-docstrap": "^1.1.4",
|
||||
"jsdoc-babel": "^0.3.0",
|
||||
"less": "^2.7.2",
|
||||
"less-loader": "^4.0.2",
|
||||
"less-loader": "^4.0.3",
|
||||
"postcss-css-variables": "^0.7.0",
|
||||
"postcss-import": "^10.0.0",
|
||||
"postcss-loader": "^2.0.5",
|
||||
"style-loader": "^0.15.0",
|
||||
"url-loader": "^0.5.8",
|
||||
"web-resource-inliner": "^4.1.0",
|
||||
@@ -65,10 +72,12 @@
|
||||
"escodegen": "^1.8.1",
|
||||
"esmangle": "^1.0.1",
|
||||
"esprima": "^3.1.3",
|
||||
"exif-parser": "^0.1.9",
|
||||
"google-code-prettify": "^1.0.5",
|
||||
"jquery": "^3.1.1",
|
||||
"jsbn": "^1.1.0",
|
||||
"jsrsasign": "^7.1.0",
|
||||
"jsrsasign": "7.1.3",
|
||||
"lodash": "^4.17.4",
|
||||
"moment": "^2.17.1",
|
||||
"moment-timezone": "^0.5.11",
|
||||
"sladex-blowfish": "^0.8.1",
|
||||
|
||||
15
postcss.config.js
Normal file
15
postcss.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require("postcss-import"),
|
||||
require("autoprefixer")({
|
||||
browsers: [
|
||||
"Chrome >= 40",
|
||||
"Firefox >= 35",
|
||||
"Edge >= 14"
|
||||
]
|
||||
}),
|
||||
require("postcss-css-variables")({
|
||||
preserve: true
|
||||
}),
|
||||
]
|
||||
};
|
||||
@@ -11,7 +11,7 @@ import Recipe from "./Recipe.js";
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
var Chef = function() {
|
||||
const Chef = function() {
|
||||
this.dish = new Dish();
|
||||
};
|
||||
|
||||
@@ -34,8 +34,8 @@ var Chef = function() {
|
||||
* @returns {number} response.duration - The number of ms it took to execute the recipe
|
||||
* @returns {number} response.error - The error object thrown by a failed operation (false if no error)
|
||||
*/
|
||||
Chef.prototype.bake = function(inputText, recipeConfig, options, progress, step) {
|
||||
var startTime = new Date().getTime(),
|
||||
Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, step) {
|
||||
let startTime = new Date().getTime(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
containsFc = recipe.containsFlowControl(),
|
||||
error = false;
|
||||
@@ -72,7 +72,7 @@ Chef.prototype.bake = function(inputText, recipeConfig, options, progress, step)
|
||||
}
|
||||
|
||||
try {
|
||||
progress = recipe.execute(this.dish, progress);
|
||||
progress = await recipe.execute(this.dish, progress);
|
||||
} catch (err) {
|
||||
// Return the error in the result so that everything else gets correctly updated
|
||||
// rather than throwing it here and losing state info.
|
||||
@@ -111,7 +111,7 @@ Chef.prototype.bake = function(inputText, recipeConfig, options, progress, step)
|
||||
* @returns {number} The time it took to run the silent bake in milliseconds.
|
||||
*/
|
||||
Chef.prototype.silentBake = function(recipeConfig) {
|
||||
var startTime = new Date().getTime(),
|
||||
let startTime = new Date().getTime(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
dish = new Dish("", Dish.STRING);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Utils from "./Utils.js";
|
||||
|
||||
|
||||
/**
|
||||
* The data being operated on by each operation.
|
||||
*
|
||||
@@ -12,7 +11,7 @@ import Utils from "./Utils.js";
|
||||
* @param {byteArray|string|number} value - The value of the input data.
|
||||
* @param {number} type - The data type of value, see Dish enums.
|
||||
*/
|
||||
var Dish = function(value, type) {
|
||||
const Dish = function(value, type) {
|
||||
this.value = value || typeof value == "string" ? value : null;
|
||||
this.type = type || Dish.BYTE_ARRAY;
|
||||
};
|
||||
@@ -105,7 +104,7 @@ Dish.prototype.set = function(value, type) {
|
||||
this.type = type;
|
||||
|
||||
if (!this.valid()) {
|
||||
var sample = Utils.truncate(JSON.stringify(this.value), 13);
|
||||
const sample = Utils.truncate(JSON.stringify(this.value), 13);
|
||||
throw "Data is not a valid " + Dish.enumLookup(type) + ": " + sample;
|
||||
}
|
||||
};
|
||||
@@ -180,7 +179,7 @@ Dish.prototype.valid = function() {
|
||||
}
|
||||
|
||||
// Check that every value is a number between 0 - 255
|
||||
for (var i = 0; i < this.value.length; i++) {
|
||||
for (let i = 0; i < this.value.length; i++) {
|
||||
if (typeof this.value[i] != "number" ||
|
||||
this.value[i] < 0 ||
|
||||
this.value[i] > 255) {
|
||||
|
||||
@@ -38,8 +38,8 @@ const FlowControl = {
|
||||
* @param {Operation[]} state.opList - The list of operations in the recipe.
|
||||
* @returns {Object} The updated state of the recipe.
|
||||
*/
|
||||
runFork: function(state) {
|
||||
var opList = state.opList,
|
||||
runFork: async function(state) {
|
||||
let opList = state.opList,
|
||||
inputType = opList[state.progress].inputType,
|
||||
outputType = opList[state.progress].outputType,
|
||||
input = state.dish.get(inputType),
|
||||
@@ -48,14 +48,15 @@ const FlowControl = {
|
||||
mergeDelim = ings[1],
|
||||
ignoreErrors = ings[2],
|
||||
subOpList = [],
|
||||
inputs = [];
|
||||
inputs = [],
|
||||
i;
|
||||
|
||||
if (input)
|
||||
inputs = input.split(splitDelim);
|
||||
|
||||
// Create subOpList for each tranche to operate on
|
||||
// (all remaining operations unless we encounter a Merge)
|
||||
for (var i = state.progress + 1; i < opList.length; i++) {
|
||||
for (i = state.progress + 1; i < opList.length; i++) {
|
||||
if (opList[i].name === "Merge" && !opList[i].isDisabled()) {
|
||||
break;
|
||||
} else {
|
||||
@@ -63,7 +64,7 @@ const FlowControl = {
|
||||
}
|
||||
}
|
||||
|
||||
var recipe = new Recipe(),
|
||||
let recipe = new Recipe(),
|
||||
output = "",
|
||||
progress = 0;
|
||||
|
||||
@@ -71,9 +72,9 @@ const FlowControl = {
|
||||
|
||||
// Run recipe over each tranche
|
||||
for (i = 0; i < inputs.length; i++) {
|
||||
var dish = new Dish(inputs[i], inputType);
|
||||
const dish = new Dish(inputs[i], inputType);
|
||||
try {
|
||||
progress = recipe.execute(dish, 0);
|
||||
progress = await recipe.execute(dish, 0);
|
||||
} catch (err) {
|
||||
if (!ignoreErrors) {
|
||||
throw err;
|
||||
@@ -127,7 +128,7 @@ const FlowControl = {
|
||||
* @returns {Object} The updated state of the recipe.
|
||||
*/
|
||||
runJump: function(state) {
|
||||
var ings = state.opList[state.progress].getIngValues(),
|
||||
let ings = state.opList[state.progress].getIngValues(),
|
||||
jumpNum = ings[0],
|
||||
maxJumps = ings[1];
|
||||
|
||||
@@ -156,7 +157,7 @@ const FlowControl = {
|
||||
* @returns {Object} The updated state of the recipe.
|
||||
*/
|
||||
runCondJump: function(state) {
|
||||
var ings = state.opList[state.progress].getIngValues(),
|
||||
let ings = state.opList[state.progress].getIngValues(),
|
||||
dish = state.dish,
|
||||
regexStr = ings[0],
|
||||
jumpNum = ings[1],
|
||||
@@ -193,6 +194,20 @@ const FlowControl = {
|
||||
return state;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Comment operation.
|
||||
*
|
||||
* @param {Object} state - The current state of the recipe.
|
||||
* @param {number} state.progress - The current position in the recipe.
|
||||
* @param {Dish} state.dish - The Dish being operated on.
|
||||
* @param {Operation[]} state.opList - The list of operations in the recipe.
|
||||
* @returns {Object} The updated state of the recipe.
|
||||
*/
|
||||
runComment: function(state) {
|
||||
return state;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default FlowControl;
|
||||
|
||||
@@ -11,7 +11,7 @@ import Utils from "./Utils.js";
|
||||
* @class
|
||||
* @param {Object} ingredientConfig
|
||||
*/
|
||||
var Ingredient = function(ingredientConfig) {
|
||||
const Ingredient = function(ingredientConfig) {
|
||||
this.name = "";
|
||||
this.type = "";
|
||||
this.value = null;
|
||||
@@ -63,6 +63,8 @@ Ingredient.prototype.setValue = function(value) {
|
||||
* @param {string} type - The name of the data type.
|
||||
*/
|
||||
Ingredient.prepare = function(data, type) {
|
||||
let number;
|
||||
|
||||
switch (type) {
|
||||
case "binaryString":
|
||||
case "binaryShortString":
|
||||
@@ -76,9 +78,9 @@ Ingredient.prepare = function(data, type) {
|
||||
return data;
|
||||
}
|
||||
case "number":
|
||||
var number = parseFloat(data);
|
||||
number = parseFloat(data);
|
||||
if (isNaN(number)) {
|
||||
var sample = Utils.truncate(data.toString(), 10);
|
||||
const sample = Utils.truncate(data.toString(), 10);
|
||||
throw "Invalid ingredient value. Not a number: " + sample;
|
||||
}
|
||||
return number;
|
||||
|
||||
@@ -13,7 +13,7 @@ import Ingredient from "./Ingredient.js";
|
||||
* @param {string} operationName
|
||||
* @param {Object} operationConfig
|
||||
*/
|
||||
var Operation = function(operationName, operationConfig) {
|
||||
const Operation = function(operationName, operationConfig) {
|
||||
this.name = operationName;
|
||||
this.description = "";
|
||||
this.inputType = -1;
|
||||
@@ -46,9 +46,9 @@ Operation.prototype._parseConfig = function(operationConfig) {
|
||||
this.highlightReverse = operationConfig.highlightReverse;
|
||||
this.flowControl = operationConfig.flowControl;
|
||||
|
||||
for (var a = 0; a < operationConfig.args.length; a++) {
|
||||
var ingredientConfig = operationConfig.args[a];
|
||||
var ingredient = new Ingredient(ingredientConfig);
|
||||
for (let a = 0; a < operationConfig.args.length; a++) {
|
||||
const ingredientConfig = operationConfig.args[a];
|
||||
const ingredient = new Ingredient(ingredientConfig);
|
||||
this.addIngredient(ingredient);
|
||||
}
|
||||
};
|
||||
@@ -60,13 +60,13 @@ Operation.prototype._parseConfig = function(operationConfig) {
|
||||
* @returns {Object}
|
||||
*/
|
||||
Operation.prototype.getConfig = function() {
|
||||
var ingredientConfig = [];
|
||||
const ingredientConfig = [];
|
||||
|
||||
for (var o = 0; o < this.ingList.length; o++) {
|
||||
for (let o = 0; o < this.ingList.length; o++) {
|
||||
ingredientConfig.push(this.ingList[o].getConfig());
|
||||
}
|
||||
|
||||
var operationConfig = {
|
||||
const operationConfig = {
|
||||
"op": this.name,
|
||||
"args": ingredientConfig
|
||||
};
|
||||
@@ -91,7 +91,7 @@ Operation.prototype.addIngredient = function(ingredient) {
|
||||
* @param {Object[]} ingValues
|
||||
*/
|
||||
Operation.prototype.setIngValues = function(ingValues) {
|
||||
for (var i = 0; i < ingValues.length; i++) {
|
||||
for (let i = 0; i < ingValues.length; i++) {
|
||||
this.ingList[i].setValue(ingValues[i]);
|
||||
}
|
||||
};
|
||||
@@ -103,8 +103,8 @@ Operation.prototype.setIngValues = function(ingValues) {
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
Operation.prototype.getIngValues = function() {
|
||||
var ingValues = [];
|
||||
for (var i = 0; i < this.ingList.length; i++) {
|
||||
const ingValues = [];
|
||||
for (let i = 0; i < this.ingList.length; i++) {
|
||||
ingValues.push(this.ingList[i].value);
|
||||
}
|
||||
return ingValues;
|
||||
|
||||
@@ -12,7 +12,7 @@ import OperationConfig from "./config/OperationConfig.js";
|
||||
* @class
|
||||
* @param {Object} recipeConfig
|
||||
*/
|
||||
var Recipe = function(recipeConfig) {
|
||||
const Recipe = function(recipeConfig) {
|
||||
this.opList = [];
|
||||
|
||||
if (recipeConfig) {
|
||||
@@ -28,10 +28,10 @@ var Recipe = function(recipeConfig) {
|
||||
* @param {Object} recipeConfig
|
||||
*/
|
||||
Recipe.prototype._parseConfig = function(recipeConfig) {
|
||||
for (var c = 0; c < recipeConfig.length; c++) {
|
||||
var operationName = recipeConfig[c].op;
|
||||
var operationConfig = OperationConfig[operationName];
|
||||
var operation = new Operation(operationName, operationConfig);
|
||||
for (let c = 0; c < recipeConfig.length; c++) {
|
||||
const operationName = recipeConfig[c].op;
|
||||
const operationConfig = OperationConfig[operationName];
|
||||
const operation = new Operation(operationName, operationConfig);
|
||||
operation.setIngValues(recipeConfig[c].args);
|
||||
operation.setBreakpoint(recipeConfig[c].breakpoint);
|
||||
operation.setDisabled(recipeConfig[c].disabled);
|
||||
@@ -46,9 +46,9 @@ Recipe.prototype._parseConfig = function(recipeConfig) {
|
||||
* @returns {*}
|
||||
*/
|
||||
Recipe.prototype.getConfig = function() {
|
||||
var recipeConfig = [];
|
||||
const recipeConfig = [];
|
||||
|
||||
for (var o = 0; o < this.opList.length; o++) {
|
||||
for (let o = 0; o < this.opList.length; o++) {
|
||||
recipeConfig.push(this.opList[o].getConfig());
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ Recipe.prototype.setBreakpoint = function(position, value) {
|
||||
* @param {number} pos
|
||||
*/
|
||||
Recipe.prototype.removeBreaksUpTo = function(pos) {
|
||||
for (var i = 0; i < pos; i++) {
|
||||
for (let i = 0; i < pos; i++) {
|
||||
this.opList[i].setBreakpoint(false);
|
||||
}
|
||||
};
|
||||
@@ -110,7 +110,7 @@ Recipe.prototype.removeBreaksUpTo = function(pos) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
Recipe.prototype.containsFlowControl = function() {
|
||||
for (var i = 0; i < this.opList.length; i++) {
|
||||
for (let i = 0; i < this.opList.length; i++) {
|
||||
if (this.opList[i].isFlowControl()) return true;
|
||||
}
|
||||
return false;
|
||||
@@ -125,7 +125,7 @@ Recipe.prototype.containsFlowControl = function() {
|
||||
* @returns (number}
|
||||
*/
|
||||
Recipe.prototype.lastOpIndex = function(startIndex) {
|
||||
var i = startIndex + 1 || 0,
|
||||
let i = startIndex + 1 || 0,
|
||||
op;
|
||||
|
||||
for (; i < this.opList.length; i++) {
|
||||
@@ -145,11 +145,11 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
|
||||
* @param {number} [startFrom=0] - The index of the Operation to start executing from
|
||||
* @returns {number} - The final progress through the recipe
|
||||
*/
|
||||
Recipe.prototype.execute = function(dish, startFrom) {
|
||||
Recipe.prototype.execute = async function(dish, startFrom) {
|
||||
startFrom = startFrom || 0;
|
||||
var op, input, output, numJumps = 0;
|
||||
let op, input, output, numJumps = 0;
|
||||
|
||||
for (var i = startFrom; i < this.opList.length; i++) {
|
||||
for (let i = startFrom; i < this.opList.length; i++) {
|
||||
op = this.opList[i];
|
||||
if (op.isDisabled()) {
|
||||
continue;
|
||||
@@ -163,22 +163,22 @@ Recipe.prototype.execute = function(dish, startFrom) {
|
||||
|
||||
if (op.isFlowControl()) {
|
||||
// Package up the current state
|
||||
var state = {
|
||||
let state = {
|
||||
"progress" : i,
|
||||
"dish" : dish,
|
||||
"opList" : this.opList,
|
||||
"numJumps" : numJumps
|
||||
};
|
||||
|
||||
state = op.run(state);
|
||||
state = await op.run(state);
|
||||
i = state.progress;
|
||||
numJumps = state.numJumps;
|
||||
} else {
|
||||
output = op.run(input, op.getIngValues());
|
||||
output = await op.run(input, op.getIngValues());
|
||||
dish.set(output, op.outputType);
|
||||
}
|
||||
} catch (err) {
|
||||
var e = typeof err == "string" ? { message: err } : err;
|
||||
const e = typeof err == "string" ? { message: err } : err;
|
||||
|
||||
e.progress = i;
|
||||
if (e.fileName) {
|
||||
@@ -213,7 +213,7 @@ Recipe.prototype.toString = function() {
|
||||
* @param {string} recipeStr
|
||||
*/
|
||||
Recipe.prototype.fromString = function(recipeStr) {
|
||||
var recipeConfig = JSON.parse(recipeStr);
|
||||
const recipeConfig = JSON.parse(recipeStr);
|
||||
this._parseConfig(recipeConfig);
|
||||
};
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ const Utils = {
|
||||
*/
|
||||
padLeft: function(str, max, chr) {
|
||||
chr = chr || "0";
|
||||
var startIndex = chr.length - (max - str.length);
|
||||
let startIndex = chr.length - (max - str.length);
|
||||
startIndex = startIndex < 0 ? 0 : startIndex;
|
||||
return str.length < max ?
|
||||
Utils.padLeft(chr.slice(startIndex, chr.length) + str, max, chr) : str;
|
||||
@@ -119,7 +119,7 @@ const Utils = {
|
||||
*/
|
||||
padBytesRight: function(arr, numBytes, padByte) {
|
||||
padByte = padByte || 0;
|
||||
var paddedBytes = new Array(numBytes);
|
||||
const paddedBytes = new Array(numBytes);
|
||||
paddedBytes.fill(padByte);
|
||||
|
||||
Array.prototype.map.call(arr, function(b, i) {
|
||||
@@ -216,8 +216,8 @@ const Utils = {
|
||||
str = Utils.byteArrayToChars(Utils.strToByteArray(str));
|
||||
}
|
||||
|
||||
var re = /[\0-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g;
|
||||
var wsRe = /[\x09-\x10\x0D\u2028\u2029]/g;
|
||||
const re = /[\0-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g;
|
||||
const wsRe = /[\x09-\x10\x0D\u2028\u2029]/g;
|
||||
|
||||
str = str.replace(re, ".");
|
||||
if (!preserveWs) str = str.replace(wsRe, ".");
|
||||
@@ -276,16 +276,16 @@ const Utils = {
|
||||
* Utils.expandAlphRange("a-d0\\-3")
|
||||
*/
|
||||
expandAlphRange: function(alphStr) {
|
||||
var alphArr = [];
|
||||
const alphArr = [];
|
||||
|
||||
for (var i = 0; i < alphStr.length; i++) {
|
||||
for (let i = 0; i < alphStr.length; i++) {
|
||||
if (i < alphStr.length - 2 &&
|
||||
alphStr[i+1] === "-" &&
|
||||
alphStr[i] !== "\\") {
|
||||
var start = Utils.ord(alphStr[i]),
|
||||
let start = Utils.ord(alphStr[i]),
|
||||
end = Utils.ord(alphStr[i+2]);
|
||||
|
||||
for (var j = start; j <= end; j++) {
|
||||
for (let j = start; j <= end; j++) {
|
||||
alphArr.push(Utils.chr(j));
|
||||
}
|
||||
i += 2;
|
||||
@@ -316,8 +316,8 @@ const Utils = {
|
||||
// TODO: Handle errors i.e. input string is not hex
|
||||
if (!hexStr) return [];
|
||||
hexStr = hexStr.replace(/\s+/g, "");
|
||||
var byteArray = [];
|
||||
for (var i = 0; i < hexStr.length; i += 2) {
|
||||
const byteArray = [];
|
||||
for (let i = 0; i < hexStr.length; i += 2) {
|
||||
byteArray.push(parseInt(hexStr.substr(i, 2), 16));
|
||||
}
|
||||
return byteArray;
|
||||
@@ -336,8 +336,8 @@ const Utils = {
|
||||
*/
|
||||
byteArrayToHex: function(byteArray) {
|
||||
if (!byteArray) return "";
|
||||
var hexStr = "";
|
||||
for (var i = 0; i < byteArray.length; i++) {
|
||||
let hexStr = "";
|
||||
for (let i = 0; i < byteArray.length; i++) {
|
||||
hexStr += Utils.hex(byteArray[i]) + " ";
|
||||
}
|
||||
return hexStr.slice(0, hexStr.length-1);
|
||||
@@ -359,8 +359,8 @@ const Utils = {
|
||||
* Utils.strToByteArray("你好");
|
||||
*/
|
||||
strToByteArray: function(str) {
|
||||
var byteArray = new Array(str.length);
|
||||
var i = str.length, b;
|
||||
const byteArray = new Array(str.length);
|
||||
let i = str.length, b;
|
||||
while (i--) {
|
||||
b = str.charCodeAt(i);
|
||||
byteArray[i] = b;
|
||||
@@ -385,7 +385,7 @@ const Utils = {
|
||||
* Utils.strToUtf8ByteArray("你好");
|
||||
*/
|
||||
strToUtf8ByteArray: function(str) {
|
||||
var wordArray = CryptoJS.enc.Utf8.parse(str),
|
||||
let wordArray = CryptoJS.enc.Utf8.parse(str),
|
||||
byteArray = Utils.wordArrayToByteArray(wordArray);
|
||||
|
||||
if (typeof window !== "undefined" && str.length !== wordArray.sigBytes) {
|
||||
@@ -409,8 +409,8 @@ const Utils = {
|
||||
* Utils.strToCharcode("你好");
|
||||
*/
|
||||
strToCharcode: function(str) {
|
||||
var byteArray = new Array(str.length);
|
||||
var i = str.length;
|
||||
const byteArray = new Array(str.length);
|
||||
let i = str.length;
|
||||
while (i--) {
|
||||
byteArray[i] = str.charCodeAt(i);
|
||||
}
|
||||
@@ -434,11 +434,11 @@ const Utils = {
|
||||
byteArrayToUtf8: function(byteArray) {
|
||||
try {
|
||||
// Try to output data as UTF-8 string
|
||||
var words = [];
|
||||
for (var i = 0; i < byteArray.length; i++) {
|
||||
const words = [];
|
||||
for (let i = 0; i < byteArray.length; i++) {
|
||||
words[i >>> 2] |= byteArray[i] << (24 - (i % 4) * 8);
|
||||
}
|
||||
var wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
|
||||
let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
|
||||
str = CryptoJS.enc.Utf8.stringify(wordArray);
|
||||
|
||||
if (typeof window !== "undefined" && str.length !== wordArray.sigBytes)
|
||||
@@ -466,8 +466,8 @@ const Utils = {
|
||||
*/
|
||||
byteArrayToChars: function(byteArray) {
|
||||
if (!byteArray) return "";
|
||||
var str = "";
|
||||
for (var i = 0; i < byteArray.length;) {
|
||||
let str = "";
|
||||
for (let i = 0; i < byteArray.length;) {
|
||||
str += String.fromCharCode(byteArray[i++]);
|
||||
}
|
||||
return str;
|
||||
@@ -487,10 +487,10 @@ const Utils = {
|
||||
wordArrayToByteArray: function(wordArray) {
|
||||
if (wordArray.sigBytes <= 0) return [];
|
||||
|
||||
var words = wordArray.words,
|
||||
let words = wordArray.words,
|
||||
byteArray = [];
|
||||
|
||||
for (var i = 0; i < wordArray.sigBytes; i++) {
|
||||
for (let i = 0; i < wordArray.sigBytes; i++) {
|
||||
byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
|
||||
}
|
||||
|
||||
@@ -498,127 +498,6 @@ const Utils = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Mapping of Unicode code points to Windows-1251
|
||||
* @private
|
||||
* @constant
|
||||
*/
|
||||
UNIC_WIN1251_MAP: {
|
||||
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13,
|
||||
14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24,
|
||||
25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35,
|
||||
36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 44: 44, 45: 45, 46: 46,
|
||||
47: 47, 48: 48, 49: 49, 50: 50, 51: 51, 52: 52, 53: 53, 54: 54, 55: 55, 56: 56, 57: 57,
|
||||
58: 58, 59: 59, 60: 60, 61: 61, 62: 62, 63: 63, 64: 64, 65: 65, 66: 66, 67: 67, 68: 68,
|
||||
69: 69, 70: 70, 71: 71, 72: 72, 73: 73, 74: 74, 75: 75, 76: 76, 77: 77, 78: 78, 79: 79,
|
||||
80: 80, 81: 81, 82: 82, 83: 83, 84: 84, 85: 85, 86: 86, 87: 87, 88: 88, 89: 89, 90: 90,
|
||||
91: 91, 92: 92, 93: 93, 94: 94, 95: 95, 96: 96, 97: 97, 98: 98, 99: 99, 100: 100, 101: 101,
|
||||
102: 102, 103: 103, 104: 104, 105: 105, 106: 106, 107: 107, 108: 108, 109: 109, 110: 110,
|
||||
111: 111, 112: 112, 113: 113, 114: 114, 115: 115, 116: 116, 117: 117, 118: 118, 119: 119,
|
||||
120: 120, 121: 121, 122: 122, 123: 123, 124: 124, 125: 125, 126: 126, 127: 127, 1027: 129,
|
||||
8225: 135, 1046: 198, 8222: 132, 1047: 199, 1168: 165, 1048: 200, 1113: 154, 1049: 201,
|
||||
1045: 197, 1050: 202, 1028: 170, 160: 160, 1040: 192, 1051: 203, 164: 164, 166: 166,
|
||||
167: 167, 169: 169, 171: 171, 172: 172, 173: 173, 174: 174, 1053: 205, 176: 176, 177: 177,
|
||||
1114: 156, 181: 181, 182: 182, 183: 183, 8221: 148, 187: 187, 1029: 189, 1056: 208,
|
||||
1057: 209, 1058: 210, 8364: 136, 1112: 188, 1115: 158, 1059: 211, 1060: 212, 1030: 178,
|
||||
1061: 213, 1062: 214, 1063: 215, 1116: 157, 1064: 216, 1065: 217, 1031: 175, 1066: 218,
|
||||
1067: 219, 1068: 220, 1069: 221, 1070: 222, 1032: 163, 8226: 149, 1071: 223, 1072: 224,
|
||||
8482: 153, 1073: 225, 8240: 137, 1118: 162, 1074: 226, 1110: 179, 8230: 133, 1075: 227,
|
||||
1033: 138, 1076: 228, 1077: 229, 8211: 150, 1078: 230, 1119: 159, 1079: 231, 1042: 194,
|
||||
1080: 232, 1034: 140, 1025: 168, 1081: 233, 1082: 234, 8212: 151, 1083: 235, 1169: 180,
|
||||
1084: 236, 1052: 204, 1085: 237, 1035: 142, 1086: 238, 1087: 239, 1088: 240, 1089: 241,
|
||||
1090: 242, 1036: 141, 1041: 193, 1091: 243, 1092: 244, 8224: 134, 1093: 245, 8470: 185,
|
||||
1094: 246, 1054: 206, 1095: 247, 1096: 248, 8249: 139, 1097: 249, 1098: 250, 1044: 196,
|
||||
1099: 251, 1111: 191, 1055: 207, 1100: 252, 1038: 161, 8220: 147, 1101: 253, 8250: 155,
|
||||
1102: 254, 8216: 145, 1103: 255, 1043: 195, 1105: 184, 1039: 143, 1026: 128, 1106: 144,
|
||||
8218: 130, 1107: 131, 8217: 146, 1108: 186, 1109: 190
|
||||
},
|
||||
|
||||
/**
|
||||
* Mapping of Windows-1251 code points to Unicode
|
||||
* @private
|
||||
* @constant
|
||||
*/
|
||||
WIN1251_UNIC_MAP: {
|
||||
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13,
|
||||
14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24,
|
||||
25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35,
|
||||
36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 44: 44, 45: 45, 46: 46,
|
||||
47: 47, 48: 48, 49: 49, 50: 50, 51: 51, 52: 52, 53: 53, 54: 54, 55: 55, 56: 56, 57: 57,
|
||||
58: 58, 59: 59, 60: 60, 61: 61, 62: 62, 63: 63, 64: 64, 65: 65, 66: 66, 67: 67, 68: 68,
|
||||
69: 69, 70: 70, 71: 71, 72: 72, 73: 73, 74: 74, 75: 75, 76: 76, 77: 77, 78: 78, 79: 79,
|
||||
80: 80, 81: 81, 82: 82, 83: 83, 84: 84, 85: 85, 86: 86, 87: 87, 88: 88, 89: 89, 90: 90,
|
||||
91: 91, 92: 92, 93: 93, 94: 94, 95: 95, 96: 96, 97: 97, 98: 98, 99: 99, 100: 100, 101: 101,
|
||||
102: 102, 103: 103, 104: 104, 105: 105, 106: 106, 107: 107, 108: 108, 109: 109, 110: 110,
|
||||
111: 111, 112: 112, 113: 113, 114: 114, 115: 115, 116: 116, 117: 117, 118: 118, 119: 119,
|
||||
120: 120, 121: 121, 122: 122, 123: 123, 124: 124, 125: 125, 126: 126, 127: 127, 160: 160,
|
||||
164: 164, 166: 166, 167: 167, 169: 169, 171: 171, 172: 172, 173: 173, 174: 174, 176: 176,
|
||||
177: 177, 181: 181, 182: 182, 183: 183, 187: 187, 168: 1025, 128: 1026, 129: 1027,
|
||||
170: 1028, 189: 1029, 178: 1030, 175: 1031, 163: 1032, 138: 1033, 140: 1034, 142: 1035,
|
||||
141: 1036, 161: 1038, 143: 1039, 192: 1040, 193: 1041, 194: 1042, 195: 1043, 196: 1044,
|
||||
197: 1045, 198: 1046, 199: 1047, 200: 1048, 201: 1049, 202: 1050, 203: 1051, 204: 1052,
|
||||
205: 1053, 206: 1054, 207: 1055, 208: 1056, 209: 1057, 210: 1058, 211: 1059, 212: 1060,
|
||||
213: 1061, 214: 1062, 215: 1063, 216: 1064, 217: 1065, 218: 1066, 219: 1067, 220: 1068,
|
||||
221: 1069, 222: 1070, 223: 1071, 224: 1072, 225: 1073, 226: 1074, 227: 1075, 228: 1076,
|
||||
229: 1077, 230: 1078, 231: 1079, 232: 1080, 233: 1081, 234: 1082, 235: 1083, 236: 1084,
|
||||
237: 1085, 238: 1086, 239: 1087, 240: 1088, 241: 1089, 242: 1090, 243: 1091, 244: 1092,
|
||||
245: 1093, 246: 1094, 247: 1095, 248: 1096, 249: 1097, 250: 1098, 251: 1099, 252: 1100,
|
||||
253: 1101, 254: 1102, 255: 1103, 184: 1105, 144: 1106, 131: 1107, 186: 1108, 190: 1109,
|
||||
179: 1110, 191: 1111, 188: 1112, 154: 1113, 156: 1114, 158: 1115, 157: 1116, 162: 1118,
|
||||
159: 1119, 165: 1168, 180: 1169, 150: 8211, 151: 8212, 145: 8216, 146: 8217, 130: 8218,
|
||||
147: 8220, 148: 8221, 132: 8222, 134: 8224, 135: 8225, 149: 8226, 133: 8230, 137: 8240,
|
||||
139: 8249, 155: 8250, 136: 8364, 185: 8470, 153: 8482
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts a Unicode string to Windows-1251 encoding
|
||||
*
|
||||
* @param {string} unicStr
|
||||
* @returns {string} String encoded in Windows-1251
|
||||
*
|
||||
* @example
|
||||
* // returns "îáíîâëåííàÿ òåõíè÷êà ïî Áîèíãó. îðèãèíàë ó ìåíÿ. çàáåðåòå êîãäà áóäåòå â ÊÈ"
|
||||
* Utils.unicodeToWin1251("обновленная техничка по Боингу. оригинал у меня. заберете когда будете в КИ");
|
||||
*/
|
||||
unicodeToWin1251: function(unicStr) {
|
||||
var res = [];
|
||||
|
||||
for (var i = 0; i < unicStr.length; i++) {
|
||||
var ord = unicStr.charCodeAt(i);
|
||||
if (!(ord in Utils.UNIC_WIN1251_MAP))
|
||||
throw "Character '" + unicStr.charAt(i) + "' isn't supported by Windows-1251";
|
||||
res.push(String.fromCharCode(Utils.UNIC_WIN1251_MAP[ord]));
|
||||
}
|
||||
|
||||
return res.join("");
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts a Windows-1251 string to Unicode encoding
|
||||
*
|
||||
* @param {string} win1251Str
|
||||
* @returns {string} String encoded in Unicode
|
||||
*
|
||||
* @example
|
||||
* // returns "обновленная техничка по Боингу. оригинал у меня. заберете когда будете в КИ"
|
||||
* Utils.unicodeToWin1251("îáíîâëåííàÿ òåõíè÷êà ïî Áîèíãó. îðèãèíàë ó ìåíÿ. çàáåðåòå êîãäà áóäåòå â ÊÈ");
|
||||
*/
|
||||
win1251ToUnicode: function(win1251Str) {
|
||||
var res = [];
|
||||
|
||||
for (var i = 0; i < win1251Str.length; i++) {
|
||||
var ord = win1251Str.charCodeAt(i);
|
||||
if (!(ord in Utils.WIN1251_UNIC_MAP))
|
||||
throw "Character '" + win1251Str.charAt(i) + "' isn't supported by Windows-1251";
|
||||
res.push(String.fromCharCode(Utils.WIN1251_UNIC_MAP[ord]));
|
||||
}
|
||||
|
||||
return res.join("");
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Base64's the input byte array using the given alphabet, returning a string.
|
||||
*
|
||||
@@ -642,7 +521,7 @@ const Utils = {
|
||||
alphabet = alphabet ?
|
||||
Utils.expandAlphRange(alphabet).join("") :
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
var output = "",
|
||||
let output = "",
|
||||
chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
@@ -700,13 +579,13 @@ const Utils = {
|
||||
if (removeNonAlphChars === undefined)
|
||||
removeNonAlphChars = true;
|
||||
|
||||
var output = [],
|
||||
let output = [],
|
||||
chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
var re = new RegExp("[^" + alphabet.replace(/[\[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
const re = new RegExp("[^" + alphabet.replace(/[\[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
data = data.replace(re, "");
|
||||
}
|
||||
|
||||
@@ -758,9 +637,9 @@ const Utils = {
|
||||
|
||||
delim = typeof delim == "string" ? delim : " ";
|
||||
padding = padding || 2;
|
||||
var output = "";
|
||||
let output = "";
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output += Utils.pad(data[i].toString(16), padding) + delim;
|
||||
}
|
||||
|
||||
@@ -788,9 +667,9 @@ const Utils = {
|
||||
toHexFast: function(data) {
|
||||
if (!data) return "";
|
||||
|
||||
var output = [];
|
||||
const output = [];
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output.push((data[i] >>> 4).toString(16));
|
||||
output.push((data[i] & 0x0f).toString(16));
|
||||
}
|
||||
@@ -818,12 +697,12 @@ const Utils = {
|
||||
delim = delim || (data.indexOf(" ") >= 0 ? "Space" : "None");
|
||||
byteLen = byteLen || 2;
|
||||
if (delim !== "None") {
|
||||
var delimRegex = Utils.regexRep[delim];
|
||||
const delimRegex = Utils.regexRep[delim];
|
||||
data = data.replace(delimRegex, "");
|
||||
}
|
||||
|
||||
var output = [];
|
||||
for (var i = 0; i < data.length; i += byteLen) {
|
||||
const output = [];
|
||||
for (let i = 0; i < data.length; i += byteLen) {
|
||||
output.push(parseInt(data.substr(i, byteLen), 16));
|
||||
}
|
||||
return output;
|
||||
@@ -842,14 +721,14 @@ const Utils = {
|
||||
*/
|
||||
parseCSV: function(data) {
|
||||
|
||||
var b,
|
||||
let b,
|
||||
ignoreNext = false,
|
||||
inString = false,
|
||||
cell = "",
|
||||
line = [],
|
||||
lines = [];
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
b = data[i];
|
||||
if (ignoreNext) {
|
||||
cell += b;
|
||||
@@ -914,7 +793,7 @@ const Utils = {
|
||||
* Utils.escapeHtml("A <script> tag");
|
||||
*/
|
||||
escapeHtml: function(str) {
|
||||
var HTML_CHARS = {
|
||||
const HTML_CHARS = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
@@ -941,7 +820,7 @@ const Utils = {
|
||||
* Utils.unescapeHtml("A <script> tag");
|
||||
*/
|
||||
unescapeHtml: function(str) {
|
||||
var HTML_CHARS = {
|
||||
const HTML_CHARS = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
@@ -997,7 +876,7 @@ const Utils = {
|
||||
* @returns {Object}
|
||||
*/
|
||||
extend: function(a, b){
|
||||
for (var key in b)
|
||||
for (const key in b)
|
||||
if (b.hasOwnProperty(key))
|
||||
a[key] = b[key];
|
||||
return a;
|
||||
@@ -1016,8 +895,8 @@ const Utils = {
|
||||
* @returns {html}
|
||||
*/
|
||||
displayFilesAsHTML: function(files){
|
||||
var formatDirectory = function(file) {
|
||||
var html = "<div class='panel panel-default'>" +
|
||||
const formatDirectory = function(file) {
|
||||
const html = "<div class='panel panel-default'>" +
|
||||
"<div class='panel-heading' role='tab'>" +
|
||||
"<h4 class='panel-title'>" +
|
||||
file.fileName +
|
||||
@@ -1029,25 +908,25 @@ const Utils = {
|
||||
return html;
|
||||
};
|
||||
|
||||
var formatFile = function(file, i) {
|
||||
var blob = new Blob(
|
||||
const formatFile = function(file, i) {
|
||||
const blob = new Blob(
|
||||
[new Uint8Array(file.bytes)],
|
||||
{type: "octet/stream"}
|
||||
);
|
||||
var blobUrl = URL.createObjectURL(blob);
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
|
||||
var downloadAnchorElem = "<a href='" + blobUrl + "' " +
|
||||
const downloadAnchorElem = "<a href='" + blobUrl + "' " +
|
||||
"title='Download " + Utils.escapeHtml(file.fileName) + "' " +
|
||||
"download='" + Utils.escapeHtml(file.fileName) + "'>\u21B4</a>";
|
||||
|
||||
var expandFileContentsElem = "<a href='#collapse" + i + "' " +
|
||||
const expandFileContentsElem = "<a href='#collapse" + i + "' " +
|
||||
"class='collapsed' " +
|
||||
"data-toggle='collapse' " +
|
||||
"aria-expanded='true' " +
|
||||
"aria-controls='collapse" + i + "' " +
|
||||
"title=\"Show/hide contents of '" + Utils.escapeHtml(file.fileName) + "'\">🔍</a>";
|
||||
|
||||
var html = "<div class='panel panel-default'>" +
|
||||
const html = "<div class='panel panel-default'>" +
|
||||
"<div class='panel-heading' role='tab' id='heading" + i + "'>" +
|
||||
"<h4 class='panel-title'>" +
|
||||
"<div>" +
|
||||
@@ -1072,7 +951,7 @@ const Utils = {
|
||||
return html;
|
||||
};
|
||||
|
||||
var html = "<div style='padding: 5px;'>" +
|
||||
let html = "<div style='padding: 5px;'>" +
|
||||
files.length +
|
||||
" file(s) found</div>\n";
|
||||
files.forEach(function(file, i) {
|
||||
@@ -1125,7 +1004,7 @@ const Utils = {
|
||||
*/
|
||||
modInv: function(x, y) {
|
||||
x %= y;
|
||||
for (var i = 1; i < y; i++) {
|
||||
for (let i = 1; i < y; i++) {
|
||||
if ((x * i) % 26 === 1) {
|
||||
return i;
|
||||
}
|
||||
@@ -1203,8 +1082,8 @@ export default Utils;
|
||||
* ["One", "Two", "Three", "One"].unique();
|
||||
*/
|
||||
Array.prototype.unique = function() {
|
||||
var u = {}, a = [];
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
let u = {}, a = [];
|
||||
for (let i = 0, l = this.length; i < l; i++) {
|
||||
if (u.hasOwnProperty(this[i])) {
|
||||
continue;
|
||||
}
|
||||
@@ -1274,7 +1153,7 @@ Array.prototype.sum = function() {
|
||||
*/
|
||||
Array.prototype.equals = function(other) {
|
||||
if (!other) return false;
|
||||
var i = this.length;
|
||||
let i = this.length;
|
||||
if (i !== other.length) return false;
|
||||
while (i--) {
|
||||
if (this[i] !== other[i]) return false;
|
||||
@@ -1314,11 +1193,11 @@ CryptoJS.enc.Hex.parse = function (hexStr) {
|
||||
hexStr = hexStr.replace(/\s/g, "");
|
||||
|
||||
// Shortcut
|
||||
var hexStrLength = hexStr.length;
|
||||
const hexStrLength = hexStr.length;
|
||||
|
||||
// Convert
|
||||
var words = [];
|
||||
for (var i = 0; i < hexStrLength; i += 2) {
|
||||
const words = [];
|
||||
for (let i = 0; i < hexStrLength; i += 2) {
|
||||
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,8 @@ const Categories = [
|
||||
"Hex to PEM",
|
||||
"Parse ASN.1 hex string",
|
||||
"Change IP format",
|
||||
"Text encoding",
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Swap endianness",
|
||||
]
|
||||
},
|
||||
@@ -125,6 +126,7 @@ const Categories = [
|
||||
{
|
||||
name: "Networking",
|
||||
ops: [
|
||||
"HTTP request",
|
||||
"Strip HTTP headers",
|
||||
"Parse User Agent",
|
||||
"Parse IP range",
|
||||
@@ -143,7 +145,8 @@ const Categories = [
|
||||
{
|
||||
name: "Language",
|
||||
ops: [
|
||||
"Text encoding",
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Unescape Unicode Characters",
|
||||
]
|
||||
},
|
||||
@@ -207,6 +210,7 @@ const Categories = [
|
||||
"Regular expression",
|
||||
"XPath expression",
|
||||
"CSS selector",
|
||||
"Extract EXIF",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -271,6 +275,9 @@ const Categories = [
|
||||
"CSS selector",
|
||||
"Strip HTML tags",
|
||||
"Diff",
|
||||
"To Snake case",
|
||||
"To Camel case",
|
||||
"To Kebab case",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -281,6 +288,9 @@ const Categories = [
|
||||
"Detect File Type",
|
||||
"Scan for Embedded Files",
|
||||
"Generate UUID",
|
||||
"Render Image",
|
||||
"Remove EXIF",
|
||||
"Extract EXIF",
|
||||
"Numberwang",
|
||||
]
|
||||
},
|
||||
@@ -292,6 +302,7 @@ const Categories = [
|
||||
"Jump",
|
||||
"Conditional Jump",
|
||||
"Return",
|
||||
"Comment"
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
@@ -15,6 +15,7 @@ import Endian from "../operations/Endian.js";
|
||||
import Entropy from "../operations/Entropy.js";
|
||||
import Extract from "../operations/Extract.js";
|
||||
import FileType from "../operations/FileType.js";
|
||||
import Image from "../operations/Image.js";
|
||||
import Hash from "../operations/Hash.js";
|
||||
import Hexdump from "../operations/Hexdump.js";
|
||||
import HTML from "../operations/HTML.js";
|
||||
@@ -162,6 +163,20 @@ const OperationConfig = {
|
||||
flowControl: true,
|
||||
args: []
|
||||
},
|
||||
"Comment": {
|
||||
description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.",
|
||||
run: FlowControl.runComment,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
flowControl: true,
|
||||
args: [
|
||||
{
|
||||
name: "",
|
||||
type: "text",
|
||||
value: ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"From Base64": {
|
||||
description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>",
|
||||
run: Base64.runFrom,
|
||||
@@ -872,21 +887,43 @@ const OperationConfig = {
|
||||
}
|
||||
]
|
||||
},
|
||||
"Text encoding": {
|
||||
description: "Translates the data between different character encodings.<br><br>Supported charsets are:<ul><li>UTF8</li><li>UTF16</li><li>UTF16LE (little-endian)</li><li>UTF16BE (big-endian)</li><li>Hex</li><li>Base64</li><li>Latin1 (ISO-8859-1)</li><li>Windows-1251</li></ul>",
|
||||
run: CharEnc.run,
|
||||
"Encode text": {
|
||||
description: [
|
||||
"Encodes text into the chosen character encoding.",
|
||||
"<br><br>",
|
||||
"Supported charsets are:",
|
||||
"<ul>",
|
||||
Object.keys(CharEnc.IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
|
||||
"</ul>",
|
||||
].join("\n"),
|
||||
run: CharEnc.runEncode,
|
||||
inputType: "string",
|
||||
outputType: "byteArray",
|
||||
args: [
|
||||
{
|
||||
name: "Encoding",
|
||||
type: "option",
|
||||
value: Object.keys(CharEnc.IO_FORMAT),
|
||||
},
|
||||
]
|
||||
},
|
||||
"Decode text": {
|
||||
description: [
|
||||
"Decodes text from the chosen character encoding.",
|
||||
"<br><br>",
|
||||
"Supported charsets are:",
|
||||
"<ul>",
|
||||
Object.keys(CharEnc.IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
|
||||
"</ul>",
|
||||
].join("\n"),
|
||||
run: CharEnc.runDecode,
|
||||
inputType: "byteArray",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Input type",
|
||||
name: "Encoding",
|
||||
type: "option",
|
||||
value: CharEnc.IO_FORMAT
|
||||
},
|
||||
{
|
||||
name: "Output type",
|
||||
type: "option",
|
||||
value: CharEnc.IO_FORMAT
|
||||
value: Object.keys(CharEnc.IO_FORMAT),
|
||||
},
|
||||
]
|
||||
},
|
||||
@@ -907,7 +944,6 @@ const OperationConfig = {
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: Cipher.IO_FORMAT1
|
||||
|
||||
},
|
||||
{
|
||||
name: "Salt",
|
||||
@@ -954,7 +990,6 @@ const OperationConfig = {
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: Cipher.IO_FORMAT1
|
||||
|
||||
},
|
||||
{
|
||||
name: "Salt",
|
||||
@@ -1387,6 +1422,11 @@ const OperationConfig = {
|
||||
type: "number",
|
||||
value: Cipher.KDF_ITERATIONS
|
||||
},
|
||||
{
|
||||
name: "Hashing function",
|
||||
type: "option",
|
||||
value: Cipher.HASHERS
|
||||
},
|
||||
{
|
||||
name: "Salt (hex)",
|
||||
type: "string",
|
||||
@@ -1420,6 +1460,11 @@ const OperationConfig = {
|
||||
type: "number",
|
||||
value: Cipher.KDF_ITERATIONS
|
||||
},
|
||||
{
|
||||
name: "Hashing function",
|
||||
type: "option",
|
||||
value: Cipher.HASHERS
|
||||
},
|
||||
{
|
||||
name: "Salt (hex)",
|
||||
type: "string",
|
||||
@@ -2199,7 +2244,7 @@ const OperationConfig = {
|
||||
]
|
||||
},
|
||||
"To UNIX Timestamp": {
|
||||
description: "Parses a datetime string and returns the corresponding UNIX timestamp.<br><br>e.g. <code>Mon 1 January 2001 11:00:00 UTC</code> becomes <code>978346800</code>",
|
||||
description: "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.<br><br>e.g. <code>Mon 1 January 2001 11:00:00</code> becomes <code>978346800</code>",
|
||||
run: DateTime.runToUnixTimestamp,
|
||||
inputType: "string",
|
||||
outputType: "number",
|
||||
@@ -2208,6 +2253,11 @@ const OperationConfig = {
|
||||
name: "Units",
|
||||
type: "option",
|
||||
value: DateTime.UNITS
|
||||
},
|
||||
{
|
||||
name: "Treat as UTC",
|
||||
type: "boolean",
|
||||
value: DateTime.TREAT_AS_UTC
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -3249,6 +3299,148 @@ const OperationConfig = {
|
||||
},
|
||||
]
|
||||
},
|
||||
"To Snake case": {
|
||||
description: [
|
||||
"Converts the input string to snake case.",
|
||||
"<br><br>",
|
||||
"Snake case is all lower case with underscores as word boundaries.",
|
||||
"<br><br>",
|
||||
"e.g. this_is_snake_case",
|
||||
"<br><br>",
|
||||
"'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.",
|
||||
].join("\n"),
|
||||
run: Code.runToSnakeCase,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Attempt to be context aware",
|
||||
type: "boolean",
|
||||
value: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
"To Camel case": {
|
||||
description: [
|
||||
"Converts the input string to camel case.",
|
||||
"<br><br>",
|
||||
"Camel case is all lower case except letters after word boundaries which are uppercase.",
|
||||
"<br><br>",
|
||||
"e.g. thisIsCamelCase",
|
||||
"<br><br>",
|
||||
"'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.",
|
||||
].join("\n"),
|
||||
run: Code.runToCamelCase,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Attempt to be context aware",
|
||||
type: "boolean",
|
||||
value: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
"To Kebab case": {
|
||||
description: [
|
||||
"Converts the input string to kebab case.",
|
||||
"<br><br>",
|
||||
"Kebab case is all lower case with dashes as word boundaries.",
|
||||
"<br><br>",
|
||||
"e.g. this-is-kebab-case",
|
||||
"<br><br>",
|
||||
"'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.",
|
||||
].join("\n"),
|
||||
run: Code.runToKebabCase,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Attempt to be context aware",
|
||||
type: "boolean",
|
||||
value: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
"Extract EXIF": {
|
||||
description: [
|
||||
"Extracts EXIF data from an image.",
|
||||
"<br><br>",
|
||||
"EXIF data is metadata embedded in images (JPEG, JPG, TIFF) and audio files.",
|
||||
"<br><br>",
|
||||
"EXIF data from photos usually contains information about the image file itself as well as the device used to create it.",
|
||||
].join("\n"),
|
||||
run: Image.runExtractEXIF,
|
||||
inputType: "byteArray",
|
||||
outputType: "string",
|
||||
args: [],
|
||||
},
|
||||
"Render Image": {
|
||||
description: "Displays the input as an image. Supports the following formats:<br><br><ul><li>jpg/jpeg</li><li>png</li><li>gif</li><li>webp</li><li>bmp</li><li>ico</li></ul>",
|
||||
run: Image.runRenderImage,
|
||||
inputType: "string",
|
||||
outputType: "html",
|
||||
args: [
|
||||
{
|
||||
name: "Input format",
|
||||
type: "option",
|
||||
value: Image.INPUT_FORMAT
|
||||
}
|
||||
]
|
||||
},
|
||||
"Remove EXIF": {
|
||||
description: [
|
||||
"Removes EXIF data from a JPEG image.",
|
||||
"<br><br>",
|
||||
"EXIF data embedded in photos usually contains information about the image file itself as well as the device used to create it.",
|
||||
].join("\n"),
|
||||
run: Image.runRemoveEXIF,
|
||||
inputType: "byteArray",
|
||||
outputType: "byteArray",
|
||||
args: []
|
||||
},
|
||||
"HTTP request": {
|
||||
description: [
|
||||
"Makes an HTTP request and returns the response.",
|
||||
"<br><br>",
|
||||
"This operation supports different HTTP verbs like GET, POST, PUT, etc.",
|
||||
"<br><br>",
|
||||
"You can add headers line by line in the format <code>Key: Value</code>",
|
||||
"<br><br>",
|
||||
"The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.",
|
||||
].join("\n"),
|
||||
run: HTTP.runHTTPRequest,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
manualBake: true,
|
||||
args: [
|
||||
{
|
||||
name: "Method",
|
||||
type: "option",
|
||||
value: HTTP.METHODS,
|
||||
},
|
||||
{
|
||||
name: "URL",
|
||||
type: "string",
|
||||
value: "",
|
||||
},
|
||||
{
|
||||
name: "Headers",
|
||||
type: "text",
|
||||
value: "",
|
||||
},
|
||||
{
|
||||
name: "Mode",
|
||||
type: "option",
|
||||
value: HTTP.MODE,
|
||||
},
|
||||
{
|
||||
name: "Show response metadata",
|
||||
type: "boolean",
|
||||
value: false,
|
||||
}
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
export default OperationConfig;
|
||||
|
||||
1982
src/core/lib/js-codepage/cptable.js
Normal file
1982
src/core/lib/js-codepage/cptable.js
Normal file
File diff suppressed because it is too large
Load Diff
515
src/core/lib/js-codepage/cputils.js
Normal file
515
src/core/lib/js-codepage/cputils.js
Normal file
@@ -0,0 +1,515 @@
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
"use strict";
|
||||
if(typeof cptable === "undefined") {
|
||||
if(typeof require !== "undefined"){
|
||||
var cpt = require('./cptable');
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = factory(cpt);
|
||||
else root.cptable = factory(cpt);
|
||||
} else throw new Error("cptable not found");
|
||||
} else cptable = factory(cptable);
|
||||
}(this, function(cpt){
|
||||
"use strict";
|
||||
var magic = {
|
||||
"1200":"utf16le",
|
||||
"1201":"utf16be",
|
||||
"12000":"utf32le",
|
||||
"12001":"utf32be",
|
||||
"16969":"utf64le",
|
||||
"20127":"ascii",
|
||||
"65000":"utf7",
|
||||
"65001":"utf8"
|
||||
};
|
||||
|
||||
var sbcs_cache = [874,1250,1251,1252,1253,1254,1255,1256,10000];
|
||||
var dbcs_cache = [932,936,949,950];
|
||||
var magic_cache = [65001];
|
||||
var magic_decode = {};
|
||||
var magic_encode = {};
|
||||
var cpdcache = {};
|
||||
var cpecache = {};
|
||||
|
||||
var sfcc = function sfcc(x) { return String.fromCharCode(x); };
|
||||
var cca = function cca(x) { return x.charCodeAt(0); };
|
||||
|
||||
var has_buf = (typeof Buffer !== 'undefined');
|
||||
if(has_buf) {
|
||||
var mdl = 1024, mdb = new Buffer(mdl);
|
||||
var make_EE = function make_EE(E){
|
||||
var EE = new Buffer(65536);
|
||||
for(var i = 0; i < 65536;++i) EE[i] = 0;
|
||||
var keys = Object.keys(E), len = keys.length;
|
||||
for(var ee = 0, e = keys[ee]; ee < len; ++ee) {
|
||||
if(!(e = keys[ee])) continue;
|
||||
EE[e.charCodeAt(0)] = E[e];
|
||||
}
|
||||
return EE;
|
||||
};
|
||||
var sbcs_encode = function make_sbcs_encode(cp) {
|
||||
var EE = make_EE(cpt[cp].enc);
|
||||
return function sbcs_e(data, ofmt) {
|
||||
var len = data.length;
|
||||
var out, i=0, j=0, D=0, w=0;
|
||||
if(typeof data === 'string') {
|
||||
out = new Buffer(len);
|
||||
for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)];
|
||||
} else if(Buffer.isBuffer(data)) {
|
||||
out = new Buffer(2*len);
|
||||
j = 0;
|
||||
for(i = 0; i < len; ++i) {
|
||||
D = data[i];
|
||||
if(D < 128) out[j++] = EE[D];
|
||||
else if(D < 224) { out[j++] = EE[((D&31)<<6)+(data[i+1]&63)]; ++i; }
|
||||
else if(D < 240) { out[j++] = EE[((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63)]; i+=2; }
|
||||
else {
|
||||
w = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3;
|
||||
if(w < 65536) out[j++] = EE[w];
|
||||
else { w -= 65536; out[j++] = EE[0xD800 + ((w>>10)&1023)]; out[j++] = EE[0xDC00 + (w&1023)]; }
|
||||
}
|
||||
}
|
||||
out = out.slice(0,j);
|
||||
} else {
|
||||
out = new Buffer(len);
|
||||
for(i = 0; i < len; ++i) out[i] = EE[data[i].charCodeAt(0)];
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return out;
|
||||
if(ofmt !== 'arr') return out.toString('binary');
|
||||
return [].slice.call(out);
|
||||
};
|
||||
};
|
||||
var sbcs_decode = function make_sbcs_decode(cp) {
|
||||
var D = cpt[cp].dec;
|
||||
var DD = new Buffer(131072), d=0, c="";
|
||||
for(d=0;d<D.length;++d) {
|
||||
if(!(c=D[d])) continue;
|
||||
var w = c.charCodeAt(0);
|
||||
DD[2*d] = w&255; DD[2*d+1] = w>>8;
|
||||
}
|
||||
return function sbcs_d(data) {
|
||||
var len = data.length, i=0, j=0;
|
||||
if(2 * len > mdl) { mdl = 2 * len; mdb = new Buffer(mdl); }
|
||||
if(Buffer.isBuffer(data)) {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
||||
}
|
||||
} else if(typeof data === "string") {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data.charCodeAt(i);
|
||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
||||
}
|
||||
}
|
||||
return mdb.slice(0, 2 * len).toString('ucs2');
|
||||
};
|
||||
};
|
||||
var dbcs_encode = function make_dbcs_encode(cp) {
|
||||
var E = cpt[cp].enc;
|
||||
var EE = new Buffer(131072);
|
||||
for(var i = 0; i < 131072; ++i) EE[i] = 0;
|
||||
var keys = Object.keys(E);
|
||||
for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) {
|
||||
if(!(e = keys[ee])) continue;
|
||||
var f = e.charCodeAt(0);
|
||||
EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8;
|
||||
}
|
||||
return function dbcs_e(data, ofmt) {
|
||||
var len = data.length, out = new Buffer(2*len), i=0, j=0, jj=0, k=0, D=0;
|
||||
if(typeof data === 'string') {
|
||||
for(i = k = 0; i < len; ++i) {
|
||||
j = data.charCodeAt(i)*2;
|
||||
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
}
|
||||
out = out.slice(0,k);
|
||||
} else if(Buffer.isBuffer(data)) {
|
||||
for(i = k = 0; i < len; ++i) {
|
||||
D = data[i];
|
||||
if(D < 128) j = D;
|
||||
else if(D < 224) { j = ((D&31)<<6)+(data[i+1]&63); ++i; }
|
||||
else if(D < 240) { j = ((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63); i+=2; }
|
||||
else { j = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3; }
|
||||
if(j<65536) { j*=2; out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j]; }
|
||||
else { jj = j-65536;
|
||||
j=2*(0xD800 + ((jj>>10)&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
j=2*(0xDC00 + (jj&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
}
|
||||
}
|
||||
out = out.slice(0,k);
|
||||
} else {
|
||||
for(i = k = 0; i < len; i++) {
|
||||
j = data[i].charCodeAt(0)*2;
|
||||
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return out;
|
||||
if(ofmt !== 'arr') return out.toString('binary');
|
||||
return [].slice.call(out);
|
||||
};
|
||||
};
|
||||
var dbcs_decode = function make_dbcs_decode(cp) {
|
||||
var D = cpt[cp].dec;
|
||||
var DD = new Buffer(131072), d=0, c, w=0, j=0, i=0;
|
||||
for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;}
|
||||
for(d = 0; d < D.length; ++d) {
|
||||
if(!(c=D[d])) continue;
|
||||
w = c.charCodeAt(0);
|
||||
j = 2*d;
|
||||
DD[j] = w&255; DD[j+1] = w>>8;
|
||||
}
|
||||
return function dbcs_d(data) {
|
||||
var len = data.length, out = new Buffer(2*len), i=0, j=0, k=0;
|
||||
if(Buffer.isBuffer(data)) {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
|
||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
||||
}
|
||||
} else if(typeof data === "string") {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data.charCodeAt(i);
|
||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data.charCodeAt(i)<<8)+data.charCodeAt(i+1)); ++i; }
|
||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
|
||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
||||
}
|
||||
}
|
||||
return out.slice(0,k).toString('ucs2');
|
||||
};
|
||||
};
|
||||
magic_decode[65001] = function utf8_d(data) {
|
||||
if(typeof data === "string") return utf8_d(data.split("").map(cca));
|
||||
var len = data.length, w = 0, ww = 0;
|
||||
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
|
||||
var i = 0;
|
||||
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
|
||||
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
|
||||
j = 1; D = data[i];
|
||||
if(D < 128) w = D;
|
||||
else if(D < 224) { w=(D&31)*64+(data[i+1]&63); j=2; }
|
||||
else if(D < 240) { w=((D&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
|
||||
else { w=(D&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
|
||||
if(w < 65536) { mdb[k++] = w&255; mdb[k++] = w>>8; }
|
||||
else {
|
||||
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
|
||||
mdb[k++] = ww&255; mdb[k++] = ww>>>8; mdb[k++] = w&255; mdb[k++] = (w>>>8)&255;
|
||||
}
|
||||
}
|
||||
return mdb.slice(0,k).toString('ucs2');
|
||||
};
|
||||
magic_encode[65001] = function utf8_e(data, ofmt) {
|
||||
if(has_buf && Buffer.isBuffer(data)) {
|
||||
if(!ofmt || ofmt === 'buf') return data;
|
||||
if(ofmt !== 'arr') return data.toString('binary');
|
||||
return [].slice.call(data);
|
||||
}
|
||||
var len = data.length, w = 0, ww = 0, j = 0;
|
||||
var direct = typeof data === "string";
|
||||
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
|
||||
for(var i = 0; i < len; ++i) {
|
||||
w = direct ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w <= 0x007F) mdb[j++] = w;
|
||||
else if(w <= 0x07FF) {
|
||||
mdb[j++] = 192 + (w >> 6);
|
||||
mdb[j++] = 128 + (w&63);
|
||||
} else if(w >= 0xD800 && w <= 0xDFFF) {
|
||||
w -= 0xD800; ++i;
|
||||
ww = (direct ? data.charCodeAt(i) : data[i].charCodeAt(0)) - 0xDC00 + (w << 10);
|
||||
mdb[j++] = 240 + ((ww>>>18) & 0x07);
|
||||
mdb[j++] = 144 + ((ww>>>12) & 0x3F);
|
||||
mdb[j++] = 128 + ((ww>>>6) & 0x3F);
|
||||
mdb[j++] = 128 + (ww & 0x3F);
|
||||
} else {
|
||||
mdb[j++] = 224 + (w >> 12);
|
||||
mdb[j++] = 128 + ((w >> 6)&63);
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
}
|
||||
|
||||
var encache = function encache() {
|
||||
if(has_buf) {
|
||||
if(cpdcache[sbcs_cache[0]]) return;
|
||||
var i=0, s=0;
|
||||
for(i = 0; i < sbcs_cache.length; ++i) {
|
||||
s = sbcs_cache[i];
|
||||
if(cpt[s]) {
|
||||
cpdcache[s] = sbcs_decode(s);
|
||||
cpecache[s] = sbcs_encode(s);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < dbcs_cache.length; ++i) {
|
||||
s = dbcs_cache[i];
|
||||
if(cpt[s]) {
|
||||
cpdcache[s] = dbcs_decode(s);
|
||||
cpecache[s] = dbcs_encode(s);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < magic_cache.length; ++i) {
|
||||
s = magic_cache[i];
|
||||
if(magic_decode[s]) cpdcache[s] = magic_decode[s];
|
||||
if(magic_encode[s]) cpecache[s] = magic_encode[s];
|
||||
}
|
||||
}
|
||||
};
|
||||
var null_enc = function(data, ofmt) { return ""; };
|
||||
var cp_decache = function cp_decache(cp) { delete cpdcache[cp]; delete cpecache[cp]; };
|
||||
var decache = function decache() {
|
||||
if(has_buf) {
|
||||
if(!cpdcache[sbcs_cache[0]]) return;
|
||||
sbcs_cache.forEach(cp_decache);
|
||||
dbcs_cache.forEach(cp_decache);
|
||||
magic_cache.forEach(cp_decache);
|
||||
}
|
||||
last_enc = null_enc; last_cp = 0;
|
||||
};
|
||||
var cache = {
|
||||
encache: encache,
|
||||
decache: decache,
|
||||
sbcs: sbcs_cache,
|
||||
dbcs: dbcs_cache
|
||||
};
|
||||
|
||||
encache();
|
||||
|
||||
var BM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var SetD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
|
||||
var last_enc = null_enc, last_cp = 0;
|
||||
var encode = function encode(cp, data, ofmt) {
|
||||
if(cp === last_cp && last_enc) { return last_enc(data, ofmt); }
|
||||
if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); }
|
||||
if(has_buf && Buffer.isBuffer(data)) data = data.toString('utf8');
|
||||
var len = data.length;
|
||||
var out = has_buf ? new Buffer(4*len) : [], w=0, i=0, j = 0, ww=0;
|
||||
var C = cpt[cp], E, M = "";
|
||||
var isstr = typeof data === 'string';
|
||||
if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) {
|
||||
w = E[isstr? data.charAt(i) : data[i]];
|
||||
if(w > 255) {
|
||||
out[j] = w>>8;
|
||||
out[++j] = w&255;
|
||||
} else out[j] = w&255;
|
||||
}
|
||||
else if((M=magic[cp])) switch(M) {
|
||||
case "utf8":
|
||||
if(has_buf && isstr) { out = new Buffer(data, M); j = out.length; break; }
|
||||
for(i = 0; i < len; ++i, ++j) {
|
||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w <= 0x007F) out[j] = w;
|
||||
else if(w <= 0x07FF) {
|
||||
out[j] = 192 + (w >> 6);
|
||||
out[++j] = 128 + (w&63);
|
||||
} else if(w >= 0xD800 && w <= 0xDFFF) {
|
||||
w -= 0xD800;
|
||||
ww = (isstr ? data.charCodeAt(++i) : data[++i].charCodeAt(0)) - 0xDC00 + (w << 10);
|
||||
out[j] = 240 + ((ww>>>18) & 0x07);
|
||||
out[++j] = 144 + ((ww>>>12) & 0x3F);
|
||||
out[++j] = 128 + ((ww>>>6) & 0x3F);
|
||||
out[++j] = 128 + (ww & 0x3F);
|
||||
} else {
|
||||
out[j] = 224 + (w >> 12);
|
||||
out[++j] = 128 + ((w >> 6)&63);
|
||||
out[++j] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "ascii":
|
||||
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
|
||||
for(i = 0; i < len; ++i, ++j) {
|
||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w <= 0x007F) out[j] = w;
|
||||
else throw new Error("bad ascii " + w);
|
||||
}
|
||||
break;
|
||||
case "utf16le":
|
||||
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
out[j++] = w&255;
|
||||
out[j++] = w>>8;
|
||||
}
|
||||
break;
|
||||
case "utf16be":
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
out[j++] = w>>8;
|
||||
out[j++] = w&255;
|
||||
}
|
||||
break;
|
||||
case "utf32le":
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
|
||||
out[j++] = w&255; w >>= 8;
|
||||
out[j++] = w&255; w >>= 8;
|
||||
out[j++] = w&255; w >>= 8;
|
||||
out[j++] = w&255;
|
||||
}
|
||||
break;
|
||||
case "utf32be":
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
|
||||
out[j+3] = w&255; w >>= 8;
|
||||
out[j+2] = w&255; w >>= 8;
|
||||
out[j+1] = w&255; w >>= 8;
|
||||
out[j] = w&255;
|
||||
j+=4;
|
||||
}
|
||||
break;
|
||||
case "utf7":
|
||||
for(i = 0; i < len; i++) {
|
||||
var c = isstr ? data.charAt(i) : data[i].charAt(0);
|
||||
if(c === "+") { out[j++] = 0x2b; out[j++] = 0x2d; continue; }
|
||||
if(SetD.indexOf(c) > -1) { out[j++] = c.charCodeAt(0); continue; }
|
||||
var tt = encode(1201, c);
|
||||
out[j++] = 0x2b;
|
||||
out[j++] = BM.charCodeAt(tt[0]>>2);
|
||||
out[j++] = BM.charCodeAt(((tt[0]&0x03)<<4) + ((tt[1]||0)>>4));
|
||||
out[j++] = BM.charCodeAt(((tt[1]&0x0F)<<2) + ((tt[2]||0)>>6));
|
||||
out[j++] = 0x2d;
|
||||
}
|
||||
break;
|
||||
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
|
||||
}
|
||||
else throw new Error("Unrecognized CP: " + cp);
|
||||
out = out.slice(0,j);
|
||||
if(!has_buf) return (ofmt == 'str') ? (out).map(sfcc).join("") : out;
|
||||
if(!ofmt || ofmt === 'buf') return out;
|
||||
if(ofmt !== 'arr') return out.toString('binary');
|
||||
return [].slice.call(out);
|
||||
};
|
||||
var decode = function decode(cp, data) {
|
||||
var F; if((F=cpdcache[cp])) return F(data);
|
||||
if(typeof data === "string") return decode(cp, data.split("").map(cca));
|
||||
var len = data.length, out = new Array(len), s="", w=0, i=0, j=1, k=0, ww=0;
|
||||
var C = cpt[cp], D, M="";
|
||||
if(C && (D=C.dec)) {
|
||||
for(i = 0; i < len; i+=j) {
|
||||
j = 2;
|
||||
s = D[(data[i]<<8)+ data[i+1]];
|
||||
if(!s) {
|
||||
j = 1;
|
||||
s = D[data[i]];
|
||||
}
|
||||
if(!s) throw new Error('Unrecognized code: ' + data[i] + ' ' + data[i+j-1] + ' ' + i + ' ' + j + ' ' + D[data[i]]);
|
||||
out[k++] = s;
|
||||
}
|
||||
}
|
||||
else if((M=magic[cp])) switch(M) {
|
||||
case "utf8":
|
||||
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
|
||||
for(; i < len; i+=j) {
|
||||
j = 1;
|
||||
if(data[i] < 128) w = data[i];
|
||||
else if(data[i] < 224) { w=(data[i]&31)*64+(data[i+1]&63); j=2; }
|
||||
else if(data[i] < 240) { w=((data[i]&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
|
||||
else { w=(data[i]&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
|
||||
if(w < 65536) { out[k++] = String.fromCharCode(w); }
|
||||
else {
|
||||
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
|
||||
out[k++] = String.fromCharCode(ww); out[k++] = String.fromCharCode(w);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "ascii":
|
||||
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
|
||||
for(i = 0; i < len; i++) out[i] = String.fromCharCode(data[i]);
|
||||
k = len; break;
|
||||
case "utf16le":
|
||||
if(len >= 2 && data[0] == 0xFF) if(data[1] == 0xFE) i = 2;
|
||||
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
|
||||
j = 2;
|
||||
for(; i+1 < len; i+=j) {
|
||||
out[k++] = String.fromCharCode((data[i+1]<<8) + data[i]);
|
||||
}
|
||||
break;
|
||||
case "utf16be":
|
||||
if(len >= 2 && data[0] == 0xFE) if(data[1] == 0xFF) i = 2;
|
||||
j = 2;
|
||||
for(; i+1 < len; i+=j) {
|
||||
out[k++] = String.fromCharCode((data[i]<<8) + data[i+1]);
|
||||
}
|
||||
break;
|
||||
case "utf32le":
|
||||
if(len >= 4 && data[0] == 0xFF) if(data[1] == 0xFE && data[2] === 0 && data[3] === 0) i = 4;
|
||||
j = 4;
|
||||
for(; i < len; i+=j) {
|
||||
w = (data[i+3]<<24) + (data[i+2]<<16) + (data[i+1]<<8) + (data[i]);
|
||||
if(w > 0xFFFF) {
|
||||
w -= 0x10000;
|
||||
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
|
||||
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
|
||||
}
|
||||
else out[k++] = String.fromCharCode(w);
|
||||
}
|
||||
break;
|
||||
case "utf32be":
|
||||
if(len >= 4 && data[3] == 0xFF) if(data[2] == 0xFE && data[1] === 0 && data[0] === 0) i = 4;
|
||||
j = 4;
|
||||
for(; i < len; i+=j) {
|
||||
w = (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + (data[i+3]);
|
||||
if(w > 0xFFFF) {
|
||||
w -= 0x10000;
|
||||
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
|
||||
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
|
||||
}
|
||||
else out[k++] = String.fromCharCode(w);
|
||||
}
|
||||
break;
|
||||
case "utf7":
|
||||
if(len >= 4 && data[0] == 0x2B && data[1] == 0x2F && data[2] == 0x76) {
|
||||
if(len >= 5 && data[3] == 0x38 && data[4] == 0x2D) i = 5;
|
||||
else if(data[3] == 0x38 || data[3] == 0x39 || data[3] == 0x2B || data[3] == 0x2F) i = 4;
|
||||
}
|
||||
for(; i < len; i+=j) {
|
||||
if(data[i] !== 0x2b) { j=1; out[k++] = String.fromCharCode(data[i]); continue; }
|
||||
j=1;
|
||||
if(data[i+1] === 0x2d) { j = 2; out[k++] = "+"; continue; }
|
||||
while(String.fromCharCode(data[i+j]).match(/[A-Za-z0-9+\/]/)) j++;
|
||||
var dash = 0;
|
||||
if(data[i+j] === 0x2d) { ++j; dash=1; }
|
||||
var tt = [];
|
||||
var o64 = "";
|
||||
var c1=0, c2=0, c3=0;
|
||||
var e1=0, e2=0, e3=0, e4=0;
|
||||
for(var l = 1; l < j - dash;) {
|
||||
e1 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
e2 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
c1 = e1 << 2 | e2 >> 4;
|
||||
tt.push(c1);
|
||||
e3 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
if(e3 === -1) break;
|
||||
c2 = (e2 & 15) << 4 | e3 >> 2;
|
||||
tt.push(c2);
|
||||
e4 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
if(e4 === -1) break;
|
||||
c3 = (e3 & 3) << 6 | e4;
|
||||
if(e4 < 64) tt.push(c3);
|
||||
}
|
||||
o64 = decode(1201, tt);
|
||||
for(l = 0; l < o64.length; ++l) out[k++] = o64.charAt(l);
|
||||
}
|
||||
break;
|
||||
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
|
||||
}
|
||||
else throw new Error("Unrecognized CP: " + cp);
|
||||
return out.slice(0,k).join("");
|
||||
};
|
||||
var hascp = function hascp(cp) { return !!(cpt[cp] || magic[cp]); };
|
||||
cpt.utils = { decode: decode, encode: encode, hascp: hascp, magic: magic, cache:cache };
|
||||
return cpt;
|
||||
}));
|
||||
153
src/core/lib/remove-exif.js
Normal file
153
src/core/lib/remove-exif.js
Normal file
@@ -0,0 +1,153 @@
|
||||
/* piexifjs
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2014, 2015 hMatoba(https://github.com/hMatoba)
|
||||
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.
|
||||
*/
|
||||
|
||||
import Utils from "../Utils.js";
|
||||
|
||||
// Param jpeg should be a binaryArray
|
||||
function removeEXIF(jpeg) {
|
||||
// Convert binaryArray to char string
|
||||
jpeg = Utils.byteArrayToChars(jpeg);
|
||||
if (jpeg.slice(0, 2) != "\xff\xd8") {
|
||||
throw ("Given data is not jpeg.");
|
||||
}
|
||||
|
||||
var segments = splitIntoSegments(jpeg);
|
||||
if (segments[1].slice(0, 2) == "\xff\xe1" &&
|
||||
segments[1].slice(4, 10) == "Exif\x00\x00") {
|
||||
segments = [segments[0]].concat(segments.slice(2));
|
||||
} else if (segments[2].slice(0, 2) == "\xff\xe1" &&
|
||||
segments[2].slice(4, 10) == "Exif\x00\x00") {
|
||||
segments = segments.slice(0, 2).concat(segments.slice(3));
|
||||
} else {
|
||||
throw ("Exif not found.");
|
||||
}
|
||||
|
||||
var new_data = segments.join("");
|
||||
|
||||
// Convert back to binaryArray
|
||||
new_data = Utils.strToCharcode(new_data);
|
||||
|
||||
return new_data;
|
||||
};
|
||||
|
||||
function splitIntoSegments(data) {
|
||||
if (data.slice(0, 2) != "\xff\xd8") {
|
||||
throw ("Given data isn't JPEG.");
|
||||
}
|
||||
|
||||
var head = 2;
|
||||
var segments = ["\xff\xd8"];
|
||||
while (true) {
|
||||
if (data.slice(head, head + 2) == "\xff\xda") {
|
||||
segments.push(data.slice(head));
|
||||
break;
|
||||
} else {
|
||||
var length = unpack(">H", data.slice(head + 2, head + 4))[0];
|
||||
var endPoint = head + length + 2;
|
||||
segments.push(data.slice(head, endPoint));
|
||||
head = endPoint;
|
||||
}
|
||||
|
||||
if (head >= data.length) {
|
||||
throw ("Wrong JPEG data.");
|
||||
}
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
function unpack(mark, str) {
|
||||
if (typeof(str) != "string") {
|
||||
throw ("'unpack' error. Got invalid type argument.");
|
||||
}
|
||||
var l = 0;
|
||||
for (var markPointer = 1; markPointer < mark.length; markPointer++) {
|
||||
if (mark[markPointer].toLowerCase() == "b") {
|
||||
l += 1;
|
||||
} else if (mark[markPointer].toLowerCase() == "h") {
|
||||
l += 2;
|
||||
} else if (mark[markPointer].toLowerCase() == "l") {
|
||||
l += 4;
|
||||
} else {
|
||||
throw ("'unpack' error. Got invalid mark.");
|
||||
}
|
||||
}
|
||||
|
||||
if (l != str.length) {
|
||||
throw ("'unpack' error. Mismatch between symbol and string length. " + l + ":" + str.length);
|
||||
}
|
||||
|
||||
var littleEndian;
|
||||
if (mark[0] == "<") {
|
||||
littleEndian = true;
|
||||
} else if (mark[0] == ">") {
|
||||
littleEndian = false;
|
||||
} else {
|
||||
throw ("'unpack' error.");
|
||||
}
|
||||
var unpacked = [];
|
||||
var strPointer = 0;
|
||||
var p = 1;
|
||||
var val = null;
|
||||
var c = null;
|
||||
var length = null;
|
||||
var sliced = "";
|
||||
|
||||
while (c = mark[p]) {
|
||||
if (c.toLowerCase() == "b") {
|
||||
length = 1;
|
||||
sliced = str.slice(strPointer, strPointer + length);
|
||||
val = sliced.charCodeAt(0);
|
||||
if ((c == "b") && (val >= 0x80)) {
|
||||
val -= 0x100;
|
||||
}
|
||||
} else if (c == "H") {
|
||||
length = 2;
|
||||
sliced = str.slice(strPointer, strPointer + length);
|
||||
if (littleEndian) {
|
||||
sliced = sliced.split("").reverse().join("");
|
||||
}
|
||||
val = sliced.charCodeAt(0) * 0x100 +
|
||||
sliced.charCodeAt(1);
|
||||
} else if (c.toLowerCase() == "l") {
|
||||
length = 4;
|
||||
sliced = str.slice(strPointer, strPointer + length);
|
||||
if (littleEndian) {
|
||||
sliced = sliced.split("").reverse().join("");
|
||||
}
|
||||
val = sliced.charCodeAt(0) * 0x1000000 +
|
||||
sliced.charCodeAt(1) * 0x10000 +
|
||||
sliced.charCodeAt(2) * 0x100 +
|
||||
sliced.charCodeAt(3);
|
||||
if ((c == "l") && (val >= 0x80000000)) {
|
||||
val -= 0x100000000;
|
||||
}
|
||||
} else {
|
||||
throw ("'unpack' error. " + c);
|
||||
}
|
||||
|
||||
unpacked.push(val);
|
||||
strPointer += length;
|
||||
p += 1;
|
||||
}
|
||||
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
export default removeEXIF;
|
||||
@@ -26,7 +26,7 @@ const Base = {
|
||||
if (!input) {
|
||||
throw ("Error: Input must be a number");
|
||||
}
|
||||
var radix = args[0] || Base.DEFAULT_RADIX;
|
||||
const radix = args[0] || Base.DEFAULT_RADIX;
|
||||
if (radix < 2 || radix > 36) {
|
||||
throw "Error: Radix argument must be between 2 and 36";
|
||||
}
|
||||
@@ -42,19 +42,19 @@ const Base = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runFrom: function(input, args) {
|
||||
var radix = args[0] || Base.DEFAULT_RADIX;
|
||||
const radix = args[0] || Base.DEFAULT_RADIX;
|
||||
if (radix < 2 || radix > 36) {
|
||||
throw "Error: Radix argument must be between 2 and 36";
|
||||
}
|
||||
|
||||
var number = input.replace(/\s/g, "").split("."),
|
||||
let number = input.replace(/\s/g, "").split("."),
|
||||
result = parseInt(number[0], radix) || 0;
|
||||
|
||||
if (number.length === 1) return result;
|
||||
|
||||
// Fractional part
|
||||
for (var i = 0; i < number[1].length; i++) {
|
||||
var digit = parseInt(number[1][i], radix);
|
||||
for (let i = 0; i < number[1].length; i++) {
|
||||
const digit = parseInt(number[1][i], radix);
|
||||
result += digit / Math.pow(radix, i+1);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ const Base58 = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo: function(input, args) {
|
||||
var alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value,
|
||||
let alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value,
|
||||
result = [0];
|
||||
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
@@ -53,11 +53,11 @@ const Base58 = {
|
||||
if (input.length === 0) return "";
|
||||
|
||||
input.forEach(function(b) {
|
||||
var carry = (result[0] << 8) + b;
|
||||
let carry = (result[0] << 8) + b;
|
||||
result[0] = carry % 58;
|
||||
carry = (carry / 58) | 0;
|
||||
|
||||
for (var i = 1; i < result.length; i++) {
|
||||
for (let i = 1; i < result.length; i++) {
|
||||
carry += result[i] << 8;
|
||||
result[i] = carry % 58;
|
||||
carry = (carry / 58) | 0;
|
||||
@@ -89,7 +89,7 @@ const Base58 = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFrom: function(input, args) {
|
||||
var alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value,
|
||||
let alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value,
|
||||
removeNonAlphaChars = args[1] === undefined ? true : args[1],
|
||||
result = [0];
|
||||
|
||||
@@ -103,7 +103,7 @@ const Base58 = {
|
||||
if (input.length === 0) return [];
|
||||
|
||||
[].forEach.call(input, function(c, charIndex) {
|
||||
var index = alphabet.indexOf(c);
|
||||
const index = alphabet.indexOf(c);
|
||||
|
||||
if (index === -1) {
|
||||
if (removeNonAlphaChars) {
|
||||
@@ -113,11 +113,11 @@ const Base58 = {
|
||||
}
|
||||
}
|
||||
|
||||
var carry = result[0] * 58 + index;
|
||||
let carry = result[0] * 58 + index;
|
||||
result[0] = carry & 0xFF;
|
||||
carry = carry >> 8;
|
||||
|
||||
for (var i = 1; i < result.length; i++) {
|
||||
for (let i = 1; i < result.length; i++) {
|
||||
carry += result[i] * 58;
|
||||
result[i] = carry & 0xFF;
|
||||
carry = carry >> 8;
|
||||
|
||||
@@ -45,7 +45,7 @@ const Base64 = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo: function(input, args) {
|
||||
var alphabet = args[0] || Base64.ALPHABET;
|
||||
const alphabet = args[0] || Base64.ALPHABET;
|
||||
return Utils.toBase64(input, alphabet);
|
||||
},
|
||||
|
||||
@@ -64,7 +64,7 @@ const Base64 = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFrom: function(input, args) {
|
||||
var alphabet = args[0] || Base64.ALPHABET,
|
||||
let alphabet = args[0] || Base64.ALPHABET,
|
||||
removeNonAlphChars = args[1];
|
||||
|
||||
return Utils.fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
|
||||
@@ -87,7 +87,7 @@ const Base64 = {
|
||||
runTo32: function(input, args) {
|
||||
if (!input) return "";
|
||||
|
||||
var alphabet = args[0] ?
|
||||
let alphabet = args[0] ?
|
||||
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
||||
output = "",
|
||||
chr1, chr2, chr3, chr4, chr5,
|
||||
@@ -139,17 +139,17 @@ const Base64 = {
|
||||
runFrom32: function(input, args) {
|
||||
if (!input) return [];
|
||||
|
||||
var alphabet = args[0] ?
|
||||
let alphabet = args[0] ?
|
||||
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
||||
removeNonAlphChars = args[0];
|
||||
|
||||
var output = [],
|
||||
let output = [],
|
||||
chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
var re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
|
||||
const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
|
||||
input = input.replace(re, "");
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ const Base64 = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runOffsets: function(input, args) {
|
||||
var alphabet = args[0] || Base64.ALPHABET,
|
||||
let alphabet = args[0] || Base64.ALPHABET,
|
||||
showVariable = args[1],
|
||||
offset0 = Utils.toBase64(input, alphabet),
|
||||
offset1 = Utils.toBase64([0].concat(input), alphabet),
|
||||
|
||||
@@ -26,12 +26,12 @@ const BitwiseOp = {
|
||||
*/
|
||||
_bitOp: function (input, key, func, nullPreserving, scheme) {
|
||||
if (!key || !key.length) key = [0];
|
||||
var result = [],
|
||||
let result = [],
|
||||
x = null,
|
||||
k = null,
|
||||
o = null;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
k = key[i % key.length];
|
||||
o = input[i];
|
||||
x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
|
||||
@@ -76,7 +76,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runXor: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
scheme = args[1],
|
||||
nullPreserving = args[2];
|
||||
|
||||
@@ -120,7 +120,7 @@ const BitwiseOp = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runXorBrute: function (input, args) {
|
||||
var keyLength = parseInt(args[0], 10),
|
||||
let keyLength = parseInt(args[0], 10),
|
||||
sampleLength = args[1],
|
||||
sampleOffset = args[2],
|
||||
nullPreserving = args[3],
|
||||
@@ -130,7 +130,7 @@ const BitwiseOp = {
|
||||
outputHex = args[7],
|
||||
regex;
|
||||
|
||||
var output = "",
|
||||
let output = "",
|
||||
result,
|
||||
resultUtf8;
|
||||
|
||||
@@ -141,7 +141,7 @@ const BitwiseOp = {
|
||||
}
|
||||
|
||||
|
||||
for (var key = 1, l = Math.pow(256, keyLength); key < l; key++) {
|
||||
for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
|
||||
result = BitwiseOp._bitOp(input, Utils.hexToByteArray(key.toString(16)), BitwiseOp._xor, nullPreserving, differential);
|
||||
resultUtf8 = Utils.byteArrayToUtf8(result);
|
||||
if (crib !== "" && resultUtf8.search(regex) === -1) continue;
|
||||
@@ -176,7 +176,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runAnd: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._and);
|
||||
@@ -191,7 +191,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runOr: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._or);
|
||||
@@ -206,7 +206,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runAdd: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._add);
|
||||
@@ -221,7 +221,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runSub: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._sub);
|
||||
@@ -301,7 +301,7 @@ const BitwiseOp = {
|
||||
* @returns {number}
|
||||
*/
|
||||
_sub: function (operand, key) {
|
||||
var result = operand - key;
|
||||
const result = operand - key;
|
||||
return (result < 0) ? 256 + result : result;
|
||||
},
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ const ByteRepr = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToHex: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
const delim = Utils.charRep[args[0] || "Space"];
|
||||
return Utils.toHex(input, delim, 2);
|
||||
},
|
||||
|
||||
@@ -50,7 +50,7 @@ const ByteRepr = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFromHex: function(input, args) {
|
||||
var delim = args[0] || "Space";
|
||||
const delim = args[0] || "Space";
|
||||
return Utils.fromHex(input, delim, 2);
|
||||
},
|
||||
|
||||
@@ -64,7 +64,7 @@ const ByteRepr = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToOct: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
const delim = Utils.charRep[args[0] || "Space"];
|
||||
return input.map(val => val.toString(8)).join(delim);
|
||||
},
|
||||
|
||||
@@ -78,7 +78,7 @@ const ByteRepr = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFromOct: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
const delim = Utils.charRep[args[0] || "Space"];
|
||||
if (input.length === 0) return [];
|
||||
return input.split(delim).map(val => parseInt(val, 8));
|
||||
},
|
||||
@@ -98,7 +98,7 @@ const ByteRepr = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToCharcode: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"],
|
||||
let delim = Utils.charRep[args[0] || "Space"],
|
||||
base = args[1],
|
||||
output = "",
|
||||
padding = 2,
|
||||
@@ -108,7 +108,7 @@ const ByteRepr = {
|
||||
throw "Error: Base argument must be between 2 and 36";
|
||||
}
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
ordinal = Utils.ord(input[i]);
|
||||
|
||||
if (base === 16) {
|
||||
@@ -139,7 +139,7 @@ const ByteRepr = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFromCharcode: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"],
|
||||
let delim = Utils.charRep[args[0] || "Space"],
|
||||
base = args[1],
|
||||
bites = input.split(delim),
|
||||
i = 0;
|
||||
@@ -161,7 +161,7 @@ const ByteRepr = {
|
||||
}
|
||||
}
|
||||
|
||||
var latin1 = "";
|
||||
let latin1 = "";
|
||||
for (i = 0; i < bites.length; i++) {
|
||||
latin1 += Utils.chr(parseInt(bites[i], base));
|
||||
}
|
||||
@@ -179,7 +179,7 @@ const ByteRepr = {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightTo: function(pos, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"],
|
||||
let delim = Utils.charRep[args[0] || "Space"],
|
||||
len = delim === "\r\n" ? 1 : delim.length;
|
||||
|
||||
pos[0].start = pos[0].start * (2 + len);
|
||||
@@ -204,7 +204,7 @@ const ByteRepr = {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightFrom: function(pos, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"],
|
||||
let delim = Utils.charRep[args[0] || "Space"],
|
||||
len = delim === "\r\n" ? 1 : delim.length,
|
||||
width = len + 2;
|
||||
|
||||
@@ -230,7 +230,7 @@ const ByteRepr = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToDecimal: function(input, args) {
|
||||
var delim = Utils.charRep[args[0]];
|
||||
const delim = Utils.charRep[args[0]];
|
||||
return input.join(delim);
|
||||
},
|
||||
|
||||
@@ -243,12 +243,12 @@ const ByteRepr = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFromDecimal: function(input, args) {
|
||||
var delim = Utils.charRep[args[0]];
|
||||
var byteStr = input.split(delim), output = [];
|
||||
const delim = Utils.charRep[args[0]];
|
||||
let byteStr = input.split(delim), output = [];
|
||||
if (byteStr[byteStr.length-1] === "")
|
||||
byteStr = byteStr.slice(0, byteStr.length-1);
|
||||
|
||||
for (var i = 0; i < byteStr.length; i++) {
|
||||
for (let i = 0; i < byteStr.length; i++) {
|
||||
output[i] = parseInt(byteStr[i], 10);
|
||||
}
|
||||
return output;
|
||||
@@ -263,11 +263,11 @@ const ByteRepr = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToBinary: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"],
|
||||
let delim = Utils.charRep[args[0] || "Space"],
|
||||
output = "",
|
||||
padding = 8;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
output += Utils.pad(input[i].toString(2), padding) + delim;
|
||||
}
|
||||
|
||||
@@ -288,13 +288,13 @@ const ByteRepr = {
|
||||
*/
|
||||
runFromBinary: function(input, args) {
|
||||
if (args[0] !== "None") {
|
||||
var delimRegex = Utils.regexRep[args[0] || "Space"];
|
||||
const delimRegex = Utils.regexRep[args[0] || "Space"];
|
||||
input = input.replace(delimRegex, "");
|
||||
}
|
||||
|
||||
var output = [];
|
||||
var byteLen = 8;
|
||||
for (var i = 0; i < input.length; i += byteLen) {
|
||||
const output = [];
|
||||
const byteLen = 8;
|
||||
for (let i = 0; i < input.length; i += byteLen) {
|
||||
output.push(parseInt(input.substr(i, byteLen), 2));
|
||||
}
|
||||
return output;
|
||||
@@ -311,7 +311,7 @@ const ByteRepr = {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightToBinary: function(pos, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
const delim = Utils.charRep[args[0] || "Space"];
|
||||
pos[0].start = pos[0].start * (8 + delim.length);
|
||||
pos[0].end = pos[0].end * (8 + delim.length) - delim.length;
|
||||
return pos;
|
||||
@@ -328,7 +328,7 @@ const ByteRepr = {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightFromBinary: function(pos, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
const delim = Utils.charRep[args[0] || "Space"];
|
||||
pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length));
|
||||
pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length));
|
||||
return pos;
|
||||
@@ -354,19 +354,19 @@ const ByteRepr = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToHexContent: function(input, args) {
|
||||
var convert = args[0];
|
||||
var spaces = args[1];
|
||||
const convert = args[0];
|
||||
const spaces = args[1];
|
||||
if (convert === "All chars") {
|
||||
var result = "|" + Utils.toHex(input) + "|";
|
||||
let result = "|" + Utils.toHex(input) + "|";
|
||||
if (!spaces) result = result.replace(/ /g, "");
|
||||
return result;
|
||||
}
|
||||
|
||||
var output = "",
|
||||
let output = "",
|
||||
inHex = false,
|
||||
convertSpaces = convert === "Only special chars including spaces",
|
||||
b;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
b = input[i];
|
||||
if ((b === 32 && convertSpaces) || (b < 48 && b !== 32) || (b > 57 && b < 65) || (b > 90 && b < 97) || b > 122) {
|
||||
if (!inHex) {
|
||||
@@ -395,17 +395,17 @@ const ByteRepr = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFromHexContent: function(input, args) {
|
||||
var regex = /\|([a-f\d ]{2,})\|/gi;
|
||||
var output = [], m, i = 0;
|
||||
const regex = /\|([a-f\d ]{2,})\|/gi;
|
||||
let output = [], m, i = 0;
|
||||
while ((m = regex.exec(input))) {
|
||||
// Add up to match
|
||||
for (; i < m.index;)
|
||||
output.push(Utils.ord(input[i++]));
|
||||
|
||||
// Add match
|
||||
var bytes = Utils.fromHex(m[1]);
|
||||
const bytes = Utils.fromHex(m[1]);
|
||||
if (bytes) {
|
||||
for (var a = 0; a < bytes.length;)
|
||||
for (let a = 0; a < bytes.length;)
|
||||
output.push(bytes[a++]);
|
||||
} else {
|
||||
// Not valid hex, print as normal
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import cptable from "../lib/js-codepage/cptable.js";
|
||||
import Utils from "../Utils.js";
|
||||
import CryptoJS from "crypto-js";
|
||||
|
||||
@@ -17,34 +18,82 @@ const CharEnc = {
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
IO_FORMAT: ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Windows-1251", "Hex", "Base64"],
|
||||
IO_FORMAT: {
|
||||
"UTF-8 (65001)": 65001,
|
||||
"UTF-7 (65000)": 65000,
|
||||
"UTF16LE (1200)": 1200,
|
||||
"UTF16BE (1201)": 1201,
|
||||
"UTF16 (1201)": 1201,
|
||||
"IBM EBCDIC International (500)": 500,
|
||||
"IBM EBCDIC US-Canada (37)": 37,
|
||||
"Windows-874 Thai (874)": 874,
|
||||
"Japanese Shift-JIS (932)": 932,
|
||||
"Simplified Chinese GBK (936)": 936,
|
||||
"Korean (949)": 949,
|
||||
"Traditional Chinese Big5 (950)": 950,
|
||||
"Windows-1250 Central European (1250)": 1250,
|
||||
"Windows-1251 Cyrillic (1251)": 1251,
|
||||
"Windows-1252 Latin (1252)": 1252,
|
||||
"Windows-1253 Greek (1253)": 1253,
|
||||
"Windows-1254 Turkish (1254)": 1254,
|
||||
"Windows-1255 Hebrew (1255)": 1255,
|
||||
"Windows-1256 Arabic (1256)": 1256,
|
||||
"Windows-1257 Baltic (1257)": 1257,
|
||||
"Windows-1258 Vietnam (1258)": 1258,
|
||||
"US-ASCII (20127)": 20127,
|
||||
"Simplified Chinese GB2312 (20936)": 20936,
|
||||
"KOI8-R Russian Cyrillic (20866)": 20866,
|
||||
"KOI8-U Ukrainian Cyrillic (21866)": 21866,
|
||||
"ISO-8859-1 Latin 1 Western European (28591)": 28591,
|
||||
"ISO-8859-2 Latin 2 Central European (28592)": 28592,
|
||||
"ISO-8859-3 Latin 3 South European (28593)": 28593,
|
||||
"ISO-8859-4 Latin 4 North European (28594)": 28594,
|
||||
"ISO-8859-5 Latin/Cyrillic (28595)": 28595,
|
||||
"ISO-8859-6 Latin/Arabic (28596)": 28596,
|
||||
"ISO-8859-7 Latin/Greek (28597)": 28597,
|
||||
"ISO-8859-8 Latin/Hebrew (28598)": 28598,
|
||||
"ISO-8859-9 Latin 5 Turkish (28599)": 28599,
|
||||
"ISO-8859-10 Latin 6 Nordic (28600)": 28600,
|
||||
"ISO-8859-11 Latin/Thai (28601)": 28601,
|
||||
"ISO-8859-13 Latin 7 Baltic Rim (28603)": 28603,
|
||||
"ISO-8859-14 Latin 8 Celtic (28604)": 28604,
|
||||
"ISO-8859-15 Latin 9 (28605)": 28605,
|
||||
"ISO-8859-16 Latin 10 (28606)": 28606,
|
||||
"ISO-2022 JIS Japanese (50222)": 50222,
|
||||
"EUC Japanese (51932)": 51932,
|
||||
"EUC Korean (51949)": 51949,
|
||||
"Simplified Chinese GB18030 (54936)": 54936,
|
||||
},
|
||||
|
||||
/**
|
||||
* Text encoding operation.
|
||||
* Encode text operation.
|
||||
* @author tlwr [toby@toby.codes]
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run: function(input, args) {
|
||||
var inputFormat = args[0],
|
||||
outputFormat = args[1];
|
||||
|
||||
if (inputFormat === "Windows-1251") {
|
||||
input = Utils.win1251ToUnicode(input);
|
||||
input = CryptoJS.enc.Utf8.parse(input);
|
||||
} else {
|
||||
input = Utils.format[inputFormat].parse(input);
|
||||
}
|
||||
|
||||
if (outputFormat === "Windows-1251") {
|
||||
input = CryptoJS.enc.Utf8.stringify(input);
|
||||
return Utils.unicodeToWin1251(input);
|
||||
} else {
|
||||
return Utils.format[outputFormat].stringify(input);
|
||||
}
|
||||
runEncode: function(input, args) {
|
||||
const format = CharEnc.IO_FORMAT[args[0]];
|
||||
let encoded = cptable.utils.encode(format, input);
|
||||
encoded = Array.from(encoded);
|
||||
return encoded;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Decode text operation.
|
||||
* @author tlwr [toby@toby.codes]
|
||||
*
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runDecode: function(input, args) {
|
||||
const format = CharEnc.IO_FORMAT[args[0]];
|
||||
let decoded = cptable.utils.decode(format, input);
|
||||
return decoded;
|
||||
},
|
||||
};
|
||||
|
||||
export default CharEnc;
|
||||
|
||||
@@ -20,10 +20,10 @@ const Checksum = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFletcher8: function(input, args) {
|
||||
var a = 0,
|
||||
let a = 0,
|
||||
b = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a = (a + input[i]) % 0xf;
|
||||
b = (b + a) % 0xf;
|
||||
}
|
||||
@@ -40,10 +40,10 @@ const Checksum = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFletcher16: function(input, args) {
|
||||
var a = 0,
|
||||
let a = 0,
|
||||
b = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a = (a + input[i]) % 0xff;
|
||||
b = (b + a) % 0xff;
|
||||
}
|
||||
@@ -60,10 +60,10 @@ const Checksum = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFletcher32: function(input, args) {
|
||||
var a = 0,
|
||||
let a = 0,
|
||||
b = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a = (a + input[i]) % 0xffff;
|
||||
b = (b + a) % 0xffff;
|
||||
}
|
||||
@@ -80,10 +80,10 @@ const Checksum = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFletcher64: function(input, args) {
|
||||
var a = 0,
|
||||
let a = 0,
|
||||
b = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a = (a + input[i]) % 0xffffffff;
|
||||
b = (b + a) % 0xffffffff;
|
||||
}
|
||||
@@ -100,11 +100,11 @@ const Checksum = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runAdler32: function(input, args) {
|
||||
var MOD_ADLER = 65521,
|
||||
let MOD_ADLER = 65521,
|
||||
a = 1,
|
||||
b = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a += input[i];
|
||||
b += a;
|
||||
}
|
||||
@@ -124,10 +124,10 @@ const Checksum = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runCRC32: function(input, args) {
|
||||
var crcTable = global.crcTable || (global.crcTable = Checksum._genCRCTable()),
|
||||
let crcTable = global.crcTable || (global.crcTable = Checksum._genCRCTable()),
|
||||
crc = 0 ^ (-1);
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
crc = (crc >>> 8) ^ crcTable[(crc ^ input[i]) & 0xff];
|
||||
}
|
||||
|
||||
@@ -153,9 +153,9 @@ const Checksum = {
|
||||
* 0x00,0x00,0xac,0x11,0x00,0x03,0xac,0x11,0x00,0x04])
|
||||
*/
|
||||
runTCPIP: function(input, args) {
|
||||
var csum = 0;
|
||||
let csum = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (i % 2 === 0) {
|
||||
csum += (input[i] << 8);
|
||||
} else {
|
||||
@@ -176,12 +176,12 @@ const Checksum = {
|
||||
* @returns {array}
|
||||
*/
|
||||
_genCRCTable: function() {
|
||||
var c,
|
||||
let c,
|
||||
crcTable = [];
|
||||
|
||||
for (var n = 0; n < 256; n++) {
|
||||
for (let n = 0; n < 256; n++) {
|
||||
c = n;
|
||||
for (var k = 0; k < 8; k++) {
|
||||
for (let k = 0; k < 8; k++) {
|
||||
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
|
||||
}
|
||||
crcTable[n] = c;
|
||||
|
||||
@@ -61,7 +61,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_enc: function (algo, input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
iv = Utils.format[args[1].option].parse(args[1].string || ""),
|
||||
salt = Utils.format[args[2].option].parse(args[2].string || ""),
|
||||
mode = CryptoJS.mode[args[3]],
|
||||
@@ -74,14 +74,14 @@ const Cipher = {
|
||||
key = key.toString(CryptoJS.enc.Latin1);
|
||||
}
|
||||
|
||||
var encrypted = algo.encrypt(input, key, {
|
||||
const encrypted = algo.encrypt(input, key, {
|
||||
salt: salt.sigBytes > 0 ? salt : false,
|
||||
iv: iv.sigBytes > 0 ? iv : null,
|
||||
mode: mode,
|
||||
padding: padding
|
||||
});
|
||||
|
||||
var result = "";
|
||||
let result = "";
|
||||
if (resultOption === "show all") {
|
||||
result += "Key: " + encrypted.key.toString(Utils.format[outputFormat]);
|
||||
result += "\nIV: " + encrypted.iv.toString(Utils.format[outputFormat]);
|
||||
@@ -105,7 +105,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_dec: function (algo, input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
iv = Utils.format[args[1].option].parse(args[1].string || ""),
|
||||
salt = Utils.format[args[2].option].parse(args[2].string || ""),
|
||||
mode = CryptoJS.mode[args[3]],
|
||||
@@ -118,14 +118,14 @@ const Cipher = {
|
||||
return "No input";
|
||||
}
|
||||
|
||||
var ciphertext = Utils.format[inputFormat].parse(input);
|
||||
const ciphertext = Utils.format[inputFormat].parse(input);
|
||||
|
||||
if (iv.sigBytes === 0) {
|
||||
// Use passphrase rather than key. Need to convert it to a string.
|
||||
key = key.toString(CryptoJS.enc.Latin1);
|
||||
}
|
||||
|
||||
var decrypted = algo.decrypt({
|
||||
const decrypted = algo.decrypt({
|
||||
ciphertext: ciphertext,
|
||||
salt: salt.sigBytes > 0 ? salt : false
|
||||
}, key, {
|
||||
@@ -134,7 +134,7 @@ const Cipher = {
|
||||
padding: padding
|
||||
});
|
||||
|
||||
var result;
|
||||
let result;
|
||||
try {
|
||||
result = decrypted.toString(Utils.format[outputFormat]);
|
||||
} catch (err) {
|
||||
@@ -260,13 +260,13 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runBlowfishEnc: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
|
||||
let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
|
||||
mode = args[1],
|
||||
outputFormat = args[2];
|
||||
|
||||
if (key.length === 0) return "Enter a key";
|
||||
|
||||
var encHex = Blowfish.encrypt(input, key, {
|
||||
let encHex = Blowfish.encrypt(input, key, {
|
||||
outputType: 1,
|
||||
cipherMode: Cipher.BLOWFISH_MODES.indexOf(mode)
|
||||
}),
|
||||
@@ -284,7 +284,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runBlowfishDec: function (input, args) {
|
||||
var key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
|
||||
let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
|
||||
mode = args[1],
|
||||
inputFormat = args[2];
|
||||
|
||||
@@ -309,6 +309,11 @@ const Cipher = {
|
||||
* @default
|
||||
*/
|
||||
KDF_ITERATIONS: 1,
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
HASHERS: ["MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "RIPEMD160"],
|
||||
|
||||
/**
|
||||
* Derive PBKDF2 key operation.
|
||||
@@ -318,13 +323,18 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runPbkdf2: function (input, args) {
|
||||
var keySize = args[0] / 32,
|
||||
let keySize = args[0] / 32,
|
||||
iterations = args[1],
|
||||
salt = CryptoJS.enc.Hex.parse(args[2] || ""),
|
||||
inputFormat = args[3],
|
||||
outputFormat = args[4],
|
||||
hasher = args[2],
|
||||
salt = CryptoJS.enc.Hex.parse(args[3] || ""),
|
||||
inputFormat = args[4],
|
||||
outputFormat = args[5],
|
||||
passphrase = Utils.format[inputFormat].parse(input),
|
||||
key = CryptoJS.PBKDF2(passphrase, salt, { keySize: keySize, iterations: iterations });
|
||||
key = CryptoJS.PBKDF2(passphrase, salt, {
|
||||
keySize: keySize,
|
||||
hasher: CryptoJS.algo[hasher],
|
||||
iterations: iterations,
|
||||
});
|
||||
|
||||
return key.toString(Utils.format[outputFormat]);
|
||||
},
|
||||
@@ -338,13 +348,18 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runEvpkdf: function (input, args) {
|
||||
var keySize = args[0] / 32,
|
||||
let keySize = args[0] / 32,
|
||||
iterations = args[1],
|
||||
salt = CryptoJS.enc.Hex.parse(args[2] || ""),
|
||||
inputFormat = args[3],
|
||||
outputFormat = args[4],
|
||||
hasher = args[2],
|
||||
salt = CryptoJS.enc.Hex.parse(args[3] || ""),
|
||||
inputFormat = args[4],
|
||||
outputFormat = args[5],
|
||||
passphrase = Utils.format[inputFormat].parse(input),
|
||||
key = CryptoJS.EvpKDF(passphrase, salt, { keySize: keySize, iterations: iterations });
|
||||
key = CryptoJS.EvpKDF(passphrase, salt, {
|
||||
keySize: keySize,
|
||||
hasher: CryptoJS.algo[hasher],
|
||||
iterations: iterations,
|
||||
});
|
||||
|
||||
return key.toString(Utils.format[outputFormat]);
|
||||
},
|
||||
@@ -358,7 +373,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runRc4: function (input, args) {
|
||||
var message = Utils.format[args[1]].parse(input),
|
||||
let message = Utils.format[args[1]].parse(input),
|
||||
passphrase = Utils.format[args[0].option].parse(args[0].string),
|
||||
encrypted = CryptoJS.RC4.encrypt(message, passphrase);
|
||||
|
||||
@@ -380,7 +395,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runRc4drop: function (input, args) {
|
||||
var message = Utils.format[args[1]].parse(input),
|
||||
let message = Utils.format[args[1]].parse(input),
|
||||
passphrase = Utils.format[args[0].option].parse(args[0].string),
|
||||
drop = args[3],
|
||||
encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop });
|
||||
@@ -398,7 +413,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runVigenereEnc: function (input, args) {
|
||||
var alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
let alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
key = args[0].toLowerCase(),
|
||||
output = "",
|
||||
fail = 0,
|
||||
@@ -409,7 +424,7 @@ const Cipher = {
|
||||
if (!key) return "No key entered";
|
||||
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (alphabet.indexOf(input[i]) >= 0) {
|
||||
// Get the corresponding character of key for the current letter, accounting
|
||||
// for chars not in alphabet
|
||||
@@ -445,7 +460,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runVigenereDec: function (input, args) {
|
||||
var alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
let alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
key = args[0].toLowerCase(),
|
||||
output = "",
|
||||
fail = 0,
|
||||
@@ -456,7 +471,7 @@ const Cipher = {
|
||||
if (!key) return "No key entered";
|
||||
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (alphabet.indexOf(input[i]) >= 0) {
|
||||
chr = key[(i - fail) % key.length];
|
||||
keyIndex = alphabet.indexOf(chr);
|
||||
@@ -499,7 +514,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runAffineEnc: function (input, args) {
|
||||
var alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
let alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
a = args[0],
|
||||
b = args[1],
|
||||
output = "";
|
||||
@@ -508,7 +523,7 @@ const Cipher = {
|
||||
return "The values of a and b can only be integers.";
|
||||
}
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (alphabet.indexOf(input[i]) >= 0) {
|
||||
// Uses the affine function ax+b % m = y (where m is length of the alphabet)
|
||||
output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26];
|
||||
@@ -533,7 +548,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runAffineDec: function (input, args) {
|
||||
var alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
let alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||
a = args[0],
|
||||
b = args[1],
|
||||
output = "",
|
||||
@@ -550,7 +565,7 @@ const Cipher = {
|
||||
// Calculates modular inverse of a
|
||||
aModInv = Utils.modInv(a, 26);
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (alphabet.indexOf(input[i]) >= 0) {
|
||||
// Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse)
|
||||
output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)];
|
||||
@@ -598,7 +613,7 @@ const Cipher = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runSubstitute: function (input, args) {
|
||||
var plaintext = Utils.strToByteArray(Utils.expandAlphRange(args[0]).join()),
|
||||
let plaintext = Utils.strToByteArray(Utils.expandAlphRange(args[0]).join()),
|
||||
ciphertext = Utils.strToByteArray(Utils.expandAlphRange(args[1]).join()),
|
||||
output = [],
|
||||
index = -1;
|
||||
@@ -607,7 +622,7 @@ const Cipher = {
|
||||
output = Utils.strToByteArray("Warning: Plaintext and Ciphertext lengths differ\n\n");
|
||||
}
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
index = plaintext.indexOf(input[i]);
|
||||
output.push(index > -1 && index < ciphertext.length ? ciphertext[index] : input[i]);
|
||||
}
|
||||
@@ -650,10 +665,10 @@ CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) {
|
||||
}
|
||||
|
||||
// Derive key and IV
|
||||
var key = CryptoJS.algo.EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
|
||||
const key = CryptoJS.algo.EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
|
||||
|
||||
// Separate key and IV
|
||||
var iv = CryptoJS.lib.WordArray.create(key.words.slice(keySize), ivSize * 4);
|
||||
const iv = CryptoJS.lib.WordArray.create(key.words.slice(keySize), ivSize * 4);
|
||||
key.sigBytes = keySize * 4;
|
||||
|
||||
// Return params
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import {camelCase, kebabCase, snakeCase} from "lodash";
|
||||
|
||||
import Utils from "../Utils.js";
|
||||
import vkbeautify from "vkbeautify";
|
||||
import {DOMParser as dom} from "xmldom";
|
||||
@@ -35,7 +37,7 @@ const Code = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runSyntaxHighlight: function(input, args) {
|
||||
var language = args[0],
|
||||
let language = args[0],
|
||||
lineNums = args[1];
|
||||
return "<code class='prettyprint'>" + prettyPrintOne(Utils.escapeHtml(input), language, lineNums) + "</code>";
|
||||
},
|
||||
@@ -55,7 +57,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runXmlBeautify: function(input, args) {
|
||||
var indentStr = args[0];
|
||||
const indentStr = args[0];
|
||||
return vkbeautify.xml(input, indentStr);
|
||||
},
|
||||
|
||||
@@ -68,7 +70,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runJsonBeautify: function(input, args) {
|
||||
var indentStr = args[0];
|
||||
const indentStr = args[0];
|
||||
if (!input) return "";
|
||||
return vkbeautify.json(input, indentStr);
|
||||
},
|
||||
@@ -82,7 +84,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runCssBeautify: function(input, args) {
|
||||
var indentStr = args[0];
|
||||
const indentStr = args[0];
|
||||
return vkbeautify.css(input, indentStr);
|
||||
},
|
||||
|
||||
@@ -95,7 +97,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runSqlBeautify: function(input, args) {
|
||||
var indentStr = args[0];
|
||||
const indentStr = args[0];
|
||||
return vkbeautify.sql(input, indentStr);
|
||||
},
|
||||
|
||||
@@ -114,7 +116,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runXmlMinify: function(input, args) {
|
||||
var preserveComments = args[0];
|
||||
const preserveComments = args[0];
|
||||
return vkbeautify.xmlmin(input, preserveComments);
|
||||
},
|
||||
|
||||
@@ -140,7 +142,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runCssMinify: function(input, args) {
|
||||
var preserveComments = args[0];
|
||||
const preserveComments = args[0];
|
||||
return vkbeautify.cssmin(input, preserveComments);
|
||||
},
|
||||
|
||||
@@ -181,45 +183,45 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runGenericBeautify: function(input, args) {
|
||||
var code = input,
|
||||
let code = input,
|
||||
t = 0,
|
||||
preservedTokens = [],
|
||||
m;
|
||||
|
||||
// Remove strings
|
||||
var sstrings = /'([^'\\]|\\.)*'/g;
|
||||
const sstrings = /'([^'\\]|\\.)*'/g;
|
||||
while ((m = sstrings.exec(code))) {
|
||||
code = preserveToken(code, m, t++);
|
||||
sstrings.lastIndex = m.index;
|
||||
}
|
||||
|
||||
var dstrings = /"([^"\\]|\\.)*"/g;
|
||||
const dstrings = /"([^"\\]|\\.)*"/g;
|
||||
while ((m = dstrings.exec(code))) {
|
||||
code = preserveToken(code, m, t++);
|
||||
dstrings.lastIndex = m.index;
|
||||
}
|
||||
|
||||
// Remove comments
|
||||
var scomments = /\/\/[^\n\r]*/g;
|
||||
const scomments = /\/\/[^\n\r]*/g;
|
||||
while ((m = scomments.exec(code))) {
|
||||
code = preserveToken(code, m, t++);
|
||||
scomments.lastIndex = m.index;
|
||||
}
|
||||
|
||||
var mcomments = /\/\*[\s\S]*?\*\//gm;
|
||||
const mcomments = /\/\*[\s\S]*?\*\//gm;
|
||||
while ((m = mcomments.exec(code))) {
|
||||
code = preserveToken(code, m, t++);
|
||||
mcomments.lastIndex = m.index;
|
||||
}
|
||||
|
||||
var hcomments = /(^|\n)#[^\n\r#]+/g;
|
||||
const hcomments = /(^|\n)#[^\n\r#]+/g;
|
||||
while ((m = hcomments.exec(code))) {
|
||||
code = preserveToken(code, m, t++);
|
||||
hcomments.lastIndex = m.index;
|
||||
}
|
||||
|
||||
// Remove regexes
|
||||
var regexes = /\/.*?[^\\]\/[gim]{0,3}/gi;
|
||||
const regexes = /\/.*?[^\\]\/[gim]{0,3}/gi;
|
||||
while ((m = regexes.exec(code))) {
|
||||
code = preserveToken(code, m, t++);
|
||||
regexes.lastIndex = m.index;
|
||||
@@ -241,8 +243,9 @@ const Code = {
|
||||
.replace(/\n{/g, "{");
|
||||
|
||||
// Indent
|
||||
var i = 0,
|
||||
level = 0;
|
||||
let i = 0,
|
||||
level = 0,
|
||||
indent;
|
||||
while (i < code.length) {
|
||||
switch (code[i]) {
|
||||
case "{":
|
||||
@@ -252,7 +255,7 @@ const Code = {
|
||||
if (i+1 >= code.length) break;
|
||||
|
||||
if (code[i+1] === "}") level--;
|
||||
var indent = (level >= 0) ? Array(level*4+1).join(" ") : "";
|
||||
indent = (level >= 0) ? Array(level*4+1).join(" ") : "";
|
||||
|
||||
code = code.substring(0, i+1) + indent + code.substring(i+1);
|
||||
if (level > 0) i += level*4;
|
||||
@@ -285,9 +288,9 @@ const Code = {
|
||||
.replace(/}\s*(else|catch|except|finally|elif|elseif|else if)/gi, "} $1");
|
||||
|
||||
// Replace preserved tokens
|
||||
var ptokens = /###preservedToken(\d+)###/g;
|
||||
const ptokens = /###preservedToken(\d+)###/g;
|
||||
while ((m = ptokens.exec(code))) {
|
||||
var ti = parseInt(m[1], 10);
|
||||
const ti = parseInt(m[1], 10);
|
||||
code = code.substring(0, m.index) + preservedTokens[ti] + code.substring(m.index + m[0].length);
|
||||
ptokens.lastIndex = m.index;
|
||||
}
|
||||
@@ -327,24 +330,24 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runXpath:function(input, args) {
|
||||
var query = args[0],
|
||||
let query = args[0],
|
||||
delimiter = args[1];
|
||||
|
||||
var doc;
|
||||
let doc;
|
||||
try {
|
||||
doc = new dom().parseFromString(input);
|
||||
} catch (err) {
|
||||
return "Invalid input XML.";
|
||||
}
|
||||
|
||||
var nodes;
|
||||
let nodes;
|
||||
try {
|
||||
nodes = xpath.select(query, doc);
|
||||
} catch (err) {
|
||||
return "Invalid XPath. Details:\n" + err.message;
|
||||
}
|
||||
|
||||
var nodeToString = function(node) {
|
||||
const nodeToString = function(node) {
|
||||
return node.toString();
|
||||
};
|
||||
|
||||
@@ -374,7 +377,7 @@ const Code = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runCSSQuery: function(input, args) {
|
||||
var query = args[0],
|
||||
let query = args[0],
|
||||
delimiter = args[1],
|
||||
parser = new DOMParser(),
|
||||
html,
|
||||
@@ -396,7 +399,7 @@ const Code = {
|
||||
return "Invalid CSS Selector. Details:\n" + err.message;
|
||||
}
|
||||
|
||||
var nodeToString = function(node) {
|
||||
const nodeToString = function(node) {
|
||||
switch (node.nodeType) {
|
||||
case Node.ELEMENT_NODE: return node.outerHTML;
|
||||
case Node.ATTRIBUTE_NODE: return node.value;
|
||||
@@ -415,6 +418,84 @@ const Code = {
|
||||
.join(delimiter);
|
||||
},
|
||||
|
||||
/**
|
||||
* This tries to rename variable names in a code snippet according to a function.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {function} replacer - this function will be fed the token which should be renamed.
|
||||
* @returns {string}
|
||||
*/
|
||||
_replaceVariableNames(input, replacer) {
|
||||
const tokenRegex = /\\"|"(?:\\"|[^"])*"|(\b[a-z0-9\-_]+\b)/ig;
|
||||
|
||||
return input.replace(tokenRegex, (...args) => {
|
||||
let match = args[0],
|
||||
quotes = args[1];
|
||||
|
||||
if (!quotes) {
|
||||
return match;
|
||||
} else {
|
||||
return replacer(match);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts to snake_case.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*
|
||||
*/
|
||||
runToSnakeCase(input, args) {
|
||||
const smart = args[0];
|
||||
|
||||
if (smart) {
|
||||
return Code._replaceVariableNames(input, snakeCase);
|
||||
} else {
|
||||
return snakeCase(input);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts to camelCase.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*
|
||||
*/
|
||||
runToCamelCase(input, args) {
|
||||
const smart = args[0];
|
||||
|
||||
if (smart) {
|
||||
return Code._replaceVariableNames(input, camelCase);
|
||||
} else {
|
||||
return camelCase(input);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts to kebab-case.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*
|
||||
*/
|
||||
runToKebabCase(input, args) {
|
||||
const smart = args[0];
|
||||
|
||||
if (smart) {
|
||||
return Code._replaceVariableNames(input, kebabCase);
|
||||
} else {
|
||||
return kebabCase(input);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default Code;
|
||||
|
||||
@@ -6,7 +6,7 @@ import zip from "zlibjs/bin/zip.min";
|
||||
import unzip from "zlibjs/bin/unzip.min";
|
||||
import bzip2 from "exports-loader?bzip2!../lib/bzip2.js";
|
||||
|
||||
var Zlib = {
|
||||
const Zlib = {
|
||||
RawDeflate: rawdeflate.Zlib.RawDeflate,
|
||||
RawInflate: rawinflate.Zlib.RawInflate,
|
||||
Deflate: zlibAndGzip.Zlib.Deflate,
|
||||
@@ -67,7 +67,7 @@ const Compress = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runRawDeflate: function(input, args) {
|
||||
var deflate = new Zlib.RawDeflate(input, {
|
||||
const deflate = new Zlib.RawDeflate(input, {
|
||||
compressionType: Compress.RAW_COMPRESSION_TYPE_LOOKUP[args[0]]
|
||||
});
|
||||
return Array.prototype.slice.call(deflate.compress());
|
||||
@@ -113,7 +113,7 @@ const Compress = {
|
||||
runRawInflate: function(input, args) {
|
||||
// Deal with character encoding issues
|
||||
input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
|
||||
var inflate = new Zlib.RawInflate(input, {
|
||||
let inflate = new Zlib.RawInflate(input, {
|
||||
index: args[0],
|
||||
bufferSize: args[1],
|
||||
bufferType: Compress.RAW_BUFFER_TYPE_LOOKUP[args[2]],
|
||||
@@ -129,8 +129,8 @@ const Compress = {
|
||||
if (result.length > 158 && result[0] === 93 && result[5] === 93) {
|
||||
// If the first two square brackets are there, check that the others
|
||||
// are also there. If they are, throw an error. If not, continue.
|
||||
var valid = false;
|
||||
for (var i = 0; i < 155; i += 5) {
|
||||
let valid = false;
|
||||
for (let i = 0; i < 155; i += 5) {
|
||||
if (result[i] !== 93) {
|
||||
valid = true;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ const Compress = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runZlibDeflate: function(input, args) {
|
||||
var deflate = new Zlib.Deflate(input, {
|
||||
const deflate = new Zlib.Deflate(input, {
|
||||
compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]]
|
||||
});
|
||||
return Array.prototype.slice.call(deflate.compress());
|
||||
@@ -189,7 +189,7 @@ const Compress = {
|
||||
runZlibInflate: function(input, args) {
|
||||
// Deal with character encoding issues
|
||||
input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
|
||||
var inflate = new Zlib.Inflate(input, {
|
||||
const inflate = new Zlib.Inflate(input, {
|
||||
index: args[0],
|
||||
bufferSize: args[1],
|
||||
bufferType: Compress.ZLIB_BUFFER_TYPE_LOOKUP[args[2]],
|
||||
@@ -214,7 +214,7 @@ const Compress = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runGzip: function(input, args) {
|
||||
var filename = args[1],
|
||||
let filename = args[1],
|
||||
comment = args[2],
|
||||
options = {
|
||||
deflateOptions: {
|
||||
@@ -234,7 +234,7 @@ const Compress = {
|
||||
options.comment = comment;
|
||||
}
|
||||
|
||||
var gzip = new Zlib.Gzip(input, options);
|
||||
const gzip = new Zlib.Gzip(input, options);
|
||||
return Array.prototype.slice.call(gzip.compress());
|
||||
},
|
||||
|
||||
@@ -249,7 +249,7 @@ const Compress = {
|
||||
runGunzip: function(input, args) {
|
||||
// Deal with character encoding issues
|
||||
input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
|
||||
var gunzip = new Zlib.Gunzip(input);
|
||||
const gunzip = new Zlib.Gunzip(input);
|
||||
return Array.prototype.slice.call(gunzip.decompress());
|
||||
},
|
||||
|
||||
@@ -285,7 +285,7 @@ const Compress = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runPkzip: function(input, args) {
|
||||
var password = Utils.strToByteArray(args[2]),
|
||||
let password = Utils.strToByteArray(args[2]),
|
||||
options = {
|
||||
filename: Utils.strToByteArray(args[0]),
|
||||
comment: Utils.strToByteArray(args[1]),
|
||||
@@ -318,7 +318,7 @@ const Compress = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runPkunzip: function(input, args) {
|
||||
var options = {
|
||||
let options = {
|
||||
password: Utils.strToByteArray(args[0]),
|
||||
verify: args[1]
|
||||
},
|
||||
@@ -327,15 +327,15 @@ const Compress = {
|
||||
files = [];
|
||||
|
||||
filenames.forEach(function(fileName) {
|
||||
var bytes = unzip.decompress(fileName);
|
||||
var contents = Utils.byteArrayToUtf8(bytes);
|
||||
const bytes = unzip.decompress(fileName);
|
||||
const contents = Utils.byteArrayToUtf8(bytes);
|
||||
|
||||
var file = {
|
||||
const file = {
|
||||
fileName: fileName,
|
||||
size: contents.length,
|
||||
};
|
||||
|
||||
var isDir = contents.length === 0 && fileName.endsWith("/");
|
||||
const isDir = contents.length === 0 && fileName.endsWith("/");
|
||||
if (!isDir) {
|
||||
file.bytes = bytes;
|
||||
file.contents = contents;
|
||||
@@ -356,7 +356,7 @@ const Compress = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runBzip2Decompress: function(input, args) {
|
||||
var compressed = new Uint8Array(input),
|
||||
let compressed = new Uint8Array(input),
|
||||
bzip2Reader,
|
||||
plain = "";
|
||||
|
||||
@@ -383,19 +383,19 @@ const Compress = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runTar: function(input, args) {
|
||||
var Tarball = function() {
|
||||
const Tarball = function() {
|
||||
this.bytes = new Array(512);
|
||||
this.position = 0;
|
||||
};
|
||||
|
||||
Tarball.prototype.addEmptyBlock = function() {
|
||||
var filler = new Array(512);
|
||||
const filler = new Array(512);
|
||||
filler.fill(0);
|
||||
this.bytes = this.bytes.concat(filler);
|
||||
};
|
||||
|
||||
Tarball.prototype.writeBytes = function(bytes) {
|
||||
var self = this;
|
||||
const self = this;
|
||||
|
||||
if (this.position + bytes.length > this.bytes.length) {
|
||||
this.addEmptyBlock();
|
||||
@@ -412,17 +412,17 @@ const Compress = {
|
||||
};
|
||||
|
||||
Tarball.prototype.writeEndBlocks = function() {
|
||||
var numEmptyBlocks = 2;
|
||||
for (var i = 0; i < numEmptyBlocks; i++) {
|
||||
const numEmptyBlocks = 2;
|
||||
for (let i = 0; i < numEmptyBlocks; i++) {
|
||||
this.addEmptyBlock();
|
||||
}
|
||||
};
|
||||
|
||||
var fileSize = Utils.padLeft(input.length.toString(8), 11, "0");
|
||||
var currentUnixTimestamp = Math.floor(Date.now() / 1000);
|
||||
var lastModTime = Utils.padLeft(currentUnixTimestamp.toString(8), 11, "0");
|
||||
const fileSize = Utils.padLeft(input.length.toString(8), 11, "0");
|
||||
const currentUnixTimestamp = Math.floor(Date.now() / 1000);
|
||||
const lastModTime = Utils.padLeft(currentUnixTimestamp.toString(8), 11, "0");
|
||||
|
||||
var file = {
|
||||
const file = {
|
||||
fileName: Utils.padBytesRight(args[0], 100),
|
||||
fileMode: Utils.padBytesRight("0000664", 8),
|
||||
ownerUID: Utils.padBytesRight("0", 8),
|
||||
@@ -441,9 +441,9 @@ const Compress = {
|
||||
fileNamePrefix: Utils.padBytesRight("", 155),
|
||||
};
|
||||
|
||||
var checksum = 0;
|
||||
for (var key in file) {
|
||||
var bytes = file[key];
|
||||
let checksum = 0;
|
||||
for (const key in file) {
|
||||
const bytes = file[key];
|
||||
Array.prototype.forEach.call(bytes, function(b) {
|
||||
if (typeof b.charCodeAt !== "undefined") {
|
||||
checksum += b.charCodeAt();
|
||||
@@ -455,7 +455,7 @@ const Compress = {
|
||||
checksum = Utils.padBytesRight(Utils.padLeft(checksum.toString(8), 7, "0"), 8);
|
||||
file.checksum = checksum;
|
||||
|
||||
var tarball = new Tarball();
|
||||
const tarball = new Tarball();
|
||||
tarball.writeBytes(file.fileName);
|
||||
tarball.writeBytes(file.fileMode);
|
||||
tarball.writeBytes(file.ownerUID);
|
||||
@@ -490,22 +490,22 @@ const Compress = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runUntar: function(input, args) {
|
||||
var Stream = function(input) {
|
||||
const Stream = function(input) {
|
||||
this.bytes = input;
|
||||
this.position = 0;
|
||||
};
|
||||
|
||||
Stream.prototype.getBytes = function(bytesToGet) {
|
||||
var newPosition = this.position + bytesToGet;
|
||||
var bytes = this.bytes.slice(this.position, newPosition);
|
||||
const newPosition = this.position + bytesToGet;
|
||||
const bytes = this.bytes.slice(this.position, newPosition);
|
||||
this.position = newPosition;
|
||||
return bytes;
|
||||
};
|
||||
|
||||
Stream.prototype.readString = function(numBytes) {
|
||||
var result = "";
|
||||
for (var i = this.position; i < this.position + numBytes; i++) {
|
||||
var currentByte = this.bytes[i];
|
||||
let result = "";
|
||||
for (let i = this.position; i < this.position + numBytes; i++) {
|
||||
const currentByte = this.bytes[i];
|
||||
if (currentByte === 0) break;
|
||||
result += String.fromCharCode(currentByte);
|
||||
}
|
||||
@@ -514,7 +514,7 @@ const Compress = {
|
||||
};
|
||||
|
||||
Stream.prototype.readInt = function(numBytes, base) {
|
||||
var string = this.readString(numBytes);
|
||||
const string = this.readString(numBytes);
|
||||
return parseInt(string, base);
|
||||
};
|
||||
|
||||
@@ -522,13 +522,13 @@ const Compress = {
|
||||
return this.position < this.bytes.length;
|
||||
};
|
||||
|
||||
var stream = new Stream(input),
|
||||
let stream = new Stream(input),
|
||||
files = [];
|
||||
|
||||
while (stream.hasMore()) {
|
||||
var dataPosition = stream.position + 512;
|
||||
const dataPosition = stream.position + 512;
|
||||
|
||||
var file = {
|
||||
const file = {
|
||||
fileName: stream.readString(100),
|
||||
fileMode: stream.readString(8),
|
||||
ownerUID: stream.readString(8),
|
||||
@@ -555,7 +555,7 @@ const Compress = {
|
||||
if (file.type === "0") {
|
||||
// File
|
||||
files.push(file);
|
||||
var endPosition = stream.position + file.size;
|
||||
let endPosition = stream.position + file.size;
|
||||
if (file.size % 512 !== 0) {
|
||||
endPosition += 512 - (file.size % 512);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ const Convert = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runDistance: function (input, args) {
|
||||
var inputUnits = args[0],
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.DISTANCE_FACTOR[inputUnits];
|
||||
@@ -146,7 +146,7 @@ const Convert = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runDataSize: function (input, args) {
|
||||
var inputUnits = args[0],
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.DATA_FACTOR[inputUnits];
|
||||
@@ -226,7 +226,7 @@ const Convert = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runArea: function (input, args) {
|
||||
var inputUnits = args[0],
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.AREA_FACTOR[inputUnits];
|
||||
@@ -337,7 +337,7 @@ const Convert = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runMass: function (input, args) {
|
||||
var inputUnits = args[0],
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.MASS_FACTOR[inputUnits];
|
||||
@@ -402,7 +402,7 @@ const Convert = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runSpeed: function (input, args) {
|
||||
var inputUnits = args[0],
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.SPEED_FACTOR[inputUnits];
|
||||
|
||||
@@ -23,7 +23,7 @@ const DateTime = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFromUnixTimestamp: function(input, args) {
|
||||
var units = args[0],
|
||||
let units = args[0],
|
||||
d;
|
||||
|
||||
input = parseFloat(input);
|
||||
@@ -46,6 +46,12 @@ const DateTime = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
TREAT_AS_UTC: true,
|
||||
|
||||
/**
|
||||
* To UNIX Timestamp operation.
|
||||
*
|
||||
@@ -54,8 +60,9 @@ const DateTime = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runToUnixTimestamp: function(input, args) {
|
||||
var units = args[0],
|
||||
d = moment(input);
|
||||
let units = args[0],
|
||||
treatAsUTC = args[1],
|
||||
d = treatAsUTC ? moment.utc(input) : moment(input);
|
||||
|
||||
if (units === "Seconds (s)") {
|
||||
return d.unix();
|
||||
@@ -129,7 +136,7 @@ const DateTime = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runTranslateFormat: function(input, args) {
|
||||
var inputFormat = args[1],
|
||||
let inputFormat = args[1],
|
||||
inputTimezone = args[2],
|
||||
outputFormat = args[3],
|
||||
outputTimezone = args[4],
|
||||
@@ -154,7 +161,7 @@ const DateTime = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runParse: function(input, args) {
|
||||
var inputFormat = args[1],
|
||||
let inputFormat = args[1],
|
||||
inputTimezone = args[2],
|
||||
date,
|
||||
output = "";
|
||||
|
||||
@@ -36,7 +36,7 @@ const Endian = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runSwapEndianness: function(input, args) {
|
||||
var dataFormat = args[0],
|
||||
let dataFormat = args[0],
|
||||
wordLength = args[1],
|
||||
padIncompleteWords = args[2],
|
||||
data = [],
|
||||
@@ -63,7 +63,7 @@ const Endian = {
|
||||
|
||||
// Split up into words
|
||||
for (i = 0; i < data.length; i += wordLength) {
|
||||
var word = data.slice(i, i + wordLength);
|
||||
const word = data.slice(i, i + wordLength);
|
||||
|
||||
// Pad word if too short
|
||||
if (padIncompleteWords && word.length < wordLength){
|
||||
|
||||
@@ -26,7 +26,7 @@ const Entropy = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runEntropy: function(input, args) {
|
||||
var chunkSize = args[0],
|
||||
let chunkSize = args[0],
|
||||
output = "",
|
||||
entropy = Entropy._calcEntropy(input);
|
||||
|
||||
@@ -58,9 +58,9 @@ const Entropy = {
|
||||
]);\
|
||||
</script>";
|
||||
|
||||
var chunkEntropy = 0;
|
||||
let chunkEntropy = 0;
|
||||
if (chunkSize !== 0) {
|
||||
for (var i = 0; i < input.length; i += chunkSize) {
|
||||
for (let i = 0; i < input.length; i += chunkSize) {
|
||||
chunkEntropy = Entropy._calcEntropy(input.slice(i, i+chunkSize));
|
||||
output += "Bytes " + i + " to " + (i+chunkSize) + ": " + chunkEntropy + "\n";
|
||||
}
|
||||
@@ -88,15 +88,11 @@ const Entropy = {
|
||||
runFreqDistrib: function (input, args) {
|
||||
if (!input.length) return "No data";
|
||||
|
||||
var distrib = new Array(256),
|
||||
let distrib = new Array(256).fill(0),
|
||||
percentages = new Array(256),
|
||||
len = input.length,
|
||||
showZeroes = args[0];
|
||||
|
||||
// Initialise distrib to 0
|
||||
for (var i = 0; i < 256; i++) {
|
||||
distrib[i] = 0;
|
||||
}
|
||||
showZeroes = args[0],
|
||||
i;
|
||||
|
||||
// Count bytes
|
||||
for (i = 0; i < len; i++) {
|
||||
@@ -104,14 +100,14 @@ const Entropy = {
|
||||
}
|
||||
|
||||
// Calculate percentages
|
||||
var repr = 0;
|
||||
let repr = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (distrib[i] > 0) repr++;
|
||||
percentages[i] = distrib[i] / len * 100;
|
||||
}
|
||||
|
||||
// Print
|
||||
var output = "<canvas id='chart-area'></canvas><br>" +
|
||||
let output = "<canvas id='chart-area'></canvas><br>" +
|
||||
"Total data length: " + len +
|
||||
"\nNumber of bytes represented: " + repr +
|
||||
"\nNumber of bytes not represented: " + (256-repr) +
|
||||
@@ -147,15 +143,16 @@ const Entropy = {
|
||||
* @returns {number}
|
||||
*/
|
||||
_calcEntropy: function(data) {
|
||||
var prob = [],
|
||||
let prob = [],
|
||||
uniques = data.unique(),
|
||||
str = Utils.byteArrayToChars(data);
|
||||
str = Utils.byteArrayToChars(data),
|
||||
i;
|
||||
|
||||
for (var i = 0; i < uniques.length; i++) {
|
||||
for (i = 0; i < uniques.length; i++) {
|
||||
prob.push(str.count(Utils.chr(uniques[i])) / data.length);
|
||||
}
|
||||
|
||||
var entropy = 0,
|
||||
let entropy = 0,
|
||||
p;
|
||||
|
||||
for (i = 0; i < prob.length; i++) {
|
||||
|
||||
@@ -21,7 +21,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_search: function(input, searchRegex, removeRegex, includeTotal) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
total = 0,
|
||||
match;
|
||||
|
||||
@@ -58,7 +58,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runStrings: function(input, args) {
|
||||
var minLen = args[0] || Extract.MIN_STRING_LEN,
|
||||
let minLen = args[0] || Extract.MIN_STRING_LEN,
|
||||
displayTotal = args[1],
|
||||
strings = "[A-Z\\d/\\-:.,_$%'\"()<>= !\\[\\]{}@]",
|
||||
regex = new RegExp(strings + "{" + minLen + ",}", "ig");
|
||||
@@ -91,7 +91,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runIp: function(input, args) {
|
||||
var includeIpv4 = args[0],
|
||||
let includeIpv4 = args[0],
|
||||
includeIpv6 = args[1],
|
||||
removeLocal = args[2],
|
||||
displayTotal = args[3],
|
||||
@@ -108,10 +108,10 @@ const Extract = {
|
||||
}
|
||||
|
||||
if (ips) {
|
||||
var regex = new RegExp(ips, "ig");
|
||||
const regex = new RegExp(ips, "ig");
|
||||
|
||||
if (removeLocal) {
|
||||
var ten = "10\\..+",
|
||||
let ten = "10\\..+",
|
||||
oneninetwo = "192\\.168\\..+",
|
||||
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
||||
onetwoseven = "127\\..+",
|
||||
@@ -136,7 +136,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runEmail: function(input, args) {
|
||||
var displayTotal = args[0],
|
||||
let displayTotal = args[0],
|
||||
regex = /\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}/ig;
|
||||
|
||||
return Extract._search(input, regex, null, displayTotal);
|
||||
@@ -151,7 +151,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runMac: function(input, args) {
|
||||
var displayTotal = args[0],
|
||||
let displayTotal = args[0],
|
||||
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig;
|
||||
|
||||
return Extract._search(input, regex, null, displayTotal);
|
||||
@@ -166,14 +166,14 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runUrls: function(input, args) {
|
||||
var displayTotal = args[0],
|
||||
let displayTotal = args[0],
|
||||
protocol = "[A-Z]+://",
|
||||
hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+",
|
||||
port = ":\\d+",
|
||||
path = "/[^.!,?;\"'<>()\\[\\]{}\\s\\x7F-\\xFF]*";
|
||||
|
||||
path += "(?:[.!,?]+[^.!,?;\"'<>()\\[\\]{}\\s\\x7F-\\xFF]+)*";
|
||||
var regex = new RegExp(protocol + hostname + "(?:" + port +
|
||||
const regex = new RegExp(protocol + hostname + "(?:" + port +
|
||||
")?(?:" + path + ")?", "ig");
|
||||
return Extract._search(input, regex, null, displayTotal);
|
||||
},
|
||||
@@ -187,7 +187,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runDomains: function(input, args) {
|
||||
var displayTotal = args[0],
|
||||
let displayTotal = args[0],
|
||||
protocol = "https?://",
|
||||
hostname = "[-\\w\\.]+",
|
||||
tld = "\\.(?:com|net|org|biz|info|co|uk|onion|int|mobi|name|edu|gov|mil|eu|ac|ae|af|de|ca|ch|cn|cy|es|gb|hk|il|in|io|tv|me|nl|no|nz|ro|ru|tr|us|az|ir|kz|uz|pk)+",
|
||||
@@ -216,7 +216,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFilePaths: function(input, args) {
|
||||
var includeWinPath = args[0],
|
||||
let includeWinPath = args[0],
|
||||
includeUnixPath = args[1],
|
||||
displayTotal = args[2],
|
||||
winDrive = "[A-Z]:\\\\",
|
||||
@@ -236,7 +236,7 @@ const Extract = {
|
||||
}
|
||||
|
||||
if (filePaths) {
|
||||
var regex = new RegExp(filePaths, "ig");
|
||||
const regex = new RegExp(filePaths, "ig");
|
||||
return Extract._search(input, regex, null, displayTotal);
|
||||
} else {
|
||||
return "";
|
||||
@@ -252,7 +252,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runDates: function(input, args) {
|
||||
var displayTotal = args[0],
|
||||
let displayTotal = args[0],
|
||||
date1 = "(?:19|20)\\d\\d[- /.](?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])", // yyyy-mm-dd
|
||||
date2 = "(?:0[1-9]|[12][0-9]|3[01])[- /.](?:0[1-9]|1[012])[- /.](?:19|20)\\d\\d", // dd/mm/yyyy
|
||||
date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy
|
||||
@@ -270,7 +270,7 @@ const Extract = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runAllIdents: function(input, args) {
|
||||
var output = "";
|
||||
let output = "";
|
||||
output += "IP addresses\n";
|
||||
output += Extract.runIp(input, [true, true, false]);
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@ const FileType = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runDetect: function(input, args) {
|
||||
var type = FileType._magicType(input);
|
||||
const type = FileType.magicType(input);
|
||||
|
||||
if (!type) {
|
||||
return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
|
||||
} else {
|
||||
var output = "File extension: " + type.ext + "\n" +
|
||||
let output = "File extension: " + type.ext + "\n" +
|
||||
"MIME type: " + type.mime;
|
||||
|
||||
if (type.desc && type.desc.length) {
|
||||
@@ -51,15 +51,15 @@ const FileType = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runScanForEmbeddedFiles: function(input, args) {
|
||||
var output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n",
|
||||
let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n",
|
||||
type,
|
||||
ignoreCommon = args[0],
|
||||
commonExts = ["ico", "ttf", ""],
|
||||
numFound = 0,
|
||||
numCommonFound = 0;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
type = FileType._magicType(input.slice(i));
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
type = FileType.magicType(input.slice(i));
|
||||
if (type) {
|
||||
if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
|
||||
numCommonFound++;
|
||||
@@ -96,14 +96,13 @@ const FileType = {
|
||||
* Given a buffer, detects magic byte sequences at specific positions and returns the
|
||||
* extension and mime type.
|
||||
*
|
||||
* @private
|
||||
* @param {byteArray} buf
|
||||
* @returns {Object} type
|
||||
* @returns {string} type.ext - File extension
|
||||
* @returns {string} type.mime - Mime type
|
||||
* @returns {string} [type.desc] - Description
|
||||
*/
|
||||
_magicType: function (buf) {
|
||||
magicType: function (buf) {
|
||||
if (!(buf && buf.length > 1)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -31,14 +31,14 @@ const HTML = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToEntity: function(input, args) {
|
||||
var convertAll = args[0],
|
||||
let convertAll = args[0],
|
||||
numeric = args[1] === "Numeric entities",
|
||||
hexa = args[1] === "Hex entities";
|
||||
|
||||
var charcodes = Utils.strToCharcode(input);
|
||||
var output = "";
|
||||
const charcodes = Utils.strToCharcode(input);
|
||||
let output = "";
|
||||
|
||||
for (var i = 0; i < charcodes.length; i++) {
|
||||
for (let i = 0; i < charcodes.length; i++) {
|
||||
if (convertAll && numeric) {
|
||||
output += "&#" + charcodes[i] + ";";
|
||||
} else if (convertAll && hexa) {
|
||||
@@ -77,7 +77,7 @@ const HTML = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFromEntity: function(input, args) {
|
||||
var regex = /&(#?x?[a-zA-Z0-9]{1,8});/g,
|
||||
let regex = /&(#?x?[a-zA-Z0-9]{1,8});/g,
|
||||
output = "",
|
||||
m,
|
||||
i = 0;
|
||||
@@ -88,16 +88,16 @@ const HTML = {
|
||||
output += input[i++];
|
||||
|
||||
// Add match
|
||||
var bite = HTML._entityToByte[m[1]];
|
||||
const bite = HTML._entityToByte[m[1]];
|
||||
if (bite) {
|
||||
output += Utils.chr(bite);
|
||||
} else if (!bite && m[1][0] === "#" && m[1].length > 1 && /^#\d{1,5}$/.test(m[1])) {
|
||||
// Numeric entity (e.g. )
|
||||
var num = m[1].slice(1, m[1].length);
|
||||
const num = m[1].slice(1, m[1].length);
|
||||
output += Utils.chr(parseInt(num, 10));
|
||||
} else if (!bite && m[1][0] === "#" && m[1].length > 3 && /^#x[\dA-F]{2,8}$/i.test(m[1])) {
|
||||
// Hex entity (e.g. :)
|
||||
var hex = m[1].slice(2, m[1].length);
|
||||
const hex = m[1].slice(2, m[1].length);
|
||||
output += Utils.chr(parseInt(hex, 16));
|
||||
} else {
|
||||
// Not a valid entity, print as normal
|
||||
@@ -134,7 +134,7 @@ const HTML = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runStripTags: function(input, args) {
|
||||
var removeIndentation = args[0],
|
||||
let removeIndentation = args[0],
|
||||
removeLineBreaks = args[1];
|
||||
|
||||
input = Utils.stripHtmlTags(input);
|
||||
@@ -160,7 +160,7 @@ const HTML = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runParseColourCode: function(input, args) {
|
||||
var m = null,
|
||||
let m = null,
|
||||
r = 0, g = 0, b = 0, a = 1;
|
||||
|
||||
// Read in the input
|
||||
@@ -177,7 +177,7 @@ const HTML = {
|
||||
a = m[4] ? parseFloat(m[4]) : 1;
|
||||
} else if ((m = input.match(/hsla?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)%,\s?(\d{1,3}(?:\.\d+)?)%(?:,\s?(\d(?:\.\d+)?))?\)/i))) {
|
||||
// HSL or HSLA - hsl(200, 65%, 91%) or hsla(200, 65%, 91%, 1)
|
||||
var h_ = parseFloat(m[1]) / 360,
|
||||
let h_ = parseFloat(m[1]) / 360,
|
||||
s_ = parseFloat(m[2]) / 100,
|
||||
l_ = parseFloat(m[3]) / 100,
|
||||
rgb_ = HTML._hslToRgb(h_, s_, l_);
|
||||
@@ -188,7 +188,7 @@ const HTML = {
|
||||
a = m[4] ? parseFloat(m[4]) : 1;
|
||||
} else if ((m = input.match(/cmyk\((\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?)\)/i))) {
|
||||
// CMYK - cmyk(0.12, 0.04, 0.00, 0.03)
|
||||
var c_ = parseFloat(m[1]),
|
||||
let c_ = parseFloat(m[1]),
|
||||
m_ = parseFloat(m[2]),
|
||||
y_ = parseFloat(m[3]),
|
||||
k_ = parseFloat(m[4]);
|
||||
@@ -198,21 +198,22 @@ const HTML = {
|
||||
b = Math.round(255 * (1 - y_) * (1 - k_));
|
||||
}
|
||||
|
||||
var hsl_ = HTML._rgbToHsl(r, g, b),
|
||||
let hsl_ = HTML._rgbToHsl(r, g, b),
|
||||
h = Math.round(hsl_[0] * 360),
|
||||
s = Math.round(hsl_[1] * 100),
|
||||
l = Math.round(hsl_[2] * 100),
|
||||
k = 1 - Math.max(r/255, g/255, b/255),
|
||||
c = (1 - r/255 - k) / (1 - k),
|
||||
m = (1 - g/255 - k) / (1 - k), // eslint-disable-line no-redeclare
|
||||
y = (1 - b/255 - k) / (1 - k);
|
||||
|
||||
m = (1 - g/255 - k) / (1 - k);
|
||||
|
||||
c = isNaN(c) ? "0" : c.toFixed(2);
|
||||
m = isNaN(m) ? "0" : m.toFixed(2);
|
||||
y = isNaN(y) ? "0" : y.toFixed(2);
|
||||
k = k.toFixed(2);
|
||||
|
||||
var hex = "#" +
|
||||
let hex = "#" +
|
||||
Utils.padLeft(Math.round(r).toString(16), 2) +
|
||||
Utils.padLeft(Math.round(g).toString(16), 2) +
|
||||
Utils.padLeft(Math.round(b).toString(16), 2),
|
||||
@@ -261,12 +262,12 @@ const HTML = {
|
||||
* @return {Array} The RGB representation
|
||||
*/
|
||||
_hslToRgb: function(h, s, l){
|
||||
var r, g, b;
|
||||
let r, g, b;
|
||||
|
||||
if (s === 0){
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
const hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
@@ -275,8 +276,8 @@ const HTML = {
|
||||
return p;
|
||||
};
|
||||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
@@ -302,14 +303,14 @@ const HTML = {
|
||||
*/
|
||||
_rgbToHsl: function(r, g, b) {
|
||||
r /= 255; g /= 255; b /= 255;
|
||||
var max = Math.max(r, g, b),
|
||||
let max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b),
|
||||
h, s, l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
const d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
|
||||
@@ -12,6 +12,17 @@ import {UAS_parser as UAParser} from "../lib/uas_parser.js";
|
||||
*/
|
||||
const HTTP = {
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
METHODS: [
|
||||
"GET", "POST", "HEAD",
|
||||
"PUT", "PATCH", "DELETE",
|
||||
"CONNECT", "TRACE", "OPTIONS"
|
||||
],
|
||||
|
||||
|
||||
/**
|
||||
* Strip HTTP headers operation.
|
||||
*
|
||||
@@ -20,7 +31,7 @@ const HTTP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runStripHeaders: function(input, args) {
|
||||
var headerEnd = input.indexOf("\r\n\r\n");
|
||||
let headerEnd = input.indexOf("\r\n\r\n");
|
||||
headerEnd = (headerEnd < 0) ? input.indexOf("\n\n") + 2 : headerEnd + 4;
|
||||
|
||||
return (headerEnd < 2) ? input : input.slice(headerEnd, input.length);
|
||||
@@ -35,7 +46,7 @@ const HTTP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParseUserAgent: function(input, args) {
|
||||
var ua = UAParser.parse(input);
|
||||
const ua = UAParser.parse(input);
|
||||
|
||||
return "Type: " + ua.type + "\n" +
|
||||
"Family: " + ua.uaFamily + "\n" +
|
||||
@@ -51,6 +62,94 @@ const HTTP = {
|
||||
"Device Type: " + ua.deviceType + "\n";
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
MODE: [
|
||||
"Cross-Origin Resource Sharing",
|
||||
"No CORS (limited to HEAD, GET or POST)",
|
||||
],
|
||||
|
||||
/**
|
||||
* Lookup table for HTTP modes
|
||||
*
|
||||
* @private
|
||||
* @constant
|
||||
*/
|
||||
_modeLookup: {
|
||||
"Cross-Origin Resource Sharing": "cors",
|
||||
"No CORS (limited to HEAD, GET or POST)": "no-cors",
|
||||
},
|
||||
|
||||
/**
|
||||
* HTTP request operation.
|
||||
*
|
||||
* @author tlwr [toby@toby.codes]
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runHTTPRequest(input, args) {
|
||||
const method = args[0],
|
||||
url = args[1],
|
||||
headersText = args[2],
|
||||
mode = args[3],
|
||||
showResponseMetadata = args[4];
|
||||
|
||||
if (url.length === 0) return "";
|
||||
|
||||
let headers = new Headers();
|
||||
headersText.split(/\r?\n/).forEach(line => {
|
||||
line = line.trim();
|
||||
|
||||
if (line.length === 0) return;
|
||||
|
||||
let split = line.split(":");
|
||||
if (split.length !== 2) throw `Could not parse header in line: ${line}`;
|
||||
|
||||
headers.set(split[0].trim(), split[1].trim());
|
||||
});
|
||||
|
||||
let config = {
|
||||
method: method,
|
||||
headers: headers,
|
||||
mode: HTTP._modeLookup[mode],
|
||||
cache: "no-cache",
|
||||
};
|
||||
|
||||
if (method !== "GET" && method !== "HEAD") {
|
||||
config.body = input;
|
||||
}
|
||||
|
||||
return fetch(url, config)
|
||||
.then(r => {
|
||||
if (r.status === 0 && r.type === "opaque") {
|
||||
return "Error: Null response. Try setting the connection mode to CORS.";
|
||||
}
|
||||
|
||||
if (showResponseMetadata) {
|
||||
let headers = "";
|
||||
for (let pair of r.headers.entries()) {
|
||||
headers += " " + pair[0] + ": " + pair[1] + "\n";
|
||||
}
|
||||
return r.text().then(b => {
|
||||
return "####\n Status: " + r.status + " " + r.statusText +
|
||||
"\n Exposed headers:\n" + headers + "####\n\n" + b;
|
||||
});
|
||||
}
|
||||
return r.text();
|
||||
})
|
||||
.catch(e => {
|
||||
return e.toString() +
|
||||
"\n\nThis error could be caused by one of the following:\n" +
|
||||
" - An invalid URL\n" +
|
||||
" - Making a cross-origin request to a server which does not support CORS\n";
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default HTTP;
|
||||
|
||||
@@ -144,7 +144,7 @@ const Hash = {
|
||||
*/
|
||||
runSHA3: function (input, args) {
|
||||
input = CryptoJS.enc.Latin1.parse(input);
|
||||
var sha3Length = args[0],
|
||||
let sha3Length = args[0],
|
||||
options = {
|
||||
outputLength: parseInt(sha3Length, 10)
|
||||
};
|
||||
@@ -179,9 +179,9 @@ const Hash = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runHMAC: function (input, args) {
|
||||
var hashFunc = args[1];
|
||||
const hashFunc = args[1];
|
||||
input = CryptoJS.enc.Latin1.parse(input);
|
||||
var execute = {
|
||||
const execute = {
|
||||
"MD5": CryptoJS.HmacMD5(input, args[0]),
|
||||
"SHA1": CryptoJS.HmacSHA1(input, args[0]),
|
||||
"SHA224": CryptoJS.HmacSHA224(input, args[0]),
|
||||
@@ -203,7 +203,7 @@ const Hash = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runAll: function (input, args) {
|
||||
var byteArray = Utils.strToByteArray(input),
|
||||
let byteArray = Utils.strToByteArray(input),
|
||||
output = "MD2: " + Hash.runMD2(input, []) +
|
||||
"\nMD4: " + Hash.runMD4(input, []) +
|
||||
"\nMD5: " + Hash.runMD5(input, []) +
|
||||
@@ -240,7 +240,7 @@ const Hash = {
|
||||
runAnalyse: function(input, args) {
|
||||
input = input.replace(/\s/g, "");
|
||||
|
||||
var output = "",
|
||||
let output = "",
|
||||
byteLength = input.length / 2,
|
||||
bitLength = byteLength * 8,
|
||||
possibleHashFunctions = [];
|
||||
|
||||
@@ -37,19 +37,19 @@ const Hexdump = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo: function(input, args) {
|
||||
var length = args[0] || Hexdump.WIDTH;
|
||||
var upperCase = args[1];
|
||||
var includeFinalLength = args[2];
|
||||
const length = args[0] || Hexdump.WIDTH;
|
||||
const upperCase = args[1];
|
||||
const includeFinalLength = args[2];
|
||||
|
||||
var output = "", padding = 2;
|
||||
for (var i = 0; i < input.length; i += length) {
|
||||
var buff = input.slice(i, i+length);
|
||||
var hexa = "";
|
||||
for (var j = 0; j < buff.length; j++) {
|
||||
let output = "", padding = 2;
|
||||
for (let i = 0; i < input.length; i += length) {
|
||||
const buff = input.slice(i, i+length);
|
||||
let hexa = "";
|
||||
for (let j = 0; j < buff.length; j++) {
|
||||
hexa += Utils.hex(buff[j], padding) + " ";
|
||||
}
|
||||
|
||||
var lineNo = Utils.hex(i, 8);
|
||||
let lineNo = Utils.hex(i, 8);
|
||||
|
||||
if (upperCase) {
|
||||
hexa = hexa.toUpperCase();
|
||||
@@ -77,19 +77,19 @@ const Hexdump = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFrom: function(input, args) {
|
||||
var output = [],
|
||||
let output = [],
|
||||
regex = /^\s*(?:[\dA-F]{4,16}:?)?\s*((?:[\dA-F]{2}\s){1,8}(?:\s|[\dA-F]{2}-)(?:[\dA-F]{2}\s){1,8}|(?:[\dA-F]{2}\s|[\dA-F]{4}\s)+)/igm,
|
||||
block, line;
|
||||
|
||||
while ((block = regex.exec(input))) {
|
||||
line = Utils.fromHex(block[1].replace(/-/g, " "));
|
||||
for (var i = 0; i < line.length; i++) {
|
||||
for (let i = 0; i < line.length; i++) {
|
||||
output.push(line[i]);
|
||||
}
|
||||
}
|
||||
// Is this a CyberChef hexdump or is it from a different tool?
|
||||
var width = input.indexOf("\n");
|
||||
var w = (width - 13) / 4;
|
||||
const width = input.indexOf("\n");
|
||||
const w = (width - 13) / 4;
|
||||
// w should be the specified width of the hexdump and therefore a round number
|
||||
if (Math.floor(w) !== w || input.indexOf("\r") !== -1 || output.indexOf(13) !== -1) {
|
||||
if (app) app.options.attemptHighlight = false;
|
||||
@@ -109,7 +109,7 @@ const Hexdump = {
|
||||
*/
|
||||
highlightTo: function(pos, args) {
|
||||
// Calculate overall selection
|
||||
var w = args[0] || 16,
|
||||
let w = args[0] || 16,
|
||||
width = 14 + (w*4),
|
||||
line = Math.floor(pos[0].start / w),
|
||||
offset = pos[0].start % w,
|
||||
@@ -127,8 +127,8 @@ const Hexdump = {
|
||||
pos[0].end = line*width + 10 + offset*3 - 1;
|
||||
|
||||
// Set up multiple selections for bytes
|
||||
var startLineNum = Math.floor(pos[0].start / width);
|
||||
var endLineNum = Math.floor(pos[0].end / width);
|
||||
let startLineNum = Math.floor(pos[0].start / width);
|
||||
const endLineNum = Math.floor(pos[0].end / width);
|
||||
|
||||
if (startLineNum === endLineNum) {
|
||||
pos.push(pos[0]);
|
||||
@@ -146,10 +146,10 @@ const Hexdump = {
|
||||
}
|
||||
|
||||
// Set up multiple selections for ASCII
|
||||
var len = pos.length, lineNum = 0;
|
||||
let len = pos.length, lineNum = 0;
|
||||
start = 0;
|
||||
end = 0;
|
||||
for (var i = 1; i < len; i++) {
|
||||
for (let i = 1; i < len; i++) {
|
||||
lineNum = Math.floor(pos[i].start / width);
|
||||
start = (((pos[i].start - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width);
|
||||
end = (((pos[i].end + 1 - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width);
|
||||
@@ -169,11 +169,11 @@ const Hexdump = {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightFrom: function(pos, args) {
|
||||
var w = args[0] || 16;
|
||||
var width = 14 + (w*4);
|
||||
const w = args[0] || 16;
|
||||
const width = 14 + (w*4);
|
||||
|
||||
var line = Math.floor(pos[0].start / width);
|
||||
var offset = pos[0].start % width;
|
||||
let line = Math.floor(pos[0].start / width);
|
||||
let offset = pos[0].start % width;
|
||||
|
||||
if (offset < 10) { // In line number section
|
||||
pos[0].start = line*w;
|
||||
|
||||
@@ -38,12 +38,12 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParseIpRange: function (input, args) {
|
||||
var includeNetworkInfo = args[0],
|
||||
let includeNetworkInfo = args[0],
|
||||
enumerateAddresses = args[1],
|
||||
allowLargeList = args[2];
|
||||
|
||||
// Check what type of input we are looking at
|
||||
var ipv4CidrRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\/(\d\d?)\s*$/,
|
||||
let ipv4CidrRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\/(\d\d?)\s*$/,
|
||||
ipv4RangeRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*-\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/,
|
||||
ipv6CidrRegex = /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\/(\d\d?\d?)\s*$/i,
|
||||
ipv6RangeRegex = /^\s*(((?=.*::)(?!.*::[^-]+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*-\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\17)::|:\b|(?![\dA-F])))|(?!\16\17)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i,
|
||||
@@ -82,11 +82,11 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParseIPv6: function (input, args) {
|
||||
var match,
|
||||
let match,
|
||||
output = "";
|
||||
|
||||
if ((match = IP.IPV6_REGEX.exec(input))) {
|
||||
var ipv6 = IP._strToIpv6(match[1]),
|
||||
let ipv6 = IP._strToIpv6(match[1]),
|
||||
longhand = IP._ipv6ToStr(ipv6),
|
||||
shorthand = IP._ipv6ToStr(ipv6, true);
|
||||
|
||||
@@ -126,7 +126,7 @@ const IP = {
|
||||
} else if (ipv6[0] === 0x2001 && ipv6[1] === 0) {
|
||||
// Teredo tunneling
|
||||
output += "\nTeredo tunneling IPv6 address detected\n";
|
||||
var serverIpv4 = (ipv6[2] << 16) + ipv6[3],
|
||||
let serverIpv4 = (ipv6[2] << 16) + ipv6[3],
|
||||
udpPort = (~ipv6[5]) & 0xffff,
|
||||
clientIpv4 = ~((ipv6[6] << 16) + ipv6[7]),
|
||||
flagCone = (ipv6[4] >>> 15) & 1,
|
||||
@@ -190,7 +190,7 @@ const IP = {
|
||||
output += "\n6to4 transition IPv6 address detected. See RFC 3056 for more details." +
|
||||
"\n6to4 prefix range: 2002::/16";
|
||||
|
||||
var v4Addr = IP._ipv4ToStr((ipv6[1] << 16) + ipv6[2]),
|
||||
let v4Addr = IP._ipv4ToStr((ipv6[1] << 16) + ipv6[2]),
|
||||
slaId = ipv6[3],
|
||||
interfaceIdStr = ipv6[4].toString(16) + ipv6[5].toString(16) + ipv6[6].toString(16) + ipv6[7].toString(16),
|
||||
interfaceId = new BigInteger(interfaceIdStr, 16);
|
||||
@@ -218,7 +218,7 @@ const IP = {
|
||||
if ((ipv6[5] & 0xff === 0xff) && (ipv6[6] >>> 8 === 0xfe)) {
|
||||
output += "\n\nThis IPv6 address contains a modified EUI-64 address, identified by the presence of FF:FE in the 12th and 13th octets.";
|
||||
|
||||
var intIdent = Utils.hex(ipv6[4] >>> 8) + ":" + Utils.hex(ipv6[4] & 0xff) + ":" +
|
||||
let intIdent = Utils.hex(ipv6[4] >>> 8) + ":" + Utils.hex(ipv6[4] & 0xff) + ":" +
|
||||
Utils.hex(ipv6[5] >>> 8) + ":" + Utils.hex(ipv6[5] & 0xff) + ":" +
|
||||
Utils.hex(ipv6[6] >>> 8) + ":" + Utils.hex(ipv6[6] & 0xff) + ":" +
|
||||
Utils.hex(ipv6[7] >>> 8) + ":" + Utils.hex(ipv6[7] & 0xff),
|
||||
@@ -249,16 +249,18 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runChangeIpFormat: function(input, args) {
|
||||
var inFormat = args[0],
|
||||
let inFormat = args[0],
|
||||
outFormat = args[1],
|
||||
lines = input.split("\n"),
|
||||
output = "",
|
||||
j = 0;
|
||||
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i] === "") continue;
|
||||
var baIp = [];
|
||||
let baIp = [];
|
||||
let octets;
|
||||
let decimal;
|
||||
|
||||
if (inFormat === outFormat) {
|
||||
output += lines[i] + "\n";
|
||||
@@ -268,13 +270,13 @@ const IP = {
|
||||
// Convert to byte array IP from input format
|
||||
switch (inFormat) {
|
||||
case "Dotted Decimal":
|
||||
var octets = lines[i].split(".");
|
||||
octets = lines[i].split(".");
|
||||
for (j = 0; j < octets.length; j++) {
|
||||
baIp.push(parseInt(octets[j], 10));
|
||||
}
|
||||
break;
|
||||
case "Decimal":
|
||||
var decimal = lines[i].toString();
|
||||
decimal = lines[i].toString();
|
||||
baIp.push(decimal >> 24 & 255);
|
||||
baIp.push(decimal >> 16 & 255);
|
||||
baIp.push(decimal >> 8 & 255);
|
||||
@@ -287,21 +289,25 @@ const IP = {
|
||||
throw "Unsupported input IP format";
|
||||
}
|
||||
|
||||
let ddIp;
|
||||
let decIp;
|
||||
let hexIp;
|
||||
|
||||
// Convert byte array IP to output format
|
||||
switch (outFormat) {
|
||||
case "Dotted Decimal":
|
||||
var ddIp = "";
|
||||
ddIp = "";
|
||||
for (j = 0; j < baIp.length; j++) {
|
||||
ddIp += baIp[j] + ".";
|
||||
}
|
||||
output += ddIp.slice(0, ddIp.length-1) + "\n";
|
||||
break;
|
||||
case "Decimal":
|
||||
var decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0;
|
||||
decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0;
|
||||
output += decIp.toString() + "\n";
|
||||
break;
|
||||
case "Hex":
|
||||
var hexIp = "";
|
||||
hexIp = "";
|
||||
for (j = 0; j < baIp.length; j++) {
|
||||
hexIp += Utils.hex(baIp[j]);
|
||||
}
|
||||
@@ -340,7 +346,7 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runGroupIps: function(input, args) {
|
||||
var delim = Utils.charRep[args[0]],
|
||||
let delim = Utils.charRep[args[0]],
|
||||
cidr = args[1],
|
||||
onlySubnets = args[2],
|
||||
ipv4Mask = cidr < 32 ? ~(0xFFFFFFFF >>> cidr) : 0xFFFFFFFF,
|
||||
@@ -352,14 +358,15 @@ const IP = {
|
||||
output = "",
|
||||
ip = null,
|
||||
network = null,
|
||||
networkStr = "";
|
||||
networkStr = "",
|
||||
i;
|
||||
|
||||
if (cidr < 0 || cidr > 127) {
|
||||
return "CIDR must be less than 32 for IPv4 or 128 for IPv6";
|
||||
}
|
||||
|
||||
// Parse all IPs and add to network dictionary
|
||||
for (var i = 0; i < ips.length; i++) {
|
||||
for (i = 0; i < ips.length; i++) {
|
||||
if ((match = IP.IPV4_REGEX.exec(ips[i]))) {
|
||||
ip = IP._strToIpv4(match[1]) >>> 0;
|
||||
network = ip & ipv4Mask;
|
||||
@@ -374,7 +381,7 @@ const IP = {
|
||||
network = [];
|
||||
networkStr = "";
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
network.push(ip[j] & ipv6Mask[j]);
|
||||
}
|
||||
|
||||
@@ -434,7 +441,7 @@ const IP = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runParseIPv4Header: function(input, args) {
|
||||
var format = args[0],
|
||||
let format = args[0],
|
||||
output;
|
||||
|
||||
if (format === "Hex") {
|
||||
@@ -445,7 +452,7 @@ const IP = {
|
||||
return "Unrecognised input format.";
|
||||
}
|
||||
|
||||
var version = (input[0] >>> 4) & 0x0f,
|
||||
let version = (input[0] >>> 4) & 0x0f,
|
||||
ihl = input[0] & 0x0f,
|
||||
dscp = (input[1] >>> 2) & 0x3f,
|
||||
ecn = input[1] & 0x03,
|
||||
@@ -471,15 +478,15 @@ const IP = {
|
||||
ihl = ihl + " (Error: this should always be at least 5)";
|
||||
} else if (ihl > 5) {
|
||||
// sort out options...
|
||||
var optionsLen = ihl * 4 - 20;
|
||||
const optionsLen = ihl * 4 - 20;
|
||||
options = input.slice(20, optionsLen + 20);
|
||||
}
|
||||
|
||||
// Protocol
|
||||
var protocolInfo = IP._protocolLookup[protocol] || {keyword: "", protocol: ""};
|
||||
const protocolInfo = IP._protocolLookup[protocol] || {keyword: "", protocol: ""};
|
||||
|
||||
// Checksum
|
||||
var correctChecksum = Checksum.runTCPIP(checksumHeader, []),
|
||||
let correctChecksum = Checksum.runTCPIP(checksumHeader, []),
|
||||
givenChecksum = Utils.hex(checksum),
|
||||
checksumResult;
|
||||
if (correctChecksum === givenChecksum) {
|
||||
@@ -534,7 +541,7 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_ipv4CidrRange: function(cidr, includeNetworkInfo, enumerateAddresses, allowLargeList) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
network = IP._strToIpv4(cidr[1]),
|
||||
cidrRange = parseInt(cidr[2], 10);
|
||||
|
||||
@@ -542,7 +549,7 @@ const IP = {
|
||||
return "IPv4 CIDR must be less than 32";
|
||||
}
|
||||
|
||||
var mask = ~(0xFFFFFFFF >>> cidrRange),
|
||||
let mask = ~(0xFFFFFFFF >>> cidrRange),
|
||||
ip1 = network & mask,
|
||||
ip2 = ip1 | ~mask;
|
||||
|
||||
@@ -574,7 +581,7 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_ipv6CidrRange: function(cidr, includeNetworkInfo) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
network = IP._strToIpv6(cidr[1]),
|
||||
cidrRange = parseInt(cidr[cidr.length-1], 10);
|
||||
|
||||
@@ -582,19 +589,19 @@ const IP = {
|
||||
return "IPv6 CIDR must be less than 128";
|
||||
}
|
||||
|
||||
var mask = IP._genIpv6Mask(cidrRange),
|
||||
let mask = IP._genIpv6Mask(cidrRange),
|
||||
ip1 = new Array(8),
|
||||
ip2 = new Array(8),
|
||||
totalDiff = "",
|
||||
total = new Array(128);
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
ip1[i] = network[i] & mask[i];
|
||||
ip2[i] = ip1[i] | (~mask[i] & 0x0000FFFF);
|
||||
totalDiff = (ip2[i] - ip1[i]).toString(2);
|
||||
|
||||
if (totalDiff !== "0") {
|
||||
for (var n = 0; n < totalDiff.length; n++) {
|
||||
for (let n = 0; n < totalDiff.length; n++) {
|
||||
total[i*16 + 16-(totalDiff.length-n)] = totalDiff[n];
|
||||
}
|
||||
}
|
||||
@@ -621,10 +628,10 @@ const IP = {
|
||||
* @returns {number[]}
|
||||
*/
|
||||
_genIpv6Mask: function(cidr) {
|
||||
var mask = new Array(8),
|
||||
let mask = new Array(8),
|
||||
shift;
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
if (cidr > ((i+1)*16)) {
|
||||
mask[i] = 0x0000FFFF;
|
||||
} else {
|
||||
@@ -650,12 +657,12 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_ipv4HyphenatedRange: function(range, includeNetworkInfo, enumerateAddresses, allowLargeList) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
ip1 = IP._strToIpv4(range[1]),
|
||||
ip2 = IP._strToIpv4(range[2]);
|
||||
|
||||
// Calculate mask
|
||||
var diff = ip1 ^ ip2,
|
||||
let diff = ip1 ^ ip2,
|
||||
cidr = 32,
|
||||
mask = 0;
|
||||
|
||||
@@ -666,7 +673,7 @@ const IP = {
|
||||
}
|
||||
|
||||
mask = ~mask >>> 0;
|
||||
var network = ip1 & mask,
|
||||
let network = ip1 & mask,
|
||||
subIp1 = network & mask,
|
||||
subIp2 = subIp1 | ~mask;
|
||||
|
||||
@@ -701,21 +708,18 @@ const IP = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_ipv6HyphenatedRange: function(range, includeNetworkInfo) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
ip1 = IP._strToIpv6(range[1]),
|
||||
ip2 = IP._strToIpv6(range[14]);
|
||||
|
||||
var t = "",
|
||||
total = new Array(128);
|
||||
|
||||
// Initialise total array to "0"
|
||||
for (var i = 0; i < 128; i++)
|
||||
total[i] = "0";
|
||||
let t = "",
|
||||
total = new Array(128).fill(),
|
||||
i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
t = (ip2[i] - ip1[i]).toString(2);
|
||||
if (t !== "0") {
|
||||
for (var n = 0; n < t.length; n++) {
|
||||
for (let n = 0; n < t.length; n++) {
|
||||
total[i*16 + 16-(t.length-n)] = t[n];
|
||||
}
|
||||
}
|
||||
@@ -743,7 +747,7 @@ const IP = {
|
||||
* IP._strToIpv4("10.10.0.0");
|
||||
*/
|
||||
_strToIpv4: function (ipStr) {
|
||||
var blocks = ipStr.split("."),
|
||||
let blocks = ipStr.split("."),
|
||||
numBlocks = parseBlocks(blocks),
|
||||
result = 0;
|
||||
|
||||
@@ -761,8 +765,8 @@ const IP = {
|
||||
if (blocks.length !== 4)
|
||||
throw "More than 4 blocks.";
|
||||
|
||||
var numBlocks = [];
|
||||
for (var i = 0; i < 4; i++) {
|
||||
const numBlocks = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
numBlocks[i] = parseInt(blocks[i], 10);
|
||||
if (numBlocks[i] < 0 || numBlocks[i] > 255)
|
||||
throw "Block out of range.";
|
||||
@@ -784,7 +788,7 @@ const IP = {
|
||||
* IP._ipv4ToStr(168427520);
|
||||
*/
|
||||
_ipv4ToStr: function(ipInt) {
|
||||
var blockA = (ipInt >> 24) & 255,
|
||||
let blockA = (ipInt >> 24) & 255,
|
||||
blockB = (ipInt >> 16) & 255,
|
||||
blockC = (ipInt >> 8) & 255,
|
||||
blockD = ipInt & 255;
|
||||
@@ -805,12 +809,12 @@ const IP = {
|
||||
* IP._strToIpv6("ff00::1111:2222");
|
||||
*/
|
||||
_strToIpv6: function(ipStr) {
|
||||
var blocks = ipStr.split(":"),
|
||||
let blocks = ipStr.split(":"),
|
||||
numBlocks = parseBlocks(blocks),
|
||||
j = 0,
|
||||
ipv6 = new Array(8);
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
if (isNaN(numBlocks[j])) {
|
||||
ipv6[i] = 0;
|
||||
if (i === (8-numBlocks.slice(j).length)) j++;
|
||||
@@ -827,8 +831,8 @@ const IP = {
|
||||
function parseBlocks(blocks) {
|
||||
if (blocks.length < 3 || blocks.length > 8)
|
||||
throw "Badly formatted IPv6 address.";
|
||||
var numBlocks = [];
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
const numBlocks = [];
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
numBlocks[i] = parseInt(blocks[i], 16);
|
||||
if (numBlocks[i] < 0 || numBlocks[i] > 65535)
|
||||
throw "Block out of range.";
|
||||
@@ -854,11 +858,11 @@ const IP = {
|
||||
* IP._ipv6ToStr([65280, 0, 0, 0, 0, 0, 4369, 8738], false);
|
||||
*/
|
||||
_ipv6ToStr: function(ipv6, compact) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
i = 0;
|
||||
|
||||
if (compact) {
|
||||
var start = -1,
|
||||
let start = -1,
|
||||
end = -1,
|
||||
s = 0,
|
||||
e = -1;
|
||||
@@ -908,7 +912,7 @@ const IP = {
|
||||
* IP._generateIpv4Range(1, 3);
|
||||
*/
|
||||
_generateIpv4Range: function(ip, endIp) {
|
||||
var range = [];
|
||||
const range = [];
|
||||
if (endIp >= ip) {
|
||||
for (; ip <= endIp; ip++) {
|
||||
range.push(IP._ipv4ToStr(ip));
|
||||
|
||||
124
src/core/operations/Image.js
Normal file
124
src/core/operations/Image.js
Normal file
@@ -0,0 +1,124 @@
|
||||
import * as ExifParser from "exif-parser";
|
||||
import removeEXIF from "../lib/remove-exif.js";
|
||||
import Utils from "../Utils.js";
|
||||
import FileType from "./FileType.js";
|
||||
|
||||
|
||||
/**
|
||||
* Image operations.
|
||||
*
|
||||
* @author tlwr [toby@toby.codes]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
const Image = {
|
||||
|
||||
/**
|
||||
* Extract EXIF operation.
|
||||
*
|
||||
* Extracts EXIF data from a byteArray, representing a JPG or a TIFF image.
|
||||
*
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runExtractEXIF(input, args) {
|
||||
try {
|
||||
const bytes = Uint8Array.from(input);
|
||||
const parser = ExifParser.create(bytes.buffer);
|
||||
const result = parser.parse();
|
||||
|
||||
let lines = [];
|
||||
for (let tagName in result.tags) {
|
||||
let value = result.tags[tagName];
|
||||
lines.push(`${tagName}: ${value}`);
|
||||
}
|
||||
|
||||
const numTags = lines.length;
|
||||
lines.unshift(`Found ${numTags} tags.\n`);
|
||||
return lines.join("\n");
|
||||
} catch (err) {
|
||||
throw "Could not extract EXIF data from image: " + err;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Remove EXIF operation.
|
||||
*
|
||||
* Removes EXIF data from a byteArray, representing a JPG.
|
||||
*
|
||||
* @author David Moodie [davidmoodie12@gmail.com]
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runRemoveEXIF(input, args) {
|
||||
// Do nothing if input is empty
|
||||
if (input.length === 0) return input;
|
||||
|
||||
try {
|
||||
return removeEXIF(input);
|
||||
} catch (err) {
|
||||
// Simply return input if no EXIF data is found
|
||||
if (err === "Exif not found.") return input;
|
||||
throw "Could not remove EXIF data from image: " + err;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
INPUT_FORMAT: ["Raw", "Base64", "Hex"],
|
||||
|
||||
/**
|
||||
* Render Image operation.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
runRenderImage(input, args) {
|
||||
const inputFormat = args[0];
|
||||
let dataURI = "data:";
|
||||
|
||||
if (!input.length) return "";
|
||||
|
||||
// Convert input to raw bytes
|
||||
switch (inputFormat) {
|
||||
case "Hex":
|
||||
input = Utils.fromHex(input);
|
||||
break;
|
||||
case "Base64":
|
||||
// Don't trust the Base64 entered by the user.
|
||||
// Unwrap it first, then re-encode later.
|
||||
input = Utils.fromBase64(input, null, "byteArray");
|
||||
break;
|
||||
case "Raw":
|
||||
default:
|
||||
input = Utils.strToByteArray(input);
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine file type
|
||||
const type = FileType.magicType(input);
|
||||
if (type && type.mime.indexOf("image") === 0) {
|
||||
dataURI += type.mime + ";";
|
||||
} else {
|
||||
throw "Invalid file type";
|
||||
}
|
||||
|
||||
// Add image data to URI
|
||||
dataURI += "base64," + Utils.toBase64(input);
|
||||
|
||||
return "<img src='" + dataURI + "'>";
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default Image;
|
||||
@@ -48,7 +48,7 @@ const JS = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParse: function (input, args) {
|
||||
var parseLoc = args[0],
|
||||
let parseLoc = args[0],
|
||||
parseRange = args[1],
|
||||
parseTokens = args[2],
|
||||
parseComment = args[3],
|
||||
@@ -96,7 +96,7 @@ const JS = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runBeautify: function(input, args) {
|
||||
var beautifyIndent = args[0] || JS.BEAUTIFY_INDENT,
|
||||
let beautifyIndent = args[0] || JS.BEAUTIFY_INDENT,
|
||||
quotes = args[1].toLowerCase(),
|
||||
beautifySemicolons = args[2],
|
||||
beautifyComment = args[3],
|
||||
@@ -110,7 +110,7 @@ const JS = {
|
||||
comment: true
|
||||
});
|
||||
|
||||
var options = {
|
||||
const options = {
|
||||
format: {
|
||||
indent: {
|
||||
style: beautifyIndent
|
||||
@@ -141,7 +141,7 @@ const JS = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runMinify: function(input, args) {
|
||||
var result = "",
|
||||
let result = "",
|
||||
AST = esprima.parse(input),
|
||||
optimisedAST = esmangle.optimize(AST, null),
|
||||
mangledAST = esmangle.mangle(optimisedAST);
|
||||
|
||||
@@ -45,7 +45,7 @@ const MAC = {
|
||||
runFormat: function(input, args) {
|
||||
if (!input) return "";
|
||||
|
||||
var outputCase = args[0],
|
||||
let outputCase = args[0],
|
||||
noDelim = args[1],
|
||||
dashDelim = args[2],
|
||||
colonDelim = args[3],
|
||||
@@ -54,7 +54,7 @@ const MAC = {
|
||||
macs = input.toLowerCase().split(/[,\s\r\n]+/);
|
||||
|
||||
macs.forEach(function(mac) {
|
||||
var cleanMac = mac.replace(/[:.-]+/g, ""),
|
||||
let cleanMac = mac.replace(/[:.-]+/g, ""),
|
||||
macHyphen = cleanMac.replace(/(.{2}(?=.))/g, "$1-"),
|
||||
macColon = cleanMac.replace(/(.{2}(?=.))/g, "$1:"),
|
||||
macCisco = cleanMac.replace(/(.{4}(?=.))/g, "$1.");
|
||||
|
||||
@@ -97,19 +97,19 @@ const MorseCode = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo: function(input, args) {
|
||||
var format = args[0].split("/");
|
||||
var dash = format[0];
|
||||
var dot = format[1];
|
||||
const format = args[0].split("/");
|
||||
const dash = format[0];
|
||||
const dot = format[1];
|
||||
|
||||
var letterDelim = Utils.charRep[args[1]];
|
||||
var wordDelim = Utils.charRep[args[2]];
|
||||
const letterDelim = Utils.charRep[args[1]];
|
||||
const wordDelim = Utils.charRep[args[2]];
|
||||
|
||||
input = input.split(/\r?\n/);
|
||||
input = Array.prototype.map.call(input, function(line) {
|
||||
var words = line.split(/ +/);
|
||||
let words = line.split(/ +/);
|
||||
words = Array.prototype.map.call(words, function(word) {
|
||||
var letters = Array.prototype.map.call(word, function(character) {
|
||||
var letter = character.toUpperCase();
|
||||
const letters = Array.prototype.map.call(word, function(character) {
|
||||
const letter = character.toUpperCase();
|
||||
if (typeof MorseCode.MORSE_TABLE[letter] == "undefined") {
|
||||
return "";
|
||||
}
|
||||
@@ -148,12 +148,12 @@ const MorseCode = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFrom: (function() {
|
||||
var reversedTable = null;
|
||||
var reverseTable = function() {
|
||||
let reversedTable = null;
|
||||
const reverseTable = function() {
|
||||
reversedTable = {};
|
||||
|
||||
for (var letter in MorseCode.MORSE_TABLE) {
|
||||
var signal = MorseCode.MORSE_TABLE[letter];
|
||||
for (const letter in MorseCode.MORSE_TABLE) {
|
||||
const signal = MorseCode.MORSE_TABLE[letter];
|
||||
reversedTable[signal] = letter;
|
||||
}
|
||||
};
|
||||
@@ -163,17 +163,17 @@ const MorseCode = {
|
||||
reverseTable();
|
||||
}
|
||||
|
||||
var letterDelim = Utils.charRep[args[0]];
|
||||
var wordDelim = Utils.charRep[args[1]];
|
||||
const letterDelim = Utils.charRep[args[0]];
|
||||
const wordDelim = Utils.charRep[args[1]];
|
||||
|
||||
input = input.replace(/-|‐|−|_|–|—|dash/ig, "<dash>"); //hyphen-minus|hyphen|minus-sign|undersore|en-dash|em-dash
|
||||
input = input.replace(/\.|·|dot/ig, "<dot>");
|
||||
|
||||
var words = input.split(wordDelim);
|
||||
let words = input.split(wordDelim);
|
||||
words = Array.prototype.map.call(words, function(word) {
|
||||
var signals = word.split(letterDelim);
|
||||
const signals = word.split(letterDelim);
|
||||
|
||||
var letters = signals.map(function(signal) {
|
||||
const letters = signals.map(function(signal) {
|
||||
return reversedTable[signal];
|
||||
});
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ const NetBIOS = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runEncodeName: function(input, args) {
|
||||
var output = [],
|
||||
let output = [],
|
||||
offset = args[0];
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
output.push((input[i] >> 4) + offset);
|
||||
output.push((input[i] & 0xf) + offset);
|
||||
}
|
||||
@@ -43,10 +43,10 @@ const NetBIOS = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runDecodeName: function(input, args) {
|
||||
var output = [],
|
||||
let output = [],
|
||||
offset = args[0];
|
||||
|
||||
for (var i = 0; i < input.length; i += 2) {
|
||||
for (let i = 0; i < input.length; i += 2) {
|
||||
output.push(((input[i] - offset) << 4) |
|
||||
((input[i + 1] - offset) & 0xf));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ const Numberwang = {
|
||||
*/
|
||||
run: function(input, args) {
|
||||
if (!input) return "Let's play Wangernumb!";
|
||||
var match = input.match(/\d+/);
|
||||
const match = input.match(/\d+/);
|
||||
if (match) {
|
||||
return match[0] + "! That's Numberwang!";
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,7 @@ const OS = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParseUnixPerms: function(input, args) {
|
||||
var perms = {
|
||||
let perms = {
|
||||
d : false, // directory
|
||||
sl : false, // symbolic link
|
||||
np : false, // named pipe
|
||||
@@ -202,7 +202,7 @@ const OS = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_permsToStr: function(perms) {
|
||||
var str = "",
|
||||
let str = "",
|
||||
type = "-";
|
||||
|
||||
if (perms.d) type = "d";
|
||||
@@ -263,7 +263,7 @@ const OS = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_permsToOctal: function(perms) {
|
||||
var d = 0,
|
||||
let d = 0,
|
||||
u = 0,
|
||||
g = 0,
|
||||
o = 0;
|
||||
|
||||
@@ -27,7 +27,7 @@ const PublicKey = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParseX509: function (input, args) {
|
||||
var cert = new r.X509(),
|
||||
let cert = new r.X509(),
|
||||
inputFormat = args[0];
|
||||
|
||||
if (!input.length) {
|
||||
@@ -56,7 +56,7 @@ const PublicKey = {
|
||||
throw "Undefined input format";
|
||||
}
|
||||
|
||||
var version = r.ASN1HEX.getDecendantHexVByNthList(cert.hex, 0, [0, 0, 0]),
|
||||
let version = r.ASN1HEX.getDecendantHexVByNthList(cert.hex, 0, [0, 0, 0]),
|
||||
sn = cert.getSerialNumberHex(),
|
||||
algorithm = r.KJUR.asn1.x509.OID.oid2name(r.KJUR.asn1.ASN1Util.oidHexToInt(r.ASN1HEX.getDecendantHexVByNthList(cert.hex, 0, [0, 2, 0]))),
|
||||
issuer = cert.getIssuerString(),
|
||||
@@ -124,15 +124,22 @@ const PublicKey = {
|
||||
}
|
||||
|
||||
// Signature fields
|
||||
if (r.ASN1HEX.dump(certSig).indexOf("SEQUENCE") === 0) { // DSA or ECDSA
|
||||
let breakoutSig = false;
|
||||
try {
|
||||
breakoutSig = r.ASN1HEX.dump(certSig).indexOf("SEQUENCE") === 0;
|
||||
} catch (err) {
|
||||
// Error processing signature, output without further breakout
|
||||
}
|
||||
|
||||
if (breakoutSig) { // DSA or ECDSA
|
||||
sigStr = " r: " + PublicKey._formatByteStr(r.ASN1HEX.getDecendantHexVByNthList(certSig, 0, [0]), 16, 18) + "\n" +
|
||||
" s: " + PublicKey._formatByteStr(r.ASN1HEX.getDecendantHexVByNthList(certSig, 0, [1]), 16, 18) + "\n";
|
||||
} else { // RSA
|
||||
} else { // RSA or unknown
|
||||
sigStr = " Signature: " + PublicKey._formatByteStr(certSig, 16, 18) + "\n";
|
||||
}
|
||||
|
||||
// Format Public Key fields
|
||||
for (var i = 0; i < pkFields.length; i++) {
|
||||
for (let i = 0; i < pkFields.length; i++) {
|
||||
pkStr += " " + pkFields[i].key + ":" +
|
||||
Utils.padLeft(
|
||||
pkFields[i].value + "\n",
|
||||
@@ -141,12 +148,12 @@ const PublicKey = {
|
||||
);
|
||||
}
|
||||
|
||||
var issuerStr = PublicKey._formatDnStr(issuer, 2),
|
||||
let issuerStr = PublicKey._formatDnStr(issuer, 2),
|
||||
nbDate = PublicKey._formatDate(notBefore),
|
||||
naDate = PublicKey._formatDate(notAfter),
|
||||
subjectStr = PublicKey._formatDnStr(subject, 2);
|
||||
|
||||
var output = "Version: " + (parseInt(version, 16) + 1) + " (0x" + version + ")\n" +
|
||||
const output = "Version: " + (parseInt(version, 16) + 1) + " (0x" + version + ")\n" +
|
||||
"Serial number: " + new r.BigInteger(sn, 16).toString() + " (0x" + sn + ")\n" +
|
||||
"Algorithm ID: " + algorithm + "\n" +
|
||||
"Validity\n" +
|
||||
@@ -245,7 +252,7 @@ const PublicKey = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runParseAsn1HexString: function(input, args) {
|
||||
var truncateLen = args[1],
|
||||
let truncateLen = args[1],
|
||||
index = args[0];
|
||||
return r.ASN1HEX.dump(input.replace(/\s/g, ""), {
|
||||
"ommitLongOctet": truncateLen
|
||||
@@ -262,14 +269,15 @@ const PublicKey = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_formatDnStr: function(dnStr, indent) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
fields = dnStr.split(",/|"),
|
||||
maxKeyLen = 0,
|
||||
key,
|
||||
value,
|
||||
i,
|
||||
str;
|
||||
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
for (i = 0; i < fields.length; i++) {
|
||||
if (!fields[i].length) continue;
|
||||
|
||||
key = fields[i].split("=")[0];
|
||||
@@ -303,10 +311,10 @@ const PublicKey = {
|
||||
_formatByteStr: function(byteStr, length, indent) {
|
||||
byteStr = Utils.toHex(Utils.fromHex(byteStr), ":");
|
||||
length = length * 3;
|
||||
var output = "";
|
||||
let output = "";
|
||||
|
||||
for (var i = 0; i < byteStr.length; i += length) {
|
||||
var str = byteStr.slice(i, i + length) + "\n";
|
||||
for (let i = 0; i < byteStr.length; i += length) {
|
||||
const str = byteStr.slice(i, i + length) + "\n";
|
||||
if (i === 0) {
|
||||
output += str;
|
||||
} else {
|
||||
@@ -347,10 +355,10 @@ export default PublicKey;
|
||||
* @returns {string}
|
||||
*/
|
||||
r.X509.hex2dn = function(hDN) {
|
||||
var s = "";
|
||||
var a = r.ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var hRDN = r.ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
|
||||
let s = "";
|
||||
const a = r.ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
const hRDN = r.ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
|
||||
s = s + ",/|" + r.X509.hex2rdn(hRDN);
|
||||
}
|
||||
return s;
|
||||
|
||||
@@ -26,7 +26,7 @@ const Punycode = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToAscii: function(input, args) {
|
||||
var idn = args[0];
|
||||
const idn = args[0];
|
||||
|
||||
if (idn) {
|
||||
return punycode.toASCII(input);
|
||||
@@ -44,7 +44,7 @@ const Punycode = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runToUnicode: function(input, args) {
|
||||
var idn = args[0];
|
||||
const idn = args[0];
|
||||
|
||||
if (idn) {
|
||||
return punycode.toUnicode(input);
|
||||
|
||||
@@ -40,7 +40,7 @@ const QuotedPrintable = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo: function (input, args) {
|
||||
var mimeEncodedStr = QuotedPrintable.mimeEncode(input);
|
||||
let mimeEncodedStr = QuotedPrintable.mimeEncode(input);
|
||||
|
||||
// fix line breaks
|
||||
mimeEncodedStr = mimeEncodedStr.replace(/\r?\n|\r/g, function() {
|
||||
@@ -61,7 +61,7 @@ const QuotedPrintable = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFrom: function (input, args) {
|
||||
var str = input.replace(/\=(?:\r?\n|$)/g, "");
|
||||
const str = input.replace(/\=(?:\r?\n|$)/g, "");
|
||||
return QuotedPrintable.mimeDecode(str);
|
||||
},
|
||||
|
||||
@@ -73,13 +73,13 @@ const QuotedPrintable = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
mimeDecode: function(str) {
|
||||
var encodedBytesCount = (str.match(/\=[\da-fA-F]{2}/g) || []).length,
|
||||
let encodedBytesCount = (str.match(/\=[\da-fA-F]{2}/g) || []).length,
|
||||
bufferLength = str.length - encodedBytesCount * 2,
|
||||
chr, hex,
|
||||
buffer = new Array(bufferLength),
|
||||
bufferPos = 0;
|
||||
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
for (let i = 0, len = str.length; i < len; i++) {
|
||||
chr = str.charAt(i);
|
||||
if (chr === "=" && (hex = str.substr(i + 1, 2)) && /[\da-fA-F]{2}/.test(hex)) {
|
||||
buffer[bufferPos++] = parseInt(hex, 16);
|
||||
@@ -100,7 +100,7 @@ const QuotedPrintable = {
|
||||
* @returns {string}
|
||||
*/
|
||||
mimeEncode: function(buffer) {
|
||||
var ranges = [
|
||||
let ranges = [
|
||||
[0x09],
|
||||
[0x0A],
|
||||
[0x0D],
|
||||
@@ -113,7 +113,7 @@ const QuotedPrintable = {
|
||||
],
|
||||
result = "";
|
||||
|
||||
for (var i = 0, len = buffer.length; i < len; i++) {
|
||||
for (let i = 0, len = buffer.length; i < len; i++) {
|
||||
if (this._checkRanges(buffer[i], ranges)) {
|
||||
result += String.fromCharCode(buffer[i]);
|
||||
continue;
|
||||
@@ -134,7 +134,7 @@ const QuotedPrintable = {
|
||||
* @returns {bolean}
|
||||
*/
|
||||
_checkRanges: function(nr, ranges) {
|
||||
for (var i = ranges.length - 1; i >= 0; i--) {
|
||||
for (let i = ranges.length - 1; i >= 0; i--) {
|
||||
if (!ranges[i].length)
|
||||
continue;
|
||||
if (ranges[i].length === 1 && nr === ranges[i][0])
|
||||
@@ -157,7 +157,7 @@ const QuotedPrintable = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_addSoftLinebreaks: function(str, encoding) {
|
||||
var lineLengthMax = 76;
|
||||
const lineLengthMax = 76;
|
||||
|
||||
encoding = (encoding || "base64").toString().toLowerCase().trim();
|
||||
|
||||
@@ -192,7 +192,7 @@ const QuotedPrintable = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_addQPSoftLinebreaks: function(mimeEncodedStr, lineLengthMax) {
|
||||
var pos = 0,
|
||||
let pos = 0,
|
||||
len = mimeEncodedStr.length,
|
||||
match, code, line,
|
||||
lineMargin = Math.floor(lineLengthMax / 3),
|
||||
|
||||
@@ -32,10 +32,10 @@ const Rotate = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
_rot: function(data, amount, algo) {
|
||||
var result = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var b = data[i];
|
||||
for (var j = 0; j < amount; j++) {
|
||||
const result = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let b = data[i];
|
||||
for (let j = 0; j < amount; j++) {
|
||||
b = algo(b);
|
||||
}
|
||||
result.push(b);
|
||||
@@ -100,7 +100,7 @@ const Rotate = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runRot13: function(input, args) {
|
||||
var amount = args[2],
|
||||
let amount = args[2],
|
||||
output = input,
|
||||
chr,
|
||||
rot13Lowercase = args[0],
|
||||
@@ -111,7 +111,7 @@ const Rotate = {
|
||||
amount = 26 - (Math.abs(amount) % 26);
|
||||
}
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
chr = input[i];
|
||||
if (rot13Upperacse && chr >= 65 && chr <= 90) { // Upper case
|
||||
chr = (chr - 65 + amount) % 26;
|
||||
@@ -141,7 +141,7 @@ const Rotate = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runRot47: function(input, args) {
|
||||
var amount = args[0],
|
||||
let amount = args[0],
|
||||
output = input,
|
||||
chr;
|
||||
|
||||
@@ -150,7 +150,7 @@ const Rotate = {
|
||||
amount = 94 - (Math.abs(amount) % 94);
|
||||
}
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
chr = input[i];
|
||||
if (chr >= 33 && chr <= 126) {
|
||||
chr = (chr - 33 + amount) % 94;
|
||||
@@ -170,7 +170,7 @@ const Rotate = {
|
||||
* @returns {byte}
|
||||
*/
|
||||
_rotr: function(b) {
|
||||
var bit = (b & 1) << 7;
|
||||
const bit = (b & 1) << 7;
|
||||
return (b >> 1) | bit;
|
||||
},
|
||||
|
||||
@@ -183,7 +183,7 @@ const Rotate = {
|
||||
* @returns {byte}
|
||||
*/
|
||||
_rotl: function(b) {
|
||||
var bit = (b >> 7) & 1;
|
||||
const bit = (b >> 7) & 1;
|
||||
return ((b << 1) | bit) & 0xFF;
|
||||
},
|
||||
|
||||
@@ -198,13 +198,13 @@ const Rotate = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
_rotrWhole: function(data, amount) {
|
||||
var carryBits = 0,
|
||||
let carryBits = 0,
|
||||
newByte,
|
||||
result = [];
|
||||
|
||||
amount = amount % 8;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var oldByte = data[i] >>> 0;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const oldByte = data[i] >>> 0;
|
||||
newByte = (oldByte >> amount) | carryBits;
|
||||
carryBits = (oldByte & (Math.pow(2, amount)-1)) << (8-amount);
|
||||
result.push(newByte);
|
||||
@@ -224,13 +224,13 @@ const Rotate = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
_rotlWhole: function(data, amount) {
|
||||
var carryBits = 0,
|
||||
let carryBits = 0,
|
||||
newByte,
|
||||
result = [];
|
||||
|
||||
amount = amount % 8;
|
||||
for (var i = data.length-1; i >= 0; i--) {
|
||||
var oldByte = data[i];
|
||||
for (let i = data.length-1; i >= 0; i--) {
|
||||
const oldByte = data[i];
|
||||
newByte = ((oldByte << amount) | carryBits) & 0xFF;
|
||||
carryBits = (oldByte >> (8-amount)) & (Math.pow(2, amount)-1);
|
||||
result[i] = (newByte);
|
||||
|
||||
@@ -26,7 +26,7 @@ const SeqUtils = {
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address"],
|
||||
SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"],
|
||||
|
||||
/**
|
||||
* Sort operation.
|
||||
@@ -36,7 +36,7 @@ const SeqUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runSort: function (input, args) {
|
||||
var delim = Utils.charRep[args[0]],
|
||||
let delim = Utils.charRep[args[0]],
|
||||
sortReverse = args[1],
|
||||
order = args[2],
|
||||
sorted = input.split(delim);
|
||||
@@ -47,6 +47,8 @@ const SeqUtils = {
|
||||
sorted = sorted.sort(SeqUtils._caseInsensitiveSort);
|
||||
} else if (order === "IP address") {
|
||||
sorted = sorted.sort(SeqUtils._ipSort);
|
||||
} else if (order === "Numeric") {
|
||||
sorted = sorted.sort(SeqUtils._numericSort);
|
||||
}
|
||||
|
||||
if (sortReverse) sorted.reverse();
|
||||
@@ -62,7 +64,7 @@ const SeqUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runUnique: function (input, args) {
|
||||
var delim = Utils.charRep[args[0]];
|
||||
const delim = Utils.charRep[args[0]];
|
||||
return input.split(delim).unique().join(delim);
|
||||
},
|
||||
|
||||
@@ -81,12 +83,12 @@ const SeqUtils = {
|
||||
* @returns {number}
|
||||
*/
|
||||
runCount: function(input, args) {
|
||||
var search = args[0].string,
|
||||
let search = args[0].string,
|
||||
type = args[0].option;
|
||||
|
||||
if (type === "Regex" && search) {
|
||||
try {
|
||||
var regex = new RegExp(search, "gi"),
|
||||
let regex = new RegExp(search, "gi"),
|
||||
matches = input.match(regex);
|
||||
return matches.length;
|
||||
} catch (err) {
|
||||
@@ -117,11 +119,12 @@ const SeqUtils = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runReverse: function (input, args) {
|
||||
let i;
|
||||
if (args[0] === "Line") {
|
||||
var lines = [],
|
||||
let lines = [],
|
||||
line = [],
|
||||
result = [];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (i = 0; i < input.length; i++) {
|
||||
if (input[i] === 0x0a) {
|
||||
lines.push(line);
|
||||
line = [];
|
||||
@@ -150,11 +153,11 @@ const SeqUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runAddLineNumbers: function(input, args) {
|
||||
var lines = input.split("\n"),
|
||||
let lines = input.split("\n"),
|
||||
output = "",
|
||||
width = lines.length.toString().length;
|
||||
|
||||
for (var n = 0; n < lines.length; n++) {
|
||||
for (let n = 0; n < lines.length; n++) {
|
||||
output += Utils.pad((n+1).toString(), width, " ") + " " + lines[n] + "\n";
|
||||
}
|
||||
return output.slice(0, output.length-1);
|
||||
@@ -207,7 +210,7 @@ const SeqUtils = {
|
||||
* @returns {number}
|
||||
*/
|
||||
_ipSort: function(a, b) {
|
||||
var a_ = a.split("."),
|
||||
let a_ = a.split("."),
|
||||
b_ = b.split(".");
|
||||
|
||||
a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1;
|
||||
@@ -220,6 +223,35 @@ const SeqUtils = {
|
||||
return a_ - b_;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Comparison operation for sorting of numeric values.
|
||||
*
|
||||
* @author Chris van Marle
|
||||
* @private
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @returns {number}
|
||||
*/
|
||||
_numericSort: function _numericSort(a, b) {
|
||||
let a_ = a.split(/([^\d]+)/),
|
||||
b_ = b.split(/([^\d]+)/);
|
||||
|
||||
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
||||
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
||||
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
||||
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
||||
let ret = a_[i].localeCompare(b_[i]); // Compare strings
|
||||
if (ret !== 0) return ret;
|
||||
}
|
||||
if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers
|
||||
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default SeqUtils;
|
||||
|
||||
@@ -100,7 +100,7 @@ const StrUtils = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runRegex: function(input, args) {
|
||||
var userRegex = args[1],
|
||||
let userRegex = args[1],
|
||||
i = args[2],
|
||||
m = args[3],
|
||||
displayTotal = args[4],
|
||||
@@ -112,7 +112,7 @@ const StrUtils = {
|
||||
|
||||
if (userRegex && userRegex !== "^" && userRegex !== "$") {
|
||||
try {
|
||||
var regex = new RegExp(userRegex, modifiers);
|
||||
const regex = new RegExp(userRegex, modifiers);
|
||||
|
||||
switch (outputFormat) {
|
||||
case "Highlight matches":
|
||||
@@ -149,7 +149,7 @@ const StrUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runUpper: function (input, args) {
|
||||
var scope = args[0];
|
||||
const scope = args[0];
|
||||
|
||||
switch (scope) {
|
||||
case "Word":
|
||||
@@ -213,7 +213,7 @@ const StrUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFindReplace: function(input, args) {
|
||||
var find = args[0].string,
|
||||
let find = args[0].string,
|
||||
type = args[0].option,
|
||||
replace = args[1],
|
||||
g = args[2],
|
||||
@@ -257,7 +257,7 @@ const StrUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runSplit: function(input, args) {
|
||||
var splitDelim = args[0] || StrUtils.SPLIT_DELIM,
|
||||
let splitDelim = args[0] || StrUtils.SPLIT_DELIM,
|
||||
joinDelim = Utils.charRep[args[1]],
|
||||
sections = input.split(splitDelim);
|
||||
|
||||
@@ -274,16 +274,17 @@ const StrUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFilter: function(input, args) {
|
||||
var delim = Utils.charRep[args[0]],
|
||||
let delim = Utils.charRep[args[0]],
|
||||
regex,
|
||||
reverse = args[2];
|
||||
|
||||
try {
|
||||
var regex = new RegExp(args[1]);
|
||||
regex = new RegExp(args[1]);
|
||||
} catch (err) {
|
||||
return "Invalid regex. Details: " + err.message;
|
||||
}
|
||||
|
||||
var regexFilter = function(value) {
|
||||
const regexFilter = function(value) {
|
||||
return reverse ^ regex.test(value);
|
||||
};
|
||||
|
||||
@@ -310,7 +311,7 @@ const StrUtils = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runDiff: function(input, args) {
|
||||
var sampleDelim = args[0],
|
||||
let sampleDelim = args[0],
|
||||
diffBy = args[1],
|
||||
showAdded = args[2],
|
||||
showRemoved = args[3],
|
||||
@@ -354,7 +355,7 @@ const StrUtils = {
|
||||
return "Invalid 'Diff by' option.";
|
||||
}
|
||||
|
||||
for (var i = 0; i < diff.length; i++) {
|
||||
for (let i = 0; i < diff.length; i++) {
|
||||
if (diff[i].added) {
|
||||
if (showAdded) output += "<span class='hlgreen'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
||||
} else if (diff[i].removed) {
|
||||
@@ -382,9 +383,9 @@ const StrUtils = {
|
||||
* @returns {html}
|
||||
*/
|
||||
runOffsetChecker: function(input, args) {
|
||||
var sampleDelim = args[0],
|
||||
let sampleDelim = args[0],
|
||||
samples = input.split(sampleDelim),
|
||||
outputs = [],
|
||||
outputs = new Array(samples.length),
|
||||
i = 0,
|
||||
s = 0,
|
||||
match = false,
|
||||
@@ -396,9 +397,7 @@ const StrUtils = {
|
||||
}
|
||||
|
||||
// Initialise output strings
|
||||
for (s = 0; s < samples.length; s++) {
|
||||
outputs[s] = "";
|
||||
}
|
||||
outputs.fill("", 0, samples.length);
|
||||
|
||||
// Loop through each character in the first sample
|
||||
for (i = 0; i < samples[0].length; i++) {
|
||||
@@ -472,7 +471,7 @@ const StrUtils = {
|
||||
number = args[1];
|
||||
|
||||
delimiter = Utils.charRep[delimiter];
|
||||
let splitInput = input.split(delimiter);
|
||||
const splitInput = input.split(delimiter);
|
||||
|
||||
return splitInput
|
||||
.filter((line, lineIndex) => {
|
||||
@@ -500,7 +499,7 @@ const StrUtils = {
|
||||
number = args[1];
|
||||
|
||||
delimiter = Utils.charRep[delimiter];
|
||||
let splitInput = input.split(delimiter);
|
||||
const splitInput = input.split(delimiter);
|
||||
|
||||
return splitInput
|
||||
.filter((line, lineIndex) => {
|
||||
@@ -526,7 +525,7 @@ const StrUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_regexHighlight: function(input, regex, displayTotal) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
m,
|
||||
hl = 1,
|
||||
i = 0,
|
||||
@@ -568,7 +567,7 @@ const StrUtils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_regexList: function(input, regex, displayTotal, matches, captureGroups) {
|
||||
var output = "",
|
||||
let output = "",
|
||||
total = 0,
|
||||
match;
|
||||
|
||||
@@ -578,7 +577,7 @@ const StrUtils = {
|
||||
output += match[0] + "\n";
|
||||
}
|
||||
if (captureGroups) {
|
||||
for (var i = 1; i < match.length; i++) {
|
||||
for (let i = 1; i < match.length; i++) {
|
||||
if (matches) {
|
||||
output += " Group " + i + ": ";
|
||||
}
|
||||
@@ -592,7 +591,6 @@ const StrUtils = {
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default StrUtils;
|
||||
|
||||
@@ -51,7 +51,7 @@ const Tidy = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runRemoveWhitespace: function (input, args) {
|
||||
var removeSpaces = args[0],
|
||||
let removeSpaces = args[0],
|
||||
removeCariageReturns = args[1],
|
||||
removeLineFeeds = args[2],
|
||||
removeTabs = args[3],
|
||||
@@ -77,8 +77,8 @@ const Tidy = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runRemoveNulls: function (input, args) {
|
||||
var output = [];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
const output = [];
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (input[i] !== 0) output.push(input[i]);
|
||||
}
|
||||
return output;
|
||||
@@ -109,7 +109,7 @@ const Tidy = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runDropBytes: function(input, args) {
|
||||
var start = args[0],
|
||||
let start = args[0],
|
||||
length = args[1],
|
||||
applyToEachLine = args[2];
|
||||
|
||||
@@ -120,10 +120,11 @@ const Tidy = {
|
||||
return input.slice(0, start).concat(input.slice(start+length, input.length));
|
||||
|
||||
// Split input into lines
|
||||
var lines = [],
|
||||
line = [];
|
||||
let lines = [],
|
||||
line = [],
|
||||
i;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (i = 0; i < input.length; i++) {
|
||||
if (input[i] === 0x0a) {
|
||||
lines.push(line);
|
||||
line = [];
|
||||
@@ -133,7 +134,7 @@ const Tidy = {
|
||||
}
|
||||
lines.push(line);
|
||||
|
||||
var output = [];
|
||||
let output = [];
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length)));
|
||||
output.push(0x0a);
|
||||
@@ -161,7 +162,7 @@ const Tidy = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runTakeBytes: function(input, args) {
|
||||
var start = args[0],
|
||||
let start = args[0],
|
||||
length = args[1],
|
||||
applyToEachLine = args[2];
|
||||
|
||||
@@ -172,10 +173,11 @@ const Tidy = {
|
||||
return input.slice(start, start+length);
|
||||
|
||||
// Split input into lines
|
||||
var lines = [],
|
||||
let lines = [],
|
||||
line = [];
|
||||
let i;
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (i = 0; i < input.length; i++) {
|
||||
if (input[i] === 0x0a) {
|
||||
lines.push(line);
|
||||
line = [];
|
||||
@@ -185,7 +187,7 @@ const Tidy = {
|
||||
}
|
||||
lines.push(line);
|
||||
|
||||
var output = [];
|
||||
let output = [];
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
output = output.concat(lines[i].slice(start, start+length));
|
||||
output.push(0x0a);
|
||||
@@ -218,7 +220,7 @@ const Tidy = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runPad: function(input, args) {
|
||||
var position = args[0],
|
||||
let position = args[0],
|
||||
len = args[1],
|
||||
chr = args[2],
|
||||
lines = input.split("\n"),
|
||||
|
||||
@@ -28,7 +28,7 @@ const URL_ = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo: function(input, args) {
|
||||
var encodeAll = args[0];
|
||||
const encodeAll = args[0];
|
||||
return encodeAll ? URL_._encodeAllChars(input) : encodeURI(input);
|
||||
},
|
||||
|
||||
@@ -41,7 +41,7 @@ const URL_ = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runFrom: function(input, args) {
|
||||
var data = input.replace(/\+/g, "%20");
|
||||
const data = input.replace(/\+/g, "%20");
|
||||
try {
|
||||
return decodeURIComponent(data);
|
||||
} catch (err) {
|
||||
@@ -62,14 +62,14 @@ const URL_ = {
|
||||
throw "This operation only works in a browser.";
|
||||
}
|
||||
|
||||
var a = document.createElement("a");
|
||||
const a = document.createElement("a");
|
||||
|
||||
// Overwrite base href which will be the current CyberChef URL to reduce confusion.
|
||||
a.href = "http://example.com/";
|
||||
a.href = input;
|
||||
|
||||
if (a.protocol) {
|
||||
var output = "";
|
||||
let output = "";
|
||||
if (a.hostname !== window.location.hostname) {
|
||||
output = "Protocol:\t" + a.protocol + "\n";
|
||||
if (a.hostname) output += "Hostname:\t" + a.hostname + "\n";
|
||||
@@ -77,7 +77,7 @@ const URL_ = {
|
||||
}
|
||||
|
||||
if (a.pathname && a.pathname !== window.location.pathname) {
|
||||
var pathname = a.pathname;
|
||||
let pathname = a.pathname;
|
||||
if (pathname.indexOf(window.location.pathname) === 0)
|
||||
pathname = pathname.replace(window.location.pathname, "");
|
||||
if (pathname)
|
||||
@@ -90,9 +90,9 @@ const URL_ = {
|
||||
|
||||
if (a.search && a.search !== window.location.search) {
|
||||
output += "Arguments:\n";
|
||||
var args_ = (a.search.slice(1, a.search.length)).split("&");
|
||||
var splitArgs = [], padding = 0;
|
||||
for (var i = 0; i < args_.length; i++) {
|
||||
const args_ = (a.search.slice(1, a.search.length)).split("&");
|
||||
let splitArgs = [], padding = 0, i;
|
||||
for (i = 0; i < args_.length; i++) {
|
||||
splitArgs.push(args_[i].split("="));
|
||||
padding = (splitArgs[i][0].length > padding) ? splitArgs[i][0].length : padding;
|
||||
}
|
||||
|
||||
@@ -18,18 +18,18 @@ const UUID = {
|
||||
*/
|
||||
runGenerateV4: function(input, args) {
|
||||
if (window && typeof(window.crypto) !== "undefined" && typeof(window.crypto.getRandomValues) !== "undefined") {
|
||||
var buf = new Uint32Array(4),
|
||||
let buf = new Uint32Array(4),
|
||||
i = 0;
|
||||
window.crypto.getRandomValues(buf);
|
||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
||||
var r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf,
|
||||
let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf,
|
||||
v = c === "x" ? r : (r & 0x3 | 0x8);
|
||||
i++;
|
||||
return v.toString(16);
|
||||
});
|
||||
} else {
|
||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
||||
var r = Math.random() * 16 | 0,
|
||||
let r = Math.random() * 16 | 0,
|
||||
v = c === "x" ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ const Unicode = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runUnescape: function(input, args) {
|
||||
var prefix = Unicode._prefixToRegex[args[0]],
|
||||
let prefix = Unicode._prefixToRegex[args[0]],
|
||||
regex = new RegExp(prefix+"([a-f\\d]{4,6})", "ig"),
|
||||
output = "",
|
||||
m,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
require("babel-polyfill");
|
||||
|
||||
var Chef = require("../core/Chef.js").default;
|
||||
const Chef = require("../core/Chef.js").default;
|
||||
|
||||
const CyberChef = module.exports = {
|
||||
|
||||
|
||||
130
src/web/App.js
130
src/web/App.js
@@ -20,7 +20,7 @@ import Split from "split.js";
|
||||
* @param {String[]} defaultFavourites - A list of default favourite operations.
|
||||
* @param {Object} options - Default setting for app options.
|
||||
*/
|
||||
var App = function(categories, operations, defaultFavourites, defaultOptions) {
|
||||
const App = function(categories, operations, defaultFavourites, defaultOptions) {
|
||||
this.categories = categories;
|
||||
this.operations = operations;
|
||||
this.dfavourites = defaultFavourites;
|
||||
@@ -30,6 +30,7 @@ var App = function(categories, operations, defaultFavourites, defaultOptions) {
|
||||
this.chef = new Chef();
|
||||
this.manager = new Manager(this);
|
||||
|
||||
this.baking = false;
|
||||
this.autoBake_ = false;
|
||||
this.progress = 0;
|
||||
this.ingId = 0;
|
||||
@@ -52,6 +53,26 @@ App.prototype.setup = function() {
|
||||
this.resetLayout();
|
||||
this.setCompileMessage();
|
||||
this.loadURIParams();
|
||||
this.loaded();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires once all setup activities have completed.
|
||||
*/
|
||||
App.prototype.loaded = function() {
|
||||
// Trigger CSS animations to remove preloader
|
||||
document.body.classList.add("loaded");
|
||||
|
||||
// Wait for animations to complete then remove the preloader and loaded style
|
||||
// so that the animations for existing elements don't play again.
|
||||
setTimeout(function() {
|
||||
document.getElementById("loader-wrapper").remove();
|
||||
document.body.classList.remove("loaded");
|
||||
}, 1000);
|
||||
|
||||
// Clear the loading message interval
|
||||
clearInterval(window.loadingMsgInt);
|
||||
};
|
||||
|
||||
|
||||
@@ -62,24 +83,54 @@ App.prototype.setup = function() {
|
||||
*/
|
||||
App.prototype.handleError = function(err) {
|
||||
console.error(err);
|
||||
var msg = err.displayStr || err.toString();
|
||||
const msg = err.displayStr || err.toString();
|
||||
this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the UI to show if baking is in process or not.
|
||||
*
|
||||
* @param {bakingStatus}
|
||||
*/
|
||||
App.prototype.setBakingStatus = function(bakingStatus) {
|
||||
this.baking = bakingStatus;
|
||||
|
||||
let inputLoadingIcon = document.querySelector("#input .title .loading-icon"),
|
||||
outputLoadingIcon = document.querySelector("#output .title .loading-icon"),
|
||||
outputElement = document.querySelector("#output-text");
|
||||
|
||||
if (bakingStatus) {
|
||||
inputLoadingIcon.style.display = "inline-block";
|
||||
outputLoadingIcon.style.display = "inline-block";
|
||||
outputElement.classList.add("disabled");
|
||||
outputElement.disabled = true;
|
||||
} else {
|
||||
inputLoadingIcon.style.display = "none";
|
||||
outputLoadingIcon.style.display = "none";
|
||||
outputElement.classList.remove("disabled");
|
||||
outputElement.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the Chef to bake the current input using the current recipe.
|
||||
*
|
||||
* @param {boolean} [step] - Set to true if we should only execute one operation instead of the
|
||||
* whole recipe.
|
||||
*/
|
||||
App.prototype.bake = function(step) {
|
||||
var response;
|
||||
App.prototype.bake = async function(step) {
|
||||
let response;
|
||||
|
||||
if (this.baking) return;
|
||||
|
||||
this.setBakingStatus(true);
|
||||
|
||||
try {
|
||||
response = this.chef.bake(
|
||||
this.getInput(), // The user's input
|
||||
this.getRecipeConfig(), // The configuration of the recipe
|
||||
response = await this.chef.bake(
|
||||
this.getInput(), // The user's input
|
||||
this.getRecipeConfig(), // The configuration of the recipe
|
||||
this.options, // Options set by the user
|
||||
this.progress, // The current position in the recipe
|
||||
step // Whether or not to take one step or execute the whole recipe
|
||||
@@ -88,6 +139,8 @@ App.prototype.bake = function(step) {
|
||||
this.handleError(err);
|
||||
}
|
||||
|
||||
this.setBakingStatus(false);
|
||||
|
||||
if (!response) return;
|
||||
|
||||
if (response.error) {
|
||||
@@ -129,7 +182,7 @@ App.prototype.autoBake = function() {
|
||||
* @returns {number} - The number of miliseconds it took to run the silent bake.
|
||||
*/
|
||||
App.prototype.silentBake = function() {
|
||||
var startTime = new Date().getTime(),
|
||||
let startTime = new Date().getTime(),
|
||||
recipeConfig = this.getRecipeConfig();
|
||||
|
||||
if (this.autoBake_) {
|
||||
@@ -146,7 +199,7 @@ App.prototype.silentBake = function() {
|
||||
* @returns {string}
|
||||
*/
|
||||
App.prototype.getInput = function() {
|
||||
var input = this.manager.input.get();
|
||||
const input = this.manager.input.get();
|
||||
|
||||
// Save to session storage in case we need to restore it later
|
||||
sessionStorage.setItem("inputLength", input.length);
|
||||
@@ -178,15 +231,16 @@ App.prototype.populateOperationsList = function() {
|
||||
// Move edit button away before we overwrite it
|
||||
document.body.appendChild(document.getElementById("edit-favourites"));
|
||||
|
||||
var html = "";
|
||||
let html = "";
|
||||
let i;
|
||||
|
||||
for (var i = 0; i < this.categories.length; i++) {
|
||||
var catConf = this.categories[i],
|
||||
for (i = 0; i < this.categories.length; i++) {
|
||||
let catConf = this.categories[i],
|
||||
selected = i === 0,
|
||||
cat = new HTMLCategory(catConf.name, selected);
|
||||
|
||||
for (var j = 0; j < catConf.ops.length; j++) {
|
||||
var opName = catConf.ops[j],
|
||||
for (let j = 0; j < catConf.ops.length; j++) {
|
||||
let opName = catConf.ops[j],
|
||||
op = new HTMLOperation(opName, this.operations[opName], this, this.manager);
|
||||
cat.addOperation(op);
|
||||
}
|
||||
@@ -196,7 +250,7 @@ App.prototype.populateOperationsList = function() {
|
||||
|
||||
document.getElementById("categories").innerHTML = html;
|
||||
|
||||
var opLists = document.querySelectorAll("#categories .op-list");
|
||||
const opLists = document.querySelectorAll("#categories .op-list");
|
||||
|
||||
for (i = 0; i < opLists.length; i++) {
|
||||
opLists[i].dispatchEvent(this.manager.oplistcreate);
|
||||
@@ -236,7 +290,7 @@ App.prototype.initialiseSplitter = function() {
|
||||
*/
|
||||
App.prototype.loadLocalStorage = function() {
|
||||
// Load options
|
||||
var lOptions;
|
||||
let lOptions;
|
||||
if (localStorage.options !== undefined) {
|
||||
lOptions = JSON.parse(localStorage.options);
|
||||
}
|
||||
@@ -253,7 +307,7 @@ App.prototype.loadLocalStorage = function() {
|
||||
* If the user currently has no saved favourites, the defaults from the view constructor are used.
|
||||
*/
|
||||
App.prototype.loadFavourites = function() {
|
||||
var favourites = localStorage.favourites &&
|
||||
let favourites = localStorage.favourites &&
|
||||
localStorage.favourites.length > 2 ?
|
||||
JSON.parse(localStorage.favourites) :
|
||||
this.dfavourites;
|
||||
@@ -261,7 +315,7 @@ App.prototype.loadFavourites = function() {
|
||||
favourites = this.validFavourites(favourites);
|
||||
this.saveFavourites(favourites);
|
||||
|
||||
var favCat = this.categories.filter(function(c) {
|
||||
const favCat = this.categories.filter(function(c) {
|
||||
return c.name === "Favourites";
|
||||
})[0];
|
||||
|
||||
@@ -284,8 +338,8 @@ App.prototype.loadFavourites = function() {
|
||||
* @returns {string[]} A list of the valid favourites
|
||||
*/
|
||||
App.prototype.validFavourites = function(favourites) {
|
||||
var validFavs = [];
|
||||
for (var i = 0; i < favourites.length; i++) {
|
||||
const validFavs = [];
|
||||
for (let i = 0; i < favourites.length; i++) {
|
||||
if (this.operations.hasOwnProperty(favourites[i])) {
|
||||
validFavs.push(favourites[i]);
|
||||
} else {
|
||||
@@ -325,7 +379,7 @@ App.prototype.resetFavourites = function() {
|
||||
* @param {string} name - The name of the operation
|
||||
*/
|
||||
App.prototype.addFavourite = function(name) {
|
||||
var favourites = JSON.parse(localStorage.favourites);
|
||||
const favourites = JSON.parse(localStorage.favourites);
|
||||
|
||||
if (favourites.indexOf(name) >= 0) {
|
||||
this.alert("'" + name + "' is already in your favourites", "info", 2000);
|
||||
@@ -347,9 +401,9 @@ App.prototype.loadURIParams = function() {
|
||||
// Load query string from URI
|
||||
this.queryString = (function(a) {
|
||||
if (a === "") return {};
|
||||
var b = {};
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var p = a[i].split("=");
|
||||
const b = {};
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
const p = a[i].split("=");
|
||||
if (p.length !== 2) {
|
||||
b[a[i]] = true;
|
||||
} else {
|
||||
@@ -360,13 +414,13 @@ App.prototype.loadURIParams = function() {
|
||||
})(window.location.search.substr(1).split("&"));
|
||||
|
||||
// Turn off auto-bake while loading
|
||||
var autoBakeVal = this.autoBake_;
|
||||
const autoBakeVal = this.autoBake_;
|
||||
this.autoBake_ = false;
|
||||
|
||||
// Read in recipe from query string
|
||||
if (this.queryString.recipe) {
|
||||
try {
|
||||
var recipeConfig = JSON.parse(this.queryString.recipe);
|
||||
const recipeConfig = JSON.parse(this.queryString.recipe);
|
||||
this.setRecipeConfig(recipeConfig);
|
||||
} catch (err) {}
|
||||
} else if (this.queryString.op) {
|
||||
@@ -376,13 +430,13 @@ App.prototype.loadURIParams = function() {
|
||||
this.manager.recipe.addOperation(this.queryString.op);
|
||||
} catch (err) {
|
||||
// If no exact match, search for nearest match and add that
|
||||
var matchedOps = this.manager.ops.filterOperations(this.queryString.op, false);
|
||||
const matchedOps = this.manager.ops.filterOperations(this.queryString.op, false);
|
||||
if (matchedOps.length) {
|
||||
this.manager.recipe.addOperation(matchedOps[0].name);
|
||||
}
|
||||
|
||||
// Populate search with the string
|
||||
var search = document.getElementById("search");
|
||||
const search = document.getElementById("search");
|
||||
|
||||
search.value = this.queryString.op;
|
||||
search.dispatchEvent(new Event("search"));
|
||||
@@ -392,7 +446,7 @@ App.prototype.loadURIParams = function() {
|
||||
// Read in input data from query string
|
||||
if (this.queryString.input) {
|
||||
try {
|
||||
var inputData = Utils.fromBase64(this.queryString.input);
|
||||
const inputData = Utils.fromBase64(this.queryString.input);
|
||||
this.setInput(inputData);
|
||||
} catch (err) {}
|
||||
}
|
||||
@@ -419,7 +473,7 @@ App.prototype.nextIngId = function() {
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
App.prototype.getRecipeConfig = function() {
|
||||
var recipeConfig = this.manager.recipe.getConfig();
|
||||
const recipeConfig = this.manager.recipe.getConfig();
|
||||
sessionStorage.setItem("recipeConfig", JSON.stringify(recipeConfig));
|
||||
return recipeConfig;
|
||||
};
|
||||
@@ -434,12 +488,12 @@ App.prototype.setRecipeConfig = function(recipeConfig) {
|
||||
sessionStorage.setItem("recipeConfig", JSON.stringify(recipeConfig));
|
||||
document.getElementById("rec-list").innerHTML = null;
|
||||
|
||||
for (var i = 0; i < recipeConfig.length; i++) {
|
||||
var item = this.manager.recipe.addOperation(recipeConfig[i].op);
|
||||
for (let i = 0; i < recipeConfig.length; i++) {
|
||||
const item = this.manager.recipe.addOperation(recipeConfig[i].op);
|
||||
|
||||
// Populate arguments
|
||||
var args = item.querySelectorAll(".arg");
|
||||
for (var j = 0; j < args.length; j++) {
|
||||
const args = item.querySelectorAll(".arg");
|
||||
for (let j = 0; j < args.length; j++) {
|
||||
if (args[j].getAttribute("type") === "checkbox") {
|
||||
// checkbox
|
||||
args[j].checked = recipeConfig[i].args[j];
|
||||
@@ -485,7 +539,7 @@ App.prototype.resetLayout = function() {
|
||||
*/
|
||||
App.prototype.setCompileMessage = function() {
|
||||
// Display time since last build and compile message
|
||||
var now = new Date(),
|
||||
let now = new Date(),
|
||||
timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime),
|
||||
compileInfo = "<span style=\"font-weight: normal\">Last build: " +
|
||||
timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1) + " ago";
|
||||
@@ -523,7 +577,7 @@ App.prototype.setCompileMessage = function() {
|
||||
* this.alert("Happy Christmas!", "info", 5000);
|
||||
*/
|
||||
App.prototype.alert = function(str, style, timeout, silent) {
|
||||
var time = new Date();
|
||||
const time = new Date();
|
||||
|
||||
console.log("[" + time.toLocaleString() + "] " + str);
|
||||
if (silent) return;
|
||||
@@ -531,7 +585,7 @@ App.prototype.alert = function(str, style, timeout, silent) {
|
||||
style = style || "danger";
|
||||
timeout = timeout || 0;
|
||||
|
||||
var alertEl = document.getElementById("alert"),
|
||||
let alertEl = document.getElementById("alert"),
|
||||
alertContent = document.getElementById("alert-content");
|
||||
|
||||
alertEl.classList.remove("alert-danger");
|
||||
@@ -649,7 +703,7 @@ App.prototype.callApi = function(url, type, data, dataType, contentType) {
|
||||
dataType = dataType || undefined;
|
||||
contentType = contentType || "application/json";
|
||||
|
||||
var response = null,
|
||||
let response = null,
|
||||
success = false;
|
||||
|
||||
$.ajax({
|
||||
|
||||
@@ -12,7 +12,7 @@ import Utils from "../core/Utils.js";
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var ControlsWaiter = function(app, manager) {
|
||||
const ControlsWaiter = function(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
};
|
||||
@@ -23,14 +23,14 @@ var ControlsWaiter = function(app, manager) {
|
||||
* without wrapping or overflowing.
|
||||
*/
|
||||
ControlsWaiter.prototype.adjustWidth = function() {
|
||||
var controls = document.getElementById("controls"),
|
||||
step = document.getElementById("step"),
|
||||
clrBreaks = document.getElementById("clr-breaks"),
|
||||
saveImg = document.querySelector("#save img"),
|
||||
loadImg = document.querySelector("#load img"),
|
||||
stepImg = document.querySelector("#step img"),
|
||||
clrRecipImg = document.querySelector("#clr-recipe img"),
|
||||
clrBreaksImg = document.querySelector("#clr-breaks img");
|
||||
const controls = document.getElementById("controls");
|
||||
const step = document.getElementById("step");
|
||||
const clrBreaks = document.getElementById("clr-breaks");
|
||||
const saveImg = document.querySelector("#save img");
|
||||
const loadImg = document.querySelector("#load img");
|
||||
const stepImg = document.querySelector("#step img");
|
||||
const clrRecipImg = document.querySelector("#clr-recipe img");
|
||||
const clrBreaksImg = document.querySelector("#clr-breaks img");
|
||||
|
||||
if (controls.clientWidth < 470) {
|
||||
step.childNodes[1].nodeValue = " Step";
|
||||
@@ -66,7 +66,7 @@ ControlsWaiter.prototype.adjustWidth = function() {
|
||||
* @param {boolean} value - The new value for Auto Bake.
|
||||
*/
|
||||
ControlsWaiter.prototype.setAutoBake = function(value) {
|
||||
var autoBakeCheckbox = document.getElementById("auto-bake");
|
||||
const autoBakeCheckbox = document.getElementById("auto-bake");
|
||||
|
||||
if (autoBakeCheckbox.checked !== value) {
|
||||
autoBakeCheckbox.click();
|
||||
@@ -79,7 +79,7 @@ ControlsWaiter.prototype.setAutoBake = function(value) {
|
||||
*/
|
||||
ControlsWaiter.prototype.bakeClick = function() {
|
||||
this.app.bake();
|
||||
var outputText = document.getElementById("output-text");
|
||||
const outputText = document.getElementById("output-text");
|
||||
outputText.focus();
|
||||
outputText.setSelectionRange(0, 0);
|
||||
};
|
||||
@@ -90,7 +90,7 @@ ControlsWaiter.prototype.bakeClick = function() {
|
||||
*/
|
||||
ControlsWaiter.prototype.stepClick = function() {
|
||||
this.app.bake(true);
|
||||
var outputText = document.getElementById("output-text");
|
||||
const outputText = document.getElementById("output-text");
|
||||
outputText.focus();
|
||||
outputText.setSelectionRange(0, 0);
|
||||
};
|
||||
@@ -100,17 +100,17 @@ ControlsWaiter.prototype.stepClick = function() {
|
||||
* Handler for changes made to the Auto Bake checkbox.
|
||||
*/
|
||||
ControlsWaiter.prototype.autoBakeChange = function() {
|
||||
var autoBakeLabel = document.getElementById("auto-bake-label"),
|
||||
autoBakeCheckbox = document.getElementById("auto-bake");
|
||||
const autoBakeLabel = document.getElementById("auto-bake-label");
|
||||
const autoBakeCheckbox = document.getElementById("auto-bake");
|
||||
|
||||
this.app.autoBake_ = autoBakeCheckbox.checked;
|
||||
|
||||
if (autoBakeCheckbox.checked) {
|
||||
autoBakeLabel.classList.remove("btn-default");
|
||||
autoBakeLabel.classList.add("btn-success");
|
||||
autoBakeLabel.classList.remove("btn-default");
|
||||
} else {
|
||||
autoBakeLabel.classList.remove("btn-success");
|
||||
autoBakeLabel.classList.add("btn-default");
|
||||
autoBakeLabel.classList.remove("btn-success");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -128,9 +128,9 @@ ControlsWaiter.prototype.clearRecipeClick = function() {
|
||||
* recipe.
|
||||
*/
|
||||
ControlsWaiter.prototype.clearBreaksClick = function() {
|
||||
var bps = document.querySelectorAll("#rec-list li.operation .breakpoint");
|
||||
const bps = document.querySelectorAll("#rec-list li.operation .breakpoint");
|
||||
|
||||
for (var i = 0; i < bps.length; i++) {
|
||||
for (let i = 0; i < bps.length; i++) {
|
||||
bps[i].setAttribute("break", "false");
|
||||
bps[i].classList.remove("breakpoint-selected");
|
||||
}
|
||||
@@ -145,10 +145,10 @@ ControlsWaiter.prototype.clearBreaksClick = function() {
|
||||
ControlsWaiter.prototype.initialiseSaveLink = function(recipeConfig) {
|
||||
recipeConfig = recipeConfig || this.app.getRecipeConfig();
|
||||
|
||||
var includeRecipe = document.getElementById("save-link-recipe-checkbox").checked,
|
||||
includeInput = document.getElementById("save-link-input-checkbox").checked,
|
||||
saveLinkEl = document.getElementById("save-link"),
|
||||
saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig);
|
||||
const includeRecipe = document.getElementById("save-link-recipe-checkbox").checked;
|
||||
const includeInput = document.getElementById("save-link-input-checkbox").checked;
|
||||
const saveLinkEl = document.getElementById("save-link");
|
||||
const saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig);
|
||||
|
||||
saveLinkEl.innerHTML = Utils.truncate(saveLink, 120);
|
||||
saveLinkEl.setAttribute("href", saveLink);
|
||||
@@ -167,23 +167,27 @@ ControlsWaiter.prototype.initialiseSaveLink = function(recipeConfig) {
|
||||
ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput, recipeConfig, baseURL) {
|
||||
recipeConfig = recipeConfig || this.app.getRecipeConfig();
|
||||
|
||||
var link = baseURL || window.location.protocol + "//" +
|
||||
window.location.host +
|
||||
window.location.pathname,
|
||||
recipeStr = JSON.stringify(recipeConfig),
|
||||
inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
|
||||
const link = baseURL || window.location.protocol + "//" +
|
||||
window.location.host +
|
||||
window.location.pathname;
|
||||
const recipeStr = JSON.stringify(recipeConfig);
|
||||
const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
|
||||
|
||||
includeRecipe = includeRecipe && (recipeConfig.length > 0);
|
||||
includeInput = includeInput && (inputStr.length > 0) && (inputStr.length < 8000);
|
||||
|
||||
if (includeRecipe) {
|
||||
link += "?recipe=" + encodeURIComponent(recipeStr);
|
||||
}
|
||||
const params = [
|
||||
includeRecipe ? ["recipe", recipeStr] : undefined,
|
||||
includeInput ? ["input", inputStr] : undefined,
|
||||
];
|
||||
|
||||
if (includeRecipe && includeInput) {
|
||||
link += "&input=" + encodeURIComponent(inputStr);
|
||||
} else if (includeInput) {
|
||||
link += "?input=" + encodeURIComponent(inputStr);
|
||||
const query = params
|
||||
.filter(v => v)
|
||||
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||
.join("&");
|
||||
|
||||
if (query) {
|
||||
return `${link}?${query}`;
|
||||
}
|
||||
|
||||
return link;
|
||||
@@ -195,7 +199,7 @@ ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput
|
||||
*/
|
||||
ControlsWaiter.prototype.saveTextChange = function() {
|
||||
try {
|
||||
var recipeConfig = JSON.parse(document.getElementById("save-text").value);
|
||||
const recipeConfig = JSON.parse(document.getElementById("save-text").value);
|
||||
this.initialiseSaveLink(recipeConfig);
|
||||
} catch (err) {}
|
||||
};
|
||||
@@ -205,8 +209,8 @@ ControlsWaiter.prototype.saveTextChange = function() {
|
||||
* Handler for the 'Save' command. Pops up the save dialog box.
|
||||
*/
|
||||
ControlsWaiter.prototype.saveClick = function() {
|
||||
var recipeConfig = this.app.getRecipeConfig(),
|
||||
recipeStr = JSON.stringify(recipeConfig).replace(/},{/g, "},\n{");
|
||||
const recipeConfig = this.app.getRecipeConfig();
|
||||
const recipeStr = JSON.stringify(recipeConfig).replace(/},{/g, "},\n{");
|
||||
|
||||
document.getElementById("save-text").value = recipeStr;
|
||||
|
||||
@@ -244,15 +248,15 @@ ControlsWaiter.prototype.loadClick = function() {
|
||||
* Saves the recipe specified in the save textarea to local storage.
|
||||
*/
|
||||
ControlsWaiter.prototype.saveButtonClick = function() {
|
||||
var recipeName = Utils.escapeHtml(document.getElementById("save-name").value),
|
||||
recipeStr = document.getElementById("save-text").value;
|
||||
const recipeName = Utils.escapeHtml(document.getElementById("save-name").value);
|
||||
const recipeStr = document.getElementById("save-text").value;
|
||||
|
||||
if (!recipeName) {
|
||||
this.app.alert("Please enter a recipe name", "danger", 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var savedRecipes = localStorage.savedRecipes ?
|
||||
let savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [],
|
||||
recipeId = localStorage.recipeId || 0;
|
||||
|
||||
@@ -273,20 +277,20 @@ ControlsWaiter.prototype.saveButtonClick = function() {
|
||||
* Populates the list of saved recipes in the load dialog box from local storage.
|
||||
*/
|
||||
ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
||||
var loadNameEl = document.getElementById("load-name");
|
||||
const loadNameEl = document.getElementById("load-name");
|
||||
|
||||
// Remove current recipes from select
|
||||
var i = loadNameEl.options.length;
|
||||
let i = loadNameEl.options.length;
|
||||
while (i--) {
|
||||
loadNameEl.remove(i);
|
||||
}
|
||||
|
||||
// Add recipes to select
|
||||
var savedRecipes = localStorage.savedRecipes ?
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
|
||||
for (i = 0; i < savedRecipes.length; i++) {
|
||||
var opt = document.createElement("option");
|
||||
const opt = document.createElement("option");
|
||||
opt.value = savedRecipes[i].id;
|
||||
// Unescape then re-escape in case localStorage has been corrupted
|
||||
opt.innerHTML = Utils.escapeHtml(Utils.unescapeHtml(savedRecipes[i].name));
|
||||
@@ -303,13 +307,11 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
||||
* Removes the currently selected recipe from local storage.
|
||||
*/
|
||||
ControlsWaiter.prototype.loadDeleteClick = function() {
|
||||
var id = parseInt(document.getElementById("load-name").value, 10),
|
||||
savedRecipes = localStorage.savedRecipes ?
|
||||
const id = parseInt(document.getElementById("load-name").value, 10);
|
||||
const rawSavedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
|
||||
savedRecipes = savedRecipes.filter(function(r) {
|
||||
return r.id !== id;
|
||||
});
|
||||
const savedRecipes = rawSavedRecipes.filter(r => r.id !== id);
|
||||
|
||||
localStorage.savedRecipes = JSON.stringify(savedRecipes);
|
||||
this.populateLoadRecipesList();
|
||||
@@ -320,14 +322,12 @@ ControlsWaiter.prototype.loadDeleteClick = function() {
|
||||
* Displays the selected recipe in the load text box.
|
||||
*/
|
||||
ControlsWaiter.prototype.loadNameChange = function(e) {
|
||||
var el = e.target,
|
||||
savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [],
|
||||
id = parseInt(el.value, 10);
|
||||
const el = e.target;
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
const id = parseInt(el.value, 10);
|
||||
|
||||
var recipe = savedRecipes.filter(function(r) {
|
||||
return r.id === id;
|
||||
})[0];
|
||||
const recipe = savedRecipes.find(r => r.id === id);
|
||||
|
||||
document.getElementById("load-text").value = recipe.recipe;
|
||||
};
|
||||
@@ -338,7 +338,7 @@ ControlsWaiter.prototype.loadNameChange = function(e) {
|
||||
*/
|
||||
ControlsWaiter.prototype.loadButtonClick = function() {
|
||||
try {
|
||||
var recipeConfig = JSON.parse(document.getElementById("load-text").value);
|
||||
const recipeConfig = JSON.parse(document.getElementById("load-text").value);
|
||||
this.app.setRecipeConfig(recipeConfig);
|
||||
|
||||
$("#rec-list [data-toggle=popover]").popover();
|
||||
@@ -352,12 +352,14 @@ ControlsWaiter.prototype.loadButtonClick = function() {
|
||||
* Populates the bug report information box with useful technical info.
|
||||
*/
|
||||
ControlsWaiter.prototype.supportButtonClick = function() {
|
||||
var reportBugInfo = document.getElementById("report-bug-info"),
|
||||
saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/");
|
||||
const reportBugInfo = document.getElementById("report-bug-info");
|
||||
const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/");
|
||||
|
||||
reportBugInfo.innerHTML = "* CyberChef compile time: " + COMPILE_TIME + "\n" +
|
||||
"* User-Agent: \n" + navigator.userAgent + "\n" +
|
||||
"* [Link to reproduce](" + saveLink + ")\n\n";
|
||||
if (reportBugInfo) {
|
||||
reportBugInfo.innerHTML = "* CyberChef compile time: " + COMPILE_TIME + "\n" +
|
||||
"* User-Agent: \n" + navigator.userAgent + "\n" +
|
||||
"* [Link to reproduce](" + saveLink + ")\n\n";
|
||||
}
|
||||
};
|
||||
|
||||
export default ControlsWaiter;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* @param {string} name - The name of the category.
|
||||
* @param {boolean} selected - Whether this category is pre-selected or not.
|
||||
*/
|
||||
var HTMLCategory = function(name, selected) {
|
||||
const HTMLCategory = function(name, selected) {
|
||||
this.name = name;
|
||||
this.selected = selected;
|
||||
this.opList = [];
|
||||
@@ -32,8 +32,8 @@ HTMLCategory.prototype.addOperation = function(operation) {
|
||||
* @returns {string}
|
||||
*/
|
||||
HTMLCategory.prototype.toHtml = function() {
|
||||
var catName = "cat" + this.name.replace(/[\s/-:_]/g, "");
|
||||
var html = "<div class='panel category'>\
|
||||
const catName = "cat" + this.name.replace(/[\s/-:_]/g, "");
|
||||
let html = "<div class='panel category'>\
|
||||
<a class='category-title' data-toggle='collapse'\
|
||||
data-parent='#categories' href='#" + catName + "'>\
|
||||
" + this.name + "\
|
||||
@@ -41,7 +41,7 @@ HTMLCategory.prototype.toHtml = function() {
|
||||
<div id='" + catName + "' class='panel-collapse collapse\
|
||||
" + (this.selected ? " in" : "") + "'><ul class='op-list'>";
|
||||
|
||||
for (var i = 0; i < this.opList.length; i++) {
|
||||
for (let i = 0; i < this.opList.length; i++) {
|
||||
html += this.opList[i].toStubHtml();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var HTMLIngredient = function(config, app, manager) {
|
||||
const HTMLIngredient = function(config, app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
@@ -32,7 +32,7 @@ var HTMLIngredient = function(config, app, manager) {
|
||||
* @returns {string}
|
||||
*/
|
||||
HTMLIngredient.prototype.toHtml = function() {
|
||||
var inline = (this.type === "boolean" ||
|
||||
let inline = (this.type === "boolean" ||
|
||||
this.type === "number" ||
|
||||
this.type === "option" ||
|
||||
this.type === "shortString" ||
|
||||
@@ -158,15 +158,14 @@ HTMLIngredient.prototype.toHtml = function() {
|
||||
* @param {event} e
|
||||
*/
|
||||
HTMLIngredient.prototype.toggleDisableArgs = function(e) {
|
||||
var el = e.target,
|
||||
op = el.parentNode.parentNode,
|
||||
args = op.querySelectorAll(".arg-group"),
|
||||
els;
|
||||
const el = e.target;
|
||||
const op = el.parentNode.parentNode;
|
||||
const args = op.querySelectorAll(".arg-group");
|
||||
|
||||
for (var i = 0; i < this.disableArgs.length; i++) {
|
||||
els = args[this.disableArgs[i]].querySelectorAll("input, select, button");
|
||||
for (let i = 0; i < this.disableArgs.length; i++) {
|
||||
const els = args[this.disableArgs[i]].querySelectorAll("input, select, button");
|
||||
|
||||
for (var j = 0; j < els.length; j++) {
|
||||
for (let j = 0; j < els.length; j++) {
|
||||
if (els[j].getAttribute("disabled")) {
|
||||
els[j].removeAttribute("disabled");
|
||||
} else {
|
||||
@@ -186,9 +185,9 @@ HTMLIngredient.prototype.toggleDisableArgs = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
HTMLIngredient.prototype.populateOptionChange = function(e) {
|
||||
var el = e.target,
|
||||
op = el.parentNode.parentNode,
|
||||
target = op.querySelectorAll(".arg-group")[this.target].querySelector("input, select, textarea");
|
||||
const el = e.target;
|
||||
const op = el.parentNode.parentNode;
|
||||
const target = op.querySelectorAll(".arg-group")[this.target].querySelector("input, select, textarea");
|
||||
|
||||
target.value = el.childNodes[el.selectedIndex].getAttribute("populate-value");
|
||||
|
||||
@@ -203,7 +202,7 @@ HTMLIngredient.prototype.populateOptionChange = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
HTMLIngredient.prototype.editableOptionChange = function(e) {
|
||||
var select = e.target,
|
||||
let select = e.target,
|
||||
input = select.nextSibling;
|
||||
|
||||
input.value = select.childNodes[select.selectedIndex].value;
|
||||
|
||||
@@ -14,7 +14,7 @@ import HTMLIngredient from "./HTMLIngredient.js";
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var HTMLOperation = function(name, config, app, manager) {
|
||||
const HTMLOperation = function(name, config, app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
@@ -24,8 +24,8 @@ var HTMLOperation = function(name, config, app, manager) {
|
||||
this.config = config;
|
||||
this.ingList = [];
|
||||
|
||||
for (var i = 0; i < config.args.length; i++) {
|
||||
var ing = new HTMLIngredient(config.args[i], this.app, this.manager);
|
||||
for (let i = 0; i < config.args.length; i++) {
|
||||
const ing = new HTMLIngredient(config.args[i], this.app, this.manager);
|
||||
this.ingList.push(ing);
|
||||
}
|
||||
};
|
||||
@@ -47,7 +47,7 @@ HTMLOperation.REMOVE_ICON = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwkl
|
||||
* @returns {string}
|
||||
*/
|
||||
HTMLOperation.prototype.toStubHtml = function(removeIcon) {
|
||||
var html = "<li class='operation'";
|
||||
let html = "<li class='operation'";
|
||||
|
||||
if (this.description) {
|
||||
html += " data-container='body' data-toggle='popover' data-placement='auto right'\
|
||||
@@ -77,9 +77,9 @@ HTMLOperation.prototype.toStubHtml = function(removeIcon) {
|
||||
* @returns {string}
|
||||
*/
|
||||
HTMLOperation.prototype.toFullHtml = function() {
|
||||
var html = "<div class='arg-title'>" + this.name + "</div>";
|
||||
let html = "<div class='arg-title'>" + this.name + "</div>";
|
||||
|
||||
for (var i = 0; i < this.ingList.length; i++) {
|
||||
for (let i = 0; i < this.ingList.length; i++) {
|
||||
html += this.ingList[i].toHtml();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import Utils from "../core/Utils.js";
|
||||
* @constructor
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
*/
|
||||
var HighlighterWaiter = function(app) {
|
||||
const HighlighterWaiter = function(app) {
|
||||
this.app = app;
|
||||
|
||||
this.mouseButtonDown = false;
|
||||
@@ -41,11 +41,11 @@ HighlighterWaiter.OUTPUT = 1;
|
||||
* @returns {boolean}
|
||||
*/
|
||||
HighlighterWaiter.prototype._isSelectionBackwards = function() {
|
||||
var backwards = false,
|
||||
let backwards = false,
|
||||
sel = window.getSelection();
|
||||
|
||||
if (!sel.isCollapsed) {
|
||||
var range = document.createRange();
|
||||
const range = document.createRange();
|
||||
range.setStart(sel.anchorNode, sel.anchorOffset);
|
||||
range.setEnd(sel.focusNode, sel.focusOffset);
|
||||
backwards = range.collapsed;
|
||||
@@ -64,8 +64,8 @@ HighlighterWaiter.prototype._isSelectionBackwards = function() {
|
||||
* @returns {number}
|
||||
*/
|
||||
HighlighterWaiter.prototype._getOutputHtmlOffset = function(node, offset) {
|
||||
var sel = window.getSelection(),
|
||||
range = document.createRange();
|
||||
const sel = window.getSelection();
|
||||
const range = document.createRange();
|
||||
|
||||
range.selectNodeContents(document.getElementById("output-html"));
|
||||
range.setEnd(node, offset);
|
||||
@@ -85,8 +85,8 @@ HighlighterWaiter.prototype._getOutputHtmlOffset = function(node, offset) {
|
||||
* @returns {number} pos.end
|
||||
*/
|
||||
HighlighterWaiter.prototype._getOutputHtmlSelectionOffsets = function() {
|
||||
var sel = window.getSelection(),
|
||||
range,
|
||||
const sel = window.getSelection();
|
||||
let range,
|
||||
start = 0,
|
||||
end = 0,
|
||||
backwards = false;
|
||||
@@ -121,7 +121,7 @@ HighlighterWaiter.prototype._getOutputHtmlSelectionOffsets = function() {
|
||||
* @param {event} e
|
||||
*/
|
||||
HighlighterWaiter.prototype.inputScroll = function(e) {
|
||||
var el = e.target;
|
||||
const el = e.target;
|
||||
document.getElementById("input-highlighter").scrollTop = el.scrollTop;
|
||||
document.getElementById("input-highlighter").scrollLeft = el.scrollLeft;
|
||||
};
|
||||
@@ -134,7 +134,7 @@ HighlighterWaiter.prototype.inputScroll = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
HighlighterWaiter.prototype.outputScroll = function(e) {
|
||||
var el = e.target;
|
||||
const el = e.target;
|
||||
document.getElementById("output-highlighter").scrollTop = el.scrollTop;
|
||||
document.getElementById("output-highlighter").scrollLeft = el.scrollLeft;
|
||||
};
|
||||
@@ -151,9 +151,9 @@ HighlighterWaiter.prototype.inputMousedown = function(e) {
|
||||
this.mouseTarget = HighlighterWaiter.INPUT;
|
||||
this.removeHighlights();
|
||||
|
||||
var el = e.target,
|
||||
start = el.selectionStart,
|
||||
end = el.selectionEnd;
|
||||
const el = e.target;
|
||||
const start = el.selectionStart;
|
||||
const end = el.selectionEnd;
|
||||
|
||||
if (start !== 0 || end !== 0) {
|
||||
document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end);
|
||||
@@ -173,9 +173,9 @@ HighlighterWaiter.prototype.outputMousedown = function(e) {
|
||||
this.mouseTarget = HighlighterWaiter.OUTPUT;
|
||||
this.removeHighlights();
|
||||
|
||||
var el = e.target,
|
||||
start = el.selectionStart,
|
||||
end = el.selectionEnd;
|
||||
const el = e.target;
|
||||
const start = el.selectionStart;
|
||||
const end = el.selectionEnd;
|
||||
|
||||
if (start !== 0 || end !== 0) {
|
||||
document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end);
|
||||
@@ -194,7 +194,7 @@ HighlighterWaiter.prototype.outputHtmlMousedown = function(e) {
|
||||
this.mouseButtonDown = true;
|
||||
this.mouseTarget = HighlighterWaiter.OUTPUT;
|
||||
|
||||
var sel = this._getOutputHtmlSelectionOffsets();
|
||||
const sel = this._getOutputHtmlSelectionOffsets();
|
||||
if (sel.start !== 0 || sel.end !== 0) {
|
||||
document.getElementById("output-selection-info").innerHTML = this.selectionInfo(sel.start, sel.end);
|
||||
}
|
||||
@@ -244,9 +244,9 @@ HighlighterWaiter.prototype.inputMousemove = function(e) {
|
||||
this.mouseTarget !== HighlighterWaiter.INPUT)
|
||||
return;
|
||||
|
||||
var el = e.target,
|
||||
start = el.selectionStart,
|
||||
end = el.selectionEnd;
|
||||
const el = e.target;
|
||||
const start = el.selectionStart;
|
||||
const end = el.selectionEnd;
|
||||
|
||||
if (start !== 0 || end !== 0) {
|
||||
document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end);
|
||||
@@ -268,9 +268,9 @@ HighlighterWaiter.prototype.outputMousemove = function(e) {
|
||||
this.mouseTarget !== HighlighterWaiter.OUTPUT)
|
||||
return;
|
||||
|
||||
var el = e.target,
|
||||
start = el.selectionStart,
|
||||
end = el.selectionEnd;
|
||||
const el = e.target;
|
||||
const start = el.selectionStart;
|
||||
const end = el.selectionEnd;
|
||||
|
||||
if (start !== 0 || end !== 0) {
|
||||
document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end);
|
||||
@@ -292,7 +292,7 @@ HighlighterWaiter.prototype.outputHtmlMousemove = function(e) {
|
||||
this.mouseTarget !== HighlighterWaiter.OUTPUT)
|
||||
return;
|
||||
|
||||
var sel = this._getOutputHtmlSelectionOffsets();
|
||||
const sel = this._getOutputHtmlSelectionOffsets();
|
||||
if (sel.start !== 0 || sel.end !== 0) {
|
||||
document.getElementById("output-selection-info").innerHTML = this.selectionInfo(sel.start, sel.end);
|
||||
}
|
||||
@@ -308,11 +308,11 @@ HighlighterWaiter.prototype.outputHtmlMousemove = function(e) {
|
||||
* @returns {string}
|
||||
*/
|
||||
HighlighterWaiter.prototype.selectionInfo = function(start, end) {
|
||||
var width = end.toString().length;
|
||||
width = width < 2 ? 2 : width;
|
||||
var startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, " "),
|
||||
endStr = Utils.pad(end.toString(), width, " ").replace(/ /g, " "),
|
||||
lenStr = Utils.pad((end-start).toString(), width, " ").replace(/ /g, " ");
|
||||
const len = end.toString().length;
|
||||
const width = len < 2 ? 2 : len;
|
||||
const startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, " ");
|
||||
const endStr = Utils.pad(end.toString(), width, " ").replace(/ /g, " ");
|
||||
const lenStr = Utils.pad((end-start).toString(), width, " ").replace(/ /g, " ");
|
||||
|
||||
return "start: " + startStr + "<br>end: " + endStr + "<br>length: " + lenStr;
|
||||
};
|
||||
@@ -339,16 +339,16 @@ HighlighterWaiter.prototype.removeHighlights = function() {
|
||||
* @returns {Object[]} highlights[].args
|
||||
*/
|
||||
HighlighterWaiter.prototype.generateHighlightList = function() {
|
||||
var recipeConfig = this.app.getRecipeConfig(),
|
||||
highlights = [];
|
||||
const recipeConfig = this.app.getRecipeConfig();
|
||||
const highlights = [];
|
||||
|
||||
for (var i = 0; i < recipeConfig.length; i++) {
|
||||
for (let i = 0; i < recipeConfig.length; i++) {
|
||||
if (recipeConfig[i].disabled) continue;
|
||||
|
||||
// If any breakpoints are set, do not attempt to highlight
|
||||
if (recipeConfig[i].breakpoint) return false;
|
||||
|
||||
var op = this.app.operations[recipeConfig[i].op];
|
||||
const op = this.app.operations[recipeConfig[i].op];
|
||||
|
||||
// If any of the operations do not support highlighting, fail immediately.
|
||||
if (op.highlight === false || op.highlight === undefined) return false;
|
||||
@@ -376,13 +376,13 @@ HighlighterWaiter.prototype.generateHighlightList = function() {
|
||||
* @param {number} pos.end - The end offset.
|
||||
*/
|
||||
HighlighterWaiter.prototype.highlightOutput = function(pos) {
|
||||
var highlights = this.generateHighlightList();
|
||||
const highlights = this.generateHighlightList();
|
||||
|
||||
if (!highlights || !this.app.autoBake_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < highlights.length; i++) {
|
||||
for (let i = 0; i < highlights.length; i++) {
|
||||
// Remove multiple highlights before processing again
|
||||
pos = [pos[0]];
|
||||
|
||||
@@ -411,13 +411,13 @@ HighlighterWaiter.prototype.highlightOutput = function(pos) {
|
||||
* @param {number} pos.end - The end offset.
|
||||
*/
|
||||
HighlighterWaiter.prototype.highlightInput = function(pos) {
|
||||
var highlights = this.generateHighlightList();
|
||||
const highlights = this.generateHighlightList();
|
||||
|
||||
if (!highlights || !this.app.autoBake_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < highlights.length; i++) {
|
||||
for (let i = 0; i < highlights.length; i++) {
|
||||
// Remove multiple highlights before processing again
|
||||
pos = [pos[0]];
|
||||
|
||||
@@ -452,11 +452,11 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
|
||||
// be displayed by the HTML textarea and will mess up highlighting offsets.
|
||||
if (!this.app.dishStr || this.app.dishStr.indexOf("\r") >= 0) return false;
|
||||
|
||||
var startPlaceholder = "[startHighlight]",
|
||||
startPlaceholderRegex = /\[startHighlight\]/g,
|
||||
endPlaceholder = "[endHighlight]",
|
||||
endPlaceholderRegex = /\[endHighlight\]/g,
|
||||
text = textarea.value;
|
||||
const startPlaceholder = "[startHighlight]";
|
||||
const startPlaceholderRegex = /\[startHighlight\]/g;
|
||||
const endPlaceholder = "[endHighlight]";
|
||||
const endPlaceholderRegex = /\[endHighlight\]/g;
|
||||
let text = textarea.value;
|
||||
|
||||
// Put placeholders in position
|
||||
// If there's only one value, select that
|
||||
@@ -468,11 +468,11 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
|
||||
text.slice(pos[0].end, text.length);
|
||||
} else {
|
||||
// O(n^2) - Can anyone improve this without overwriting placeholders?
|
||||
var result = "",
|
||||
let result = "",
|
||||
endPlaced = true;
|
||||
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
for (var j = 1; j < pos.length; j++) {
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
for (let j = 1; j < pos.length; j++) {
|
||||
if (pos[j].end < pos[j].start) continue;
|
||||
if (pos[j].start === i) {
|
||||
result += startPlaceholder;
|
||||
@@ -489,7 +489,7 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
|
||||
text = result;
|
||||
}
|
||||
|
||||
var cssClass = "hl1";
|
||||
const cssClass = "hl1";
|
||||
//if (colour) cssClass += "-"+colour;
|
||||
|
||||
// Remove HTML tags
|
||||
|
||||
@@ -12,7 +12,7 @@ import Utils from "../core/Utils.js";
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var InputWaiter = function(app, manager) {
|
||||
const InputWaiter = function(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
@@ -66,11 +66,11 @@ InputWaiter.prototype.set = function(input) {
|
||||
* @param {number} lines - The number of the lines in the current input string
|
||||
*/
|
||||
InputWaiter.prototype.setInputInfo = function(length, lines) {
|
||||
var width = length.toString().length;
|
||||
let width = length.toString().length;
|
||||
width = width < 2 ? 2 : width;
|
||||
|
||||
var lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " ");
|
||||
var linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " ");
|
||||
const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " ");
|
||||
const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " ");
|
||||
|
||||
document.getElementById("input-info").innerHTML = "length: " + lengthStr + "<br>lines: " + linesStr;
|
||||
};
|
||||
@@ -92,8 +92,8 @@ InputWaiter.prototype.inputChange = function(e) {
|
||||
this.app.progress = 0;
|
||||
|
||||
// Update the input metadata info
|
||||
var inputText = this.get(),
|
||||
lines = inputText.count("\n") + 1;
|
||||
const inputText = this.get();
|
||||
const lines = inputText.count("\n") + 1;
|
||||
|
||||
this.setInputInfo(inputText.length, lines);
|
||||
|
||||
@@ -149,22 +149,22 @@ InputWaiter.prototype.inputDrop = function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var el = e.target,
|
||||
file = e.dataTransfer.files[0],
|
||||
text = e.dataTransfer.getData("Text"),
|
||||
reader = new FileReader(),
|
||||
inputCharcode = "",
|
||||
offset = 0,
|
||||
CHUNK_SIZE = 20480; // 20KB
|
||||
const el = e.target;
|
||||
const file = e.dataTransfer.files[0];
|
||||
const text = e.dataTransfer.getData("Text");
|
||||
const reader = new FileReader();
|
||||
let inputCharcode = "";
|
||||
let offset = 0;
|
||||
const CHUNK_SIZE = 20480; // 20KB
|
||||
|
||||
var setInput = function() {
|
||||
const setInput = function() {
|
||||
if (inputCharcode.length > 100000 && this.app.autoBake_) {
|
||||
this.manager.controls.setAutoBake(false);
|
||||
this.app.alert("Turned off Auto Bake as the input is large", "warning", 5000);
|
||||
}
|
||||
|
||||
this.set(inputCharcode);
|
||||
var recipeConfig = this.app.getRecipeConfig();
|
||||
const recipeConfig = this.app.getRecipeConfig();
|
||||
if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
|
||||
recipeConfig.unshift({op:"From Hex", args:["Space"]});
|
||||
this.app.setRecipeConfig(recipeConfig);
|
||||
@@ -173,18 +173,18 @@ InputWaiter.prototype.inputDrop = function(e) {
|
||||
el.classList.remove("loadingFile");
|
||||
}.bind(this);
|
||||
|
||||
var seek = function() {
|
||||
const seek = function() {
|
||||
if (offset >= file.size) {
|
||||
setInput();
|
||||
return;
|
||||
}
|
||||
el.value = "Processing... " + Math.round(offset / file.size * 100) + "%";
|
||||
var slice = file.slice(offset, offset + CHUNK_SIZE);
|
||||
const slice = file.slice(offset, offset + CHUNK_SIZE);
|
||||
reader.readAsArrayBuffer(slice);
|
||||
};
|
||||
|
||||
reader.onload = function(e) {
|
||||
var data = new Uint8Array(reader.result);
|
||||
const data = new Uint8Array(reader.result);
|
||||
inputCharcode += Utils.toHexFast(data);
|
||||
offset += CHUNK_SIZE;
|
||||
seek();
|
||||
|
||||
@@ -19,7 +19,7 @@ import SeasonalWaiter from "./SeasonalWaiter.js";
|
||||
* @constructor
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
*/
|
||||
var Manager = function(app) {
|
||||
const Manager = function(app) {
|
||||
this.app = app;
|
||||
|
||||
// Define custom events
|
||||
@@ -154,6 +154,7 @@ Manager.prototype.initialiseEventListeners = function() {
|
||||
this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options);
|
||||
this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options);
|
||||
this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options);
|
||||
document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options));
|
||||
|
||||
// Misc
|
||||
document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
|
||||
@@ -195,8 +196,8 @@ Manager.prototype.addListeners = function(selector, eventType, callback, scope)
|
||||
* this.addMultiEventListener("search", "keyup paste search", this.search, this);
|
||||
*/
|
||||
Manager.prototype.addMultiEventListener = function(selector, eventTypes, callback, scope) {
|
||||
var evs = eventTypes.split(" ");
|
||||
for (var i = 0; i < evs.length; i++) {
|
||||
const evs = eventTypes.split(" ");
|
||||
for (let i = 0; i < evs.length; i++) {
|
||||
document.querySelector(selector).addEventListener(evs[i], callback.bind(scope));
|
||||
}
|
||||
};
|
||||
@@ -216,8 +217,8 @@ Manager.prototype.addMultiEventListener = function(selector, eventTypes, callbac
|
||||
* this.addMultiEventListener(".saveable", "keyup paste", this.save, this);
|
||||
*/
|
||||
Manager.prototype.addMultiEventListeners = function(selector, eventTypes, callback, scope) {
|
||||
var evs = eventTypes.split(" ");
|
||||
for (var i = 0; i < evs.length; i++) {
|
||||
const evs = eventTypes.split(" ");
|
||||
for (let i = 0; i < evs.length; i++) {
|
||||
this.addListeners(selector, evs[i], callback, scope);
|
||||
}
|
||||
};
|
||||
@@ -238,7 +239,7 @@ Manager.prototype.addMultiEventListeners = function(selector, eventTypes, callba
|
||||
* this.addDynamicListener("button", "click", alert, this);
|
||||
*/
|
||||
Manager.prototype.addDynamicListener = function(selector, eventType, callback, scope) {
|
||||
var eventConfig = {
|
||||
const eventConfig = {
|
||||
selector: selector,
|
||||
callback: callback.bind(scope || this)
|
||||
};
|
||||
@@ -261,15 +262,16 @@ Manager.prototype.addDynamicListener = function(selector, eventType, callback, s
|
||||
* @param {Event} e - The event to be handled
|
||||
*/
|
||||
Manager.prototype.dynamicListenerHandler = function(e) {
|
||||
var handlers = this.dynamicHandlers[e.type],
|
||||
matches = e.target.matches ||
|
||||
e.target.webkitMatchesSelector ||
|
||||
e.target.mozMatchesSelector ||
|
||||
e.target.msMatchesSelector ||
|
||||
e.target.oMatchesSelector;
|
||||
const { type, target } = e;
|
||||
const handlers = this.dynamicHandlers[type];
|
||||
const matches = target.matches ||
|
||||
target.webkitMatchesSelector ||
|
||||
target.mozMatchesSelector ||
|
||||
target.msMatchesSelector ||
|
||||
target.oMatchesSelector;
|
||||
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
if (matches && e.target[matches.name](handlers[i].selector)) {
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
if (matches && matches.call(target, handlers[i].selector)) {
|
||||
handlers[i].callback(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import Sortable from "sortablejs";
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var OperationsWaiter = function(app, manager) {
|
||||
const OperationsWaiter = function(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
@@ -29,7 +29,7 @@ var OperationsWaiter = function(app, manager) {
|
||||
* @param {event} e
|
||||
*/
|
||||
OperationsWaiter.prototype.searchOperations = function(e) {
|
||||
var ops, selected;
|
||||
let ops, selected;
|
||||
|
||||
if (e.type === "search") { // Search
|
||||
e.preventDefault();
|
||||
@@ -68,9 +68,9 @@ OperationsWaiter.prototype.searchOperations = function(e) {
|
||||
ops[selected-1].classList.add("selected-op");
|
||||
}
|
||||
} else {
|
||||
var searchResultsEl = document.getElementById("search-results"),
|
||||
el = e.target,
|
||||
str = el.value;
|
||||
const searchResultsEl = document.getElementById("search-results");
|
||||
const el = e.target;
|
||||
const str = el.value;
|
||||
|
||||
while (searchResultsEl.firstChild) {
|
||||
try {
|
||||
@@ -81,12 +81,10 @@ OperationsWaiter.prototype.searchOperations = function(e) {
|
||||
|
||||
$("#categories .in").collapse("hide");
|
||||
if (str) {
|
||||
var matchedOps = this.filterOperations(str, true),
|
||||
matchedOpsHtml = "";
|
||||
|
||||
for (var i = 0; i < matchedOps.length; i++) {
|
||||
matchedOpsHtml += matchedOps[i].toStubHtml();
|
||||
}
|
||||
const matchedOps = this.filterOperations(str, true);
|
||||
const matchedOpsHtml = matchedOps
|
||||
.map(v => v.toStubHtml())
|
||||
.join("");
|
||||
|
||||
searchResultsEl.innerHTML = matchedOpsHtml;
|
||||
searchResultsEl.dispatchEvent(this.manager.oplistcreate);
|
||||
@@ -103,19 +101,19 @@ OperationsWaiter.prototype.searchOperations = function(e) {
|
||||
* name and description
|
||||
* @returns {string[]}
|
||||
*/
|
||||
OperationsWaiter.prototype.filterOperations = function(searchStr, highlight) {
|
||||
var matchedOps = [],
|
||||
matchedDescs = [];
|
||||
OperationsWaiter.prototype.filterOperations = function(inStr, highlight) {
|
||||
const matchedOps = [];
|
||||
const matchedDescs = [];
|
||||
|
||||
searchStr = searchStr.toLowerCase();
|
||||
const searchStr = inStr.toLowerCase();
|
||||
|
||||
for (var opName in this.app.operations) {
|
||||
var op = this.app.operations[opName],
|
||||
namePos = opName.toLowerCase().indexOf(searchStr),
|
||||
descPos = op.description.toLowerCase().indexOf(searchStr);
|
||||
for (const opName in this.app.operations) {
|
||||
const op = this.app.operations[opName];
|
||||
const namePos = opName.toLowerCase().indexOf(searchStr);
|
||||
const descPos = op.description.toLowerCase().indexOf(searchStr);
|
||||
|
||||
if (namePos >= 0 || descPos >= 0) {
|
||||
var operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
if (highlight) {
|
||||
operation.highlightSearchString(searchStr, namePos, descPos);
|
||||
}
|
||||
@@ -140,7 +138,7 @@ OperationsWaiter.prototype.filterOperations = function(searchStr, highlight) {
|
||||
* @returns {number}
|
||||
*/
|
||||
OperationsWaiter.prototype.getSelectedOp = function(ops) {
|
||||
for (var i = 0; i < ops.length; i++) {
|
||||
for (let i = 0; i < ops.length; i++) {
|
||||
if (ops[i].classList.contains("selected-op")) {
|
||||
return i;
|
||||
}
|
||||
@@ -168,7 +166,7 @@ OperationsWaiter.prototype.opListCreate = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
OperationsWaiter.prototype.operationDblclick = function(e) {
|
||||
var li = e.target;
|
||||
const li = e.target;
|
||||
|
||||
this.manager.recipe.addOperation(li.textContent);
|
||||
this.app.autoBake();
|
||||
@@ -186,25 +184,25 @@ OperationsWaiter.prototype.editFavouritesClick = function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// Add favourites to modal
|
||||
var favCat = this.app.categories.filter(function(c) {
|
||||
const favCat = this.app.categories.filter(function(c) {
|
||||
return c.name === "Favourites";
|
||||
})[0];
|
||||
|
||||
var html = "";
|
||||
for (var i = 0; i < favCat.ops.length; i++) {
|
||||
var opName = favCat.ops[i];
|
||||
var operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
let html = "";
|
||||
for (let i = 0; i < favCat.ops.length; i++) {
|
||||
const opName = favCat.ops[i];
|
||||
const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
html += operation.toStubHtml(true);
|
||||
}
|
||||
|
||||
var editFavouritesList = document.getElementById("edit-favourites-list");
|
||||
const editFavouritesList = document.getElementById("edit-favourites-list");
|
||||
editFavouritesList.innerHTML = html;
|
||||
this.removeIntent = false;
|
||||
|
||||
var editableList = Sortable.create(editFavouritesList, {
|
||||
const editableList = Sortable.create(editFavouritesList, {
|
||||
filter: ".remove-icon",
|
||||
onFilter: function (evt) {
|
||||
var el = editableList.closest(evt.item);
|
||||
const el = editableList.closest(evt.item);
|
||||
if (el) {
|
||||
$(el).popover("destroy");
|
||||
el.parentNode.removeChild(el);
|
||||
@@ -236,12 +234,8 @@ OperationsWaiter.prototype.editFavouritesClick = function(e) {
|
||||
* Saves the selected favourites and reloads them.
|
||||
*/
|
||||
OperationsWaiter.prototype.saveFavouritesClick = function() {
|
||||
var favouritesList = [],
|
||||
favs = document.querySelectorAll("#edit-favourites-list li");
|
||||
|
||||
for (var i = 0; i < favs.length; i++) {
|
||||
favouritesList.push(favs[i].textContent);
|
||||
}
|
||||
const favs = document.querySelectorAll("#edit-favourites-list li");
|
||||
const favouritesList = Array.from(favs, e => e.textContent);
|
||||
|
||||
this.app.saveFavourites(favouritesList);
|
||||
this.app.loadFavourites();
|
||||
@@ -266,7 +260,7 @@ OperationsWaiter.prototype.resetFavouritesClick = function() {
|
||||
* @param {event} e
|
||||
*/
|
||||
OperationsWaiter.prototype.opIconMouseover = function(e) {
|
||||
var opEl = e.target.parentNode;
|
||||
const opEl = e.target.parentNode;
|
||||
if (e.target.getAttribute("data-toggle") === "popover") {
|
||||
$(opEl).popover("hide");
|
||||
}
|
||||
@@ -281,8 +275,8 @@ OperationsWaiter.prototype.opIconMouseover = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
OperationsWaiter.prototype.opIconMouseleave = function(e) {
|
||||
var opEl = e.target.parentNode,
|
||||
toEl = e.toElement || e.relatedElement;
|
||||
const opEl = e.target.parentNode;
|
||||
const toEl = e.toElement || e.relatedElement;
|
||||
|
||||
if (e.target.getAttribute("data-toggle") === "popover" && toEl === opEl) {
|
||||
$(opEl).popover("show");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @constructor
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
*/
|
||||
var OptionsWaiter = function(app) {
|
||||
const OptionsWaiter = function(app) {
|
||||
this.app = app;
|
||||
};
|
||||
|
||||
@@ -24,26 +24,32 @@ OptionsWaiter.prototype.load = function(options) {
|
||||
animate: false,
|
||||
});
|
||||
|
||||
for (var option in options) {
|
||||
for (const option in options) {
|
||||
this.app.options[option] = options[option];
|
||||
}
|
||||
|
||||
// Set options to match object
|
||||
var cboxes = document.querySelectorAll("#options-body input[type=checkbox]");
|
||||
for (var i = 0; i < cboxes.length; i++) {
|
||||
const cboxes = document.querySelectorAll("#options-body input[type=checkbox]");
|
||||
let i;
|
||||
for (i = 0; i < cboxes.length; i++) {
|
||||
$(cboxes[i]).bootstrapSwitch("state", this.app.options[cboxes[i].getAttribute("option")]);
|
||||
}
|
||||
|
||||
var nboxes = document.querySelectorAll("#options-body input[type=number]");
|
||||
const nboxes = document.querySelectorAll("#options-body input[type=number]");
|
||||
for (i = 0; i < nboxes.length; i++) {
|
||||
nboxes[i].value = this.app.options[nboxes[i].getAttribute("option")];
|
||||
nboxes[i].dispatchEvent(new CustomEvent("change", {bubbles: true}));
|
||||
}
|
||||
|
||||
var selects = document.querySelectorAll("#options-body select");
|
||||
const selects = document.querySelectorAll("#options-body select");
|
||||
for (i = 0; i < selects.length; i++) {
|
||||
selects[i].value = this.app.options[selects[i].getAttribute("option")];
|
||||
selects[i].dispatchEvent(new CustomEvent("change", {bubbles: true}));
|
||||
const val = this.app.options[selects[i].getAttribute("option")];
|
||||
if (val) {
|
||||
selects[i].value = val;
|
||||
selects[i].dispatchEvent(new CustomEvent("change", {bubbles: true}));
|
||||
} else {
|
||||
selects[i].selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,8 +80,8 @@ OptionsWaiter.prototype.resetOptionsClick = function() {
|
||||
* @param {boolean} state
|
||||
*/
|
||||
OptionsWaiter.prototype.switchChange = function(e, state) {
|
||||
var el = e.target,
|
||||
option = el.getAttribute("option");
|
||||
const el = e.target;
|
||||
const option = el.getAttribute("option");
|
||||
|
||||
this.app.options[option] = state;
|
||||
localStorage.setItem("options", JSON.stringify(this.app.options));
|
||||
@@ -89,8 +95,8 @@ OptionsWaiter.prototype.switchChange = function(e, state) {
|
||||
* @param {event} e
|
||||
*/
|
||||
OptionsWaiter.prototype.numberChange = function(e) {
|
||||
var el = e.target,
|
||||
option = el.getAttribute("option");
|
||||
const el = e.target;
|
||||
const option = el.getAttribute("option");
|
||||
|
||||
this.app.options[option] = parseInt(el.value, 10);
|
||||
localStorage.setItem("options", JSON.stringify(this.app.options));
|
||||
@@ -104,8 +110,8 @@ OptionsWaiter.prototype.numberChange = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
OptionsWaiter.prototype.selectChange = function(e) {
|
||||
var el = e.target,
|
||||
option = el.getAttribute("option");
|
||||
const el = e.target;
|
||||
const option = el.getAttribute("option");
|
||||
|
||||
this.app.options[option] = el.value;
|
||||
localStorage.setItem("options", JSON.stringify(this.app.options));
|
||||
@@ -131,4 +137,14 @@ OptionsWaiter.prototype.setWordWrap = function() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the theme by setting the class of the <html> element.
|
||||
*/
|
||||
OptionsWaiter.prototype.themeChange = function (e) {
|
||||
const themeClass = e.target.value;
|
||||
|
||||
document.querySelector(":root").className = themeClass;
|
||||
};
|
||||
|
||||
export default OptionsWaiter;
|
||||
|
||||
@@ -12,7 +12,7 @@ import Utils from "../core/Utils.js";
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var OutputWaiter = function(app, manager) {
|
||||
const OutputWaiter = function(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
};
|
||||
@@ -36,10 +36,10 @@ OutputWaiter.prototype.get = function() {
|
||||
* @param {number} duration - The length of time (ms) it took to generate the output
|
||||
*/
|
||||
OutputWaiter.prototype.set = function(dataStr, type, duration) {
|
||||
var outputText = document.getElementById("output-text"),
|
||||
outputHtml = document.getElementById("output-html"),
|
||||
outputHighlighter = document.getElementById("output-highlighter"),
|
||||
inputHighlighter = document.getElementById("input-highlighter");
|
||||
const outputText = document.getElementById("output-text");
|
||||
const outputHtml = document.getElementById("output-html");
|
||||
const outputHighlighter = document.getElementById("output-highlighter");
|
||||
const inputHighlighter = document.getElementById("input-highlighter");
|
||||
|
||||
if (type === "html") {
|
||||
outputText.style.display = "none";
|
||||
@@ -51,8 +51,8 @@ OutputWaiter.prototype.set = function(dataStr, type, duration) {
|
||||
outputHtml.innerHTML = dataStr;
|
||||
|
||||
// Execute script sections
|
||||
var scriptElements = outputHtml.querySelectorAll("script");
|
||||
for (var i = 0; i < scriptElements.length; i++) {
|
||||
const scriptElements = outputHtml.querySelectorAll("script");
|
||||
for (let i = 0; i < scriptElements.length; i++) {
|
||||
try {
|
||||
eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval
|
||||
} catch (err) {
|
||||
@@ -70,7 +70,7 @@ OutputWaiter.prototype.set = function(dataStr, type, duration) {
|
||||
}
|
||||
|
||||
this.manager.highlighter.removeHighlights();
|
||||
var lines = dataStr.count("\n") + 1;
|
||||
const lines = dataStr.count("\n") + 1;
|
||||
this.setOutputInfo(dataStr.length, lines, duration);
|
||||
};
|
||||
|
||||
@@ -83,12 +83,12 @@ OutputWaiter.prototype.set = function(dataStr, type, duration) {
|
||||
* @param {number} duration - The length of time (ms) it took to generate the output
|
||||
*/
|
||||
OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) {
|
||||
var width = length.toString().length;
|
||||
let width = length.toString().length;
|
||||
width = width < 4 ? 4 : width;
|
||||
|
||||
var lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " ");
|
||||
var linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " ");
|
||||
var timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " ");
|
||||
const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " ");
|
||||
const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " ");
|
||||
const timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " ");
|
||||
|
||||
document.getElementById("output-info").innerHTML = "time: " + timeStr +
|
||||
"<br>length: " + lengthStr +
|
||||
@@ -103,11 +103,11 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) {
|
||||
* without wrapping or overflowing.
|
||||
*/
|
||||
OutputWaiter.prototype.adjustWidth = function() {
|
||||
var output = document.getElementById("output"),
|
||||
saveToFile = document.getElementById("save-to-file"),
|
||||
switchIO = document.getElementById("switch"),
|
||||
undoSwitch = document.getElementById("undo-switch"),
|
||||
maximiseOutput = document.getElementById("maximise-output");
|
||||
const output = document.getElementById("output");
|
||||
const saveToFile = document.getElementById("save-to-file");
|
||||
const switchIO = document.getElementById("switch");
|
||||
const undoSwitch = document.getElementById("undo-switch");
|
||||
const maximiseOutput = document.getElementById("maximise-output");
|
||||
|
||||
if (output.clientWidth < 680) {
|
||||
saveToFile.childNodes[1].nodeValue = "";
|
||||
@@ -129,11 +129,11 @@ OutputWaiter.prototype.adjustWidth = function() {
|
||||
* Saves the current output to a file, downloaded as a URL octet stream.
|
||||
*/
|
||||
OutputWaiter.prototype.saveClick = function() {
|
||||
var data = Utils.toBase64(this.app.dishStr),
|
||||
filename = window.prompt("Please enter a filename:", "download.dat");
|
||||
const data = Utils.toBase64(this.app.dishStr);
|
||||
const filename = window.prompt("Please enter a filename:", "download.dat");
|
||||
|
||||
if (filename) {
|
||||
var el = document.createElement("a");
|
||||
const el = document.createElement("a");
|
||||
el.setAttribute("href", "data:application/octet-stream;base64;charset=utf-8," + data);
|
||||
el.setAttribute("download", filename);
|
||||
|
||||
@@ -173,7 +173,7 @@ OutputWaiter.prototype.undoSwitchClick = function() {
|
||||
* Resizes the output frame to be as large as possible, or restores it to its original size.
|
||||
*/
|
||||
OutputWaiter.prototype.maximiseOutputClick = function(e) {
|
||||
var el = e.target.id === "maximise-output" ? e.target : e.target.parentNode;
|
||||
const el = e.target.id === "maximise-output" ? e.target : e.target.parentNode;
|
||||
|
||||
if (el.getAttribute("title") === "Maximise") {
|
||||
this.app.columnSplitter.collapse(0);
|
||||
|
||||
@@ -13,7 +13,7 @@ import Sortable from "sortablejs";
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var RecipeWaiter = function(app, manager) {
|
||||
const RecipeWaiter = function(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
this.removeIntent = false;
|
||||
@@ -24,7 +24,7 @@ var RecipeWaiter = function(app, manager) {
|
||||
* Sets up the drag and drop capability for operations in the operations and recipe areas.
|
||||
*/
|
||||
RecipeWaiter.prototype.initialiseOperationDragNDrop = function() {
|
||||
var recList = document.getElementById("rec-list");
|
||||
const recList = document.getElementById("rec-list");
|
||||
|
||||
// Recipe list
|
||||
Sortable.create(recList, {
|
||||
@@ -60,8 +60,8 @@ RecipeWaiter.prototype.initialiseOperationDragNDrop = function() {
|
||||
}.bind(this));
|
||||
|
||||
Sortable.utils.on(recList, "touchend", function(e) {
|
||||
var loc = e.changedTouches[0],
|
||||
target = document.elementFromPoint(loc.clientX, loc.clientY);
|
||||
const loc = e.changedTouches[0];
|
||||
const target = document.elementFromPoint(loc.clientX, loc.clientY);
|
||||
|
||||
this.removeIntent = !recList.contains(target);
|
||||
}.bind(this));
|
||||
@@ -182,7 +182,7 @@ RecipeWaiter.prototype.favDrop = function(e) {
|
||||
e.preventDefault();
|
||||
e.target.classList.remove("favourites-hover");
|
||||
|
||||
var opName = e.dataTransfer.getData("Text");
|
||||
const opName = e.dataTransfer.getData("Text");
|
||||
this.app.addFavourite(opName);
|
||||
};
|
||||
|
||||
@@ -205,7 +205,7 @@ RecipeWaiter.prototype.ingChange = function() {
|
||||
* @param {event} e
|
||||
*/
|
||||
RecipeWaiter.prototype.disableClick = function(e) {
|
||||
var icon = e.target;
|
||||
const icon = e.target;
|
||||
|
||||
if (icon.getAttribute("disabled") === "false") {
|
||||
icon.setAttribute("disabled", "true");
|
||||
@@ -230,7 +230,7 @@ RecipeWaiter.prototype.disableClick = function(e) {
|
||||
* @param {event} e
|
||||
*/
|
||||
RecipeWaiter.prototype.breakpointClick = function(e) {
|
||||
var bp = e.target;
|
||||
const bp = e.target;
|
||||
|
||||
if (bp.getAttribute("break") === "false") {
|
||||
bp.setAttribute("break", "true");
|
||||
@@ -276,16 +276,17 @@ RecipeWaiter.prototype.operationChildDblclick = function(e) {
|
||||
* @returns {recipeConfig}
|
||||
*/
|
||||
RecipeWaiter.prototype.getConfig = function() {
|
||||
var config = [], ingredients, ingList, disabled, bp, item,
|
||||
operations = document.querySelectorAll("#rec-list li.operation");
|
||||
const config = [];
|
||||
let ingredients, ingList, disabled, bp, item;
|
||||
const operations = document.querySelectorAll("#rec-list li.operation");
|
||||
|
||||
for (var i = 0; i < operations.length; i++) {
|
||||
for (let i = 0; i < operations.length; i++) {
|
||||
ingredients = [];
|
||||
disabled = operations[i].querySelector(".disable-icon");
|
||||
bp = operations[i].querySelector(".breakpoint");
|
||||
ingList = operations[i].querySelectorAll(".arg");
|
||||
|
||||
for (var j = 0; j < ingList.length; j++) {
|
||||
for (let j = 0; j < ingList.length; j++) {
|
||||
if (ingList[j].getAttribute("type") === "checkbox") {
|
||||
// checkbox
|
||||
ingredients[j] = ingList[j].checked;
|
||||
@@ -327,8 +328,8 @@ RecipeWaiter.prototype.getConfig = function() {
|
||||
* @param {number} position
|
||||
*/
|
||||
RecipeWaiter.prototype.updateBreakpointIndicator = function(position) {
|
||||
var operations = document.querySelectorAll("#rec-list li.operation");
|
||||
for (var i = 0; i < operations.length; i++) {
|
||||
const operations = document.querySelectorAll("#rec-list li.operation");
|
||||
for (let i = 0; i < operations.length; i++) {
|
||||
if (i === position) {
|
||||
operations[i].classList.add("break");
|
||||
} else {
|
||||
@@ -345,8 +346,8 @@ RecipeWaiter.prototype.updateBreakpointIndicator = function(position) {
|
||||
* @param {element} el - The operation stub element from the operations pane
|
||||
*/
|
||||
RecipeWaiter.prototype.buildRecipeOperation = function(el) {
|
||||
var opName = el.textContent;
|
||||
var op = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
const opName = el.textContent;
|
||||
const op = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
el.innerHTML = op.toFullHtml();
|
||||
|
||||
if (this.app.operations[opName].flowControl) {
|
||||
@@ -369,7 +370,7 @@ RecipeWaiter.prototype.buildRecipeOperation = function(el) {
|
||||
* @returns {element}
|
||||
*/
|
||||
RecipeWaiter.prototype.addOperation = function(name) {
|
||||
var item = document.createElement("li");
|
||||
const item = document.createElement("li");
|
||||
|
||||
item.classList.add("operation");
|
||||
item.innerHTML = name;
|
||||
@@ -387,7 +388,7 @@ RecipeWaiter.prototype.addOperation = function(name) {
|
||||
* @fires Manager#operationremove
|
||||
*/
|
||||
RecipeWaiter.prototype.clearRecipe = function() {
|
||||
var recList = document.getElementById("rec-list");
|
||||
const recList = document.getElementById("rec-list");
|
||||
while (recList.firstChild) {
|
||||
recList.removeChild(recList.firstChild);
|
||||
}
|
||||
@@ -402,8 +403,8 @@ RecipeWaiter.prototype.clearRecipe = function() {
|
||||
* @param {event} e
|
||||
*/
|
||||
RecipeWaiter.prototype.dropdownToggleClick = function(e) {
|
||||
var el = e.target,
|
||||
button = el.parentNode.parentNode.previousSibling;
|
||||
const el = e.target;
|
||||
const button = el.parentNode.parentNode.previousSibling;
|
||||
|
||||
button.innerHTML = el.textContent + " <span class='caret'></span>";
|
||||
this.ingChange();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
var SeasonalWaiter = function(app, manager) {
|
||||
const SeasonalWaiter = function(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
};
|
||||
@@ -19,69 +19,12 @@ var SeasonalWaiter = function(app, manager) {
|
||||
* Loads all relevant items depending on the current date.
|
||||
*/
|
||||
SeasonalWaiter.prototype.load = function() {
|
||||
//var now = new Date();
|
||||
|
||||
// SpiderChef
|
||||
// if (now.getMonth() === 3 && now.getDate() === 1) { // Apr 1
|
||||
// this.insertSpiderIcons();
|
||||
// this.insertSpiderText();
|
||||
// }
|
||||
|
||||
// Konami code
|
||||
this.kkeys = [];
|
||||
window.addEventListener("keydown", this.konamiCodeListener.bind(this));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Replaces chef icons with spider icons.
|
||||
* #spiderchef
|
||||
*/
|
||||
SeasonalWaiter.prototype.insertSpiderIcons = function() {
|
||||
var spider16 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB3UlEQVQ4y2NgGJaAmYGBgVnf0oKJgYGBobWtXamqqoYTn2I4CI+LTzM2NTulpKbu+vPHz2dV5RWlluZmi3j5+KqFJSSEzpw8uQPdAEYYIzo5Kfjrl28rWFlZzjAzMYuEBQao3Lh+g+HGvbsMzExMDN++fWf4/PXLBzY2tqYNK1f2+4eHM2xcuRLigsT09Igf3384MTExbf767etBI319jU8fPsi+//jx/72HDxh5uLkZ7ty7y/Dz1687Avz8n2UUFR3Z2NjOySoqfmdhYGBg+PbtuwI7O8e5H79+8X379t357PnzYo+ePP7y6cuXc9++f69nYGRsvf/w4XdtLS2R799/bBUWFHr57sP7Jbs3b/ZkzswvUP3165fZ7z9//r988WIVAyPDr8tXr576+u3bpb9//7YwMjKeV1dV41NWVGoVEhDgPH761DJREeHaz1+/lqlpafUx6+jrRfz4+fPy+w8fTu/fsf3uw7t3L39+//4cv7DwGQYGhpdPbt9m4BcRFlNWVJC4fuvWASszs4C379792Ldt2xZBUdEdDP5hYSqQGIjDGa965uYKCalpZQwMDAxhMTG9DAwMDLaurhIkJY7A8IgGBgYGBgd3Dz2yUpeFo6O4rasrA9T24ZRxAAMTwMpgEJwLAAAAAElFTkSuQmCC",
|
||||
spider32 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAACYVBMVEUAAAAcJSU2Pz85QkM9RUWEhIWMjI2MkJEcJSU2Pz85QkM9RUWWlpc9RUVXXl4cJSU2Pz85QkM8REU9RUVRWFh6ens9RUVCSkpNVFRdY2McJSU5QkM7REQ9RUVGTk5KUlJQVldcY2Rla2uTk5WampscJSVUWltZX2BrcHF1e3scJSUjLCw9RUVASEhFTU1HTk9bYWJeZGRma2xudHV1eHiZmZocJSUyOjpJUFFQVldSWlpTWVpXXl5YXl5rb3B9fX6RkZIcJSUmLy8tNTU9RUVFTU1IT1BOVldRV1hTWlp0enocJSUfKChJUFBWXV1hZ2hnbGwcJSVETExLUlJLU1NNVVVPVlZYXl9cY2RiaGlobW5rcXFyd3h0eHgcJSUpMTFDS0tQV1dRV1hSWFlWXF1bYWJma2tobW5uc3SsrK0cJSVJUFBMVFROVlZVW1xZX2BdYmNhZ2hjaGhla2tqcHBscHE4Pz9KUlJRWVlSWVlXXF1aYGFbYWFfZWZlampqbW4cJSUgKSkiKysuNjY0PD01PT07QkNES0tHTk5JUFBMUlNMU1NOU1ROVVVPVVZRVlZRV1dSWVlWXFxXXV5aX2BbYWFbYWJcYmJcYmNcY2RdYmNgZmZhZmdkaWpkampkamtlamtla2tma2tma2xnbG1obW5pbG1pb3Bqb3Brb3BtcXJudHVvcHFvcXJvc3NwcXNwdXVxc3RzeXl1eXp2eXl3ent6e3x+gYKAhISBg4SKi4yLi4yWlpeampudnZ6fn6CkpaanqKiur6+vr7C4uLm6urq6u7u8vLy9vb3Av8DR0dL2b74UAAAAgHRSTlMAEBAQEBAQECAgICAgMDBAQEBAQEBAUFBQUGBgYGBgYGBgYGBgcHBwcHCAgICAgICAgICAgICPj4+Pj4+Pj4+Pj5+fn5+fn5+fn5+vr6+vr6+/v7+/v7+/v7+/v7+/z8/Pz8/Pz8/Pz8/P39/f39/f39/f39/f7+/v7+/v7+/v78x6RlYAAAGBSURBVDjLY2AYWUCSgUGAk4GBTdlUhQebvP7yjIgCPQbWzBMnjx5wwJSX37Rwfm1isqj9/iPHTuxYlyeMJi+yunfptBkZOw/uWj9h3vatcycu8eRGlldb3Vsts3ph/cFTh7fN3bCoe2Vf8+TZoQhTvBa6REozVC7cuPvQnmULJm1e2z+308eyJieEBSLPXbKQIUqQIczk+N6eNaumtnZMaWhaHM89m8XVCqJA02Y5w0xmga6yfVsamtrN4xoXNzS0JTHkK3CXy4EVFMumcxUy2LbENTVkZfEzMDAudtJyTmNwS2XQreAFyvOlK9louDNVaXurmjkGgnTMkWDgXswtNouFISEX6Awv+RihQi5OcYY4DtVARpCCFCMGhiJ1hjwFBpagEAaWEpFoC0WQOCOjFMRRwXYMDB4BDLJ+QLYsg7GBGjtasLnEMjCIrWBgyAZ7058FI9x1SoFEnTCDsCyIhynPILYYSFgbYpUDA5bpQBluXzxpI1yYAbd2sCMYRhwAAHB9ZPztbuMUAAAAAElFTkSuQmCC",
|
||||
spider64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJZUlEQVR42u1ZaXMU1xXlJ+gHpFITOy5sAcnIYCi2aIL2bTSSZrSP1NpHK41kISQBHgFaQIJBCMwi4TFUGYcPzggwEMcxHVGxQaag5QR/np/QP+Hmnsdr0hpmtEACwulb9aq7p7d3zz333Pt61q2zzTbbbLPNNttss80222yzzTbbVmu7MzKcJRWVkXjntqam6jyURPeGQqeTpqbOqp+evxC5dGlam5m5rE3PzGi8Hzx/4aLzbXDe09HdYxwZHaPc4mLFXVoW9pRXGNv3pDngeHlNLfE2Ljjj4xPOUGjSYKfpq6/+TLdv36bbX39Nt27epGvXvqSLl6bp3LlPtdOnz7jWrPNZ7kLCKCovp5bOTmP/4EHq6vmYMtzuSKbbbQCAHE8Rxd47MjrmuHjxkjF3/z4tLCzQkyc6PX78mB49ekQPHjygub/P0d27f6FrX/6JpqbO0YkT48E1R/sCr9cYHZ+gqrp64mPq+riXcoqKKC0vP9q6VyV/fQOiH+LrsPVY7z82PBKZnb1Bd+7cpfn5eQbgCT1hAADC/MN5uj83R99881eanZ2lL5gN/nrxjihAXwvOJ7l9vuiBQ4dF9LEtLC0V+2rv/ijTX6luaCS3rxT57wADAMTBQ4c9PIIDg4PBwYOHaHhklM5MnSWkwLff/o0+v3qVHv34Iz344QEDc4d8VVXUEAhQXXMzVdQqzKweKq6oABARzOGNOZ+Wl6fD6T25ubQrPT0E5xF93o82tbdjkkZ+iZfAAgbD6fZ6o339A8S0p7HjJ2h4eIQOHf6EujlV9nX3UOj0JDXzfXje+KlTdOPGDeF0T1+fGHg+2JSen08tHZ0CiPySEoPn8vq1IaOgIAzneQK0UzjcQd6qaqrlCVfV1+tpubnRnv5+2p2ZqYMF/oZGPTh0xLhy5Sr9wLn9j++/p5nLn9FxBoLZQJ1dKrkys6iYNeTExEnx3PqWFuF4W9deKq2upkEGCyzyMBC709MFC7r391Fjayv9MSdHZyCU1xJ5FjrNdN6VnU1KS4CjU4Yoh/m8CsezCguFJgAMV05ueP+BfhF5OL+gL9A/f/qJ7t3TaPLMFB09eoy6mTkMGg2PjTELOsS20OcTACgMKqJugqA0NtE7ycn0202b6A+ZmYIVAAKApGZlgRHB/0lqQPAqFEVE9hntM0R0ZblTzeswWdCeU8HAtYW+Uu0AUx+0f/jwoXD+56c/073v7tHU2XMiFbrUfVTNAtfL10FIAQL2QftsBrOEnavld5kg7E7PoF+99x79ev162rJrV9RMi6a2dvKUlQsR5uAgII7/ivMsbEE4g2hggjzC7LQL1OftovoO0WJKUn0gYEAn2hmMXo4QHIXQIfLfsfOXPwuLvB86cpQqamooyEzg1BLMwv04RkoE+B3B4BBBMHEcCwIP0N+ByJdUVhpgBJ7j4WvdANDjeTUglOaWEChfJF7uJzPX2HEPaj1vg7EAbHO5QnAeIPgqKvUB7gtAdbBgcvKMqOnc/NAIVwCcq21qElFnCgvaI9cBBFKhlSPbPzBIbbzduGULpWzfLkDAdZs++sgEwSlZqoIJMg2CzFSNGzODwdBfOi26+w4YTCm9LhDQwQDzdzguFf4FALjciTws8/u1yyx2N2/dovPnL9DRY8PkZ204xtuhoSM0wI7V8DEiirQCCHD+99u2CUdx3Lmvmz7kfemoGDgPEDr4HNKAf1MlAC4wgMGLWFJXQUrklZSEX6rLE2rOyDIQGlhgBUAyYFEZkm2vAGVi4qQ+x83M0389pevXr6OToy07d4qcR+krr/KzqpeJ/IfjGO+npDx3FCKHVPjd1q2LAMBI3ryZ9vL7U56BEzLfD80ACFba876OlGCQV9dAcT0Pyw7PgWij6zPP5Xt9EYgg+n3LosdVzdfz5CI8KY1LH31+5Yro9KanZwjHmPzmHTsoOeVDemfDBuE8dGVnWpqx3unUrE4CDLCAG64XAHB88IFgQV5xMY7DFmc16A6CZvnNBYYVcW+yKj0A/VHTsQ8dwMPNc6X+Gg0VIGbVpzYGWundjRujmGQWi9Eol7+TJ0/R2Nhx2sNlM9YJRPDdDRsM5DGPJB4KHOIhngHhAwixAGAAuDZ2lsuiYnFWBQOYrdEYNochilyiV6YHoH+rRNJkAG+fUw31PzU7Z1EFKPD69CIuQ1Bm6URoh8tFmVym3nc6rZOPyi0cD8HxeHPg3x2InNrbS79JTsYzNXmPuBclsO3ZvKwAOJEGsmI5rT0M+gSf3y9K5LIA1LUEIlL1k0AhCYBH5r9TCqBqib4D+c/1PyInGOThkvuaHCYALhlpbQWBMGR/4IpzTqlpbKQyf0045vdoe0zATHagSYMeWFMkbscnHRYPZjoFJaIiUkz9EJy15j/X3qCsAIqMcFjSWrNE1Iygg0fEmrtLzEUTdT/OhBFht9fHDVCbEUt3LJxi08B8Xj6vTDESriq9lVWqBECgHujqiqAUmufb1X3cfRXoluhjZWiwkOnSUcUS6ZD8LUmmhks6b5j1ezkAkAKZBe5QvPPcNBnoCawMwT66Qxk0R2xwwRAui2iSDGuaPDcubzo3EJq8wcx/9Vmk3QryH42QBQCFF0UagIiJtjX6DskIXTLEucJSHIIIMuO0BOcjn3A3ybU/lu5RCUBc5qA0Ih0Q2EWiCPRk7VfMNhjLW1zETic1tLYZDMKyuSsdfh5l6bwho5+0il4kyA0VohlNcF5FP8DlWo/VB16HYB2hJ0pzgIe2mcXxP2IOumPRY17U0tll8KIkZNb+sppafOxYkQPSaYfchyYoL9GMqWYpTLRIq1QUcT4O3aPQgqVqPwIOIMwDhzX6mQUFIQAgo+9MzcrWrML3mj6+YIKiFCZyhL87RqVQKrEskF+P1BUvfLCAkfRwoPUtq6l5o5+lZb5SolJo6oT8avTCl+c9OTmat6pKW8mLkvBpGzlvsiGuQr4ZEEwA1EQgoR/gNtxIxKBluz+OtMJiF31jHxqXBiAqAUj4WRxpADFM0DCFlv1khvX7Wol4vF4AIldVVxdZqlrIfiCYQPHDy6bAGv7nKYRVY6JewExZVAP+ey5Rv+Ba97aaUHMW5NauLmMZFkegBb/EP14d6NoS9QLWFSzWBmuZza8CQmSpXsAqmGtVy14VALWuuYWWy+W3OteXa4jwceQX6+BKG6J1/8+2VCNkm2222WabbbbZZpttttlmm22rt38DCdA0vq3bcAkAAAAASUVORK5CYII=";
|
||||
|
||||
// Favicon
|
||||
document.querySelector("link[rel=icon]").setAttribute("href", "data:image/png;base64," + spider16);
|
||||
|
||||
// Bake button
|
||||
document.querySelector("#bake img").setAttribute("src", "data:image/png;base64," + spider32);
|
||||
|
||||
// About box
|
||||
document.querySelector(".about-img-left").setAttribute("src", "data:image/png;base64," + spider64);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Replaces all instances of the word "cyber" with "spider".
|
||||
* #spiderchef
|
||||
*/
|
||||
SeasonalWaiter.prototype.insertSpiderText = function() {
|
||||
// Title
|
||||
document.title = document.title.replace(/Cyber/g, "Spider");
|
||||
|
||||
// Body
|
||||
SeasonalWaiter.treeWalk(document.body, function(node) {
|
||||
// process only text nodes
|
||||
if (node.nodeType === 3) {
|
||||
node.nodeValue = node.nodeValue.replace(/Cyber/g, "Spider");
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Bake button
|
||||
SeasonalWaiter.treeWalk(document.getElementById("bake-group"), function(node) {
|
||||
// process only text nodes
|
||||
if (node.nodeType === 3) {
|
||||
node.nodeValue = node.nodeValue.replace(/Bake/g, "Spin");
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Recipe title
|
||||
document.querySelector("#recipe .title").innerHTML = "Web";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Listen for the Konami code sequence of keys. Turn the page upside down if they are all heard in
|
||||
* sequence.
|
||||
@@ -89,8 +32,8 @@ SeasonalWaiter.prototype.insertSpiderText = function() {
|
||||
*/
|
||||
SeasonalWaiter.prototype.konamiCodeListener = function(e) {
|
||||
this.kkeys.push(e.keyCode);
|
||||
var konami = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
|
||||
for (var i = 0; i < this.kkeys.length; i++) {
|
||||
const konami = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
|
||||
for (let i = 0; i < this.kkeys.length; i++) {
|
||||
if (this.kkeys[i] !== konami[i]) {
|
||||
this.kkeys = [];
|
||||
break;
|
||||
@@ -102,53 +45,4 @@ SeasonalWaiter.prototype.konamiCodeListener = function(e) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Walks through the entire DOM starting at the specified element and operates on each node.
|
||||
*
|
||||
* @static
|
||||
* @param {element} parent - The DOM node to start from
|
||||
* @param {Function} fn - The callback function to operate on each node
|
||||
* @param {booleam} allNodes - Whether to operate on every node or not
|
||||
*/
|
||||
SeasonalWaiter.treeWalk = (function() {
|
||||
// Create closure for constants
|
||||
var skipTags = {
|
||||
"SCRIPT": true, "IFRAME": true, "OBJECT": true,
|
||||
"EMBED": true, "STYLE": true, "LINK": true, "META": true
|
||||
};
|
||||
|
||||
return function(parent, fn, allNodes) {
|
||||
var node = parent.firstChild;
|
||||
|
||||
while (node && node !== parent) {
|
||||
if (allNodes || node.nodeType === 1) {
|
||||
if (fn(node) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If it's an element &&
|
||||
// has children &&
|
||||
// has a tagname && is not in the skipTags list
|
||||
// then, we can enumerate children
|
||||
if (node.nodeType === 1 &&
|
||||
node.firstChild &&
|
||||
!(node.tagName && skipTags[node.tagName])) {
|
||||
node = node.firstChild;
|
||||
} else if (node.nextSibling) {
|
||||
node = node.nextSibling;
|
||||
} else {
|
||||
// No child and no nextsibling
|
||||
// Find parent that has a nextSibling
|
||||
while ((node = node.parentNode) !== parent) {
|
||||
if (node.nextSibling) {
|
||||
node = node.nextSibling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export default SeasonalWaiter;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @constructor
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
*/
|
||||
var WindowWaiter = function(app) {
|
||||
const WindowWaiter = function(app) {
|
||||
this.app = app;
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ WindowWaiter.prototype.windowBlur = function() {
|
||||
* a long time and the browser has swapped out all its memory.
|
||||
*/
|
||||
WindowWaiter.prototype.windowFocus = function() {
|
||||
var unfocusedTime = new Date().getTime() - this.windowBlurTime;
|
||||
const unfocusedTime = new Date().getTime() - this.windowBlurTime;
|
||||
if (unfocusedTime > 60000) {
|
||||
this.app.silentBake();
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* CSS index
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import "google-code-prettify/src/prettify.css";
|
||||
|
||||
import "./lib/bootstrap.less";
|
||||
import "bootstrap-switch/src/less/bootstrap3/build.less";
|
||||
import "bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css";
|
||||
|
||||
import "./structure/overrides.css";
|
||||
import "./structure/layout.css";
|
||||
import "./structure/utils.css";
|
||||
import "./themes/classic.css";
|
||||
File diff suppressed because one or more lines are too long
@@ -1,113 +0,0 @@
|
||||
/* Bootstrap */
|
||||
|
||||
button,
|
||||
a:focus {
|
||||
outline: none;
|
||||
-moz-outline-style: none;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.btn-default:focus {
|
||||
background-color: #fff;
|
||||
border-color: #adadad;
|
||||
}
|
||||
|
||||
.btn-default:hover,
|
||||
.btn-default:active {
|
||||
background-color: #ebebeb;
|
||||
border-color: #adadad;
|
||||
}
|
||||
|
||||
.btn,
|
||||
.btn-lg,
|
||||
.nav-tabs>li>a,
|
||||
.form-control,
|
||||
.popover,
|
||||
.alert,
|
||||
.modal-content,
|
||||
.tooltip-inner,
|
||||
.dropdown-menu {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: searchfield;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: searchfield-cancel-button;
|
||||
}
|
||||
|
||||
.modal {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
code {
|
||||
border: 0;
|
||||
white-space: pre-wrap;
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
|
||||
pre {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
blockquote a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.panel-body:before,
|
||||
.panel-body:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.table-nonfluid {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
|
||||
/* Bootstrap-switch */
|
||||
|
||||
.bootstrap-switch,
|
||||
.bootstrap-switch-container,
|
||||
.bootstrap-switch-handle-on,
|
||||
.bootstrap-switch-handle-off,
|
||||
.bootstrap-switch-label {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
/* Sortable */
|
||||
|
||||
.sortable-ghost {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
||||
/* Bootstrap Colorpicker */
|
||||
|
||||
.colorpicker-element {
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.colorpicker-color,
|
||||
.colorpicker-color div {
|
||||
height: 100px;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
.word-wrap {
|
||||
white-space: pre !important;
|
||||
word-wrap: normal !important;
|
||||
overflow-x: scroll !important;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.blur {
|
||||
color: transparent !important;
|
||||
text-shadow: rgba(0, 0, 0, 0.95) 0 0 10px !important;
|
||||
}
|
||||
|
||||
.no-select {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.konami {
|
||||
-ms-transform: rotate(180deg);
|
||||
-webkit-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.hl1, .hlyellow { background-color: #fff000; }
|
||||
.hl2, .hlblue { background-color: #95dfff; }
|
||||
.hl3, .hlred { background-color: #ffb6b6; } /* Half-Life 3 confirmed :O */
|
||||
.hl4, .hlorange { background-color: #fcf8e3; }
|
||||
.hl5, .hlgreen { background-color: #8de768; }
|
||||
@@ -1,258 +0,0 @@
|
||||
#banner {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #ddd;
|
||||
font-weight: bold;
|
||||
color: #424242;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
background-color: #eee;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50%;
|
||||
}
|
||||
|
||||
.gutter.gutter-horizontal {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAeCAYAAAAGos/EAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAlSURBVChTYzxz5sx/BiBgAhEgwPju3TtUEZZ79+6BGcNcDQMDACWJMFs4hNOSAAAAAElFTkSuQmCC');
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.gutter.gutter-vertical {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAACCAYAAABPJGxCAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACHDwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKL2lDQ1BJQ0MgUHJvZmlsZQAASMedlndUVNcWh8+9d3qhzTDSGXqTLjCA9C4gHQRRGGYGGMoAwwxNbIioQEQREQFFkKCAAaOhSKyIYiEoqGAPSBBQYjCKqKhkRtZKfHl57+Xl98e939pn73P32XuftS4AJE8fLi8FlgIgmSfgB3o401eFR9Cx/QAGeIABpgAwWempvkHuwUAkLzcXerrICfyL3gwBSPy+ZejpT6eD/0/SrFS+AADIX8TmbE46S8T5Ik7KFKSK7TMipsYkihlGiZkvSlDEcmKOW+Sln30W2VHM7GQeW8TinFPZyWwx94h4e4aQI2LER8QFGVxOpohvi1gzSZjMFfFbcWwyh5kOAIoktgs4rHgRm4iYxA8OdBHxcgBwpLgvOOYLFnCyBOJDuaSkZvO5cfECui5Lj25qbc2ge3IykzgCgaE/k5XI5LPpLinJqUxeNgCLZ/4sGXFt6aIiW5paW1oamhmZflGo/7r4NyXu7SK9CvjcM4jW94ftr/xS6gBgzIpqs+sPW8x+ADq2AiB3/w+b5iEAJEV9a7/xxXlo4nmJFwhSbYyNMzMzjbgclpG4oL/rfzr8DX3xPSPxdr+Xh+7KiWUKkwR0cd1YKUkpQj49PZXJ4tAN/zzE/zjwr/NYGsiJ5fA5PFFEqGjKuLw4Ubt5bK6Am8Kjc3n/qYn/MOxPWpxrkSj1nwA1yghI3aAC5Oc+gKIQARJ5UNz13/vmgw8F4psXpjqxOPefBf37rnCJ+JHOjfsc5xIYTGcJ+RmLa+JrCdCAACQBFcgDFaABdIEhMANWwBY4AjewAviBYBAO1gIWiAfJgA8yQS7YDApAEdgF9oJKUAPqQSNoASdABzgNLoDL4Dq4Ce6AB2AEjIPnYAa8AfMQBGEhMkSB5CFVSAsygMwgBmQPuUE+UCAUDkVDcRAPEkK50BaoCCqFKqFaqBH6FjoFXYCuQgPQPWgUmoJ+hd7DCEyCqbAyrA0bwwzYCfaGg+E1cBycBufA+fBOuAKug4/B7fAF+Dp8Bx6Bn8OzCECICA1RQwwRBuKC+CERSCzCRzYghUg5Uoe0IF1IL3ILGUGmkXcoDIqCoqMMUbYoT1QIioVKQ21AFaMqUUdR7age1C3UKGoG9QlNRiuhDdA2aC/0KnQcOhNdgC5HN6Db0JfQd9Dj6DcYDIaG0cFYYTwx4ZgEzDpMMeYAphVzHjOAGcPMYrFYeawB1g7rh2ViBdgC7H7sMew57CB2HPsWR8Sp4sxw7rgIHA+XhyvHNeHO4gZxE7h5vBReC2+D98Oz8dn4Enw9vgt/Az+OnydIE3QIdoRgQgJhM6GC0EK4RHhIeEUkEtWJ1sQAIpe4iVhBPE68QhwlviPJkPRJLqRIkpC0k3SEdJ50j/SKTCZrkx3JEWQBeSe5kXyR/Jj8VoIiYSThJcGW2ChRJdEuMSjxQhIvqSXpJLlWMkeyXPKk5A3JaSm8lLaUixRTaoNUldQpqWGpWWmKtKm0n3SydLF0k/RV6UkZrIy2jJsMWyZf5rDMRZkxCkLRoLhQWJQtlHrKJco4FUPVoXpRE6hF1G+o/dQZWRnZZbKhslmyVbJnZEdoCE2b5kVLopXQTtCGaO+XKC9xWsJZsmNJy5LBJXNyinKOchy5QrlWuTty7+Xp8m7yifK75TvkHymgFPQVAhQyFQ4qXFKYVqQq2iqyFAsVTyjeV4KV9JUCldYpHVbqU5pVVlH2UE5V3q98UXlahabiqJKgUqZyVmVKlaJqr8pVLVM9p/qMLkt3oifRK+g99Bk1JTVPNaFarVq/2ry6jnqIep56q/ojDYIGQyNWo0yjW2NGU1XTVzNXs1nzvhZei6EVr7VPq1drTltHO0x7m3aH9qSOnI6XTo5Os85DXbKug26abp3ubT2MHkMvUe+A3k19WN9CP16/Sv+GAWxgacA1OGAwsBS91Hopb2nd0mFDkqGTYYZhs+GoEc3IxyjPqMPohbGmcYTxbuNe408mFiZJJvUmD0xlTFeY5pl2mf5qpm/GMqsyu21ONnc332jeaf5ymcEyzrKDy+5aUCx8LbZZdFt8tLSy5Fu2WE5ZaVpFW1VbDTOoDH9GMeOKNdra2Xqj9WnrdzaWNgKbEza/2BraJto22U4u11nOWV6/fMxO3Y5pV2s3Yk+3j7Y/ZD/ioObAdKhzeOKo4ch2bHCccNJzSnA65vTC2cSZ79zmPOdi47Le5bwr4urhWuja7ybjFuJW6fbYXd09zr3ZfcbDwmOdx3lPtKe3527PYS9lL5ZXo9fMCqsV61f0eJO8g7wrvZ/46Pvwfbp8Yd8Vvnt8H67UWslb2eEH/Lz89vg98tfxT/P/PgAT4B9QFfA00DQwN7A3iBIUFdQU9CbYObgk+EGIbogwpDtUMjQytDF0Lsw1rDRsZJXxqvWrrocrhHPDOyOwEaERDRGzq91W7109HmkRWRA5tEZnTdaaq2sV1iatPRMlGcWMOhmNjg6Lbor+wPRj1jFnY7xiqmNmWC6sfaznbEd2GXuKY8cp5UzE2sWWxk7G2cXtiZuKd4gvj5/munAruS8TPBNqEuYS/RKPJC4khSW1JuOSo5NP8WR4ibyeFJWUrJSBVIPUgtSRNJu0vWkzfG9+QzqUvia9U0AV/Uz1CXWFW4WjGfYZVRlvM0MzT2ZJZ/Gy+rL1s3dkT+S453y9DrWOta47Vy13c+7oeqf1tRugDTEbujdqbMzfOL7JY9PRzYTNiZt/yDPJK817vSVsS1e+cv6m/LGtHlubCyQK+AXD22y31WxHbedu799hvmP/jk+F7MJrRSZF5UUfilnF174y/ariq4WdsTv7SyxLDu7C7OLtGtrtsPtoqXRpTunYHt897WX0ssKy13uj9l4tX1Zes4+wT7hvpMKnonO/5v5d+z9UxlfeqXKuaq1Wqt5RPXeAfWDwoOPBlhrlmqKa94e4h+7WetS212nXlR/GHM44/LQ+tL73a8bXjQ0KDUUNH4/wjowcDTza02jV2Nik1FTSDDcLm6eORR67+Y3rN50thi21rbTWouPguPD4s2+jvx064X2i+yTjZMt3Wt9Vt1HaCtuh9uz2mY74jpHO8M6BUytOdXfZdrV9b/T9kdNqp6vOyJ4pOUs4m3924VzOudnzqeenL8RdGOuO6n5wcdXF2z0BPf2XvC9duex++WKvU++5K3ZXTl+1uXrqGuNax3XL6+19Fn1tP1j80NZv2d9+w+pG503rm10DywfODjoMXrjleuvyba/b1++svDMwFDJ0dzhyeOQu++7kvaR7L+9n3J9/sOkh+mHhI6lH5Y+VHtf9qPdj64jlyJlR19G+J0FPHoyxxp7/lP7Th/H8p+Sn5ROqE42TZpOnp9ynbj5b/Wz8eerz+emCn6V/rn6h++K7Xxx/6ZtZNTP+kv9y4dfiV/Kvjrxe9rp71n/28ZvkN/NzhW/l3x59x3jX+z7s/cR85gfsh4qPeh+7Pnl/eriQvLDwG/eE8/s3BCkeAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAI0lEQVQYV2M8c+bMfwYgUFJSAlEM9+7dA9O05jOBSboDBgYAtPcYZ1oUA30AAAAASUVORK5CYII=');
|
||||
cursor: ns-resize;
|
||||
}
|
||||
|
||||
.operation {
|
||||
border: 1px solid #999;
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.op-list .operation { /*blue*/
|
||||
color: #3a87ad;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
}
|
||||
|
||||
#rec-list .operation { /*green*/
|
||||
color: #468847;
|
||||
background-color: #dff0d8;
|
||||
border-color: #d6e9c6;
|
||||
}
|
||||
|
||||
#controls {
|
||||
border-top: 1px solid #ddd;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.textarea-wrapper textarea,
|
||||
.textarea-wrapper div {
|
||||
font-family: Consolas, monospace;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.io-info {
|
||||
font-family: Consolas, monospace;
|
||||
font-weight: normal;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
.arg-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.arg-input {
|
||||
height: 34px;
|
||||
font-size: 15px;
|
||||
line-height: 1.428571429;
|
||||
color: #424242;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 6px 8px;
|
||||
height: 34px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #fff;
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
.arg[disabled] {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
textarea.arg {
|
||||
color: #424242;
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
|
||||
.break {
|
||||
color: #b94a48 !important;
|
||||
background-color: #f2dede !important;
|
||||
border-color: #eed3d7 !important;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
background-color: #fafafa;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.category-title[href='#catFavourites'] {
|
||||
border-bottom-color: #ddd;
|
||||
}
|
||||
|
||||
.category-title[aria-expanded=true] {
|
||||
border-bottom-color: #ddd;
|
||||
}
|
||||
|
||||
.category-title.collapsed {
|
||||
border-bottom-color: #eee;
|
||||
}
|
||||
|
||||
.category-title:hover {
|
||||
color: #3a87ad;
|
||||
}
|
||||
|
||||
#search {
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
}
|
||||
|
||||
.dropping-file {
|
||||
border: 5px dashed #3a87ad !important;
|
||||
}
|
||||
|
||||
.selected-op {
|
||||
color: #c09853 !important;
|
||||
background-color: #fcf8e3 !important;
|
||||
border-color: #fbeed5 !important;
|
||||
}
|
||||
|
||||
.option-item input[type=number] {
|
||||
font-size: 14px;
|
||||
line-height: 1.428571429;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.favourites-hover {
|
||||
color: #468847;
|
||||
background-color: #dff0d8;
|
||||
border: 2px dashed #468847 !important;
|
||||
padding: 8px 8px 9px 8px;
|
||||
}
|
||||
|
||||
#edit-favourites-list {
|
||||
border: 1px solid #bce8f1;
|
||||
}
|
||||
|
||||
#edit-favourites-list .operation {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
#edit-favourites-list .operation:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.subtext {
|
||||
font-style: italic;
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#save-footer {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.flow-control-op {
|
||||
color: #396f3a !important;
|
||||
background-color: #c7e4ba !important;
|
||||
border-color: #b3dba2 !important;
|
||||
}
|
||||
|
||||
.flow-control-op.break {
|
||||
color: #94312f !important;
|
||||
background-color: #eabfbf !important;
|
||||
border-color: #e2aeb5 !important;
|
||||
}
|
||||
|
||||
#support-modal textarea {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#save-text,
|
||||
#load-text {
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
|
||||
button.dropdown-toggle {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #bbb;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: #999 !important;
|
||||
background-color: #dfdfdf !important;
|
||||
border-color: #cdcdcd !important;
|
||||
}
|
||||
|
||||
.grey {
|
||||
color: #333;
|
||||
background-color: #f5f5f5;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.dark-blue {
|
||||
color: #fff;
|
||||
background-color: #428bca;
|
||||
border-color: #428bca;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #b94a48;
|
||||
background-color: #f2dede;
|
||||
border-color: #eed3d7;
|
||||
}
|
||||
|
||||
.amber {
|
||||
color: #c09853;
|
||||
background-color: #fcf8e3;
|
||||
border-color: #fbeed5;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: #468847;
|
||||
background-color: #dff0d8;
|
||||
border-color: #d6e9c6;
|
||||
}
|
||||
|
||||
.blue {
|
||||
color: #3a87ad;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
-->
|
||||
<!-- htmlmin:ignore -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="classic">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>CyberChef</title>
|
||||
@@ -30,15 +30,63 @@
|
||||
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
|
||||
|
||||
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
|
||||
|
||||
<script type="application/javascript">
|
||||
// Load theme before the preloader is shown
|
||||
document.querySelector(":root").className = JSON.parse(localStorage.getItem("options")).theme;
|
||||
|
||||
// Define loading messages
|
||||
const loadingMsgs = [
|
||||
"Proving P = NP...",
|
||||
"Computing 6 x 9...",
|
||||
"Mining bitcoin...",
|
||||
"Dividing by 0...",
|
||||
"Initialising Skynet...",
|
||||
"[REDACTED]",
|
||||
"Downloading more RAM...",
|
||||
"Loading more loading messages...",
|
||||
"Ordering 1s and 0s...",
|
||||
"Navigating neural network...",
|
||||
"Importing machine learning..."
|
||||
];
|
||||
|
||||
// Shuffle array using Durstenfeld algorithm
|
||||
for (let i = loadingMsgs.length - 1; i > 0; --i) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
const temp = loadingMsgs[i];
|
||||
loadingMsgs[i] = loadingMsgs[j];
|
||||
loadingMsgs[j] = temp;
|
||||
}
|
||||
|
||||
// Show next loading message then move it to the end of the array
|
||||
function changeLoadingMsg() {
|
||||
const msg = loadingMsgs.shift();
|
||||
try {
|
||||
const el = document.getElementById("preloader-msg");
|
||||
el.className = "loading"; // Causes CSS transition on first message
|
||||
el.innerHTML = msg;
|
||||
} catch (err) {} // Ignore errors if DOM not yet ready
|
||||
loadingMsgs.push(msg);
|
||||
}
|
||||
|
||||
changeLoadingMsg();
|
||||
window.loadingMsgsInt = setInterval(changeLoadingMsg, (Math.random() * 1000) + 1000);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Preloader overlay -->
|
||||
<div id="loader-wrapper">
|
||||
<div id="preloader"></div>
|
||||
<div id="preloader-msg"></div>
|
||||
</div>
|
||||
<!-- End preloader overlay -->
|
||||
<span id="edit-favourites" class="btn btn-default btn-sm"><img aria-hidden="true" src="<%- require('../static/images/favourite-16x16.png') %>" alt="Star Icon"/> Edit</span>
|
||||
<div id="alert" class="alert alert-danger">
|
||||
<button type="button" class="close" id="alert-close">×</button>
|
||||
<span id="alert-content"></span>
|
||||
</div>
|
||||
<div id="content-wrapper">
|
||||
<div id="banner" class="green">
|
||||
<div id="banner">
|
||||
<% if (htmlWebpackPlugin.options.inline) { %>
|
||||
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
|
||||
<% } else { %>
|
||||
@@ -57,17 +105,17 @@
|
||||
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img aria-hidden="true" src="<%- require('../static/images/help-22x22.png') %>" alt="Question Mark Icon"/></a>
|
||||
<a href="#" id="options" class="banner-right">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
|
||||
</div>
|
||||
<div id="wrapper">
|
||||
<div id="workspace-wrapper">
|
||||
<div id="operations" class="split split-horizontal no-select">
|
||||
<div class="title no-select">Operations</div>
|
||||
<input type="search" class="form-control" id="search" placeholder="Search..." autocomplete="off">
|
||||
<ul class="op-list" id="search-results"></ul>
|
||||
<div class="panel-group no-select" id="categories"></div>
|
||||
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off">
|
||||
<ul id="search-results" class="op-list"></ul>
|
||||
<div id="categories" class="panel-group no-select"></div>
|
||||
</div>
|
||||
|
||||
<div id="recipe" class="split split-horizontal no-select">
|
||||
<div class="title no-select">Recipe</div>
|
||||
<ul id="rec-list" class="no-select"></ul>
|
||||
<ul id="rec-list" class="list-area no-select"></ul>
|
||||
|
||||
<div id="controls" class="no-select">
|
||||
<div id="operational-controls">
|
||||
@@ -100,6 +148,7 @@
|
||||
<div id="input" class="split no-select">
|
||||
<div class="title no-select">
|
||||
<label for="input-text">Input</label>
|
||||
<div class="loading-icon" style="display: none"></div>
|
||||
<div class="btn-group io-btn-group">
|
||||
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
|
||||
@@ -116,6 +165,7 @@
|
||||
<div id="output" class="split">
|
||||
<div class="title no-select">
|
||||
<label for="output-text">Output</label>
|
||||
<div class="loading-icon" style="display: none"></div>
|
||||
<div class="btn-group io-btn-group">
|
||||
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
|
||||
@@ -163,6 +213,7 @@
|
||||
<input type="checkbox" id="save-link-recipe-checkbox" checked> <label for="save-link-recipe-checkbox"> Include recipe </label>
|
||||
<input type="checkbox" id="save-link-input-checkbox" checked> <label for="save-link-input-checkbox"> Include input </label>
|
||||
</div>
|
||||
<br>
|
||||
<a id="save-link" style="word-wrap: break-word;"></a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -205,6 +256,13 @@
|
||||
</div>
|
||||
<div class="modal-body" id="options-body">
|
||||
<p style="font-weight: bold">Please note that these options will persist between sessions.</p>
|
||||
<div class="option-item">
|
||||
<select option="theme" id="theme">
|
||||
<option value="classic">Classic</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
<label for="theme"> Theme (only supported in modern browsers)</label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="update_url" id="update_url" checked />
|
||||
<label for="update_url"> Update the URL when the input or recipe changes </label>
|
||||
@@ -278,8 +336,11 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" alt="CyberChef Logo"/>
|
||||
<p class="subtext">Compile time: <%= htmlWebpackPlugin.options.compileTime %></p>
|
||||
<p>© Crown Copyright 2016.</p>
|
||||
<p class="subtext">
|
||||
Version <%= htmlWebpackPlugin.options.version %><br>
|
||||
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
|
||||
</p>
|
||||
<p>© Crown Copyright 2016.</p>
|
||||
<p>Licenced under the Apache Licence, Version 2.0.</p>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
// CSS
|
||||
import "./css/index.js";
|
||||
// Styles
|
||||
import "./stylesheets/index.js";
|
||||
|
||||
// Libs
|
||||
import "babel-polyfill";
|
||||
@@ -23,8 +23,8 @@ import OperationConfig from "../core/config/OperationConfig.js";
|
||||
/**
|
||||
* Main function used to build the CyberChef web app.
|
||||
*/
|
||||
var main = function() {
|
||||
var defaultFavourites = [
|
||||
function main() {
|
||||
const defaultFavourites = [
|
||||
"To Base64",
|
||||
"From Base64",
|
||||
"To Hex",
|
||||
@@ -37,7 +37,7 @@ var main = function() {
|
||||
"Fork"
|
||||
];
|
||||
|
||||
var defaultOptions = {
|
||||
const defaultOptions = {
|
||||
updateUrl : true,
|
||||
showHighlighter : true,
|
||||
treatAsUtf8 : true,
|
||||
@@ -46,12 +46,13 @@ var main = function() {
|
||||
errorTimeout : 4000,
|
||||
autoBakeThreshold : 200,
|
||||
attemptHighlight : true,
|
||||
theme : "classic",
|
||||
};
|
||||
|
||||
document.removeEventListener("DOMContentLoaded", main, false);
|
||||
window.app = new App(Categories, OperationConfig, defaultFavourites, defaultOptions);
|
||||
window.app.setup();
|
||||
};
|
||||
}
|
||||
|
||||
// Fix issues with browsers that don't support console.log()
|
||||
window.console = console || {log: function() {}, error: function() {}};
|
||||
|
||||
22
src/web/stylesheets/components/_alert.css
Normal file
22
src/web/stylesheets/components/_alert.css
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Alert styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
#alert {
|
||||
position: fixed;
|
||||
width: 30%;
|
||||
margin: 30px auto;
|
||||
top: 10px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 2000;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#alert a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
13
src/web/stylesheets/components/_button.css
Normal file
13
src/web/stylesheets/components/_button.css
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Button styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
button img,
|
||||
span.btn img {
|
||||
margin-right: 3px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
43
src/web/stylesheets/components/_list.css
Normal file
43
src/web/stylesheets/components/_list.css
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Operation list styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
.op-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
background-color: var(--secondary-background-colour);
|
||||
border-bottom: 1px solid var(--secondary-border-colour);
|
||||
font-weight: var(--title-weight);
|
||||
}
|
||||
|
||||
.category-title[href='#catFavourites'] {
|
||||
border-bottom-color: var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.category-title[aria-expanded=true] {
|
||||
border-bottom-color: var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.category-title.collapsed {
|
||||
border-bottom-color: var(--secondary-border-colour);
|
||||
}
|
||||
|
||||
.category-title:hover {
|
||||
color: var(--op-list-operation-font-colour);
|
||||
}
|
||||
|
||||
.category {
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border: none;
|
||||
}
|
||||
196
src/web/stylesheets/components/_operation.css
Normal file
196
src/web/stylesheets/components/_operation.css
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Operation styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
.operation {
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
list-style-type: none;
|
||||
position: relative;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.arg-group {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.arg-group-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.inline-args {
|
||||
float: left;
|
||||
width: auto;
|
||||
margin-right: 30px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.inline-args input[type="checkbox"] {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.inline-args input[type="number"] {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.arg-title {
|
||||
font-weight: var(--arg-title-font-weight);
|
||||
}
|
||||
|
||||
.arg-input {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
padding: 6px 12px;
|
||||
vertical-align: middle;
|
||||
height: var(--arg-input-height);
|
||||
font-size: var(--arg-input-font-size);
|
||||
line-height: var(--arg-input-line-height);
|
||||
color: var(--arg-font-colour);
|
||||
background-color: var(--arg-background);
|
||||
border: 1px solid var(--arg-border-colour);
|
||||
font-family: var(--fixed-width-font-family);
|
||||
}
|
||||
|
||||
.short-string {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
select {
|
||||
display: block;
|
||||
padding: 6px 8px;
|
||||
height: 34px;
|
||||
border: 1px solid var(--arg-border-colour);
|
||||
background-color: var(--arg-background);
|
||||
color: var(--arg-font-colour);
|
||||
}
|
||||
|
||||
.arg[disabled] {
|
||||
cursor: not-allowed;
|
||||
opacity: 1;
|
||||
background-color: var(--arg-disabled-background);
|
||||
}
|
||||
|
||||
textarea.arg {
|
||||
width: 100%;
|
||||
min-height: 50px;
|
||||
height: 70px;
|
||||
margin-top: 5px;
|
||||
border: 1px solid var(--arg-border-colour);
|
||||
resize: vertical;
|
||||
color: var(--arg-font-colour);
|
||||
background-color: var(--arg-background);
|
||||
font-family: var(--fixed-width-font-family);
|
||||
}
|
||||
|
||||
.arg-label {
|
||||
display: table-cell;
|
||||
width: 1px;
|
||||
padding-right: 10px;
|
||||
font-weight: normal;
|
||||
vertical-align: middle;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.editable-option {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.editable-option-select {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.editable-option-input {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
width: calc(100% - 20px);
|
||||
height: calc(100% - 2px) !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
button.dropdown-toggle {
|
||||
background-color: var(--secondary-background-colour);
|
||||
}
|
||||
|
||||
.op-icon {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.recip-icons {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
right: 10px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.recip-icon {
|
||||
margin-right: 10px;
|
||||
vertical-align: baseline;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.disable-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-top: -1px;
|
||||
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAACfElEQVQ4y6WTPWgTYRjHf8nlfVvuoDVIP4Yuki4WHKoUqggFRUTsUEGkVG2hmCq6OnTwIxYHB+eijZOKdLNDW1pKKyGigh8dBHUJElxyBgx3vEnukvdyDrUhRXDxGR+e/+/583xEwjDkfyIGwNVTzURm4tYAMA6MAoN/0tvAMrA48uL+l2bx4w0iYRjSuHKC6OnTZLqHk8CcaZq9bW1tSCkBqNVq+L5PpVIpAHdGfr5LN9bXiT7Z2nGgteb1/qFkLBJZ6OjowHEc8vk8pVIJgHg8TldXF52dnb2u6y5s7R/iuF5JSyAKkLl4eyAMwznLsrBtm1wu99Z13amk+BFJih8R13WXANrb27EsizAM5zIXbw+wC9Baj0spe5VSFAqFt4ZhXJ6ufXuK55E5cDKVSCTGenp6yGazKKWQUvZqrcebgCAIRqWUOI6DEOLR1K8POapVMgfPpoC7u2LLspYcx0FKSRAEo60OBg3DwPd9Jr5vPqWvj8zh83vEwL2J75vnfN/HMAy01oPNNQZBQBAEO1OvVsl0D/8lTuZfpYDd7gRBQKuD7XK5jGmarB679PIv8deVFJUKq8cuTZqmSblcRmu93QpYVkohhMCyrLE94n2/UlSrbJy5kRBCXBNCoJRCa73cClh0XbfgeR6WZZHNZunv719KvnmeYnWVVxdmJ2Ox2DMhxFHP83Bdt6C1XgR2LvHzQDvvb84npZQL8Xgc0zSJRqN7br7RaFCpVCiVStRqtZmhh9fTh754TQdMr82nPc+bsW27UCwWUUpRr9ep1+sopSgWi9i2XfA8b2Z6bT6ttabp4GMi0uz0aXbhn890+MFM85mO5MIdwP/Eb1pMUCdctYRzAAAAAElFTkSuQmCC') no-repeat;
|
||||
}
|
||||
|
||||
.disable-icon-selected {
|
||||
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACFUlEQVR4XqWTP0tbURjGn9zY3mjBwsUhBQtS6XKxiNypIGZJ6SKYUYdaKWg7OrrE3pYO+Qit3dpFuuQO6lI7Z4nESQdjlJbkJh0MksSb3Jvk9H0gjZFu9YWH83LO7zn/3nNCSincJobAeP1sEDBFi6J50UyPy4l2RNuioz756Ts0tt1OB4jH2a52Ne2HGh9PwrJm2EcxZx/HyPRYMDgB2u02/N3d1c7w8BZMM1ptNJBPp3GwsUExB/s4RoYsPf0JOkFgdoH34YkJ/D48xC/HyTTOzl5ayWSIktwxqlVo0SjIkKWnP0Hg+4swjGitVMJFNpu5o+svptfXv6DZBDIZezoWS3Db3A0ZsvRcH8H354dGR9EoFHA3EvlorqycwvOAXM4G8Pav+f7YmEOGLD1gsIzl54+V+vBK/Yw9ZAv1LQW1FrdFSnKVfQTK5liPUfRI9I8ArqiPjLAF9vcHVybyzlpasgcZeq7voNXKNSsV3DMMXB4fp/8xLyzYuLri2DIZsvQM3sFOzXURiUR4zsQNcyrFleFVKpNyP2/IkKVnsArbF65bbkqplJSJZrl5x5qbs7G3h3artSyV+arr+lMyZOnpP2Wp6ZFos3R+vvUgCGDNzgKalkA4rECIr07662J2i0X4nrfJJ33jJT6Zmvpcr9XWCicn5WI+j7rrAmKgmLOPY2TI0sPgb8TBZOi/PpN1qnDr7/wH3jxgB/FKIXkAAAAASUVORK5CYII=') no-repeat;
|
||||
}
|
||||
|
||||
.breakpoint {
|
||||
float: right;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: #eee;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.breakpoint-selected {
|
||||
background: #eee url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAXVBMVEXIUkvzUVHzTEzzn5785eXrbW24BgbzWVnze3vzVVXzY2Pyion509PzbW3zXV1UMxj0l5f1srKbRTRgOxzJDg796ur74ODfIyP5zs6LLx3pNTXYGxuxdkVZNhn////sCC1eAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAABWSURBVBjTnc+7EoAgDERRTOQVxMEZFAf//z8FjAUFDbfb060QU2FwxngimxnCea3bjegSgz+0tguAfBgIy64QGfZQdg91dgAtqUZgnfz6IacYVWvu2AvR4wNAv0nxrAAAAABJRU5ErkJggg==') no-repeat -2px -2px;
|
||||
}
|
||||
|
||||
.break {
|
||||
color: var(--breakpoint-font-colour) !important;
|
||||
background-color: var(--breakpoint-bg-colour) !important;
|
||||
border-color: var(--breakpoint-border-colour) !important;
|
||||
}
|
||||
|
||||
.selected-op {
|
||||
color: var(--selected-operation-font-color) !important;
|
||||
background-color: var(--selected-operation-bg-colour) !important;
|
||||
border-color: var(--selected-operation-border-colour) !important;
|
||||
}
|
||||
|
||||
.flow-control-op {
|
||||
color: var(--fc-operation-font-colour) !important;
|
||||
background-color: var(--fc-operation-bg-colour) !important;
|
||||
border-color: var(--fc-operation-border-colour) !important;
|
||||
}
|
||||
|
||||
.flow-control-op.break {
|
||||
color: var(--fc-breakpoint-operation-font-colour) !important;
|
||||
background-color: var(--fc-breakpoint-operation-bg-colour) !important;
|
||||
border-color: var(--fc-breakpoint-operation-border-colour) !important;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: var(--disabled-font-colour) !important;
|
||||
background-color: var(--disabled-bg-colour) !important;
|
||||
border-color: var(--disabled-border-colour) !important;
|
||||
}
|
||||
30
src/web/stylesheets/components/_pane.css
Normal file
30
src/web/stylesheets/components/_pane.css
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Workspace pane styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
:root {
|
||||
--title-height: 43px;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 10px;
|
||||
height: var(--title-height);
|
||||
border-bottom: 1px solid var(--primary-border-colour);
|
||||
font-weight: var(--title-weight);
|
||||
color: var(--title-colour);
|
||||
background-color: var(--title-background-colour);
|
||||
}
|
||||
|
||||
.list-area {
|
||||
position: absolute;
|
||||
top: var(--title-height);
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
34
src/web/stylesheets/index.css
Normal file
34
src/web/stylesheets/index.css
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* CyberChef styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/* Themes */
|
||||
@import "./themes/_classic.css";
|
||||
@import "./themes/_dark.css";
|
||||
|
||||
/* Utilities */
|
||||
@import "./utils/_overrides.css";
|
||||
@import "./utils/_general.css";
|
||||
|
||||
/* Preloader styles */
|
||||
@import "./preloader.css";
|
||||
|
||||
/* Components */
|
||||
@import "./components/_alert.css";
|
||||
@import "./components/_button.css";
|
||||
@import "./components/_list.css";
|
||||
@import "./components/_operation.css";
|
||||
@import "./components/_pane.css";
|
||||
|
||||
/* Layout */
|
||||
@import "./layout/_banner.css";
|
||||
@import "./layout/_controls.css";
|
||||
@import "./layout/_io.css";
|
||||
@import "./layout/_modals.css";
|
||||
@import "./layout/_operations.css";
|
||||
@import "./layout/_recipe.css";
|
||||
@import "./layout/_structure.css";
|
||||
18
src/web/stylesheets/index.js
Normal file
18
src/web/stylesheets/index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Styles index
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/* Libraries */
|
||||
import "google-code-prettify/src/prettify.css";
|
||||
|
||||
/* Frameworks */
|
||||
import "./vendors/bootstrap.less";
|
||||
import "bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.css";
|
||||
import "bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css";
|
||||
|
||||
/* CyberChef styles */
|
||||
import "./index.css";
|
||||
28
src/web/stylesheets/layout/_banner.css
Normal file
28
src/web/stylesheets/layout/_banner.css
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Banner area styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
#banner {
|
||||
position: absolute;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
border-bottom: 1px solid var(--primary-border-colour);
|
||||
color: var(--banner-font-colour);
|
||||
background-color: var(--banner-bg-colour);
|
||||
}
|
||||
|
||||
.banner-right {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#banner img {
|
||||
margin-bottom: 2px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
65
src/web/stylesheets/layout/_controls.css
Normal file
65
src/web/stylesheets/layout/_controls.css
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Controls area styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
:root {
|
||||
--controls-height: 120px;
|
||||
--controls-division: 65%;
|
||||
}
|
||||
|
||||
#controls {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: var(--controls-height);
|
||||
bottom: 0;
|
||||
padding: 10px;
|
||||
border-top: 1px solid var(--primary-border-colour);
|
||||
background-color: var(--secondary-background-colour);
|
||||
}
|
||||
|
||||
#operational-controls {
|
||||
width: var(--controls-division);
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#bake-group {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#bake {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
#auto-bake-label {
|
||||
display: table-cell;
|
||||
padding: 1px;
|
||||
line-height: 1.35;
|
||||
width: 60px;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-left: 1px solid var(--btn-success-bg-colour);
|
||||
}
|
||||
|
||||
#auto-bake-label:hover {
|
||||
border-left-color: var(--btn-success-hover-border-colour);
|
||||
}
|
||||
|
||||
#auto-bake-label div {
|
||||
font-size: 10px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#extra-controls {
|
||||
float: right;
|
||||
width: calc(100% - var(--controls-division));
|
||||
padding-left: 10px;
|
||||
}
|
||||
109
src/web/stylesheets/layout/_io.css
Normal file
109
src/web/stylesheets/layout/_io.css
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Input/Output area styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
#input-text,
|
||||
#output-text,
|
||||
#output-html {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 3px;
|
||||
-moz-padding-start: 3px;
|
||||
-moz-padding-end: 3px;
|
||||
border: none;
|
||||
border-width: 0px;
|
||||
resize: none;
|
||||
background-color: transparent;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#output-html {
|
||||
display: none;
|
||||
overflow-y: auto;
|
||||
-moz-padding-start: 1px; /* Fixes bug in Firefox */
|
||||
}
|
||||
|
||||
.textarea-wrapper {
|
||||
position: absolute;
|
||||
top: 43px;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.textarea-wrapper textarea,
|
||||
.textarea-wrapper div {
|
||||
font-family: var(--fixed-width-font-family);
|
||||
font-size: var(--fixed-width-font-size);
|
||||
color: var(--fixed-width-font-colour);
|
||||
}
|
||||
|
||||
#input-highlighter,
|
||||
#output-highlighter {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 3px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
letter-spacing: normal;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.io-btn-group {
|
||||
float: right;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.io-info {
|
||||
margin-right: 20px;
|
||||
margin-top: -4px;
|
||||
float: right;
|
||||
height: 30px;
|
||||
text-align: right;
|
||||
line-height: 10px;
|
||||
font-family: var(--fixed-width-font-family);
|
||||
font-weight: normal;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
#input-info {
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.dropping-file {
|
||||
border: 5px dashed var(--drop-file-border-colour) !important;
|
||||
}
|
||||
|
||||
@keyframes spinner {
|
||||
from {
|
||||
transform:rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform:rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-icon::before {
|
||||
content: "\21bb";
|
||||
}
|
||||
|
||||
.loading-icon {
|
||||
animation-name: spinner;
|
||||
animation-duration: 1000ms;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
80
src/web/stylesheets/layout/_modals.css
Normal file
80
src/web/stylesheets/layout/_modals.css
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Modal layout styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
.option-item .bootstrap-switch {
|
||||
margin: 15px 10px;
|
||||
}
|
||||
|
||||
.option-item button {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.option-item input[type=number] {
|
||||
margin: 15px 10px;
|
||||
width: 80px;
|
||||
height: 28px;
|
||||
padding: 3px 10px;
|
||||
vertical-align: middle;
|
||||
font-size: calc(var(--arg-input-font-size) - 1px);
|
||||
line-height: var(--arg-input-line-height);
|
||||
color: var(--arg-font-colour);
|
||||
background-color: var(--arg-background);
|
||||
border: 1px solid var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.option-item select {
|
||||
margin: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#edit-favourites-list {
|
||||
margin: 10px;
|
||||
border: 1px solid var(--op-list-operation-border-colour);
|
||||
}
|
||||
|
||||
#edit-favourites-list .operation {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
#edit-favourites-list .operation:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.about-img-left {
|
||||
float: left;
|
||||
margin: 10px 20px 20px 0;
|
||||
}
|
||||
|
||||
.about-img-right {
|
||||
float: right;
|
||||
margin: 10px 0 20px 20px;
|
||||
}
|
||||
|
||||
.save-link-options {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.save-link-options input{
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#save-footer {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
border-bottom: 1px solid var(--primary-border-colour);
|
||||
}
|
||||
|
||||
#support-modal textarea {
|
||||
font-family: var(--primary-font-family);
|
||||
}
|
||||
|
||||
#save-text,
|
||||
#load-text {
|
||||
font-family: var(--fixed-width-font-family);
|
||||
}
|
||||
32
src/web/stylesheets/layout/_operations.css
Normal file
32
src/web/stylesheets/layout/_operations.css
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Operation area styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
.op-list .operation {
|
||||
color: var(--op-list-operation-font-colour);
|
||||
background-color: var(--op-list-operation-bg-colour);
|
||||
border-color: var(--op-list-operation-border-colour);
|
||||
}
|
||||
|
||||
#search {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--primary-border-colour);
|
||||
color: var(--primary-font-colour);
|
||||
}
|
||||
|
||||
#edit-favourites {
|
||||
float: right;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.favourites-hover {
|
||||
color: var(--rec-list-operation-font-colour);
|
||||
background-color: var(--rec-list-operation-bg-colour);
|
||||
border: 2px dashed var(--rec-list-operation-font-colour) !important;
|
||||
padding: 8px 8px 9px 8px;
|
||||
}
|
||||
18
src/web/stylesheets/layout/_recipe.css
Normal file
18
src/web/stylesheets/layout/_recipe.css
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Recipe area styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
#rec-list {
|
||||
bottom: var(--controls-height);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#rec-list .operation {
|
||||
color: var(--rec-list-operation-font-colour);
|
||||
background-color: var(--rec-list-operation-bg-colour);
|
||||
border-color: var(--rec-list-operation-border-colour);
|
||||
}
|
||||
65
src/web/stylesheets/layout/_structure.css
Normal file
65
src/web/stylesheets/layout/_structure.css
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Overall page structure styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#content-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#workspace-wrapper {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div#operations,
|
||||
div#recipe {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div#input,
|
||||
div#output {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.split {
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.split.split-horizontal, .gutter.gutter-horizontal {
|
||||
height: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
background-color: var(--secondary-border-colour);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50%;
|
||||
}
|
||||
|
||||
.gutter.gutter-horizontal {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAeCAYAAAAGos/EAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB+EFBhEwBDmIiYYAAAAjSURBVBjTYzxz5sx/BgYGBiYGKGB89+4dA4oIy71790aGGgCn+DBbOcAB0wAAAABJRU5ErkJggg==');
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.gutter.gutter-vertical {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAACCAYAAABPJGxCAAAABGdBTUEAALGOfPtRkwAACkNpQ0NQSUNDIFByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/vcxDeEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH4QUGETI0LWfbqAAAACNJREFUCNdjPHPmzH8GBgYGJSUlRgYGBoZ79+7Rhc/EMEAAAHd6H2e3/71BAAAAAElFTkSuQmCC');
|
||||
cursor: ns-resize;
|
||||
}
|
||||
152
src/web/stylesheets/preloader.css
Normal file
152
src/web/stylesheets/preloader.css
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Preloader styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
#loader-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1000;
|
||||
background-color: var(--secondary-border-colour);
|
||||
}
|
||||
|
||||
#preloader {
|
||||
display: block;
|
||||
position: relative;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin: -75px 0 0 -75px;
|
||||
|
||||
border: 3px solid transparent;
|
||||
border-top-color: #3498db;
|
||||
border-radius: 50%;
|
||||
z-index: 1500;
|
||||
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
#preloader:before,
|
||||
#preloader:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
right: 5px;
|
||||
bottom: 5px;
|
||||
border: 3px solid transparent;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#preloader:before {
|
||||
border-top-color: #e74c3c;
|
||||
animation: spin 3s linear infinite;
|
||||
}
|
||||
|
||||
#preloader:after {
|
||||
border-top-color: #f9c922;
|
||||
animation: spin 1.5s linear infinite;
|
||||
}
|
||||
|
||||
#preloader-msg {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 300px;
|
||||
left: calc(50% - 150px);
|
||||
top: calc(50% + 50px);
|
||||
text-align: center;
|
||||
margin-top: 50px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#preloader-msg.loading {
|
||||
opacity: 1;
|
||||
transition: all 0.1s ease-in;
|
||||
}
|
||||
|
||||
|
||||
/* Loaded */
|
||||
.loaded #preloader,
|
||||
.loaded #preloader-msg {
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
|
||||
.loaded #loader-wrapper {
|
||||
opacity: 0;
|
||||
transition: all 0.5s 0.3s ease-out;
|
||||
}
|
||||
|
||||
.loaded #rec-list li {
|
||||
animation: bump 0.7s cubic-bezier(0.7, 0, 0.3, 1) both;
|
||||
}
|
||||
|
||||
.loaded #content-wrapper {
|
||||
animation-delay: 0.10s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:first-child {
|
||||
animation-delay: 0.20s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(2) {
|
||||
animation-delay: 0.25s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(3) {
|
||||
animation-delay: 0.30s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(4) {
|
||||
animation-delay: 0.35s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(5) {
|
||||
animation-delay: 0.40s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(6) {
|
||||
animation-delay: 0.45s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(7) {
|
||||
animation-delay: 0.50s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(8) {
|
||||
animation-delay: 0.55s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(9) {
|
||||
animation-delay: 0.60s;
|
||||
}
|
||||
|
||||
.loaded #rec-list li:nth-child(10) {
|
||||
animation-delay: 0.65s;
|
||||
}
|
||||
|
||||
|
||||
/* Animations */
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bump {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 200px, 0);
|
||||
}
|
||||
}
|
||||
116
src/web/stylesheets/themes/_classic.css
Executable file
116
src/web/stylesheets/themes/_classic.css
Executable file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Classic theme definitions
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
:root,
|
||||
:root.classic {
|
||||
--primary-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--primary-font-colour: #333;
|
||||
--primary-font-size: 14px;
|
||||
--primary-line-height: 20px;
|
||||
|
||||
--fixed-width-font-family: "Consolas", monospace;
|
||||
--fixed-width-font-colour: inherit;
|
||||
--fixed-width-font-size: inherit;
|
||||
|
||||
--subtext-font-colour: #999;
|
||||
--subtext-font-size: 13px;
|
||||
|
||||
--primary-background-colour: #fff;
|
||||
--secondary-background-colour: #fafafa;
|
||||
|
||||
--primary-border-colour: #ddd;
|
||||
--secondary-border-colour: #eee;
|
||||
|
||||
--title-colour: #424242;
|
||||
--title-weight: bold;
|
||||
--title-background-colour: #fafafa;
|
||||
|
||||
--banner-font-colour: #468847;
|
||||
--banner-bg-colour: #dff0d8;
|
||||
|
||||
|
||||
/* Operation colours */
|
||||
--op-list-operation-font-colour: #3a87ad;
|
||||
--op-list-operation-bg-colour: #d9edf7;
|
||||
--op-list-operation-border-colour: #bce8f1;
|
||||
|
||||
--rec-list-operation-font-colour: #468847;
|
||||
--rec-list-operation-bg-colour: #dff0d8;
|
||||
--rec-list-operation-border-colour: #d6e9c6;
|
||||
|
||||
--selected-operation-font-color: #c09853;
|
||||
--selected-operation-bg-colour: #fcf8e3;
|
||||
--selected-operation-border-colour: #fbeed5;
|
||||
|
||||
--breakpoint-font-colour: #b94a48;
|
||||
--breakpoint-bg-colour: #f2dede;
|
||||
--breakpoint-border-colour: #eed3d7;
|
||||
|
||||
--disabled-font-colour: #999;
|
||||
--disabled-bg-colour: #dfdfdf;
|
||||
--disabled-border-colour: #cdcdcd;
|
||||
|
||||
--fc-operation-font-colour: #396f3a;
|
||||
--fc-operation-bg-colour: #c7e4ba;
|
||||
--fc-operation-border-colour: #b3dba2;
|
||||
|
||||
--fc-breakpoint-operation-font-colour: #94312f;
|
||||
--fc-breakpoint-operation-bg-colour: #eabfbf;
|
||||
--fc-breakpoint-operation-border-colour: #e2aeb5;
|
||||
|
||||
|
||||
/* Operation arguments */
|
||||
--arg-title-font-weight: bold;
|
||||
--arg-input-height: 34px;
|
||||
--arg-input-line-height: 20px;
|
||||
--arg-input-font-size: 15px;
|
||||
--arg-font-colour: #424242;
|
||||
--arg-background: #fff;
|
||||
--arg-border-colour: #ddd;
|
||||
--arg-disabled-background: #eee;
|
||||
|
||||
|
||||
/* Buttons */
|
||||
--btn-default-font-colour: #333;
|
||||
--btn-default-bg-colour: #fff;
|
||||
--btn-default-border-colour: #ddd;
|
||||
|
||||
--btn-default-hover-font-colour: #333;
|
||||
--btn-default-hover-bg-colour: #ebebeb;
|
||||
--btn-default-hover-border-colour: #adadad;
|
||||
|
||||
--btn-success-font-colour: #fff;
|
||||
--btn-success-bg-colour: #5cb85c;
|
||||
--btn-success-border-colour: #4cae4c;
|
||||
|
||||
--btn-success-hover-font-colour: #fff;
|
||||
--btn-success-hover-bg-colour: #449d44;
|
||||
--btn-success-hover-border-colour: #398439;
|
||||
|
||||
|
||||
/* Highlighter colours */
|
||||
--hl1: #fff000;
|
||||
--hl2: #95dfff;
|
||||
--hl3: #ffb6b6;
|
||||
--hl4: #fcf8e3;
|
||||
--hl5: #8de768;
|
||||
|
||||
|
||||
/* Scrollbar */
|
||||
--scrollbar-track: var(--secondary-background-colour);
|
||||
--scrollbar-thumb: #ccc;
|
||||
--scrollbar-hover: #bbb;
|
||||
|
||||
|
||||
/* Misc. */
|
||||
--drop-file-border-colour: #3a87ad;
|
||||
--popover-background: #fff;
|
||||
--popover-border-colour: #ccc;
|
||||
--code-background: #f9f2f4;
|
||||
--code-font-colour: #c7254e;
|
||||
}
|
||||
115
src/web/stylesheets/themes/_dark.css
Normal file
115
src/web/stylesheets/themes/_dark.css
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Dark theme definitions
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
:root.dark {
|
||||
--primary-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--primary-font-colour: #c5c5c5;
|
||||
--primary-font-size: 14px;
|
||||
--primary-line-height: 20px;
|
||||
|
||||
--fixed-width-font-family: "Monaco", "Droid Sans Mono", "Consolas", monospace;
|
||||
--fixed-width-font-colour: inherit;
|
||||
--fixed-width-font-size: inherit;
|
||||
|
||||
--subtext-font-colour: #999;
|
||||
--subtext-font-size: 13px;
|
||||
|
||||
--primary-background-colour: #1e1e1e;
|
||||
--secondary-background-colour: #252525;
|
||||
|
||||
--primary-border-colour: #444;
|
||||
--secondary-border-colour: #3c3c3c;
|
||||
|
||||
--title-colour: #fff;
|
||||
--title-weight: bold;
|
||||
--title-background-colour: #333;
|
||||
|
||||
--banner-font-colour: #c5c5c5;
|
||||
--banner-bg-colour: #252525;
|
||||
|
||||
|
||||
/* Operation colours */
|
||||
--op-list-operation-font-colour: #c5c5c5;
|
||||
--op-list-operation-bg-colour: #333;
|
||||
--op-list-operation-border-colour: #444;
|
||||
|
||||
--rec-list-operation-font-colour: #c5c5c5;
|
||||
--rec-list-operation-bg-colour: #252525;
|
||||
--rec-list-operation-border-colour: #444;
|
||||
|
||||
--selected-operation-font-color: #c5c5c5;
|
||||
--selected-operation-bg-colour: #3f3f3f;
|
||||
--selected-operation-border-colour: #444;
|
||||
|
||||
--breakpoint-font-colour: #ddd;
|
||||
--breakpoint-bg-colour: #073655;
|
||||
--breakpoint-border-colour: #444;
|
||||
|
||||
--disabled-font-colour: #666;
|
||||
--disabled-bg-colour: #444;
|
||||
--disabled-border-colour: #444;
|
||||
|
||||
--fc-operation-font-colour: #c5c5c5;
|
||||
--fc-operation-bg-colour: #2d2d2d;
|
||||
--fc-operation-border-colour: #444;
|
||||
|
||||
--fc-breakpoint-operation-font-colour: #ddd;
|
||||
--fc-breakpoint-operation-bg-colour: #072b49;
|
||||
--fc-breakpoint-operation-border-colour: #444;
|
||||
|
||||
|
||||
/* Operation arguments */
|
||||
--arg-title-font-weight: bold;
|
||||
--arg-input-height: 34px;
|
||||
--arg-input-line-height: 20px;
|
||||
--arg-input-font-size: 15px;
|
||||
--arg-font-colour: #bbb;
|
||||
--arg-background: #3c3c3c;
|
||||
--arg-border-colour: #3c3c3c;
|
||||
--arg-disabled-background: #4f4f4f;
|
||||
|
||||
|
||||
/* Buttons */
|
||||
--btn-default-font-colour: #c5c5c5;
|
||||
--btn-default-bg-colour: #2d2d2d;
|
||||
--btn-default-border-colour: #3c3c3c;
|
||||
|
||||
--btn-default-hover-font-colour: #c5c5c5;
|
||||
--btn-default-hover-bg-colour: #2d2d2d;
|
||||
--btn-default-hover-border-colour: #205375;
|
||||
|
||||
--btn-success-font-colour: #fff;
|
||||
--btn-success-bg-colour: #073655;
|
||||
--btn-success-border-colour: #0e639c;
|
||||
|
||||
--btn-success-hover-font-colour: #fff;
|
||||
--btn-success-hover-bg-colour: #0e639c;
|
||||
--btn-success-hover-border-colour: #0e639c;
|
||||
|
||||
|
||||
/* Highlighter colours */
|
||||
--hl1: #264f78;
|
||||
--hl2: #675351;
|
||||
--hl3: #ffb6b6;
|
||||
--hl4: #fcf8e3;
|
||||
--hl5: #8de768;
|
||||
|
||||
|
||||
/* Scrollbar */
|
||||
--scrollbar-track: #1e1e1e;
|
||||
--scrollbar-thumb: #424242;
|
||||
--scrollbar-hover: #4e4e4e;
|
||||
|
||||
|
||||
/* Misc. */
|
||||
--drop-file-border-colour: #0e639c;
|
||||
--popover-background: #444;
|
||||
--popover-border-colour: #555;
|
||||
--code-background: #0e639c;
|
||||
--code-font-colour: #fff;
|
||||
}
|
||||
73
src/web/stylesheets/utils/_general.css
Executable file
73
src/web/stylesheets/utils/_general.css
Executable file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* General styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
body {
|
||||
font-family: var(--primary-font-family);
|
||||
font-size: var(--primary-font-size);
|
||||
line-height: var(--primary-line-height);
|
||||
color: var(--primary-font-colour);
|
||||
background-color: var(--primary-background-colour);
|
||||
}
|
||||
|
||||
.subtext {
|
||||
font-style: italic;
|
||||
font-size: var(--subtext-font-size);
|
||||
color: var(--subtext-font-colour);
|
||||
}
|
||||
|
||||
.word-wrap {
|
||||
white-space: pre !important;
|
||||
word-wrap: normal !important;
|
||||
overflow-x: scroll !important;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.blur {
|
||||
color: transparent !important;
|
||||
text-shadow: rgba(0, 0, 0, 0.95) 0 0 10px !important;
|
||||
}
|
||||
|
||||
.no-select {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.konami {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: var(--scrollbar-track);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--scrollbar-thumb);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--scrollbar-hover);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: var(--scrollbar-track);
|
||||
}
|
||||
|
||||
/* Highlighters */
|
||||
.hl1 { background-color: var(--hl1); }
|
||||
.hl2 { background-color: var(--hl2); }
|
||||
.hl3 { background-color: var(--hl3); } /* Half-Life 3 confirmed :O */
|
||||
.hl4 { background-color: var(--hl4); }
|
||||
.hl5 { background-color: var(--hl5); }
|
||||
223
src/web/stylesheets/utils/_overrides.css
Executable file
223
src/web/stylesheets/utils/_overrides.css
Executable file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* Overrides for vendor styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/* Bootstrap */
|
||||
|
||||
button,
|
||||
a:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
color: var(--btn-default-font-colour);
|
||||
background-color: var(--btn-default-bg-colour);
|
||||
border-color: var(--btn-default-border-colour);
|
||||
}
|
||||
|
||||
.btn-default:hover,
|
||||
.btn-default:active,
|
||||
.btn-default:hover:active,
|
||||
.open>.dropdown-toggle.btn-default {
|
||||
color: var(--btn-default-hover-font-colour);
|
||||
background-color: var(--btn-default-hover-bg-colour);
|
||||
border-color: var(--btn-default-hover-border-colour);
|
||||
}
|
||||
|
||||
.btn-default:focus,
|
||||
.open>.dropdown-toggle.btn-default:hover,
|
||||
.open>.dropdown-toggle.btn-default:focus {
|
||||
color: var(--btn-default-font-colour);
|
||||
background-color: var(--btn-default-bg-colour);
|
||||
border-color: var(--btn-default-hover-border-colour);
|
||||
}
|
||||
|
||||
.btn-default[disabled]:hover {
|
||||
background-color: var(--primary-background-colour);
|
||||
border-color: var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
color: var(--btn-success-font-colour);
|
||||
background-color: var(--btn-success-bg-colour);
|
||||
border-color: var(--btn-success-border-colour);
|
||||
}
|
||||
|
||||
.btn-success:hover,
|
||||
.btn-success:active,
|
||||
.btn-success:focus,
|
||||
.btn-success:hover:active {
|
||||
color: var(--btn-success-hover-font-colour);
|
||||
background-color: var(--btn-success-hover-bg-colour);
|
||||
border-color: var(--btn-success-hover-border-colour);
|
||||
}
|
||||
|
||||
.btn,
|
||||
.btn-lg,
|
||||
.nav-tabs>li>a,
|
||||
.form-control,
|
||||
.popover,
|
||||
.alert,
|
||||
.modal-content,
|
||||
.tooltip-inner,
|
||||
.dropdown-menu {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.btn.dropdown-toggle {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: searchfield;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: searchfield-cancel-button;
|
||||
}
|
||||
|
||||
.modal {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: var(--primary-background-colour);
|
||||
}
|
||||
|
||||
.modal-header,
|
||||
.modal-footer {
|
||||
border-color: var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: transparent;
|
||||
border-color: var(--primary-border-colour);
|
||||
color: var(--primary-font-colour);
|
||||
}
|
||||
|
||||
code {
|
||||
border: 0;
|
||||
white-space: pre-wrap;
|
||||
font-family: var(--fixed-width-font-family);
|
||||
background-color: var(--code-background);
|
||||
color: var(--code-font-colour);
|
||||
}
|
||||
|
||||
pre {
|
||||
border-radius: 0 !important;
|
||||
background-color: var(--secondary-background-colour);
|
||||
border-color: var(--secondary-border-colour);
|
||||
color: var(--fixed-width-font-colour);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-size: inherit;
|
||||
border-left-color: var(--secondary-border-colour);
|
||||
}
|
||||
|
||||
blockquote a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.panel-body:before,
|
||||
.panel-body:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.table-nonfluid {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.popover {
|
||||
background-color: var(--popover-background);
|
||||
border-color: var(--popover-border-colour);
|
||||
}
|
||||
|
||||
|
||||
.popover.right>.arrow {
|
||||
border-right-color: var(--popover-border-colour);
|
||||
}
|
||||
|
||||
.popover.right>.arrow:after {
|
||||
border-right-color: var(--popover-background);
|
||||
}
|
||||
|
||||
.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover {
|
||||
background-color: var(--primary-background-colour);
|
||||
border-color: var(--primary-border-colour);
|
||||
border-bottom-color: transparent;
|
||||
color: var(--primary-font-colour);
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-color: var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.nav>li>a:focus, .nav>li>a:hover {
|
||||
background-color: var(--secondary-border-colour);
|
||||
}
|
||||
|
||||
.nav-tabs>li>a:hover {
|
||||
border-color: var(--secondary-border-colour) var(--secondary-border-colour) var(--primary-border-colour);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: var(--primary-background-colour);
|
||||
}
|
||||
|
||||
.dropdown-menu>li>a {
|
||||
color: var(--primary-font-colour);
|
||||
}
|
||||
|
||||
.dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover {
|
||||
background-color: var(--secondary-background-colour);
|
||||
color: var(--primary-font-colour);
|
||||
}
|
||||
|
||||
|
||||
/* Bootstrap-switch */
|
||||
|
||||
.bootstrap-switch,
|
||||
.bootstrap-switch-container,
|
||||
.bootstrap-switch-handle-on,
|
||||
.bootstrap-switch-handle-off,
|
||||
.bootstrap-switch-label {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.bootstrap-switch .bootstrap-switch-label {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bootstrap-switch {
|
||||
border-color: var(--primary-border-colour);
|
||||
}
|
||||
|
||||
|
||||
/* Sortable */
|
||||
|
||||
.sortable-ghost {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
||||
/* Bootstrap Colorpicker */
|
||||
|
||||
.colorpicker-element {
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.colorpicker-color,
|
||||
.colorpicker-color div {
|
||||
height: 100px;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user