function RandomTextGenerator(settings) { Object.assign(this, { tries: 80, safeMode: true, forceCombiningOrigins: false, minLength: 1, maxLength: 400, deepness: 40, trust: 2, weightsLeft: {}, weightsRight: {}, splitter: "", startingCharacter: String.fromCharCode(2), endingCharacter: String.fromCharCode(3), }); Object.assign(this, settings); } RandomTextGenerator.prototype._exampleIterator=function(example, func) { for (let i=0; i{ if (weights[origin] == undefined) weights[origin]={}; if (weights[origin][from] == undefined) weights[origin][from]={}; if (weights[origin][from][to] == undefined) weights[origin][from][to]=0; weights[origin][from][to]+=multiplier; }); }; RandomTextGenerator.prototype._forget=function(weights, example, origin, multiplier) { this._exampleIterator(example, (from, to)=>{ if (weights[origin][from] == undefined) weights[origin][from]={}; if (weights[origin][from][to] == undefined) weights[origin][from][to]=0; weights[origin][from][to]-=multiplier; if (weights[origin][from][to] <= 0) delete weights[origin][from][to]; if (Object.keys(weights[origin][from]).length <= 0) delete weights[origin][from]; if (Object.keys(weights[origin]).length <= 0) delete weights[origin]; }); }; RandomTextGenerator.prototype.learnLeft=function(example, origin, multiplier, isRaw) { this._learn( this.weightsLeft, [...(isRaw)?(""):(this.endingCharacter), ...example, ...(isRaw)?(""):(this.startingCharacter)].reverse(), origin || "_default", (multiplier != null)?(multiplier):(1), ); }; RandomTextGenerator.prototype.learnBoth=function(example, origin, multiplier, isRaw) { this._learn( this.weightsLeft, [...(isRaw)?(""):(this.endingCharacter), ...example, ...(isRaw)?(""):(this.startingCharacter)].reverse(), origin || "_default", (multiplier != null)?(multiplier):(1), ); this._learn( this.weightsRight, [...(isRaw)?(""):(this.startingCharacter), ...example, ...(isRaw)?(""):(this.endingCharacter)], origin || "_default", (multiplier != null)?(multiplier):(1), ); }; RandomTextGenerator.prototype.learnRight=function(example, origin, multiplier, isRaw) { this._learn( this.weightsRight, [...(isRaw)?(""):(this.startingCharacter), ...example, ...(isRaw)?(""):(this.endingCharacter)], origin || "_default", (multiplier != null)?(multiplier):(1), ); }; RandomTextGenerator.prototype.forgetBoth=function(example, origin, multiplier, isRaw) { this._forget( this.weightsLeft, [...(isRaw)?(""):(this.endingCharacter), ...example, ...(isRaw)?(""):(this.startingCharacter)].reverse(), origin || "_default", (multiplier != null)?(multiplier):(1), ); this._forget( this.weightsRight, [...(isRaw)?(""):(this.startingCharacter), ...example, ...(isRaw)?(""):(this.endingCharacter)], origin || "_default", (multiplier != null)?(multiplier):(1), ); }; RandomTextGenerator.prototype.forgetLeft=function(example, origin, multiplier, isRaw) { this._forget( this.weightsLeft, [...(isRaw)?(""):(this.endingCharacter), ...example, ...(isRaw)?(""):(this.startingCharacter)].reverse(), origin || "_default", (multiplier != null)?(multiplier):(1), ); }; RandomTextGenerator.prototype.forgetRight=function(example, origin, multiplier, isRaw) { this._forget( this.weightsRight, [...(isRaw)?(""):(this.startingCharacter), ...example, ...(isRaw)?(""):(this.endingCharacter)], origin || "_default", (multiplier != null)?(multiplier):(1), ); }; RandomTextGenerator.prototype._getNexts=function(weights, text, origins, safe) { let nexts={}; let sum=0; let from=text; for (let origin of origins) { if (!weights[origin]) continue; let weightsRow=weights[origin][from]; if (weightsRow) { for (let to of Object.keys(weightsRow)) { if (!nexts[to]) nexts[to]=0; sum+=weightsRow[to]; nexts[to]+=weightsRow[to]; } } else if (!safe && this.forceCombiningOrigins) return {}; } if (!safe && sum < this.trust) return {}; for (let to of Object.keys(nexts)) nexts[to]/=sum; return nexts; }; RandomTextGenerator.prototype._chooseNext=function(nexts, pick) { for (let to of Object.keys(nexts)) { pick-=nexts[to]; if (pick < 0) return to; } return null; }; RandomTextGenerator.prototype._predict=function(weights, splittedText, origins, obeyLimit, safe) { let realLength=splittedText.length-(splittedText[0] == this.startingCharacter); if (obeyLimit && realLength > this.maxLength) return null; for (let i=Math.max(0, splittedText.length-this.deepness); i{ splittedText=[...(isRaw)?(""):(this.startingCharacter), ...text]; realLength=splittedText.length-!isRaw; }; reset(); if (realLength >= this.maxLength) return splittedText.slice(!isRaw).join(this.splitter); for (let i=0; i this.maxLength) { reset(); break; } splittedText.push(character); ++realLength; } } return null; }; RandomTextGenerator.prototype.generateBoth=function(text, origins) { if (!text) text=""; if (!origins) origins=[...new Set([...Object.keys(this.weightsRight) ,...Object.keys(this.weightsLeft)])]; let splittedText; let leftDone; let rightDone; let reset=()=>{ splittedText=[...text]; leftDone=false; rightDone=false; }; reset(); if (splittedText.length >= this.maxLength) return splittedText.join(this.splitter); for (let i=0; i this.maxLength) { reset(); break; } else return splittedText.join(this.splitter); } if (!leftDone) splittedText.unshift(characterLeft); if (!rightDone) splittedText.push(characterRight); } } return null; }; RandomTextGenerator.prototype._shrink=function(weights, origins) { for (let origin of origins) { if (!weights[origin]) continue; for (let from of Object.keys(weights[origin])) { //console.log(weights); let weightsRow=weights[origin][from]; let sum=0; for (let to of Object.keys(weightsRow)) sum+=weightsRow[to]; if (sum < this.trust) delete weights[origin][from]; } } }; RandomTextGenerator.prototype.shrinkLeft=function(origins) { this._shrink(this.weightsLeft, origins || Object.keys(this.weightsLeft)); }; RandomTextGenerator.prototype.shrinkRight=function(origins) { this._shrink(this.weightsRight, origins || Object.keys(this.weightsRight)); }; RandomTextGenerator.prototype.shrinkBoth=function(origins) { this._shrink(this.weightsLeft, origins || Object.keys(this.weightsLeft)); this._shrink(this.weightsRight, origins || Object.keys(this.weightsRight)); }; RandomTextGenerator.prototype.saveToJson=function() {return JSON.stringify(this);}; RandomTextGenerator.prototype.loadFromJson=function(json) { let settings=JSON.parse(json); Object.keys(generatorSettingsManager).forEach((key)=>{ if (settings[key] != undefined) { generatorSettingsManager[key].validate(key, settings[key], generatorSettingsManager[key].type); this[key]=settings[key]; } }); if (this.minLength > this.maxLength) throw "minLength has to be smaller or equal to maxLength"; }; RandomTextGenerator.prototype.saveWeightsToJson=function() { return JSON.stringify({weightsLeft: this.weightsLeft, weightsRight: this.weightsRight}); }; RandomTextGenerator.prototype.loadWeightsFromJson=function(json) { let weights=JSON.parse(json); this.weightsLeft=weights.weightsLeft; this.weightsRight=weights.weightsRight; }; RandomTextGenerator.prototype.predict=RandomTextGenerator.prototype.predictRight; RandomTextGenerator.prototype.learn=RandomTextGenerator.prototype.learnRight; RandomTextGenerator.prototype.forget=RandomTextGenerator.prototype.forgetRight; RandomTextGenerator.prototype.generate=RandomTextGenerator.prototype.generateRight; RandomTextGenerator.prototype.shrink=RandomTextGenerator.prototype.shrinkBoth; RandomTextGenerator.prototype.generateLeft=function(text, origins, isRaw) { if (!text) text=""; if (!origins) origins=Object.keys(this.weightsLeft); let splittedText; let realLength; let reset=()=>{ splittedText=[...text, ...(isRaw)?(""):(this.startingCharacter)].reverse(); realLength=splittedText.length-!isRaw; }; reset(); if (realLength >= this.maxLength) return splittedText.slice(!isRaw).join(this.splitter); for (let i=0; i this.maxLength) { reset(); break; } splittedText.push(character); ++realLength; } } return null; }; RandomTextGenerator.prototype._validate=function(weights, text, origins) { let sum=0; let all=0; this._exampleIterator(text, (from, to)=>{ let nexts=this._getNexts(weights, from, origins, this.safeMode); if (nexts[to]) ++sum; ++all; }); return sum/all || 0; } RandomTextGenerator.prototype.validateLeft=function(text, origins, isRaw) { if (!text) text=""; if (!origins) origins=Object.keys(this.weightsLeft); return this._validate(this.weightsLeft, [...(isRaw)?(""):(this.endingCharacter), ...text, ...(isRaw)?(""):(this.startingCharacter)].reverse(), origins); }; RandomTextGenerator.prototype.validateRight=function(text, origins, isRaw) { if (!text) text=""; if (!origins) origins=Object.keys(this.weightsRight); return this._validate(this.weightsRight, [...(isRaw)?(""):(this.startingCharacter), ...text, ...(isRaw)?(""):(this.endingCharacter)], origins); }; RandomTextGenerator.prototype.validate=RandomTextGenerator.prototype.validateRight;