mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
153 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77e074efc2 | ||
|
|
bd000d2d2c | ||
|
|
5f1c88104d | ||
|
|
a61df0832f | ||
|
|
58361e58f8 | ||
|
|
96b4361b31 | ||
|
|
c773edceb9 | ||
|
|
bcaef8ba54 | ||
|
|
c7d0b0ccc5 | ||
|
|
38792a0f02 | ||
|
|
cda557e1b9 | ||
|
|
8d09f7c7eb | ||
|
|
4845a56435 | ||
|
|
f164dcdd70 | ||
|
|
6c8da6b070 | ||
|
|
09df753ca9 | ||
|
|
72ec9df1b1 | ||
|
|
086d5272ac | ||
|
|
2555de7712 | ||
|
|
645e540c66 | ||
|
|
d16e1a4451 | ||
|
|
7c5dd2bd78 | ||
|
|
2f0121f0e4 | ||
|
|
7e310a8de7 | ||
|
|
c460c2bf6b | ||
|
|
2400de337b | ||
|
|
85d41085de | ||
|
|
48d45d026e | ||
|
|
183c57643b | ||
|
|
e7cea889ab | ||
|
|
61c799447b | ||
|
|
ad25daf206 | ||
|
|
4143bba89f | ||
|
|
8eb7d65b74 | ||
|
|
51798553e1 | ||
|
|
323928ff86 | ||
|
|
fe3aeabd0a | ||
|
|
ec7a55dba6 | ||
|
|
b4fe708d70 | ||
|
|
c3469bd545 | ||
|
|
92018b761d | ||
|
|
bb45ff0515 | ||
|
|
df1405e998 | ||
|
|
62ec018bb2 | ||
|
|
14b7c4bf23 | ||
|
|
5c774a3ce2 | ||
|
|
246480daef | ||
|
|
91c6f682e7 | ||
|
|
a417a6469c | ||
|
|
2821bdd52b | ||
|
|
d37300be39 | ||
|
|
15b83072bb | ||
|
|
6d2e2259db | ||
|
|
5b70614212 | ||
|
|
4363da534d | ||
|
|
685f7a4f00 | ||
|
|
6e26f25418 | ||
|
|
d8051ce9a2 | ||
|
|
00e7d8a390 | ||
|
|
213ec028b8 | ||
|
|
61951e76ac | ||
|
|
47cf763b3f | ||
|
|
04aac03d6e | ||
|
|
3faef2c9c9 | ||
|
|
eda17d1671 | ||
|
|
fbd6ead6b7 | ||
|
|
bf2950abdd | ||
|
|
3eacc325a3 | ||
|
|
15decd9cd9 | ||
|
|
c0142adba9 | ||
|
|
ec01333c83 | ||
|
|
8110384ea2 | ||
|
|
0c2c0d7b8b | ||
|
|
ae38bb0927 | ||
|
|
003e076b00 | ||
|
|
2c2a0eb7d9 | ||
|
|
e7f5b17184 | ||
|
|
69e12b1067 | ||
|
|
fef446687a | ||
|
|
3affce8f98 | ||
|
|
0b91468edc | ||
|
|
127364e8a4 | ||
|
|
a144f65dcf | ||
|
|
96ec3a869b | ||
|
|
52426bc1a4 | ||
|
|
cbab995c6d | ||
|
|
d27fa43120 | ||
|
|
45a9da5b30 | ||
|
|
aed22aebb2 | ||
|
|
369d213da5 | ||
|
|
e92775eec2 | ||
|
|
2c0f48f4e5 | ||
|
|
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 | ||
|
|
823b276ef5 | ||
|
|
6bf06a9629 | ||
|
|
3c15bd9e29 | ||
|
|
280f1ee2df | ||
|
|
0dc72d8301 | ||
|
|
80cdf0c014 | ||
|
|
d1d394eec7 | ||
|
|
2e4076bb75 | ||
|
|
d71ac2e894 | ||
|
|
e3f41fea9c | ||
|
|
a4d93f23d6 | ||
|
|
e0e5670d0e | ||
|
|
e120422b05 |
@@ -52,6 +52,9 @@
|
|||||||
"no-trailing-spaces": "warn",
|
"no-trailing-spaces": "warn",
|
||||||
"eol-last": "error",
|
"eol-last": "error",
|
||||||
"func-call-spacing": "error",
|
"func-call-spacing": "error",
|
||||||
|
"key-spacing": ["warn", {
|
||||||
|
"mode": "minimum"
|
||||||
|
}],
|
||||||
"indent": ["error", 4, {
|
"indent": ["error", 4, {
|
||||||
"ArrayExpression": "first",
|
"ArrayExpression": "first",
|
||||||
"SwitchCase": 1
|
"SwitchCase": 1
|
||||||
@@ -93,6 +96,7 @@
|
|||||||
"moment": false,
|
"moment": false,
|
||||||
|
|
||||||
"COMPILE_TIME": false,
|
"COMPILE_TIME": false,
|
||||||
"COMPILE_MSG": false
|
"COMPILE_MSG": false,
|
||||||
|
"PKG_VERSION": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ script:
|
|||||||
- grunt test
|
- grunt test
|
||||||
- grunt docs
|
- grunt docs
|
||||||
- grunt node
|
- grunt node
|
||||||
- grunt prod
|
- grunt prod --msg="$COMPILE_MSG"
|
||||||
before_deploy:
|
before_deploy:
|
||||||
- grunt copy:ghPages
|
- grunt copy:ghPages
|
||||||
deploy:
|
deploy:
|
||||||
@@ -19,6 +19,7 @@ deploy:
|
|||||||
local_dir: build/prod/
|
local_dir: build/prod/
|
||||||
target_branch: gh-pages
|
target_branch: gh-pages
|
||||||
on:
|
on:
|
||||||
|
repo: gchq/CyberChef
|
||||||
branch: master
|
branch: master
|
||||||
- provider: releases
|
- provider: releases
|
||||||
skip_cleaup: true
|
skip_cleaup: true
|
||||||
|
|||||||
46
CODE_OF_CONDUCT.md
Normal file
46
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at oss@gchq.gov.uk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
||||||
19
Gruntfile.js
19
Gruntfile.js
@@ -54,7 +54,7 @@ module.exports = function (grunt) {
|
|||||||
|
|
||||||
|
|
||||||
// Project configuration
|
// Project configuration
|
||||||
const 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" +
|
banner = "/**\n" +
|
||||||
"* CyberChef - The Cyber Swiss Army Knife\n" +
|
"* CyberChef - The Cyber Swiss Army Knife\n" +
|
||||||
"*\n" +
|
"*\n" +
|
||||||
@@ -74,7 +74,8 @@ module.exports = function (grunt) {
|
|||||||
"* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
|
"* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
|
||||||
"* See the License for the specific language governing permissions and\n" +
|
"* See the License for the specific language governing permissions and\n" +
|
||||||
"* limitations under the License.\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.
|
* Compiles a production build of CyberChef into a single, portable web page.
|
||||||
@@ -163,7 +164,8 @@ module.exports = function (grunt) {
|
|||||||
}),
|
}),
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
COMPILE_TIME: JSON.stringify(compileTime),
|
COMPILE_TIME: JSON.stringify(compileTime),
|
||||||
COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || "")
|
COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""),
|
||||||
|
PKG_VERSION: JSON.stringify(pkg.version)
|
||||||
}),
|
}),
|
||||||
new ExtractTextPlugin("styles.css"),
|
new ExtractTextPlugin("styles.css"),
|
||||||
],
|
],
|
||||||
@@ -182,7 +184,10 @@ module.exports = function (grunt) {
|
|||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: ExtractTextPlugin.extract({
|
use: ExtractTextPlugin.extract({
|
||||||
use: "css-loader?minimize"
|
use: [
|
||||||
|
{ loader: "css-loader?minimize" },
|
||||||
|
{ loader: "postcss-loader" },
|
||||||
|
]
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -190,6 +195,7 @@ module.exports = function (grunt) {
|
|||||||
use: ExtractTextPlugin.extract({
|
use: ExtractTextPlugin.extract({
|
||||||
use: [
|
use: [
|
||||||
{ loader: "css-loader?minimize" },
|
{ loader: "css-loader?minimize" },
|
||||||
|
{ loader: "postcss-loader" },
|
||||||
{ loader: "less-loader" }
|
{ loader: "less-loader" }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@@ -235,7 +241,8 @@ module.exports = function (grunt) {
|
|||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: "index.html",
|
filename: "index.html",
|
||||||
template: "./src/web/html/index.html",
|
template: "./src/web/html/index.html",
|
||||||
compileTime: compileTime
|
compileTime: compileTime,
|
||||||
|
version: pkg.version,
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
watch: true
|
watch: true
|
||||||
@@ -261,6 +268,7 @@ module.exports = function (grunt) {
|
|||||||
filename: "index.html",
|
filename: "index.html",
|
||||||
template: "./src/web/html/index.html",
|
template: "./src/web/html/index.html",
|
||||||
compileTime: compileTime,
|
compileTime: compileTime,
|
||||||
|
version: pkg.version,
|
||||||
minify: {
|
minify: {
|
||||||
removeComments: true,
|
removeComments: true,
|
||||||
collapseWhitespace: true,
|
collapseWhitespace: true,
|
||||||
@@ -272,6 +280,7 @@ module.exports = function (grunt) {
|
|||||||
filename: "cyberchef.htm",
|
filename: "cyberchef.htm",
|
||||||
template: "./src/web/html/index.html",
|
template: "./src/web/html/index.html",
|
||||||
compileTime: compileTime,
|
compileTime: compileTime,
|
||||||
|
version: pkg.version,
|
||||||
inline: true,
|
inline: true,
|
||||||
minify: {
|
minify: {
|
||||||
removeComments: true,
|
removeComments: true,
|
||||||
|
|||||||
30
README.md
30
README.md
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
#### *The Cyber Swiss Army Knife*
|
#### *The Cyber Swiss Army Knife*
|
||||||
|
|
||||||
CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include creating hexdumps, simple encoding like XOR or Base64, more complex encryption like AES, DES and Blowfish, data compression and decompression, calculating hashes and checksums, IPv6 and X.509 parsing, and much more.
|
CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include simple encoding like XOR or Base64, more complex encryption like AES, DES and Blowfish, creating binary and hexdumps, compression and decompression of data, calculating hashes and checksums, IPv6 and X.509 parsing, changing character encodings, and much more.
|
||||||
|
|
||||||
The tool is designed to enable both technical and non-technical analysts to manipulate data in complex ways without having to deal with complex tools or algorithms. It was conceived, designed, built and incrementally improved by an analyst in their 10% innovation time over several years. Every effort has been made to structure the code in a readable and extendable format, however it should be noted that the analyst is not a professional developer and the code has not been peer-reviewed for compliance with a formal specification.
|
The tool is designed to enable both technical and non-technical analysts to manipulate data in complex ways without having to deal with complex tools or algorithms. It was conceived, designed, built and incrementally improved by an analyst in their 10% innovation time over several years. Every effort has been made to structure the code in a readable and extendable format, however it should be noted that the analyst is not a professional developer.
|
||||||
|
|
||||||
## Live demo
|
## Live demo
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ Cryptographic operations in CyberChef should not be relied upon to provide secur
|
|||||||
There are four main areas in CyberChef:
|
There are four main areas in CyberChef:
|
||||||
|
|
||||||
1. The **input** box in the top right, where you can paste, type or drag the data you want to operate on.
|
1. The **input** box in the top right, where you can paste, type or drag the data you want to operate on.
|
||||||
2. The **output** box in the bottom right, where the outcome of the specified processing will be displayed.
|
2. The **output** box in the bottom right, where the outcome of your processing will be displayed.
|
||||||
3. The **operations** list on the far left, where you can find all the operations that CyberChef is capable of in categorised lists, or by searching.
|
3. The **operations** list on the far left, where you can find all the operations that CyberChef is capable of in categorised lists, or by searching.
|
||||||
4. The **recipe** area in the middle, where you drag the operations that you want to use and specify arguments and options.
|
4. The **recipe** area in the middle, where you can drag the operations that you want to use and specify arguments and options.
|
||||||
|
|
||||||
You can use as many operations as you like in simple or complex ways. Some examples are as follows:
|
You can use as many operations as you like in simple or complex ways. Some examples are as follows:
|
||||||
|
|
||||||
@@ -66,12 +66,16 @@ You can use as many operations as you like in simple or complex ways. Some examp
|
|||||||
|
|
||||||
## Browser support
|
## Browser support
|
||||||
|
|
||||||
CyberChef is built to support Google Chrome 40+, Mozilla Firefox 35+ and Microsoft Edge 14+.
|
CyberChef is built to support
|
||||||
|
|
||||||
|
- Google Chrome 40+
|
||||||
|
- Mozilla Firefox 35+
|
||||||
|
- Microsoft Edge 14+
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
An installation walkthrough, how-to guides for adding new operations, descriptions of the repository structure, available data types and coding conventions can all be found in the project [wiki pages](https://github.com/gchq/CyberChef/wiki).
|
An installation walkthrough, how-to guides for adding new operations and themes, descriptions of the repository structure, available data types and coding conventions can all be found in the project [wiki pages](https://github.com/gchq/CyberChef/wiki).
|
||||||
|
|
||||||
- Sign the [GCHQ Contributor Licence Agreement](https://github.com/gchq/Gaffer/wiki/GCHQ-OSS-Contributor-License-Agreement-V1.0)
|
- Sign the [GCHQ Contributor Licence Agreement](https://github.com/gchq/Gaffer/wiki/GCHQ-OSS-Contributor-License-Agreement-V1.0)
|
||||||
- Push your changes to your fork.
|
- Push your changes to your fork.
|
||||||
@@ -84,10 +88,10 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice
|
|||||||
|
|
||||||
|
|
||||||
[1]: https://gchq.github.io/CyberChef
|
[1]: https://gchq.github.io/CyberChef
|
||||||
[2]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22From%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%2Ctrue%5D%7D%5D&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1
|
[2]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22From%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%2Ctrue%5D%7D%5D&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1
|
||||||
[3]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Translate%20DateTime%20Format%22%2C%22args%22%3A%5B%22Standard%20date%20and%20time%22%2C%22DD%2FMM%2FYYYY%20HH%3Amm%3Ass%22%2C%22UTC%22%2C%22dddd%20Do%20MMMM%20YYYY%20HH%3Amm%3Ass%20Z%20z%22%2C%22Australia%2FQueensland%22%5D%7D%5D&input=MTUvMDYvMjAxNSAyMDo0NTowMA
|
[3]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22Translate%20DateTime%20Format%22%2C%22args%22%3A%5B%22Standard%20date%20and%20time%22%2C%22DD%2FMM%2FYYYY%20HH%3Amm%3Ass%22%2C%22UTC%22%2C%22dddd%20Do%20MMMM%20YYYY%20HH%3Amm%3Ass%20Z%20z%22%2C%22Australia%2FQueensland%22%5D%7D%5D&input=MTUvMDYvMjAxNSAyMDo0NTowMA
|
||||||
[4]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Parse%20IPv6%20address%22%2C%22args%22%3A%5B%5D%7D%5D&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy
|
[4]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22Parse%20IPv6%20address%22%2C%22args%22%3A%5B%5D%7D%5D&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy
|
||||||
[5]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22From%20Hexdump%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22Gunzip%22%2C%22args%22%3A%5B%5D%7D%5D&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu%2Fy7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb%2F3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
|
[5]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22From%20Hexdump%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22Gunzip%22%2C%22args%22%3A%5B%5D%7D%5D&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu%2Fy7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb%2F3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
|
||||||
[6]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22From%20UNIX%20Timestamp%22%2C%22args%22%3A%5B%22Seconds%20(s)%22%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
|
[6]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22From%20UNIX%20Timestamp%22%2C%22args%22%3A%5B%22Seconds%20(s)%22%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
|
||||||
[7]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22Conditional%20Jump%22%2C%22args%22%3A%5B%221%22%2C%222%22%2C%2210%22%5D%7D%2C%7B%22op%22%3A%22To%20Hex%22%2C%22args%22%3A%5B%22Space%22%5D%7D%2C%7B%22op%22%3A%22Return%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22To%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%5D%7D%5D&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
|
[7]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22Conditional%20Jump%22%2C%22args%22%3A%5B%221%22%2C%222%22%2C%2210%22%5D%7D%2C%7B%22op%22%3A%22To%20Hex%22%2C%22args%22%3A%5B%22Space%22%5D%7D%2C%7B%22op%22%3A%22Return%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22To%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%5D%7D%5D&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
|
||||||
[8]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22XOR%22%2C%22args%22%3A%5B%7B%22option%22%3A%22Hex%22%2C%22string%22%3A%223a%22%7D%2Cfalse%2Cfalse%5D%7D%2C%7B%22op%22%3A%22To%20Hexdump%22%2C%22args%22%3A%5B%2216%22%2Cfalse%2Cfalse%5D%7D%5D&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
|
[8]: https://gchq.github.io/CyberChef/#recipe=%5B%7B%22op%22%3A%22XOR%22%2C%22args%22%3A%5B%7B%22option%22%3A%22Hex%22%2C%22string%22%3A%223a%22%7D%2Cfalse%2Cfalse%5D%7D%2C%7B%22op%22%3A%22To%20Hexdump%22%2C%22args%22%3A%5B%2216%22%2Cfalse%2Cfalse%5D%7D%5D&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
|
||||||
|
|||||||
7717
package-lock.json
generated
Normal file
7717
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
41
package.json
41
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cyberchef",
|
"name": "cyberchef",
|
||||||
"version": "5.4.1",
|
"version": "5.12.1",
|
||||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||||
"author": "n1474335 <n1474335@gmail.com>",
|
"author": "n1474335 <n1474335@gmail.com>",
|
||||||
"homepage": "https://gchq.github.io/CyberChef",
|
"homepage": "https://gchq.github.io/CyberChef",
|
||||||
@@ -31,33 +31,36 @@
|
|||||||
"bugs": "https://github.com/gchq/CyberChef/issues",
|
"bugs": "https://github.com/gchq/CyberChef/issues",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.24.0",
|
"babel-core": "^6.24.0",
|
||||||
"babel-loader": "^6.4.0",
|
"babel-loader": "^7.1.1",
|
||||||
"babel-polyfill": "^6.23.0",
|
"babel-polyfill": "^6.23.0",
|
||||||
"babel-preset-env": "^1.2.2",
|
"babel-preset-env": "^1.6.0",
|
||||||
"css-loader": "^0.27.3",
|
"css-loader": "^0.28.4",
|
||||||
"exports-loader": "^0.6.4",
|
"exports-loader": "^0.6.4",
|
||||||
"extract-text-webpack-plugin": "^2.1.0",
|
"extract-text-webpack-plugin": "^3.0.0",
|
||||||
"file-loader": "^0.10.1",
|
"file-loader": "^0.11.2",
|
||||||
"grunt": ">=0.4.5",
|
"grunt": ">=0.4.5",
|
||||||
"grunt-accessibility": "~5.0.0",
|
"grunt-accessibility": "~5.0.0",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-contrib-clean": "~1.0.0",
|
"grunt-contrib-clean": "~1.1.0",
|
||||||
"grunt-contrib-copy": "~1.0.0",
|
"grunt-contrib-copy": "~1.0.0",
|
||||||
"grunt-eslint": "^19.0.0",
|
"grunt-eslint": "^20.0.0",
|
||||||
"grunt-exec": "~1.0.1",
|
"grunt-exec": "~2.0.0",
|
||||||
"grunt-execute": "^0.2.2",
|
"grunt-execute": "^0.2.2",
|
||||||
"grunt-jsdoc": "^2.1.0",
|
"grunt-jsdoc": "^2.1.0",
|
||||||
"grunt-webpack": "^2.0.1",
|
"grunt-webpack": "^3.0.2",
|
||||||
"html-webpack-plugin": "^2.28.0",
|
"html-webpack-plugin": "^2.29.0",
|
||||||
"imports-loader": "^0.7.1",
|
"imports-loader": "^0.7.1",
|
||||||
"ink-docstrap": "^1.1.4",
|
"ink-docstrap": "^1.1.4",
|
||||||
"jsdoc-babel": "^0.3.0",
|
"jsdoc-babel": "^0.3.0",
|
||||||
"less": "^2.7.2",
|
"less": "^2.7.2",
|
||||||
"less-loader": "^4.0.2",
|
"less-loader": "^4.0.5",
|
||||||
"style-loader": "^0.15.0",
|
"postcss-css-variables": "^0.7.0",
|
||||||
|
"postcss-import": "^10.0.0",
|
||||||
|
"postcss-loader": "^2.0.5",
|
||||||
|
"style-loader": "^0.18.2",
|
||||||
"url-loader": "^0.5.8",
|
"url-loader": "^0.5.8",
|
||||||
"web-resource-inliner": "^4.1.0",
|
"web-resource-inliner": "^4.1.0",
|
||||||
"webpack": "^2.2.1"
|
"webpack": "^3.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "^3.3.7",
|
"bootstrap": "^3.3.7",
|
||||||
@@ -65,15 +68,15 @@
|
|||||||
"bootstrap-switch": "^3.3.4",
|
"bootstrap-switch": "^3.3.4",
|
||||||
"crypto-api": "^0.6.2",
|
"crypto-api": "^0.6.2",
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"diff": "^3.2.0",
|
"diff": "^3.3.0",
|
||||||
"escodegen": "^1.8.1",
|
"escodegen": "^1.8.1",
|
||||||
"esmangle": "^1.0.1",
|
"esmangle": "^1.0.1",
|
||||||
"esprima": "^3.1.3",
|
"esprima": "^4.0.0",
|
||||||
"exif-parser": "^0.1.9",
|
"exif-parser": "^0.1.12",
|
||||||
"google-code-prettify": "^1.0.5",
|
"google-code-prettify": "^1.0.5",
|
||||||
"jquery": "^3.1.1",
|
"jquery": "^3.1.1",
|
||||||
"jsbn": "^1.1.0",
|
"jsbn": "^1.1.0",
|
||||||
"jsrsasign": "7.1.3",
|
"jsrsasign": "8.0.3",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"moment": "^2.17.1",
|
"moment": "^2.17.1",
|
||||||
"moment-timezone": "^0.5.11",
|
"moment-timezone": "^0.5.11",
|
||||||
@@ -83,7 +86,7 @@
|
|||||||
"vkbeautify": "^0.99.1",
|
"vkbeautify": "^0.99.1",
|
||||||
"xmldom": "^0.1.27",
|
"xmldom": "^0.1.27",
|
||||||
"xpath": "0.0.24",
|
"xpath": "0.0.24",
|
||||||
"zlibjs": "^0.2.0"
|
"zlibjs": "^0.3.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "grunt prod",
|
"build": "grunt prod",
|
||||||
|
|||||||
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
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -73,7 +73,7 @@ Ingredient.prepare = function(data, type) {
|
|||||||
case "byteArray":
|
case "byteArray":
|
||||||
if (typeof data == "string") {
|
if (typeof data == "string") {
|
||||||
data = data.replace(/\s+/g, "");
|
data = data.replace(/\s+/g, "");
|
||||||
return Utils.hexToByteArray(data);
|
return Utils.fromHex(data);
|
||||||
} else {
|
} else {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,10 +164,10 @@ Recipe.prototype.execute = async function(dish, startFrom) {
|
|||||||
if (op.isFlowControl()) {
|
if (op.isFlowControl()) {
|
||||||
// Package up the current state
|
// Package up the current state
|
||||||
let state = {
|
let state = {
|
||||||
"progress" : i,
|
"progress": i,
|
||||||
"dish" : dish,
|
"dish": dish,
|
||||||
"opList" : this.opList,
|
"opList": this.opList,
|
||||||
"numJumps" : numJumps
|
"numJumps": numJumps
|
||||||
};
|
};
|
||||||
|
|
||||||
state = await op.run(state);
|
state = await op.run(state);
|
||||||
|
|||||||
@@ -23,6 +23,16 @@ const Utils = {
|
|||||||
* Utils.chr(97);
|
* Utils.chr(97);
|
||||||
*/
|
*/
|
||||||
chr: function(o) {
|
chr: function(o) {
|
||||||
|
// Detect astral symbols
|
||||||
|
// Thanks to @mathiasbynens for this solution
|
||||||
|
// https://mathiasbynens.be/notes/javascript-unicode
|
||||||
|
if (o > 0xffff) {
|
||||||
|
o -= 0x10000;
|
||||||
|
const high = String.fromCharCode(o >>> 10 & 0x3ff | 0xd800);
|
||||||
|
o = 0xdc00 | o & 0x3ff;
|
||||||
|
return high + String.fromCharCode(o);
|
||||||
|
}
|
||||||
|
|
||||||
return String.fromCharCode(o);
|
return String.fromCharCode(o);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -38,6 +48,18 @@ const Utils = {
|
|||||||
* Utils.ord('a');
|
* Utils.ord('a');
|
||||||
*/
|
*/
|
||||||
ord: function(c) {
|
ord: function(c) {
|
||||||
|
// Detect astral symbols
|
||||||
|
// Thanks to @mathiasbynens for this solution
|
||||||
|
// https://mathiasbynens.be/notes/javascript-unicode
|
||||||
|
if (c.length === 2) {
|
||||||
|
const high = c.charCodeAt(0);
|
||||||
|
const low = c.charCodeAt(1);
|
||||||
|
if (high >= 0xd800 && high < 0xdc00 &&
|
||||||
|
low >= 0xdc00 && low < 0xe000) {
|
||||||
|
return (high - 0xd800) * 0x400 + low - 0xdc00 + 0x10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return c.charCodeAt(0);
|
return c.charCodeAt(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -216,7 +238,7 @@ const Utils = {
|
|||||||
str = Utils.byteArrayToChars(Utils.strToByteArray(str));
|
str = Utils.byteArrayToChars(Utils.strToByteArray(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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-\uD7FF\uE000-\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;
|
const wsRe = /[\x09-\x10\x0D\u2028\u2029]/g;
|
||||||
|
|
||||||
str = str.replace(re, ".");
|
str = str.replace(re, ".");
|
||||||
@@ -259,6 +281,22 @@ const Utils = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape a string containing regex control characters so that it can be safely
|
||||||
|
* used in a regex without causing unintended behaviours.
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // returns "\[example\]"
|
||||||
|
* Utils.escapeRegex("[example]");
|
||||||
|
*/
|
||||||
|
escapeRegex: function(str) {
|
||||||
|
return str.replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1");
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand an alphabet range string into a list of the characters in that range.
|
* Expand an alphabet range string into a list of the characters in that range.
|
||||||
*
|
*
|
||||||
@@ -302,48 +340,6 @@ const Utils = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates a hex string into an array of bytes.
|
|
||||||
*
|
|
||||||
* @param {string} hexStr
|
|
||||||
* @returns {byteArray}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // returns [0xfe, 0x09, 0xa7]
|
|
||||||
* Utils.hexToByteArray("fe09a7");
|
|
||||||
*/
|
|
||||||
hexToByteArray: function(hexStr) {
|
|
||||||
// TODO: Handle errors i.e. input string is not hex
|
|
||||||
if (!hexStr) return [];
|
|
||||||
hexStr = hexStr.replace(/\s+/g, "");
|
|
||||||
const byteArray = [];
|
|
||||||
for (let i = 0; i < hexStr.length; i += 2) {
|
|
||||||
byteArray.push(parseInt(hexStr.substr(i, 2), 16));
|
|
||||||
}
|
|
||||||
return byteArray;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates an array of bytes to a hex string.
|
|
||||||
*
|
|
||||||
* @param {byteArray} byteArray
|
|
||||||
* @returns {string}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // returns "fe09a7"
|
|
||||||
* Utils.byteArrayToHex([0xfe, 0x09, 0xa7]);
|
|
||||||
*/
|
|
||||||
byteArrayToHex: function(byteArray) {
|
|
||||||
if (!byteArray) return "";
|
|
||||||
let hexStr = "";
|
|
||||||
for (let i = 0; i < byteArray.length; i++) {
|
|
||||||
hexStr += Utils.hex(byteArray[i]) + " ";
|
|
||||||
}
|
|
||||||
return hexStr.slice(0, hexStr.length-1);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a string to a byte array.
|
* Converts a string to a byte array.
|
||||||
* Treats the string as UTF-8 if any values are over 255.
|
* Treats the string as UTF-8 if any values are over 255.
|
||||||
@@ -396,7 +392,7 @@ const Utils = {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a string to a charcode array
|
* Converts a string to a unicode charcode array
|
||||||
*
|
*
|
||||||
* @param {string} str
|
* @param {string} str
|
||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
@@ -409,12 +405,23 @@ const Utils = {
|
|||||||
* Utils.strToCharcode("你好");
|
* Utils.strToCharcode("你好");
|
||||||
*/
|
*/
|
||||||
strToCharcode: function(str) {
|
strToCharcode: function(str) {
|
||||||
const byteArray = new Array(str.length);
|
const charcode = new Array();
|
||||||
let i = str.length;
|
|
||||||
while (i--) {
|
for (let i = 0; i < str.length; i++) {
|
||||||
byteArray[i] = str.charCodeAt(i);
|
let ord = str.charCodeAt(i);
|
||||||
|
|
||||||
|
// Detect and merge astral symbols
|
||||||
|
if (i < str.length - 1 && ord >= 0xd800 && ord < 0xdc00) {
|
||||||
|
const low = str[i + 1].charCodeAt(0);
|
||||||
|
if (low >= 0xdc00 && low < 0xe000) {
|
||||||
|
ord = Utils.ord(str[i] + str[++i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
charcode.push(ord);
|
||||||
}
|
}
|
||||||
return byteArray;
|
|
||||||
|
return charcode;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@@ -498,127 +505,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) {
|
|
||||||
const res = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < unicStr.length; i++) {
|
|
||||||
const 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) {
|
|
||||||
const res = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < win1251Str.length; i++) {
|
|
||||||
const 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.
|
* Base64's the input byte array using the given alphabet, returning a string.
|
||||||
*
|
*
|
||||||
@@ -706,7 +592,7 @@ const Utils = {
|
|||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (removeNonAlphChars) {
|
if (removeNonAlphChars) {
|
||||||
const re = new RegExp("[^" + alphabet.replace(/[\[\]\\\-^$]/g, "\\$&") + "]", "g");
|
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||||
data = data.replace(re, "");
|
data = data.replace(re, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,7 +784,7 @@ const Utils = {
|
|||||||
if (removeScriptAndStyle) {
|
if (removeScriptAndStyle) {
|
||||||
htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*<\/(script|style)>/gmi, "");
|
htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*<\/(script|style)>/gmi, "");
|
||||||
}
|
}
|
||||||
return htmlStr.replace(/<[^>\n]+>/g, "");
|
return htmlStr.replace(/<[^>]+>/g, "");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@@ -924,7 +810,7 @@ const Utils = {
|
|||||||
"`": "`"
|
"`": "`"
|
||||||
};
|
};
|
||||||
|
|
||||||
return str.replace(/[&<>"'\/`]/g, function (match) {
|
return str.replace(/[&<>"'/`]/g, function (match) {
|
||||||
return HTML_CHARS[match];
|
return HTML_CHARS[match];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -1015,17 +901,20 @@ const Utils = {
|
|||||||
* @param {Object[]} files
|
* @param {Object[]} files
|
||||||
* @returns {html}
|
* @returns {html}
|
||||||
*/
|
*/
|
||||||
displayFilesAsHTML: function(files){
|
displayFilesAsHTML: function(files) {
|
||||||
|
/* <NL> and <SP> used to denote newlines and spaces in HTML markup.
|
||||||
|
* If a non-html operation is used, all markup will be removed but these
|
||||||
|
* whitespace chars will remain for formatting purposes.
|
||||||
|
*/
|
||||||
|
|
||||||
const formatDirectory = function(file) {
|
const formatDirectory = function(file) {
|
||||||
const html = "<div class='panel panel-default'>" +
|
const html = `<div class='panel panel-default' style='white-space: normal;'>
|
||||||
"<div class='panel-heading' role='tab'>" +
|
<div class='panel-heading' role='tab'>
|
||||||
"<h4 class='panel-title'>" +
|
<h4 class='panel-title'>
|
||||||
file.fileName +
|
<NL>${Utils.escapeHtml(file.fileName)}
|
||||||
// The following line is for formatting when HTML is stripped
|
</h4>
|
||||||
"<span style='display: none'>\n0 bytes\n</span>" +
|
</div>
|
||||||
"</h4>" +
|
</div>`;
|
||||||
"</div>" +
|
|
||||||
"</div>";
|
|
||||||
return html;
|
return html;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1036,45 +925,52 @@ const Utils = {
|
|||||||
);
|
);
|
||||||
const blobUrl = URL.createObjectURL(blob);
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
const downloadAnchorElem = "<a href='" + blobUrl + "' " +
|
const viewFileElem = `<a href='#collapse${i}'
|
||||||
"title='Download " + Utils.escapeHtml(file.fileName) + "' " +
|
class='collapsed'
|
||||||
"download='" + Utils.escapeHtml(file.fileName) + "'>\u21B4</a>";
|
data-toggle='collapse'
|
||||||
|
aria-expanded='true'
|
||||||
|
aria-controls='collapse${i}'
|
||||||
|
title="Show/hide contents of '${Utils.escapeHtml(file.fileName)}'">👁️</a>`;
|
||||||
|
|
||||||
const expandFileContentsElem = "<a href='#collapse" + i + "' " +
|
const downloadFileElem = `<a href='${blobUrl}'
|
||||||
"class='collapsed' " +
|
title='Download ${Utils.escapeHtml(file.fileName)}'
|
||||||
"data-toggle='collapse' " +
|
download='${Utils.escapeHtml(file.fileName)}'>💾</a>`;
|
||||||
"aria-expanded='true' " +
|
|
||||||
"aria-controls='collapse" + i + "' " +
|
|
||||||
"title=\"Show/hide contents of '" + Utils.escapeHtml(file.fileName) + "'\">🔍</a>";
|
|
||||||
|
|
||||||
const html = "<div class='panel panel-default'>" +
|
const hexFileData = Utils.toHexFast(new Uint8Array(file.bytes));
|
||||||
"<div class='panel-heading' role='tab' id='heading" + i + "'>" +
|
|
||||||
"<h4 class='panel-title'>" +
|
const switchToInputElem = `<a href='#switchFileToInput${i}'
|
||||||
"<div>" +
|
class='file-switch'
|
||||||
Utils.escapeHtml(file.fileName) +
|
title='Move file to input as hex'
|
||||||
" " + expandFileContentsElem +
|
fileValue='${hexFileData}'>⇧</a>`;
|
||||||
" " + downloadAnchorElem +
|
|
||||||
"<span class='pull-right'>" +
|
const html = `<div class='panel panel-default' style='white-space: normal;'>
|
||||||
// These are for formatting when stripping HTML
|
<div class='panel-heading' role='tab' id='heading${i}'>
|
||||||
"<span style='display: none'>\n</span>" +
|
<h4 class='panel-title'>
|
||||||
file.size.toLocaleString() + " bytes" +
|
<div>
|
||||||
"<span style='display: none'>\n</span>" +
|
${Utils.escapeHtml(file.fileName)}<NL>
|
||||||
"</span>" +
|
${viewFileElem}<SP>
|
||||||
"</div>" +
|
${downloadFileElem}<SP>
|
||||||
"</h4>" +
|
${switchToInputElem}<SP>
|
||||||
"</div>" +
|
<span class='pull-right'>
|
||||||
"<div id='collapse" + i + "' class='panel-collapse collapse' " +
|
<NL>${file.size.toLocaleString()} bytes
|
||||||
"role='tabpanel' aria-labelledby='heading" + i + "'>" +
|
</span>
|
||||||
"<div class='panel-body'>" +
|
</div>
|
||||||
"<pre><code>" + Utils.escapeHtml(file.contents) + "</pre></code></div>" +
|
</h4>
|
||||||
"</div>" +
|
</div>
|
||||||
"</div>";
|
<div id='collapse${i}' class='panel-collapse collapse'
|
||||||
|
role='tabpanel' aria-labelledby='heading${i}'>
|
||||||
|
<div class='panel-body'>
|
||||||
|
<NL><NL><pre><code>${Utils.escapeHtml(file.contents)}</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
return html;
|
return html;
|
||||||
};
|
};
|
||||||
|
|
||||||
let html = "<div style='padding: 5px;'>" +
|
let html = `<div style='padding: 5px; white-space: normal;'>
|
||||||
files.length +
|
${files.length} file(s) found<NL>
|
||||||
" file(s) found</div>\n";
|
</div>`;
|
||||||
|
|
||||||
files.forEach(function(file, i) {
|
files.forEach(function(file, i) {
|
||||||
if (typeof file.contents !== "undefined") {
|
if (typeof file.contents !== "undefined") {
|
||||||
html += formatFile(file, i);
|
html += formatFile(file, i);
|
||||||
@@ -1082,14 +978,53 @@ const Utils = {
|
|||||||
html += formatDirectory(file);
|
html += formatDirectory(file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return html;
|
|
||||||
|
return html.replace(/(?:(<pre>(?:\n|.)*<\/pre>)|\s{2,})/g, "$1") // Remove whitespace from markup
|
||||||
|
.replace(/<NL>/g, "\n") // Replace <NP> with newlines
|
||||||
|
.replace(/<SP>/g, " "); // Replace <SP> with spaces
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses URI parameters into a JSON object.
|
||||||
|
*
|
||||||
|
* @param {string} paramStr - The serialised query or hash section of a URI
|
||||||
|
* @returns {object}
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // returns {a: 'abc', b: '123'}
|
||||||
|
* Utils.parseURIParams("?a=abc&b=123")
|
||||||
|
* Utils.parseURIParams("#a=abc&b=123")
|
||||||
|
*/
|
||||||
|
parseURIParams: function(paramStr) {
|
||||||
|
if (paramStr === "") return {};
|
||||||
|
|
||||||
|
// Cut off ? or # and split on &
|
||||||
|
if (paramStr[0] === "?" ||
|
||||||
|
paramStr[0] === "#") {
|
||||||
|
paramStr = paramStr.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = paramStr.split("&");
|
||||||
|
const result = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < params.length; i++) {
|
||||||
|
const param = params[i].split("=");
|
||||||
|
if (param.length !== 2) {
|
||||||
|
result[params[i]] = true;
|
||||||
|
} else {
|
||||||
|
result[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actual modulo function, since % is actually the remainder function in JS.
|
* Actual modulo function, since % is actually the remainder function in JS.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {number} x
|
* @param {number} x
|
||||||
* @param {number} y
|
* @param {number} y
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
@@ -1102,7 +1037,7 @@ const Utils = {
|
|||||||
/**
|
/**
|
||||||
* Finds the greatest common divisor of two numbers.
|
* Finds the greatest common divisor of two numbers.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {number} x
|
* @param {number} x
|
||||||
* @param {number} y
|
* @param {number} y
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
@@ -1118,7 +1053,7 @@ const Utils = {
|
|||||||
/**
|
/**
|
||||||
* Finds the modular inverse of two values.
|
* Finds the modular inverse of two values.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {number} x
|
* @param {number} x
|
||||||
* @param {number} y
|
* @param {number} y
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ const Categories = [
|
|||||||
"From Base58",
|
"From Base58",
|
||||||
"To Base",
|
"To Base",
|
||||||
"From Base",
|
"From Base",
|
||||||
|
"To BCD",
|
||||||
|
"From BCD",
|
||||||
"To HTML Entity",
|
"To HTML Entity",
|
||||||
"From HTML Entity",
|
"From HTML Entity",
|
||||||
"URL Encode",
|
"URL Encode",
|
||||||
@@ -61,7 +63,8 @@ const Categories = [
|
|||||||
"Hex to PEM",
|
"Hex to PEM",
|
||||||
"Parse ASN.1 hex string",
|
"Parse ASN.1 hex string",
|
||||||
"Change IP format",
|
"Change IP format",
|
||||||
"Text encoding",
|
"Encode text",
|
||||||
|
"Decode text",
|
||||||
"Swap endianness",
|
"Swap endianness",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -88,6 +91,8 @@ const Categories = [
|
|||||||
"Vigenère Decode",
|
"Vigenère Decode",
|
||||||
"To Morse Code",
|
"To Morse Code",
|
||||||
"From Morse Code",
|
"From Morse Code",
|
||||||
|
"Bifid Cipher Encode",
|
||||||
|
"Bifid Cipher Decode",
|
||||||
"Affine Cipher Encode",
|
"Affine Cipher Encode",
|
||||||
"Affine Cipher Decode",
|
"Affine Cipher Decode",
|
||||||
"Atbash Cipher",
|
"Atbash Cipher",
|
||||||
@@ -125,6 +130,7 @@ const Categories = [
|
|||||||
{
|
{
|
||||||
name: "Networking",
|
name: "Networking",
|
||||||
ops: [
|
ops: [
|
||||||
|
"HTTP request",
|
||||||
"Strip HTTP headers",
|
"Strip HTTP headers",
|
||||||
"Parse User Agent",
|
"Parse User Agent",
|
||||||
"Parse IP range",
|
"Parse IP range",
|
||||||
@@ -143,7 +149,8 @@ const Categories = [
|
|||||||
{
|
{
|
||||||
name: "Language",
|
name: "Language",
|
||||||
ops: [
|
ops: [
|
||||||
"Text encoding",
|
"Encode text",
|
||||||
|
"Decode text",
|
||||||
"Unescape Unicode Characters",
|
"Unescape Unicode Characters",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -190,6 +197,8 @@ const Categories = [
|
|||||||
"Translate DateTime Format",
|
"Translate DateTime Format",
|
||||||
"From UNIX Timestamp",
|
"From UNIX Timestamp",
|
||||||
"To UNIX Timestamp",
|
"To UNIX Timestamp",
|
||||||
|
"Windows Filetime to UNIX Timestamp",
|
||||||
|
"UNIX Timestamp to Windows Filetime",
|
||||||
"Extract dates",
|
"Extract dates",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -285,6 +294,9 @@ const Categories = [
|
|||||||
"Detect File Type",
|
"Detect File Type",
|
||||||
"Scan for Embedded Files",
|
"Scan for Embedded Files",
|
||||||
"Generate UUID",
|
"Generate UUID",
|
||||||
|
"Render Image",
|
||||||
|
"Remove EXIF",
|
||||||
|
"Extract EXIF",
|
||||||
"Numberwang",
|
"Numberwang",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import FlowControl from "../FlowControl.js";
|
|||||||
import Base from "../operations/Base.js";
|
import Base from "../operations/Base.js";
|
||||||
import Base58 from "../operations/Base58.js";
|
import Base58 from "../operations/Base58.js";
|
||||||
import Base64 from "../operations/Base64.js";
|
import Base64 from "../operations/Base64.js";
|
||||||
|
import BCD from "../operations/BCD.js";
|
||||||
import BitwiseOp from "../operations/BitwiseOp.js";
|
import BitwiseOp from "../operations/BitwiseOp.js";
|
||||||
import ByteRepr from "../operations/ByteRepr.js";
|
import ByteRepr from "../operations/ByteRepr.js";
|
||||||
import CharEnc from "../operations/CharEnc.js";
|
import CharEnc from "../operations/CharEnc.js";
|
||||||
@@ -330,30 +331,25 @@ const OperationConfig = {
|
|||||||
value: BitwiseOp.XOR_BRUTE_KEY_LENGTH
|
value: BitwiseOp.XOR_BRUTE_KEY_LENGTH
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Length of sample",
|
name: "Sample length",
|
||||||
type: "number",
|
type: "number",
|
||||||
value: BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH
|
value: BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Offset of sample",
|
name: "Sample offset",
|
||||||
type: "number",
|
type: "number",
|
||||||
value: BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET
|
value: BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Scheme",
|
||||||
|
type: "option",
|
||||||
|
value: BitwiseOp.XOR_SCHEME
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Null preserving",
|
name: "Null preserving",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: BitwiseOp.XOR_PRESERVE_NULLS
|
value: BitwiseOp.XOR_PRESERVE_NULLS
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Differential",
|
|
||||||
type: "boolean",
|
|
||||||
value: BitwiseOp.XOR_DIFFERENTIAL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Crib (known plaintext string)",
|
|
||||||
type: "binaryString",
|
|
||||||
value: ""
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Print key",
|
name: "Print key",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
@@ -363,6 +359,11 @@ const OperationConfig = {
|
|||||||
name: "Output as hex",
|
name: "Output as hex",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: BitwiseOp.XOR_BRUTE_OUTPUT_HEX
|
value: BitwiseOp.XOR_BRUTE_OUTPUT_HEX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Crib (known plaintext string)",
|
||||||
|
type: "binaryString",
|
||||||
|
value: ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -605,7 +606,7 @@ const OperationConfig = {
|
|||||||
args: []
|
args: []
|
||||||
},
|
},
|
||||||
"To Hexdump": {
|
"To Hexdump": {
|
||||||
description: "Creates a hexdump of the input data, displaying both the hexademinal values of each byte and an ASCII representation alongside.",
|
description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.",
|
||||||
run: Hexdump.runTo,
|
run: Hexdump.runTo,
|
||||||
highlight: Hexdump.highlightTo,
|
highlight: Hexdump.highlightTo,
|
||||||
highlightReverse: Hexdump.highlightFrom,
|
highlightReverse: Hexdump.highlightFrom,
|
||||||
@@ -887,21 +888,43 @@ const OperationConfig = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Text encoding": {
|
"Encode text": {
|
||||||
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>",
|
description: [
|
||||||
run: CharEnc.run,
|
"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",
|
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",
|
outputType: "string",
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "Input type",
|
name: "Encoding",
|
||||||
type: "option",
|
type: "option",
|
||||||
value: CharEnc.IO_FORMAT
|
value: Object.keys(CharEnc.IO_FORMAT),
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Output type",
|
|
||||||
type: "option",
|
|
||||||
value: CharEnc.IO_FORMAT
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -922,7 +945,6 @@ const OperationConfig = {
|
|||||||
type: "toggleString",
|
type: "toggleString",
|
||||||
value: "",
|
value: "",
|
||||||
toggleValues: Cipher.IO_FORMAT1
|
toggleValues: Cipher.IO_FORMAT1
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Salt",
|
name: "Salt",
|
||||||
@@ -969,7 +991,6 @@ const OperationConfig = {
|
|||||||
type: "toggleString",
|
type: "toggleString",
|
||||||
value: "",
|
value: "",
|
||||||
toggleValues: Cipher.IO_FORMAT1
|
toggleValues: Cipher.IO_FORMAT1
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Salt",
|
name: "Salt",
|
||||||
@@ -1492,6 +1513,36 @@ const OperationConfig = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"Bifid Cipher Encode": {
|
||||||
|
description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.",
|
||||||
|
run: Cipher.runBifidEnc,
|
||||||
|
highlight: true,
|
||||||
|
highlightReverse: true,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Keyword",
|
||||||
|
type: "string",
|
||||||
|
value: ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Bifid Cipher Decode": {
|
||||||
|
description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.",
|
||||||
|
run: Cipher.runBifidDec,
|
||||||
|
highlight: true,
|
||||||
|
highlightReverse: true,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Keyword",
|
||||||
|
type: "string",
|
||||||
|
value: ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"Affine Cipher Encode": {
|
"Affine Cipher Encode": {
|
||||||
description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, <code>(ax + b) % 26</code>, and converted back to a letter.",
|
description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, <code>(ax + b) % 26</code>, and converted back to a letter.",
|
||||||
run: Cipher.runAffineEnc,
|
run: Cipher.runAffineEnc,
|
||||||
@@ -1899,7 +1950,7 @@ const OperationConfig = {
|
|||||||
args: []
|
args: []
|
||||||
},
|
},
|
||||||
"Find / Replace": {
|
"Find / Replace": {
|
||||||
description: "Replaces all occurrences of the first string with the second.<br><br>The three match options are only relevant to regex search strings.",
|
description: "Replaces all occurrences of the first string with the second.<br><br> Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).",
|
||||||
run: StrUtils.runFindReplace,
|
run: StrUtils.runFindReplace,
|
||||||
manualBake: true,
|
manualBake: true,
|
||||||
inputType: "string",
|
inputType: "string",
|
||||||
@@ -2211,7 +2262,7 @@ const OperationConfig = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"From UNIX Timestamp": {
|
"From UNIX Timestamp": {
|
||||||
description: "Converts a UNIX timestamp to a datetime string.<br><br>e.g. <code>978346800</code> becomes <code>Mon 1 January 2001 11:00:00 UTC</code>",
|
description: "Converts a UNIX timestamp to a datetime string.<br><br>e.g. <code>978346800</code> becomes <code>Mon 1 January 2001 11:00:00 UTC</code><br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).",
|
||||||
run: DateTime.runFromUnixTimestamp,
|
run: DateTime.runFromUnixTimestamp,
|
||||||
inputType: "number",
|
inputType: "number",
|
||||||
outputType: "string",
|
outputType: "string",
|
||||||
@@ -2224,7 +2275,7 @@ const OperationConfig = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"To UNIX Timestamp": {
|
"To UNIX Timestamp": {
|
||||||
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>",
|
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><br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).",
|
||||||
run: DateTime.runToUnixTimestamp,
|
run: DateTime.runToUnixTimestamp,
|
||||||
inputType: "string",
|
inputType: "string",
|
||||||
outputType: "number",
|
outputType: "number",
|
||||||
@@ -2241,6 +2292,42 @@ const OperationConfig = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"Windows Filetime to UNIX Timestamp": {
|
||||||
|
description: "Converts a Windows Filetime value to a UNIX timestamp.<br><br>A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.<br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).<br><br>This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.",
|
||||||
|
run: DateTime.runFromFiletimeToUnix,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Output units",
|
||||||
|
type: "option",
|
||||||
|
value: DateTime.UNITS
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input format",
|
||||||
|
type: "option",
|
||||||
|
value: DateTime.FILETIME_FORMATS
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"UNIX Timestamp to Windows Filetime": {
|
||||||
|
description: "Converts a UNIX timestamp to a Windows Filetime value.<br><br>A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.<br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).<br><br>This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.",
|
||||||
|
run: DateTime.runToFiletimeFromUnix,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Input units",
|
||||||
|
type: "option",
|
||||||
|
value: DateTime.UNITS
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Output format",
|
||||||
|
type: "option",
|
||||||
|
value: DateTime.FILETIME_FORMATS
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"Translate DateTime Format": {
|
"Translate DateTime Format": {
|
||||||
description: "Parses a datetime string in one format and re-writes it in another.<br><br>Run with no input to see the relevant format string examples.",
|
description: "Parses a datetime string in one format and re-writes it in another.<br><br>Run with no input to see the relevant format string examples.",
|
||||||
run: DateTime.runTranslateFormat,
|
run: DateTime.runTranslateFormat,
|
||||||
@@ -3150,8 +3237,8 @@ const OperationConfig = {
|
|||||||
"Substitute": {
|
"Substitute": {
|
||||||
description: "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.<br><br>Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.<br><br>Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either <code>\\n</code> or <code>\\x0a</code>.<br><br>Byte ranges can be specified using a hyphen. For example, the sequence <code>0123456789</code> can be written as <code>0-9</code>.",
|
description: "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.<br><br>Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.<br><br>Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either <code>\\n</code> or <code>\\x0a</code>.<br><br>Byte ranges can be specified using a hyphen. For example, the sequence <code>0123456789</code> can be written as <code>0-9</code>.",
|
||||||
run: Cipher.runSubstitute,
|
run: Cipher.runSubstitute,
|
||||||
inputType: "byteArray",
|
inputType: "string",
|
||||||
outputType: "byteArray",
|
outputType: "string",
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "Plaintext",
|
name: "Plaintext",
|
||||||
@@ -3350,11 +3437,135 @@ const OperationConfig = {
|
|||||||
"<br><br>",
|
"<br><br>",
|
||||||
"EXIF data from photos usually contains information about the image file itself as well as the device used to create it.",
|
"EXIF data from photos usually contains information about the image file itself as well as the device used to create it.",
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
run: Image.runEXIF,
|
run: Image.runExtractEXIF,
|
||||||
inputType: "byteArray",
|
inputType: "byteArray",
|
||||||
outputType: "string",
|
outputType: "string",
|
||||||
args: [],
|
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,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"From BCD": {
|
||||||
|
description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.",
|
||||||
|
run: BCD.runFromBCD,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "number",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Scheme",
|
||||||
|
type: "option",
|
||||||
|
value: BCD.ENCODING_SCHEME
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Packed",
|
||||||
|
type: "boolean",
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Signed",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input format",
|
||||||
|
type: "option",
|
||||||
|
value: BCD.FORMAT
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
|
"To BCD": {
|
||||||
|
description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign",
|
||||||
|
run: BCD.runToBCD,
|
||||||
|
inputType: "number",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Scheme",
|
||||||
|
type: "option",
|
||||||
|
value: BCD.ENCODING_SCHEME
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Packed",
|
||||||
|
type: "boolean",
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Signed",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Output format",
|
||||||
|
type: "option",
|
||||||
|
value: BCD.FORMAT
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default OperationConfig;
|
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;
|
||||||
214
src/core/operations/BCD.js
Executable file
214
src/core/operations/BCD.js
Executable file
@@ -0,0 +1,214 @@
|
|||||||
|
import Utils from "../Utils.js";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binary-Coded Decimal operations.
|
||||||
|
*
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*
|
||||||
|
* @namespace
|
||||||
|
*/
|
||||||
|
const BCD = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
ENCODING_SCHEME: [
|
||||||
|
"8 4 2 1",
|
||||||
|
"7 4 2 1",
|
||||||
|
"4 2 2 1",
|
||||||
|
"2 4 2 1",
|
||||||
|
"8 4 -2 -1",
|
||||||
|
"Excess-3",
|
||||||
|
"IBM 8 4 2 1",
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup table for the binary value of each digit representation.
|
||||||
|
*
|
||||||
|
* I wrote a very nice algorithm to generate 8 4 2 1 encoding programatically,
|
||||||
|
* but unfortunately it's much easier (if less elegant) to use lookup tables
|
||||||
|
* when supporting multiple encoding schemes.
|
||||||
|
*
|
||||||
|
* "Practicality beats purity" - PEP 20
|
||||||
|
*
|
||||||
|
* In some schemes it is possible to represent the same value in multiple ways.
|
||||||
|
* For instance, in 4 2 2 1 encoding, 0100 and 0010 both represent 2. Support
|
||||||
|
* has not yet been added for this.
|
||||||
|
*
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
ENCODING_LOOKUP: {
|
||||||
|
"8 4 2 1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||||
|
"7 4 2 1": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10],
|
||||||
|
"4 2 2 1": [0, 1, 4, 5, 8, 9, 12, 13, 14, 15],
|
||||||
|
"2 4 2 1": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15],
|
||||||
|
"8 4 -2 -1": [0, 7, 6, 5, 4, 11, 10, 9, 8, 15],
|
||||||
|
"Excess-3": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||||
|
"IBM 8 4 2 1": [10, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @default
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
FORMAT: ["Nibbles", "Bytes", "Raw"],
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To BCD operation.
|
||||||
|
*
|
||||||
|
* @param {number} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runToBCD: function(input, args) {
|
||||||
|
if (isNaN(input))
|
||||||
|
return "Invalid input";
|
||||||
|
if (Math.floor(input) !== input)
|
||||||
|
return "Fractional values are not supported by BCD";
|
||||||
|
|
||||||
|
const encoding = BCD.ENCODING_LOOKUP[args[0]],
|
||||||
|
packed = args[1],
|
||||||
|
signed = args[2],
|
||||||
|
outputFormat = args[3];
|
||||||
|
|
||||||
|
// Split input number up into separate digits
|
||||||
|
const digits = input.toString().split("");
|
||||||
|
|
||||||
|
if (digits[0] === "-" || digits[0] === "+") {
|
||||||
|
digits.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
let nibbles = [];
|
||||||
|
|
||||||
|
digits.forEach(d => {
|
||||||
|
const n = parseInt(d, 10);
|
||||||
|
nibbles.push(encoding[n]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (signed) {
|
||||||
|
if (packed && digits.length % 2 === 0) {
|
||||||
|
// If there are an even number of digits, we add a leading 0 so
|
||||||
|
// that the sign nibble doesn't sit in its own byte, leading to
|
||||||
|
// ambiguity around whether the number ends with a 0 or not.
|
||||||
|
nibbles.unshift(encoding[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
nibbles.push(input > 0 ? 12 : 13);
|
||||||
|
// 12 ("C") for + (credit)
|
||||||
|
// 13 ("D") for - (debit)
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes = [];
|
||||||
|
|
||||||
|
if (packed) {
|
||||||
|
let encoded = 0,
|
||||||
|
little = false;
|
||||||
|
|
||||||
|
nibbles.forEach(n => {
|
||||||
|
encoded ^= little ? n : (n << 4);
|
||||||
|
if (little) {
|
||||||
|
bytes.push(encoded);
|
||||||
|
encoded = 0;
|
||||||
|
}
|
||||||
|
little = !little;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (little) bytes.push(encoded);
|
||||||
|
} else {
|
||||||
|
bytes = nibbles;
|
||||||
|
|
||||||
|
// Add null high nibbles
|
||||||
|
nibbles = nibbles.map(n => {
|
||||||
|
return [0, n];
|
||||||
|
}).reduce((a, b) => {
|
||||||
|
return a.concat(b);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output
|
||||||
|
switch (outputFormat) {
|
||||||
|
case "Nibbles":
|
||||||
|
return nibbles.map(n => {
|
||||||
|
return Utils.padLeft(n.toString(2), 4);
|
||||||
|
}).join(" ");
|
||||||
|
case "Bytes":
|
||||||
|
return bytes.map(b => {
|
||||||
|
return Utils.padLeft(b.toString(2), 8);
|
||||||
|
}).join(" ");
|
||||||
|
case "Raw":
|
||||||
|
default:
|
||||||
|
return Utils.byteArrayToChars(bytes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From BCD operation.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
runFromBCD: function(input, args) {
|
||||||
|
const encoding = BCD.ENCODING_LOOKUP[args[0]],
|
||||||
|
packed = args[1],
|
||||||
|
signed = args[2],
|
||||||
|
inputFormat = args[3];
|
||||||
|
|
||||||
|
let nibbles = [],
|
||||||
|
output = "",
|
||||||
|
byteArray;
|
||||||
|
|
||||||
|
// Normalise the input
|
||||||
|
switch (inputFormat) {
|
||||||
|
case "Nibbles":
|
||||||
|
case "Bytes":
|
||||||
|
input = input.replace(/\s/g, "");
|
||||||
|
for (let i = 0; i < input.length; i += 4) {
|
||||||
|
nibbles.push(parseInt(input.substr(i, 4), 2));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Raw":
|
||||||
|
default:
|
||||||
|
byteArray = Utils.strToByteArray(input);
|
||||||
|
byteArray.forEach(b => {
|
||||||
|
nibbles.push(b >>> 4);
|
||||||
|
nibbles.push(b & 15);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!packed) {
|
||||||
|
// Discard each high nibble
|
||||||
|
for (let i = 0; i < nibbles.length; i++) {
|
||||||
|
nibbles.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signed) {
|
||||||
|
const sign = nibbles.pop();
|
||||||
|
if (sign === 13 ||
|
||||||
|
sign === 11) {
|
||||||
|
// Negative
|
||||||
|
output += "-";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nibbles.forEach(n => {
|
||||||
|
if (isNaN(n)) throw "Invalid input";
|
||||||
|
let val = encoding.indexOf(n);
|
||||||
|
if (val < 0) throw `Value ${Utils.bin(n, 4)} not in encoding scheme`;
|
||||||
|
output += val.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
return parseInt(output, 10);
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BCD;
|
||||||
@@ -221,15 +221,15 @@ const Base64 = {
|
|||||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
|
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
|
||||||
staticSection + "</span>" +
|
staticSection + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
|
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
|
||||||
"<span class='hlred'>" + offset0.substr(offset0.length - 2) + "</span>";
|
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
|
||||||
} else if (len0 % 4 === 3) {
|
} else if (len0 % 4 === 3) {
|
||||||
staticSection = offset0.slice(0, -2);
|
staticSection = offset0.slice(0, -2);
|
||||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
|
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
|
||||||
staticSection + "</span>" +
|
staticSection + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
|
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
|
||||||
"<span class='hlred'>" + offset0.substr(offset0.length - 1) + "</span>";
|
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
|
||||||
} else {
|
} else {
|
||||||
staticSection = offset0;
|
staticSection = offset0;
|
||||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
@@ -243,23 +243,23 @@ const Base64 = {
|
|||||||
|
|
||||||
|
|
||||||
// Highlight offset 1
|
// Highlight offset 1
|
||||||
padding = "<span class='hlred'>" + offset1.substr(0, 1) + "</span>" +
|
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset1.substr(1, 1) + "</span>";
|
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
|
||||||
offset1 = offset1.substr(2);
|
offset1 = offset1.substr(2);
|
||||||
if (len1 % 4 === 2) {
|
if (len1 % 4 === 2) {
|
||||||
staticSection = offset1.slice(0, -3);
|
staticSection = offset1.slice(0, -3);
|
||||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
|
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
|
||||||
staticSection + "</span>" +
|
staticSection + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
|
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
|
||||||
"<span class='hlred'>" + offset1.substr(offset1.length - 2) + "</span>";
|
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
|
||||||
} else if (len1 % 4 === 3) {
|
} else if (len1 % 4 === 3) {
|
||||||
staticSection = offset1.slice(0, -2);
|
staticSection = offset1.slice(0, -2);
|
||||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
|
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
|
||||||
staticSection + "</span>" +
|
staticSection + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
|
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
|
||||||
"<span class='hlred'>" + offset1.substr(offset1.length - 1) + "</span>";
|
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
|
||||||
} else {
|
} else {
|
||||||
staticSection = offset1;
|
staticSection = offset1;
|
||||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
@@ -272,23 +272,23 @@ const Base64 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Highlight offset 2
|
// Highlight offset 2
|
||||||
padding = "<span class='hlred'>" + offset2.substr(0, 2) + "</span>" +
|
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset2.substr(2, 1) + "</span>";
|
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
|
||||||
offset2 = offset2.substr(3);
|
offset2 = offset2.substr(3);
|
||||||
if (len2 % 4 === 2) {
|
if (len2 % 4 === 2) {
|
||||||
staticSection = offset2.slice(0, -3);
|
staticSection = offset2.slice(0, -3);
|
||||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||||
staticSection + "</span>" +
|
staticSection + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
|
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
|
||||||
"<span class='hlred'>" + offset2.substr(offset2.length - 2) + "</span>";
|
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
|
||||||
} else if (len2 % 4 === 3) {
|
} else if (len2 % 4 === 3) {
|
||||||
staticSection = offset2.slice(0, -2);
|
staticSection = offset2.slice(0, -2);
|
||||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||||
staticSection + "</span>" +
|
staticSection + "</span>" +
|
||||||
"<span class='hlgreen'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
|
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
|
||||||
"<span class='hlred'>" + offset2.substr(offset2.length - 1) + "</span>";
|
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
|
||||||
} else {
|
} else {
|
||||||
staticSection = offset2;
|
staticSection = offset2;
|
||||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||||
@@ -300,8 +300,8 @@ const Base64 = {
|
|||||||
offset2 = staticSection;
|
offset2 = staticSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (showVariable ? "Characters highlighted in <span class='hlgreen'>green</span> could change if the input is surrounded by more data." +
|
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
|
||||||
"\nCharacters highlighted in <span class='hlred'>red</span> are for padding purposes only." +
|
"\nCharacters highlighted in <span class='hl3'>red</span> are for padding purposes only." +
|
||||||
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
|
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
|
||||||
"\nHover over the static sections to see what they decode to on their own.\n" +
|
"\nHover over the static sections to see what they decode to on their own.\n" +
|
||||||
"\nOffset 0: " + offset0 +
|
"\nOffset 0: " + offset0 +
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ const BitwiseOp = {
|
|||||||
o = input[i];
|
o = input[i];
|
||||||
x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
|
x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
|
||||||
result.push(x);
|
result.push(x);
|
||||||
if (scheme !== "Standard" && !(nullPreserving && (o === 0 || o === k))) {
|
if (scheme &&
|
||||||
|
scheme !== "Standard" &&
|
||||||
|
!(nullPreserving && (o === 0 || o === k))) {
|
||||||
switch (scheme) {
|
switch (scheme) {
|
||||||
case "Input differential":
|
case "Input differential":
|
||||||
key[i % key.length] = x;
|
key[i % key.length] = x;
|
||||||
@@ -120,19 +122,19 @@ const BitwiseOp = {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
runXorBrute: function (input, args) {
|
runXorBrute: function (input, args) {
|
||||||
let keyLength = parseInt(args[0], 10),
|
const keyLength = parseInt(args[0], 10),
|
||||||
sampleLength = args[1],
|
sampleLength = args[1],
|
||||||
sampleOffset = args[2],
|
sampleOffset = args[2],
|
||||||
nullPreserving = args[3],
|
scheme = args[3],
|
||||||
differential = args[4],
|
nullPreserving = args[4],
|
||||||
crib = args[5],
|
printKey = args[5],
|
||||||
printKey = args[6],
|
outputHex = args[6],
|
||||||
outputHex = args[7],
|
crib = args[7];
|
||||||
regex;
|
|
||||||
|
|
||||||
let output = "",
|
let output = "",
|
||||||
result,
|
result,
|
||||||
resultUtf8;
|
resultUtf8,
|
||||||
|
regex;
|
||||||
|
|
||||||
input = input.slice(sampleOffset, sampleOffset + sampleLength);
|
input = input.slice(sampleOffset, sampleOffset + sampleLength);
|
||||||
|
|
||||||
@@ -142,14 +144,12 @@ const BitwiseOp = {
|
|||||||
|
|
||||||
|
|
||||||
for (let 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);
|
result = BitwiseOp._bitOp(input, Utils.fromHex(key.toString(16)), BitwiseOp._xor, nullPreserving, scheme);
|
||||||
resultUtf8 = Utils.byteArrayToUtf8(result);
|
resultUtf8 = Utils.byteArrayToUtf8(result);
|
||||||
if (crib !== "" && resultUtf8.search(regex) === -1) continue;
|
if (crib !== "" && resultUtf8.search(regex) === -1) continue;
|
||||||
if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
|
if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
|
||||||
if (outputHex)
|
if (outputHex) output += Utils.toHex(result) + "\n";
|
||||||
output += Utils.byteArrayToHex(result) + "\n";
|
else output += Utils.printable(resultUtf8, false) + "\n";
|
||||||
else
|
|
||||||
output += Utils.printable(resultUtf8, false) + "\n";
|
|
||||||
if (printKey) output += "\n";
|
if (printKey) output += "\n";
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const ByteRepr = {
|
|||||||
/**
|
/**
|
||||||
* To Octal operation.
|
* To Octal operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {byteArray} input
|
* @param {byteArray} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -72,7 +72,7 @@ const ByteRepr = {
|
|||||||
/**
|
/**
|
||||||
* From Octal operation.
|
* From Octal operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
@@ -108,8 +108,9 @@ const ByteRepr = {
|
|||||||
throw "Error: Base argument must be between 2 and 36";
|
throw "Error: Base argument must be between 2 and 36";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
const charcode = Utils.strToCharcode(input);
|
||||||
ordinal = Utils.ord(input[i]);
|
for (let i = 0; i < charcode.length; i++) {
|
||||||
|
ordinal = charcode[i];
|
||||||
|
|
||||||
if (base === 16) {
|
if (base === 16) {
|
||||||
if (ordinal < 256) padding = 2;
|
if (ordinal < 256) padding = 2;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import cptable from "../lib/js-codepage/cptable.js";
|
||||||
import Utils from "../Utils.js";
|
import Utils from "../Utils.js";
|
||||||
import CryptoJS from "crypto-js";
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
@@ -17,34 +18,82 @@ const CharEnc = {
|
|||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @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 {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
run: function(input, args) {
|
runEncode: function(input, args) {
|
||||||
let inputFormat = args[0],
|
const format = CharEnc.IO_FORMAT[args[0]];
|
||||||
outputFormat = args[1];
|
let encoded = cptable.utils.encode(format, input);
|
||||||
|
encoded = Array.from(encoded);
|
||||||
if (inputFormat === "Windows-1251") {
|
return encoded;
|
||||||
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);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
export default CharEnc;
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ const Cipher = {
|
|||||||
/**
|
/**
|
||||||
* Vigenère Encode operation.
|
* Vigenère Encode operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -454,7 +454,7 @@ const Cipher = {
|
|||||||
/**
|
/**
|
||||||
* Vigenère Decode operation.
|
* Vigenère Decode operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -508,7 +508,7 @@ const Cipher = {
|
|||||||
/**
|
/**
|
||||||
* Affine Cipher Encode operation.
|
* Affine Cipher Encode operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -540,9 +540,9 @@ const Cipher = {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affine Cipher Encode operation.
|
* Affine Cipher Decode operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -584,7 +584,7 @@ const Cipher = {
|
|||||||
/**
|
/**
|
||||||
* Atbash Cipher Encode operation.
|
* Atbash Cipher Encode operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -594,6 +594,159 @@ const Cipher = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a polybius square for the given keyword
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @param {string} keyword - Must be upper case
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
_genPolybiusSquare: function (keyword) {
|
||||||
|
const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
||||||
|
const polArray = `${keyword}${alpha}`.split("").unique();
|
||||||
|
let polybius = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
polybius[i] = polArray.slice(i*5, i*5 + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return polybius;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bifid Cipher Encode operation
|
||||||
|
*
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runBifidEnc: function (input, args) {
|
||||||
|
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
||||||
|
keyword = keywordStr.split("").unique(),
|
||||||
|
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
let output = "",
|
||||||
|
xCo = [],
|
||||||
|
yCo = [],
|
||||||
|
structure = [],
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
if (keyword.length > 25)
|
||||||
|
return "The alphabet keyword must be less than 25 characters.";
|
||||||
|
|
||||||
|
if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
|
||||||
|
return "The key must consist only of letters";
|
||||||
|
|
||||||
|
const polybius = Cipher._genPolybiusSquare(keywordStr);
|
||||||
|
|
||||||
|
input.replace("J", "I").split("").forEach(letter => {
|
||||||
|
let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0,
|
||||||
|
polInd;
|
||||||
|
|
||||||
|
if (alpInd) {
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
|
||||||
|
if (polInd >= 0) {
|
||||||
|
xCo.push(polInd);
|
||||||
|
yCo.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alpha.split("").indexOf(letter) >= 0) {
|
||||||
|
structure.push(true);
|
||||||
|
} else if (alpInd) {
|
||||||
|
structure.push(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
structure.push(letter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const trans = `${yCo.join("")}${xCo.join("")}`;
|
||||||
|
|
||||||
|
structure.forEach(pos => {
|
||||||
|
if (typeof pos === "boolean") {
|
||||||
|
let coords = trans.substr(2*count, 2).split("");
|
||||||
|
|
||||||
|
output += pos ?
|
||||||
|
polybius[coords[0]][coords[1]] :
|
||||||
|
polybius[coords[0]][coords[1]].toLocaleLowerCase();
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
output += pos;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bifid Cipher Decode operation
|
||||||
|
*
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runBifidDec: function (input, args) {
|
||||||
|
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
||||||
|
keyword = keywordStr.split("").unique(),
|
||||||
|
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
let output = "",
|
||||||
|
structure = [],
|
||||||
|
count = 0,
|
||||||
|
trans = "";
|
||||||
|
|
||||||
|
if (keyword.length > 25)
|
||||||
|
return "The alphabet keyword must be less than 25 characters.";
|
||||||
|
|
||||||
|
if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
|
||||||
|
return "The key must consist only of letters";
|
||||||
|
|
||||||
|
const polybius = Cipher._genPolybiusSquare(keywordStr);
|
||||||
|
|
||||||
|
input.replace("J", "I").split("").forEach((letter) => {
|
||||||
|
let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0,
|
||||||
|
polInd;
|
||||||
|
|
||||||
|
if (alpInd) {
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
|
||||||
|
if (polInd >= 0) {
|
||||||
|
trans += `${i}${polInd}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alpha.split("").indexOf(letter) >= 0) {
|
||||||
|
structure.push(true);
|
||||||
|
} else if (alpInd) {
|
||||||
|
structure.push(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
structure.push(letter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
structure.forEach(pos => {
|
||||||
|
if (typeof pos === "boolean") {
|
||||||
|
let coords = [trans[count], trans[count+trans.length/2]];
|
||||||
|
|
||||||
|
output += pos ?
|
||||||
|
polybius[coords[0]][coords[1]] :
|
||||||
|
polybius[coords[0]][coords[1]].toLocaleLowerCase();
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
output += pos;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
@@ -608,23 +761,23 @@ const Cipher = {
|
|||||||
/**
|
/**
|
||||||
* Substitute operation.
|
* Substitute operation.
|
||||||
*
|
*
|
||||||
* @param {byteArray} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {byteArray}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
runSubstitute: function (input, args) {
|
runSubstitute: function (input, args) {
|
||||||
let plaintext = Utils.strToByteArray(Utils.expandAlphRange(args[0]).join()),
|
let plaintext = Utils.expandAlphRange(args[0]).join(),
|
||||||
ciphertext = Utils.strToByteArray(Utils.expandAlphRange(args[1]).join()),
|
ciphertext = Utils.expandAlphRange(args[1]).join(),
|
||||||
output = [],
|
output = "",
|
||||||
index = -1;
|
index = -1;
|
||||||
|
|
||||||
if (plaintext.length !== ciphertext.length) {
|
if (plaintext.length !== ciphertext.length) {
|
||||||
output = Utils.strToByteArray("Warning: Plaintext and Ciphertext lengths differ\n\n");
|
output = "Warning: Plaintext and Ciphertext lengths differ\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
for (let i = 0; i < input.length; i++) {
|
||||||
index = plaintext.indexOf(input[i]);
|
index = plaintext.indexOf(input[i]);
|
||||||
output.push(index > -1 && index < ciphertext.length ? ciphertext[index] : input[i]);
|
output += index > -1 && index < ciphertext.length ? ciphertext[index] : input[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@@ -228,19 +228,19 @@ const Code = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code = code
|
code = code
|
||||||
// Create newlines after ;
|
// Create newlines after ;
|
||||||
.replace(/;/g, ";\n")
|
.replace(/;/g, ";\n")
|
||||||
// Create newlines after { and around }
|
// Create newlines after { and around }
|
||||||
.replace(/{/g, "{\n")
|
.replace(/{/g, "{\n")
|
||||||
.replace(/}/g, "\n}\n")
|
.replace(/}/g, "\n}\n")
|
||||||
// Remove carriage returns
|
// Remove carriage returns
|
||||||
.replace(/\r/g, "")
|
.replace(/\r/g, "")
|
||||||
// Remove all indentation
|
// Remove all indentation
|
||||||
.replace(/^\s+/g, "")
|
.replace(/^\s+/g, "")
|
||||||
.replace(/\n\s+/g, "\n")
|
.replace(/\n\s+/g, "\n")
|
||||||
// Remove trailing spaces
|
// Remove trailing spaces
|
||||||
.replace(/\s*$/g, "")
|
.replace(/\s*$/g, "")
|
||||||
.replace(/\n{/g, "{");
|
.replace(/\n{/g, "{");
|
||||||
|
|
||||||
// Indent
|
// Indent
|
||||||
let i = 0,
|
let i = 0,
|
||||||
@@ -265,27 +265,27 @@ const Code = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code = code
|
code = code
|
||||||
// Add strategic spaces
|
// Add strategic spaces
|
||||||
.replace(/\s*([!<>=+-/*]?)=\s*/g, " $1= ")
|
.replace(/\s*([!<>=+-/*]?)=\s*/g, " $1= ")
|
||||||
.replace(/\s*<([=]?)\s*/g, " <$1 ")
|
.replace(/\s*<([=]?)\s*/g, " <$1 ")
|
||||||
.replace(/\s*>([=]?)\s*/g, " >$1 ")
|
.replace(/\s*>([=]?)\s*/g, " >$1 ")
|
||||||
.replace(/([^+])\+([^+=])/g, "$1 + $2")
|
.replace(/([^+])\+([^+=])/g, "$1 + $2")
|
||||||
.replace(/([^-])-([^-=])/g, "$1 - $2")
|
.replace(/([^-])-([^-=])/g, "$1 - $2")
|
||||||
.replace(/([^*])\*([^*=])/g, "$1 * $2")
|
.replace(/([^*])\*([^*=])/g, "$1 * $2")
|
||||||
.replace(/([^/])\/([^/=])/g, "$1 / $2")
|
.replace(/([^/])\/([^/=])/g, "$1 / $2")
|
||||||
.replace(/\s*,\s*/g, ", ")
|
.replace(/\s*,\s*/g, ", ")
|
||||||
.replace(/\s*{/g, " {")
|
.replace(/\s*{/g, " {")
|
||||||
.replace(/}\n/g, "}\n\n")
|
.replace(/}\n/g, "}\n\n")
|
||||||
// Hacky horribleness
|
// Hacky horribleness
|
||||||
.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)\s*\n([^{])/gim, "$1 ($2)\n $3")
|
.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)\s*\n([^{])/gim, "$1 ($2)\n $3")
|
||||||
.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)([^{])/gim, "$1 ($2) $3")
|
.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)([^{])/gim, "$1 ($2) $3")
|
||||||
.replace(/else\s*\n([^{])/gim, "else\n $1")
|
.replace(/else\s*\n([^{])/gim, "else\n $1")
|
||||||
.replace(/else\s+([^{])/gim, "else $1")
|
.replace(/else\s+([^{])/gim, "else $1")
|
||||||
// Remove strategic spaces
|
// Remove strategic spaces
|
||||||
.replace(/\s+;/g, ";")
|
.replace(/\s+;/g, ";")
|
||||||
.replace(/\{\s+\}/g, "{}")
|
.replace(/\{\s+\}/g, "{}")
|
||||||
.replace(/\[\s+\]/g, "[]")
|
.replace(/\[\s+\]/g, "[]")
|
||||||
.replace(/}\s*(else|catch|except|finally|elif|elseif|else if)/gi, "} $1");
|
.replace(/}\s*(else|catch|except|finally|elif|elseif|else if)/gi, "} $1");
|
||||||
|
|
||||||
// Replace preserved tokens
|
// Replace preserved tokens
|
||||||
const ptokens = /###preservedToken(\d+)###/g;
|
const ptokens = /###preservedToken(\d+)###/g;
|
||||||
@@ -329,7 +329,7 @@ const Code = {
|
|||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
runXpath:function(input, args) {
|
runXpath: function(input, args) {
|
||||||
let query = args[0],
|
let query = args[0],
|
||||||
delimiter = args[1];
|
delimiter = args[1];
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import bzip2 from "exports-loader?bzip2!../lib/bzip2.js";
|
|||||||
const Zlib = {
|
const Zlib = {
|
||||||
RawDeflate: rawdeflate.Zlib.RawDeflate,
|
RawDeflate: rawdeflate.Zlib.RawDeflate,
|
||||||
RawInflate: rawinflate.Zlib.RawInflate,
|
RawInflate: rawinflate.Zlib.RawInflate,
|
||||||
Deflate: zlibAndGzip.Zlib.Deflate,
|
Deflate: zlibAndGzip.Zlib.Deflate,
|
||||||
Inflate: zlibAndGzip.Zlib.Inflate,
|
Inflate: zlibAndGzip.Zlib.Inflate,
|
||||||
Gzip: zlibAndGzip.Zlib.Gzip,
|
Gzip: zlibAndGzip.Zlib.Gzip,
|
||||||
Gunzip: zlibAndGzip.Zlib.Gunzip,
|
Gunzip: zlibAndGzip.Zlib.Gunzip,
|
||||||
Zip: zip.Zlib.Zip,
|
Zip: zip.Zlib.Zip,
|
||||||
Unzip: unzip.Zlib.Unzip,
|
Unzip: unzip.Zlib.Unzip,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -54,9 +54,9 @@ const Compress = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
RAW_COMPRESSION_TYPE_LOOKUP: {
|
RAW_COMPRESSION_TYPE_LOOKUP: {
|
||||||
"Fixed Huffman Coding" : Zlib.RawDeflate.CompressionType.FIXED,
|
"Fixed Huffman Coding": Zlib.RawDeflate.CompressionType.FIXED,
|
||||||
"Dynamic Huffman Coding" : Zlib.RawDeflate.CompressionType.DYNAMIC,
|
"Dynamic Huffman Coding": Zlib.RawDeflate.CompressionType.DYNAMIC,
|
||||||
"None (Store)" : Zlib.RawDeflate.CompressionType.NONE,
|
"None (Store)": Zlib.RawDeflate.CompressionType.NONE,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,8 +99,8 @@ const Compress = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
RAW_BUFFER_TYPE_LOOKUP: {
|
RAW_BUFFER_TYPE_LOOKUP: {
|
||||||
"Adaptive" : Zlib.RawInflate.BufferType.ADAPTIVE,
|
"Adaptive": Zlib.RawInflate.BufferType.ADAPTIVE,
|
||||||
"Block" : Zlib.RawInflate.BufferType.BLOCK,
|
"Block": Zlib.RawInflate.BufferType.BLOCK,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,9 +150,9 @@ const Compress = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
ZLIB_COMPRESSION_TYPE_LOOKUP: {
|
ZLIB_COMPRESSION_TYPE_LOOKUP: {
|
||||||
"Fixed Huffman Coding" : Zlib.Deflate.CompressionType.FIXED,
|
"Fixed Huffman Coding": Zlib.Deflate.CompressionType.FIXED,
|
||||||
"Dynamic Huffman Coding" : Zlib.Deflate.CompressionType.DYNAMIC,
|
"Dynamic Huffman Coding": Zlib.Deflate.CompressionType.DYNAMIC,
|
||||||
"None (Store)" : Zlib.Deflate.CompressionType.NONE,
|
"None (Store)": Zlib.Deflate.CompressionType.NONE,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,8 +175,8 @@ const Compress = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
ZLIB_BUFFER_TYPE_LOOKUP: {
|
ZLIB_BUFFER_TYPE_LOOKUP: {
|
||||||
"Adaptive" : Zlib.Inflate.BufferType.ADAPTIVE,
|
"Adaptive": Zlib.Inflate.BufferType.ADAPTIVE,
|
||||||
"Block" : Zlib.Inflate.BufferType.BLOCK,
|
"Block": Zlib.Inflate.BufferType.BLOCK,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -264,17 +264,17 @@ const Compress = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
ZIP_COMPRESSION_METHOD_LOOKUP: {
|
ZIP_COMPRESSION_METHOD_LOOKUP: {
|
||||||
"Deflate" : Zlib.Zip.CompressionMethod.DEFLATE,
|
"Deflate": Zlib.Zip.CompressionMethod.DEFLATE,
|
||||||
"None (Store)" : Zlib.Zip.CompressionMethod.STORE
|
"None (Store)": Zlib.Zip.CompressionMethod.STORE
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
ZIP_OS_LOOKUP: {
|
ZIP_OS_LOOKUP: {
|
||||||
"MSDOS" : Zlib.Zip.OperatingSystem.MSDOS,
|
"MSDOS": Zlib.Zip.OperatingSystem.MSDOS,
|
||||||
"Unix" : Zlib.Zip.OperatingSystem.UNIX,
|
"Unix": Zlib.Zip.OperatingSystem.UNIX,
|
||||||
"Macintosh" : Zlib.Zip.OperatingSystem.MACINTOSH
|
"Macintosh": Zlib.Zip.OperatingSystem.MACINTOSH
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,36 +25,36 @@ const Convert = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
DISTANCE_FACTOR: { // Multiples of a metre
|
DISTANCE_FACTOR: { // Multiples of a metre
|
||||||
"Nanometres (nm)" : 1e-9,
|
"Nanometres (nm)": 1e-9,
|
||||||
"Micrometres (µm)" : 1e-6,
|
"Micrometres (µm)": 1e-6,
|
||||||
"Millimetres (mm)" : 1e-3,
|
"Millimetres (mm)": 1e-3,
|
||||||
"Centimetres (cm)" : 1e-2,
|
"Centimetres (cm)": 1e-2,
|
||||||
"Metres (m)" : 1,
|
"Metres (m)": 1,
|
||||||
"Kilometers (km)" : 1e3,
|
"Kilometers (km)": 1e3,
|
||||||
|
|
||||||
"Thou (th)" : 0.0000254,
|
"Thou (th)": 0.0000254,
|
||||||
"Inches (in)" : 0.0254,
|
"Inches (in)": 0.0254,
|
||||||
"Feet (ft)" : 0.3048,
|
"Feet (ft)": 0.3048,
|
||||||
"Yards (yd)" : 0.9144,
|
"Yards (yd)": 0.9144,
|
||||||
"Chains (ch)" : 20.1168,
|
"Chains (ch)": 20.1168,
|
||||||
"Furlongs (fur)" : 201.168,
|
"Furlongs (fur)": 201.168,
|
||||||
"Miles (mi)" : 1609.344,
|
"Miles (mi)": 1609.344,
|
||||||
"Leagues (lea)" : 4828.032,
|
"Leagues (lea)": 4828.032,
|
||||||
|
|
||||||
"Fathoms (ftm)" : 1.853184,
|
"Fathoms (ftm)": 1.853184,
|
||||||
"Cables" : 185.3184,
|
"Cables": 185.3184,
|
||||||
"Nautical miles" : 1853.184,
|
"Nautical miles": 1853.184,
|
||||||
|
|
||||||
"Cars (4m)" : 4,
|
"Cars (4m)": 4,
|
||||||
"Buses (8.4m)" : 8.4,
|
"Buses (8.4m)": 8.4,
|
||||||
"American football fields (91m)": 91,
|
"American football fields (91m)": 91,
|
||||||
"Football pitches (105m)": 105,
|
"Football pitches (105m)": 105,
|
||||||
|
|
||||||
"Earth-to-Moons" : 380000000,
|
"Earth-to-Moons": 380000000,
|
||||||
"Earth's equators" : 40075016.686,
|
"Earth's equators": 40075016.686,
|
||||||
"Astronomical units (au)": 149597870700,
|
"Astronomical units (au)": 149597870700,
|
||||||
"Light-years (ly)" : 9460730472580800,
|
"Light-years (ly)": 9460730472580800,
|
||||||
"Parsecs (pc)" : 3.0856776e16
|
"Parsecs (pc)": 3.0856776e16
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,52 +90,52 @@ const Convert = {
|
|||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
DATA_FACTOR: { // Multiples of a bit
|
DATA_FACTOR: { // Multiples of a bit
|
||||||
"Bits (b)" : 1,
|
"Bits (b)": 1,
|
||||||
"Nibbles" : 4,
|
"Nibbles": 4,
|
||||||
"Octets" : 8,
|
"Octets": 8,
|
||||||
"Bytes (B)" : 8,
|
"Bytes (B)": 8,
|
||||||
|
|
||||||
// Binary bits (2^n)
|
// Binary bits (2^n)
|
||||||
"Kibibits (Kib)" : 1024,
|
"Kibibits (Kib)": 1024,
|
||||||
"Mebibits (Mib)" : 1048576,
|
"Mebibits (Mib)": 1048576,
|
||||||
"Gibibits (Gib)" : 1073741824,
|
"Gibibits (Gib)": 1073741824,
|
||||||
"Tebibits (Tib)" : 1099511627776,
|
"Tebibits (Tib)": 1099511627776,
|
||||||
"Pebibits (Pib)" : 1125899906842624,
|
"Pebibits (Pib)": 1125899906842624,
|
||||||
"Exbibits (Eib)" : 1152921504606846976,
|
"Exbibits (Eib)": 1152921504606846976,
|
||||||
"Zebibits (Zib)" : 1180591620717411303424,
|
"Zebibits (Zib)": 1180591620717411303424,
|
||||||
"Yobibits (Yib)" : 1208925819614629174706176,
|
"Yobibits (Yib)": 1208925819614629174706176,
|
||||||
|
|
||||||
// Decimal bits (10^n)
|
// Decimal bits (10^n)
|
||||||
"Decabits" : 10,
|
"Decabits": 10,
|
||||||
"Hectobits" : 100,
|
"Hectobits": 100,
|
||||||
"Kilobits (Kb)" : 1e3,
|
"Kilobits (Kb)": 1e3,
|
||||||
"Megabits (Mb)" : 1e6,
|
"Megabits (Mb)": 1e6,
|
||||||
"Gigabits (Gb)" : 1e9,
|
"Gigabits (Gb)": 1e9,
|
||||||
"Terabits (Tb)" : 1e12,
|
"Terabits (Tb)": 1e12,
|
||||||
"Petabits (Pb)" : 1e15,
|
"Petabits (Pb)": 1e15,
|
||||||
"Exabits (Eb)" : 1e18,
|
"Exabits (Eb)": 1e18,
|
||||||
"Zettabits (Zb)" : 1e21,
|
"Zettabits (Zb)": 1e21,
|
||||||
"Yottabits (Yb)" : 1e24,
|
"Yottabits (Yb)": 1e24,
|
||||||
|
|
||||||
// Binary bytes (8 x 2^n)
|
// Binary bytes (8 x 2^n)
|
||||||
"Kibibytes (KiB)" : 8192,
|
"Kibibytes (KiB)": 8192,
|
||||||
"Mebibytes (MiB)" : 8388608,
|
"Mebibytes (MiB)": 8388608,
|
||||||
"Gibibytes (GiB)" : 8589934592,
|
"Gibibytes (GiB)": 8589934592,
|
||||||
"Tebibytes (TiB)" : 8796093022208,
|
"Tebibytes (TiB)": 8796093022208,
|
||||||
"Pebibytes (PiB)" : 9007199254740992,
|
"Pebibytes (PiB)": 9007199254740992,
|
||||||
"Exbibytes (EiB)" : 9223372036854775808,
|
"Exbibytes (EiB)": 9223372036854775808,
|
||||||
"Zebibytes (ZiB)" : 9444732965739290427392,
|
"Zebibytes (ZiB)": 9444732965739290427392,
|
||||||
"Yobibytes (YiB)" : 9671406556917033397649408,
|
"Yobibytes (YiB)": 9671406556917033397649408,
|
||||||
|
|
||||||
// Decimal bytes (8 x 10^n)
|
// Decimal bytes (8 x 10^n)
|
||||||
"Kilobytes (KB)" : 8e3,
|
"Kilobytes (KB)": 8e3,
|
||||||
"Megabytes (MB)" : 8e6,
|
"Megabytes (MB)": 8e6,
|
||||||
"Gigabytes (GB)" : 8e9,
|
"Gigabytes (GB)": 8e9,
|
||||||
"Terabytes (TB)" : 8e12,
|
"Terabytes (TB)": 8e12,
|
||||||
"Petabytes (PB)" : 8e15,
|
"Petabytes (PB)": 8e15,
|
||||||
"Exabytes (EB)" : 8e18,
|
"Exabytes (EB)": 8e18,
|
||||||
"Zettabytes (ZB)" : 8e21,
|
"Zettabytes (ZB)": 8e21,
|
||||||
"Yottabytes (YB)" : 8e24,
|
"Yottabytes (YB)": 8e24,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -171,51 +171,51 @@ const Convert = {
|
|||||||
*/
|
*/
|
||||||
AREA_FACTOR: { // Multiples of a square metre
|
AREA_FACTOR: { // Multiples of a square metre
|
||||||
// Metric
|
// Metric
|
||||||
"Square metre (sq m)" : 1,
|
"Square metre (sq m)": 1,
|
||||||
"Square kilometre (sq km)" : 1e6,
|
"Square kilometre (sq km)": 1e6,
|
||||||
|
|
||||||
"Centiare (ca)" : 1,
|
"Centiare (ca)": 1,
|
||||||
"Deciare (da)" : 10,
|
"Deciare (da)": 10,
|
||||||
"Are (a)" : 100,
|
"Are (a)": 100,
|
||||||
"Decare (daa)" : 1e3,
|
"Decare (daa)": 1e3,
|
||||||
"Hectare (ha)" : 1e4,
|
"Hectare (ha)": 1e4,
|
||||||
|
|
||||||
// Imperial
|
// Imperial
|
||||||
"Square inch (sq in)" : 0.00064516,
|
"Square inch (sq in)": 0.00064516,
|
||||||
"Square foot (sq ft)" : 0.09290304,
|
"Square foot (sq ft)": 0.09290304,
|
||||||
"Square yard (sq yd)" : 0.83612736,
|
"Square yard (sq yd)": 0.83612736,
|
||||||
"Square mile (sq mi)" : 2589988.110336,
|
"Square mile (sq mi)": 2589988.110336,
|
||||||
"Perch (sq per)" : 42.21,
|
"Perch (sq per)": 42.21,
|
||||||
"Rood (ro)" : 1011,
|
"Rood (ro)": 1011,
|
||||||
"International acre (ac)" : 4046.8564224,
|
"International acre (ac)": 4046.8564224,
|
||||||
|
|
||||||
// US customary units
|
// US customary units
|
||||||
"US survey acre (ac)" : 4046.87261,
|
"US survey acre (ac)": 4046.87261,
|
||||||
"US survey square mile (sq mi)" : 2589998.470305239,
|
"US survey square mile (sq mi)": 2589998.470305239,
|
||||||
"US survey township" : 93239944.9309886,
|
"US survey township": 93239944.9309886,
|
||||||
|
|
||||||
// Nuclear physics
|
// Nuclear physics
|
||||||
"Yoctobarn (yb)" : 1e-52,
|
"Yoctobarn (yb)": 1e-52,
|
||||||
"Zeptobarn (zb)" : 1e-49,
|
"Zeptobarn (zb)": 1e-49,
|
||||||
"Attobarn (ab)" : 1e-46,
|
"Attobarn (ab)": 1e-46,
|
||||||
"Femtobarn (fb)" : 1e-43,
|
"Femtobarn (fb)": 1e-43,
|
||||||
"Picobarn (pb)" : 1e-40,
|
"Picobarn (pb)": 1e-40,
|
||||||
"Nanobarn (nb)" : 1e-37,
|
"Nanobarn (nb)": 1e-37,
|
||||||
"Microbarn (μb)" : 1e-34,
|
"Microbarn (μb)": 1e-34,
|
||||||
"Millibarn (mb)" : 1e-31,
|
"Millibarn (mb)": 1e-31,
|
||||||
"Barn (b)" : 1e-28,
|
"Barn (b)": 1e-28,
|
||||||
"Kilobarn (kb)" : 1e-25,
|
"Kilobarn (kb)": 1e-25,
|
||||||
"Megabarn (Mb)" : 1e-22,
|
"Megabarn (Mb)": 1e-22,
|
||||||
|
|
||||||
"Planck area" : 2.6e-70,
|
"Planck area": 2.6e-70,
|
||||||
"Shed" : 1e-52,
|
"Shed": 1e-52,
|
||||||
"Outhouse" : 1e-34,
|
"Outhouse": 1e-34,
|
||||||
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
"Washington D.C." : 176119191.502848,
|
"Washington D.C.": 176119191.502848,
|
||||||
"Isle of Wight" : 380000000,
|
"Isle of Wight": 380000000,
|
||||||
"Wales" : 20779000000,
|
"Wales": 20779000000,
|
||||||
"Texas" : 696241000000,
|
"Texas": 696241000000,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -252,81 +252,81 @@ const Convert = {
|
|||||||
*/
|
*/
|
||||||
MASS_FACTOR: { // Multiples of a gram
|
MASS_FACTOR: { // Multiples of a gram
|
||||||
// Metric
|
// Metric
|
||||||
"Yoctogram (yg)" : 1e-24,
|
"Yoctogram (yg)": 1e-24,
|
||||||
"Zeptogram (zg)" : 1e-21,
|
"Zeptogram (zg)": 1e-21,
|
||||||
"Attogram (ag)" : 1e-18,
|
"Attogram (ag)": 1e-18,
|
||||||
"Femtogram (fg)" : 1e-15,
|
"Femtogram (fg)": 1e-15,
|
||||||
"Picogram (pg)" : 1e-12,
|
"Picogram (pg)": 1e-12,
|
||||||
"Nanogram (ng)" : 1e-9,
|
"Nanogram (ng)": 1e-9,
|
||||||
"Microgram (μg)" : 1e-6,
|
"Microgram (μg)": 1e-6,
|
||||||
"Milligram (mg)" : 1e-3,
|
"Milligram (mg)": 1e-3,
|
||||||
"Centigram (cg)" : 1e-2,
|
"Centigram (cg)": 1e-2,
|
||||||
"Decigram (dg)" : 1e-1,
|
"Decigram (dg)": 1e-1,
|
||||||
"Gram (g)" : 1,
|
"Gram (g)": 1,
|
||||||
"Decagram (dag)" : 10,
|
"Decagram (dag)": 10,
|
||||||
"Hectogram (hg)" : 100,
|
"Hectogram (hg)": 100,
|
||||||
"Kilogram (kg)" : 1000,
|
"Kilogram (kg)": 1000,
|
||||||
"Megagram (Mg)" : 1e6,
|
"Megagram (Mg)": 1e6,
|
||||||
"Tonne (t)" : 1e6,
|
"Tonne (t)": 1e6,
|
||||||
"Gigagram (Gg)" : 1e9,
|
"Gigagram (Gg)": 1e9,
|
||||||
"Teragram (Tg)" : 1e12,
|
"Teragram (Tg)": 1e12,
|
||||||
"Petagram (Pg)" : 1e15,
|
"Petagram (Pg)": 1e15,
|
||||||
"Exagram (Eg)" : 1e18,
|
"Exagram (Eg)": 1e18,
|
||||||
"Zettagram (Zg)" : 1e21,
|
"Zettagram (Zg)": 1e21,
|
||||||
"Yottagram (Yg)" : 1e24,
|
"Yottagram (Yg)": 1e24,
|
||||||
|
|
||||||
// Imperial Avoirdupois
|
// Imperial Avoirdupois
|
||||||
"Grain (gr)" : 64.79891e-3,
|
"Grain (gr)": 64.79891e-3,
|
||||||
"Dram (dr)" : 1.7718451953125,
|
"Dram (dr)": 1.7718451953125,
|
||||||
"Ounce (oz)" : 28.349523125,
|
"Ounce (oz)": 28.349523125,
|
||||||
"Pound (lb)" : 453.59237,
|
"Pound (lb)": 453.59237,
|
||||||
"Nail" : 3175.14659,
|
"Nail": 3175.14659,
|
||||||
"Stone (st)" : 6.35029318e3,
|
"Stone (st)": 6.35029318e3,
|
||||||
"Quarter (gr)" : 12700.58636,
|
"Quarter (gr)": 12700.58636,
|
||||||
"Tod" : 12700.58636,
|
"Tod": 12700.58636,
|
||||||
"US hundredweight (cwt)" : 45.359237e3,
|
"US hundredweight (cwt)": 45.359237e3,
|
||||||
"Imperial hundredweight (cwt)" : 50.80234544e3,
|
"Imperial hundredweight (cwt)": 50.80234544e3,
|
||||||
"US ton (t)" : 907.18474e3,
|
"US ton (t)": 907.18474e3,
|
||||||
"Imperial ton (t)" : 1016.0469088e3,
|
"Imperial ton (t)": 1016.0469088e3,
|
||||||
|
|
||||||
// Imperial Troy
|
// Imperial Troy
|
||||||
"Pennyweight (dwt)" : 1.55517384,
|
"Pennyweight (dwt)": 1.55517384,
|
||||||
"Troy dram (dr t)" : 3.8879346,
|
"Troy dram (dr t)": 3.8879346,
|
||||||
"Troy ounce (oz t)" : 31.1034768,
|
"Troy ounce (oz t)": 31.1034768,
|
||||||
"Troy pound (lb t)" : 373.2417216,
|
"Troy pound (lb t)": 373.2417216,
|
||||||
"Mark" : 248.8278144,
|
"Mark": 248.8278144,
|
||||||
|
|
||||||
// Archaic
|
// Archaic
|
||||||
"Wey" : 76.5e3,
|
"Wey": 76.5e3,
|
||||||
"Wool wey" : 101.7e3,
|
"Wool wey": 101.7e3,
|
||||||
"Suffolk wey" : 161.5e3,
|
"Suffolk wey": 161.5e3,
|
||||||
"Wool sack" : 153000,
|
"Wool sack": 153000,
|
||||||
"Coal sack" : 50.80234544e3,
|
"Coal sack": 50.80234544e3,
|
||||||
"Load" : 918000,
|
"Load": 918000,
|
||||||
"Last" : 1836000,
|
"Last": 1836000,
|
||||||
"Flax or feather last" : 770e3,
|
"Flax or feather last": 770e3,
|
||||||
"Gunpowder last" : 1090e3,
|
"Gunpowder last": 1090e3,
|
||||||
"Picul" : 60.478982e3,
|
"Picul": 60.478982e3,
|
||||||
"Rice last" : 1200e3,
|
"Rice last": 1200e3,
|
||||||
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
"Big Ben (14 tonnes)" : 14e6,
|
"Big Ben (14 tonnes)": 14e6,
|
||||||
"Blue whale (180 tonnes)" : 180e6,
|
"Blue whale (180 tonnes)": 180e6,
|
||||||
"International Space Station (417 tonnes)" : 417e6,
|
"International Space Station (417 tonnes)": 417e6,
|
||||||
"Space Shuttle (2,041 tonnes)" : 2041e6,
|
"Space Shuttle (2,041 tonnes)": 2041e6,
|
||||||
"RMS Titanic (52,000 tonnes)" : 52000e6,
|
"RMS Titanic (52,000 tonnes)": 52000e6,
|
||||||
"Great Pyramid of Giza (6,000,000 tonnes)" : 6e12,
|
"Great Pyramid of Giza (6,000,000 tonnes)": 6e12,
|
||||||
"Earth's oceans (1.4 yottagrams)" : 1.4e24,
|
"Earth's oceans (1.4 yottagrams)": 1.4e24,
|
||||||
|
|
||||||
// Astronomical
|
// Astronomical
|
||||||
"A teaspoon of neutron star (5,500 million tonnes)" : 5.5e15,
|
"A teaspoon of neutron star (5,500 million tonnes)": 5.5e15,
|
||||||
"Lunar mass (ML)" : 7.342e25,
|
"Lunar mass (ML)": 7.342e25,
|
||||||
"Earth mass (M⊕)" : 5.97219e27,
|
"Earth mass (M⊕)": 5.97219e27,
|
||||||
"Jupiter mass (MJ)" : 1.8981411476999997e30,
|
"Jupiter mass (MJ)": 1.8981411476999997e30,
|
||||||
"Solar mass (M☉)" : 1.98855e33,
|
"Solar mass (M☉)": 1.98855e33,
|
||||||
"Sagittarius A* (7.5 x 10^36 kgs-ish)" : 7.5e39,
|
"Sagittarius A* (7.5 x 10^36 kgs-ish)": 7.5e39,
|
||||||
"Milky Way galaxy (1.2 x 10^42 kgs)" : 1.2e45,
|
"Milky Way galaxy (1.2 x 10^42 kgs)": 1.2e45,
|
||||||
"The observable universe (1.45 x 10^53 kgs)" : 1.45e56,
|
"The observable universe (1.45 x 10^53 kgs)": 1.45e56,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -361,37 +361,37 @@ const Convert = {
|
|||||||
*/
|
*/
|
||||||
SPEED_FACTOR: { // Multiples of m/s
|
SPEED_FACTOR: { // Multiples of m/s
|
||||||
// Metric
|
// Metric
|
||||||
"Metres per second (m/s)" : 1,
|
"Metres per second (m/s)": 1,
|
||||||
"Kilometres per hour (km/h)" : 0.2778,
|
"Kilometres per hour (km/h)": 0.2778,
|
||||||
|
|
||||||
// Imperial
|
// Imperial
|
||||||
"Miles per hour (mph)" : 0.44704,
|
"Miles per hour (mph)": 0.44704,
|
||||||
"Knots (kn)" : 0.5144,
|
"Knots (kn)": 0.5144,
|
||||||
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
"Human hair growth rate" : 4.8e-9,
|
"Human hair growth rate": 4.8e-9,
|
||||||
"Bamboo growth rate" : 1.4e-5,
|
"Bamboo growth rate": 1.4e-5,
|
||||||
"World's fastest snail" : 0.00275,
|
"World's fastest snail": 0.00275,
|
||||||
"Usain Bolt's top speed" : 12.42,
|
"Usain Bolt's top speed": 12.42,
|
||||||
"Jet airliner cruising speed" : 250,
|
"Jet airliner cruising speed": 250,
|
||||||
"Concorde" : 603,
|
"Concorde": 603,
|
||||||
"SR-71 Blackbird" : 981,
|
"SR-71 Blackbird": 981,
|
||||||
"Space Shuttle" : 1400,
|
"Space Shuttle": 1400,
|
||||||
"International Space Station" : 7700,
|
"International Space Station": 7700,
|
||||||
|
|
||||||
// Scientific
|
// Scientific
|
||||||
"Sound in standard atmosphere" : 340.3,
|
"Sound in standard atmosphere": 340.3,
|
||||||
"Sound in water" : 1500,
|
"Sound in water": 1500,
|
||||||
"Lunar escape velocity" : 2375,
|
"Lunar escape velocity": 2375,
|
||||||
"Earth escape velocity" : 11200,
|
"Earth escape velocity": 11200,
|
||||||
"Earth's solar orbit" : 29800,
|
"Earth's solar orbit": 29800,
|
||||||
"Solar system's Milky Way orbit" : 200000,
|
"Solar system's Milky Way orbit": 200000,
|
||||||
"Milky Way relative to the cosmic microwave background" : 552000,
|
"Milky Way relative to the cosmic microwave background": 552000,
|
||||||
"Solar escape velocity" : 617700,
|
"Solar escape velocity": 617700,
|
||||||
"Neutron star escape velocity (0.3c)" : 100000000,
|
"Neutron star escape velocity (0.3c)": 100000000,
|
||||||
"Light in a diamond (0.4136c)" : 124000000,
|
"Light in a diamond (0.4136c)": 124000000,
|
||||||
"Signal in an optical fibre (0.667c)" : 200000000,
|
"Signal in an optical fibre (0.667c)": 200000000,
|
||||||
"Light (c)" : 299792458,
|
"Light (c)": 299792458,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import {BigInteger} from "jsbn";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date and time operations.
|
* Date and time operations.
|
||||||
*
|
*
|
||||||
@@ -78,6 +80,85 @@ const DateTime = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows Filetime to Unix Timestamp operation.
|
||||||
|
*
|
||||||
|
* @author bwhitn [brian.m.whitney@outlook.com]
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runFromFiletimeToUnix: function(input, args) {
|
||||||
|
let units = args[0],
|
||||||
|
format = args[1];
|
||||||
|
|
||||||
|
if (format === "Hex") {
|
||||||
|
input = new BigInteger(input, 16);
|
||||||
|
} else {
|
||||||
|
input = new BigInteger(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
input = input.subtract(new BigInteger("116444736000000000"));
|
||||||
|
|
||||||
|
if (units === "Seconds (s)"){
|
||||||
|
input = input.divide(new BigInteger("10000000"));
|
||||||
|
} else if (units === "Milliseconds (ms)") {
|
||||||
|
input = input.divide(new BigInteger("10000"));
|
||||||
|
} else if (units === "Microseconds (μs)") {
|
||||||
|
input = input.divide(new BigInteger("10"));
|
||||||
|
} else if (units === "Nanoseconds (ns)") {
|
||||||
|
input = input.multiply(new BigInteger("100"));
|
||||||
|
} else {
|
||||||
|
throw "Unrecognised unit";
|
||||||
|
}
|
||||||
|
|
||||||
|
return input.toString();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unix Timestamp to Windows Filetime operation.
|
||||||
|
*
|
||||||
|
* @author bwhitn [brian.m.whitney@outlook.com]
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runToFiletimeFromUnix: function(input, args) {
|
||||||
|
let units = args[0],
|
||||||
|
format = args[1];
|
||||||
|
|
||||||
|
input = new BigInteger(input);
|
||||||
|
|
||||||
|
if (units === "Seconds (s)"){
|
||||||
|
input = input.multiply(new BigInteger("10000000"));
|
||||||
|
} else if (units === "Milliseconds (ms)") {
|
||||||
|
input = input.multiply(new BigInteger("10000"));
|
||||||
|
} else if (units === "Microseconds (μs)") {
|
||||||
|
input = input.multiply(new BigInteger("10"));
|
||||||
|
} else if (units === "Nanoseconds (ns)") {
|
||||||
|
input = input.divide(new BigInteger("100"));
|
||||||
|
} else {
|
||||||
|
throw "Unrecognised unit";
|
||||||
|
}
|
||||||
|
|
||||||
|
input = input.add(new BigInteger("116444736000000000"));
|
||||||
|
|
||||||
|
if (format === "Hex"){
|
||||||
|
return input.toString(16);
|
||||||
|
} else {
|
||||||
|
return input.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
FILETIME_FORMATS: ["Decimal", "Hex"],
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const FileType = {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
runDetect: function(input, args) {
|
runDetect: function(input, args) {
|
||||||
const type = FileType._magicType(input);
|
const type = FileType.magicType(input);
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
|
return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
|
||||||
@@ -59,7 +59,7 @@ const FileType = {
|
|||||||
numCommonFound = 0;
|
numCommonFound = 0;
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
for (let i = 0; i < input.length; i++) {
|
||||||
type = FileType._magicType(input.slice(i));
|
type = FileType.magicType(input.slice(i));
|
||||||
if (type) {
|
if (type) {
|
||||||
if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
|
if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
|
||||||
numCommonFound++;
|
numCommonFound++;
|
||||||
@@ -96,14 +96,13 @@ const FileType = {
|
|||||||
* Given a buffer, detects magic byte sequences at specific positions and returns the
|
* Given a buffer, detects magic byte sequences at specific positions and returns the
|
||||||
* extension and mime type.
|
* extension and mime type.
|
||||||
*
|
*
|
||||||
* @private
|
|
||||||
* @param {byteArray} buf
|
* @param {byteArray} buf
|
||||||
* @returns {Object} type
|
* @returns {Object} type
|
||||||
* @returns {string} type.ext - File extension
|
* @returns {string} type.ext - File extension
|
||||||
* @returns {string} type.mime - Mime type
|
* @returns {string} type.mime - Mime type
|
||||||
* @returns {string} [type.desc] - Description
|
* @returns {string} [type.desc] - Description
|
||||||
*/
|
*/
|
||||||
_magicType: function (buf) {
|
magicType: function (buf) {
|
||||||
if (!(buf && buf.length > 1)) {
|
if (!(buf && buf.length > 1)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,17 @@ import {UAS_parser as UAParser} from "../lib/uas_parser.js";
|
|||||||
*/
|
*/
|
||||||
const HTTP = {
|
const HTTP = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
METHODS: [
|
||||||
|
"GET", "POST", "HEAD",
|
||||||
|
"PUT", "PATCH", "DELETE",
|
||||||
|
"CONNECT", "TRACE", "OPTIONS"
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip HTTP headers operation.
|
* Strip HTTP headers operation.
|
||||||
*
|
*
|
||||||
@@ -51,6 +62,95 @@ const HTTP = {
|
|||||||
"Device Type: " + ua.deviceType + "\n";
|
"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 request to an insecure resource (HTTP) from a secure source (HTTPS)\n" +
|
||||||
|
" - Making a cross-origin request to a server which does not support CORS\n";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HTTP;
|
export default HTTP;
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ const IP = {
|
|||||||
baIp.push(decimal & 255);
|
baIp.push(decimal & 255);
|
||||||
break;
|
break;
|
||||||
case "Hex":
|
case "Hex":
|
||||||
baIp = Utils.hexToByteArray(lines[i]);
|
baIp = Utils.fromHex(lines[i]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw "Unsupported input IP format";
|
throw "Unsupported input IP format";
|
||||||
@@ -516,7 +516,7 @@ const IP = {
|
|||||||
"<tr><td>Destination IP address</td><td>" + IP._ipv4ToStr(dstIP) + "</td></tr>";
|
"<tr><td>Destination IP address</td><td>" + IP._ipv4ToStr(dstIP) + "</td></tr>";
|
||||||
|
|
||||||
if (ihl > 5) {
|
if (ihl > 5) {
|
||||||
output += "<tr><td>Options</td><td>" + Utils.byteArrayToHex(options) + "</td></tr>";
|
output += "<tr><td>Options</td><td>" + Utils.toHex(options) + "</td></tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return output + "</table>";
|
return output + "</table>";
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import * as ExifParser from "exif-parser";
|
import * as ExifParser from "exif-parser";
|
||||||
|
import removeEXIF from "../lib/remove-exif.js";
|
||||||
import Utils from "../Utils.js";
|
import Utils from "../Utils.js";
|
||||||
|
import FileType from "./FileType.js";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +24,7 @@ const Image = {
|
|||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
runEXIF(input, args) {
|
runExtractEXIF(input, args) {
|
||||||
try {
|
try {
|
||||||
const bytes = Uint8Array.from(input);
|
const bytes = Uint8Array.from(input);
|
||||||
const parser = ExifParser.create(bytes.buffer);
|
const parser = ExifParser.create(bytes.buffer);
|
||||||
@@ -42,6 +44,81 @@ const Image = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
export default Image;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import esprima from "esprima";
|
import * as esprima from "esprima";
|
||||||
import escodegen from "escodegen";
|
import escodegen from "escodegen";
|
||||||
import esmangle from "esmangle";
|
import esmangle from "esmangle";
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ const JS = {
|
|||||||
tolerant: parseTolerant
|
tolerant: parseTolerant
|
||||||
};
|
};
|
||||||
|
|
||||||
result = esprima.parse(input, options);
|
result = esprima.parseScript(input, options);
|
||||||
return JSON.stringify(result, null, 2);
|
return JSON.stringify(result, null, 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ const JS = {
|
|||||||
AST;
|
AST;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AST = esprima.parse(input, {
|
AST = esprima.parseScript(input, {
|
||||||
range: true,
|
range: true,
|
||||||
tokens: true,
|
tokens: true,
|
||||||
comment: true
|
comment: true
|
||||||
@@ -142,7 +142,7 @@ const JS = {
|
|||||||
*/
|
*/
|
||||||
runMinify: function(input, args) {
|
runMinify: function(input, args) {
|
||||||
let result = "",
|
let result = "",
|
||||||
AST = esprima.parse(input),
|
AST = esprima.parseScript(input),
|
||||||
optimisedAST = esmangle.optimize(AST, null),
|
optimisedAST = esmangle.optimize(AST, null),
|
||||||
mangledAST = esmangle.mangle(optimisedAST);
|
mangledAST = esmangle.mangle(optimisedAST);
|
||||||
|
|
||||||
|
|||||||
@@ -18,25 +18,25 @@ const OS = {
|
|||||||
*/
|
*/
|
||||||
runParseUnixPerms: function(input, args) {
|
runParseUnixPerms: function(input, args) {
|
||||||
let perms = {
|
let perms = {
|
||||||
d : false, // directory
|
d: false, // directory
|
||||||
sl : false, // symbolic link
|
sl: false, // symbolic link
|
||||||
np : false, // named pipe
|
np: false, // named pipe
|
||||||
s : false, // socket
|
s: false, // socket
|
||||||
cd : false, // character device
|
cd: false, // character device
|
||||||
bd : false, // block device
|
bd: false, // block device
|
||||||
dr : false, // door
|
dr: false, // door
|
||||||
sb : false, // sticky bit
|
sb: false, // sticky bit
|
||||||
su : false, // setuid
|
su: false, // setuid
|
||||||
sg : false, // setgid
|
sg: false, // setgid
|
||||||
ru : false, // read user
|
ru: false, // read user
|
||||||
wu : false, // write user
|
wu: false, // write user
|
||||||
eu : false, // execute user
|
eu: false, // execute user
|
||||||
rg : false, // read group
|
rg: false, // read group
|
||||||
wg : false, // write group
|
wg: false, // write group
|
||||||
eg : false, // execute group
|
eg: false, // execute group
|
||||||
ro : false, // read other
|
ro: false, // read other
|
||||||
wo : false, // write other
|
wo: false, // write other
|
||||||
eo : false // execute other
|
eo: false // execute other
|
||||||
},
|
},
|
||||||
d = 0,
|
d = 0,
|
||||||
u = 0,
|
u = 0,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,7 @@ const QuotedPrintable = {
|
|||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
runFrom: function (input, args) {
|
runFrom: function (input, args) {
|
||||||
const str = input.replace(/\=(?:\r?\n|$)/g, "");
|
const str = input.replace(/=(?:\r?\n|$)/g, "");
|
||||||
return QuotedPrintable.mimeDecode(str);
|
return QuotedPrintable.mimeDecode(str);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ const QuotedPrintable = {
|
|||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
mimeDecode: function(str) {
|
mimeDecode: function(str) {
|
||||||
let encodedBytesCount = (str.match(/\=[\da-fA-F]{2}/g) || []).length,
|
let encodedBytesCount = (str.match(/=[\da-fA-F]{2}/g) || []).length,
|
||||||
bufferLength = str.length - encodedBytesCount * 2,
|
bufferLength = str.length - encodedBytesCount * 2,
|
||||||
chr, hex,
|
chr, hex,
|
||||||
buffer = new Array(bufferLength),
|
buffer = new Array(bufferLength),
|
||||||
@@ -219,21 +219,21 @@ const QuotedPrintable = {
|
|||||||
result += line;
|
result += line;
|
||||||
pos += line.length;
|
pos += line.length;
|
||||||
continue;
|
continue;
|
||||||
} else if (line.length > lineLengthMax - lineMargin && (match = line.substr(-lineMargin).match(/[ \t\.,!\?][^ \t\.,!\?]*$/))) {
|
} else if (line.length > lineLengthMax - lineMargin && (match = line.substr(-lineMargin).match(/[ \t.,!?][^ \t.,!?]*$/))) {
|
||||||
// truncate to nearest space
|
// truncate to nearest space
|
||||||
line = line.substr(0, line.length - (match[0].length - 1));
|
line = line.substr(0, line.length - (match[0].length - 1));
|
||||||
} else if (line.substr(-1) === "\r") {
|
} else if (line.substr(-1) === "\r") {
|
||||||
line = line.substr(0, line.length - 1);
|
line = line.substr(0, line.length - 1);
|
||||||
} else {
|
} else {
|
||||||
if (line.match(/\=[\da-f]{0,2}$/i)) {
|
if (line.match(/=[\da-f]{0,2}$/i)) {
|
||||||
|
|
||||||
// push incomplete encoding sequences to the next line
|
// push incomplete encoding sequences to the next line
|
||||||
if ((match = line.match(/\=[\da-f]{0,1}$/i))) {
|
if ((match = line.match(/=[\da-f]{0,1}$/i))) {
|
||||||
line = line.substr(0, line.length - match[0].length);
|
line = line.substr(0, line.length - match[0].length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that utf-8 sequences are not split
|
// ensure that utf-8 sequences are not split
|
||||||
while (line.length > 3 && line.length < len - pos && !line.match(/^(?:=[\da-f]{2}){1,4}$/i) && (match = line.match(/\=[\da-f]{2}$/ig))) {
|
while (line.length > 3 && line.length < len - pos && !line.match(/^(?:=[\da-f]{2}){1,4}$/i) && (match = line.match(/=[\da-f]{2}$/ig))) {
|
||||||
code = parseInt(match[0].substr(1, 2), 16);
|
code = parseInt(match[0].substr(1, 2), 16);
|
||||||
if (code < 128) {
|
if (code < 128) {
|
||||||
break;
|
break;
|
||||||
@@ -250,7 +250,7 @@ const QuotedPrintable = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pos + line.length < len && line.substr(-1) !== "\n") {
|
if (pos + line.length < len && line.substr(-1) !== "\n") {
|
||||||
if (line.length === 76 && line.match(/\=[\da-f]{2}$/i)) {
|
if (line.length === 76 && line.match(/=[\da-f]{2}$/i)) {
|
||||||
line = line.substr(0, line.length - 3);
|
line = line.substr(0, line.length - 3);
|
||||||
} else if (line.length === 76) {
|
} else if (line.length === 76) {
|
||||||
line = line.substr(0, line.length - 1);
|
line = line.substr(0, line.length - 1);
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ const Rotate = {
|
|||||||
/**
|
/**
|
||||||
* ROT47 operation.
|
* ROT47 operation.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @param {byteArray} input
|
* @param {byteArray} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const SeqUtils = {
|
|||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address"],
|
SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort operation.
|
* Sort operation.
|
||||||
@@ -47,6 +47,8 @@ const SeqUtils = {
|
|||||||
sorted = sorted.sort(SeqUtils._caseInsensitiveSort);
|
sorted = sorted.sort(SeqUtils._caseInsensitiveSort);
|
||||||
} else if (order === "IP address") {
|
} else if (order === "IP address") {
|
||||||
sorted = sorted.sort(SeqUtils._ipSort);
|
sorted = sorted.sort(SeqUtils._ipSort);
|
||||||
|
} else if (order === "Numeric") {
|
||||||
|
sorted = sorted.sort(SeqUtils._numericSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortReverse) sorted.reverse();
|
if (sortReverse) sorted.reverse();
|
||||||
@@ -221,6 +223,35 @@ const SeqUtils = {
|
|||||||
return a_ - b_;
|
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;
|
export default SeqUtils;
|
||||||
|
|||||||
@@ -193,17 +193,17 @@ const StrUtils = {
|
|||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
FIND_REPLACE_GLOBAL : true,
|
FIND_REPLACE_GLOBAL: true,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
FIND_REPLACE_CASE : false,
|
FIND_REPLACE_CASE: false,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
FIND_REPLACE_MULTILINE : true,
|
FIND_REPLACE_MULTILINE: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find / Replace operation.
|
* Find / Replace operation.
|
||||||
@@ -227,14 +227,16 @@ const StrUtils = {
|
|||||||
|
|
||||||
if (type === "Regex") {
|
if (type === "Regex") {
|
||||||
find = new RegExp(find, modifiers);
|
find = new RegExp(find, modifiers);
|
||||||
} else if (type.indexOf("Extended") === 0) {
|
return input.replace(find, replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.indexOf("Extended") === 0) {
|
||||||
find = Utils.parseEscapedChars(find);
|
find = Utils.parseEscapedChars(find);
|
||||||
}
|
}
|
||||||
|
|
||||||
return input.replace(find, replace, modifiers);
|
find = new RegExp(Utils.escapeRegex(find), modifiers);
|
||||||
// Non-standard addition of flags in the third argument. This will work in Firefox but
|
|
||||||
// probably nowhere else. The purpose is to allow global matching when the `find` parameter
|
return input.replace(find, replace);
|
||||||
// is just a string.
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@@ -357,9 +359,9 @@ const StrUtils = {
|
|||||||
|
|
||||||
for (let i = 0; i < diff.length; i++) {
|
for (let i = 0; i < diff.length; i++) {
|
||||||
if (diff[i].added) {
|
if (diff[i].added) {
|
||||||
if (showAdded) output += "<span class='hlgreen'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
if (showAdded) output += "<span class='hl5'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
||||||
} else if (diff[i].removed) {
|
} else if (diff[i].removed) {
|
||||||
if (showRemoved) output += "<span class='hlred'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
if (showRemoved) output += "<span class='hl3'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
||||||
} else {
|
} else {
|
||||||
output += Utils.escapeHtml(diff[i].value);
|
output += Utils.escapeHtml(diff[i].value);
|
||||||
}
|
}
|
||||||
@@ -422,7 +424,7 @@ const StrUtils = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (match && !inMatch) {
|
if (match && !inMatch) {
|
||||||
outputs[s] += "<span class='hlgreen'>" + Utils.escapeHtml(samples[s][i]);
|
outputs[s] += "<span class='hl5'>" + Utils.escapeHtml(samples[s][i]);
|
||||||
if (samples[s].length === i + 1) outputs[s] += "</span>";
|
if (samples[s].length === i + 1) outputs[s] += "</span>";
|
||||||
if (s === samples.length - 1) inMatch = true;
|
if (s === samples.length - 1) inMatch = true;
|
||||||
} else if (!match && inMatch) {
|
} else if (!match && inMatch) {
|
||||||
@@ -474,16 +476,16 @@ const StrUtils = {
|
|||||||
const splitInput = input.split(delimiter);
|
const splitInput = input.split(delimiter);
|
||||||
|
|
||||||
return splitInput
|
return splitInput
|
||||||
.filter((line, lineIndex) => {
|
.filter((line, lineIndex) => {
|
||||||
lineIndex += 1;
|
lineIndex += 1;
|
||||||
|
|
||||||
if (number < 0) {
|
if (number < 0) {
|
||||||
return lineIndex <= splitInput.length + number;
|
return lineIndex <= splitInput.length + number;
|
||||||
} else {
|
} else {
|
||||||
return lineIndex <= number;
|
return lineIndex <= number;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.join(delimiter);
|
.join(delimiter);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@@ -502,16 +504,16 @@ const StrUtils = {
|
|||||||
const splitInput = input.split(delimiter);
|
const splitInput = input.split(delimiter);
|
||||||
|
|
||||||
return splitInput
|
return splitInput
|
||||||
.filter((line, lineIndex) => {
|
.filter((line, lineIndex) => {
|
||||||
lineIndex += 1;
|
lineIndex += 1;
|
||||||
|
|
||||||
if (number < 0) {
|
if (number < 0) {
|
||||||
return lineIndex > -number;
|
return lineIndex > -number;
|
||||||
} else {
|
} else {
|
||||||
return lineIndex > splitInput.length - number;
|
return lineIndex > splitInput.length - number;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.join(delimiter);
|
.join(delimiter);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,32 +16,32 @@ const Tidy = {
|
|||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
REMOVE_SPACES : true,
|
REMOVE_SPACES: true,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
REMOVE_CARIAGE_RETURNS : true,
|
REMOVE_CARIAGE_RETURNS: true,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
REMOVE_LINE_FEEDS : true,
|
REMOVE_LINE_FEEDS: true,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
REMOVE_TABS : true,
|
REMOVE_TABS: true,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
REMOVE_FORM_FEEDS : true,
|
REMOVE_FORM_FEEDS: true,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
REMOVE_FULL_STOPS : false,
|
REMOVE_FULL_STOPS: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove whitespace operation.
|
* Remove whitespace operation.
|
||||||
@@ -89,17 +89,17 @@ const Tidy = {
|
|||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
APPLY_TO_EACH_LINE : false,
|
APPLY_TO_EACH_LINE: false,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
DROP_START : 0,
|
DROP_START: 0,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
DROP_LENGTH : 5,
|
DROP_LENGTH: 5,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop bytes operation.
|
* Drop bytes operation.
|
||||||
@@ -200,17 +200,17 @@ const Tidy = {
|
|||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
PAD_POSITION : ["Start", "End"],
|
PAD_POSITION: ["Start", "End"],
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
PAD_LENGTH : 5,
|
PAD_LENGTH: 5,
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
PAD_CHAR : " ",
|
PAD_CHAR: " ",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pad lines operation.
|
* Pad lines operation.
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ const URL_ = {
|
|||||||
.replace(/\(/g, "%28")
|
.replace(/\(/g, "%28")
|
||||||
.replace(/\)/g, "%29")
|
.replace(/\)/g, "%29")
|
||||||
.replace(/\*/g, "%2A")
|
.replace(/\*/g, "%2A")
|
||||||
.replace(/\-/g, "%2D")
|
.replace(/-/g, "%2D")
|
||||||
.replace(/\./g, "%2E")
|
.replace(/\./g, "%2E")
|
||||||
.replace(/_/g, "%5F")
|
.replace(/_/g, "%5F")
|
||||||
.replace(/~/g, "%7E");
|
.replace(/~/g, "%7E");
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ const CyberChef = module.exports = {
|
|||||||
bake: function(input, recipeConfig) {
|
bake: function(input, recipeConfig) {
|
||||||
this.chef = new Chef();
|
this.chef = new Chef();
|
||||||
return this.chef.bake(
|
return this.chef.bake(
|
||||||
input,
|
input,
|
||||||
recipeConfig,
|
recipeConfig,
|
||||||
{},
|
{},
|
||||||
0,
|
0,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
118
src/web/App.js
118
src/web/App.js
@@ -21,21 +21,22 @@ import Split from "split.js";
|
|||||||
* @param {Object} options - Default setting for app options.
|
* @param {Object} options - Default setting for app options.
|
||||||
*/
|
*/
|
||||||
const App = function(categories, operations, defaultFavourites, defaultOptions) {
|
const App = function(categories, operations, defaultFavourites, defaultOptions) {
|
||||||
this.categories = categories;
|
this.categories = categories;
|
||||||
this.operations = operations;
|
this.operations = operations;
|
||||||
this.dfavourites = defaultFavourites;
|
this.dfavourites = defaultFavourites;
|
||||||
this.doptions = defaultOptions;
|
this.doptions = defaultOptions;
|
||||||
this.options = Utils.extend({}, defaultOptions);
|
this.options = Utils.extend({}, defaultOptions);
|
||||||
|
|
||||||
this.chef = new Chef();
|
this.chef = new Chef();
|
||||||
this.manager = new Manager(this);
|
this.manager = new Manager(this);
|
||||||
|
|
||||||
this.baking = false;
|
this.baking = false;
|
||||||
this.autoBake_ = false;
|
this.autoBake_ = false;
|
||||||
this.progress = 0;
|
this.autoBakePause = false;
|
||||||
this.ingId = 0;
|
this.progress = 0;
|
||||||
|
this.ingId = 0;
|
||||||
|
|
||||||
window.chef = this.chef;
|
window.chef = this.chef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -53,6 +54,26 @@ App.prototype.setup = function() {
|
|||||||
this.resetLayout();
|
this.resetLayout();
|
||||||
this.setCompileMessage();
|
this.setCompileMessage();
|
||||||
this.loadURIParams();
|
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.loadingMsgsInt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -146,7 +167,7 @@ App.prototype.bake = async function(step) {
|
|||||||
* Runs Auto Bake if it is set.
|
* Runs Auto Bake if it is set.
|
||||||
*/
|
*/
|
||||||
App.prototype.autoBake = function() {
|
App.prototype.autoBake = function() {
|
||||||
if (this.autoBake_) {
|
if (this.autoBake_ && !this.autoBakePause) {
|
||||||
this.bake();
|
this.bake();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -179,13 +200,7 @@ App.prototype.silentBake = function() {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
App.prototype.getInput = function() {
|
App.prototype.getInput = function() {
|
||||||
const input = this.manager.input.get();
|
return this.manager.input.get();
|
||||||
|
|
||||||
// Save to session storage in case we need to restore it later
|
|
||||||
sessionStorage.setItem("inputLength", input.length);
|
|
||||||
sessionStorage.setItem("input", input);
|
|
||||||
|
|
||||||
return input;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -195,8 +210,6 @@ App.prototype.getInput = function() {
|
|||||||
* @param {string} input - The string to set the input to
|
* @param {string} input - The string to set the input to
|
||||||
*/
|
*/
|
||||||
App.prototype.setInput = function(input) {
|
App.prototype.setInput = function(input) {
|
||||||
sessionStorage.setItem("inputLength", input.length);
|
|
||||||
sessionStorage.setItem("input", input);
|
|
||||||
this.manager.input.set(input);
|
this.manager.input.set(input);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -378,39 +391,33 @@ App.prototype.addFavourite = function(name) {
|
|||||||
* Checks for input and recipe in the URI parameters and loads them if present.
|
* Checks for input and recipe in the URI parameters and loads them if present.
|
||||||
*/
|
*/
|
||||||
App.prototype.loadURIParams = function() {
|
App.prototype.loadURIParams = function() {
|
||||||
// Load query string from URI
|
// Load query string or hash from URI (depending on which is populated)
|
||||||
this.queryString = (function(a) {
|
// We prefer getting the hash by splitting the href rather than referencing
|
||||||
if (a === "") return {};
|
// location.hash as some browsers (Firefox) automatically URL decode it,
|
||||||
const b = {};
|
// which cause issues.
|
||||||
for (let i = 0; i < a.length; i++) {
|
const params = window.location.search ||
|
||||||
const p = a[i].split("=");
|
window.location.href.split("#")[1] ||
|
||||||
if (p.length !== 2) {
|
window.location.hash;
|
||||||
b[a[i]] = true;
|
this.uriParams = Utils.parseURIParams(params);
|
||||||
} else {
|
|
||||||
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
})(window.location.search.substr(1).split("&"));
|
|
||||||
|
|
||||||
// Turn off auto-bake while loading
|
// Pause auto-bake while loading but don't modify `this.autoBake_`
|
||||||
const autoBakeVal = this.autoBake_;
|
// otherwise `manualBake` cannot trigger.
|
||||||
this.autoBake_ = false;
|
this.autoBakePause = true;
|
||||||
|
|
||||||
// Read in recipe from query string
|
// Read in recipe from URI params
|
||||||
if (this.queryString.recipe) {
|
if (this.uriParams.recipe) {
|
||||||
try {
|
try {
|
||||||
const recipeConfig = JSON.parse(this.queryString.recipe);
|
const recipeConfig = JSON.parse(this.uriParams.recipe);
|
||||||
this.setRecipeConfig(recipeConfig);
|
this.setRecipeConfig(recipeConfig);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
} else if (this.queryString.op) {
|
} else if (this.uriParams.op) {
|
||||||
// If there's no recipe, look for single operations
|
// If there's no recipe, look for single operations
|
||||||
this.manager.recipe.clearRecipe();
|
this.manager.recipe.clearRecipe();
|
||||||
try {
|
try {
|
||||||
this.manager.recipe.addOperation(this.queryString.op);
|
this.manager.recipe.addOperation(this.uriParams.op);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// If no exact match, search for nearest match and add that
|
// If no exact match, search for nearest match and add that
|
||||||
const matchedOps = this.manager.ops.filterOperations(this.queryString.op, false);
|
const matchedOps = this.manager.ops.filterOperations(this.uriParams.op, false);
|
||||||
if (matchedOps.length) {
|
if (matchedOps.length) {
|
||||||
this.manager.recipe.addOperation(matchedOps[0].name);
|
this.manager.recipe.addOperation(matchedOps[0].name);
|
||||||
}
|
}
|
||||||
@@ -418,21 +425,21 @@ App.prototype.loadURIParams = function() {
|
|||||||
// Populate search with the string
|
// Populate search with the string
|
||||||
const search = document.getElementById("search");
|
const search = document.getElementById("search");
|
||||||
|
|
||||||
search.value = this.queryString.op;
|
search.value = this.uriParams.op;
|
||||||
search.dispatchEvent(new Event("search"));
|
search.dispatchEvent(new Event("search"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read in input data from query string
|
// Read in input data from URI params
|
||||||
if (this.queryString.input) {
|
if (this.uriParams.input) {
|
||||||
try {
|
try {
|
||||||
const inputData = Utils.fromBase64(this.queryString.input);
|
const inputData = Utils.fromBase64(this.uriParams.input);
|
||||||
this.setInput(inputData);
|
this.setInput(inputData);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore auto-bake state
|
// Unpause auto-bake
|
||||||
this.autoBake_ = autoBakeVal;
|
this.autoBakePause = false;
|
||||||
this.autoBake();
|
this.autoBake();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -453,9 +460,7 @@ App.prototype.nextIngId = function() {
|
|||||||
* @returns {Object[]}
|
* @returns {Object[]}
|
||||||
*/
|
*/
|
||||||
App.prototype.getRecipeConfig = function() {
|
App.prototype.getRecipeConfig = function() {
|
||||||
const recipeConfig = this.manager.recipe.getConfig();
|
return this.manager.recipe.getConfig();
|
||||||
sessionStorage.setItem("recipeConfig", JSON.stringify(recipeConfig));
|
|
||||||
return recipeConfig;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -465,7 +470,6 @@ App.prototype.getRecipeConfig = function() {
|
|||||||
* @param {Object[]} recipeConfig - The recipe configuration
|
* @param {Object[]} recipeConfig - The recipe configuration
|
||||||
*/
|
*/
|
||||||
App.prototype.setRecipeConfig = function(recipeConfig) {
|
App.prototype.setRecipeConfig = function(recipeConfig) {
|
||||||
sessionStorage.setItem("recipeConfig", JSON.stringify(recipeConfig));
|
|
||||||
document.getElementById("rec-list").innerHTML = null;
|
document.getElementById("rec-list").innerHTML = null;
|
||||||
|
|
||||||
for (let i = 0; i < recipeConfig.length; i++) {
|
for (let i = 0; i < recipeConfig.length; i++) {
|
||||||
@@ -668,9 +672,7 @@ App.prototype.stateChange = function(e) {
|
|||||||
* @param {event} e
|
* @param {event} e
|
||||||
*/
|
*/
|
||||||
App.prototype.popState = function(e) {
|
App.prototype.popState = function(e) {
|
||||||
if (window.location.href.split("#")[0] !== this.lastStateUrl) {
|
this.loadURIParams();
|
||||||
this.loadURIParams();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -106,11 +106,11 @@ ControlsWaiter.prototype.autoBakeChange = function() {
|
|||||||
this.app.autoBake_ = autoBakeCheckbox.checked;
|
this.app.autoBake_ = autoBakeCheckbox.checked;
|
||||||
|
|
||||||
if (autoBakeCheckbox.checked) {
|
if (autoBakeCheckbox.checked) {
|
||||||
autoBakeLabel.classList.remove("btn-default");
|
|
||||||
autoBakeLabel.classList.add("btn-success");
|
autoBakeLabel.classList.add("btn-success");
|
||||||
|
autoBakeLabel.classList.remove("btn-default");
|
||||||
} else {
|
} else {
|
||||||
autoBakeLabel.classList.remove("btn-success");
|
|
||||||
autoBakeLabel.classList.add("btn-default");
|
autoBakeLabel.classList.add("btn-default");
|
||||||
|
autoBakeLabel.classList.remove("btn-success");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,20 +174,21 @@ ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput
|
|||||||
const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
|
const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
|
||||||
|
|
||||||
includeRecipe = includeRecipe && (recipeConfig.length > 0);
|
includeRecipe = includeRecipe && (recipeConfig.length > 0);
|
||||||
includeInput = includeInput && (inputStr.length > 0) && (inputStr.length < 8000);
|
// Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded)
|
||||||
|
includeInput = includeInput && (inputStr.length > 0) && (inputStr.length <= 68267);
|
||||||
|
|
||||||
const params = [
|
const params = [
|
||||||
includeRecipe ? ["recipe", recipeStr] : undefined,
|
includeRecipe ? ["recipe", recipeStr] : undefined,
|
||||||
includeInput ? ["input", inputStr] : undefined,
|
includeInput ? ["input", inputStr] : undefined,
|
||||||
];
|
];
|
||||||
|
|
||||||
const query = params
|
const hash = params
|
||||||
.filter(v => v)
|
.filter(v => v)
|
||||||
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||||
.join("&");
|
.join("&");
|
||||||
|
|
||||||
if (query) {
|
if (hash) {
|
||||||
return `${link}?${query}`;
|
return `${link}#${hash}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return link;
|
return link;
|
||||||
@@ -287,7 +288,7 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
|||||||
|
|
||||||
// Add recipes to select
|
// Add recipes to select
|
||||||
const savedRecipes = localStorage.savedRecipes ?
|
const savedRecipes = localStorage.savedRecipes ?
|
||||||
JSON.parse(localStorage.savedRecipes) : [];
|
JSON.parse(localStorage.savedRecipes) : [];
|
||||||
|
|
||||||
for (i = 0; i < savedRecipes.length; i++) {
|
for (i = 0; i < savedRecipes.length; i++) {
|
||||||
const opt = document.createElement("option");
|
const opt = document.createElement("option");
|
||||||
@@ -309,7 +310,7 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
|||||||
ControlsWaiter.prototype.loadDeleteClick = function() {
|
ControlsWaiter.prototype.loadDeleteClick = function() {
|
||||||
const id = parseInt(document.getElementById("load-name").value, 10);
|
const id = parseInt(document.getElementById("load-name").value, 10);
|
||||||
const rawSavedRecipes = localStorage.savedRecipes ?
|
const rawSavedRecipes = localStorage.savedRecipes ?
|
||||||
JSON.parse(localStorage.savedRecipes) : [];
|
JSON.parse(localStorage.savedRecipes) : [];
|
||||||
|
|
||||||
const savedRecipes = rawSavedRecipes.filter(r => r.id !== id);
|
const savedRecipes = rawSavedRecipes.filter(r => r.id !== id);
|
||||||
|
|
||||||
@@ -324,7 +325,7 @@ ControlsWaiter.prototype.loadDeleteClick = function() {
|
|||||||
ControlsWaiter.prototype.loadNameChange = function(e) {
|
ControlsWaiter.prototype.loadNameChange = function(e) {
|
||||||
const el = e.target;
|
const el = e.target;
|
||||||
const savedRecipes = localStorage.savedRecipes ?
|
const savedRecipes = localStorage.savedRecipes ?
|
||||||
JSON.parse(localStorage.savedRecipes) : [];
|
JSON.parse(localStorage.savedRecipes) : [];
|
||||||
const id = parseInt(el.value, 10);
|
const id = parseInt(el.value, 10);
|
||||||
|
|
||||||
const recipe = savedRecipes.find(r => r.id === id);
|
const recipe = savedRecipes.find(r => r.id === id);
|
||||||
@@ -350,14 +351,21 @@ ControlsWaiter.prototype.loadButtonClick = function() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates the bug report information box with useful technical info.
|
* Populates the bug report information box with useful technical info.
|
||||||
|
*
|
||||||
|
* @param {event} e
|
||||||
*/
|
*/
|
||||||
ControlsWaiter.prototype.supportButtonClick = function() {
|
ControlsWaiter.prototype.supportButtonClick = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
const reportBugInfo = document.getElementById("report-bug-info");
|
const reportBugInfo = document.getElementById("report-bug-info");
|
||||||
const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/");
|
const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/");
|
||||||
|
|
||||||
reportBugInfo.innerHTML = "* CyberChef compile time: " + COMPILE_TIME + "\n" +
|
if (reportBugInfo) {
|
||||||
"* User-Agent: \n" + navigator.userAgent + "\n" +
|
reportBugInfo.innerHTML = "* Version: " + PKG_VERSION + "\n" +
|
||||||
"* [Link to reproduce](" + saveLink + ")\n\n";
|
"* Compile time: " + COMPILE_TIME + "\n" +
|
||||||
|
"* User-Agent: \n" + navigator.userAgent + "\n" +
|
||||||
|
"* [Link to reproduce](" + saveLink + ")\n\n";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ControlsWaiter;
|
export default ControlsWaiter;
|
||||||
|
|||||||
@@ -493,13 +493,14 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
|
|||||||
//if (colour) cssClass += "-"+colour;
|
//if (colour) cssClass += "-"+colour;
|
||||||
|
|
||||||
// Remove HTML tags
|
// Remove HTML tags
|
||||||
text = text.replace(/&/g, "&")
|
text = text
|
||||||
.replace(/</g, "<")
|
.replace(/&/g, "&")
|
||||||
.replace(/>/g, ">")
|
.replace(/</g, "<")
|
||||||
.replace(/\n/g, " ")
|
.replace(/>/g, ">")
|
||||||
// Convert placeholders to tags
|
.replace(/\n/g, " ")
|
||||||
.replace(startPlaceholderRegex, "<span class=\""+cssClass+"\">")
|
// Convert placeholders to tags
|
||||||
.replace(endPlaceholderRegex, "</span>") + " ";
|
.replace(startPlaceholderRegex, "<span class=\""+cssClass+"\">")
|
||||||
|
.replace(endPlaceholderRegex, "</span>") + " ";
|
||||||
|
|
||||||
// Adjust width to allow for scrollbars
|
// Adjust width to allow for scrollbars
|
||||||
highlighter.style.width = textarea.clientWidth + "px";
|
highlighter.style.width = textarea.clientWidth + "px";
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ InputWaiter.prototype.inputDrop = function(e) {
|
|||||||
this.set(inputCharcode);
|
this.set(inputCharcode);
|
||||||
const recipeConfig = this.app.getRecipeConfig();
|
const recipeConfig = this.app.getRecipeConfig();
|
||||||
if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
|
if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
|
||||||
recipeConfig.unshift({op:"From Hex", args:["Space"]});
|
recipeConfig.unshift({op: "From Hex", args: ["Space"]});
|
||||||
this.app.setRecipeConfig(recipeConfig);
|
this.app.setRecipeConfig(recipeConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ Manager.prototype.initialiseEventListeners = function() {
|
|||||||
document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter));
|
document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter));
|
||||||
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
||||||
this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter);
|
this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter);
|
||||||
|
this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output);
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
|
document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
|
||||||
@@ -154,6 +155,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]", "keyup", this.options.numberChange, this.options);
|
||||||
this.addDynamicListener(".option-item input[type=number]", "change", 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);
|
this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options);
|
||||||
|
document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options));
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
|
document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
|
||||||
|
|||||||
@@ -43,8 +43,13 @@ OptionsWaiter.prototype.load = function(options) {
|
|||||||
|
|
||||||
const selects = document.querySelectorAll("#options-body select");
|
const selects = document.querySelectorAll("#options-body select");
|
||||||
for (i = 0; i < selects.length; i++) {
|
for (i = 0; i < selects.length; i++) {
|
||||||
selects[i].value = this.app.options[selects[i].getAttribute("option")];
|
const val = this.app.options[selects[i].getAttribute("option")];
|
||||||
selects[i].dispatchEvent(new CustomEvent("change", {bubbles: true}));
|
if (val) {
|
||||||
|
selects[i].value = val;
|
||||||
|
selects[i].dispatchEvent(new CustomEvent("change", {bubbles: true}));
|
||||||
|
} else {
|
||||||
|
selects[i].selectedIndex = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,8 +57,11 @@ OptionsWaiter.prototype.load = function(options) {
|
|||||||
/**
|
/**
|
||||||
* Handler for options click events.
|
* Handler for options click events.
|
||||||
* Dispays the options pane.
|
* Dispays the options pane.
|
||||||
|
*
|
||||||
|
* @param {event} e
|
||||||
*/
|
*/
|
||||||
OptionsWaiter.prototype.optionsClick = function() {
|
OptionsWaiter.prototype.optionsClick = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
$("#options-modal").modal();
|
$("#options-modal").modal();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,4 +140,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;
|
export default OptionsWaiter;
|
||||||
|
|||||||
@@ -167,6 +167,17 @@ OutputWaiter.prototype.undoSwitchClick = function() {
|
|||||||
document.getElementById("undo-switch").disabled = true;
|
document.getElementById("undo-switch").disabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for file switch click events.
|
||||||
|
* Moves a files data for items created via Utils.displayFilesAsHTML to the input.
|
||||||
|
*/
|
||||||
|
OutputWaiter.prototype.fileSwitch = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.switchOrigData = this.manager.input.get();
|
||||||
|
this.app.setInput(e.target.getAttribute("fileValue"));
|
||||||
|
document.getElementById("undo-switch").disabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for maximise output click events.
|
* Handler for maximise output click events.
|
||||||
|
|||||||
@@ -354,8 +354,7 @@ RecipeWaiter.prototype.buildRecipeOperation = function(el) {
|
|||||||
el.classList.add("flow-control-op");
|
el.classList.add("flow-control-op");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable auto-bake if this is a manual op - this should be moved to the 'operationadd'
|
// Disable auto-bake if this is a manual op
|
||||||
// handler after event restructuring
|
|
||||||
if (op.manualBake && this.app.autoBake_) {
|
if (op.manualBake && this.app.autoBake_) {
|
||||||
this.manager.controls.setAutoBake(false);
|
this.manager.controls.setAutoBake(false);
|
||||||
this.app.alert("Auto-Bake is disabled by default when using this operation.", "info", 5000);
|
this.app.alert("Auto-Bake is disabled by default when using this operation.", "info", 5000);
|
||||||
|
|||||||
@@ -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 -->
|
<!-- htmlmin:ignore -->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="classic">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>CyberChef</title>
|
<title>CyberChef</title>
|
||||||
@@ -30,44 +30,102 @@
|
|||||||
<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" />
|
<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') %>" />
|
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Load theme before the preloader is shown
|
||||||
|
try {
|
||||||
|
document.querySelector(":root").className = JSON.parse(localStorage.getItem("options")).theme;
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// 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>
|
</head>
|
||||||
<body>
|
<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>
|
<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">
|
<div id="alert" class="alert alert-danger">
|
||||||
<button type="button" class="close" id="alert-close">×</button>
|
<button type="button" class="close" id="alert-close">×</button>
|
||||||
<span id="alert-content"></span>
|
<span id="alert-content"></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="content-wrapper">
|
<div id="content-wrapper">
|
||||||
<div id="banner" class="green">
|
<div id="banner">
|
||||||
<% if (htmlWebpackPlugin.options.inline) { %>
|
<div class="col-md-4" style="text-align: left; padding-left: 10px;">
|
||||||
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
|
<% if (htmlWebpackPlugin.options.inline) { %>
|
||||||
<% } else { %>
|
<span>Version <%= htmlWebpackPlugin.options.version %></span>
|
||||||
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img aria-hidden="true" src="<%- require('../static/images/download-24x24.png') %>" alt="Download Icon"/></a>
|
<% } else { %>
|
||||||
<% } %>
|
<a href="cyberchef.htm" download>Download CyberChef<img aria-hidden="true" src="<%- require('../static/images/download-24x24.png') %>" alt="Download Icon"/></a>
|
||||||
<span id="notice">
|
<% } %>
|
||||||
<script type="text/javascript">
|
</div>
|
||||||
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
|
<div class="col-md-4" style="text-align: center;">
|
||||||
if (navigator.userAgent && navigator.userAgent.match(/MSIE \d\d?\./)) {
|
<span id="notice">
|
||||||
document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
<script type="text/javascript">
|
||||||
alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
|
||||||
}
|
if (navigator.userAgent && navigator.userAgent.match(/MSIE \d\d?\./)) {
|
||||||
</script>
|
document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||||
<noscript>JavaScript is not enabled. Good luck.</noscript>
|
alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||||
</span>
|
}
|
||||||
<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>
|
</script>
|
||||||
<a href="#" id="options" class="banner-right">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
|
<noscript>JavaScript is not enabled. Good luck.</noscript>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4" style="text-align: right; padding-right: 0;">
|
||||||
|
<a href="#" id="options">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
|
||||||
|
<a href="#" id="support" 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>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="wrapper">
|
<div id="workspace-wrapper">
|
||||||
<div id="operations" class="split split-horizontal no-select">
|
<div id="operations" class="split split-horizontal no-select">
|
||||||
<div class="title no-select">Operations</div>
|
<div class="title no-select">Operations</div>
|
||||||
<input type="search" class="form-control" id="search" placeholder="Search..." autocomplete="off">
|
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off">
|
||||||
<ul class="op-list" id="search-results"></ul>
|
<ul id="search-results" class="op-list"></ul>
|
||||||
<div class="panel-group no-select" id="categories"></div>
|
<div id="categories" class="panel-group no-select"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="recipe" class="split split-horizontal no-select">
|
<div id="recipe" class="split split-horizontal no-select">
|
||||||
<div class="title no-select">Recipe</div>
|
<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="controls" class="no-select">
|
||||||
<div id="operational-controls">
|
<div id="operational-controls">
|
||||||
@@ -165,6 +223,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-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>
|
<input type="checkbox" id="save-link-input-checkbox" checked> <label for="save-link-input-checkbox"> Include input </label>
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
<a id="save-link" style="word-wrap: break-word;"></a>
|
<a id="save-link" style="word-wrap: break-word;"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -208,32 +267,39 @@
|
|||||||
<div class="modal-body" id="options-body">
|
<div class="modal-body" id="options-body">
|
||||||
<p style="font-weight: bold">Please note that these options will persist between sessions.</p>
|
<p style="font-weight: bold">Please note that these options will persist between sessions.</p>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="checkbox" option="update_url" id="update_url" checked />
|
<select option="theme" id="theme">
|
||||||
<label for="update_url"> Update the URL when the input or recipe changes </label>
|
<option value="classic">Classic</option>
|
||||||
|
<option value="dark">Dark</option>
|
||||||
|
</select>
|
||||||
|
<label for="theme"> Theme (only supported in modern browsers)</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="checkbox" option="show_highlighter" id="show_highlighter" checked />
|
<input type="checkbox" option="updateUrl" id="updateUrl" checked />
|
||||||
<label for="show_highlighter"> Highlight selected bytes in output and input (when possible) </label>
|
<label for="updateUrl"> Update the URL when the input or recipe changes </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="checkbox" option="treat_as_utf8" id="treat_as_utf8" checked />
|
<input type="checkbox" option="showHighlighter" id="showHighlighter" checked />
|
||||||
<label for="treat_as_utf8"> Treat output as UTF-8 if possible </label>
|
<label for="showHighlighter"> Highlight selected bytes in output and input (when possible) </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="checkbox" option="word_wrap" id="word_wrap" checked />
|
<input type="checkbox" option="treatAsUtf8" id="treatAsUtf8" checked />
|
||||||
<label for="word_wrap"> Word wrap the input and output </label>
|
<label for="treatAsUtf8"> Treat output as UTF-8 if possible </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="checkbox" option="show_errors" id="show_errors" checked />
|
<input type="checkbox" option="wordWrap" id="wordWrap" checked />
|
||||||
<label for="show_errors"> Operation error reporting (recommended) </label>
|
<label for="wordWrap"> Word wrap the input and output </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="number" option="error_timeout" id="error_timeout" />
|
<input type="checkbox" option="showErrors" id="showErrors" checked />
|
||||||
<label for="error_timeout"> Operation error timeout in ms (0 for never) </label>
|
<label for="showErrors"> Operation error reporting (recommended) </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="option-item">
|
<div class="option-item">
|
||||||
<input type="number" option="auto_bake_threshold" id="auto_bake_threshold"/>
|
<input type="number" option="errorTimeout" id="errorTimeout" />
|
||||||
<label for="auto_bake_threshold"> Auto Bake threshold in ms </label>
|
<label for="errorTimeout"> Operation error timeout in ms (0 for never) </label>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="number" option="autoBakeThreshold" id="autoBakeThreshold"/>
|
||||||
|
<label for="autoBakeThreshold"> Auto Bake threshold in ms </label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@@ -280,9 +346,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" alt="CyberChef Logo"/>
|
<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 class="subtext">
|
||||||
<p>© Crown Copyright 2016.</p>
|
Version <%= htmlWebpackPlugin.options.version %><br>
|
||||||
<p>Licenced under the Apache Licence, Version 2.0.</p>
|
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
|
||||||
|
</p>
|
||||||
|
<p>© Crown Copyright 2016.</p>
|
||||||
|
<p>Released under the Apache Licence, Version 2.0.</p>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<div>
|
<div>
|
||||||
@@ -309,14 +378,14 @@
|
|||||||
</a>
|
</a>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<div class="collapse" id="faq-examples">
|
<div class="collapse" id="faq-examples">
|
||||||
<p>There are well over 100 operations in CyberChef allowing you to carry simple and complex tasks easily. Here are some examples:</p>
|
<p>There are around 200 operations in CyberChef allowing you to carry out simple and complex tasks easily. Here are some examples:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="?recipe=%5B%7B%22op%22%3A%22From%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%2Ctrue%5D%7D%5D&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1">Decode a Base64-encoded string</a></li>
|
<li><a href="#recipe=%5B%7B%22op%22%3A%22From%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%2Ctrue%5D%7D%5D&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1">Decode a Base64-encoded string</a></li>
|
||||||
<li><a href="?recipe=%5B%7B%22op%22%3A%22Translate%20DateTime%20Format%22%2C%22args%22%3A%5B%22Standard%20date%20and%20time%22%2C%22DD%2FMM%2FYYYY%20HH%3Amm%3Ass%22%2C%22UTC%22%2C%22dddd%20Do%20MMMM%20YYYY%20HH%3Amm%3Ass%20Z%20z%22%2C%22Australia%2FQueensland%22%5D%7D%5D&input=MTUvMDYvMjAxNSAyMDo0NTowMA">Convert a date and time to a different time zone</a></li>
|
<li><a href="#recipe=%5B%7B%22op%22%3A%22Translate%20DateTime%20Format%22%2C%22args%22%3A%5B%22Standard%20date%20and%20time%22%2C%22DD%2FMM%2FYYYY%20HH%3Amm%3Ass%22%2C%22UTC%22%2C%22dddd%20Do%20MMMM%20YYYY%20HH%3Amm%3Ass%20Z%20z%22%2C%22Australia%2FQueensland%22%5D%7D%5D&input=MTUvMDYvMjAxNSAyMDo0NTowMA">Convert a date and time to a different time zone</a></li>
|
||||||
<li><a href="?recipe=%5B%7B%22op%22%3A%22Parse%20IPv6%20address%22%2C%22args%22%3A%5B%5D%7D%5D&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy">Parse a Teredo IPv6 address</a></li>
|
<li><a href="#recipe=%5B%7B%22op%22%3A%22Parse%20IPv6%20address%22%2C%22args%22%3A%5B%5D%7D%5D&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy">Parse a Teredo IPv6 address</a></li>
|
||||||
<li><a href="?recipe=%5B%7B%22op%22%3A%22From%20Hexdump%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22Gunzip%22%2C%22args%22%3A%5B%5D%7D%5D&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu%2Fy7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb%2F3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
|
<li><a href="#recipe=%5B%7B%22op%22%3A%22From%20Hexdump%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22Gunzip%22%2C%22args%22%3A%5B%5D%7D%5D&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu%2Fy7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb%2F3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
|
||||||
<li><a href="?recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22From%20UNIX%20Timestamp%22%2C%22args%22%3A%5B%22Seconds%20(s)%22%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
|
<li><a href="#recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22From%20UNIX%20Timestamp%22%2C%22args%22%3A%5B%22Seconds%20(s)%22%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
|
||||||
<li><a href="?recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22Conditional%20Jump%22%2C%22args%22%3A%5B%221%22%2C%222%22%2C%2210%22%5D%7D%2C%7B%22op%22%3A%22To%20Hex%22%2C%22args%22%3A%5B%22Space%22%5D%7D%2C%7B%22op%22%3A%22Return%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22To%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%5D%7D%5D&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA">Carry out different operations on data of different types</a></li>
|
<li><a href="#recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22Conditional%20Jump%22%2C%22args%22%3A%5B%221%22%2C%222%22%2C%2210%22%5D%7D%2C%7B%22op%22%3A%22To%20Hex%22%2C%22args%22%3A%5B%22Space%22%5D%7D%2C%7B%22op%22%3A%22Return%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22To%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%5D%7D%5D&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA">Carry out different operations on data of different types</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
@@ -336,7 +405,7 @@
|
|||||||
<div class="collapse" id="faq-fork">
|
<div class="collapse" id="faq-fork">
|
||||||
<p>Maybe you have 10 timestamps that you want to parse or 16 encoded strings that all have the same key.</p>
|
<p>Maybe you have 10 timestamps that you want to parse or 16 encoded strings that all have the same key.</p>
|
||||||
<p>The 'Fork' operation (found in the 'Flow control' category) splits up the input line by line and runs all subsequent operations on each line separately. Each output is then displayed on a separate line. These delimiters can be changed, so if your inputs are separated by commas, you can change the split delimiter to a comma instead.</p>
|
<p>The 'Fork' operation (found in the 'Flow control' category) splits up the input line by line and runs all subsequent operations on each line separately. Each output is then displayed on a separate line. These delimiters can be changed, so if your inputs are separated by commas, you can change the split delimiter to a comma instead.</p>
|
||||||
<p><a href='?recipe=%5B%7B"op"%3A"Fork"%2C"args"%3A%5B"%5C%5Cn"%2C"%5C%5Cn"%5D%7D%2C%7B"op"%3A"From%20UNIX%20Timestamp"%2C"args"%3A%5B"Seconds%20(s)"%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA%3D%3D'>Click here</a> for an example.</p>
|
<p><a href='#recipe=%5B%7B"op"%3A"Fork"%2C"args"%3A%5B"%5C%5Cn"%2C"%5C%5Cn"%5D%7D%2C%7B"op"%3A"From%20UNIX%20Timestamp"%2C"args"%3A%5B"Seconds%20(s)"%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA%3D%3D'>Click here</a> for an example.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="report-bug">
|
<div role="tabpanel" class="tab-pane" id="report-bug">
|
||||||
@@ -348,21 +417,25 @@
|
|||||||
<a class="btn btn-primary" href="https://github.com/gchq/CyberChef/issues/new" role="button">Raise issue on GitHub</a>
|
<a class="btn btn-primary" href="https://github.com/gchq/CyberChef/issues/new" role="button">Raise issue on GitHub</a>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
|
<div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
|
||||||
<h4>What</h4>
|
<h5><strong>What</strong></h5>
|
||||||
<p>A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.</p>
|
<p>A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.</p><br>
|
||||||
|
|
||||||
<h4>Why</h4>
|
<h5><strong>Why</strong></h5>
|
||||||
<p>Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.</p>
|
<p>Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.</p><br>
|
||||||
|
|
||||||
|
|
||||||
<h4>How</h4>
|
<h5><strong>How</strong></h5>
|
||||||
<p>The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.</p>
|
<p>The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.</p>
|
||||||
<p>For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.</p>
|
<p>For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.</p><br>
|
||||||
|
|
||||||
|
|
||||||
<h4>Who</h4>
|
<h5><strong>Who</strong></h5>
|
||||||
<p>It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.</p>
|
<p>It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.</p><br>
|
||||||
|
|
||||||
|
|
||||||
<h4>Aim</h4>
|
<h5><strong>Aim</strong></h5>
|
||||||
<p>It is hoped that by releasing CyberChef through <a href="https://github.com/gchq/cyberchef">GitHub</a>, contributions can be added which can be rolled out into future versions of the tool.</p>
|
<p>It is hoped that by releasing CyberChef through <a href="https://github.com/gchq/CyberChef">GitHub</a>, contributions can be added which can be rolled out into future versions of the tool.</p><br>
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p>There are around 150 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.</p>
|
<p>There are around 150 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.</p>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// CSS
|
// Styles
|
||||||
import "./css/index.js";
|
import "./stylesheets/index.js";
|
||||||
|
|
||||||
// Libs
|
// Libs
|
||||||
import "babel-polyfill";
|
import "babel-polyfill";
|
||||||
@@ -38,14 +38,15 @@ function main() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
updateUrl : true,
|
updateUrl: true,
|
||||||
showHighlighter : true,
|
showHighlighter: true,
|
||||||
treatAsUtf8 : true,
|
treatAsUtf8: true,
|
||||||
wordWrap : true,
|
wordWrap: true,
|
||||||
showErrors : true,
|
showErrors: true,
|
||||||
errorTimeout : 4000,
|
errorTimeout: 4000,
|
||||||
autoBakeThreshold : 200,
|
autoBakeThreshold: 200,
|
||||||
attemptHighlight : true,
|
attemptHighlight: true,
|
||||||
|
theme: "classic",
|
||||||
};
|
};
|
||||||
|
|
||||||
document.removeEventListener("DOMContentLoaded", main, false);
|
document.removeEventListener("DOMContentLoaded", main, false);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
ga('create', 'UA-85682716-2', 'auto');
|
ga('create', 'UA-85682716-2', 'auto');
|
||||||
|
|
||||||
// Specifying location.pathname here overrides the default URL which would include arguments.
|
// Specifying location.pathname here overrides the default URL which could include arguments.
|
||||||
// This method prevents Google Analytics from logging any recipe or input data in the URL.
|
// This method prevents Google Analytics from logging any recipe or input data in the URL.
|
||||||
ga('send', 'pageview', location.pathname);
|
ga('send', 'pageview', location.pathname);
|
||||||
|
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
197
src/web/stylesheets/components/_operation.css
Normal file
197
src/web/stylesheets/components/_operation.css
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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";
|
||||||
24
src/web/stylesheets/layout/_banner.css
Normal file
24
src/web/stylesheets/layout/_banner.css
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Banner area styles
|
||||||
|
*
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#banner {
|
||||||
|
position: absolute;
|
||||||
|
height: 30px;
|
||||||
|
width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
border-bottom: 1px solid var(--primary-border-colour);
|
||||||
|
color: var(--banner-font-colour);
|
||||||
|
background-color: var(--banner-bg-colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
#banner img {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
84
src/web/stylesheets/layout/_modals.css
Normal file
84
src/web/stylesheets/layout/_modals.css
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* 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 label {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
156
src/web/stylesheets/preloader.css
Normal file
156
src/web/stylesheets/preloader.css
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
border: 3px solid transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#preloader:before {
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
right: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
border-top-color: #e74c3c;
|
||||||
|
animation: spin 3s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#preloader:after {
|
||||||
|
top: 13px;
|
||||||
|
left: 13px;
|
||||||
|
right: 13px;
|
||||||
|
bottom: 13px;
|
||||||
|
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); }
|
||||||
228
src/web/stylesheets/utils/_overrides.css
Executable file
228
src/web/stylesheets/utils/_overrides.css
Executable file
@@ -0,0 +1,228 @@
|
|||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default {
|
||||||
|
background-color: var(--primary-border-colour);
|
||||||
|
color: var(--primary-font-colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Sortable */
|
||||||
|
|
||||||
|
.sortable-ghost {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Bootstrap Colorpicker */
|
||||||
|
|
||||||
|
.colorpicker-element {
|
||||||
|
float: left;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorpicker-color,
|
||||||
|
.colorpicker-color div {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
@import "~bootstrap/less/scaffolding.less";
|
@import "~bootstrap/less/scaffolding.less";
|
||||||
@import "~bootstrap/less/type.less";
|
@import "~bootstrap/less/type.less";
|
||||||
@import "~bootstrap/less/code.less";
|
@import "~bootstrap/less/code.less";
|
||||||
// @import "~bootstrap/less/grid.less";
|
@import "~bootstrap/less/grid.less";
|
||||||
@import "~bootstrap/less/tables.less";
|
@import "~bootstrap/less/tables.less";
|
||||||
@import "~bootstrap/less/forms.less";
|
@import "~bootstrap/less/forms.less";
|
||||||
@import "~bootstrap/less/buttons.less";
|
@import "~bootstrap/less/buttons.less";
|
||||||
@@ -55,4 +55,4 @@
|
|||||||
|
|
||||||
// Utility classes
|
// Utility classes
|
||||||
@import "~bootstrap/less/utilities.less";
|
@import "~bootstrap/less/utilities.less";
|
||||||
// @import "~bootstrap/less/responsive-utilities.less";
|
// @import "~bootstrap/less/responsive-utilities.less";
|
||||||
@@ -46,8 +46,7 @@ import Chef from "../src/core/Chef.js";
|
|||||||
{},
|
{},
|
||||||
0,
|
0,
|
||||||
false
|
false
|
||||||
)
|
).then(function(result) {
|
||||||
.then(function(result) {
|
|
||||||
const ret = {
|
const ret = {
|
||||||
test: test,
|
test: test,
|
||||||
status: null,
|
status: null,
|
||||||
|
|||||||
@@ -12,13 +12,18 @@ import "babel-polyfill";
|
|||||||
|
|
||||||
import TestRegister from "./TestRegister.js";
|
import TestRegister from "./TestRegister.js";
|
||||||
import "./tests/operations/Base58.js";
|
import "./tests/operations/Base58.js";
|
||||||
|
import "./tests/operations/BCD.js";
|
||||||
import "./tests/operations/ByteRepr.js";
|
import "./tests/operations/ByteRepr.js";
|
||||||
|
import "./tests/operations/CharEnc.js";
|
||||||
|
import "./tests/operations/Cipher.js";
|
||||||
import "./tests/operations/Code.js";
|
import "./tests/operations/Code.js";
|
||||||
import "./tests/operations/Compress.js";
|
import "./tests/operations/Compress.js";
|
||||||
|
import "./tests/operations/DateTime.js";
|
||||||
import "./tests/operations/FlowControl.js";
|
import "./tests/operations/FlowControl.js";
|
||||||
import "./tests/operations/Image.js";
|
import "./tests/operations/Image.js";
|
||||||
import "./tests/operations/MorseCode.js";
|
import "./tests/operations/MorseCode.js";
|
||||||
import "./tests/operations/StrUtils.js";
|
import "./tests/operations/StrUtils.js";
|
||||||
|
import "./tests/operations/SeqUtils.js";
|
||||||
|
|
||||||
let allTestsPassing = true;
|
let allTestsPassing = true;
|
||||||
const testStatusCounts = {
|
const testStatusCounts = {
|
||||||
@@ -75,7 +80,7 @@ function handleTestResult(testResult) {
|
|||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
console.log("Tests took longer than 10 seconds to run, returning.");
|
console.log("Tests took longer than 10 seconds to run, returning.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}, 1 * 1000);
|
}, 10 * 1000);
|
||||||
|
|
||||||
|
|
||||||
TestRegister.runTests()
|
TestRegister.runTests()
|
||||||
|
|||||||
103
test/tests/operations/BCD.js
Normal file
103
test/tests/operations/BCD.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* BCD tests
|
||||||
|
*
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../TestRegister.js";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "To BCD: default 0",
|
||||||
|
input: "0",
|
||||||
|
expectedOutput: "0000",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "To BCD",
|
||||||
|
"args": ["8 4 2 1", true, false, "Nibbles"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "To BCD: unpacked nibbles",
|
||||||
|
input: "1234567890",
|
||||||
|
expectedOutput: "0000 0001 0000 0010 0000 0011 0000 0100 0000 0101 0000 0110 0000 0111 0000 1000 0000 1001 0000 0000",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "To BCD",
|
||||||
|
"args": ["8 4 2 1", false, false, "Nibbles"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "To BCD: packed, signed bytes",
|
||||||
|
input: "1234567890",
|
||||||
|
expectedOutput: "00000001 00100011 01000101 01100111 10001001 00001100",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "To BCD",
|
||||||
|
"args": ["8 4 2 1", true, true, "Bytes"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "To BCD: packed, signed nibbles, 8 4 -2 -1",
|
||||||
|
input: "-1234567890",
|
||||||
|
expectedOutput: "0000 0111 0110 0101 0100 1011 1010 1001 1000 1111 0000 1101",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "To BCD",
|
||||||
|
"args": ["8 4 -2 -1", true, true, "Nibbles"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "From BCD: default 0",
|
||||||
|
input: "0000",
|
||||||
|
expectedOutput: "0",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From BCD",
|
||||||
|
"args": ["8 4 2 1", true, false, "Nibbles"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "From BCD: packed, signed bytes",
|
||||||
|
input: "00000001 00100011 01000101 01100111 10001001 00001101",
|
||||||
|
expectedOutput: "-1234567890",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From BCD",
|
||||||
|
"args": ["8 4 2 1", true, true, "Bytes"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "From BCD: Excess-3, unpacked, unsigned",
|
||||||
|
input: "00000100 00000101 00000110 00000111 00001000 00001001 00001010 00001011 00001100 00000011",
|
||||||
|
expectedOutput: "1234567890",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From BCD",
|
||||||
|
"args": ["Excess-3", false, false, "Nibbles"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "BCD: raw 4 2 2 1, packed, signed",
|
||||||
|
input: "1234567890",
|
||||||
|
expectedOutput: "1234567890",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "To BCD",
|
||||||
|
"args": ["4 2 2 1", true, true, "Raw"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "From BCD",
|
||||||
|
"args": ["4 2 2 1", true, true, "Raw"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* ByteRepr tests.
|
* ByteRepr tests.
|
||||||
*
|
*
|
||||||
* @author Matt C [matt@artemisbot.pw]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @copyright Crown Copyright 2017
|
* @copyright Crown Copyright 2017
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|||||||
90
test/tests/operations/CharEnc.js
Normal file
90
test/tests/operations/CharEnc.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* CharEnc tests.
|
||||||
|
*
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../TestRegister.js";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Encode text, Decode text: nothing",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Encode text",
|
||||||
|
"args": ["UTF-8 (65001)"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Decode text",
|
||||||
|
"args": ["UTF-8 (65001)"]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Encode text, Decode text: hello",
|
||||||
|
input: "hello",
|
||||||
|
expectedOutput: "hello",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Encode text",
|
||||||
|
"args": ["UTF-8 (65001)"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Decode text",
|
||||||
|
"args": ["UTF-8 (65001)"]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Encode text (EBCDIC): hello",
|
||||||
|
input: "hello",
|
||||||
|
expectedOutput: "88 85 93 93 96",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Encode text",
|
||||||
|
"args": ["IBM EBCDIC International (500)"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "To Hex",
|
||||||
|
"args": ["Space"]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Decode text (EBCDIC): 88 85 93 93 96",
|
||||||
|
input: "88 85 93 93 96",
|
||||||
|
expectedOutput: "hello",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From Hex",
|
||||||
|
"args": ["Space"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Decode text",
|
||||||
|
"args": ["IBM EBCDIC International (500)"]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generate Base64 Windows Powershell",
|
||||||
|
input: "ZABpAHIAIAAiAGMAOgBcAHAAcgBvAGcAcgBhAG0AIABmAGkAbABlAHMAIgAgAA==",
|
||||||
|
expectedOutput: "dir \"c:\\program files\" ",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From Base64",
|
||||||
|
"args": ["A-Za-z0-9+/=", true]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Decode text",
|
||||||
|
"args": ["UTF16LE (1200)"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Encode text",
|
||||||
|
"args": ["UTF-8 (65001)"]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
78
test/tests/operations/Cipher.js
Normal file
78
test/tests/operations/Cipher.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* Cipher tests.
|
||||||
|
*
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
*
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../TestRegister.js";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Encode: no input",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Encode",
|
||||||
|
"args": ["nothing"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Encode: no key",
|
||||||
|
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
||||||
|
expectedOutput: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Encode",
|
||||||
|
"args": [""]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Encode: normal",
|
||||||
|
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
||||||
|
expectedOutput: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Encode",
|
||||||
|
"args": ["Schrodinger"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Decode: no input",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Decode",
|
||||||
|
"args": ["nothing"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Decode: no key",
|
||||||
|
input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
|
||||||
|
expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Decode",
|
||||||
|
"args": [""]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Decode: normal",
|
||||||
|
input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
|
||||||
|
expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Decode",
|
||||||
|
"args": ["Schrodinger"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
@@ -14,12 +14,12 @@ TestRegister.addTests([
|
|||||||
expectedOutput: "The cat sat on the mat.",
|
expectedOutput: "The cat sat on the mat.",
|
||||||
recipeConfig: [
|
recipeConfig: [
|
||||||
{
|
{
|
||||||
"op" : "From Hex",
|
"op": "From Hex",
|
||||||
"args" : ["Space"]
|
"args": ["Space"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"op" : "Bzip2 Decompress",
|
"op": "Bzip2 Decompress",
|
||||||
"args" : []
|
"args": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
34
test/tests/operations/DateTime.js
Normal file
34
test/tests/operations/DateTime.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* DateTime tests.
|
||||||
|
*
|
||||||
|
* @author bwhitn [brian.m.whitney@outlook.com]
|
||||||
|
*
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../TestRegister.js";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Filetime to Unix",
|
||||||
|
input: "129207366395297693",
|
||||||
|
expectedOutput: "1276263039529769300",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Windows Filetime to UNIX Timestamp",
|
||||||
|
args: ["Nanoseconds (ns)", "Decimal"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unix to Filetime",
|
||||||
|
input: "1276263039529769300",
|
||||||
|
expectedOutput: "129207366395297693",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "UNIX Timestamp to Windows Filetime",
|
||||||
|
args: ["Nanoseconds (ns)", "Decimal"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
@@ -59,11 +59,11 @@ TestRegister.addTests([
|
|||||||
input: "Some data with a 1 in it\nSome data with a 2 in it",
|
input: "Some data with a 1 in it\nSome data with a 2 in it",
|
||||||
expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n",
|
expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n",
|
||||||
recipeConfig: [
|
recipeConfig: [
|
||||||
{"op":"Fork", "args":["\\n", "\\n", false]},
|
{"op": "Fork", "args": ["\\n", "\\n", false]},
|
||||||
{"op":"Conditional Jump", "args":["1", "2", "10"]},
|
{"op": "Conditional Jump", "args": ["1", "2", "10"]},
|
||||||
{"op":"To Hex", "args":["Space"]},
|
{"op": "To Hex", "args": ["Space"]},
|
||||||
{"op":"Return", "args":[]},
|
{"op": "Return", "args": []},
|
||||||
{"op":"To Base64", "args":["A-Za-z0-9+/="]}
|
{"op": "To Base64", "args": ["A-Za-z0-9+/="]}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
33
test/tests/operations/SeqUtils.js
Normal file
33
test/tests/operations/SeqUtils.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* SeqUtils tests.
|
||||||
|
*
|
||||||
|
* @author Chris van Marle
|
||||||
|
* @copyright Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../TestRegister.js";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "SeqUtils - Numeric sort photos",
|
||||||
|
input: "Photo-1.jpg\nPhoto-4.jpg\nPhoto-2.jpg\nPhoto-3.jpg\n",
|
||||||
|
expectedOutput: "Photo-1.jpg\nPhoto-2.jpg\nPhoto-3.jpg\nPhoto-4.jpg\n",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Sort",
|
||||||
|
"args": ["Line feed", false, "Numeric"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SeqUtils - Numeric sort CVE IDs",
|
||||||
|
input: "CVE-2017-1234,CVE-2017-9999,CVE-2017-10000,CVE-2017-10001,CVE-2017-12345,CVE-2016-1234,CVE-2016-4321,CVE-2016-10000,CVE-2016-9999,CVE-2016-10001",
|
||||||
|
expectedOutput: "CVE-2017-12345,CVE-2017-10001,CVE-2017-10000,CVE-2017-9999,CVE-2017-1234,CVE-2016-10001,CVE-2016-10000,CVE-2016-9999,CVE-2016-4321,CVE-2016-1234",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Sort",
|
||||||
|
"args": ["Comma", true, "Numeric"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
@@ -26,7 +26,7 @@ TestRegister.addTests([
|
|||||||
{
|
{
|
||||||
name: "Diff, basic usage",
|
name: "Diff, basic usage",
|
||||||
input: "testing23\n\ntesting123",
|
input: "testing23\n\ntesting123",
|
||||||
expectedOutput: "testing<span class='hlgreen'>1</span>23",
|
expectedOutput: "testing<span class='hl5'>1</span>23",
|
||||||
recipeConfig: [
|
recipeConfig: [
|
||||||
{
|
{
|
||||||
"op": "Diff",
|
"op": "Diff",
|
||||||
|
|||||||
Reference in New Issue
Block a user