forked from Qortal/qortal-ui
AlphaX-Projects
2 years ago
7 changed files with 247 additions and 25 deletions
@ -0,0 +1,160 @@ |
|||||||
|
// Author: irontiga <[email protected]>
|
||||||
|
|
||||||
|
'use strict' |
||||||
|
import { LitElement, html, css } from 'lit' |
||||||
|
import * as WORDLISTS from './wordlists.js' |
||||||
|
|
||||||
|
class RandomSentenceGenerator extends LitElement { |
||||||
|
static get properties() { |
||||||
|
return { |
||||||
|
template: { |
||||||
|
type: String, |
||||||
|
attribute: 'template' |
||||||
|
}, |
||||||
|
parsedString: { |
||||||
|
type: String |
||||||
|
}, |
||||||
|
fetchedWordlistCount: { |
||||||
|
type: Number, |
||||||
|
value: 0 |
||||||
|
}, |
||||||
|
capitalize: { |
||||||
|
type: Boolean |
||||||
|
}, |
||||||
|
partsOfSpeechMap: { |
||||||
|
type: Object |
||||||
|
}, |
||||||
|
templateEntropy: { |
||||||
|
type: Number, |
||||||
|
reflect: true, |
||||||
|
attribute: 'template-entropy' |
||||||
|
}, |
||||||
|
maxWordLength: { |
||||||
|
type: Number, |
||||||
|
attribute: 'max-word-length' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
constructor() { |
||||||
|
super() |
||||||
|
this.template = 'adjective noun verb adverb.' |
||||||
|
this.maxWordLength = 0 |
||||||
|
this.parsedString = '' |
||||||
|
this.fetchedWordlistCount = 0 |
||||||
|
this.capitalize = true |
||||||
|
this.partsOfSpeechMap = { |
||||||
|
'noun': 'nouns', |
||||||
|
'adverb': 'adverbs', |
||||||
|
'adv': 'adverbs', |
||||||
|
'verb': 'verbs', |
||||||
|
'interjection': 'interjections', |
||||||
|
'adjective': 'adjectives', |
||||||
|
'adj': 'adjectives', |
||||||
|
'verbed': 'verbed' |
||||||
|
} |
||||||
|
this.partsOfSpeech = Object.keys(this.partsOfSpeechMap) |
||||||
|
this._wordlists = WORDLISTS |
||||||
|
} |
||||||
|
|
||||||
|
updated(changedProperties) { |
||||||
|
let regen = false |
||||||
|
if (changedProperties.has('template')) { |
||||||
|
regen = true |
||||||
|
} |
||||||
|
if (changedProperties.has('maxWordLength')) { |
||||||
|
console.dir(this.maxWordLength) |
||||||
|
if (this.maxWordLength) { |
||||||
|
const wl = { ...this._wordlists } |
||||||
|
for (const partOfSpeech in this._wordlists) { |
||||||
|
console.log(this._wordlists[partOfSpeech]) |
||||||
|
if (Array.isArray(this._wordlists[partOfSpeech])) { |
||||||
|
wl[partOfSpeech] = this._wordlists[partOfSpeech].filter(word => word.length <= this.maxWordLength) |
||||||
|
} |
||||||
|
} |
||||||
|
this._wordlists = wl |
||||||
|
} |
||||||
|
regen = true |
||||||
|
} |
||||||
|
if (regen) this.generate() |
||||||
|
} |
||||||
|
|
||||||
|
_RNG(entropy) { |
||||||
|
if (entropy > 1074) { |
||||||
|
throw new Error('Javascript can not handle that much entropy!') |
||||||
|
} |
||||||
|
let randNum = 0 |
||||||
|
const crypto = window.crypto || window.msCrypto |
||||||
|
|
||||||
|
if (crypto) { |
||||||
|
const entropy256 = Math.ceil(entropy / 8) |
||||||
|
|
||||||
|
let buffer = new Uint8Array(entropy256) |
||||||
|
crypto.getRandomValues(buffer) |
||||||
|
|
||||||
|
randNum = buffer.reduce((num, value) => { |
||||||
|
return num * value |
||||||
|
}, 1) / Math.pow(256, entropy256) |
||||||
|
} else { |
||||||
|
console.warn('Secure RNG not found. Using Math.random') |
||||||
|
randNum = Math.random() |
||||||
|
} |
||||||
|
return randNum |
||||||
|
} |
||||||
|
|
||||||
|
setRNG(fn) { |
||||||
|
this._RNG = fn |
||||||
|
} |
||||||
|
|
||||||
|
_captitalize(str) { |
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1) |
||||||
|
} |
||||||
|
|
||||||
|
getWord(partOfSpeech) { |
||||||
|
const words = this._wordlists[this.partsOfSpeechMap[partOfSpeech]] |
||||||
|
const requiredEntropy = Math.log(words.length) / Math.log(2) |
||||||
|
const index = this._RNG(requiredEntropy) * words.length |
||||||
|
|
||||||
|
return { |
||||||
|
word: words[Math.round(index)], |
||||||
|
entropy: words.length |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
generate() { |
||||||
|
this.parsedString = this.parse(this.template) |
||||||
|
} |
||||||
|
|
||||||
|
parse(template) { |
||||||
|
const split = template.split(/[\s]/g) |
||||||
|
let entropy = 1 |
||||||
|
const final = split.map(word => { |
||||||
|
const lower = word.toLowerCase() |
||||||
|
|
||||||
|
this.partsOfSpeech.some(partOfSpeech => { |
||||||
|
const partOfSpeechIndex = lower.indexOf(partOfSpeech) // Check it exists
|
||||||
|
const nextChar = word.charAt(partOfSpeech.length) |
||||||
|
|
||||||
|
if (partOfSpeechIndex === 0 && !(nextChar && (nextChar.match(/[a-zA-Z]/g) != null))) { |
||||||
|
const replacement = this.getWord(partOfSpeech) |
||||||
|
word = replacement.word + word.slice(partOfSpeech.length) // Append the rest of the "word" (punctuation)
|
||||||
|
entropy = entropy * replacement.entropy |
||||||
|
return true |
||||||
|
} |
||||||
|
}) |
||||||
|
return word |
||||||
|
}) |
||||||
|
this.templateEntropy = Math.floor(Math.log(entropy) / Math.log(8)) |
||||||
|
return final.join(' ') |
||||||
|
} |
||||||
|
|
||||||
|
render() { |
||||||
|
return html` |
||||||
|
${this.parsedString} |
||||||
|
` |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
customElements.define('random-sentence-generator', RandomSentenceGenerator) |
||||||
|
|
||||||
|
export default RandomSentenceGenerator |
@ -0,0 +1,36 @@ |
|||||||
|
// Sourced from https://gist.github.com/letsgetrandy/1e05a68ea74ba6736eb5
|
||||||
|
|
||||||
|
export const EXCEPTIONS = { |
||||||
|
'are': 'were', |
||||||
|
'eat': 'ate', |
||||||
|
'go': 'went', |
||||||
|
'have': 'had', |
||||||
|
'inherit': 'inherited', |
||||||
|
'is': 'was', |
||||||
|
'run': 'ran', |
||||||
|
'sit': 'sat', |
||||||
|
'visit': 'visited' |
||||||
|
} |
||||||
|
|
||||||
|
export const getPastTense = (verb, exceptions = EXCEPTIONS) => { |
||||||
|
if (exceptions[verb]) { |
||||||
|
return exceptions[verb] |
||||||
|
} |
||||||
|
if ((/e$/i).test(verb)) { |
||||||
|
return verb + 'd' |
||||||
|
} |
||||||
|
if ((/[aeiou]c$/i).test(verb)) { |
||||||
|
return verb + 'ked' |
||||||
|
} |
||||||
|
// for american english only
|
||||||
|
if ((/el$/i).test(verb)) { |
||||||
|
return verb + 'ed' |
||||||
|
} |
||||||
|
if ((/[aeio][aeiou][dlmnprst]$/).test(verb)) { |
||||||
|
return verb + 'ed' |
||||||
|
} |
||||||
|
if ((/[aeiou][bdglmnprst]$/i).test(verb)) { |
||||||
|
return verb.replace(/(.+[aeiou])([bdglmnprst])/, '$1$2$2ed') |
||||||
|
} |
||||||
|
return verb + 'ed' |
||||||
|
} |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue