Commit bf12129c authored by Akari Labs's avatar Akari Labs

populate repo

parent 62648927
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# nanopack build output
build/
\ No newline at end of file
# gltchrr
an artificial text corruption system
\ No newline at end of file
an artificial text corruption system
## to build
run `npm run build`
\ No newline at end of file
/*
nanopack build stub
Copyright 2019 caela akari (lp0)
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.
*/
// TODO: this should become a part of nanopack proper at some point
const fs = require('fs');
const path = require('path');
const nanopack = require('nanopack');
const suffix = '.nanopack.js';
const targetdir = path.join(__dirname, 'scripts');
const builddir = path.join(__dirname, 'build');
if (!fs.existsSync(builddir))
fs.mkdirSync(builddir);
var targets = [];
if (process.argv.length > 2) {
process.argv.forEach(c => {
if (!c.endsWith(suffix)) c = c + suffix;
targets.push(c);
});
targets.shift();
targets.shift();
}
else {
targets = fs.readdirSync(targetdir);
}
targets.forEach(target => {
const tgpath = path.join(__dirname, 'scripts', target);
if (!fs.existsSync(tgpath))
throw new Error(`target "${target}" not found`);
console.log(`building ${target}`);
const params = require(tgpath)();
fs.writeFileSync(path.join(builddir, params.output || `${target}.out.js`), nanopack.build(params));
console.log(`${target} okay`);
});
\ No newline at end of file
module.exports = require('./modules/shared/gltchrr');
\ No newline at end of file
/*
cascade!webpack 1.1
Copyright 2019 astra akari (nocebo)
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.
*/
var _webpack;
const moduleInfo = [];
const replacements = [];
const preCtor = [];
const postCtor = [];
function ctorSearchToFunc(cond) {
if (typeof cond === 'function') return cond;
if (typeof cond === 'string') return info => info.ctor.toString().indexOf(cond) !== -1;
if (Array.isArray(cond)) return info => cond.filter(s => info.ctor.toString().indexOf(s) !== -1).length > 0;
if (cond instanceof RegExp) return info => info.ctor.toString().match(cond);
}
function callbackSearchToFunc(cond) {
if (typeof cond === 'function') return cond;
if (typeof cond === 'string') return info => info.module.exports && ((!!info.module.exports[cond]) || (info.module.exports.default && !!info.module.exports.default[cond]));
if (Array.isArray(cond)) return info => info.module.exports && ((cond.filter(s => info.module.exports[s]).length === cond.length) || (info.module.exports.default && cond.filter(s => info.module.exports.default[s]).length === cond.length));
}
const search = {
byCtor(search) {
const searchFunc = ctorSearchToFunc(search);
return moduleInfo.filter(searchFunc);
},
byCallback(search) {
const searchFunc = callbackSearchToFunc(search);
return moduleInfo.filter(searchFunc);
},
moduleInfo: moduleInfo
};
function cascadeModule(_self, _exports, _require) {
search.require = _require;
}
function exportHook(_self, _exports, _require, _ctor) {
const modinfo = {
ctor: _ctor,
module: _self
};
moduleInfo.push(modinfo);
preCtor.filter(c => c.condition(modinfo)).forEach(c => c.callback(modinfo));
modinfo.ctor(_self, _exports, _require);
postCtor.filter(c => c.condition(modinfo)).forEach(c => c.callback(modinfo));
}
function processModule(mod, i) {
if (!mod) return mod;
var ctorstr = mod.toString();
replacements.forEach(set => {
if (typeof set === 'function') set(ctorstr);
else {
if (
typeof set.search === 'function' ? set.search(ctorstr) :
set.search instanceof RegExp ? ctorstr.match(set.search) :
ctorstr.indexOf(set.search) != -1
) {
console.debug(`patching module ${i} (${set.search})`);
if (typeof set.search === 'function' && typeof set.replace !== 'function')
throw 'function search must have function replace';
ctorstr = typeof set.replace === 'function' ?
set.replace(ctorstr) :
ctorstr.replace(set.search, set.replace);
}
}
});
return (s, e, r) => exportHook(s, e, r, eval(`(${ctorstr})`));
}
function pushHook(mod) {
if (Array.isArray(mod)) {
console.debug(`processing ${mod.length} modules (in array)`);
for (var i in mod) mod[i] = processModule(mod[i], i);
}
else if (typeof mod === 'object') {
var keys = Object.keys(mod);
console.debug(`processing ${keys.length} modules (in object)`);
keys.forEach(i => mod[i] = processModule(mod[i], i));
}
/*else if (typeof mod === 'function') {
console.debug(`processing a module (single)`);
mod = processModule(mod);
}*/
else {
console.warn(`weird type passed to push (${typeof mod}); ignoring it`);
console.debug(mod);
}
return mod;
}
function hookWebpack() {
console.debug('hooking webpackJsonp');
Object.defineProperty(window, 'webpackJsonp', {
get: () => _webpack,
set(webpack) {
_webpack = (x, mod) => webpack(x, pushHook(mod));
setTimeout(() => webpack([9e9, 0], [cascadeModule]), 10);
}
});
}
module.exports = {
search, hookWebpack,
replacements, preCtor, postCtor
};
\ No newline at end of file
const cascade = require('cascade!webpack');
const ui = new (require('gltchrr!ui'))();
const gltchrr = ui.gltchrr;
// install cascade
cascade.hookWebpack();
// hook postStatus
cascade.postCtor.push({
condition: info =>
info.module.exports &&
info.module.exports.default &&
info.module.exports.default.postStatus &&
info.module.exports.default.register,
callback: info => {
const _postStatus = info.module.exports.default.postStatus;
info.module.exports.default.postStatus = e => (e.status = gltchrr.processText(e.status), _postStatus(e));
}
});
// expose the control functions through window.gltchrr
window.gltchrr = ui.gltchrr.control;
window.onload = () => ui.show();
module.exports = {
ui
}
\ No newline at end of file
const _gltchrr = require('gltchrr');
const kwm = require('kwm');
const Window = kwm.Window;
function GltchrrWindow(attr) {
const me = attr.instance;
const gltchrr = me.gltchrr;
const options = attr.options;
const controls = {};
function updateBase(e) {
controls.intesity_echo.innerText = gltchrr.parameters.base = e.target.value / 100;
me.onupdate();
}
function updateDecay(e) {
controls.decay_echo.innerText = gltchrr.parameters.decayTo = e.target.value / 100;
me.onupdate();
}
function updateMode(e) {
gltchrr.state.mode = e.target.value;
me.onupdate();
}
// TODO: bind the radio buttons to the modes provided by gltchrr
return <Window x={options.x || 32} y={options.y || 128} height="320" title="gltchrr">
<label>enabled? <input type="checkbox" checked={gltchrr.state.enabled} onchange={e => { gltchrr.state.enabled = e.target.checked; me.onupdate(); }} /></label><br />
<br />
<label>intensity {controls.intesity_echo = <span style="float: right;">1</span>}
<input type="range" min="0" max="700" value={gltchrr.parameters.base * 100} oninput={updateBase} />
</label><br />
<br />
<label>mode</label><br />
<label><input type="radio" name="mode" value="pass" checked={gltchrr.state.mode === 'pass'} onchange={updateMode} /> default</label><br />
<label><input type="radio" name="mode" value="keymash" checked={gltchrr.state.mode === 'keymash'} onchange={updateMode} /> keymash</label><br />
<label><input type="radio" name="mode" value="meow" checked={gltchrr.state.mode === 'meow'} onchange={updateMode} /> meow</label><br />
<label><input type="radio" name="mode" value="override" checked={gltchrr.state.mode === 'override'} onchange={updateMode} /> override</label><br />
<br />
<label>override text
<input type="text" value={gltchrr.parameters.text} oninput={e => { gltchrr.parameters.text = e.target.value; me.onupdate(); }} />
</label><br />
<br />
<label>decay? <input type="checkbox" checked={gltchrr.state.decay} onchange={e => { gltchrr.state.decay = e.target.checked; me.onupdate(); }} /></label><br />
<label>target intensity {controls.decay_echo = <span style="float: right;">2</span>}
<input type="range" min="0" max="700" value={gltchrr.parameters.decayTo * 100} oninput={updateDecay} />
</label>
</Window>
}
module.exports = function (options) {
options = options || {};``
this.gltchrr = new _gltchrr();
this.onupdate = () => { };
this.show = function () {
if (!this.window) {
kwm.init();
this.window = <GltchrrWindow instance={this} options={options} />
kwm.append(this.window);
}
else {
this.window.style.display = '';
}
};
this.hide = function () {
this.window.style.display = 'none';
};
}
\ No newline at end of file
/*
gltchrr 1.2
an artificial text corruption system
Copyright 2019 caela akari (lp0) and astra akari (nocebo)
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.
changelog:
[ 1.1 (2019-06-16) ]
+ added transformation "garbage" (random insertion of garbage into string)
+ added decay feature
+ added garbage overread feature
~ refactored transformation engine
~ bitrot and garbage generation should not generate any character below 0x20
*/
module.exports = function () {
// base coefficients
const tuning = {
base: 0.4,
slurring: 0.05,
stutter: 0.1,
bitrot: 0.09,
blackout: 0.08 / 16,
garbage: 0.015,
zalgo: 0.7,
overread: 0.3
};
// homerow character pools
const homerow = {
qwerty: 'asdfghjkl ',
azerty: 'qsdfghjklm '
};
// raw parameters
const params = {
base: 1,
varyBy: 0.15,
decayTo: 1.4,
decayExponent: 2,
text: 'meow'
};
// state parameters that shouldnt be exposed
const state = {
enabled: false,
vary: true,
decay: false,
mode: 'pass',
layout: 'azerty'
};
// generate a random character between 0x20 and 0x100
function trashCh() { return String.fromCharCode(Math.floor(0x20 + Math.random() * 0xe0)); }
// preprocessing modes
const preprocess = {
// pass the text as is
pass(msg) {
return msg;
},
// every word in the string is replaced with a different word
meow(msg) {
return msg.replace(/\w+/g, params.text);
},
// the entire input string is discarded and a different string is used instead
override(msg) {
return params.text;
},
// the input string is discarded and a fake keymash string is generated with the same length
keymash(msg) {
state.layout = state.layout in homerow ? state.layout : 'azerty';
const row = homerow[state.layout];
var output = [];
for (var i = 0; i < msg.length; i++) output.push(row[Math.floor(Math.random() * row.length)]);
return output.join('');
}
};
// postprocessing modes
const postprocess = {
// append random garbage data to the end of the string, crudely simulating a buffer overread
overread(msg, intensity) {
if (Math.random() >= intensity) return msg;
const times = 1 + Math.floor(Math.random() * 0x20);
for (var j = 0; j < times; j++) msg += trashCh();
return msg;
}
}
// text transformations
// these are defined in the order they are executed
const transform = {
// remove whitespace characters
slurring(data, intensity, p) {
if (data[p.i] === ' ' && Math.random() < intensity)
data.splice(p.i, 1);
},
// cause characters to repeat as if stuttering
stutter(data, intensity, p) {
if (Math.random() < intensity) {
const times = 1 + Math.floor(Math.random() * 4);
for (var j = 0; j < times; j++)
data.splice(p.i, 0, data[p.i]);
p.i += times + 1;
}
},
// flip bits in characters
bitrot(data, intensity, p) {
if (Math.random() < intensity) {
data[p.i] = String.fromCharCode(Math.max(data[p.i].charCodeAt() ^ (1 << Math.floor(Math.random() * 8)), 0x20));
}
},
// replace random stretches of characters with a full block as if they are missing
blackout(data, intensity, p) {
if (Math.random() < intensity) {
const times = p.i + 1 + Math.floor(Math.random() * 4);
while (p.i < times && p.i < data.length) data[p.i++] = '';
}
},
// insert random junk into the string
garbage(data, intensity, p) {
if (Math.random() < intensity) {
const times = 1 + Math.floor(Math.random() * 0x8);
for (var j = 0; j < times; j++) data.splice(p.i, 0, trashCh());
p.i += times + 1;
}
},
// insert diacritic marks (like zalgo text)
zalgo(data, intensity, p) {
if (Math.random() < intensity) {
const times = p.i + 2 + Math.floor(Math.random() * 6);
while (p.i < times) data.splice(++p.i, 0, String.fromCodePoint(0x300 + Math.floor(Math.random() * 0x4E)));
p.i += times + 1;
}
}
};
// populate params with default coefficients
Object.keys(transform).forEach(k => params[k] = 1);
Object.keys(postprocess).forEach(k => params[k] = 1);
// get a coefficient
function getCoeff(name) {
if (name in params) {
if (name in tuning) return tuning[name] * params[name];
return params[name];
}
}
// used to add some additional randomness
function vary(c) {
const v = params.varyBy;
const floor = 1 - v / 2
return state.vary ? c * ((Math.random() * v) + floor) : c;
}
this.preprocess = preprocess;
this.postprocess = postprocess;
this.transform = transform;
this.parameters = params;
this.processText = function (text) {
if (!state.enabled) return text;
// initial processing (meow/override/whatever)
text = preprocess[state.mode](text);
const base = getCoeff('base');
// apply transformations on text
const data = text.split('');
Object.keys(transform).forEach(k => {
const func = transform[k];
const lparams = { i: 0 }
for (; lparams.i < data.length; lparams.i++) {
const decayC = Math.pow(1 / data.length * lparams.i, params.decayExponent);
const decayStep = state.decay ? ((params.decayTo - base) * decayC) : 0;
const lbase = vary(base + decayStep);
func(data, lbase * getCoeff(k), lparams);
}
});
text = data.join('');
// apply postprocessing
Object.keys(postprocess).forEach(k => text = postprocess[k](text, (state.decay ? params.decayTo : base) * getCoeff(k)));
return text;
};
this.state = state;
this.control = {
// set the overall intensity coefficient
useIntensity(c) { params.base = c; return this; },
// set decay rate
useDecay(c) { state.decay = true; if (c !== undefined) params.decayTo = c; return this; },
dontDecay() { state.decay = false; return this; },
// use qwerty or azerty for keymash mode
useLayoutQWERTY() { state.layout = 'qwerty'; return this; },
useLayoutAZERTY() { state.layout = 'azerty'; return this; },
// default: the input string is passed through the corruption engine like normal
useModeDefault() { state.mode = 'pass'; return this; },
// meow: every word in the string is replaced with a different word
useModeWordReplace(word) { if (!word) word = 'meow'; state.mode = 'meow'; params.text = word; return this; },
// override: the entire input string is discarded and a different string is used instead
useModeOverride(text) { if (!text) text = 'meow'; state.mode = 'override'; params.text = text; return this; },
// keymash: the input string is discarded and a fake keymash string is generated with the same length
useModeKeymash() { state.mode = 'keymash'; return this; },