Restructured and fixed inliner.

This commit is contained in:
n1474335 2017-03-27 16:08:36 +01:00
parent d37bc4ab08
commit 97d41fd50a
24 changed files with 378 additions and 5720 deletions

View File

@ -1,5 +1,7 @@
var webpack = require("webpack"), var webpack = require("webpack"),
ExtractTextPlugin = require("extract-text-webpack-plugin"); ExtractTextPlugin = require("extract-text-webpack-plugin"),
HtmlWebpackPlugin = require("html-webpack-plugin"),
Inliner = require("web-resource-inliner");
module.exports = function (grunt) { module.exports = function (grunt) {
grunt.file.defaultEncoding = "utf8"; grunt.file.defaultEncoding = "utf8";
@ -8,7 +10,7 @@ module.exports = function (grunt) {
// Tasks // Tasks
grunt.registerTask("dev", grunt.registerTask("dev",
"A persistent task which creates a development build whenever source files are modified.", "A persistent task which creates a development build whenever source files are modified.",
["clean:dev", "copy:htmlDev", "copy:staticDev", "chmod:build", "webpack:webDev", "watch"]); ["clean:dev", "webpack:webDev"]);
grunt.registerTask("node", grunt.registerTask("node",
"Compiles CyberChef into a single NodeJS module.", "Compiles CyberChef into a single NodeJS module.",
@ -16,17 +18,16 @@ module.exports = function (grunt) {
grunt.registerTask("test", grunt.registerTask("test",
"A task which runs all the tests in test/tests.", "A task which runs all the tests in test/tests.",
["clean:test", "webpack:tests", "chmod:build", "execute:test"]); ["clean:test", "webpack:tests", "execute:test"]);
grunt.registerTask("prod",
"Creates a production-ready build. Use the --msg flag to add a compile message.",
["eslint", "test", "exec:stats", "clean", "jsdoc", "webpack:webProd", "copy:htmlDev", "copy:htmlProd", "copy:htmlInline",
"copy:staticDev", "copy:staticProd", "cssmin", "inline", "htmlmin", "chmod"]);
grunt.registerTask("docs", grunt.registerTask("docs",
"Compiles documentation in the /docs directory.", "Compiles documentation in the /docs directory.",
["clean:docs", "jsdoc", "chmod:docs"]); ["clean:docs", "jsdoc", "chmod:docs"]);
grunt.registerTask("prod",
"Creates a production-ready build. Use the --msg flag to add a compile message.",
["eslint", "test", "clean:prod", "clean:docs", "jsdoc", "exec:stats", "webpack:webProd", "inline", "chmod"]);
grunt.registerTask("stats", grunt.registerTask("stats",
"Provides statistics about the code base such as how many lines there are as well as details of file sizes before and after compression.", "Provides statistics about the code base such as how many lines there are as well as details of file sizes before and after compression.",
["webpack:webDev", "webpack:webProd", "exec:stats", "exec:repoSize", "exec:displayStats"]); ["webpack:webDev", "webpack:webProd", "exec:stats", "exec:repoSize", "exec:displayStats"]);
@ -39,6 +40,10 @@ module.exports = function (grunt) {
"Lints the code base and shows stats", "Lints the code base and shows stats",
["eslint", "exec:stats", "exec:displayStats"]); ["eslint", "exec:stats", "exec:displayStats"]);
grunt.registerTask("inline",
"Compiles a production build of CyberChef into a single, portable web page.",
runInliner);
grunt.registerTask("doc", "docs"); grunt.registerTask("doc", "docs");
grunt.registerTask("tests", "test"); grunt.registerTask("tests", "test");
grunt.registerTask("lint", "eslint"); grunt.registerTask("lint", "eslint");
@ -46,20 +51,18 @@ module.exports = function (grunt) {
// Load tasks provided by each plugin // Load tasks provided by each plugin
grunt.loadNpmTasks("grunt-eslint"); grunt.loadNpmTasks("grunt-eslint");
grunt.loadNpmTasks("grunt-webpack");
grunt.loadNpmTasks("grunt-jsdoc"); grunt.loadNpmTasks("grunt-jsdoc");
grunt.loadNpmTasks("grunt-contrib-clean"); grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks("grunt-webpack");
grunt.loadNpmTasks("grunt-contrib-copy"); grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-htmlmin");
grunt.loadNpmTasks("grunt-inline-alt");
grunt.loadNpmTasks("grunt-chmod"); grunt.loadNpmTasks("grunt-chmod");
grunt.loadNpmTasks("grunt-exec"); grunt.loadNpmTasks("grunt-exec");
grunt.loadNpmTasks("grunt-execute"); grunt.loadNpmTasks("grunt-execute");
grunt.loadNpmTasks("grunt-contrib-watch");
// Project configuration
var compileTime = grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC", var compileTime = grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC",
codebaseStats = grunt.file.read("src/web/static/stats.txt").split("\n").join("<br>"),
banner = "/**\n" + banner = "/**\n" +
"* CyberChef - The Cyber Swiss Army Knife\n" + "* CyberChef - The Cyber Swiss Army Knife\n" +
"*\n" + "*\n" +
@ -81,16 +84,39 @@ module.exports = function (grunt) {
"* limitations under the License.\n" + "* limitations under the License.\n" +
"*/\n"; "*/\n";
var templateOptions = { /**
data: { * Compiles a production build of CyberChef into a single, portable web page.
compileTime: compileTime, */
compileMsg: grunt.option("compile-msg") || grunt.option("msg") || "", function runInliner() {
codebaseStats: grunt.file.read("src/web/static/stats.txt").split("\n").join("<br>") var inlinerError = false;
} Inliner.html({
}; relativeTo: "build/prod/",
fileContent: grunt.file.read("build/prod/cyberchef.htm"),
images: true,
svgs: true,
scripts: true,
links: true,
strict: true
}, function(error, result) {
if (error) {
console.log(error);
inlinerError = true;
return false;
}
grunt.file.write("build/prod/cyberchef.htm", result);
});
return !inlinerError;
}
// Project configuration
grunt.initConfig({ grunt.initConfig({
clean: {
dev: ["build/dev/*"],
prod: ["build/prod/*"],
test: ["build/test/*"],
node: ["build/node/*"],
docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
},
eslint: { eslint: {
options: { options: {
configFile: "src/.eslintrc.json" configFile: "src/.eslintrc.json"
@ -116,13 +142,6 @@ module.exports = function (grunt) {
], ],
} }
}, },
clean: {
dev: ["build/dev/*"],
prod: ["build/prod/*"],
test: ["build/test/*"],
node: ["build/node/*"],
docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
},
webpack: { webpack: {
options: { options: {
plugins: [ plugins: [
@ -132,9 +151,9 @@ module.exports = function (grunt) {
moment: "moment-timezone" moment: "moment-timezone"
}), }),
new webpack.BannerPlugin({ new webpack.BannerPlugin({
"banner": banner, banner: banner,
"raw": true, raw: true,
"entryOnly": true entryOnly: true
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
COMPILE_TIME: JSON.stringify(compileTime), COMPILE_TIME: JSON.stringify(compileTime),
@ -148,37 +167,54 @@ module.exports = function (grunt) {
} }
}, },
module: { module: {
loaders: [ rules: [
{ {
test: /\.js$/, test: /\.js$/,
exclude: /node_modules/, exclude: /node_modules/,
loader: "babel-loader?compact=false" loader: "babel-loader?compact=false"
} },
],
rules: [
{ {
test: /\.css$/, test: /\.css$/,
use: ExtractTextPlugin.extract({ use: ExtractTextPlugin.extract({
use: "css-loader" use: "css-loader?minimize"
}) })
}, },
{ {
test: /\.less$/, test: /\.less$/,
use: ExtractTextPlugin.extract({ use: ExtractTextPlugin.extract({
use: [ use: [
{ loader: "css-loader" }, { loader: "css-loader?minimize" },
{ loader: "less-loader" } { loader: "less-loader" }
] ]
}) })
}, },
{ {
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/, test: /\.(ico|eot|ttf|woff|woff2)$/,
loader: "url-loader", loader: "url-loader",
options: { options: {
limit: 10000 limit: 10000
} }
} },
{ // First party images are saved as files to be cached
test: /\.(png|jpg|gif|svg)$/,
exclude: /node_modules/,
loader: "file-loader",
options: {
name: "images/[name].[ext]"
}
},
{ // Third party images are inlined
test: /\.(png|jpg|gif|svg)$/,
exclude: /web\/static/,
loader: "url-loader",
options: {
limit: 10000
}
},
] ]
},
stats: {
children: false
} }
}, },
webDev: { webDev: {
@ -187,7 +223,16 @@ module.exports = function (grunt) {
output: { output: {
filename: "scripts.js", filename: "scripts.js",
path: "build/dev" path: "build/dev"
} },
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "./src/web/html/index.html",
compileTime: compileTime,
codebaseStats: codebaseStats
})
],
watch: true
}, },
webProd: { webProd: {
target: "web", target: "web",
@ -206,8 +251,66 @@ module.exports = function (grunt) {
}, },
comments: false, comments: false,
}), }),
new HtmlWebpackPlugin({ // Main version
filename: "index.html",
template: "./src/web/html/index.html",
compileTime: compileTime,
codebaseStats: codebaseStats,
minify: {
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true
}
}),
new HtmlWebpackPlugin({ // Inline version
filename: "cyberchef.htm",
template: "./src/web/html/index.html",
compileTime: compileTime,
codebaseStats: codebaseStats,
inline: true,
minify: {
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true
}
}),
] ]
}, },
// webInline: {
// target: "web",
// entry: "./src/web/index.js",
// output: {
// filename: "scripts.js",
// path: "build/prod"
// },
// plugins: [
// new webpack.optimize.UglifyJsPlugin({
// compress: {
// "screw_ie8": true,
// "dead_code": true,
// "unused": true,
// "warnings": false
// },
// comments: false,
// }),
// new HtmlWebpackPlugin({
// filename: "cyberchef.htm",
// template: "./src/web/html/index.html",
// compileTime: compileTime,
// codebaseStats: codebaseStats,
// inline: true,
// minify: {
// removeComments: true,
// collapseWhitespace: true,
// minifyJS: true,
// minifyCSS: true
// }
// }),
// new StyleExtHtmlWebpackPlugin()
// ]
// },
tests: { tests: {
target: "node", target: "node",
entry: "./test/index.js", entry: "./test/index.js",
@ -228,134 +331,37 @@ module.exports = function (grunt) {
} }
}, },
copy: { copy: {
htmlDev: {
options: {
process: function (content, srcpath) {
return grunt.template.process(content, templateOptions);
}
},
src: "src/web/html/index.html",
dest: "build/dev/index.html"
},
htmlProd: {
options: {
process: function (content, srcpath) {
return grunt.template.process(content, templateOptions);
}
},
src: "src/web/html/index.html",
dest: "build/prod/index.html"
},
htmlInline: {
options: {
process: function (content, srcpath) {
// TODO: Do all this in Jade
content = content.replace(
'<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="images/download-24x24.png" /></a>',
'<span style="float: left; margin-left: 10px;">Compile time: ' + grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC</span>");
return grunt.template.process(content, templateOptions);
}
},
src: "src/web/html/index.html",
dest: "build/prod/cyberchef.htm"
},
staticDev: {
files: [
{
expand: true,
cwd: "src/web/static/",
src: [
"**/*",
"**/.*",
"!stats.txt",
"!ga.html"
],
dest: "build/dev/"
}
]
},
staticProd: {
files: [
{
expand: true,
cwd: "src/web/static/",
src: [
"**/*",
"**/.*",
"!stats.txt",
"!ga.html"
],
dest: "build/prod/"
}
]
},
ghPages: { ghPages: {
options: { options: {
process: function (content, srcpath) { process: function (content, srcpath) {
// Add Google Analytics code to index.html // Add Google Analytics code to index.html
content = content.replace("</body></html>", content = content.replace("</body></html>",
grunt.file.read("src/static/ga.html") + "</body></html>"); grunt.file.read("src/static/ga.html") + "</body></html>");
return grunt.template.process(content, templateOptions); return grunt.template.process(content);
} }
}, },
src: "build/prod/index.html", src: "build/prod/index.html",
dest: "build/prod/index.html" dest: "build/prod/index.html"
} }
}, },
cssmin: { // inline: {
prod: { // options: {
src: "build/dev/styles.css", // tag: "",
dest: "build/prod/styles.css" // inlineTagAttributes: {
} // js: "type='application/javascript'",
}, // css: "type='text/css'"
htmlmin: { // }
prod: { // },
options: { // compiled: {
removeComments: true, // src: "build/prod/cyberchef.htm"
collapseWhitespace: true, // }
minifyJS: true, // },
minifyCSS: true
},
src: "build/prod/index.html",
dest: "build/prod/index.html"
},
inline: {
options: {
removeComments: true,
collapseWhitespace: true,
minifyJS: false,
minifyCSS: false
},
src: "build/prod/cyberchef.htm",
dest: "build/prod/cyberchef.htm"
}
},
inline: {
options: {
tag: "",
inlineTagAttributes: {
js: "type='application/javascript'",
css: "type='text/css'"
}
},
compiled: {
src: "build/prod/cyberchef.htm",
dest: "build/prod/cyberchef.htm"
},
prod: {
options: {
tag: "__inline"
},
src: "build/prod/index.html",
dest: "build/prod/index.html"
}
},
chmod: { chmod: {
build: { build: {
options: { options: {
mode: "755", mode: "755",
}, },
src: ["build/**/*", "build/**/.htaccess", "build/"] src: ["build/**/*", "build/"]
}, },
docs: { docs: {
options: { options: {
@ -412,28 +418,6 @@ module.exports = function (grunt) {
execute: { execute: {
test: "build/test/index.js" test: "build/test/index.js"
}, },
watch: {
css: {
files: ["src/web/css/**/*.css", "src/web/css/**/*.less"],
tasks: ["webpack:webDev", "chmod:build"]
},
js: {
files: "src/**/*.js",
tasks: ["webpack:webDev", "chmod:build"]
},
html: {
files: "src/web/html/**/*.html",
tasks: ["copy:htmlDev", "chmod:build"]
},
static: {
files: ["src/web/static/**/*", "src/web/static/**/.*"],
tasks: ["copy:staticDev", "chmod:build"]
},
grunt: {
files: "Gruntfile.js",
tasks: ["clean:dev", "webpack:webDev", "copy:htmlDev", "copy:staticDev", "chmod:build"]
}
},
}); });
}; };

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -38,23 +38,19 @@
"grunt-chmod": "~1.1.1", "grunt-chmod": "~1.1.1",
"grunt-contrib-clean": "~1.0.0", "grunt-contrib-clean": "~1.0.0",
"grunt-contrib-copy": "~1.0.0", "grunt-contrib-copy": "~1.0.0",
"grunt-contrib-cssmin": "~1.0.2",
"grunt-contrib-htmlmin": "~2.0.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-eslint": "^19.0.0", "grunt-eslint": "^19.0.0",
"grunt-exec": "~1.0.1", "grunt-exec": "~1.0.1",
"grunt-execute": "^0.2.2", "grunt-execute": "^0.2.2",
"grunt-inline-alt": "~0.3.10",
"grunt-jsdoc": "^2.1.0", "grunt-jsdoc": "^2.1.0",
"grunt-webpack": "^2.0.1", "grunt-webpack": "^2.0.1",
"import-loader": "^1.0.1", "html-webpack-plugin": "^2.28.0",
"imports-loader": "^0.7.1", "imports-loader": "^0.7.1",
"ink-docstrap": "^1.1.4", "ink-docstrap": "^1.1.4",
"less": "^2.7.2", "less": "^2.7.2",
"less-loader": "^4.0.2", "less-loader": "^4.0.2",
"phantomjs-prebuilt": "^2.1.14",
"style-loader": "^0.15.0", "style-loader": "^0.15.0",
"url-loader": "^0.5.8", "url-loader": "^0.5.8",
"web-resource-inliner": "^4.1.0",
"webpack": "^2.2.1" "webpack": "^2.2.1"
}, },
"dependencies": { "dependencies": {

View File

@ -29,18 +29,21 @@
<meta name="description" content="The Cyber Swiss Army Knife" /> <meta name="description" content="The Cyber Swiss Army Knife" />
<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/png" href="images/favicon.ico?__inline" /> <link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
<link href="styles.css" rel="stylesheet" />
</head> </head>
<body> <body>
<span id="edit-favourites" class="btn btn-default btn-sm"><img src="images/favourite-16x16.png" /> Edit</span> <span id="edit-favourites" class="btn btn-default btn-sm"><img src="<%- require('../static/images/favourite-16x16.png') %>" /> Edit</span>
<div id="alert" class="alert alert-danger"> <div id="alert" class="alert alert-danger">
<button type="button" class="close" id="alert-close">&times;</button> <button type="button" class="close" id="alert-close">&times;</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" class="green">
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="images/download-24x24.png" /></a> <% if (htmlWebpackPlugin.options.inline) { %>
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
<% } else { %>
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="<%- require('../static/images/download-24x24.png') %>" /></a>
<% } %>
<span id="notice"> <span id="notice">
<script type="text/javascript"> <script type="text/javascript">
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it... // Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
@ -51,8 +54,8 @@
</script> </script>
<noscript>JavaScript is not enabled. Good luck.</noscript> <noscript>JavaScript is not enabled. Good luck.</noscript>
</span> </span>
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img src="images/help-22x22.png" /></a> <a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img src="<%- require('../static/images/help-22x22.png') %>" /></a>
<a href="#" id="options" class="banner-right">Options<img src="images/settings-22x22.png" /></a> <a href="#" id="options" class="banner-right">Options<img src="<%- require('../static/images/settings-22x22.png') %>" /></a>
</div> </div>
<div id="wrapper"> <div id="wrapper">
<div id="operations" class="split split-horizontal no-select"> <div id="operations" class="split split-horizontal no-select">
@ -70,7 +73,7 @@
<div id="operational-controls"> <div id="operational-controls">
<div id="bake-group"> <div id="bake-group">
<button type="button" class="btn btn-success btn-lg" id="bake"> <button type="button" class="btn btn-success btn-lg" id="bake">
<img src="images/cook_male-32x32.png" /> <img src="<%- require('../static/images/cook_male-32x32.png') %>" />
Bake! Bake!
</button> </button>
<label class="btn btn-success btn-lg" id="auto-bake-label"> <label class="btn btn-success btn-lg" id="auto-bake-label">
@ -80,15 +83,15 @@
</div> </div>
<div class="btn-group" style="padding-top: 10px;"> <div class="btn-group" style="padding-top: 10px;">
<button type="button" class="btn btn-default" id="step"><img src="images/step-16x16.png" /> Step through</button> <button type="button" class="btn btn-default" id="step"><img src="<%- require('../static/images/step-16x16.png') %>" /> Step through</button>
<button type="button" class="btn btn-default" id="clr-breaks"><img src="images/erase-16x16.png" /> Clear breakpoints</button> <button type="button" class="btn btn-default" id="clr-breaks"><img src="<%- require('../static/images/erase-16x16.png') %>" /> Clear breakpoints</button>
</div> </div>
</div> </div>
<div class="btn-group-vertical" id="extra-controls"> <div class="btn-group-vertical" id="extra-controls">
<button type="button" class="btn btn-default" id="save"><img src="images/save-16x16.png" /> Save recipe</button> <button type="button" class="btn btn-default" id="save"><img src="<%- require('../static/images/save-16x16.png') %>" /> Save recipe</button>
<button type="button" class="btn btn-default" id="load"><img src="images/open_yellow-16x16.png" /> Load recipe</button> <button type="button" class="btn btn-default" id="load"><img src="<%- require('../static/images/open_yellow-16x16.png') %>" /> Load recipe</button>
<button type="button" class="btn btn-default" id="clr-recipe"><img src="images/clean-16x16.png" /> Clear recipe</button> <button type="button" class="btn btn-default" id="clr-recipe"><img src="<%- require('../static/images/clean-16x16.png') %>" /> Clear recipe</button>
</div> </div>
</div> </div>
</div> </div>
@ -98,8 +101,8 @@
<div class="title no-select"> <div class="title no-select">
Input Input
<div class="btn-group io-btn-group"> <div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img src="images/recycle-16x16.png" /> Clear I/O</button> <button type="button" class="btn btn-default btn-sm" id="clr-io"><img src="<%- require('../static/images/recycle-16x16.png') %>" /> Clear I/O</button>
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img src="images/layout-16x16.png" /> Reset layout</button> <button type="button" class="btn btn-default btn-sm" id="reset-layout"><img src="<%- require('../static/images/layout-16x16.png') %>" /> Reset layout</button>
</div> </div>
<div class="io-info" id="input-info"></div> <div class="io-info" id="input-info"></div>
<div class="io-info" id="input-selection-info"></div> <div class="io-info" id="input-selection-info"></div>
@ -114,10 +117,10 @@
<div class="title no-select"> <div class="title no-select">
Output Output
<div class="btn-group io-btn-group"> <div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img src="images/save_as-16x16.png" /> Save to file</button> <button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img src="<%- require('../static/images/save_as-16x16.png') %>" /> Save to file</button>
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img src="images/switch-16x16.png" /> Move output to input</button> <button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img src="<%- require('../static/images/switch-16x16.png') %>" /> Move output to input</button>
<button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img src="images/undo-16x16.png" /> Undo</button> <button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img src="<%- require('../static/images/undo-16x16.png') %>" /> Undo</button>
<button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img src="images/maximise-16x16.png" /> Max</button> <button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img src="<%- require('../static/images/maximise-16x16.png') %>" /> Max</button>
</div> </div>
<div class="io-info" id="output-info"></div> <div class="io-info" id="output-info"></div>
<div class="io-info" id="output-selection-info"></div> <div class="io-info" id="output-selection-info"></div>
@ -136,7 +139,7 @@
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<img class="pull-right" src="images/save-22x22.png" /> <img class="pull-right" src="<%- require('../static/images/save-22x22.png') %>" />
<h4 class="modal-title">Save recipe</h4> <h4 class="modal-title">Save recipe</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
@ -171,7 +174,7 @@
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<img class="pull-right" src="images/open_yellow-24x24.png" /> <img class="pull-right" src="<%- require('../static/images/open_yellow-24x24.png') %>" />
<h4 class="modal-title">Load recipe</h4> <h4 class="modal-title">Load recipe</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
@ -196,7 +199,7 @@
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<img class="pull-right" src="images/settings-22x22.png" /> <img class="pull-right" src="<%- require('../static/images/settings-22x22.png') %>" />
<h4 class="modal-title">Options</h4> <h4 class="modal-title">Options</h4>
</div> </div>
<div class="modal-body" id="options-body"> <div class="modal-body" id="options-body">
@ -242,7 +245,7 @@
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<img class="pull-right" src="images/favourite-24x24.png" /> <img class="pull-right" src="<%- require('../static/images/favourite-24x24.png') %>" />
<h4 class="modal-title">Edit Favourites</h4> <h4 class="modal-title">Edit Favourites</h4>
</div> </div>
<div class="modal-body" id="options-body"> <div class="modal-body" id="options-body">
@ -269,44 +272,44 @@
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<img class="pull-right" src="images/help-22x22.png" /> <img class="pull-right" src="<%- require('../static/images/help-22x22.png') %>" />
<h4 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h4> <h4 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<img class="about-img-left" src="images/cyberchef-128x128.png" /> <img class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" />
<p class="subtext">Compile time: <%= compileTime %></p> <p class="subtext">Compile time: <%= htmlWebpackPlugin.options.compileTime %></p>
<p>&copy Crown Copyright 2016.</p> <p>&copy Crown Copyright 2016.</p>
<p>Licenced under the Apache Licence, Version 2.0.</p> <p>Licenced under the Apache Licence, Version 2.0.</p>
<br> <br>
<br> <br>
<div> <div>
<ul class='nav nav-tabs' role='tablist'> <ul class="nav nav-tabs" role="tablist">
<li role='presentation' class='active'><a href='#faqs' aria-controls='profile' role='tab' data-toggle='tab'> <li role="presentation" class="active"><a href="#faqs" aria-controls="profile" role="tab" data-toggle="tab">
<img src='images/help-16x16.png' /> <img src="<%- require('../static/images/help-16x16.png') %>" />
FAQs FAQs
</a></li> </a></li>
<li role='presentation'><a href='#report-bug' aria-controls='messages' role='tab' data-toggle='tab'> <li role="presentation"><a href="#report-bug" aria-controls="messages" role="tab" data-toggle="tab">
<img src='images/bug-16x16.png' /> <img src="<%- require('../static/images/bug-16x16.png') %>" />
Report a bug Report a bug
</a></li> </a></li>
<li role='presentation'><a href='#stats' aria-controls='messages' role='tab' data-toggle='tab'> <li role="presentation"><a href="#stats" aria-controls="messages" role="tab" data-toggle="tab">
<img src='images/stats-16x16.png' /> <img src="<%- require('../static/images/stats-16x16.png') %>" />
Stats Stats
</a></li> </a></li>
<li role='presentation'><a href='#about' aria-controls='messages' role='tab' data-toggle='tab'> <li role="presentation"><a href="#about" aria-controls="messages" role="tab" data-toggle="tab">
<img src='images/speech-16x16.png' /> <img src="<%- require('../static/images/speech-16x16.png') %>" />
About About
</a></li> </a></li>
</ul> </ul>
<div class='tab-content'> <div class="tab-content">
<div role='tabpanel' class='tab-pane active' id='faqs'> <div role="tabpanel" class="tab-pane active" id="faqs">
<br> <br>
<blockquote> <blockquote>
<a data-toggle='collapse' data-target='#faq-examples'> <a data-toggle="collapse" data-target="#faq-examples">
What sort of things can I do with CyberChef? What sort of things can I do with CyberChef?
</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 well over 100 operations in CyberChef allowing you to carry 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>
@ -318,39 +321,39 @@
</ul> </ul>
</div> </div>
<blockquote> <blockquote>
<a data-toggle='collapse' data-target='#faq-load-files'> <a data-toggle="collapse" data-target="#faq-load-files">
Can I load input directly from files? Can I load input directly from files?
</a> </a>
</blockquote> </blockquote>
<div class='collapse' id='faq-load-files'> <div class="collapse" id="faq-load-files">
<p>Yes! Just drag your file over the input box and drop it. The contents of the file will be converted into hexadecimal and the 'From Hex' operation will be added to the beginning of the recipe (if it's not already there). This is so that special characters like carriage returns aren't removed by your browser.</p> <p>Yes! Just drag your file over the input box and drop it. The contents of the file will be converted into hexadecimal and the 'From Hex' operation will be added to the beginning of the recipe (if it's not already there). This is so that special characters like carriage returns aren't removed by your browser.</p>
<p>Please note that loading large files is likely to cause a crash. There's not a lot that can be done about this - browsers just aren't very good at handling and displaying large amounts of data.</p> <p>Please note that loading large files is likely to cause a crash. There's not a lot that can be done about this - browsers just aren't very good at handling and displaying large amounts of data.</p>
</div> </div>
<blockquote> <blockquote>
<a data-toggle='collapse' data-target='#faq-fork'> <a data-toggle="collapse" data-target="#faq-fork">
How do I run operation X over multiple inputs at once? How do I run operation X over multiple inputs at once?
</a> </a>
</blockquote> </blockquote>
<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">
<br> <br>
<p>If you find a bug in CyberChef, please raise an issue in our GitHub repository explaining it in as much detail as possible. Copy and include the following information if relevant.</p> <p>If you find a bug in CyberChef, please raise an issue in our GitHub repository explaining it in as much detail as possible. Copy and include the following information if relevant.</p>
<br> <br>
<pre id='report-bug-info'></pre> <pre id="report-bug-info"></pre>
<br> <br>
<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='stats'> <div role="tabpanel" class="tab-pane" id="stats">
<br> <br>
<p>If you're a nerd like me, you might find statistics really fun! Here's some about the CyberChef code base:</p> <p>If you're a nerd like me, you might find statistics really fun! Here's some about the CyberChef code base:</p>
<br><pre><%= codebaseStats %></pre> <br><pre><%= htmlWebpackPlugin.options.codebaseStats %></pre>
</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> <h4>What</h4>
<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>
@ -378,7 +381,7 @@
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div> </div>
<a href="https://github.com/gchq/CyberChef"> <a href="https://github.com/gchq/CyberChef">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="images/fork_me.png" alt="Fork me on GitHub"> <img style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png') %>" alt="Fork me on GitHub">
</a> </a>
</div> </div>
</div> </div>
@ -393,11 +396,11 @@
<div class="modal-body" id="confirm-body"></div> <div class="modal-body" id="confirm-body"></div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-success" id="confirm-yes"> <button type="button" class="btn btn-success" id="confirm-yes">
<img src="images/thumb_up-16x16.png" /> <img src="<%- require('../static/images/thumb_up-16x16.png') %>" />
Yes Yes
</button> </button>
<button type="button" class="btn btn-danger" id="confirm-no" data-dismiss="modal"> <button type="button" class="btn btn-danger" id="confirm-no" data-dismiss="modal">
<img src="images/thumb_down-16x16.png" /> <img src="<%- require('../static/images/thumb_down-16x16.png') %>" />
No No
</button> </button>
</div> </div>
@ -405,6 +408,5 @@
</div> </div>
</div> </div>
<script type="application/javascript" src="scripts.js"></script>
</body> </body>
</html> </html>

View File

@ -1,50 +0,0 @@
# Serve up .htm files as binary files rather than text/html.
# This allows cyberchef.htm to be downloaded rather than opened in the browser.
AddType application/octet-stream .htm
# Fix Apache bug #45023 where "-gzip" is appended to all ETags, preventing 304 responses
<IfModule mod_headers.c>
RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""
</IfModule>
# Set gzip compression on all resources that support it
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
</IfModule>
# Set Expires headers on various resources
<IfModule mod_expires.c>
ExpiresActive On
# 10 minutes
ExpiresDefault "access plus 600 seconds"
# 30 days
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
# 7 days
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 604800 seconds"
ExpiresByType application/javascript "access plus 604800 seconds"
ExpiresByType text/html "access plus 604800 seconds"
</IfModule>
# Set Cache-Control headers on various resources
<IfModule mod_headers.c>
<FilesMatch "\\.(ico|jpe?g|png|gif)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=600, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
<FilesMatch "\\.(x?html?)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
</IfModule>

View File

@ -1,13 +1,13 @@
128 source files 129 source files
49068 lines 49149 lines
1.9M size 1.9M size
63 JavaScript source files 63 JavaScript source files
20841 lines 20966 lines
788K size 788K size
4.7M uncompressed JavaScript size uncompressed JavaScript size
2.6M compressed JavaScript size compressed JavaScript size
15 categories 15 categories
177 operations 177 operations