+ // https://github.com/rigoneri/indefinite-article.js/blob/master/indefinite-article.js
+ if (word.match(/(?!FJO|[HLMNS]Y.|RY[EO]|SQU|(F[LR]?|[HL]|MN?|N|RH?|S[CHKLMNPTVW]?|X(YL)?)[AEIOU])[FHLMNRSX][A-Z]/)) {
+ // Special cases where a word that begins with a vowel should be preceded by 'a'
+ const regexes = [/^e[uw]/, /^onc?e\b/, /^uni([^nmd]|mo)/, /^u[bcfhjkqrst][aeiou]/]
+ return content.replace(/
+ }
+ static isValidEmail(email = "") {
+ return email.toLowerCase().match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)
+ }
+ static capitalizeFirstLetter(str) {
+ return str.charAt(0).toUpperCase() + str.slice(1)
+ }
+ // generate a random alpha numeric hash:
+ static getRandomCharacters(length) {
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ let result = ""
+ for (let i = 0; i < length; i++) {
+ result += characters.charAt(Math.floor(Math.random() * characters.length))
+ }
+ return result
+ }
Changed around line 10621: class TreeUtils {
+ static titleToPermalink(str) {
+ return str
+ .replace(/[\/\_\:\\\[\]]/g, "-")
+ .replace(/π/g, "pi")
+ .replace(/`/g, "tick")
+ .replace(/\$/g, "dollar-sign")
+ .replace(/\*$/g, "-star")
+ .replace(/^\*/g, "star-")
+ .replace(/\*/g, "-star-")
+ .replace(/\'+$/g, "q")
+ .replace(/^@/g, "at-")
+ .replace(/@$/g, "-at")
+ .replace(/@/g, "-at-")
+ .replace(/[\'\"\,\ū]/g, "")
+ .replace(/^\#/g, "sharp-")
+ .replace(/\#$/g, "-sharp")
+ .replace(/\#/g, "-sharp-")
+ .replace(/[\(\)]/g, "")
+ .replace(/\+\+$/g, "pp")
+ .replace(/\+$/g, "p")
+ .replace(/^\!/g, "bang-")
+ .replace(/\!$/g, "-bang")
+ .replace(/\!/g, "-bang-")
+ .replace(/\&/g, "-n-")
+ .replace(/[\+ ]/g, "-")
+ .replace(/[^a-zA-Z0-9\-\.]/g, "")
+ .toLowerCase()
+ }
Changed around line 10661: class TreeUtils {
- matrix.push(TreeUtils.makeVector(cols, fill))
+ matrix.push(Utils.makeVector(cols, fill))
Changed around line 10702: class TreeUtils {
- const randFn = TreeUtils._getPseudoRandom0to1FloatGenerator(seed)
+ const randFn = Utils._getPseudoRandom0to1FloatGenerator(seed)
Changed around line 10711: class TreeUtils {
- return str.length
- ? str
- .toLowerCase()
- .replace(reg, "")
- .replace(/ /g, "-")
- : ""
+ return str.length ? str.toLowerCase().replace(reg, "").replace(/ /g, "-") : ""
Changed around line 10809: class TreeUtils {
- const editDistance = TreeUtils._getEditDistance(str, caseSensitive ? candidate : candidate.toLowerCase(), maximumEditDistanceToBeBestMatch)
+ const editDistance = Utils._getEditDistance(str, caseSensitive ? candidate : candidate.toLowerCase(), maximumEditDistanceToBeBestMatch)
Changed around line 10820: class TreeUtils {
- maxInt = maxInt || maxInt === 0 ? maxInt : TreeUtils.MAX_INT
+ maxInt = maxInt || maxInt === 0 ? maxInt : Utils.MAX_INT
Changed around line 10843: class TreeUtils {
- colMin = TreeUtils.MAX_INT
+ colMin = Utils.MAX_INT
Changed around line 10928: class TreeUtils {
- const randFn = TreeUtils._getPseudoRandom0to1FloatGenerator(seed)
+ const randFn = Utils._getPseudoRandom0to1FloatGenerator(seed)
Changed around line 10939: class TreeUtils {
- const randFn = TreeUtils._getPseudoRandom0to1FloatGenerator(seed)
+ const randFn = Utils._getPseudoRandom0to1FloatGenerator(seed)
Changed around line 10957: class TreeUtils {
- return function() {
+ return function () {
Changed around line 11085: class TreeUtils {
- TreeUtils.Timer = Timer
+ Utils.Timer = Timer
- TreeUtils.linkify = text => {
+ Utils.linkify = (text, target = "_blank") => {
- replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim
- replacedText = text.replace(replacePattern1, '
$1 ')
+ replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z\(\)0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+\(\)&@#\/%=~_|])/gim
+ replacedText = text.replace(replacePattern1, `
$1 `)
- replacedText = replacedText.replace(replacePattern2, '$1
$2 ')
+ replacedText = replacedText.replace(replacePattern2, `$1
$2 `)
- TreeUtils.makeSemiRandomFn = (seed = Date.now()) => {
+ Utils.makeSemiRandomFn = (seed = Date.now()) => {
- TreeUtils.randomUniformInt = (min, max, seed = Date.now()) => {
- return Math.floor(TreeUtils.randomUniformFloat(min, max, seed))
+ Utils.randomUniformInt = (min, max, seed = Date.now()) => {
+ return Math.floor(Utils.randomUniformFloat(min, max, seed))
- TreeUtils.randomUniformFloat = (min, max, seed = Date.now()) => {
- const randFn = TreeUtils.makeSemiRandomFn(seed)
+ Utils.randomUniformFloat = (min, max, seed = Date.now()) => {
+ const randFn = Utils.makeSemiRandomFn(seed)
- TreeUtils.getRange = (startIndex, endIndexExclusive, increment = 1) => {
+ Utils.getRange = (startIndex, endIndexExclusive, increment = 1) => {
- TreeUtils.MAX_INT = Math.pow(2, 32) - 1
- window.TreeUtils = TreeUtils
- class TestRacerTestBlock {
- constructor(testFile, testName, fn) {
- this._parentFile = testFile
- this._testName = testName
- this._testFn = fn
- }
- _emitMessage(message) {
- this._parentFile.getRunner()._emitMessage(message)
- return message
- }
- async execute() {
- let passes = []
- let failures = []
- const assertEqual = (actual, expected, message = "") => {
- if (expected === actual) {
- passes.push(message)
- } else {
- failures.push([actual, expected, message])
- }
- }
- try {
- await this._testFn(assertEqual)
- } catch (err) {
- failures.push([
- "1",
- "0",
- `Should not have uncaught errors but in ${this._testName} got error:
- toString:
- ${new TreeNode(err.toString()).toString(2)}
- stack:
- ${new TreeNode(err.stack).toString(2)}`
- ])
- }
- failures.length ? this._emitBlockFailedMessage(failures) : this._emitBlockPassedMessage(passes)
- return {
- passes,
- failures
- }
- }
- _emitBlockPassedMessage(passes) {
- this._emitMessage(`ok block ${this._testName} - ${passes.length} passed`)
- }
- _emitBlockFailedMessage(failures) {
- // todo: should replace not replace last newline?
- // todo: do side by side.
- // todo: add diff.
- this._emitMessage(`failed block ${this._testName}`)
- this._emitMessage(
- failures
- .map(failure => {
- const actualVal = failure[0] === undefined ? "undefined" : failure[0].toString()
- const expectedVal = failure[1] === undefined ? "undefined" : failure[1].toString()
- const actual = new jtree.TreeNode(`actual\n${new jtree.TreeNode(actualVal).toString(1)}`)
- const expected = new jtree.TreeNode(`expected\n${new jtree.TreeNode(expectedVal.toString()).toString(1)}`)
- const comparison = actual.toComparison(expected)
- return new jtree.TreeNode(` assertion ${failure[2]}\n${comparison.toSideBySide([actual, expected]).toString(2)}`)
- })
- .join("\n")
- )
- }
- }
- class TestRacerFile {
- constructor(runner, testTree, fileName) {
- this._runner = runner
- this._testTree = {}
- this._fileName = fileName
- Object.keys(testTree).forEach(key => {
- this._testTree[key] = new TestRacerTestBlock(this, key, testTree[key])
- })
- }
- getRunner() {
- return this._runner
- }
- getFileName() {
- return this._fileName
- }
- get length() {
- return Object.values(this._testTree).length
- }
- get skippedTestBlockNames() {
- const testsToRun = this._filterSkippedTestBlocks()
- return Object.keys(this._testTree).filter(blockName => !testsToRun.includes(blockName))
- }
- _emitMessage(message) {
- this.getRunner()._emitMessage(message)
- }
- _filterSkippedTestBlocks() {
- // _ prefix = run on these tests block
- // $ prefix = skip this test
- const runOnlyTheseTestBlocks = Object.keys(this._testTree).filter(key => key.startsWith("_"))
- if (runOnlyTheseTestBlocks.length) return runOnlyTheseTestBlocks
- return Object.keys(this._testTree).filter(key => !key.startsWith("$"))
- }
- async execute() {
- const testBlockNames = this._filterSkippedTestBlocks()
- this._emitStartFileMessage(testBlockNames.length)
- const fileTimer = new TreeUtils.Timer()
- const blockResults = {}
- const blockPromises = testBlockNames.map(async testName => {
- const results = await this._testTree[testName].execute()
- blockResults[testName] = results
- })
- await Promise.all(blockPromises)
- const fileStats = this._aggregateBlockResultsIntoFileResults(blockResults)
- const fileTimeElapsed = fileTimer.tick()
- fileStats.blocksFailed ? this._emitFileFailedMessage(fileStats, fileTimeElapsed, testBlockNames.length) : this._emitFilePassedMessage(fileStats, fileTimeElapsed, testBlockNames.length)
- return fileStats
- }
- _aggregateBlockResultsIntoFileResults(fileBlockResults) {
- const fileStats = {
- assertionsPassed: 0,
- assertionsFailed: 0,
- blocksPassed: 0,
- blocksFailed: 0,
- failedBlocks: []
- }
- Object.keys(fileBlockResults).forEach(blockName => {
- const results = fileBlockResults[blockName]
- fileStats.assertionsPassed += results.passes.length
- fileStats.assertionsFailed += results.failures.length
- if (results.failures.length) {
- fileStats.blocksFailed++
- fileStats.failedBlocks.push(blockName)
- } else fileStats.blocksPassed++
- })
- return fileStats
- }
- _emitStartFileMessage(blockCount) {
- this._emitMessage(`start file ${blockCount} test blocks in file ${this._fileName}`)
- }
- _emitFilePassedMessage(fileStats, fileTimeElapsed, blockCount) {
- this._emitMessage(`ok file ${this._fileName} in ${fileTimeElapsed}ms. ${blockCount} blocks and ${fileStats.assertionsPassed} assertions passed.`)
- }
- _emitFileFailedMessage(fileStats, fileTimeElapsed, blockCount) {
- this._emitMessage(
- `failed file ${this._fileName} over ${fileTimeElapsed}ms. ${fileStats.blocksFailed} blocks and ${fileStats.assertionsFailed} failed. ${blockCount - fileStats.blocksFailed} blocks and ${fileStats.assertionsPassed} assertions passed`
- )
- }
- }
- class TestRacer {
- constructor(fileTestTree) {
- this._logFunction = console.log
- this._timer = new TreeUtils.Timer()
- this._sessionFilesPassed = 0
- this._sessionFilesFailed = {}
- this._sessionBlocksFailed = 0
- this._sessionBlocksPassed = 0
- this._sessionAssertionsFailed = 0
- this._sessionAssertionsPassed = 0
- this._fileTestTree = {}
- Object.keys(fileTestTree).forEach(fileName => {
- this._fileTestTree[fileName] = new TestRacerFile(this, fileTestTree[fileName], fileName)
- })
- }
- setLogFunction(logFunction) {
- this._logFunction = logFunction
- return this
- }
- _addFileResultsToSessionResults(fileStats, fileName) {
- this._sessionAssertionsPassed += fileStats.assertionsPassed
- this._sessionAssertionsFailed += fileStats.assertionsFailed
- this._sessionBlocksPassed += fileStats.blocksPassed
- this._sessionBlocksFailed += fileStats.blocksFailed
- if (!fileStats.blocksFailed) this._sessionFilesPassed++
- else {
- this._sessionFilesFailed[fileName] = fileStats.failedBlocks
- }
- }
- async execute() {
- this._emitSessionPlanMessage()
- const proms = Object.values(this._fileTestTree).map(async testFile => {
- const results = await testFile.execute()
- this._addFileResultsToSessionResults(results, testFile.getFileName())
- })
- await Promise.all(proms)
- return this
- }
- finish() {
- return this._emitSessionFinishMessage()
- }
- _emitMessage(message) {
- this._logFunction(message)
- return message
- }
- get length() {
- return Object.values(this._fileTestTree).length
- }
- _emitSessionPlanMessage() {
- let blocks = 0
- Object.values(this._fileTestTree).forEach(value => (blocks += value.length))
- this._emitMessage(`${this.length} files and ${blocks} blocks to run. ${this._getSkippedBlockNames().length} skipped blocks.`)
- }
- _getSkippedBlockNames() {
- const skippedBlocks = []
- Object.values(this._fileTestTree).forEach(file => {
- file.skippedTestBlockNames.forEach(blockName => {
- skippedBlocks.push(blockName)
- })
- })
- return skippedBlocks
- }
- _getFailures() {
- if (!Object.keys(this._sessionFilesFailed).length) return ""
- return `
- failures
- ${new TreeNode(this._sessionFilesFailed).forEach(row => row.forEach(line => line.deleteWordAt(0))).toString(2)}`
- }
- _emitSessionFinishMessage() {
- const skipped = this._getSkippedBlockNames()
- return this._emitMessage(`finished in ${this._timer.getTotalElapsedTime()}ms
- skipped
- ${skipped.length} blocks${skipped ? " " + skipped.join(" ") : ""}
- passed
- ${this._sessionFilesPassed} files
- ${this._sessionBlocksPassed} blocks
- ${this._sessionAssertionsPassed} assertions
- failed
- ${Object.keys(this._sessionFilesFailed).length} files
- ${this._sessionBlocksFailed} blocks
- ${this._sessionAssertionsFailed} assertions${this._getFailures()}`)
- }
- static async testSingleFile(fileName, testTree) {
- const obj = {}
- obj[fileName] = testTree
- const session = new TestRacer(obj)
- await session.execute()
- session.finish()
- }
- }
- window.TestRacer = TestRacer
+ Utils.MAX_INT = Math.pow(2, 32) - 1
+ window.Utils = Utils
+
+
Changed around line 11146: class AbstractNode {
- ;(function(FileFormat) {
+ ;(function (FileFormat) {
Changed around line 11174: class TreeWord {
- ;(function(WhereOperators) {
+ ;(function (WhereOperators) {
Changed around line 11189: var WhereOperators
- ;(function(TreeNotationConstants) {
+ ;(function (TreeNotationConstants) {
- class Parser {
- constructor(catchAllNodeConstructor, firstWordMap = {}, regexTests = undefined) {
- this._catchAllNodeConstructor = catchAllNodeConstructor
+ class ParserCombinator {
+ constructor(catchAllParser, firstWordMap = {}, regexTests = undefined) {
+ this._catchAllParser = catchAllParser
Changed around line 11214: class Parser {
- _getNodeConstructor(line, contextNode, wordBreakSymbol = " ") {
- return this._getFirstWordMap().get(this._getFirstWord(line, wordBreakSymbol)) || this._getConstructorFromRegexTests(line) || this._getCatchAllNodeConstructor(contextNode)
+ _getParser(line, contextNode, wordBreakSymbol = " ") {
+ return this._getFirstWordMap().get(this._getFirstWord(line, wordBreakSymbol)) || this._getParserFromRegexTests(line) || this._getCatchAllParser(contextNode)
- _getCatchAllNodeConstructor(contextNode) {
- if (this._catchAllNodeConstructor) return this._catchAllNodeConstructor
- const parent = contextNode.getParent()
- if (parent) return parent._getParser()._getCatchAllNodeConstructor(parent)
+ _getCatchAllParser(contextNode) {
+ if (this._catchAllParser) return this._catchAllParser
+ const parent = contextNode.parent
+ if (parent) return parent._getParser()._getCatchAllParser(parent)
- _getConstructorFromRegexTests(line) {
+ _getParserFromRegexTests(line) {
- if (hit) return hit.nodeConstructor
+ if (hit) return hit.parser
Changed around line 11251: class TreeNode extends AbstractNode {
- getLineCellTypes() {
+ get lineCellTypes() {
- return "undefinedCellType ".repeat(this.getWords().length).trim()
+ return "undefinedCellType ".repeat(this.words.length).trim()
Changed around line 11263: class TreeNode extends AbstractNode {
- return this.getParent().slice(0, this.getIndex())
+ return this.parent.slice(0, this.getIndex())
Changed around line 11271: class TreeNode extends AbstractNode {
- return this.getParent().slice(this.getIndex() + 1)
+ return this.parent.slice(this.getIndex() + 1)
- return this.getParent().filter(node => node !== this)
+ return this.parent.filter(node => node !== this)
- getParent() {
+ get parent() {
- getIndentation(relativeTo) {
- const indentLevel = this._getIndentLevel(relativeTo) - 1
+ get indentation() {
+ const indentLevel = this._getIndentLevel() - 1
- return this.getEdgeSymbol().repeat(indentLevel)
+ return this.edgeSymbol.repeat(indentLevel)
Changed around line 11299: class TreeNode extends AbstractNode {
- getTopDownArray() {
+ get topDownArray() {
Changed around line 11317: class TreeNode extends AbstractNode {
- getNumberOfLines() {
+ get numberOfLines() {
Changed around line 11327: class TreeNode extends AbstractNode {
- const count = node.getWords().length + node.getIndentLevel()
+ const count = node.words.length + node.getIndentLevel()
- getNumberOfWords() {
+ get numberOfWords() {
- wordCount += node.getWords().length
+ wordCount += node.words.length
- getLineNumber() {
+ get lineNumber() {
- for (let node of this.getRootNode().getTopDownArrayIterator()) {
+ for (let node of this.root.getTopDownArrayIterator()) {
Changed around line 11358: class TreeNode extends AbstractNode {
- return !this.length && !this.getContent()
+ return !this.length && !this.content
- const start = relativeTo || this.getRootNode()
+ const start = relativeTo || this.root
- return relativeTo === this || !this.getParent()
+ return relativeTo === this || !this.parent
- getRootNode() {
+ get root() {
- return this.getParent()._getRootNode(relativeTo)
+ return this.parent._getRootNode(relativeTo)
- return language.getEdgeSymbol().repeat(indentCount) + this.getLine(language) + (this.length ? language.getNodeBreakSymbol() + this._childrenToString(indentCount + 1, language) : "")
+ return language.edgeSymbol.repeat(indentCount) + this.getLine(language) + (this.length ? language.nodeBreakSymbol + this._childrenToString(indentCount + 1, language) : "")
+ }
+ get asString() {
+ return this.toString()
Changed around line 11405: class TreeNode extends AbstractNode {
+ get list() {
+ return this.getWordsFrom(1)
+ }
Changed around line 11416: class TreeNode extends AbstractNode {
- const edge = this.getEdgeSymbol().repeat(indentCount)
+ const edge = this.edgeSymbol.repeat(indentCount)
- const childrenHtml = this.length ? `${this.getNodeBreakSymbol()} ` + `${this._childrenToHtml(indentCount + 1)} ` : ""
+ const childrenHtml = this.length ? `${this.nodeBreakSymbol} ` + `${this._childrenToHtml(indentCount + 1)} ` : ""
- if (!this._words) this._words = this._getLine().split(this.getWordBreakSymbol())
+ if (!this._words) this._words = this._getLine().split(this.wordBreakSymbol)
- getWords() {
+ get words() {
- doesExtend(nodeTypeId) {
+ doesExtend(parserId) {
Changed around line 11441: class TreeNode extends AbstractNode {
- const parent = this.getParent()
+ const parent = this.parent
Changed around line 11468: class TreeNode extends AbstractNode {
- return this.isRoot() ? "" : this.getRootNode()._getProjectRootDir()
+ return this.isRoot() ? "" : this.root._getProjectRootDir()
+ }
+ // Concat 2 trees amd return a new true, but replace any nodes
+ // in this tree that start with the same node from the first tree with
+ // that patched version. Does not recurse.
+ patch(two) {
+ const copy = this.clone()
+ two.forEach(node => {
+ const hit = copy.getNode(node.getWord(0))
+ if (hit) hit.destroy()
+ })
+ copy.concat(two)
+ return copy
Changed around line 11515: class TreeNode extends AbstractNode {
- const xiLength = this.getEdgeSymbol().length
- const numIndents = this._getIndentLevel(undefined) - 1
+ const xiLength = this.edgeSymbol.length
+ const numIndents = this._getIndentLevel() - 1
- return (
- indentPosition +
- this.getWords()
- .slice(0, wordIndex)
- .join(this.getWordBreakSymbol()).length +
- this.getWordBreakSymbol().length
- )
+ return indentPosition + this.words.slice(0, wordIndex).join(this.wordBreakSymbol).length + this.wordBreakSymbol.length
Changed around line 11527: class TreeNode extends AbstractNode {
- node = node.getParent()
+ node = node.parent
Changed around line 11542: class TreeNode extends AbstractNode {
- this.getTopDownArray().forEach(line => {
- line.getWords().forEach((word, index) => {
- line.setWord(index, fill)
- })
+ this.topDownArray.forEach(line => {
+ line.words.forEach((word, index) => line.setWord(index, fill))
Changed around line 11564: class TreeNode extends AbstractNode {
- const wordBreakSymbolLength = this.getWordBreakSymbol().length
+ const wordBreakSymbolLength = this.wordBreakSymbol.length
- return this.getWords().map((word, wordIndex) => {
+ return this.words.map((word, wordIndex) => {
Changed around line 11581: class TreeNode extends AbstractNode {
- this.getWords().forEach((word, wordIndex) => {
+ this.words.forEach((word, wordIndex) => {
Changed around line 11592: class TreeNode extends AbstractNode {
- for (let node of this.getTopDownArray()) {
+ for (let node of this.topDownArray) {
Changed around line 11611: class TreeNode extends AbstractNode {
- getFirstWord() {
- return this.getWords()[0]
+ get firstWord() {
+ return this.words[0]
- getContent() {
+ get content() {
- return words.length ? words.join(this.getWordBreakSymbol()) : undefined
+ return words.length ? words.join(this.wordBreakSymbol) : undefined
- getContentWithChildren() {
+ get contentWithChildren() {
- const content = this.getContent()
- return (content ? content : "") + (this.length ? this.getNodeBreakSymbol() + this._childrenToString() : "")
+ const content = this.content
+ return (content ? content : "") + (this.length ? this.nodeBreakSymbol + this._childrenToString() : "")
Changed around line 11631: class TreeNode extends AbstractNode {
- const parent = this.getParent()
+ const parent = this.parent
- .map((node, index) => this.getEdgeSymbol().repeat(index) + node.getLine())
- .join(this.getNodeBreakSymbol())
+ .map((node, index) => this.edgeSymbol.repeat(index) + node.getLine())
+ .join(this.nodeBreakSymbol)
- return this.getWords().join((language || this).getWordBreakSymbol())
+ return this.words.join((language || this).wordBreakSymbol)
Changed around line 11662: class TreeNode extends AbstractNode {
- else if (this.getParent().isRoot(relativeTo)) return this.getFirstWord()
- return this.getParent()._getFirstWordPath(relativeTo) + this.getEdgeSymbol() + this.getFirstWord()
+ else if (this.parent.isRoot(relativeTo)) return this.firstWord
+ return this.parent._getFirstWordPath(relativeTo) + this.edgeSymbol + this.firstWord
Changed around line 11679: class TreeNode extends AbstractNode {
- const path = this.getParent()._getPathVector(relativeTo)
+ const path = this.parent._getPathVector(relativeTo)
- return this.getParent()._indexOfNode(this)
+ return this.parent._indexOfNode(this)
- return this.getWords()
- .map((word, index) => `${TreeUtils.stripHtml(word)} `)
- .join(`${this.getWordBreakSymbol()} `)
+ return this.words.map((word, index) => `${Utils.stripHtml(word)} `).join(`${this.wordBreakSymbol} `)
- if (this.getContent() !== undefined) return this.getContentWithChildren()
+ if (this.content !== undefined) return this.contentWithChildren
- const tag = this.getFirstWord()
+ const tag = this.firstWord
- const content = this.getContent()
+ const content = this.content
- const tupleValue = hasChildrenNoContent ? this.toObject() : hasContentAndHasChildren ? this.getContentWithChildren() : content
- return [this.getFirstWord(), tupleValue]
+ const tupleValue = hasChildrenNoContent ? this.toObject() : hasContentAndHasChildren ? this.contentWithChildren : content
+ return [this.firstWord, tupleValue]
Changed around line 11739: class TreeNode extends AbstractNode {
- this.getTopDownArray().forEach(node => node._rightPad(newWidth, padCharacter))
+ this.topDownArray.forEach(node => node._rightPad(newWidth, padCharacter))
- let linesToAdd = numberOfLines - this.getNumberOfLines()
+ let linesToAdd = numberOfLines - this.numberOfLines
Changed around line 11756: class TreeNode extends AbstractNode {
- clone.lengthen(next.getNumberOfLines())
+ clone.lengthen(next.numberOfLines)
Changed around line 11780: class TreeNode extends AbstractNode {
- const nodeDelimiter = this.getNodeBreakSymbol()
+ const nodeDelimiter = this.nodeBreakSymbol
- TreeUtils.interweave(treesOrStrings.map(tree => tree.toString().split(nodeDelimiter)))
+ Utils.interweave(treesOrStrings.map(tree => tree.toString().split(nodeDelimiter)))
Changed around line 11795: class TreeNode extends AbstractNode {
- const words = this.getWords()
+ const words = this.words
- return this.getTopDownArray().find(node => node._hasColumns(columns))
+ return this.topDownArray.find(node => node._hasColumns(columns))
Changed around line 11829: class TreeNode extends AbstractNode {
- return this.getTopDownArray().filter(node => node.isSelected())
+ return this.topDownArray.filter(node => node.isSelected())
Changed around line 11915: class TreeNode extends AbstractNode {
- this.getTopDownArray().forEach(node => {
+ this.topDownArray.forEach(node => {
Changed around line 11947: class TreeNode extends AbstractNode {
+ // Flatten a tree node into an object like {twitter:"pldb", "twitter.followers":123}.
+ // Assumes you have a nested key/value list with no multiline strings.
+ toFlatObject(delimiter = ".") {
+ let newObject = {}
+ const { edgeSymbolRegex } = this
+ this.forEach((child, index) => {
+ newObject[child.getWord(0)] = child.content
+ child.topDownArray.forEach(node => {
+ const newColumnName = node.getFirstWordPathRelativeTo(this).replace(edgeSymbolRegex, delimiter)
+ const value = node.content
+ newObject[newColumnName] = value
+ })
+ })
+ return newObject
+ }
Changed around line 11970: class TreeNode extends AbstractNode {
- toHtml() {
+ get asHtml() {
- this.getWords().forEach((word, index) => (word ? cells.push(getLine(index + indents, word)) : ""))
+ this.words.forEach((word, index) => (word ? cells.push(getLine(index + indents, word)) : ""))
- toHtmlCube() {
- return this.map((plane, planeIndex) =>
- plane
- .getTopDownArray()
- .map((line, lineIndex) => line._toHtmlCubeLine(line.getIndentLevel() - 2, lineIndex, planeIndex))
- .join("")
- ).join("")
+ get asHtmlCube() {
+ return this.map((plane, planeIndex) => plane.topDownArray.map((line, lineIndex) => line._toHtmlCubeLine(line.getIndentLevel() - 2, lineIndex, planeIndex)).join("")).join("")
- return `${this.getNodeBreakSymbol()} `
+ return `${this.nodeBreakSymbol} `
- return this.map(node => node.toString(indentCount, language)).join(language.getNodeBreakSymbol())
+ return this.map(node => node.toString(indentCount, language)).join(language.nodeBreakSymbol)
Changed around line 12007: class TreeNode extends AbstractNode {
- toXml() {
+ get asXml() {
Changed around line 12015: class TreeNode extends AbstractNode {
- csv: tree => tree.toCsv(),
- tsv: tree => tree.toTsv()
+ csv: tree => tree.asCsv,
+ tsv: tree => tree.asTsv
Changed around line 12024: class TreeNode extends AbstractNode {
- return prefix + `${this.getFirstWord()}:` + (this.getContent() ? " " + this.getContent() : "")
+ return prefix + `${this.firstWord}:` + (this.content ? " " + this.content : "")
- toYaml() {
+ get asYaml() {
Changed around line 12063: class TreeNode extends AbstractNode {
- toJsonSubset() {
+ get asJsonSubset() {
- cells: this.getWords(),
+ cells: this.words,
- cells: this.getWords()
+ cells: this.words
- toJson() {
+ get asJson() {
- toGrid() {
- const WordBreakSymbol = this.getWordBreakSymbol()
+ get asGrid() {
+ const WordBreakSymbol = this.wordBreakSymbol
- .split(this.getNodeBreakSymbol())
+ .split(this.nodeBreakSymbol)
- toGridJson() {
- return JSON.stringify(this.toGrid(), null, 2)
+ get asGridJson() {
+ return JSON.stringify(this.asGrid, null, 2)
- return this.getTopDownArray().filter(node => {
+ return this.topDownArray.filter(node => {
Changed around line 12122: class TreeNode extends AbstractNode {
- if (hit) return hit.getLine().substr((prefix + this.getWordBreakSymbol()).length)
+ if (hit) return hit.getLine().substr((prefix + this.wordBreakSymbol).length)
- return node === undefined ? undefined : node.getContent()
+ return node === undefined ? undefined : node.content
Changed around line 12138: class TreeNode extends AbstractNode {
- const map = TreeUtils.arrayToMap(fields)
+ const map = Utils.arrayToMap(fields)
Changed around line 12148: class TreeNode extends AbstractNode {
- const edgeSymbol = this.getEdgeSymbol()
+ const edgeSymbol = this.edgeSymbol
- return this.filter(node => node.getFirstWord() === globPath)
+ return this.filter(node => node.firstWord === globPath)
- const matchingNodes = current === "*" ? this.getChildren() : this.filter(child => child.getFirstWord() === current)
- return [].concat.apply([], matchingNodes.map(node => node._getNodesByGlobPath(rest)))
+ const matchingNodes = current === "*" ? this.getChildren() : this.filter(child => child.firstWord === current)
+ return [].concat.apply(
+ [],
+ matchingNodes.map(node => node._getNodesByGlobPath(rest))
+ )
- const edgeSymbol = this.getEdgeSymbol()
+ const edgeSymbol = this.edgeSymbol
Changed around line 12173: class TreeNode extends AbstractNode {
- getNext() {
+ get next() {
- const parent = this.getParent()
+ const parent = this.parent
- getPrevious() {
+ get previous() {
- const parent = this.getParent()
+ const parent = this.parent
Changed around line 12195: class TreeNode extends AbstractNode {
- obj[node.getFirstWord()] = 1
+ obj[node.firstWord] = 1
- const ancestorNodes = this._getAncestorNodes((node, id) => node._getNodesByColumn(0, id), node => node.get(key), this)
+ const ancestorNodes = this._getAncestorNodes(
+ (node, id) => node._getNodesByColumn(0, id),
+ node => node.get(key),
+ this
+ )
- const ancestorNodes = this._getAncestorNodes((node, id) => node._getNodesByColumn(thisColumnNumber, id), node => node.getWord(extendsColumnNumber), this)
+ const ancestorNodes = this._getAncestorNodes(
+ (node, id) => node._getNodesByColumn(thisColumnNumber, id),
+ node => node.getWord(extendsColumnNumber),
+ this
+ )
- const potentialParentNodes = getPotentialParentNodesByIdFn(this.getParent(), parentId)
+ const potentialParentNodes = getPotentialParentNodesByIdFn(this.parent, parentId)
Changed around line 12238: class TreeNode extends AbstractNode {
- names.push(node.nodeAt(path[0]).getFirstWord())
+ names.push(node.nodeAt(path[0]).firstWord)
Changed around line 12249: class TreeNode extends AbstractNode {
- toCsv() {
+ get asCsv() {
Changed around line 12298: class TreeNode extends AbstractNode {
- _toArrays(header, cellFn) {
+ _toArrays(columnNames, cellFn) {
- const headerArray = header.map((columnName, index) => cellFn(columnName, 0, index))
+ const header = columnNames.map((columnName, index) => cellFn(columnName, 0, index))
- header.map((columnName, columnIndex) => {
+ columnNames.map((columnName, columnIndex) => {
- const content = childNode ? childNode.getContentWithChildren() : ""
+ const content = childNode ? childNode.contentWithChildren : ""
- rows: rows,
- header: headerArray
+ rows,
+ header
- toTable() {
+ get asTable() {
Changed around line 12349: class TreeNode extends AbstractNode {
- toSsv() {
+ get asSsv() {
- toOutline() {
+ get asOutline() {
Changed around line 12395: class TreeNode extends AbstractNode {
- const NodeBreakSymbol = this.getNodeBreakSymbol()
- const WordBreakSymbol = this.getWordBreakSymbol()
+ const NodeBreakSymbol = this.nodeBreakSymbol
+ const WordBreakSymbol = this.wordBreakSymbol
- toMarkdownTable() {
+ get asMarkdownTable() {
Changed around line 12416: class TreeNode extends AbstractNode {
- toTsv() {
+ get asTsv() {
- getNodeBreakSymbol() {
+ get nodeBreakSymbol() {
- getWordBreakSymbol() {
+ get wordBreakSymbol() {
- getNodeBreakSymbolRegex() {
- return new RegExp(this.getNodeBreakSymbol(), "g")
+ get edgeSymbolRegex() {
+ return new RegExp(this.edgeSymbol, "g")
- getEdgeSymbol() {
+ get nodeBreakSymbolRegex() {
+ return new RegExp(this.nodeBreakSymbol, "g")
+ }
+ get edgeSymbol() {
- const lines = text.split(this.getNodeBreakSymbolRegex())
+ const lines = text.split(this.nodeBreakSymbolRegex)
- .map(line => (line.substr(0, 1) === this.getEdgeSymbol() ? line : this.getEdgeSymbol() + line))
+ .map(line => (line.substr(0, 1) === this.edgeSymbol ? line : this.edgeSymbol + line))
- .join(this.getNodeBreakSymbol())
+ .join(this.nodeBreakSymbol)
Changed around line 12454: class TreeNode extends AbstractNode {
- this._deleteByIndexes(TreeUtils.getRange(0, this.length))
+ this._deleteByIndexes(Utils.getRange(0, this.length))
Changed around line 12512: class TreeNode extends AbstractNode {
- const nodeConstructor = this._getParser()._getNodeConstructor(line, this)
- const newNode = new nodeConstructor(children, line, this)
+ const parser = this._getParser()._getParser(line, this)
+ const newNode = new parser(children, line, this)
+ this.clearQuickCache()
- const lines = str.split(this.getNodeBreakSymbolRegex())
+ const lines = str.split(this.nodeBreakSymbolRegex)
Changed around line 12539: class TreeNode extends AbstractNode {
- const nodeConstructor = parent._getParser()._getNodeConstructor(lineContent, parent)
- lastNode = new nodeConstructor(undefined, lineContent, parent)
+ const parser = parent._getParser()._getParser(lineContent, parent)
+ lastNode = new parser(undefined, lineContent, parent)
Changed around line 12551: class TreeNode extends AbstractNode {
- return this.map(node => node.getContent())
+ return this.map(node => node.content)
- // todo: rename to getChildrenByConstructor(?)
- getChildrenByNodeConstructor(constructor) {
- return this.filter(child => child instanceof constructor)
+ getChildrenByParser(parser) {
+ return this.filter(child => child instanceof parser)
- getAncestorByNodeConstructor(constructor) {
- if (this instanceof constructor) return this
+ getAncestorByParser(parser) {
+ if (this instanceof parser) return this
- const parent = this.getParent()
- return parent instanceof constructor ? parent : parent.getAncestorByNodeConstructor(constructor)
+ const parent = this.parent
+ return parent instanceof parser ? parent : parent.getAncestorByParser(parser)
- // todo: rename to getNodeByConstructor(?)
- getNodeByType(constructor) {
- return this.find(child => child instanceof constructor)
+ getNodeByParser(parser) {
+ return this.find(child => child instanceof parser)
Changed around line 12575: class TreeNode extends AbstractNode {
- if (nodes[index].getFirstWord() === firstWord) return index
+ if (nodes[index].firstWord === firstWord) return index
Changed around line 12583: class TreeNode extends AbstractNode {
- return this.map(node => node.getFirstWord())
+ return this.map(node => node.firstWord)
Changed around line 12591: class TreeNode extends AbstractNode {
- newIndex[nodes[index].getFirstWord()] = index
+ newIndex[nodes[index].firstWord] = index
Changed around line 12600: class TreeNode extends AbstractNode {
- const edgeChar = this.getEdgeSymbol()
+ const edgeChar = this.edgeSymbol
- clone() {
- return new this.constructor(this.childrenToString(), this.getLine())
+ clone(children = this.childrenToString(), line = this.getLine()) {
+ return new this.constructor(children, line)
- // todo: rename to hasFirstWord
- has(firstWord) {
+ hasFirstWord(firstWord) {
+ has(firstWordPath) {
+ const edgeSymbol = this.edgeSymbol
+ if (!firstWordPath.includes(edgeSymbol)) return this.hasFirstWord(firstWordPath)
+ const parts = firstWordPath.split(edgeSymbol)
+ const next = this.getNode(parts.shift())
+ if (!next) return false
+ return next.has(parts.join(edgeSymbol))
+ }
Changed around line 12637: class TreeNode extends AbstractNode {
- return this.getChildren()
- .reverse()
- .find(fn)
+ return this.getChildren().reverse().find(fn)
Changed around line 12657: class TreeNode extends AbstractNode {
+ get quickCache() {
+ if (!this._quickCache) this._quickCache = {}
+ return this._quickCache
+ }
+ getCustomIndex(key) {
+ if (!this.quickCache.customIndexes) this.quickCache.customIndexes = {}
+ const customIndexes = this.quickCache.customIndexes
+ if (customIndexes[key]) return customIndexes[key]
+ const customIndex = {}
+ customIndexes[key] = customIndex
+ this.filter(file => file.has(key)).forEach(file => {
+ const value = file.get(key)
+ if (!customIndex[value]) customIndex[value] = []
+ customIndex[value].push(file)
+ })
+ return customIndex
+ }
+ clearQuickCache() {
+ delete this._quickCache
+ }
+ this.clearQuickCache()
Changed around line 12699: class TreeNode extends AbstractNode {
- return this.isRoot() || this.getParent().isRoot() ? undefined : this.getParent().getParent()
+ return this.isRoot() || this.parent.isRoot() ? undefined : this.parent.parent
- if (!TreeNode._parsers.has(this.constructor)) TreeNode._parsers.set(this.constructor, this.createParser())
- return TreeNode._parsers.get(this.constructor)
+ if (!TreeNode._parserCombinators.has(this.constructor)) TreeNode._parserCombinators.set(this.constructor, this.createParserCombinator())
+ return TreeNode._parserCombinators.get(this.constructor)
- createParser() {
- return new Parser(this.constructor)
+ createParserCombinator() {
+ return new ParserCombinator(this.constructor)
Changed around line 12728: class TreeNode extends AbstractNode {
- return Math.max(this.getLineModifiedTime(), this.getChildArrayModifiedTime(), Math.max.apply(null, this.map(child => child.getLineOrChildrenModifiedTime())))
+ return Math.max(
+ this.getLineModifiedTime(),
+ this.getChildArrayModifiedTime(),
+ Math.max.apply(
+ null,
+ this.map(child => child.getLineOrChildrenModifiedTime())
+ )
+ )
Changed around line 12791: class TreeNode extends AbstractNode {
- const firstWord = sourceNode.getFirstWord()
+ const firstWord = sourceNode.firstWord
Changed around line 12801: class TreeNode extends AbstractNode {
- targetNode = this.touchNode(firstWord).setContent(sourceNode.getContent())
+ targetNode = this.touchNode(firstWord).setContent(sourceNode.content)
Changed around line 12816: class TreeNode extends AbstractNode {
- lastNode.getTopDownArray().forEach(node => {
+ lastNode.topDownArray.forEach(node => {
Changed around line 12827: class TreeNode extends AbstractNode {
- const wordBreakSymbol = clone.getWordBreakSymbol()
+ const wordBreakSymbol = clone.wordBreakSymbol
Changed around line 12854: class TreeNode extends AbstractNode {
- const wi = this.getWordBreakSymbol()
+ const wi = this.wordBreakSymbol
Changed around line 12862: class TreeNode extends AbstractNode {
- this.getTopDownArray().forEach(node => {
+ this.topDownArray.forEach(node => {
Changed around line 12870: class TreeNode extends AbstractNode {
- const wi = this.getWordBreakSymbol()
+ const wi = this.wordBreakSymbol
Changed around line 12880: class TreeNode extends AbstractNode {
- if (content === this.getContent()) return this
- const newArray = [this.getFirstWord()]
+ if (content === this.content) return this
+ const newArray = [this.firstWord]
- if (content.match(this.getNodeBreakSymbol())) return this.setContentWithChildren(content)
+ if (content.match(this.nodeBreakSymbol)) return this.setContentWithChildren(content)
- this._setLine(newArray.join(this.getWordBreakSymbol()))
+ this._setLine(newArray.join(this.wordBreakSymbol))
- return this.getParent().insertLineAndChildren(line, children, this.getIndex())
+ return this.parent.insertLineAndChildren(line, children, this.getIndex())
- return this.getParent().insertLineAndChildren(line, children, this.getIndex() + 1)
+ return this.parent.insertLineAndChildren(line, children, this.getIndex() + 1)
- if (!text.includes(this.getNodeBreakSymbol())) {
+ if (!text.includes(this.nodeBreakSymbol)) {
- const lines = text.split(this.getNodeBreakSymbolRegex())
+ const lines = text.split(this.nodeBreakSymbolRegex)
- const remainingString = lines.join(this.getNodeBreakSymbol())
+ const remainingString = lines.join(this.nodeBreakSymbol)
Changed around line 12919: class TreeNode extends AbstractNode {
- this.getParent()._clearIndex()
+ this.parent._clearIndex()
- return this.getParent()._insertLineAndChildren(this.getLine(), this.childrenToString(), this.getIndex() + 1)
+ return this.parent._insertLineAndChildren(this.getLine(), this.childrenToString(), this.getIndex() + 1)
Changed around line 12933: class TreeNode extends AbstractNode {
- this.getParent()._deleteNode(this)
+ this.parent._deleteNode(this)
Changed around line 12964: class TreeNode extends AbstractNode {
+ appendUniqueLine(line) {
+ if (!this.hasLine(line)) return this.appendLine(line)
+ return this.findLine(line)
+ }
Changed around line 12980: class TreeNode extends AbstractNode {
- this._getNodesByLineRegex(matches, columns.map(str => new RegExp("^" + str)))
+ this._getNodesByLineRegex(
+ matches,
+ columns.map(str => new RegExp("^" + str))
+ )
Changed around line 13028: class TreeNode extends AbstractNode {
- this.forEach(node => node.getWords().reverse())
+ this.forEach(node => node.words.reverse())
Changed around line 13042: class TreeNode extends AbstractNode {
- const firstWord = node.getFirstWord()
+ const firstWord = node.firstWord
Changed around line 13060: class TreeNode extends AbstractNode {
- if (node.getFirstWord() === firstWord) indexesToDelete.push(index)
+ if (node.firstWord === firstWord) indexesToDelete.push(index)
- const edgeSymbol = this.getEdgeSymbol()
+ const edgeSymbol = this.edgeSymbol
Changed around line 13077: class TreeNode extends AbstractNode {
- const results = this.getTopDownArray().filter(node => node.hasDuplicateFirstWords())
+ const results = this.topDownArray.filter(node => node.hasDuplicateFirstWords())
- const parent = this.getParent()
+ const parent = this.parent
Changed around line 13107: class TreeNode extends AbstractNode {
- const line = index.toString() + (content === undefined ? "" : this.getWordBreakSymbol() + content)
+ const line = index.toString() + (content === undefined ? "" : this.wordBreakSymbol + content)
Changed around line 13121: class TreeNode extends AbstractNode {
- const words = this.getWords()
+ const words = this.words
Changed around line 13138: class TreeNode extends AbstractNode {
- const parent = this.getParent()
+ const parent = this.parent
Changed around line 13161: class TreeNode extends AbstractNode {
- return this.setLine(words.join(this.getWordBreakSymbol()))
+ return this.setLine(words.join(this.wordBreakSymbol))
- this.setWords(
- this.getWords()
- .slice(0, index)
- .concat(words)
- )
+ this.setWords(this.words.slice(0, index).concat(words))
- const words = this.getWords()
+ const words = this.words
Changed around line 13180: class TreeNode extends AbstractNode {
- const valA = map[nodeA.getFirstWord()]
- const valB = map[nodeB.getFirstWord()]
+ const valA = map[nodeA.firstWord]
+ const valB = map[nodeB.firstWord]
Changed around line 13196: class TreeNode extends AbstractNode {
- str = str.replace(this.getNodeBreakSymbolRegex(), "") // todo: do we want to do this sanitization?
- return this._touchNode(str.split(this.getWordBreakSymbol()))
+ str = str.replace(this.nodeBreakSymbolRegex, "") // todo: do we want to do this sanitization?
+ return this._touchNode(str.split(this.wordBreakSymbol))
Changed around line 13208: class TreeNode extends AbstractNode {
+ findLine(line) {
+ return this.getChildren().find(node => node.getLine() === line)
+ }
Changed around line 13227: class TreeNode extends AbstractNode {
- const wordsA = nodeA.getWords()
- const wordsB = nodeB.getWords()
+ const wordsA = nodeA.words
+ const wordsB = nodeB.words
Changed around line 13250: class TreeNode extends AbstractNode {
- addObjectsAsDelimited(arrayOfObjects, delimiter = TreeUtils._chooseDelimiter(new TreeNode(arrayOfObjects).toString())) {
+ addObjectsAsDelimited(arrayOfObjects, delimiter = Utils._chooseDelimiter(new TreeNode(arrayOfObjects).toString())) {
Changed around line 13261: class TreeNode extends AbstractNode {
- setChildrenAsDelimited(tree, delimiter = TreeUtils._chooseDelimiter(tree.toString())) {
+ setChildrenAsDelimited(tree, delimiter = Utils._chooseDelimiter(tree.toString())) {
- convertChildrenToDelimited(delimiter = TreeUtils._chooseDelimiter(this.childrenToString())) {
+ convertChildrenToDelimited(delimiter = Utils._chooseDelimiter(this.childrenToString())) {
Changed around line 13280: class TreeNode extends AbstractNode {
- const parentIndex = this.getParent().getIndex()
+ const parentIndex = this.parent.getIndex()
- const parent = this.getParent()
+ const parent = this.parent
Changed around line 13307: class TreeNode extends AbstractNode {
- tree.getTopDownArray().forEach(node => {
+ tree.topDownArray.forEach(node => {
Changed around line 13423: class TreeNode extends AbstractNode {
- const cellDelimiter = language.getWordBreakSymbol()
- const nodeDelimiter = language.getNodeBreakSymbol()
+ const cellDelimiter = language.wordBreakSymbol
+ const nodeDelimiter = language.nodeBreakSymbol
Changed around line 13439: class TreeNode extends AbstractNode {
- const cellDelimiter = language.getWordBreakSymbol()
- const nodeDelimiter = language.getNodeBreakSymbol()
+ const cellDelimiter = language.wordBreakSymbol
+ const nodeDelimiter = language.nodeBreakSymbol
Changed around line 13657: class TreeNode extends AbstractNode {
+ static fromFolder(folderPath, filepathPredicate = filepath => filepath !== ".DS_Store") {
+ const path = require("path")
+ const fs = require("fs")
+ const tree = new TreeNode()
+ const files = fs
+ .readdirSync(folderPath)
+ .map(filename => path.join(folderPath, filename))
+ .filter(filepath => !fs.statSync(filepath).isDirectory() && filepathPredicate(filepath))
+ .forEach(filePath => tree.appendLineAndChildren(filePath, fs.readFileSync(filePath, "utf8")))
+ return tree
+ }
- TreeNode._parsers = new Map()
- TreeNode.Parser = Parser
+ TreeNode._parserCombinators = new Map()
+ TreeNode.ParserCombinator = ParserCombinator
Changed around line 13682: TreeNode.iris = `sepal_length,sepal_width,petal_length,petal_width,species
- TreeNode.getVersion = () => "53.8.0"
+ TreeNode.getVersion = () => "74.0.0"
Changed around line 13691: class AbstractExtendibleTreeNode extends TreeNode {
- const path = node._getAncestorsArray().map(node => node._getId())
+ const path = node._getAncestorsArray().map(node => node.id)
- _getChildrenByNodeConstructorInExtended(constructor) {
- return TreeUtils.flatten(this._getAncestorsArray().map(node => node.getChildrenByNodeConstructor(constructor)))
+ _getChildrenByParserInExtended(parser) {
+ return Utils.flatten(this._getAncestorsArray().map(node => node.getChildrenByParser(parser)))
Changed around line 13717: class AbstractExtendibleTreeNode extends TreeNode {
- _doesExtend(nodeTypeId) {
- return this._getAncestorSet().has(nodeTypeId)
+ _doesExtend(parserId) {
+ return this._getAncestorSet().has(parserId)
- if (!this._cache_ancestorSet) this._cache_ancestorSet = new Set(this._getAncestorsArray().map(def => def._getId()))
+ if (!this._cache_ancestorSet) this._cache_ancestorSet = new Set(this._getAncestorsArray().map(def => def.id))
Changed around line 13729: class AbstractExtendibleTreeNode extends TreeNode {
- _getIdThatThisExtends() {
+ get idThatThisExtends() {
Changed around line 13737: class AbstractExtendibleTreeNode extends TreeNode {
- const extendedId = this._getIdThatThisExtends()
+ const extendedId = this.idThatThisExtends
- const parentNode = this._getIdToNodeMap()[extendedId]
+ const parentNode = this.idToNodeMap[extendedId]
Changed around line 13747: class AbstractExtendibleTreeNode extends TreeNode {
- _getIdToNodeMap() {
- if (!this.isRoot()) return this.getRootNode()._getIdToNodeMap()
+ get idToNodeMap() {
+ if (!this.isRoot()) return this.root.idToNodeMap
- this._nodeMapCache[child._getId()] = child
+ this._nodeMapCache[child.id] = child
- _getId() {
+ get id() {
Changed around line 13766: window.ExtendibleTreeNode = ExtendibleTreeNode
+
+
+ // Compiled language parsers will include these files:
+ const GlobalNamespaceAdditions = {
+ Utils: "Utils.js",
+ TreeNode: "TreeNode.js",
+ HandGrammarProgram: "GrammarLanguage.js",
+ GrammarBackedNode: "GrammarLanguage.js"
+ }
- ;(function(GrammarConstantsCompiler) {
+ ;(function (GrammarConstantsCompiler) {
Changed around line 13784: var GrammarConstantsCompiler
- var SQLiteTypes
- ;(function(SQLiteTypes) {
- SQLiteTypes["integer"] = "INTEGER"
- SQLiteTypes["float"] = "FLOAT"
- SQLiteTypes["text"] = "TEXT"
- })(SQLiteTypes || (SQLiteTypes = {}))
- ;(function(GrammarConstantsMisc) {
+ ;(function (GrammarConstantsMisc) {
- GrammarConstantsMisc["tableName"] = "tableName"
- ;(function(PreludeCellTypeIds) {
+ ;(function (PreludeCellTypeIds) {
Changed around line 13800: var PreludeCellTypeIds
- ;(function(GrammarConstantsConstantTypes) {
+ ;(function (GrammarConstantsConstantTypes) {
- ;(function(GrammarBundleFiles) {
+ ;(function (GrammarBundleFiles) {
Changed around line 13815: var GrammarBundleFiles
- ;(function(GrammarCellParser) {
+ ;(function (GrammarCellParser) {
- ;(function(GrammarConstants) {
+ ;(function (GrammarConstants) {
- GrammarConstants["toolingDirective"] = "tooling"
- GrammarConstants["todoComment"] = "todo"
+ GrammarConstants["comment"] = "//"
- GrammarConstants["nodeType"] = "nodeType"
+ GrammarConstants["parser"] = "parser"
- GrammarConstants["nodeTypeSuffix"] = "Node"
+ GrammarConstants["abstractParserPrefix"] = "abstract"
+ GrammarConstants["parserSuffix"] = "Parser"
Changed around line 13840: var GrammarConstants
- // baseNodeTypes
- GrammarConstants["baseNodeType"] = "baseNodeType"
- GrammarConstants["blobNode"] = "blobNode"
- GrammarConstants["errorNode"] = "errorNode"
+ // baseParsers
+ GrammarConstants["baseParser"] = "baseParser"
+ GrammarConstants["blobParser"] = "blobParser"
+ GrammarConstants["errorParser"] = "errorParser"
- GrammarConstants["abstract"] = "abstract"
+ GrammarConstants["listDelimiter"] = "listDelimiter"
+ GrammarConstants["contentKey"] = "contentKey"
+ GrammarConstants["childrenKey"] = "childrenKey"
+ GrammarConstants["uniqueFirstWord"] = "uniqueFirstWord"
- GrammarConstants["catchAllNodeType"] = "catchAllNodeType"
+ GrammarConstants["catchAllParser"] = "catchAllParser"
+ GrammarConstants["uniqueLine"] = "uniqueLine"
- // default catchAll nodeType
- GrammarConstants["BlobNode"] = "BlobNode"
- GrammarConstants["defaultRootNode"] = "defaultRootNode"
+ // default catchAll parser
+ GrammarConstants["BlobParser"] = "BlobParser"
+ GrammarConstants["DefaultRootParser"] = "DefaultRootParser"
- GrammarConstants["compilerNodeType"] = "compiler"
+ GrammarConstants["compilerParser"] = "compiler"
+ GrammarConstants["sortTemplate"] = "sortTemplate"
Changed around line 13895: class TypedWord extends TreeWord {
- getDefinition() {
- const handGrammarProgram = this.getHandGrammarProgram()
- return this.isRoot() ? handGrammarProgram : handGrammarProgram.getNodeTypeDefinitionByNodeTypeId(this.constructor.name)
- }
- toSQLiteInsertStatement(primaryKeyFunction = node => node.getWord(0)) {
- const def = this.getDefinition()
- const tableName = def.getTableNameIfAny() || def._getId()
- const columns = def.getSQLiteTableColumns()
- const hits = columns.filter(colDef => this.has(colDef.columnName))
- const values = hits.map(colDef => {
- const node = this.getNode(colDef.columnName)
- const content = node.getContent()
- return colDef.type === SQLiteTypes.text ? `"${content}"` : content
- })
- hits.unshift({ columnName: "id", type: SQLiteTypes.text })
- values.unshift(`"${primaryKeyFunction(this)}"`)
- return `INSERT INTO ${tableName} (${hits.map(col => col.columnName).join(",")}) VALUES (${values.join(",")});`
+ get definition() {
+ if (this._definition) return this._definition
+ this._definition = this.isRoot() ? this.handGrammarProgram : this.parent.definition.getParserDefinitionByParserId(this.constructor.name)
+ return this._definition
+ }
+ get rootGrammarTree() {
+ return this.definition.root
- getChildInstancesOfNodeTypeId(nodeTypeId) {
- return this.filter(node => node.doesExtend(nodeTypeId))
+ get nodeIndex() {
+ // StringMap {firstWord: index}
+ // When there are multiple tails with the same firstWord, _index stores the last content.
+ // todo: change the above behavior: when a collision occurs, create an array.
+ return this._nodeIndex || this._makeNodeIndex()
- doesExtend(nodeTypeId) {
- return this.getDefinition()._doesExtend(nodeTypeId)
+ _clearIndex() {
+ delete this._nodeIndex
+ return super._clearIndex()
- _getErrorNodeErrors() {
- return [this.getFirstWord() ? new UnknownNodeTypeError(this) : new BlankLineError(this)]
+ _makeIndex(startAt = 0) {
+ if (this._nodeIndex) this._makeNodeIndex(startAt)
+ return super._makeIndex(startAt)
- _getBlobNodeCatchAllNodeType() {
- return BlobNode
+ _makeNodeIndex(startAt = 0) {
+ if (!this._nodeIndex || !startAt) this._nodeIndex = {}
+ const nodes = this._getChildrenArray()
+ const newIndex = this._nodeIndex
+ const length = nodes.length
+ for (let index = startAt; index < length; index++) {
+ const node = nodes[index]
+ const ancestors = Array.from(node.definition._getAncestorSet()).forEach(id => {
+ if (!newIndex[id]) newIndex[id] = []
+ newIndex[id].push(node)
+ })
+ }
+ return newIndex
+ }
+ getChildInstancesOfParserId(parserId) {
+ return this.nodeIndex[parserId] || []
+ }
+ doesExtend(parserId) {
+ return this.definition._doesExtend(parserId)
+ }
+ _getErrorParserErrors() {
+ return [this.firstWord ? new UnknownParserError(this) : new BlankLineError(this)]
+ }
+ _getBlobParserCatchAllParser() {
+ return BlobParser
- const keywordMap = this.getDefinition().getFirstWordMapWithDefinitions()
+ const keywordMap = this.definition.firstWordMapWithDefinitions
- return keywords.map(keyword => {
- const def = keywordMap[keyword]
- const description = def.getDescription()
- return {
- text: keyword,
- displayText: keyword + (description ? " " + description : "")
- }
- })
+ return keywords
+ .map(keyword => {
+ const def = keywordMap[keyword]
+ if (def.suggestInAutocomplete === false) return false
+ const description = def.description
+ return {
+ text: keyword,
+ displayText: keyword + (description ? " " + description : "")
+ }
+ })
+ .filter(i => i)
- const cell = this._getParsedCells()[cellIndex]
+ const cell = this.parsedCells[cellIndex]
- getHandGrammarProgram() {
+ get handGrammarProgram() {
- return this.getRootNode().getHandGrammarProgram()
+ return this.root.handGrammarProgram
- const nodeTypeOrder = this.getDefinition()._getMyInScopeNodeTypeIds()
- if (!nodeTypeOrder.length) return this
+ const parserOrder = this.definition._getMyInScopeParserIds()
+ if (!parserOrder.length) return this
- nodeTypeOrder.forEach((word, index) => {
- orderMap[word] = index
- })
- this.sort(
- TreeUtils.makeSortByFn(runtimeNode => {
- return orderMap[runtimeNode.getDefinition().getNodeTypeIdFromDefinition()]
- })
- )
+ parserOrder.forEach((word, index) => (orderMap[word] = index))
+ this.sort(Utils.makeSortByFn(runtimeNode => orderMap[runtimeNode.definition.parserIdFromDefinition]))
- Object.values(this.getDefinition().getFirstWordMapWithDefinitions()).forEach(def => {
- if (def.isRequired()) if (!this.getChildren().some(node => node.getDefinition() === def)) errors.push(new MissingRequiredNodeTypeError(this, def.getNodeTypeIdFromDefinition()))
+ Object.values(this.definition.firstWordMapWithDefinitions).forEach(def => {
+ if (def.isRequired() && !this.nodeIndex[def.id]) errors.push(new MissingRequiredParserError(this, def.id))
- getProgramAsCells() {
+ get programAsCells() {
- return this.getTopDownArray().map(node => {
- const cells = node._getParsedCells()
+ return this.topDownArray.map(node => {
+ const cells = node.parsedCells
Changed around line 14003: class GrammarBackedNode extends TreeNode {
- getProgramWidth() {
- return Math.max(...this.getProgramAsCells().map(line => line.length))
+ get programWidth() {
+ return Math.max(...this.programAsCells.map(line => line.length))
- getAllTypedWords() {
+ get allTypedWords() {
- this.getTopDownArray().forEach(node => {
- node.getWordTypes().forEach((cell, index) => {
- words.push(new TypedWord(node, index, cell.getCellTypeId()))
- })
- })
+ this.topDownArray.forEach(node => node.wordTypes.forEach((cell, index) => words.push(new TypedWord(node, index, cell.cellTypeId))))
- return this.getAllTypedWords().filter(typedWord => typedWord.type === cellTypeId)
+ return this.allTypedWords.filter(typedWord => typedWord.type === cellTypeId)
- findAllNodesWithNodeType(nodeTypeId) {
- return this.getTopDownArray().filter(node => node.getDefinition().getNodeTypeIdFromDefinition() === nodeTypeId)
+ findAllNodesWithParser(parserId) {
+ return this.topDownArray.filter(node => node.definition.parserIdFromDefinition === parserId)
- return this.getTopDownArray()
- .map(child => child.getIndentation() + child.getLineCellTypes())
- .join("\n")
+ return this.topDownArray.map(child => child.indentation + child.lineCellTypes).join("\n")
- tree.getTopDownArray().map((node, lineNumber) => {
+ tree.topDownArray.map((node, lineNumber) => {
- source: sourceNode.getIndentation() + sourceNode.getLine(),
- nodeType: sourceNode.constructor.name,
- cellTypes: node.getContent(),
+ source: sourceNode.indentation + sourceNode.getLine(),
+ parser: sourceNode.constructor.name,
+ cellTypes: node.content,
- if (errorCount) obj.errorMessages = errs.map(err => err.getMessage()).join(";")
+ if (errorCount) obj.errorMessages = errs.map(err => err.message).join(";")
- // Helper method for selecting potential nodeTypes needed to update grammar file.
- getInvalidNodeTypes() {
+ // Helper method for selecting potential parsers needed to update grammar file.
+ get invalidParsers() {
- .filter(err => err instanceof UnknownNodeTypeError)
- .map(err => err.getNode().getFirstWord())
+ .filter(err => err instanceof UnknownParserError)
+ .map(err => err.getNode().firstWord)
Changed around line 14078: class GrammarBackedNode extends TreeNode {
- ).toTable()
+ ).asTable
Changed around line 14095: class GrammarBackedNode extends TreeNode {
- _sortWithParentNodeTypesUpTop() {
- const familyTree = new HandGrammarProgram(this.toString()).getNodeTypeFamilyTree()
+ _sortWithParentParsersUpTop() {
+ const familyTree = new HandGrammarProgram(this.toString()).parserFamilyTree
- familyTree.getTopDownArray().forEach((node, index) => {
+ familyTree.topDownArray.forEach((node, index) => {
Changed around line 14114: class GrammarBackedNode extends TreeNode {
- this._sortWithParentNodeTypesUpTop()
+ this._sortWithParentParsersUpTop()
- this.getTopDownArray().forEach(child => {
+ this.topDownArray.forEach(child => {
- getNodeTypeUsage(filepath = "") {
- // returns a report on what nodeTypes from its language the program uses
+ sortFromSortTemplate() {
+ if (!this.length) return this
+ // Recurse
+ this.forEach(node => node.sortFromSortTemplate())
+ const def = this.isRoot() ? this.definition.rootParserDefinition : this.definition
+ const { sortIndices, sortSections } = def.sortSpec
+ // Sort and insert section breaks
+ if (sortIndices.size) {
+ // Sort keywords
+ this.sort((nodeA, nodeB) => {
+ var _a, _b
+ const aIndex = (_a = sortIndices.get(nodeA.firstWord)) !== null && _a !== void 0 ? _a : sortIndices.get(nodeA.sortKey)
+ const bIndex = (_b = sortIndices.get(nodeB.firstWord)) !== null && _b !== void 0 ? _b : sortIndices.get(nodeB.sortKey)
+ if (aIndex === undefined) console.error(`sortTemplate is missing "${nodeA.firstWord}"`)
+ const a = aIndex !== null && aIndex !== void 0 ? aIndex : 1000
+ const b = bIndex !== null && bIndex !== void 0 ? bIndex : 1000
+ return a > b ? 1 : a < b ? -1 : nodeA.getLine() > nodeB.getLine()
+ })
+ // pad sections
+ let currentSection = 0
+ this.forEach(node => {
+ var _a
+ const nodeSection = (_a = sortSections.get(node.firstWord)) !== null && _a !== void 0 ? _a : sortSections.get(node.sortKey)
+ const sectionHasAdvanced = nodeSection > currentSection
+ if (sectionHasAdvanced) {
+ currentSection = nodeSection
+ node.prependSibling("") // Put a blank line before this section
+ }
+ })
+ }
+ return this
+ }
+ getParserUsage(filepath = "") {
+ // returns a report on what parsers from its language the program uses
- const handGrammarProgram = this.getHandGrammarProgram()
- handGrammarProgram.getValidConcreteAndAbstractNodeTypeDefinitions().forEach(def => {
- const requiredCellTypeIds = def.getCellParser().getRequiredCellTypeIds()
- usage.appendLine([def.getNodeTypeIdFromDefinition(), "line-id", "nodeType", requiredCellTypeIds.join(" ")].join(" "))
+ const handGrammarProgram = this.handGrammarProgram
+ handGrammarProgram.validConcreteAndAbstractParserDefinitions.forEach(def => {
+ const requiredCellTypeIds = def.cellParser.getRequiredCellTypeIds()
+ usage.appendLine([def.parserIdFromDefinition, "line-id", "parser", requiredCellTypeIds.join(" ")].join(" "))
- this.getTopDownArray().forEach((node, lineNumber) => {
- const stats = usage.getNode(node.getNodeTypeId())
- stats.appendLine([filepath + "-" + lineNumber, node.getWords().join(" ")].join(" "))
+ this.topDownArray.forEach((node, lineNumber) => {
+ const stats = usage.getNode(node.parserId)
+ stats.appendLine([filepath + "-" + lineNumber, node.words.join(" ")].join(" "))
- return this.getTopDownArray()
- .map(child => child.getIndentation() + child.getLineHighlightScopes())
- .join("\n")
+ return this.topDownArray.map(child => child.indentation + child.getLineHighlightScopes()).join("\n")
- return this.getTopDownArray()
- .map(child => child.getDefinition().getLineNumber() + " " + child.getIndentation() + child.getCellDefinitionLineNumbers().join(" "))
- .join("\n")
+ return this.topDownArray.map(child => child.definition.lineNumber + " " + child.indentation + child.cellDefinitionLineNumbers.join(" ")).join("\n")
- toCellTypeTreeWithNodeConstructorNames() {
- return this.getTopDownArray()
- .map(child => child.constructor.name + this.getWordBreakSymbol() + child.getIndentation() + child.getLineCellTypes())
- .join("\n")
+ get asCellTypeTreeWithParserIds() {
+ return this.topDownArray.map(child => child.constructor.name + this.wordBreakSymbol + child.indentation + child.lineCellTypes).join("\n")
- toPreludeCellTypeTreeWithNodeConstructorNames() {
- return this.getTopDownArray()
- .map(child => child.constructor.name + this.getWordBreakSymbol() + child.getIndentation() + child.getLineCellPreludeTypes())
- .join("\n")
+ toPreludeCellTypeTreeWithParserIds() {
+ return this.topDownArray.map(child => child.constructor.name + this.wordBreakSymbol + child.indentation + child.getLineCellPreludeTypes()).join("\n")
- getTreeWithNodeTypes() {
- return this.getTopDownArray()
- .map(child => child.constructor.name + this.getWordBreakSymbol() + child.getIndentation() + child.getLine())
- .join("\n")
+ get asTreeWithParsers() {
+ return this.topDownArray.map(child => child.constructor.name + this.wordBreakSymbol + child.indentation + child.getLine()).join("\n")
- const typeNode = this._cache_highlightScopeTree.getTopDownArray()[lineIndex - 1]
+ const typeNode = this._cache_highlightScopeTree.topDownArray[lineIndex - 1]
Changed around line 14197: class GrammarBackedNode extends TreeNode {
- createParser() {
- return this.isRoot()
- ? new TreeNode.Parser(BlobNode)
- : new TreeNode.Parser(
- this.getParent()
- ._getParser()
- ._getCatchAllNodeConstructor(this.getParent()),
- {}
- )
+ createParserCombinator() {
+ return this.isRoot() ? new TreeNode.ParserCombinator(BlobParser) : new TreeNode.ParserCombinator(this.parent._getParser()._getCatchAllParser(this.parent), {})
- getNodeTypeId() {
- return this.getDefinition().getNodeTypeIdFromDefinition()
+ get parserId() {
+ return this.definition.parserIdFromDefinition
- getWordTypes() {
- return this._getParsedCells().filter(cell => cell.getWord() !== undefined)
+ get wordTypes() {
+ return this.parsedCells.filter(cell => cell.getWord() !== undefined)
- return this._getParsedCells()
- .map(check => check.getErrorIfAny())
- .filter(identity => identity)
+ return this.parsedCells.map(check => check.getErrorIfAny()).filter(identity => identity)
- get singleNodeUsedTwiceErrors() {
+ get singleParserUsedTwiceErrors() {
- const parent = this.getParent()
- const hits = parent.getChildInstancesOfNodeTypeId(this.getDefinition().id)
+ const parent = this.parent
+ const hits = parent.getChildInstancesOfParserId(this.definition.id)
- if (node === this) errors.push(new NodeTypeUsedMultipleTimesError(node))
+ if (node === this) errors.push(new ParserUsedMultipleTimesError(node))
+ get uniqueLineAppearsTwiceErrors() {
+ const errors = []
+ const parent = this.parent
+ const hits = parent.getChildInstancesOfParserId(this.definition.id)
+ if (hits.length > 1) {
+ const set = new Set()
+ hits.forEach((node, index) => {
+ const line = node.getLine()
+ if (set.has(line)) errors.push(new ParserUsedMultipleTimesError(node))
+ set.add(line)
+ })
+ }
+ return errors
+ }
- if (this.getDefinition().isSingle) errors = errors.concat(this.singleNodeUsedTwiceErrors)
+ const def = this.definition
+ if (def.isSingle) errors = errors.concat(this.singleParserUsedTwiceErrors)
+ if (def.isUniqueLine) errors = errors.concat(this.uniqueLineAppearsTwiceErrors)
Changed around line 14245: class GrammarBackedNode extends TreeNode {
- _getParsedCells() {
- return this.getDefinition()
- .getCellParser()
- .getCellArray(this)
+ get parsedCells() {
+ return this.definition.cellParser.getCellArray(this)
- getLineCellTypes() {
- return this._getParsedCells()
- .map(slot => slot.getCellTypeId())
- .join(" ")
+ get lineCellTypes() {
+ return this.parsedCells.map(slot => slot.cellTypeId).join(" ")
- return this._getParsedCells()
+ return this.parsedCells
- const def = slot._getCellTypeDefinition()
+ const def = slot.cellTypeDefinition
- return def ? def._getPreludeKindId() : PreludeCellTypeIds.anyCell
+ return def ? def.preludeKindId : PreludeCellTypeIds.anyCell
- return this._getParsedCells()
- .map(slot => slot.getHighlightScope() || defaultScope)
- .join(" ")
+ return this.parsedCells.map(slot => slot.highlightScope || defaultScope).join(" ")
- getCellDefinitionLineNumbers() {
- return this._getParsedCells().map(cell => cell.getDefinitionLineNumber())
+ get cellDefinitionLineNumbers() {
+ return this.parsedCells.map(cell => cell.definitionLineNumber)
- const indentCharacter = this.getDefinition()._getCompilerObject()[GrammarConstantsCompiler.indentCharacter]
- const indent = this.getIndentation()
+ const indentCharacter = this.definition._getCompilerObject()[GrammarConstantsCompiler.indentCharacter]
+ const indent = this.indentation
- const def = node.getDefinition()
- if (def.isRequired() || def.isSingle) fields[node.getWord(0)] = node.getContent()
+ const def = node.definition
+ if (def.isRequired() || def.isSingle) fields[node.getWord(0)] = node.content
- const compiler = this.getDefinition()._getCompilerObject()
+ const compiler = this.definition._getCompilerObject()
- return str !== undefined ? TreeUtils.formatStr(str, catchAllCellDelimiter, Object.assign(this._getFields(), this.cells)) : this.getLine()
+ return str !== undefined ? Utils.formatStr(str, catchAllCellDelimiter, Object.assign(this._getFields(), this.cells)) : this.getLine()
+ }
+ get listDelimiter() {
+ return this.definition._getFromExtended(GrammarConstants.listDelimiter)
+ }
+ get contentKey() {
+ return this.definition._getFromExtended(GrammarConstants.contentKey)
+ }
+ get childrenKey() {
+ return this.definition._getFromExtended(GrammarConstants.childrenKey)
+ }
+ get childrenAreTextBlob() {
+ return this.definition._isBlobParser()
+ }
+ get isArrayElement() {
+ return this.definition._hasFromExtended(GrammarConstants.uniqueFirstWord) ? false : !this.definition.isSingle
+ }
+ get list() {
+ return this.listDelimiter ? this.content.split(this.listDelimiter) : super.list
+ }
+ get typedContent() {
+ // todo: probably a better way to do this, perhaps by defining a cellDelimiter at the node level
+ // todo: this currently parse anything other than string types
+ if (this.listDelimiter) return this.content.split(this.listDelimiter)
+ const cells = this.parsedCells
+ if (cells.length === 2) return cells[1].parsed
+ return this.content
+ }
+ get typedTuple() {
+ const key = this.firstWord
+ if (this.childrenAreTextBlob) return [key, this.childrenToString()]
+ const { typedContent, contentKey, childrenKey } = this
+ if (contentKey || childrenKey) {
+ let obj = {}
+ if (childrenKey) obj[childrenKey] = this.childrenToString()
+ else obj = this.typedMap
+ if (contentKey) {
+ obj[contentKey] = typedContent
+ }
+ return [key, obj]
+ }
+ const hasChildren = this.length > 0
+ const hasChildrenNoContent = typedContent === undefined && hasChildren
+ const shouldReturnValueAsObject = hasChildrenNoContent
+ if (shouldReturnValueAsObject) return [key, this.typedMap]
+ const hasChildrenAndContent = typedContent !== undefined && hasChildren
+ const shouldReturnValueAsContentPlusChildren = hasChildrenAndContent
+ // If the node has a content and a subtree return it as a string, as
+ // Javascript object values can't be both a leaf and a tree.
+ if (shouldReturnValueAsContentPlusChildren) return [key, this.contentWithChildren]
+ return [key, typedContent]
+ }
+ get _shouldSerialize() {
+ const should = this.shouldSerialize
+ return should === undefined ? true : should
+ get typedMap() {
+ const obj = {}
+ this.forEach(node => {
+ if (!node._shouldSerialize) return true
+ const tuple = node.typedTuple
+ if (!node.isArrayElement) obj[tuple[0]] = tuple[1]
+ else {
+ if (!obj[tuple[0]]) obj[tuple[0]] = []
+ obj[tuple[0]].push(tuple[1])
+ }
+ })
+ return obj
+ }
+ fromTypedMap() {}
- const def = this.getDefinition()
+ const def = this.definition
- if (def.isTerminalNodeType()) return indent + compiledLine
+ if (def.isTerminalParser()) return indent + compiledLine
Changed around line 14373: ${indent}${closeChildrenString}`
- this._getParsedCells().forEach(cell => {
- const cellTypeId = cell.getCellTypeId()
- if (!cell.isCatchAll()) cells[cellTypeId] = cell.getParsed()
+ this.parsedCells.forEach(cell => {
+ const cellTypeId = cell.cellTypeId
+ if (!cell.isCatchAll()) cells[cellTypeId] = cell.parsed
- cells[cellTypeId].push(cell.getParsed())
+ cells[cellTypeId].push(cell.parsed)
- class BlobNode extends GrammarBackedNode {
- createParser() {
- return new TreeNode.Parser(BlobNode, {})
+ class BlobParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(BlobParser, {})
- class UnknownNodeTypeNode extends GrammarBackedNode {
- createParser() {
- return new TreeNode.Parser(UnknownNodeTypeNode, {})
+ class UnknownParserNode extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(UnknownParserNode, {})
- return [new UnknownNodeTypeError(this)]
+ return [new UnknownParserError(this)]
- constructor(node, index, typeDef, cellTypeId, isCatchAll, nodeTypeDef) {
+ constructor(node, index, typeDef, cellTypeId, isCatchAll, parserDefinitionParser) {
- this._nodeTypeDefinition = nodeTypeDef
+ this._parserDefinitionParser = parserDefinitionParser
- getDefinitionLineNumber() {
- return this._typeDef.getLineNumber()
- }
- getSQLiteType() {
- return SQLiteTypes.text
+ get definitionLineNumber() {
+ return this._typeDef.lineNumber
- getCellTypeId() {
+ get cellTypeId() {
- getCellIndex() {
+ get cellIndex() {
- return this._getCellTypeDefinition().get(GrammarConstants.min) || "0"
+ return this.cellTypeDefinition.get(GrammarConstants.min) || "0"
- return this._getCellTypeDefinition().get(GrammarConstants.max) || "100"
+ return this.cellTypeDefinition.get(GrammarConstants.max) || "100"
- return this._getCellTypeDefinition().get(GrammarConstants.examples) || ""
+ return this.cellTypeDefinition.get(GrammarConstants.examples) || ""
- getHighlightScope() {
- const definition = this._getCellTypeDefinition()
- if (definition) return definition.getHighlightScope() // todo: why the undefined?
+ get highlightScope() {
+ const definition = this.cellTypeDefinition
+ if (definition) return definition.highlightScope // todo: why the undefined?
- const cellDef = this._getCellTypeDefinition()
- let words = cellDef ? cellDef._getAutocompleteWordOptions(this.getNode().getRootNode()) : []
+ const cellDef = this.cellTypeDefinition
+ let words = cellDef ? cellDef._getAutocompleteWordOptions(this.getNode().root) : []
Changed around line 14459: class AbstractGrammarBackedCell {
- const cellDef = this._getCellTypeDefinition()
+ const cellDef = this.cellTypeDefinition
- if (enumOptions) return TreeUtils.getRandomString(1, enumOptions.split(" "))
+ if (enumOptions) return Utils.getRandomString(1, enumOptions.split(" "))
- const cellDef = this._getCellTypeDefinition()
+ const cellDef = this.cellTypeDefinition
Changed around line 14487: ${options.toString(1)}`
- _getCellTypeDefinition() {
+ get cellTypeDefinition() {
- _getFullLine() {
- return this.getNode().getLine()
- }
- return this._getFullLine().split(" ")[0] // todo: WordBreakSymbol
+ return this.getNode().getLine().split(" ")[0] // todo: WordBreakSymbol
- return this._getCellTypeDefinition().isValid(word, this.getNode().getRootNode()) && this._isValid()
+ return this.cellTypeDefinition.isValid(word, this.getNode().root) && this._isValid()
Changed around line 14513: class GrammarBitCell extends AbstractGrammarBackedCell {
- return TreeUtils.getRandomString(1, "01".split(""))
+ return Utils.getRandomString(1, "01".split(""))
- getRegexString() {
+ get regexString() {
- getParsed() {
+ get parsed() {
Changed around line 14542: class GrammarIntCell extends GrammarNumericCell {
- return TreeUtils.randomUniformInt(parseInt(this.min), parseInt(this.max), seed).toString()
+ return Utils.randomUniformInt(parseInt(this.min), parseInt(this.max), seed).toString()
- getRegexString() {
+ get regexString() {
- getSQLiteType() {
- return SQLiteTypes.integer
- }
- getParsed() {
+ get parsed() {
Changed around line 14560: class GrammarFloatCell extends GrammarNumericCell {
- getSQLiteType() {
- return SQLiteTypes.float
- }
- return TreeUtils.randomUniformFloat(parseFloat(this.min), parseFloat(this.max), seed).toString()
+ return Utils.randomUniformFloat(parseFloat(this.min), parseFloat(this.max), seed).toString()
- getRegexString() {
+ get regexString() {
- getParsed() {
+ get parsed() {
Changed around line 14586: class GrammarBoolCell extends AbstractGrammarBackedCell {
- return TreeUtils.getRandomString(1, ["1", "true", "t", "yes", "0", "false", "f", "no"])
+ return Utils.getRandomString(1, ["1", "true", "t", "yes", "0", "false", "f", "no"])
- getRegexString() {
+ get regexString() {
- getParsed() {
+ get parsed() {
Changed around line 14605: class GrammarAnyCell extends AbstractGrammarBackedCell {
- const examples = this._getCellTypeDefinition()._getFromExtended(GrammarConstants.examples)
- if (examples) return TreeUtils.getRandomString(1, examples.split(" "))
- return this._nodeTypeDefinition.getNodeTypeIdFromDefinition() + "-" + this.constructor.name
+ const examples = this.cellTypeDefinition._getFromExtended(GrammarConstants.examples)
+ if (examples) return Utils.getRandomString(1, examples.split(" "))
+ return this._parserDefinitionParser.parserIdFromDefinition + "-" + this.constructor.name
- getRegexString() {
+ get regexString() {
- getParsed() {
+ get parsed() {
- return this._nodeTypeDefinition._getCruxIfAny()
+ return this._parserDefinitionParser.cruxIfAny
Changed around line 14633: class GrammarExtraWordCellTypeCell extends AbstractGrammarBackedCell {
- getParsed() {
+ get parsed() {
Changed around line 14651: class GrammarUnknownCellTypeCell extends AbstractGrammarBackedCell {
- getParsed() {
+ get parsed() {
Changed around line 14663: class AbstractTreeError {
- return this.getLineNumber() - 1
+ return this.lineNumber - 1
- getLineNumber() {
+ get lineNumber() {
- return this.getCellIndex() === this.getNode().getWordIndexAtCharacterIndex(characterIndex)
+ return this.cellIndex === this.getNode().getWordIndexAtCharacterIndex(characterIndex)
Changed around line 14683: class AbstractTreeError {
- return this.getNode().getIndentation()
+ return this.getNode().indentation
- const suggestion = this.getSuggestionMessage()
+ const suggestion = this.suggestionMessage
- getNodeTypeId() {
- return this.getNode()
- .getDefinition()
- .getNodeTypeIdFromDefinition()
+ get parserId() {
+ return this.getNode().definition.parserIdFromDefinition
- el.appendChild(
- document.createTextNode(
- this.getIndent() +
- this.getNode()
- .getDefinition()
- .getLineHints()
- )
- )
+ el.appendChild(document.createTextNode(this.getIndent() + this.getNode().definition.lineHints))
- el.appendChild(document.createTextNode(this.getIndent() + this.getMessage()))
+ el.appendChild(document.createTextNode(this.getIndent() + this.message))
- el.appendChild(document.createTextNode(this.getIndent() + `${this.getErrorTypeName()}. Suggestion: ${suggestion}`))
+ el.appendChild(document.createTextNode(this.getIndent() + `${this.errorTypeName}. Suggestion: ${suggestion}`))
Changed around line 14720: class AbstractTreeError {
- return this.getNode()
- .getHandGrammarProgram()
- .getExtensionName()
+ return this.getNode().handGrammarProgram.extensionName
- getErrorTypeName() {
+ get errorTypeName() {
- getCellIndex() {
+ get cellIndex() {
- type: this.getErrorTypeName(),
- line: this.getLineNumber(),
- cell: this.getCellIndex(),
- suggestion: this.getSuggestionMessage(),
+ type: this.errorTypeName,
+ line: this.lineNumber,
+ cell: this.cellIndex,
+ suggestion: this.suggestionMessage,
- message: this.getMessage()
+ message: this.message
- return this.getSuggestionMessage() !== ""
+ return this.suggestionMessage !== ""
- getSuggestionMessage() {
+ get suggestionMessage() {
- return this.getMessage()
+ return this.message
- getMessage() {
- return `${this.getErrorTypeName()} at line ${this.getLineNumber()} cell ${this.getCellIndex()}.`
+ get message() {
+ return `${this.errorTypeName} at line ${this.lineNumber} cell ${this.cellIndex}.`
Changed around line 14760: class AbstractCellError extends AbstractTreeError {
- getCell() {
+ get cell() {
- getCellIndex() {
- return this._cell.getCellIndex()
+ get cellIndex() {
+ return this._cell.cellIndex
- _getWordSuggestion() {
- return TreeUtils.didYouMean(
- this.getCell().getWord(),
- this.getCell()
- .getAutoCompleteWords()
- .map(option => option.text)
+ get wordSuggestion() {
+ return Utils.didYouMean(
+ this.cell.getWord(),
+ this.cell.getAutoCompleteWords().map(option => option.text)
- class UnknownNodeTypeError extends AbstractTreeError {
- getMessage() {
+ class UnknownParserError extends AbstractTreeError {
+ get message() {
- const parentNode = node.getParent()
+ const parentNode = node.parent
- return super.getMessage() + ` Invalid nodeType "${node.getFirstWord()}". Valid nodeTypes are: ${TreeUtils._listToEnglishText(options, 7)}.`
+ return super.message + ` Invalid parser "${node.firstWord}". Valid parsers are: ${Utils._listToEnglishText(options, 7)}.`
- _getWordSuggestion() {
+ get wordSuggestion() {
- const parentNode = node.getParent()
- return TreeUtils.didYouMean(node.getFirstWord(), parentNode.getAutocompleteResults("", 0).map(option => option.text))
+ const parentNode = node.parent
+ return Utils.didYouMean(
+ node.firstWord,
+ parentNode.getAutocompleteResults("", 0).map(option => option.text)
+ )
- getSuggestionMessage() {
- const suggestion = this._getWordSuggestion()
+ get suggestionMessage() {
+ const suggestion = this.wordSuggestion
- if (suggestion) return `Change "${node.getFirstWord()}" to "${suggestion}"`
+ if (suggestion) return `Change "${node.firstWord}" to "${suggestion}"`
- const suggestion = this._getWordSuggestion()
- if (suggestion) this.getNode().setWord(this.getCellIndex(), suggestion)
+ const suggestion = this.wordSuggestion
+ if (suggestion) this.getNode().setWord(this.cellIndex, suggestion)
- class BlankLineError extends UnknownNodeTypeError {
- getMessage() {
- return super.getMessage() + ` Line: "${this.getNode().getLine()}". Blank lines are errors.`
+ class BlankLineError extends UnknownParserError {
+ get message() {
+ return super.message + ` Line: "${this.getNode().getLine()}". Blank lines are errors.`
- getSuggestionMessage() {
- return `Delete line ${this.getLineNumber()}`
+ get suggestionMessage() {
+ return `Delete line ${this.lineNumber}`
- class MissingRequiredNodeTypeError extends AbstractTreeError {
- constructor(node, missingNodeTypeId) {
+ class MissingRequiredParserError extends AbstractTreeError {
+ constructor(node, missingParserId) {
- this._missingNodeTypeId = missingNodeTypeId
+ this._missingParserId = missingParserId
+ }
+ get message() {
+ return super.message + ` A "${this._missingParserId}" is required.`
- getMessage() {
- return super.getMessage() + ` A "${this._missingNodeTypeId}" is required.`
+ }
+ class ParserUsedMultipleTimesError extends AbstractTreeError {
+ get message() {
+ return super.message + ` Multiple "${this.getNode().firstWord}" found.`
+ }
+ get suggestionMessage() {
+ return `Delete line ${this.lineNumber}`
+ }
+ applySuggestion() {
+ return this.getNode().destroy()
- class NodeTypeUsedMultipleTimesError extends AbstractTreeError {
- getMessage() {
- return super.getMessage() + ` Multiple "${this.getNode().getFirstWord()}" found.`
+ class LineAppearsMultipleTimesError extends AbstractTreeError {
+ get message() {
+ return super.message + ` "${this.getNode().getLine()}" appears multiple times.`
- getSuggestionMessage() {
- return `Delete line ${this.getLineNumber()}`
+ get suggestionMessage() {
+ return `Delete line ${this.lineNumber}`
- getMessage() {
- return super.getMessage() + ` No cellType "${this.getCell().getCellTypeId()}" found. Language grammar for "${this.getExtension()}" may need to be fixed.`
+ get message() {
+ return super.message + ` No cellType "${this.cell.cellTypeId}" found. Language grammar for "${this.getExtension()}" may need to be fixed.`
- getMessage() {
- return super.getMessage() + ` "${this.getCell().getWord()}" does not fit in cellType "${this.getCell().getCellTypeId()}".`
+ get message() {
+ return super.message + ` "${this.cell.getWord()}" does not fit in cellType "${this.cell.cellTypeId}".`
- getSuggestionMessage() {
- const suggestion = this._getWordSuggestion()
- if (suggestion) return `Change "${this.getCell().getWord()}" to "${suggestion}"`
+ get suggestionMessage() {
+ const suggestion = this.wordSuggestion
+ if (suggestion) return `Change "${this.cell.getWord()}" to "${suggestion}"`
- const suggestion = this._getWordSuggestion()
- if (suggestion) this.getNode().setWord(this.getCellIndex(), suggestion)
+ const suggestion = this.wordSuggestion
+ if (suggestion) this.getNode().setWord(this.cellIndex, suggestion)
- getMessage() {
- return super.getMessage() + ` Extra word "${this.getCell().getWord()}" in ${this.getNodeTypeId()}.`
+ get message() {
+ return super.message + ` Extra word "${this.cell.getWord()}" in ${this.parserId}.`
- getSuggestionMessage() {
- return `Delete word "${this.getCell().getWord()}" at cell ${this.getCellIndex()}`
+ get suggestionMessage() {
+ return `Delete word "${this.cell.getWord()}" at cell ${this.cellIndex}`
- return this.getNode().deleteWordAt(this.getCellIndex())
+ return this.getNode().deleteWordAt(this.cellIndex)
- getMessage() {
- return super.getMessage() + ` Missing word for cell "${this.getCell().getCellTypeId()}".`
+ get message() {
+ return super.message + ` Missing word for cell "${this.cell.cellTypeId}".`
- class AbstractGrammarWordTestNode extends TreeNode {}
- class GrammarRegexTestNode extends AbstractGrammarWordTestNode {
+ class AbstractGrammarWordTestParser extends TreeNode {}
+ class GrammarRegexTestParser extends AbstractGrammarWordTestParser {
- if (!this._regex) this._regex = new RegExp("^" + this.getContent() + "$")
+ if (!this._regex) this._regex = new RegExp("^" + this.content + "$")
- class GrammarReservedWordsTestNode extends AbstractGrammarWordTestNode {
+ class GrammarReservedWordsTestParser extends AbstractGrammarWordTestParser {
- if (!this._set) this._set = new Set(this.getContent().split(" "))
+ if (!this._set) this._set = new Set(this.content.split(" "))
- class EnumFromCellTypesTestNode extends AbstractGrammarWordTestNode {
+ class EnumFromCellTypesTestParser extends AbstractGrammarWordTestParser {
Changed around line 14913: class EnumFromCellTypesTestNode extends AbstractGrammarWordTestNode {
- programRootNode
- .getAllTypedWords()
+ programRootNode.allTypedWords
Changed around line 14926: class EnumFromCellTypesTestNode extends AbstractGrammarWordTestNode {
- class GrammarEnumTestNode extends AbstractGrammarWordTestNode {
+ class GrammarEnumTestNode extends AbstractGrammarWordTestParser {
- if (!this._map) this._map = TreeUtils.arrayToMap(this.getWordsFrom(1))
+ if (!this._map) this._map = Utils.arrayToMap(this.getWordsFrom(1))
- class cellTypeDefinitionNode extends AbstractExtendibleTreeNode {
- createParser() {
+ class cellTypeDefinitionParser extends AbstractExtendibleTreeNode {
+ createParserCombinator() {
- types[GrammarConstants.regex] = GrammarRegexTestNode
- types[GrammarConstants.reservedWords] = GrammarReservedWordsTestNode
- types[GrammarConstants.enumFromCellTypes] = EnumFromCellTypesTestNode
+ types[GrammarConstants.regex] = GrammarRegexTestParser
+ types[GrammarConstants.reservedWords] = GrammarReservedWordsTestParser
+ types[GrammarConstants.enumFromCellTypes] = EnumFromCellTypesTestParser
- types[GrammarConstants.todoComment] = TreeNode
+ types[GrammarConstants.comment] = TreeNode
- return new TreeNode.Parser(undefined, types)
+ return new TreeNode.ParserCombinator(undefined, types)
- _getId() {
+ get id() {
- _getIdToNodeMap() {
- return this.getParent().getCellTypeDefinitions()
+ get idToNodeMap() {
+ return this.parent.cellTypeDefinitions
- return `get ${this.getCellTypeId()}() {
+ return `get ${this.cellTypeId}() {
- return `get ${this.getCellTypeId()}() {
+ return `get ${this.cellTypeId}() {
- return this._getPreludeKind() || GrammarAnyCell
+ return this.preludeKind || GrammarAnyCell
- _getPreludeKind() {
+ get preludeKind() {
- _getPreludeKindId() {
+ get preludeKindId() {
- return arr[arr.length - 1]._getId()
+ return arr[arr.length - 1].id
- getHighlightScope() {
+ get highlightScope() {
- const preludeKind = this._getPreludeKind()
+ const preludeKind = this.preludeKind
Changed around line 15008: class cellTypeDefinitionNode extends AbstractExtendibleTreeNode {
- getRegexString() {
+ get regexString() {
+ _getAllTests() {
+ return this._getChildrenByParserInExtended(AbstractGrammarWordTestParser)
+ }
- return this._getChildrenByNodeConstructorInExtended(AbstractGrammarWordTestNode).every(node => node.isValid(str, programRootNode))
+ return this._getAllTests().every(node => node.isValid(str, programRootNode))
- getCellTypeId() {
+ get cellTypeId() {
Changed around line 15027: class AbstractCellParser {
- getCatchAllCellTypeId() {
+ get catchAllCellTypeId() {
- getLineHints() {
- const catchAllCellTypeId = this.getCatchAllCellTypeId()
- const nodeTypeId = this._definition._getCruxIfAny() || this._definition._getId() // todo: cleanup
- return `${nodeTypeId}: ${this.getRequiredCellTypeIds().join(" ")}${catchAllCellTypeId ? ` ${catchAllCellTypeId}...` : ""}`
+ get lineHints() {
+ const catchAllCellTypeId = this.catchAllCellTypeId
+ const parserId = this._definition.cruxIfAny || this._definition.id // todo: cleanup
+ return `${parserId}: ${this.getRequiredCellTypeIds().join(" ")}${catchAllCellTypeId ? ` ${catchAllCellTypeId}...` : ""}`
- const parameters = this._definition._getFromExtended(GrammarConstants.cells)
- return parameters ? parameters.split(" ") : []
+ if (!this._requiredCellTypeIds) {
+ const parameters = this._definition._getFromExtended(GrammarConstants.cells)
+ this._requiredCellTypeIds = parameters ? parameters.split(" ") : []
+ }
+ return this._requiredCellTypeIds
Changed around line 15050: class AbstractCellParser {
- const wordCount = node ? node.getWords().length : 0
+ const wordCount = node ? node.words.length : 0
- const grammarProgram = def.getLanguageDefinitionProgram()
+ const grammarProgram = def.languageDefinitionProgram
Changed around line 15060: class AbstractCellParser {
- let cellTypeId = isCatchAll ? this.getCatchAllCellTypeId() : this._getCellTypeId(cellIndex, requiredCellTypeIds, wordCount)
+ let cellTypeId = isCatchAll ? this.catchAllCellTypeId : this._getCellTypeId(cellIndex, requiredCellTypeIds, wordCount)
Changed around line 15070: class AbstractCellParser {
- cells[cellIndex] = new cellConstructor(node, cellIndex, cellTypeDefinition, cellTypeId, isCatchAll, def)
+ const anyCellConstructor = cellConstructor
+ cells[cellIndex] = new anyCellConstructor(node, cellIndex, cellTypeDefinition, cellTypeId, isCatchAll, def)
Changed around line 15090: class OmnifixCellParser extends AbstractCellParser {
- const program = node ? node.getRootNode() : undefined
- const grammarProgram = def.getLanguageDefinitionProgram()
- const words = node ? node.getWords() : []
+ const program = node ? node.root : undefined
+ const grammarProgram = def.languageDefinitionProgram
+ const words = node ? node.words : []
- const catchAllCellTypeId = this.getCatchAllCellTypeId()
+ const catchAllCellTypeId = this.catchAllCellTypeId
Changed around line 15103: class OmnifixCellParser extends AbstractCellParser {
- cells.push(new cellConstructor(node, wordIndex, cellTypeDefinition, cellTypeDefinition._getId(), false, def))
+ cells.push(new cellConstructor(node, wordIndex, cellTypeDefinition, cellTypeDefinition.id, false, def))
Changed around line 15118: class OmnifixCellParser extends AbstractCellParser {
- cells.push(new cellConstructor(node, wordCount + index, cellTypeDef, cellTypeDef._getId(), false, def))
+ cells.push(new cellConstructor(node, wordCount + index, cellTypeDef, cellTypeDef.id, false, def))
- class GrammarExampleNode extends TreeNode {}
- class GrammarCompilerNode extends TreeNode {
- createParser() {
+ class GrammarExampleParser extends TreeNode {}
+ class GrammarCompilerParser extends TreeNode {
+ createParserCombinator() {
Changed around line 15138: class GrammarCompilerNode extends TreeNode {
- return new TreeNode.Parser(undefined, map)
+ return new TreeNode.ParserCombinator(undefined, map)
- class GrammarNodeTypeConstant extends TreeNode {
+ class AbstractParserConstantParser extends TreeNode {
+ constructor(children, line, parent) {
+ super(children, line, parent)
+ parent[this.identifier] = this.constantValue
+ }
- return `get ${this.getIdentifier()}() { return ${this.getConstantValueAsJsText()} }`
+ return `get ${this.identifier}() { return ${this.constantValueAsJsText} }`
- getIdentifier() {
+ get identifier() {
- getConstantValueAsJsText() {
+ get constantValueAsJsText() {
- getConstantValue() {
- return JSON.parse(this.getConstantValueAsJsText())
+ get constantValue() {
+ return JSON.parse(this.constantValueAsJsText)
- class GrammarNodeTypeConstantInt extends GrammarNodeTypeConstant {}
- class GrammarNodeTypeConstantString extends GrammarNodeTypeConstant {
- getConstantValueAsJsText() {
- return "`" + TreeUtils.escapeBackTicks(this.getConstantValue()) + "`"
+ class GrammarParserConstantInt extends AbstractParserConstantParser {}
+ class GrammarParserConstantString extends AbstractParserConstantParser {
+ get constantValueAsJsText() {
+ return "`" + Utils.escapeBackTicks(this.constantValue) + "`"
- getConstantValue() {
+ get constantValue() {
- class GrammarNodeTypeConstantFloat extends GrammarNodeTypeConstant {}
- class GrammarNodeTypeConstantBoolean extends GrammarNodeTypeConstant {}
- class AbstractGrammarDefinitionNode extends AbstractExtendibleTreeNode {
- createParser() {
+ class GrammarParserConstantFloat extends AbstractParserConstantParser {}
+ class GrammarParserConstantBoolean extends AbstractParserConstantParser {}
+ class AbstractParserDefinitionParser extends AbstractExtendibleTreeNode {
+ createParserCombinator() {
Changed around line 15180: class AbstractGrammarDefinitionNode extends AbstractExtendibleTreeNode {
- GrammarConstants.catchAllNodeType,
+ GrammarConstants.catchAllParser,
+ GrammarConstants.sortTemplate,
+ GrammarConstants.listDelimiter,
+ GrammarConstants.contentKey,
+ GrammarConstants.childrenKey,
+ GrammarConstants.uniqueFirstWord,
+ GrammarConstants.uniqueLine,
- GrammarConstants.baseNodeType,
+ GrammarConstants.baseParser,
- GrammarConstants.abstract,
- GrammarConstants.todoComment
+ GrammarConstants.comment
- map[GrammarConstantsConstantTypes.boolean] = GrammarNodeTypeConstantBoolean
- map[GrammarConstantsConstantTypes.int] = GrammarNodeTypeConstantInt
- map[GrammarConstantsConstantTypes.string] = GrammarNodeTypeConstantString
- map[GrammarConstantsConstantTypes.float] = GrammarNodeTypeConstantFloat
- map[GrammarConstants.compilerNodeType] = GrammarCompilerNode
- map[GrammarConstants.example] = GrammarExampleNode
- return new TreeNode.Parser(undefined, map)
+ map[GrammarConstantsConstantTypes.boolean] = GrammarParserConstantBoolean
+ map[GrammarConstantsConstantTypes.int] = GrammarParserConstantInt
+ map[GrammarConstantsConstantTypes.string] = GrammarParserConstantString
+ map[GrammarConstantsConstantTypes.float] = GrammarParserConstantFloat
+ map[GrammarConstants.compilerParser] = GrammarCompilerParser
+ map[GrammarConstants.example] = GrammarExampleParser
+ return new TreeNode.ParserCombinator(undefined, map, [{ regex: HandGrammarProgram.parserFullRegex, parser: parserDefinitionParser }])
+ }
+ get sortSpec() {
+ const sortSections = new Map()
+ const sortIndices = new Map()
+ const sortTemplate = this.get(GrammarConstants.sortTemplate)
+ if (!sortTemplate) return { sortSections, sortIndices }
+ sortTemplate.split(" ").forEach((section, sectionIndex) => section.split(" ").forEach(word => sortSections.set(word, sectionIndex)))
+ sortTemplate.split(" ").forEach((word, index) => sortIndices.set(word, index))
+ return { sortSections, sortIndices }
- const inScope = this.getFirstWordMapWithDefinitions()
- const thisId = this._getId()
+ const inScope = this.firstWordMapWithDefinitions
+ const thisId = this.id
- const map = def.getFirstWordMapWithDefinitions()
- const id = def._getId()
+ const map = def.firstWordMapWithDefinitions
+ const id = def.id
- const description = def.getDescription()
+ const description = def.description
- const description = this.getDescription()
+ const description = this.description
Changed around line 15254: interface ${thisId} {
- getTableNameIfAny() {
- return this.getFrom(`${GrammarConstantsConstantTypes.string} ${GrammarConstantsMisc.tableName}`)
- }
- getSQLiteTableColumns() {
- return this._getConcreteNonErrorInScopeNodeDefinitions(this._getInScopeNodeTypeIds()).map(node => {
- const firstNonKeywordCellType = node.getCellParser().getCellArray()[1]
- const type = firstNonKeywordCellType ? firstNonKeywordCellType.getSQLiteType() : SQLiteTypes.text
- return {
- columnName: node._getIdWithoutSuffix(),
- type
- }
- })
- }
- toSQLiteTableSchema() {
- const columns = this.getSQLiteTableColumns().map(columnDef => `${columnDef.columnName} ${columnDef.type}`)
- return `create table ${this.getTableNameIfAny() || this._getId()} (
- id TEXT NOT NULL PRIMARY KEY,
- ${columns.join(",\n ")}
- );`
- }
- _getId() {
- return this.getWord(0)
- }
- return this._getId()
+ return this.getWord(0)
- _getIdWithoutSuffix() {
- return this._getId().replace(HandGrammarProgram.nodeTypeSuffixRegex, "")
+ get idWithoutSuffix() {
+ return this.id.replace(HandGrammarProgram.parserSuffixRegex, "")
- getConstantsObject() {
+ get constantsObject() {
- Object.keys(obj).forEach(key => {
- obj[key] = obj[key].getConstantValue()
- })
+ Object.keys(obj).forEach(key => (obj[key] = obj[key].constantValue))
- const items = extended ? this._getChildrenByNodeConstructorInExtended(GrammarNodeTypeConstant) : this.getChildrenByNodeConstructor(GrammarNodeTypeConstant)
+ const items = extended ? this._getChildrenByParserInExtended(AbstractParserConstantParser) : this.getChildrenByParser(AbstractParserConstantParser)
- items.forEach(node => {
- obj[node.getIdentifier()] = node
- })
+ items.forEach(node => (obj[node.identifier] = node))
- getExamples() {
- return this._getChildrenByNodeConstructorInExtended(GrammarExampleNode)
+ get examples() {
+ return this._getChildrenByParserInExtended(GrammarExampleParser)
- getNodeTypeIdFromDefinition() {
+ get parserIdFromDefinition() {
- // todo: remove? just reused nodeTypeId
- _getGeneratedClassName() {
- return this.getNodeTypeIdFromDefinition()
+ // todo: remove? just reused parserId
+ get generatedClassName() {
+ return this.parserIdFromDefinition
- _hasValidNodeTypeId() {
- return !!this._getGeneratedClassName()
+ _hasValidParserId() {
+ return !!this.generatedClassName
- return this.has(GrammarConstants.abstract)
- }
- _getConcreteDescendantDefinitions() {
- const defs = this._getProgramNodeTypeDefinitionCache()
- const id = this._getId()
- return Object.values(defs).filter(def => {
- return def._doesExtend(id) && !def._isAbstract()
- })
+ return this.id.startsWith(GrammarConstants.abstractParserPrefix)
- _getCruxIfAny() {
- return this.get(GrammarConstants.crux) || (this._hasFromExtended(GrammarConstants.cruxFromId) ? this._getIdWithoutSuffix() : undefined)
+ get cruxIfAny() {
+ return this.get(GrammarConstants.crux) || (this._hasFromExtended(GrammarConstants.cruxFromId) ? this.idWithoutSuffix : undefined)
- _getRegexMatch() {
+ get regexMatch() {
- _getFirstCellEnumOptions() {
+ get firstCellEnumOptions() {
- getLanguageDefinitionProgram() {
- return this.getParent()
+ get languageDefinitionProgram() {
+ return this.root
- _getCustomJavascriptMethods() {
+ get customJavascriptMethods() {
- getFirstWordMapWithDefinitions() {
- if (!this._cache_firstWordToNodeDefMap) this._cache_firstWordToNodeDefMap = this._createParserInfo(this._getInScopeNodeTypeIds()).firstWordMap
+ get firstWordMapWithDefinitions() {
+ if (!this._cache_firstWordToNodeDefMap) this._cache_firstWordToNodeDefMap = this._createParserInfo(this._getInScopeParserIds()).firstWordMap
- getRunTimeFirstWordsInScope() {
+ get runTimeFirstWordsInScope() {
- const grammarProgram = this.getLanguageDefinitionProgram()
+ const grammarProgram = this.languageDefinitionProgram
Changed around line 15324: ${properties.join("\n")}
- _getCellGettersAndNodeTypeConstants() {
+ get cellGettersAndParserConstants() {
- const grammarProgram = this.getLanguageDefinitionProgram()
+ const grammarProgram = this.languageDefinitionProgram
- Object.values(this._getUniqueConstantNodes(false)).forEach(node => {
- getters.push(node.getGetter())
- })
+ Object.values(this._getUniqueConstantNodes(false)).forEach(node => getters.push(node.getGetter()))
- _createParserInfo(nodeTypeIdsInScope) {
+ _createParserInfo(parserIdsInScope) {
- if (!nodeTypeIdsInScope.length) return result
- const allProgramNodeTypeDefinitionsMap = this._getProgramNodeTypeDefinitionCache()
- Object.keys(allProgramNodeTypeDefinitionsMap)
- .filter(nodeTypeId => allProgramNodeTypeDefinitionsMap[nodeTypeId].isOrExtendsANodeTypeInScope(nodeTypeIdsInScope))
- .filter(nodeTypeId => !allProgramNodeTypeDefinitionsMap[nodeTypeId]._isAbstract())
- .forEach(nodeTypeId => {
- const def = allProgramNodeTypeDefinitionsMap[nodeTypeId]
- const regex = def._getRegexMatch()
- const crux = def._getCruxIfAny()
- const enumOptions = def._getFirstCellEnumOptions()
- if (regex) result.regexTests.push({ regex: regex, nodeConstructor: def.getNodeTypeIdFromDefinition() })
+ if (!parserIdsInScope.length) return result
+ const allProgramParserDefinitionsMap = this.programParserDefinitionCache
+ Object.keys(allProgramParserDefinitionsMap)
+ .filter(parserId => {
+ const def = allProgramParserDefinitionsMap[parserId]
+ return def.isOrExtendsAParserInScope(parserIdsInScope) && !def._isAbstract()
+ })
+ .forEach(parserId => {
+ const def = allProgramParserDefinitionsMap[parserId]
+ const regex = def.regexMatch
+ const crux = def.cruxIfAny
+ const enumOptions = def.firstCellEnumOptions
+ if (regex) result.regexTests.push({ regex: regex, parser: def.parserIdFromDefinition })
- enumOptions.forEach(option => {
- result.firstWordMap[option] = def
- })
+ enumOptions.forEach(option => (result.firstWordMap[option] = def))
- getTopNodeTypeDefinitions() {
- const arr = Object.values(this.getFirstWordMapWithDefinitions())
- arr.sort(TreeUtils.makeSortByFn(definition => definition.getFrequency()))
+ get topParserDefinitions() {
+ const arr = Object.values(this.firstWordMapWithDefinitions)
+ arr.sort(Utils.makeSortByFn(definition => definition.frequency))
- _getMyInScopeNodeTypeIds() {
- const nodeTypesNode = this.getNode(GrammarConstants.inScope)
- return nodeTypesNode ? nodeTypesNode.getWordsFrom(1) : []
+ _getMyInScopeParserIds(target = this) {
+ const parsersNode = target.getNode(GrammarConstants.inScope)
+ const scopedDefinitionIds = target.myScopedParserDefinitions.map(def => def.id)
+ return parsersNode ? parsersNode.getWordsFrom(1).concat(scopedDefinitionIds) : scopedDefinitionIds
- _getInScopeNodeTypeIds() {
+ _getInScopeParserIds() {
- const ids = this._getMyInScopeNodeTypeIds()
+ const ids = this._getMyInScopeParserIds()
- return parentDef ? ids.concat(parentDef._getInScopeNodeTypeIds()) : ids
+ return parentDef ? ids.concat(parentDef._getInScopeParserIds()) : ids
- // Should only one of these node types be present in the parent node?
- return this._hasFromExtended(GrammarConstants.single)
+ const hit = this._getNodeFromExtended(GrammarConstants.single)
+ return hit && hit.get(GrammarConstants.single) !== "false"
+ }
+ get isUniqueLine() {
+ const hit = this._getNodeFromExtended(GrammarConstants.uniqueLine)
+ return hit && hit.get(GrammarConstants.uniqueLine) !== "false"
- getNodeTypeDefinitionByNodeTypeId(nodeTypeId) {
+ getParserDefinitionByParserId(parserId) {
- const def = this._getProgramNodeTypeDefinitionCache()[nodeTypeId]
+ const def = this.programParserDefinitionCache[parserId]
- // todo: cleanup
- this.getLanguageDefinitionProgram()._addDefaultCatchAllBlobNode()
- return this._getProgramNodeTypeDefinitionCache()[nodeTypeId]
+ this.languageDefinitionProgram._addDefaultCatchAllBlobParser() // todo: cleanup. Why did I do this? Needs to be removed or documented.
+ const nodeDef = this.languageDefinitionProgram.programParserDefinitionCache[parserId]
+ if (!nodeDef) throw new Error(`No definition found for parser id "${parserId}". Node: \n---\n${this.asString}\n---`)
+ return nodeDef
- isDefined(nodeTypeId) {
- return !!this._getProgramNodeTypeDefinitionCache()[nodeTypeId]
+ isDefined(parserId) {
+ return !!this.programParserDefinitionCache[parserId]
- _getIdToNodeMap() {
- return this._getProgramNodeTypeDefinitionCache()
+ get idToNodeMap() {
+ return this.programParserDefinitionCache
- if (this._cache_isRoot === undefined) this._cache_isRoot = this._getLanguageRootNode() === this
+ if (this._cache_isRoot === undefined) this._cache_isRoot = this._languageRootNode === this
- _getLanguageRootNode() {
- return this.getParent().getRootNodeTypeDefinitionNode()
+ get _languageRootNode() {
+ return this.root.rootParserDefinition
- _isErrorNodeType() {
- return this.get(GrammarConstants.baseNodeType) === GrammarConstants.errorNode
+ _isErrorParser() {
+ return this.get(GrammarConstants.baseParser) === GrammarConstants.errorParser
- _isBlobNodeType() {
+ _isBlobParser() {
- return this.get(GrammarConstants.baseNodeType) === GrammarConstants.blobNode
+ return this._getFromExtended(GrammarConstants.baseParser) === GrammarConstants.blobParser
- _getErrorMethodToJavascript() {
- if (this._isBlobNodeType()) return "getErrors() { return [] }" // Skips parsing child nodes for perf gains.
- if (this._isErrorNodeType()) return "getErrors() { return this._getErrorNodeErrors() }"
+ get errorMethodToJavascript() {
+ if (this._isBlobParser()) return "getErrors() { return [] }" // Skips parsing child nodes for perf gains.
+ if (this._isErrorParser()) return "getErrors() { return this._getErrorParserErrors() }"
- _getParserToJavascript() {
- if (this._isBlobNodeType())
+ get parserAsJavascript() {
+ if (this._isBlobParser())
- return "createParser() { return new jtree.TreeNode.Parser(this._getBlobNodeCatchAllNodeType())}"
- const parserInfo = this._createParserInfo(this._getMyInScopeNodeTypeIds())
+ return "createParserCombinator() { return new TreeNode.ParserCombinator(this._getBlobParserCatchAllParser())}"
+ const parserInfo = this._createParserInfo(this._getMyInScopeParserIds())
- const catchAllConstructor = this._getCatchAllNodeConstructorToJavascript()
- if (!hasFirstWords && !catchAllConstructor && !regexRules.length) return ""
+ const catchAllParser = this.catchAllParserToJavascript
+ if (!hasFirstWords && !catchAllParser && !regexRules.length) return ""
- ? `Object.assign(Object.assign({}, super.createParser()._getFirstWordMapAsObject()), {` + firstWords.map(firstWord => `"${firstWord}" : ${myFirstWordMap[firstWord].getNodeTypeIdFromDefinition()}`).join(",\n") + "})"
+ ? `Object.assign(Object.assign({}, super.createParserCombinator()._getFirstWordMapAsObject()), {` + firstWords.map(firstWord => `"${firstWord}" : ${myFirstWordMap[firstWord].parserIdFromDefinition}`).join(",\n") + "})"
- return `{regex: /${rule.regex}/, nodeConstructor: ${rule.nodeConstructor}}`
+ return `{regex: /${rule.regex}/, parser: ${rule.parser}}`
- const catchAllStr = catchAllConstructor ? catchAllConstructor : this._amIRoot() ? `this._getBlobNodeCatchAllNodeType()` : "undefined"
- return `createParser() {
- return new jtree.TreeNode.Parser(${catchAllStr}, ${firstWordsStr}, ${regexStr})
+ const catchAllStr = catchAllParser ? catchAllParser : this._amIRoot() ? `this._getBlobParserCatchAllParser()` : "undefined"
+ const scopedParserJavascript = this.myScopedParserDefinitions.map(def => def.asJavascriptClass).join("\n\n")
+ return `createParserCombinator() {${scopedParserJavascript}
+ return new TreeNode.ParserCombinator(${catchAllStr}, ${firstWordsStr}, ${regexStr})
- _getCatchAllNodeConstructorToJavascript() {
- if (this._isBlobNodeType()) return "this._getBlobNodeCatchAllNodeType()"
- const nodeTypeId = this.get(GrammarConstants.catchAllNodeType)
- if (!nodeTypeId) return ""
- const nodeDef = this.getNodeTypeDefinitionByNodeTypeId(nodeTypeId)
- if (!nodeDef) throw new Error(`No definition found for nodeType id "${nodeTypeId}"`)
- return nodeDef._getGeneratedClassName()
+ get myScopedParserDefinitions() {
+ return this.getChildrenByParser(parserDefinitionParser)
+ }
+ get catchAllParserToJavascript() {
+ if (this._isBlobParser()) return "this._getBlobParserCatchAllParser()"
+ const parserId = this.get(GrammarConstants.catchAllParser)
+ if (!parserId) return ""
+ const nodeDef = this.getParserDefinitionByParserId(parserId)
+ return nodeDef.generatedClassName
- _nodeDefToJavascriptClass() {
- const components = [this._getParserToJavascript(), this._getErrorMethodToJavascript(), this._getCellGettersAndNodeTypeConstants(), this._getCustomJavascriptMethods()].filter(identity => identity)
+ get asJavascriptClass() {
+ const components = [this.parserAsJavascript, this.errorMethodToJavascript, this.cellGettersAndParserConstants, this.customJavascriptMethods].filter(identity => identity)
+ const thisClassName = this.generatedClassName
- components.push(`static cachedHandGrammarProgramRoot = new jtree.HandGrammarProgram(\`${TreeUtils.escapeBackTicks(
- this.getParent()
- .toString()
- .replace(/\\/g, "\\\\")
- )}\`)
- getHandGrammarProgram() {
+ components.push(`static cachedHandGrammarProgramRoot = new HandGrammarProgram(\`${Utils.escapeBackTicks(this.parent.toString().replace(/\\/g, "\\\\"))}\`)
+ get handGrammarProgram() {
- const nodeTypeMap = this.getLanguageDefinitionProgram()
- .getValidConcreteAndAbstractNodeTypeDefinitions()
- .map(def => {
- const id = def.getNodeTypeIdFromDefinition()
- return `"${id}": ${id}`
- })
- .join(",\n")
- components.push(`static getNodeTypeMap() { return {${nodeTypeMap} }}`)
+ components.push(`static rootParser = ${thisClassName}`)
- return `class ${this._getGeneratedClassName()} extends ${this._getExtendsClassName()} {
+ return `class ${thisClassName} extends ${this._getExtendsClassName()} {
Changed around line 15479: ${properties.join("\n")}
- return extendedDef ? extendedDef._getGeneratedClassName() : "jtree.GrammarBackedNode"
+ return extendedDef ? extendedDef.generatedClassName : "GrammarBackedNode"
- const items = this._getChildrenByNodeConstructorInExtended(GrammarCompilerNode)
+ const items = this._getChildrenByParserInExtended(GrammarCompilerParser)
Changed around line 15491: ${properties.join("\n")}
- getLineHints() {
- return this.getCellParser().getLineHints()
+ get lineHints() {
+ return this.cellParser.lineHints
- isOrExtendsANodeTypeInScope(firstWordsInScope) {
- const chain = this._getNodeTypeInheritanceSet()
+ isOrExtendsAParserInScope(firstWordsInScope) {
+ const chain = this._getParserInheritanceSet()
- isTerminalNodeType() {
- return !this._getFromExtended(GrammarConstants.inScope) && !this._getFromExtended(GrammarConstants.catchAllNodeType)
+ isTerminalParser() {
+ return !this._getFromExtended(GrammarConstants.inScope) && !this._getFromExtended(GrammarConstants.catchAllParser)
- _getSublimeMatchLine() {
- const regexMatch = this._getRegexMatch()
+ get sublimeMatchLine() {
+ const regexMatch = this.regexMatch
- const cruxMatch = this._getCruxIfAny()
- if (cruxMatch) return `'^ *${TreeUtils.escapeRegExp(cruxMatch)}(?: |$)'`
- const enumOptions = this._getFirstCellEnumOptions()
- if (enumOptions) return `'^ *(${TreeUtils.escapeRegExp(enumOptions.join("|"))})(?: |$)'`
+ const cruxMatch = this.cruxIfAny
+ if (cruxMatch) return `'^ *${Utils.escapeRegExp(cruxMatch)}(?: |$)'`
+ const enumOptions = this.firstCellEnumOptions
+ if (enumOptions) return `'^ *(${Utils.escapeRegExp(enumOptions.join("|"))})(?: |$)'`
- const program = this.getLanguageDefinitionProgram()
- const cellParser = this.getCellParser()
+ const program = this.languageDefinitionProgram
+ const cellParser = this.cellParser
- const catchAllCellTypeId = cellParser.getCatchAllCellTypeId()
+ const catchAllCellTypeId = cellParser.catchAllCellTypeId
- const firstWordHighlightScope = (firstCellTypeDef ? firstCellTypeDef.getHighlightScope() : defaultHighlightScope) + "." + this.getNodeTypeIdFromDefinition()
- const topHalf = ` '${this.getNodeTypeIdFromDefinition()}':
- - match: ${this._getSublimeMatchLine()}
+ const firstWordHighlightScope = (firstCellTypeDef ? firstCellTypeDef.highlightScope : defaultHighlightScope) + "." + this.parserIdFromDefinition
+ const topHalf = ` '${this.parserIdFromDefinition}':
+ - match: ${this.sublimeMatchLine}
Changed around line 15527: ${properties.join("\n")}
- return ` ${index + 1}: ${(cellTypeDefinition.getHighlightScope() || defaultHighlightScope) + "." + cellTypeDefinition.getCellTypeId()}`
+ return ` ${index + 1}: ${(cellTypeDefinition.highlightScope || defaultHighlightScope) + "." + cellTypeDefinition.cellTypeId}`
Changed around line 15539: ${captures}
- match: $
- _getNodeTypeInheritanceSet() {
- if (!this._cache_nodeTypeInheritanceSet) this._cache_nodeTypeInheritanceSet = new Set(this.getAncestorNodeTypeIdsArray())
- return this._cache_nodeTypeInheritanceSet
+ _getParserInheritanceSet() {
+ if (!this._cache_parserInheritanceSet) this._cache_parserInheritanceSet = new Set(this.ancestorParserIdsArray)
+ return this._cache_parserInheritanceSet
- getAncestorNodeTypeIdsArray() {
- if (!this._cache_ancestorNodeTypeIdsArray) {
- this._cache_ancestorNodeTypeIdsArray = this._getAncestorsArray().map(def => def.getNodeTypeIdFromDefinition())
- this._cache_ancestorNodeTypeIdsArray.reverse()
+ get ancestorParserIdsArray() {
+ if (!this._cache_ancestorParserIdsArray) {
+ this._cache_ancestorParserIdsArray = this._getAncestorsArray().map(def => def.parserIdFromDefinition)
+ this._cache_ancestorParserIdsArray.reverse()
- return this._cache_ancestorNodeTypeIdsArray
+ return this._cache_ancestorParserIdsArray
+ }
+ get programParserDefinitionCache() {
+ if (!this._cache_parserDefinitionParsers) this._cache_parserDefinitionParsers = this.isRoot || this.hasParserDefinitions ? this.makeProgramParserDefinitionCache() : this.parent.programParserDefinitionCache
+ return this._cache_parserDefinitionParsers
- _getProgramNodeTypeDefinitionCache() {
- return this.getLanguageDefinitionProgram()._getProgramNodeTypeDefinitionCache()
+ get hasParserDefinitions() {
+ return !!this.getChildrenByParser(parserDefinitionParser).length
- getDescription() {
+ makeProgramParserDefinitionCache() {
+ const scopedParsers = this.getChildrenByParser(parserDefinitionParser)
+ const cache = Object.assign({}, this.parent.programParserDefinitionCache) // todo. We don't really need this. we should just lookup the parent if no local hits.
+ scopedParsers.forEach(parserDefinitionParser => (cache[parserDefinitionParser.parserIdFromDefinition] = parserDefinitionParser))
+ return cache
+ }
+ get description() {
- getFrequency() {
+ get frequency() {
- _getExtendedNodeTypeId() {
- const ancestorIds = this.getAncestorNodeTypeIdsArray()
+ _getExtendedParserId() {
+ const ancestorIds = this.ancestorParserIdsArray
- const crux = this._getCruxIfAny()
- const cellArray = this.getCellParser()
- .getCellArray()
- .filter((item, index) => index) // for now this only works for keyword langs
+ const crux = this.cruxIfAny
+ const cellArray = this.cellParser.getCellArray().filter((item, index) => index) // for now this only works for keyword langs
Changed around line 15587: ${cells.toString(1)}`
- return this._getConcreteNonErrorInScopeNodeDefinitions(this._getInScopeNodeTypeIds())
+ return this._getConcreteNonErrorInScopeNodeDefinitions(this._getInScopeParserIds())
- const crux = this._getCruxIfAny()
- return this.getCellParser()
+ const crux = this.cruxIfAny
+ return this.cellParser
- _shouldSynthesize(def, nodeTypeChain) {
- if (def._isErrorNodeType() || def._isAbstract()) return false
- if (nodeTypeChain.includes(def._getId())) return false
+ _shouldSynthesize(def, parserChain) {
+ if (def._isErrorParser() || def._isAbstract()) return false
+ if (parserChain.includes(def.id)) return false
- _getConcreteNonErrorInScopeNodeDefinitions(nodeTypeIds) {
- const results = []
- nodeTypeIds.forEach(nodeTypeId => {
- const def = this.getNodeTypeDefinitionByNodeTypeId(nodeTypeId)
- if (def._isErrorNodeType()) return true
- else if (def._isAbstract()) {
- def._getConcreteDescendantDefinitions().forEach(def => results.push(def))
- } else {
- results.push(def)
- }
+ // Get all definitions in this current scope down, even ones that are scoped inside other definitions.
+ get inScopeAndDescendantDefinitions() {
+ return this.languageDefinitionProgram._collectAllDefinitions(Object.values(this.programParserDefinitionCache), [])
+ }
+ _collectAllDefinitions(defs, collection = []) {
+ defs.forEach(def => {
+ collection.push(def)
+ def._collectAllDefinitions(def.getChildrenByParser(parserDefinitionParser), collection)
- return results
+ return collection
+ }
+ get cruxPath() {
+ const parentPath = this.parent.cruxPath
+ return (parentPath ? parentPath + " " : "") + this.cruxIfAny
+ }
+ get cruxPathAsColumnName() {
+ return this.cruxPath.replace(/ /g, "_")
+ }
+ // Get every definition that extends from this one, even ones that are scoped inside other definitions.
+ get concreteDescendantDefinitions() {
+ const { inScopeAndDescendantDefinitions, id } = this
+ return Object.values(inScopeAndDescendantDefinitions).filter(def => def._doesExtend(id) && !def._isAbstract())
+ }
+ get concreteInScopeDescendantDefinitions() {
+ // Note: non-recursive.
+ const defs = this.programParserDefinitionCache
+ const id = this.id
+ return Object.values(defs).filter(def => def._doesExtend(id) && !def._isAbstract())
+ }
+ _getConcreteNonErrorInScopeNodeDefinitions(parserIds) {
+ const defs = []
+ parserIds.forEach(parserId => {
+ const def = this.getParserDefinitionByParserId(parserId)
+ if (def._isErrorParser()) return
+ else if (def._isAbstract()) def.concreteInScopeDescendantDefinitions.forEach(def => defs.push(def))
+ else defs.push(def)
+ })
+ return defs
- synthesizeNode(nodeCount = 1, indentCount = -1, nodeTypesAlreadySynthesized = [], seed = Date.now()) {
- let inScopeNodeTypeIds = this._getInScopeNodeTypeIds()
- const catchAllNodeTypeId = this._getFromExtended(GrammarConstants.catchAllNodeType)
- if (catchAllNodeTypeId) inScopeNodeTypeIds.push(catchAllNodeTypeId)
- const thisId = this._getId()
- if (!nodeTypesAlreadySynthesized.includes(thisId)) nodeTypesAlreadySynthesized.push(thisId)
+ synthesizeNode(nodeCount = 1, indentCount = -1, parsersAlreadySynthesized = [], seed = Date.now()) {
+ let inScopeParserIds = this._getInScopeParserIds()
+ const catchAllParserId = this._getFromExtended(GrammarConstants.catchAllParser)
+ if (catchAllParserId) inScopeParserIds.push(catchAllParserId)
+ const thisId = this.id
+ if (!parsersAlreadySynthesized.includes(thisId)) parsersAlreadySynthesized.push(thisId)
- this._getConcreteNonErrorInScopeNodeDefinitions(inScopeNodeTypeIds.filter(nodeTypeId => !nodeTypesAlreadySynthesized.includes(nodeTypeId)))
- .filter(def => this._shouldSynthesize(def, nodeTypesAlreadySynthesized))
+ this._getConcreteNonErrorInScopeNodeDefinitions(inScopeParserIds.filter(parserId => !parsersAlreadySynthesized.includes(parserId)))
+ .filter(def => this._shouldSynthesize(def, parsersAlreadySynthesized))
- const chain = nodeTypesAlreadySynthesized // .slice(0)
- chain.push(def._getId())
- def.synthesizeNode(1, indentCount + 1, chain, seed).forEach(line => {
- lines.push(line)
- })
+ const chain = parsersAlreadySynthesized // .slice(0)
+ chain.push(def.id)
+ def.synthesizeNode(1, indentCount + 1, chain, seed).forEach(line => lines.push(line))
- getCellParser() {
+ get cellParser() {
Changed around line 15679: ${cells.toString(1)}`
- class nodeTypeDefinitionNode extends AbstractGrammarDefinitionNode {}
+ class parserDefinitionParser extends AbstractParserDefinitionParser {}
- class HandGrammarProgram extends AbstractGrammarDefinitionNode {
- createParser() {
+ class HandGrammarProgram extends AbstractParserDefinitionParser {
+ createParserCombinator() {
- map[GrammarConstants.toolingDirective] = TreeNode
- map[GrammarConstants.todoComment] = TreeNode
- return new TreeNode.Parser(UnknownNodeTypeNode, map, [{ regex: HandGrammarProgram.nodeTypeFullRegex, nodeConstructor: nodeTypeDefinitionNode }, { regex: HandGrammarProgram.cellTypeFullRegex, nodeConstructor: cellTypeDefinitionNode }])
- }
+ map[GrammarConstants.comment] = TreeNode
+ return new TreeNode.ParserCombinator(UnknownParserNode, map, [
+ { regex: HandGrammarProgram.blankLineRegex, parser: TreeNode },
+ { regex: HandGrammarProgram.parserFullRegex, parser: parserDefinitionParser },
+ { regex: HandGrammarProgram.cellTypeFullRegex, parser: cellTypeDefinitionParser }
+ ])
+ }
+ // rootParser
- _compileAndEvalGrammar() {
- if (!this.isNodeJs()) this._cache_compiledLoadedNodeTypes = TreeUtils.appendCodeAndReturnValueOnWindow(this.toBrowserJavascript(), this.getRootNodeTypeId()).getNodeTypeMap()
- else {
- const path = require("path")
- const code = this.toNodeJsJavascript(path.join(__dirname, "..", "index.js"))
- try {
- const rootNode = this._requireInVmNodeJsRootNodeTypeConstructor(code)
- this._cache_compiledLoadedNodeTypes = rootNode.getNodeTypeMap()
- if (!this._cache_compiledLoadedNodeTypes) throw new Error(`Failed to getNodeTypeMap`)
- } catch (err) {
- // todo: figure out best error pattern here for debugging
- console.log(err)
- // console.log(`Error in code: `)
- // console.log(new TreeNode(code).toStringWithLineNumbers())
- }
+ _compileAndReturnRootParser() {
+ if (this._cache_rootParser) return this._cache_rootParser
+ if (!this.isNodeJs()) {
+ this._cache_rootParser = Utils.appendCodeAndReturnValueOnWindow(this.toBrowserJavascript(), this.rootParserId).rootParser
+ return this._cache_rootParser
+ }
+ const path = require("path")
+ const code = this.toNodeJsJavascript(__dirname)
+ try {
+ const rootNode = this._requireInVmNodeJsRootParser(code)
+ this._cache_rootParser = rootNode.rootParser
+ if (!this._cache_rootParser) throw new Error(`Failed to rootParser`)
+ } catch (err) {
+ // todo: figure out best error pattern here for debugging
+ console.log(err)
+ // console.log(`Error in code: `)
+ // console.log(new TreeNode(code).toStringWithLineNumbers())
+ return this._cache_rootParser
- trainModel(programs, programConstructor = this.compileAndReturnRootConstructor()) {
- const nodeDefs = this.getValidConcreteAndAbstractNodeTypeDefinitions()
+ get cruxPath() {
+ return ""
+ }
+ trainModel(programs, rootParser = this.compileAndReturnRootParser()) {
+ const nodeDefs = this.validConcreteAndAbstractParserDefinitions
- const matrix = TreeUtils.makeMatrix(nodeDefCountIncludingRoot, nodeDefCountIncludingRoot, 0)
+ const matrix = Utils.makeMatrix(nodeDefCountIncludingRoot, nodeDefCountIncludingRoot, 0)
- const id = def._getId()
+ const id = def.id
- const exampleProgram = new programConstructor(code)
- exampleProgram.getTopDownArray().forEach(node => {
- const nodeIndex = idToIndex[node.getDefinition()._getId()]
- const parentNode = node.getParent()
+ const exampleProgram = new rootParser(code)
+ exampleProgram.topDownArray.forEach(node => {
+ const nodeIndex = idToIndex[node.definition.id]
+ const parentNode = node.parent
- const parentIndex = idToIndex[parentNode.getDefinition()._getId()]
+ const parentIndex = idToIndex[parentNode.definition.id]
Changed around line 15749: class HandGrammarProgram extends AbstractGrammarDefinitionNode {
- const total = TreeUtils.sum(predictionsVector)
+ const total = Utils.sum(predictionsVector)
- id: id,
- def: this.getNodeTypeDefinitionByNodeTypeId(id),
+ id,
+ def: this.getParserDefinitionByParserId(id),
- predictions.sort(TreeUtils.makeSortByFn(prediction => prediction.count)).reverse()
+ predictions.sort(Utils.makeSortByFn(prediction => prediction.count)).reverse()
Changed around line 15769: class HandGrammarProgram extends AbstractGrammarDefinitionNode {
- return model.matrix[node.isRoot() ? 0 : model.idToIndex[node.getDefinition()._getId()]]
+ return model.matrix[node.isRoot() ? 0 : model.idToIndex[node.definition.id]]
- const nodeIndex = model.idToIndex[node.getDefinition()._getId()]
+ const nodeIndex = model.idToIndex[node.definition.id]
- _compileAndReturnNodeTypeMap() {
- if (!this._cache_compiledLoadedNodeTypes) this._compileAndEvalGrammar()
- return this._cache_compiledLoadedNodeTypes
- }
- _requireInVmNodeJsRootNodeTypeConstructor(code) {
+ _requireInVmNodeJsRootParser(code) {
- const jtreePath = path.join(__dirname, "..", "index.js")
- global.jtree = require(jtreePath)
+ Object.keys(GlobalNamespaceAdditions).forEach(key => {
+ global[key] = require("./" + GlobalNamespaceAdditions[key])
+ })
- console.log(`Error in compiled grammar code for language "${this.getGrammarName()}"`)
+ console.log(`Error in compiled grammar code for language "${this.grammarName}"`)
- console.log(`jtreePath: "${jtreePath}"`)
- examplesToTestBlocks(programConstructor = this.compileAndReturnRootConstructor(), expectedErrorMessage = "") {
+ examplesToTestBlocks(rootParser = this.compileAndReturnRootParser(), expectedErrorMessage = "") {
- this.getValidConcreteAndAbstractNodeTypeDefinitions().forEach(def =>
- def.getExamples().forEach(example => {
- const id = def._getId() + example.getContent()
+ this.validConcreteAndAbstractParserDefinitions.forEach(def =>
+ def.examples.forEach(example => {
+ const id = def.id + example.content
- const exampleProgram = new programConstructor(example.childrenToString())
+ const exampleProgram = new rootParser(example.childrenToString())
Changed around line 15815: class HandGrammarProgram extends AbstractGrammarDefinitionNode {
- const languageName = this.getExtensionName()
- const rootNodeDef = this.getRootNodeTypeDefinitionNode()
- const cellTypes = this.getCellTypeDefinitions()
- const nodeTypeFamilyTree = this.getNodeTypeFamilyTree()
- const exampleNode = rootNodeDef.getExamples()[0]
+ const languageName = this.extensionName
+ const rootNodeDef = this.rootParserDefinition
+ const cellTypes = this.cellTypeDefinitions
+ const parserFamilyTree = this.parserFamilyTree
+ const exampleNode = rootNodeDef.examples[0]
- paragraph ${rootNodeDef.getDescription()}
+ paragraph ${rootNodeDef.description}
Changed around line 15832: ${exampleNode ? exampleNode.childrenToString(1) : ""}
- - ${languageName} has ${nodeTypeFamilyTree.getTopDownArray().length} node types.
+ - ${languageName} has ${parserFamilyTree.topDownArray.length} node types.
- ${languageName} has ${Object.keys(cellTypes).length} cell types
- - The source code for ${languageName} is ${this.getTopDownArray().length} lines long.
+ - The source code for ${languageName} is ${this.topDownArray.length} lines long.
Changed around line 15849: code
- ${nodeTypeFamilyTree.toString(1)}
+ ${parserFamilyTree.toString(1)}
Changed around line 15861: subtitle Road Map
- ${this.getTopDownArray()
+ ${this.topDownArray
Changed around line 15871: paragraph This readme was auto-generated using the
- const rootNodeDef = this.getRootNodeTypeDefinitionNode()
- const languageName = this.getExtensionName()
- const example = rootNodeDef.getExamples()[0]
+ const rootNodeDef = this.rootParserDefinition
+ const languageName = this.extensionName
+ const example = rootNodeDef.examples[0]
Changed around line 15891: paragraph This readme was auto-generated using the
- console.log(errors.map(error => error.getMessage()))`
+ console.log(errors.map(error => error.message))`
- files[GrammarBundleFiles.indexHtml] = `
+ files[GrammarBundleFiles.indexHtml] = `
+
+
- const samplePath = "sample." + this.getExtensionName()
+ const samplePath = "sample." + this.extensionName
- getTargetExtension() {
- return this.getRootNodeTypeDefinitionNode().get(GrammarConstants.compilesTo)
+ get targetExtension() {
+ return this.rootParserDefinition.get(GrammarConstants.compilesTo)
- getCellTypeDefinitions() {
- if (!this._cache_cellTypes) this._cache_cellTypes = this._getCellTypeDefinitions()
- return this._cache_cellTypes
+ get cellTypeDefinitions() {
+ if (this._cache_cellTypes) return this._cache_cellTypes
+ const types = {}
+ // todo: add built in word types?
+ this.getChildrenByParser(cellTypeDefinitionParser).forEach(type => (types[type.cellTypeId] = type))
+ this._cache_cellTypes = types
+ return types
- return this.getCellTypeDefinitions()[cellTypeId]
+ return this.cellTypeDefinitions[cellTypeId]
- getNodeTypeFamilyTree() {
+ get parserFamilyTree() {
- Object.values(this.getValidConcreteAndAbstractNodeTypeDefinitions()).forEach(node => {
- const path = node.getAncestorNodeTypeIdsArray().join(" ")
- tree.touchNode(path)
- })
+ Object.values(this.validConcreteAndAbstractParserDefinitions).forEach(node => tree.touchNode(node.ancestorParserIdsArray.join(" ")))
- _getCellTypeDefinitions() {
- const types = {}
- // todo: add built in word types?
- this.getChildrenByNodeConstructor(cellTypeDefinitionNode).forEach(type => (types[type.getCellTypeId()] = type))
- return types
- }
- getLanguageDefinitionProgram() {
+ get languageDefinitionProgram() {
- getValidConcreteAndAbstractNodeTypeDefinitions() {
- return this.getChildrenByNodeConstructor(nodeTypeDefinitionNode).filter(node => node._hasValidNodeTypeId())
+ get validConcreteAndAbstractParserDefinitions() {
+ return this.getChildrenByParser(parserDefinitionParser).filter(node => node._hasValidParserId())
- _getLastRootNodeTypeDefinitionNode() {
- return this.findLast(def => def instanceof AbstractGrammarDefinitionNode && def.has(GrammarConstants.root) && def._hasValidNodeTypeId())
+ get lastRootParserDefinitionNode() {
+ return this.findLast(def => def instanceof AbstractParserDefinitionParser && def.has(GrammarConstants.root) && def._hasValidParserId())
- _initRootNodeTypeDefinitionNode() {
- if (this._cache_rootNodeTypeNode) return
- if (!this._cache_rootNodeTypeNode) this._cache_rootNodeTypeNode = this._getLastRootNodeTypeDefinitionNode()
+ _initRootParserDefinitionNode() {
+ if (this._cache_rootParserNode) return
+ if (!this._cache_rootParserNode) this._cache_rootParserNode = this.lastRootParserDefinitionNode
- if (!this._cache_rootNodeTypeNode) {
- this._cache_rootNodeTypeNode = this.concat(`${GrammarConstants.defaultRootNode}
+ if (!this._cache_rootParserNode) {
+ this._cache_rootParserNode = this.concat(`${GrammarConstants.DefaultRootParser}
- ${GrammarConstants.catchAllNodeType} ${GrammarConstants.BlobNode}`)[0]
- this._addDefaultCatchAllBlobNode()
+ ${GrammarConstants.catchAllParser} ${GrammarConstants.BlobParser}`)[0]
+ this._addDefaultCatchAllBlobParser()
- getRootNodeTypeDefinitionNode() {
- this._initRootNodeTypeDefinitionNode()
- return this._cache_rootNodeTypeNode
+ get rootParserDefinition() {
+ this._initRootParserDefinitionNode()
+ return this._cache_rootParserNode
- // todo: whats the best design pattern to use for this sort of thing?
- _addDefaultCatchAllBlobNode() {
- delete this._cache_nodeTypeDefinitions
- this.concat(`${GrammarConstants.BlobNode}
- ${GrammarConstants.baseNodeType} ${GrammarConstants.blobNode}`)
+ _addDefaultCatchAllBlobParser() {
+ if (this._addedCatchAll) return
+ this._addedCatchAll = true
+ delete this._cache_parserDefinitionParsers
+ this.concat(`${GrammarConstants.BlobParser}
+ ${GrammarConstants.baseParser} ${GrammarConstants.blobParser}`)
- getExtensionName() {
- return this.getGrammarName()
+ get extensionName() {
+ return this.grammarName
- _getId() {
- return this.getRootNodeTypeId()
- }
- getRootNodeTypeId() {
- return this.getRootNodeTypeDefinitionNode().getNodeTypeIdFromDefinition()
+ get id() {
+ return this.rootParserId
- getGrammarName() {
- return this.getRootNodeTypeId().replace(HandGrammarProgram.nodeTypeSuffixRegex, "")
+ get rootParserId() {
+ return this.rootParserDefinition.parserIdFromDefinition
- _getMyInScopeNodeTypeIds() {
- const nodeTypesNode = this.getRootNodeTypeDefinitionNode().getNode(GrammarConstants.inScope)
- return nodeTypesNode ? nodeTypesNode.getWordsFrom(1) : []
+ get grammarName() {
+ return this.rootParserId.replace(HandGrammarProgram.parserSuffixRegex, "")
- _getInScopeNodeTypeIds() {
- const nodeTypesNode = this.getRootNodeTypeDefinitionNode().getNode(GrammarConstants.inScope)
- return nodeTypesNode ? nodeTypesNode.getWordsFrom(1) : []
+ _getMyInScopeParserIds() {
+ return super._getMyInScopeParserIds(this.rootParserDefinition)
- _initProgramNodeTypeDefinitionCache() {
- if (this._cache_nodeTypeDefinitions) return undefined
- this._cache_nodeTypeDefinitions = {}
- this.getChildrenByNodeConstructor(nodeTypeDefinitionNode).forEach(nodeTypeDefinitionNode => {
- this._cache_nodeTypeDefinitions[nodeTypeDefinitionNode.getNodeTypeIdFromDefinition()] = nodeTypeDefinitionNode
- })
+ _getInScopeParserIds() {
+ const parsersNode = this.rootParserDefinition.getNode(GrammarConstants.inScope)
+ return parsersNode ? parsersNode.getWordsFrom(1) : []
- _getProgramNodeTypeDefinitionCache() {
- this._initProgramNodeTypeDefinitionCache()
- return this._cache_nodeTypeDefinitions
+ makeProgramParserDefinitionCache() {
+ const cache = {}
+ this.getChildrenByParser(parserDefinitionParser).forEach(parserDefinitionParser => (cache[parserDefinitionParser.parserIdFromDefinition] = parserDefinitionParser))
+ return cache
- compileAndReturnRootConstructor() {
- if (!this._cache_rootConstructorClass) {
- const def = this.getRootNodeTypeDefinitionNode()
- const rootNodeTypeId = def.getNodeTypeIdFromDefinition()
- this._cache_rootConstructorClass = def.getLanguageDefinitionProgram()._compileAndReturnNodeTypeMap()[rootNodeTypeId]
+ compileAndReturnRootParser() {
+ if (!this._cached_rootParser) {
+ const rootDef = this.rootParserDefinition
+ this._cached_rootParser = rootDef.languageDefinitionProgram._compileAndReturnRootParser()
- return this._cache_rootConstructorClass
+ return this._cached_rootParser
- _getFileExtensions() {
- return this.getRootNodeTypeDefinitionNode().get(GrammarConstants.extensions)
- ? this.getRootNodeTypeDefinitionNode()
- .get(GrammarConstants.extensions)
- .split(" ")
- .join(",")
- : this.getExtensionName()
+ get fileExtensions() {
+ return this.rootParserDefinition.get(GrammarConstants.extensions) ? this.rootParserDefinition.get(GrammarConstants.extensions).split(" ").join(",") : this.extensionName
- toNodeJsJavascript(normalizedJtreePath = "jtree") {
- return this._rootNodeDefToJavascriptClass(normalizedJtreePath, true).trim()
+ toNodeJsJavascript(jtreeProductsPath = "jtree/products") {
+ return this._rootNodeDefToJavascriptClass(jtreeProductsPath, true).trim()
- _getProperName() {
- return TreeUtils.ucfirst(this.getExtensionName())
- }
- _rootNodeDefToJavascriptClass(normalizedJtreePath, forNodeJs = true) {
- const defs = this.getValidConcreteAndAbstractNodeTypeDefinitions()
+ _rootNodeDefToJavascriptClass(jtreeProductsPath, forNodeJs = true) {
+ const defs = this.validConcreteAndAbstractParserDefinitions
- const nodeTypeClasses = defs.map(def => def._nodeDefToJavascriptClass()).join("\n\n")
- const rootDef = this.getRootNodeTypeDefinitionNode()
+ const parserClasses = defs.map(def => def.asJavascriptClass).join("\n\n")
+ const rootDef = this.rootParserDefinition
- const rootName = rootDef._getGeneratedClassName()
+ const rootName = rootDef.generatedClassName
- if (forNodeJs) {
+ if (forNodeJs)
- } else {
- exportScript = `window.${rootName} = ${rootName}`
- }
+ else exportScript = `window.${rootName} = ${rootName}`
+ let nodeJsImports = ``
+ if (forNodeJs)
+ nodeJsImports = Object.keys(GlobalNamespaceAdditions)
+ .map(key => `const { ${key} } = require("${jtreeProductsPath}/${GlobalNamespaceAdditions[key]}")`)
+ .join("\n")
- ${forNodeJs ? `const {jtree} = require("${normalizedJtreePath.replace(/\\/g, "\\\\")}")` : ""}
+ ${nodeJsImports}
- ${nodeTypeClasses}
+ ${parserClasses}
- const cellTypeDefs = this.getCellTypeDefinitions()
+ const cellTypeDefs = this.cellTypeDefinitions
- .map(name => ` ${name}: '${cellTypeDefs[name].getRegexString()}'`)
+ .map(name => ` ${name}: '${cellTypeDefs[name].regexString}'`)
- const defs = this.getValidConcreteAndAbstractNodeTypeDefinitions().filter(kw => !kw._isAbstract())
- const nodeTypeContexts = defs.map(def => def._toSublimeMatchBlock()).join("\n\n")
- const includes = defs.map(nodeTypeDef => ` - include: '${nodeTypeDef.getNodeTypeIdFromDefinition()}'`).join("\n")
+ const defs = this.validConcreteAndAbstractParserDefinitions.filter(kw => !kw._isAbstract())
+ const parserContexts = defs.map(def => def._toSublimeMatchBlock()).join("\n\n")
+ const includes = defs.map(parserDef => ` - include: '${parserDef.parserIdFromDefinition}'`).join("\n")
- name: ${this.getExtensionName()}
- file_extensions: [${this._getFileExtensions()}]
- scope: source.${this.getExtensionName()}
+ name: ${this.extensionName}
+ file_extensions: [${this.fileExtensions}]
+ scope: source.${this.extensionName}
Changed around line 16053: contexts:
- ${nodeTypeContexts}`
+ ${parserContexts}`
- HandGrammarProgram.makeNodeTypeId = str => TreeUtils._replaceNonAlphaNumericCharactersWithCharCodes(str).replace(HandGrammarProgram.nodeTypeSuffixRegex, "") + GrammarConstants.nodeTypeSuffix
- HandGrammarProgram.makeCellTypeId = str => TreeUtils._replaceNonAlphaNumericCharactersWithCharCodes(str).replace(HandGrammarProgram.cellTypeSuffixRegex, "") + GrammarConstants.cellTypeSuffix
- HandGrammarProgram.nodeTypeSuffixRegex = new RegExp(GrammarConstants.nodeTypeSuffix + "$")
- HandGrammarProgram.nodeTypeFullRegex = new RegExp("^[a-zA-Z0-9_]+" + GrammarConstants.nodeTypeSuffix + "$")
+ HandGrammarProgram.makeParserId = str => Utils._replaceNonAlphaNumericCharactersWithCharCodes(str).replace(HandGrammarProgram.parserSuffixRegex, "") + GrammarConstants.parserSuffix
+ HandGrammarProgram.makeCellTypeId = str => Utils._replaceNonAlphaNumericCharactersWithCharCodes(str).replace(HandGrammarProgram.cellTypeSuffixRegex, "") + GrammarConstants.cellTypeSuffix
+ HandGrammarProgram.parserSuffixRegex = new RegExp(GrammarConstants.parserSuffix + "$")
+ HandGrammarProgram.parserFullRegex = new RegExp("^[a-zA-Z0-9_]+" + GrammarConstants.parserSuffix + "$")
+ HandGrammarProgram.blankLineRegex = new RegExp("^$")
- HandGrammarProgram._nodeTypes = {}
+ HandGrammarProgram._parsers = {}
Changed around line 16073: PreludeKinds[PreludeCellTypeIds.numberCell] = GrammarFloatCell
- window.GrammarConstants = GrammarConstants
- window.PreludeCellTypeIds = PreludeCellTypeIds
- window.HandGrammarProgram = HandGrammarProgram
- window.GrammarBackedNode = GrammarBackedNode
- window.UnknownNodeTypeError = UnknownNodeTypeError
- class Upgrader extends TreeNode {
- upgradeManyInPlace(globPatterns, fromVersion, toVersion) {
- this._upgradeMany(globPatterns, fromVersion, toVersion).forEach(file => file.tree.toDisk(file.path))
- return this
- }
- upgradeManyPreview(globPatterns, fromVersion, toVersion) {
- return this._upgradeMany(globPatterns, fromVersion, toVersion)
- }
- _upgradeMany(globPatterns, fromVersion, toVersion) {
- const glob = this.require("glob")
- const files = TreeUtils.flatten(globPatterns.map(pattern => glob.sync(pattern)))
- console.log(`${files.length} files to upgrade`)
- return files.map(path => {
- console.log("Upgrading " + path)
- return {
- tree: this.upgrade(TreeNode.fromDisk(path), fromVersion, toVersion),
- path: path
- }
- })
- }
- upgrade(code, fromVersion, toVersion) {
- const updateFromMap = this.getUpgradeFromMap()
- const semver = this.require("semver")
- let fromMap
- while ((fromMap = updateFromMap[fromVersion])) {
- const toNextVersion = Object.keys(fromMap)[0] // todo: currently we just assume 1 step at a time
- if (semver.lt(toVersion, toNextVersion)) break
- const fn = Object.values(fromMap)[0]
- code = fn(code)
- fromVersion = toNextVersion
- }
- return code
- }
- }
- window.Upgrader = Upgrader
- grammarName = HandGrammarProgram.makeNodeTypeId(grammarName)
+ grammarName = HandGrammarProgram.makeParserId(grammarName)
- // note: right now we assume 1 global cellTypeMap and nodeTypeMap per grammar. But we may have scopes in the future?
+ // note: right now we assume 1 global cellTypeMap and parserMap per grammar. But we may have scopes in the future?
- .map(word => HandGrammarProgram.makeNodeTypeId(word))
+ .map(word => HandGrammarProgram.makeParserId(word))
Changed around line 16091: class UnknownGrammarProgram extends TreeNode {
- const firstWordIsAnInteger = !!node.getFirstWord().match(/^\d+$/)
- const parentFirstWord = node.getParent().getFirstWord()
- if (firstWordIsAnInteger && parentFirstWord) node.setFirstWord(HandGrammarProgram.makeNodeTypeId(parentFirstWord + UnknownGrammarProgram._childSuffix))
+ const firstWordIsAnInteger = !!node.firstWord.match(/^\d+$/)
+ const parentFirstWord = node.parent.firstWord
+ if (firstWordIsAnInteger && parentFirstWord) node.setFirstWord(HandGrammarProgram.makeParserId(parentFirstWord + UnknownGrammarProgram._childSuffix))
- const firstWord = node.getFirstWord()
+ const firstWord = node.firstWord
- node.forEach(child => {
- keywordsToChildKeywords[firstWord][child.getFirstWord()] = true
- })
+ node.forEach(child => (keywordsToChildKeywords[firstWord][child.firstWord] = true))
- _inferNodeTypeDef(firstWord, globalCellTypeMap, childFirstWords, instances) {
- const edgeSymbol = this.getEdgeSymbol()
- const nodeTypeId = HandGrammarProgram.makeNodeTypeId(firstWord)
- const nodeDefNode = new TreeNode(nodeTypeId).nodeAt(0)
- const childNodeTypeIds = childFirstWords.map(word => HandGrammarProgram.makeNodeTypeId(word))
- if (childNodeTypeIds.length) nodeDefNode.touchNode(GrammarConstants.inScope).setWordsFrom(1, childNodeTypeIds)
+ _inferParserDef(firstWord, globalCellTypeMap, childFirstWords, instances) {
+ const edgeSymbol = this.edgeSymbol
+ const parserId = HandGrammarProgram.makeParserId(firstWord)
+ const nodeDefNode = new TreeNode(parserId).nodeAt(0)
+ const childParserIds = childFirstWords.map(word => HandGrammarProgram.makeParserId(word))
+ if (childParserIds.length) nodeDefNode.touchNode(GrammarConstants.inScope).setWordsFrom(1, childParserIds)
- .map(line => line.getContent())
+ .map(line => line.content)
Changed around line 16124: class UnknownGrammarProgram extends TreeNode {
- const cellType = this._getBestCellType(firstWord, instances.length, maxCellsOnLine, cellsForAllInstances.map(cells => cells[cellIndex]))
+ const cellType = this._getBestCellType(
+ firstWord,
+ instances.length,
+ maxCellsOnLine,
+ cellsForAllInstances.map(cells => cells[cellIndex])
+ )
Changed around line 16140: class UnknownGrammarProgram extends TreeNode {
- const needsCruxProperty = !firstWord.endsWith(UnknownGrammarProgram._childSuffix + "Node") // todo: cleanup
+ const needsCruxProperty = !firstWord.endsWith(UnknownGrammarProgram._childSuffix + GrammarConstants.parserSuffix) // todo: cleanup
Changed around line 16148: class UnknownGrammarProgram extends TreeNode {
- return nodeDefNode.getParent().toString()
+ return nodeDefNode.parent.toString()
- // grammarName = HandGrammarProgram.makeNodeTypeId(grammarName)
+ // grammarName = HandGrammarProgram.makeParserId(grammarName)
- // // note: right now we assume 1 global cellTypeMap and nodeTypeMap per grammar. But we may have scopes in the future?
- // const rootNodeNames = this.getFirstWords().map(word => HandGrammarProgram.makeNodeTypeId(word))
+ // // note: right now we assume 1 global cellTypeMap and parserMap per grammar. But we may have scopes in the future?
+ // const rootNodeNames = this.getFirstWords().map(word => HandGrammarProgram.makeParserId(word))
Changed around line 16168: class UnknownGrammarProgram extends TreeNode {
- const nodeTypeDefs = Object.keys(keywordsToChildKeywords)
+ const parserDefs = Object.keys(keywordsToChildKeywords)
- .map(firstWord => this._inferNodeTypeDef(firstWord, globalCellTypeMap, Object.keys(keywordsToChildKeywords[firstWord]), keywordsToNodeInstances[firstWord]))
+ .map(firstWord => this._inferParserDef(firstWord, globalCellTypeMap, Object.keys(keywordsToChildKeywords[firstWord]), keywordsToNodeInstances[firstWord]))
- const nodeBreakSymbol = this.getNodeBreakSymbol()
- return this._formatCode([this._inferRootNodeForAPrefixLanguage(grammarName).toString(), cellTypeDefs.join(nodeBreakSymbol), nodeTypeDefs.join(nodeBreakSymbol)].filter(identity => identity).join("\n"))
+ const nodeBreakSymbol = this.nodeBreakSymbol
+ return this._formatCode([this._inferRootNodeForAPrefixLanguage(grammarName).toString(), cellTypeDefs.join(nodeBreakSymbol), parserDefs.join(nodeBreakSymbol)].filter(identity => identity).join("\n"))
- const programConstructor = grammarProgram.compileAndReturnRootConstructor()
- const program = new programConstructor(code)
+ const rootParser = grammarProgram.compileAndReturnRootParser()
+ const program = new rootParser(code)
- const edgeSymbol = this.getEdgeSymbol()
+ const edgeSymbol = this.edgeSymbol
Changed around line 16219: class UnknownGrammarProgram extends TreeNode {
+ window.GrammarConstants = GrammarConstants
+ window.PreludeCellTypeIds = PreludeCellTypeIds
+ window.HandGrammarProgram = HandGrammarProgram
+ window.GrammarBackedNode = GrammarBackedNode
+ window.UnknownParserError = UnknownParserError
+
+
+ "use strict"
- ;(function(CmToken) {
+ ;(function (CmToken) {
Changed around line 16408: const textMateScopeToCodeMirrorStyle = (scopeSegments, styleTree = tmToCm) => {
- class TreeNotationCodeMirrorMode {
- constructor(name, getProgramConstructorFn, getProgramCodeFn, codeMirrorLib = undefined) {
+ class GrammarCodeMirrorMode {
+ constructor(name, getRootParserFn, getProgramCodeFn, codeMirrorLib = undefined) {
- this._getProgramConstructorFn = getProgramConstructorFn
+ this._getRootParserFn = getRootParserFn
Changed around line 16419: class TreeNotationCodeMirrorMode {
- this._cachedProgram = new (this._getProgramConstructorFn())(source)
+ this._cachedProgram = new (this._getRootParserFn())(source)
- "8": "backspace",
- "9": "tab",
- "13": "enter",
- "16": "shift",
- "17": "ctrl",
- "18": "alt",
- "19": "pause",
- "20": "capslock",
- "27": "escape",
- "33": "pageup",
- "34": "pagedown",
- "35": "end",
- "36": "home",
- "37": "left",
- "38": "up",
- "39": "right",
- "40": "down",
- "45": "insert",
- "46": "delete",
- "91": "left window key",
- "92": "right window key",
- "93": "select",
- "112": "f1",
- "113": "f2",
- "114": "f3",
- "115": "f4",
- "116": "f5",
- "117": "f6",
- "118": "f7",
- "119": "f8",
- "120": "f9",
- "121": "f10",
- "122": "f11",
- "123": "f12",
- "144": "numlock",
- "145": "scrolllock"
+ 8: "backspace",
+ 9: "tab",
+ 13: "enter",
+ 16: "shift",
+ 17: "ctrl",
+ 18: "alt",
+ 19: "pause",
+ 20: "capslock",
+ 27: "escape",
+ 33: "pageup",
+ 34: "pagedown",
+ 35: "end",
+ 36: "home",
+ 37: "left",
+ 38: "up",
+ 39: "right",
+ 40: "down",
+ 45: "insert",
+ 46: "delete",
+ 91: "left window key",
+ 92: "right window key",
+ 93: "select",
+ 112: "f1",
+ 113: "f2",
+ 114: "f3",
+ 115: "f4",
+ 116: "f5",
+ 117: "f6",
+ 118: "f7",
+ 119: "f8",
+ 120: "f9",
+ 121: "f10",
+ 122: "f11",
+ 123: "f12",
+ 144: "numlock",
+ 145: "scrolllock"
Changed around line 16563: class TreeNotationCodeMirrorMode {
- window.TreeNotationCodeMirrorMode = TreeNotationCodeMirrorMode
- class jtree {}
- jtree.GrammarBackedNode = GrammarBackedNode
- jtree.GrammarConstants = GrammarConstants
- jtree.Utils = TreeUtils
- jtree.UnknownNodeTypeError = UnknownNodeTypeError
- jtree.TestRacer = TestRacer
- jtree.TreeEvents = TreeEvents
- jtree.TreeNode = TreeNode
- jtree.ExtendibleTreeNode = ExtendibleTreeNode
- jtree.HandGrammarProgram = HandGrammarProgram
- jtree.UnknownGrammarProgram = UnknownGrammarProgram
- jtree.TreeNotationCodeMirrorMode = TreeNotationCodeMirrorMode
- jtree.getVersion = () => TreeNode.getVersion()
- window.jtree = jtree
+ window.GrammarCodeMirrorMode = GrammarCodeMirrorMode
- class stumpNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(
- errorNode,
- Object.assign(Object.assign({}, super.createParser()._getFirstWordMapAsObject()), {
- blockquote: htmlTagNode,
- colgroup: htmlTagNode,
- datalist: htmlTagNode,
- fieldset: htmlTagNode,
- menuitem: htmlTagNode,
- noscript: htmlTagNode,
- optgroup: htmlTagNode,
- progress: htmlTagNode,
- styleTag: htmlTagNode,
- template: htmlTagNode,
- textarea: htmlTagNode,
- titleTag: htmlTagNode,
- address: htmlTagNode,
- article: htmlTagNode,
- caption: htmlTagNode,
- details: htmlTagNode,
- section: htmlTagNode,
- summary: htmlTagNode,
- button: htmlTagNode,
- canvas: htmlTagNode,
- dialog: htmlTagNode,
- figure: htmlTagNode,
- footer: htmlTagNode,
- header: htmlTagNode,
- hgroup: htmlTagNode,
- iframe: htmlTagNode,
- keygen: htmlTagNode,
- legend: htmlTagNode,
- object: htmlTagNode,
- option: htmlTagNode,
- output: htmlTagNode,
- script: htmlTagNode,
- select: htmlTagNode,
- source: htmlTagNode,
- strong: htmlTagNode,
- aside: htmlTagNode,
- embed: htmlTagNode,
- input: htmlTagNode,
- label: htmlTagNode,
- meter: htmlTagNode,
- param: htmlTagNode,
- small: htmlTagNode,
- table: htmlTagNode,
- tbody: htmlTagNode,
- tfoot: htmlTagNode,
- thead: htmlTagNode,
- track: htmlTagNode,
- video: htmlTagNode,
- abbr: htmlTagNode,
- area: htmlTagNode,
- base: htmlTagNode,
- body: htmlTagNode,
- code: htmlTagNode,
- form: htmlTagNode,
- head: htmlTagNode,
- html: htmlTagNode,
- link: htmlTagNode,
- main: htmlTagNode,
- mark: htmlTagNode,
- menu: htmlTagNode,
- meta: htmlTagNode,
- ruby: htmlTagNode,
- samp: htmlTagNode,
- span: htmlTagNode,
- time: htmlTagNode,
- bdi: htmlTagNode,
- bdo: htmlTagNode,
- col: htmlTagNode,
- del: htmlTagNode,
- dfn: htmlTagNode,
- div: htmlTagNode,
- img: htmlTagNode,
- ins: htmlTagNode,
- kbd: htmlTagNode,
- map: htmlTagNode,
- nav: htmlTagNode,
- pre: htmlTagNode,
- rtc: htmlTagNode,
- sub: htmlTagNode,
- sup: htmlTagNode,
- var: htmlTagNode,
- wbr: htmlTagNode,
- br: htmlTagNode,
- dd: htmlTagNode,
- dl: htmlTagNode,
- dt: htmlTagNode,
- em: htmlTagNode,
- h1: htmlTagNode,
- h2: htmlTagNode,
- h3: htmlTagNode,
- h4: htmlTagNode,
- h5: htmlTagNode,
- h6: htmlTagNode,
- hr: htmlTagNode,
- li: htmlTagNode,
- ol: htmlTagNode,
- rb: htmlTagNode,
- rp: htmlTagNode,
- rt: htmlTagNode,
- td: htmlTagNode,
- th: htmlTagNode,
- tr: htmlTagNode,
- ul: htmlTagNode,
- a: htmlTagNode,
- b: htmlTagNode,
- i: htmlTagNode,
- p: htmlTagNode,
- q: htmlTagNode,
- s: htmlTagNode,
- u: htmlTagNode
+ class stumpParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(
+ errorParser,
+ Object.assign(Object.assign({}, super.createParserCombinator()._getFirstWordMapAsObject()), {
+ blockquote: htmlTagParser,
+ colgroup: htmlTagParser,
+ datalist: htmlTagParser,
+ fieldset: htmlTagParser,
+ menuitem: htmlTagParser,
+ noscript: htmlTagParser,
+ optgroup: htmlTagParser,
+ progress: htmlTagParser,
+ styleTag: htmlTagParser,
+ template: htmlTagParser,
+ textarea: htmlTagParser,
+ titleTag: htmlTagParser,
+ address: htmlTagParser,
+ article: htmlTagParser,
+ caption: htmlTagParser,
+ details: htmlTagParser,
+ section: htmlTagParser,
+ summary: htmlTagParser,
+ button: htmlTagParser,
+ canvas: htmlTagParser,
+ dialog: htmlTagParser,
+ figure: htmlTagParser,
+ footer: htmlTagParser,
+ header: htmlTagParser,
+ hgroup: htmlTagParser,
+ iframe: htmlTagParser,
+ keygen: htmlTagParser,
+ legend: htmlTagParser,
+ object: htmlTagParser,
+ option: htmlTagParser,
+ output: htmlTagParser,
+ script: htmlTagParser,
+ select: htmlTagParser,
+ source: htmlTagParser,
+ strong: htmlTagParser,
+ aside: htmlTagParser,
+ embed: htmlTagParser,
+ input: htmlTagParser,
+ label: htmlTagParser,
+ meter: htmlTagParser,
+ param: htmlTagParser,
+ small: htmlTagParser,
+ table: htmlTagParser,
+ tbody: htmlTagParser,
+ tfoot: htmlTagParser,
+ thead: htmlTagParser,
+ track: htmlTagParser,
+ video: htmlTagParser,
+ abbr: htmlTagParser,
+ area: htmlTagParser,
+ base: htmlTagParser,
+ body: htmlTagParser,
+ code: htmlTagParser,
+ form: htmlTagParser,
+ head: htmlTagParser,
+ html: htmlTagParser,
+ link: htmlTagParser,
+ main: htmlTagParser,
+ mark: htmlTagParser,
+ menu: htmlTagParser,
+ meta: htmlTagParser,
+ ruby: htmlTagParser,
+ samp: htmlTagParser,
+ span: htmlTagParser,
+ time: htmlTagParser,
+ bdi: htmlTagParser,
+ bdo: htmlTagParser,
+ col: htmlTagParser,
+ del: htmlTagParser,
+ dfn: htmlTagParser,
+ div: htmlTagParser,
+ img: htmlTagParser,
+ ins: htmlTagParser,
+ kbd: htmlTagParser,
+ map: htmlTagParser,
+ nav: htmlTagParser,
+ pre: htmlTagParser,
+ rtc: htmlTagParser,
+ sub: htmlTagParser,
+ sup: htmlTagParser,
+ var: htmlTagParser,
+ wbr: htmlTagParser,
+ br: htmlTagParser,
+ dd: htmlTagParser,
+ dl: htmlTagParser,
+ dt: htmlTagParser,
+ em: htmlTagParser,
+ h1: htmlTagParser,
+ h2: htmlTagParser,
+ h3: htmlTagParser,
+ h4: htmlTagParser,
+ h5: htmlTagParser,
+ h6: htmlTagParser,
+ hr: htmlTagParser,
+ li: htmlTagParser,
+ ol: htmlTagParser,
+ rb: htmlTagParser,
+ rp: htmlTagParser,
+ rt: htmlTagParser,
+ td: htmlTagParser,
+ th: htmlTagParser,
+ tr: htmlTagParser,
+ ul: htmlTagParser,
+ a: htmlTagParser,
+ b: htmlTagParser,
+ i: htmlTagParser,
+ p: htmlTagParser,
+ q: htmlTagParser,
+ s: htmlTagParser,
+ u: htmlTagParser,
- [{ regex: /^$/, nodeConstructor: blankLineNode }, { regex: /^[a-zA-Z0-9_]+Component/, nodeConstructor: componentDefinitionNode }]
+ [
+ { regex: /^$/, parser: blankLineParser },
+ { regex: /^[a-zA-Z0-9_]+Component/, parser: componentDefinitionParser },
+ ]
- return this.toHtml()
+ return this.asHtml
- static cachedHandGrammarProgramRoot = new jtree.HandGrammarProgram(`tooling onsave jtree build produceLang stump
+ static cachedHandGrammarProgramRoot = new HandGrammarProgram(`// Cell parsers
Changed around line 16719: htmlAttributeNameCell
- stumpNode
+
+ // Line parsers
+ stumpParser
- catchAllNodeType errorNode
- inScope htmlTagNode blankLineNode
+ catchAllParser errorParser
+ inScope htmlTagParser blankLineParser
- return this.toHtml()
+ return this.asHtml
- blankLineNode
+ blankLineParser
Changed around line 16746: blankLineNode
- htmlTagNode
- inScope bernNode htmlTagNode htmlAttributeNode blankLineNode
+ htmlTagParser
+ inScope bernParser htmlTagParser htmlAttributeParser blankLineParser
- isHtmlTagNode = true
+ isHtmlTagParser = true
- const firstWord = this.getFirstWord()
+ const firstWord = this.firstWord
Changed around line 16764: htmlTagNode
- toHtmlWithSuids() {
+ asHtmlWithSuids() {
Changed around line 16780: htmlTagNode
- this.filter(node => node.isAttributeNode)
- .forEach(child => elem.setAttribute(child.getFirstWord(), child.getContent()))
+ this.filter(node => node.isAttributeParser)
+ .forEach(child => elem.setAttribute(child.firstWord, child.content))
- this.filter(node => node.isHtmlTagNode)
+ this.filter(node => node.isHtmlTagParser)
- const attributesStr = this.filter(node => node.isAttributeNode)
+ const attributesStr = this.filter(node => node.isAttributeParser)
- const indentForChildNodes = !collapse && this.getChildInstancesOfNodeTypeId("htmlTagNode").length > 0
+ const indentForChildParsers = !collapse && this.getChildInstancesOfParserId("htmlTagParser").length > 0
- return \`\${!collapse ? indent : ""}<\${tag}\${attributesStr}\${suid}>\${oneLiner}\${indentForChildNodes ? "\\n" : ""}\${children}\${tag}>\${collapse ? "" : "\\n"}\`
+ return \`\${!collapse ? indent : ""}<\${tag}\${attributesStr}\${suid}>\${oneLiner}\${indentForChildParsers ? "\\n" : ""}\${children}\${tag}>\${collapse ? "" : "\\n"}\`
Changed around line 16808: htmlTagNode
- return this.getTopDownArray().find(node => node._getUid() === guid)
+ return this.topDownArray.find(node => node._getUid() === guid)
- const classNode = this.touchNode("class")
- const words = classNode.getWordsFrom(1)
+ const classParser = this.touchNode("class")
+ const words = classParser.getWordsFrom(1)
- classNode.setContent(words.join(this.getWordBreakSymbol()))
+ classParser.setContent(words.join(this.wordBreakSymbol))
- const classNode = this.getNode("class")
- if (!classNode) return this
- const newClasses = classNode.getWords().filter(word => word !== className)
- if (!newClasses.length) classNode.destroy()
- else classNode.setContent(newClasses.join(" "))
+ const classParser = this.getNode("class")
+ if (!classParser) return this
+ const newClasses = classParser.words.filter(word => word !== className)
+ if (!newClasses.length) classParser.destroy()
+ else classParser.setContent(newClasses.join(" "))
- const classNode = this.getNode("class")
- return classNode && classNode.getWords().includes(className) ? true : false
+ const classParser = this.getNode("class")
+ return classParser && classParser.words.includes(className) ? true : false
Changed around line 16848: htmlTagNode
- const singleNode = new jtree.TreeNode(text).getChildren()[0]
+ const singleNode = new TreeNode(text).getChildren()[0]
- const stumpNodeIndex = this.filter(node => node.isHtmlTagNode).indexOf(newNode)
- this.getShadow().insertHtmlNode(newNode, stumpNodeIndex)
+ const stumpParserIndex = this.filter(node => node.isHtmlTagParser).indexOf(newNode)
+ this.getShadow().insertHtmlNode(newNode, stumpParserIndex)
Changed around line 16861: htmlTagNode
- return this.getTopDownArray().find(node =>
+ return this.topDownArray.find(node =>
Changed around line 16872: htmlTagNode
- return this.getTopDownArray().filter(node => node.doesExtend("htmlTagNode") && node.getFirstWord() === firstWord)
+ return this.topDownArray.filter(node => node.doesExtend("htmlTagParser") && node.firstWord === firstWord)
- return this.getTopDownArray().filter(node => node.doesExtend("htmlTagNode") && node.hasLine(line))
+ return this.topDownArray.filter(node => node.doesExtend("htmlTagParser") && node.hasLine(line))
- return this.getTopDownArray().filter(
+ return this.topDownArray.filter(
- node.doesExtend("htmlTagNode") &&
+ node.doesExtend("htmlTagParser") &&
- .getWords()
+ .words
- return this.getParent().getShadowClass()
+ return this.parent.getShadowClass()
- return this._treeComponent || this.getParent().getStumpNodeTreeComponent()
+ return this._treeComponent || this.parent.getStumpNodeTreeComponent()
Changed around line 16913: htmlTagNode
- toHtml() {
+ get asHtml() {
- errorNode
- baseNodeType errorNode
- componentDefinitionNode
- extends htmlTagNode
+ errorParser
+ baseParser errorParser
+ componentDefinitionParser
+ extends htmlTagParser
- htmlAttributeNode
+ htmlAttributeParser
- return \` \${this.getFirstWord()}="\${this.getContent()}"\`
+ return \` \${this.firstWord}="\${this.content}"\`
- boolean isAttributeNode true
+ boolean isAttributeParser true
- catchAllNodeType errorNode
+ catchAllParser errorParser
- stumpExtendedAttributeNode
- description Node types not present in HTML but included in stump.
- extends htmlAttributeNode
+ stumpExtendedAttributeParser
+ description Parser types not present in HTML but included in stump.
+ extends htmlAttributeParser
- lineOfHtmlContentNode
+ lineOfHtmlContentParser
- catchAllNodeType lineOfHtmlContentNode
+ catchAllParser lineOfHtmlContentParser
- bernNode
+ bernParser
- todo Rename this node type
+ // todo Rename this node type
- catchAllNodeType lineOfHtmlContentNode
+ catchAllParser lineOfHtmlContentParser
- getHandGrammarProgram() {
+ get handGrammarProgram() {
- static getNodeTypeMap() {
- return {
- stumpNode: stumpNode,
- blankLineNode: blankLineNode,
- htmlTagNode: htmlTagNode,
- errorNode: errorNode,
- componentDefinitionNode: componentDefinitionNode,
- htmlAttributeNode: htmlAttributeNode,
- stumpExtendedAttributeNode: stumpExtendedAttributeNode,
- lineOfHtmlContentNode: lineOfHtmlContentNode,
- bernNode: bernNode
- }
- }
+ static rootParser = stumpParser
- class blankLineNode extends jtree.GrammarBackedNode {
+ class blankLineParser extends GrammarBackedNode {
Changed around line 16982: bernNode
- class htmlTagNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(
+ class htmlTagParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(
- Object.assign(Object.assign({}, super.createParser()._getFirstWordMapAsObject()), {
- blockquote: htmlTagNode,
- colgroup: htmlTagNode,
- datalist: htmlTagNode,
- fieldset: htmlTagNode,
- menuitem: htmlTagNode,
- noscript: htmlTagNode,
- optgroup: htmlTagNode,
- progress: htmlTagNode,
- styleTag: htmlTagNode,
- template: htmlTagNode,
- textarea: htmlTagNode,
- titleTag: htmlTagNode,
- address: htmlTagNode,
- article: htmlTagNode,
- caption: htmlTagNode,
- details: htmlTagNode,
- section: htmlTagNode,
- summary: htmlTagNode,
- button: htmlTagNode,
- canvas: htmlTagNode,
- dialog: htmlTagNode,
- figure: htmlTagNode,
- footer: htmlTagNode,
- header: htmlTagNode,
- hgroup: htmlTagNode,
- iframe: htmlTagNode,
- keygen: htmlTagNode,
- legend: htmlTagNode,
- object: htmlTagNode,
- option: htmlTagNode,
- output: htmlTagNode,
- script: htmlTagNode,
- select: htmlTagNode,
- source: htmlTagNode,
- strong: htmlTagNode,
- aside: htmlTagNode,
- embed: htmlTagNode,
- input: htmlTagNode,
- label: htmlTagNode,
- meter: htmlTagNode,
- param: htmlTagNode,
- small: htmlTagNode,
- table: htmlTagNode,
- tbody: htmlTagNode,
- tfoot: htmlTagNode,
- thead: htmlTagNode,
- track: htmlTagNode,
- video: htmlTagNode,
- abbr: htmlTagNode,
- area: htmlTagNode,
- base: htmlTagNode,
- body: htmlTagNode,
- code: htmlTagNode,
- form: htmlTagNode,
- head: htmlTagNode,
- html: htmlTagNode,
- link: htmlTagNode,
- main: htmlTagNode,
- mark: htmlTagNode,
- menu: htmlTagNode,
- meta: htmlTagNode,
- ruby: htmlTagNode,
- samp: htmlTagNode,
- span: htmlTagNode,
- time: htmlTagNode,
- bdi: htmlTagNode,
- bdo: htmlTagNode,
- col: htmlTagNode,
- del: htmlTagNode,
- dfn: htmlTagNode,
- div: htmlTagNode,
- img: htmlTagNode,
- ins: htmlTagNode,
- kbd: htmlTagNode,
- map: htmlTagNode,
- nav: htmlTagNode,
- pre: htmlTagNode,
- rtc: htmlTagNode,
- sub: htmlTagNode,
- sup: htmlTagNode,
- var: htmlTagNode,
- wbr: htmlTagNode,
- br: htmlTagNode,
- dd: htmlTagNode,
- dl: htmlTagNode,
- dt: htmlTagNode,
- em: htmlTagNode,
- h1: htmlTagNode,
- h2: htmlTagNode,
- h3: htmlTagNode,
- h4: htmlTagNode,
- h5: htmlTagNode,
- h6: htmlTagNode,
- hr: htmlTagNode,
- li: htmlTagNode,
- ol: htmlTagNode,
- rb: htmlTagNode,
- rp: htmlTagNode,
- rt: htmlTagNode,
- td: htmlTagNode,
- th: htmlTagNode,
- tr: htmlTagNode,
- ul: htmlTagNode,
- a: htmlTagNode,
- b: htmlTagNode,
- i: htmlTagNode,
- p: htmlTagNode,
- q: htmlTagNode,
- s: htmlTagNode,
- u: htmlTagNode,
- oncanplaythrough: htmlAttributeNode,
- ondurationchange: htmlAttributeNode,
- onloadedmetadata: htmlAttributeNode,
- contenteditable: htmlAttributeNode,
- "accept-charset": htmlAttributeNode,
- onbeforeunload: htmlAttributeNode,
- onvolumechange: htmlAttributeNode,
- onbeforeprint: htmlAttributeNode,
- oncontextmenu: htmlAttributeNode,
- autocomplete: htmlAttributeNode,
- onafterprint: htmlAttributeNode,
- onhashchange: htmlAttributeNode,
- onloadeddata: htmlAttributeNode,
- onmousewheel: htmlAttributeNode,
- onratechange: htmlAttributeNode,
- ontimeupdate: htmlAttributeNode,
- oncuechange: htmlAttributeNode,
- ondragenter: htmlAttributeNode,
- ondragleave: htmlAttributeNode,
- ondragstart: htmlAttributeNode,
- onloadstart: htmlAttributeNode,
- onmousedown: htmlAttributeNode,
- onmousemove: htmlAttributeNode,
- onmouseover: htmlAttributeNode,
- placeholder: htmlAttributeNode,
- formaction: htmlAttributeNode,
- "http-equiv": htmlAttributeNode,
- novalidate: htmlAttributeNode,
- ondblclick: htmlAttributeNode,
- ondragover: htmlAttributeNode,
- onkeypress: htmlAttributeNode,
- onmouseout: htmlAttributeNode,
- onpagehide: htmlAttributeNode,
- onpageshow: htmlAttributeNode,
- onpopstate: htmlAttributeNode,
- onprogress: htmlAttributeNode,
- spellcheck: htmlAttributeNode,
- accesskey: htmlAttributeNode,
- autofocus: htmlAttributeNode,
- draggable: htmlAttributeNode,
- maxlength: htmlAttributeNode,
- oncanplay: htmlAttributeNode,
- ondragend: htmlAttributeNode,
- onemptied: htmlAttributeNode,
- oninvalid: htmlAttributeNode,
- onkeydown: htmlAttributeNode,
- onmouseup: htmlAttributeNode,
- onoffline: htmlAttributeNode,
- onplaying: htmlAttributeNode,
- onseeking: htmlAttributeNode,
- onstalled: htmlAttributeNode,
- onstorage: htmlAttributeNode,
- onsuspend: htmlAttributeNode,
- onwaiting: htmlAttributeNode,
- translate: htmlAttributeNode,
- autoplay: htmlAttributeNode,
- controls: htmlAttributeNode,
- datetime: htmlAttributeNode,
- disabled: htmlAttributeNode,
- download: htmlAttributeNode,
- dropzone: htmlAttributeNode,
- hreflang: htmlAttributeNode,
- multiple: htmlAttributeNode,
- onchange: htmlAttributeNode,
- ononline: htmlAttributeNode,
- onresize: htmlAttributeNode,
- onscroll: htmlAttributeNode,
- onsearch: htmlAttributeNode,
- onseeked: htmlAttributeNode,
- onselect: htmlAttributeNode,
- onsubmit: htmlAttributeNode,
- ontoggle: htmlAttributeNode,
- onunload: htmlAttributeNode,
- property: htmlAttributeNode,
- readonly: htmlAttributeNode,
- required: htmlAttributeNode,
- reversed: htmlAttributeNode,
- selected: htmlAttributeNode,
- tabindex: htmlAttributeNode,
- bgcolor: htmlAttributeNode,
- charset: htmlAttributeNode,
- checked: htmlAttributeNode,
- colspan: htmlAttributeNode,
- content: htmlAttributeNode,
- default: htmlAttributeNode,
- dirname: htmlAttributeNode,
- enctype: htmlAttributeNode,
- headers: htmlAttributeNode,
- onabort: htmlAttributeNode,
- onclick: htmlAttributeNode,
- onended: htmlAttributeNode,
- onerror: htmlAttributeNode,
- onfocus: htmlAttributeNode,
- oninput: htmlAttributeNode,
- onkeyup: htmlAttributeNode,
- onpaste: htmlAttributeNode,
- onpause: htmlAttributeNode,
- onreset: htmlAttributeNode,
- onwheel: htmlAttributeNode,
- optimum: htmlAttributeNode,
- pattern: htmlAttributeNode,
- preload: htmlAttributeNode,
- rowspan: htmlAttributeNode,
- sandbox: htmlAttributeNode,
- srclang: htmlAttributeNode,
- accept: htmlAttributeNode,
- action: htmlAttributeNode,
- border: htmlAttributeNode,
- coords: htmlAttributeNode,
- height: htmlAttributeNode,
- hidden: htmlAttributeNode,
- method: htmlAttributeNode,
- onblur: htmlAttributeNode,
- oncopy: htmlAttributeNode,
- ondrag: htmlAttributeNode,
- ondrop: htmlAttributeNode,
- onload: htmlAttributeNode,
- onplay: htmlAttributeNode,
- poster: htmlAttributeNode,
- srcdoc: htmlAttributeNode,
- srcset: htmlAttributeNode,
- target: htmlAttributeNode,
- usemap: htmlAttributeNode,
- align: htmlAttributeNode,
- async: htmlAttributeNode,
- class: htmlAttributeNode,
- color: htmlAttributeNode,
- defer: htmlAttributeNode,
- ismap: htmlAttributeNode,
- media: htmlAttributeNode,
- muted: htmlAttributeNode,
- oncut: htmlAttributeNode,
- scope: htmlAttributeNode,
- shape: htmlAttributeNode,
- sizes: htmlAttributeNode,
- start: htmlAttributeNode,
- style: htmlAttributeNode,
- title: htmlAttributeNode,
- value: htmlAttributeNode,
- width: htmlAttributeNode,
- cols: htmlAttributeNode,
- high: htmlAttributeNode,
- href: htmlAttributeNode,
- kind: htmlAttributeNode,
- lang: htmlAttributeNode,
- list: htmlAttributeNode,
- loop: htmlAttributeNode,
- name: htmlAttributeNode,
- open: htmlAttributeNode,
- rows: htmlAttributeNode,
- size: htmlAttributeNode,
- step: htmlAttributeNode,
- type: htmlAttributeNode,
- wrap: htmlAttributeNode,
- alt: htmlAttributeNode,
- dir: htmlAttributeNode,
- for: htmlAttributeNode,
- low: htmlAttributeNode,
- max: htmlAttributeNode,
- min: htmlAttributeNode,
- rel: htmlAttributeNode,
- src: htmlAttributeNode,
- id: htmlAttributeNode,
- lineShiftClickCommand: stumpExtendedAttributeNode,
- contextMenuCommand: stumpExtendedAttributeNode,
- doubleClickCommand: stumpExtendedAttributeNode,
- shiftClickCommand: stumpExtendedAttributeNode,
- lineClickCommand: stumpExtendedAttributeNode,
- changeCommand: stumpExtendedAttributeNode,
- clickCommand: stumpExtendedAttributeNode,
- keyUpCommand: stumpExtendedAttributeNode,
- blurCommand: stumpExtendedAttributeNode,
- collapse: stumpExtendedAttributeNode,
- bern: bernNode
+ Object.assign(Object.assign({}, super.createParserCombinator()._getFirstWordMapAsObject()), {
+ blockquote: htmlTagParser,
+ colgroup: htmlTagParser,
+ datalist: htmlTagParser,
+ fieldset: htmlTagParser,
+ menuitem: htmlTagParser,
+ noscript: htmlTagParser,
+ optgroup: htmlTagParser,
+ progress: htmlTagParser,
+ styleTag: htmlTagParser,
+ template: htmlTagParser,
+ textarea: htmlTagParser,
+ titleTag: htmlTagParser,
+ address: htmlTagParser,
+ article: htmlTagParser,
+ caption: htmlTagParser,
+ details: htmlTagParser,
+ section: htmlTagParser,
+ summary: htmlTagParser,
+ button: htmlTagParser,
+ canvas: htmlTagParser,
+ dialog: htmlTagParser,
+ figure: htmlTagParser,
+ footer: htmlTagParser,
+ header: htmlTagParser,
+ hgroup: htmlTagParser,
+ iframe: htmlTagParser,
+ keygen: htmlTagParser,
+ legend: htmlTagParser,
+ object: htmlTagParser,
+ option: htmlTagParser,
+ output: htmlTagParser,
+ script: htmlTagParser,
+ select: htmlTagParser,
+ source: htmlTagParser,
+ strong: htmlTagParser,
+ aside: htmlTagParser,
+ embed: htmlTagParser,
+ input: htmlTagParser,
+ label: htmlTagParser,
+ meter: htmlTagParser,
+ param: htmlTagParser,
+ small: htmlTagParser,
+ table: htmlTagParser,
+ tbody: htmlTagParser,
+ tfoot: htmlTagParser,
+ thead: htmlTagParser,
+ track: htmlTagParser,
+ video: htmlTagParser,
+ abbr: htmlTagParser,
+ area: htmlTagParser,
+ base: htmlTagParser,
+ body: htmlTagParser,
+ code: htmlTagParser,
+ form: htmlTagParser,
+ head: htmlTagParser,
+ html: htmlTagParser,
+ link: htmlTagParser,
+ main: htmlTagParser,
+ mark: htmlTagParser,
+ menu: htmlTagParser,
+ meta: htmlTagParser,
+ ruby: htmlTagParser,
+ samp: htmlTagParser,
+ span: htmlTagParser,
+ time: htmlTagParser,
+ bdi: htmlTagParser,
+ bdo: htmlTagParser,
+ col: htmlTagParser,
+ del: htmlTagParser,
+ dfn: htmlTagParser,
+ div: htmlTagParser,
+ img: htmlTagParser,
+ ins: htmlTagParser,
+ kbd: htmlTagParser,
+ map: htmlTagParser,
+ nav: htmlTagParser,
+ pre: htmlTagParser,
+ rtc: htmlTagParser,
+ sub: htmlTagParser,
+ sup: htmlTagParser,
+ var: htmlTagParser,
+ wbr: htmlTagParser,
+ br: htmlTagParser,
+ dd: htmlTagParser,
+ dl: htmlTagParser,
+ dt: htmlTagParser,
+ em: htmlTagParser,
+ h1: htmlTagParser,
+ h2: htmlTagParser,
+ h3: htmlTagParser,
+ h4: htmlTagParser,
+ h5: htmlTagParser,
+ h6: htmlTagParser,
+ hr: htmlTagParser,
+ li: htmlTagParser,
+ ol: htmlTagParser,
+ rb: htmlTagParser,
+ rp: htmlTagParser,
+ rt: htmlTagParser,
+ td: htmlTagParser,
+ th: htmlTagParser,
+ tr: htmlTagParser,
+ ul: htmlTagParser,
+ a: htmlTagParser,
+ b: htmlTagParser,
+ i: htmlTagParser,
+ p: htmlTagParser,
+ q: htmlTagParser,
+ s: htmlTagParser,
+ u: htmlTagParser,
+ oncanplaythrough: htmlAttributeParser,
+ ondurationchange: htmlAttributeParser,
+ onloadedmetadata: htmlAttributeParser,
+ contenteditable: htmlAttributeParser,
+ "accept-charset": htmlAttributeParser,
+ onbeforeunload: htmlAttributeParser,
+ onvolumechange: htmlAttributeParser,
+ onbeforeprint: htmlAttributeParser,
+ oncontextmenu: htmlAttributeParser,
+ autocomplete: htmlAttributeParser,
+ onafterprint: htmlAttributeParser,
+ onhashchange: htmlAttributeParser,
+ onloadeddata: htmlAttributeParser,
+ onmousewheel: htmlAttributeParser,
+ onratechange: htmlAttributeParser,
+ ontimeupdate: htmlAttributeParser,
+ oncuechange: htmlAttributeParser,
+ ondragenter: htmlAttributeParser,
+ ondragleave: htmlAttributeParser,
+ ondragstart: htmlAttributeParser,
+ onloadstart: htmlAttributeParser,
+ onmousedown: htmlAttributeParser,
+ onmousemove: htmlAttributeParser,
+ onmouseover: htmlAttributeParser,
+ placeholder: htmlAttributeParser,
+ formaction: htmlAttributeParser,
+ "http-equiv": htmlAttributeParser,
+ novalidate: htmlAttributeParser,
+ ondblclick: htmlAttributeParser,
+ ondragover: htmlAttributeParser,
+ onkeypress: htmlAttributeParser,
+ onmouseout: htmlAttributeParser,
+ onpagehide: htmlAttributeParser,
+ onpageshow: htmlAttributeParser,
+ onpopstate: htmlAttributeParser,
+ onprogress: htmlAttributeParser,
+ spellcheck: htmlAttributeParser,
+ accesskey: htmlAttributeParser,
+ autofocus: htmlAttributeParser,
+ draggable: htmlAttributeParser,
+ maxlength: htmlAttributeParser,
+ oncanplay: htmlAttributeParser,
+ ondragend: htmlAttributeParser,
+ onemptied: htmlAttributeParser,
+ oninvalid: htmlAttributeParser,
+ onkeydown: htmlAttributeParser,
+ onmouseup: htmlAttributeParser,
+ onoffline: htmlAttributeParser,
+ onplaying: htmlAttributeParser,
+ onseeking: htmlAttributeParser,
+ onstalled: htmlAttributeParser,
+ onstorage: htmlAttributeParser,
+ onsuspend: htmlAttributeParser,
+ onwaiting: htmlAttributeParser,
+ translate: htmlAttributeParser,
+ autoplay: htmlAttributeParser,
+ controls: htmlAttributeParser,
+ datetime: htmlAttributeParser,
+ disabled: htmlAttributeParser,
+ download: htmlAttributeParser,
+ dropzone: htmlAttributeParser,
+ hreflang: htmlAttributeParser,
+ multiple: htmlAttributeParser,
+ onchange: htmlAttributeParser,
+ ononline: htmlAttributeParser,
+ onresize: htmlAttributeParser,
+ onscroll: htmlAttributeParser,
+ onsearch: htmlAttributeParser,
+ onseeked: htmlAttributeParser,
+ onselect: htmlAttributeParser,
+ onsubmit: htmlAttributeParser,
+ ontoggle: htmlAttributeParser,
+ onunload: htmlAttributeParser,
+ property: htmlAttributeParser,
+ readonly: htmlAttributeParser,
+ required: htmlAttributeParser,
+ reversed: htmlAttributeParser,
+ selected: htmlAttributeParser,
+ tabindex: htmlAttributeParser,
+ bgcolor: htmlAttributeParser,
+ charset: htmlAttributeParser,
+ checked: htmlAttributeParser,
+ colspan: htmlAttributeParser,
+ content: htmlAttributeParser,
+ default: htmlAttributeParser,
+ dirname: htmlAttributeParser,
+ enctype: htmlAttributeParser,
+ headers: htmlAttributeParser,
+ onabort: htmlAttributeParser,
+ onclick: htmlAttributeParser,
+ onended: htmlAttributeParser,
+ onerror: htmlAttributeParser,
+ onfocus: htmlAttributeParser,
+ oninput: htmlAttributeParser,
+ onkeyup: htmlAttributeParser,
+ onpaste: htmlAttributeParser,
+ onpause: htmlAttributeParser,
+ onreset: htmlAttributeParser,
+ onwheel: htmlAttributeParser,
+ optimum: htmlAttributeParser,
+ pattern: htmlAttributeParser,
+ preload: htmlAttributeParser,
+ rowspan: htmlAttributeParser,
+ sandbox: htmlAttributeParser,
+ srclang: htmlAttributeParser,
+ accept: htmlAttributeParser,
+ action: htmlAttributeParser,
+ border: htmlAttributeParser,
+ coords: htmlAttributeParser,
+ height: htmlAttributeParser,
+ hidden: htmlAttributeParser,
+ method: htmlAttributeParser,
+ onblur: htmlAttributeParser,
+ oncopy: htmlAttributeParser,
+ ondrag: htmlAttributeParser,
+ ondrop: htmlAttributeParser,
+ onload: htmlAttributeParser,
+ onplay: htmlAttributeParser,
+ poster: htmlAttributeParser,
+ srcdoc: htmlAttributeParser,
+ srcset: htmlAttributeParser,
+ target: htmlAttributeParser,
+ usemap: htmlAttributeParser,
+ align: htmlAttributeParser,
+ async: htmlAttributeParser,
+ class: htmlAttributeParser,
+ color: htmlAttributeParser,
+ defer: htmlAttributeParser,
+ ismap: htmlAttributeParser,
+ media: htmlAttributeParser,
+ muted: htmlAttributeParser,
+ oncut: htmlAttributeParser,
+ scope: htmlAttributeParser,
+ shape: htmlAttributeParser,
+ sizes: htmlAttributeParser,
+ start: htmlAttributeParser,
+ style: htmlAttributeParser,
+ title: htmlAttributeParser,
+ value: htmlAttributeParser,
+ width: htmlAttributeParser,
+ cols: htmlAttributeParser,
+ high: htmlAttributeParser,
+ href: htmlAttributeParser,
+ kind: htmlAttributeParser,
+ lang: htmlAttributeParser,
+ list: htmlAttributeParser,
+ loop: htmlAttributeParser,
+ name: htmlAttributeParser,
+ open: htmlAttributeParser,
+ rows: htmlAttributeParser,
+ size: htmlAttributeParser,
+ step: htmlAttributeParser,
+ type: htmlAttributeParser,
+ wrap: htmlAttributeParser,
+ alt: htmlAttributeParser,
+ dir: htmlAttributeParser,
+ for: htmlAttributeParser,
+ low: htmlAttributeParser,
+ max: htmlAttributeParser,
+ min: htmlAttributeParser,
+ rel: htmlAttributeParser,
+ src: htmlAttributeParser,
+ id: htmlAttributeParser,
+ lineShiftClickCommand: stumpExtendedAttributeParser,
+ contextMenuCommand: stumpExtendedAttributeParser,
+ doubleClickCommand: stumpExtendedAttributeParser,
+ shiftClickCommand: stumpExtendedAttributeParser,
+ lineClickCommand: stumpExtendedAttributeParser,
+ changeCommand: stumpExtendedAttributeParser,
+ clickCommand: stumpExtendedAttributeParser,
+ keyUpCommand: stumpExtendedAttributeParser,
+ blurCommand: stumpExtendedAttributeParser,
+ collapse: stumpExtendedAttributeParser,
+ bern: bernParser,
- [{ regex: /^$/, nodeConstructor: blankLineNode }, { regex: /^[a-zA-Z0-9_]+Component/, nodeConstructor: componentDefinitionNode }]
+ [
+ { regex: /^$/, parser: blankLineParser },
+ { regex: /^[a-zA-Z0-9_]+Component/, parser: componentDefinitionParser },
+ ]
Changed around line 17284: bernNode
- isHtmlTagNode = true
+ isHtmlTagParser = true
- const firstWord = this.getFirstWord()
+ const firstWord = this.firstWord
- styleTag: "style"
+ styleTag: "style",
- toHtmlWithSuids() {
+ asHtmlWithSuids() {
Changed around line 17313: bernNode
- this.filter(node => node.isAttributeNode).forEach(child => elem.setAttribute(child.getFirstWord(), child.getContent()))
+ this.filter((node) => node.isAttributeParser).forEach((child) => elem.setAttribute(child.firstWord, child.content))
- this.filter(node => node.isHtmlTagNode).forEach(child => elem.appendChild(child.domElement))
+ this.filter((node) => node.isHtmlTagParser).forEach((child) => elem.appendChild(child.domElement))
- const children = this.map(child => child._toHtml(indentCount + 1, withSuid)).join("")
- const attributesStr = this.filter(node => node.isAttributeNode)
- .map(child => child.getAttribute())
+ const children = this.map((child) => child._toHtml(indentCount + 1, withSuid)).join("")
+ const attributesStr = this.filter((node) => node.isAttributeParser)
+ .map((child) => child.getAttribute())
- const indentForChildNodes = !collapse && this.getChildInstancesOfNodeTypeId("htmlTagNode").length > 0
+ const indentForChildParsers = !collapse && this.getChildInstancesOfParserId("htmlTagParser").length > 0
- return `${!collapse ? indent : ""}<${tag}${attributesStr}${suid}>${oneLiner}${indentForChildNodes ? "\n" : ""}${children}${tag}>${collapse ? "" : "\n"}`
+ return `${!collapse ? indent : ""}<${tag}${attributesStr}${suid}>${oneLiner}${indentForChildParsers ? "\n" : ""}${children}${tag}>${
+ collapse ? "" : "\n"
+ }`
Changed around line 17341: bernNode
- return this.getTopDownArray().find(node => node._getUid() === guid)
+ return this.topDownArray.find((node) => node._getUid() === guid)
- const classNode = this.touchNode("class")
- const words = classNode.getWordsFrom(1)
+ const classParser = this.touchNode("class")
+ const words = classParser.getWordsFrom(1)
- classNode.setContent(words.join(this.getWordBreakSymbol()))
+ classParser.setContent(words.join(this.wordBreakSymbol))
- const classNode = this.getNode("class")
- if (!classNode) return this
- const newClasses = classNode.getWords().filter(word => word !== className)
- if (!newClasses.length) classNode.destroy()
- else classNode.setContent(newClasses.join(" "))
+ const classParser = this.getNode("class")
+ if (!classParser) return this
+ const newClasses = classParser.words.filter((word) => word !== className)
+ if (!newClasses.length) classParser.destroy()
+ else classParser.setContent(newClasses.join(" "))
- const classNode = this.getNode("class")
- return classNode && classNode.getWords().includes(className) ? true : false
+ const classParser = this.getNode("class")
+ return classParser && classParser.words.includes(className) ? true : false
Changed around line 17381: bernNode
- const singleNode = new jtree.TreeNode(text).getChildren()[0]
+ const singleNode = new TreeNode(text).getChildren()[0]
- const stumpNodeIndex = this.filter(node => node.isHtmlTagNode).indexOf(newNode)
- this.getShadow().insertHtmlNode(newNode, stumpNodeIndex)
+ const stumpParserIndex = this.filter((node) => node.isHtmlTagParser).indexOf(newNode)
+ this.getShadow().insertHtmlNode(newNode, stumpParserIndex)
Changed around line 17394: bernNode
- return this.getTopDownArray().find(node =>
+ return this.topDownArray.find((node) =>
- .map(child => child.getLine())
+ .map((child) => child.getLine())
Changed around line 17405: bernNode
- return this.getTopDownArray().filter(node => node.doesExtend("htmlTagNode") && node.getFirstWord() === firstWord)
+ return this.topDownArray.filter((node) => node.doesExtend("htmlTagParser") && node.firstWord === firstWord)
- return this.getChildren().some(node => node.getLine() === line)
+ return this.getChildren().some((node) => node.getLine() === line)
- return this.getTopDownArray().filter(node => node.doesExtend("htmlTagNode") && node.hasLine(line))
+ return this.topDownArray.filter((node) => node.doesExtend("htmlTagParser") && node.hasLine(line))
- return this.getTopDownArray().filter(
- node =>
- node.doesExtend("htmlTagNode") &&
- node.has("class") &&
- node
- .getNode("class")
- .getWords()
- .includes(className)
- )
+ return this.topDownArray.filter((node) => node.doesExtend("htmlTagParser") && node.has("class") && node.getNode("class").words.includes(className))
- return this.getParent().getShadowClass()
+ return this.parent.getShadowClass()
- return this._treeComponent || this.getParent().getStumpNodeTreeComponent()
+ return this._treeComponent || this.parent.getStumpNodeTreeComponent()
Changed around line 17438: bernNode
- toHtml() {
+ get asHtml() {
- class errorNode extends jtree.GrammarBackedNode {
+ class errorParser extends GrammarBackedNode {
- return this._getErrorNodeErrors()
+ return this._getErrorParserErrors()
- class componentDefinitionNode extends htmlTagNode {
+ class componentDefinitionParser extends htmlTagParser {
Changed around line 17458: bernNode
- class htmlAttributeNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(errorNode, undefined, undefined)
+ class htmlAttributeParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(errorParser, undefined, undefined)
Changed around line 17471: bernNode
- get isAttributeNode() {
+ get isAttributeParser() {
Changed around line 17481: bernNode
- return ` ${this.getFirstWord()}="${this.getContent()}"`
+ return ` ${this.firstWord}="${this.content}"`
- class stumpExtendedAttributeNode extends htmlAttributeNode {
+ class stumpExtendedAttributeParser extends htmlAttributeParser {
- class lineOfHtmlContentNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(lineOfHtmlContentNode, undefined, undefined)
+ class lineOfHtmlContentParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(lineOfHtmlContentParser, undefined, undefined)
Changed around line 17506: bernNode
- class bernNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(lineOfHtmlContentNode, undefined, undefined)
+ class bernParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(lineOfHtmlContentParser, undefined, undefined)
Changed around line 17524: bernNode
- window.stumpNode = stumpNode
+ window.stumpParser = stumpParser
- class hakonNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(
- selectorNode,
- Object.assign(Object.assign({}, super.createParser()._getFirstWordMapAsObject()), { comment: commentNode }),
+ class hakonParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(
+ selectorParser,
+ Object.assign(Object.assign({}, super.createParserCombinator()._getFirstWordMapAsObject()), { comment: commentParser }),
Changed around line 17541: bernNode
- return this.getTopDownArray()
- .filter(node => node.isSelectorNode)
- .map(child => child.compile())
+ return this.topDownArray
+ .filter((node) => node.isSelectorParser)
+ .map((child) => child.compile())
- static cachedHandGrammarProgramRoot = new jtree.HandGrammarProgram(`tooling onsave jtree build produceLang hakon
+ static cachedHandGrammarProgramRoot = new HandGrammarProgram(`// Cell Parsers
Changed around line 17560: cssValueCell
- todo add html tags, css and ids selector regexes, etc
+ // todo add html tags, css and ids selector regexes, etc
Changed around line 17568: vendorPrefixPropertyKeywordCell
- todo Where are these coming from? Can we add a url link
+ // todo Where are these coming from? Can we add a url link
- hakonNode
+
+ // Line Parsers
+ hakonParser
- todo Add variables?
+ // todo Add variables?
- inScope commentNode
- catchAllNodeType selectorNode
+ inScope commentParser
+ catchAllParser selectorParser
- return this.getTopDownArray()
- .filter(node => node.isSelectorNode)
+ return this.topDownArray
+ .filter(node => node.isSelectorParser)
Changed around line 17602: hakonNode
- propertyNode
+ propertyParser
- catchAllNodeType errorNode
+ catchAllParser errorParser
- return \`\${spaces}\${this.getFirstWord()}: \${this.getContent()};\`
+ return \`\${spaces}\${this.firstWord}: \${this.content};\`
- variableNode
- extends propertyNode
+ variableParser
+ extends propertyParser
- browserPrefixPropertyNode
- extends propertyNode
+ browserPrefixPropertyParser
+ extends propertyParser
- errorNode
- catchAllNodeType errorNode
+ errorParser
+ catchAllParser errorParser
- baseNodeType errorNode
- commentNode
+ baseParser errorParser
+ commentParser
- catchAllNodeType commentNode
- selectorNode
- inScope propertyNode variableNode commentNode
- catchAllNodeType selectorNode
- boolean isSelectorNode true
+ catchAllParser commentParser
+ selectorParser
+ inScope propertyParser variableParser commentParser
+ catchAllParser selectorParser
+ boolean isSelectorParser true
- const parentSelector = this.getParent().getSelector()
- return this.getFirstWord()
+ const parentSelector = this.parent.getSelector()
+ return this.firstWord
Changed around line 17641: selectorNode
- const propertyNodes = this.getChildren().filter(node => node.doesExtend("propertyNode"))
- if (!propertyNodes.length) return ""
+ const propertyParsers = this.getChildren().filter(node => node.doesExtend("propertyParser"))
+ if (!propertyParsers.length) return ""
- \${propertyNodes.map(child => child.compile(spaces)).join("\\n")}
+ \${propertyParsers.map(child => child.compile(spaces)).join("\\n")}
- getHandGrammarProgram() {
+ get handGrammarProgram() {
- static getNodeTypeMap() {
- return {
- hakonNode: hakonNode,
- propertyNode: propertyNode,
- variableNode: variableNode,
- browserPrefixPropertyNode: browserPrefixPropertyNode,
- errorNode: errorNode,
- commentNode: commentNode,
- selectorNode: selectorNode
- }
- }
+ static rootParser = hakonParser
- class propertyNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(errorNode, undefined, undefined)
+ class propertyParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(errorParser, undefined, undefined)
Changed around line 17666: selectorNode
- return `${spaces}${this.getFirstWord()}: ${this.getContent()};`
+ return `${spaces}${this.firstWord}: ${this.content};`
- class variableNode extends propertyNode {}
+ class variableParser extends propertyParser {}
- class browserPrefixPropertyNode extends propertyNode {
+ class browserPrefixPropertyParser extends propertyParser {
- class errorNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(errorNode, undefined, undefined)
+ class errorParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(errorParser, undefined, undefined)
- return this._getErrorNodeErrors()
+ return this._getErrorParserErrors()
- class commentNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(commentNode, undefined, undefined)
+ class commentParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(commentParser, undefined, undefined)
Changed around line 17702: selectorNode
- class selectorNode extends jtree.GrammarBackedNode {
- createParser() {
- return new jtree.TreeNode.Parser(
- selectorNode,
- Object.assign(Object.assign({}, super.createParser()._getFirstWordMapAsObject()), {
- "border-bottom-right-radius": propertyNode,
- "transition-timing-function": propertyNode,
- "animation-iteration-count": propertyNode,
- "animation-timing-function": propertyNode,
- "border-bottom-left-radius": propertyNode,
- "border-top-right-radius": propertyNode,
- "border-top-left-radius": propertyNode,
- "background-attachment": propertyNode,
- "background-blend-mode": propertyNode,
- "text-decoration-color": propertyNode,
- "text-decoration-style": propertyNode,
- "overscroll-behavior-x": propertyNode,
- "-webkit-touch-callout": propertyNode,
- "grid-template-columns": propertyNode,
- "animation-play-state": propertyNode,
- "text-decoration-line": propertyNode,
- "animation-direction": propertyNode,
- "animation-fill-mode": propertyNode,
- "backface-visibility": propertyNode,
- "background-position": propertyNode,
- "border-bottom-color": propertyNode,
- "border-bottom-style": propertyNode,
- "border-bottom-width": propertyNode,
- "border-image-outset": propertyNode,
- "border-image-repeat": propertyNode,
- "border-image-source": propertyNode,
- "hanging-punctuation": propertyNode,
- "list-style-position": propertyNode,
- "transition-duration": propertyNode,
- "transition-property": propertyNode,
- "-webkit-user-select": propertyNode,
- "animation-duration": propertyNode,
- "border-image-slice": propertyNode,
- "border-image-width": propertyNode,
- "border-right-color": propertyNode,
- "border-right-style": propertyNode,
- "border-right-width": propertyNode,
- "perspective-origin": propertyNode,
- "-khtml-user-select": propertyNode,
- "grid-template-rows": propertyNode,
- "background-origin": propertyNode,
- "background-repeat": propertyNode,
- "border-left-color": propertyNode,
- "border-left-style": propertyNode,
- "border-left-width": propertyNode,
- "column-rule-color": propertyNode,
- "column-rule-style": propertyNode,
- "column-rule-width": propertyNode,
- "counter-increment": propertyNode,
- "page-break-before": propertyNode,
- "page-break-inside": propertyNode,
- "grid-column-start": propertyNode,
- "background-color": propertyNode,
- "background-image": propertyNode,
- "border-top-color": propertyNode,
- "border-top-style": propertyNode,
- "border-top-width": propertyNode,
- "font-size-adjust": propertyNode,
- "list-style-image": propertyNode,
- "page-break-after": propertyNode,
- "transform-origin": propertyNode,
- "transition-delay": propertyNode,
- "-ms-touch-action": propertyNode,
- "-moz-user-select": propertyNode,
- "animation-delay": propertyNode,
- "background-clip": propertyNode,
- "background-size": propertyNode,
- "border-collapse": propertyNode,
- "justify-content": propertyNode,
- "list-style-type": propertyNode,
- "text-align-last": propertyNode,
- "text-decoration": propertyNode,
- "transform-style": propertyNode,
- "-ms-user-select": propertyNode,
- "grid-column-end": propertyNode,
- "grid-column-gap": propertyNode,
- "animation-name": propertyNode,
- "border-spacing": propertyNode,
- "flex-direction": propertyNode,
- "letter-spacing": propertyNode,
- "outline-offset": propertyNode,
- "padding-bottom": propertyNode,
- "text-transform": propertyNode,
- "vertical-align": propertyNode,
- "grid-auto-flow": propertyNode,
- "grid-row-start": propertyNode,
- "align-content": propertyNode,
- "border-bottom": propertyNode,
- "border-radius": propertyNode,
- "counter-reset": propertyNode,
- "margin-bottom": propertyNode,
- "outline-color": propertyNode,
- "outline-style": propertyNode,
- "outline-width": propertyNode,
- "padding-right": propertyNode,
- "text-overflow": propertyNode,
- "justify-items": propertyNode,
- "border-color": propertyNode,
- "border-image": propertyNode,
- "border-right": propertyNode,
- "border-style": propertyNode,
- "border-width": propertyNode,
- "break-inside": propertyNode,
- "caption-side": propertyNode,
- "column-count": propertyNode,
- "column-width": propertyNode,
- "font-stretch": propertyNode,
- "font-variant": propertyNode,
- "margin-right": propertyNode,
- "padding-left": propertyNode,
- "table-layout": propertyNode,
- "text-justify": propertyNode,
- "unicode-bidi": propertyNode,
- "word-spacing": propertyNode,
- "touch-action": propertyNode,
- "grid-row-end": propertyNode,
- "grid-row-gap": propertyNode,
- "justify-self": propertyNode,
- "align-items": propertyNode,
- "border-left": propertyNode,
- "column-fill": propertyNode,
- "column-rule": propertyNode,
- "column-span": propertyNode,
- "empty-cells": propertyNode,
- "flex-shrink": propertyNode,
- "font-family": propertyNode,
- "font-weight": propertyNode,
- "line-height": propertyNode,
- "margin-left": propertyNode,
- "padding-top": propertyNode,
- perspective: propertyNode,
- "text-indent": propertyNode,
- "text-shadow": propertyNode,
- "white-space": propertyNode,
- "user-select": propertyNode,
- "grid-column": propertyNode,
- "align-self": propertyNode,
- background: propertyNode,
- "border-top": propertyNode,
- "box-shadow": propertyNode,
- "box-sizing": propertyNode,
- "column-gap": propertyNode,
- "flex-basis": propertyNode,
- "@font-face": propertyNode,
- "font-style": propertyNode,
- "@keyframes": propertyNode,
- "list-style": propertyNode,
- "margin-top": propertyNode,
- "max-height": propertyNode,
- "min-height": propertyNode,
- "overflow-x": propertyNode,
- "overflow-y": propertyNode,
- "text-align": propertyNode,
- transition: propertyNode,
- visibility: propertyNode,
- "word-break": propertyNode,
- animation: propertyNode,
- direction: propertyNode,
- "flex-flow": propertyNode,
- "flex-grow": propertyNode,
- "flex-wrap": propertyNode,
- "font-size": propertyNode,
- "max-width": propertyNode,
- "min-width": propertyNode,
- "nav-index": propertyNode,
- "nav-right": propertyNode,
- transform: propertyNode,
- "word-wrap": propertyNode,
- "nav-down": propertyNode,
- "nav-left": propertyNode,
- overflow: propertyNode,
- position: propertyNode,
- "tab-size": propertyNode,
- "grid-gap": propertyNode,
- "grid-row": propertyNode,
- columns: propertyNode,
- content: propertyNode,
- display: propertyNode,
- hyphens: propertyNode,
- opacity: propertyNode,
- outline: propertyNode,
- padding: propertyNode,
- "z-index": propertyNode,
- border: propertyNode,
- bottom: propertyNode,
- cursor: propertyNode,
- filter: propertyNode,
- height: propertyNode,
- margin: propertyNode,
- "@media": propertyNode,
- "nav-up": propertyNode,
- quotes: propertyNode,
- resize: propertyNode,
- clear: propertyNode,
- color: propertyNode,
- float: propertyNode,
- order: propertyNode,
- right: propertyNode,
- width: propertyNode,
- clip: propertyNode,
- fill: propertyNode,
- flex: propertyNode,
- font: propertyNode,
- left: propertyNode,
- all: propertyNode,
- top: propertyNode,
- gap: propertyNode,
- "": propertyNode,
- comment: commentNode
+ class selectorParser extends GrammarBackedNode {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(
+ selectorParser,
+ Object.assign(Object.assign({}, super.createParserCombinator()._getFirstWordMapAsObject()), {
+ "border-bottom-right-radius": propertyParser,
+ "transition-timing-function": propertyParser,
+ "animation-iteration-count": propertyParser,
+ "animation-timing-function": propertyParser,
+ "border-bottom-left-radius": propertyParser,
+ "border-top-right-radius": propertyParser,
+ "border-top-left-radius": propertyParser,
+ "background-attachment": propertyParser,
+ "background-blend-mode": propertyParser,
+ "text-decoration-color": propertyParser,
+ "text-decoration-style": propertyParser,
+ "overscroll-behavior-x": propertyParser,
+ "-webkit-touch-callout": propertyParser,
+ "grid-template-columns": propertyParser,
+ "animation-play-state": propertyParser,
+ "text-decoration-line": propertyParser,
+ "animation-direction": propertyParser,
+ "animation-fill-mode": propertyParser,
+ "backface-visibility": propertyParser,
+ "background-position": propertyParser,
+ "border-bottom-color": propertyParser,
+ "border-bottom-style": propertyParser,
+ "border-bottom-width": propertyParser,
+ "border-image-outset": propertyParser,
+ "border-image-repeat": propertyParser,
+ "border-image-source": propertyParser,
+ "hanging-punctuation": propertyParser,
+ "list-style-position": propertyParser,
+ "transition-duration": propertyParser,
+ "transition-property": propertyParser,
+ "-webkit-user-select": propertyParser,
+ "animation-duration": propertyParser,
+ "border-image-slice": propertyParser,
+ "border-image-width": propertyParser,
+ "border-right-color": propertyParser,
+ "border-right-style": propertyParser,
+ "border-right-width": propertyParser,
+ "perspective-origin": propertyParser,
+ "-khtml-user-select": propertyParser,
+ "grid-template-rows": propertyParser,
+ "background-origin": propertyParser,
+ "background-repeat": propertyParser,
+ "border-left-color": propertyParser,
+ "border-left-style": propertyParser,
+ "border-left-width": propertyParser,
+ "column-rule-color": propertyParser,
+ "column-rule-style": propertyParser,
+ "column-rule-width": propertyParser,
+ "counter-increment": propertyParser,
+ "page-break-before": propertyParser,
+ "page-break-inside": propertyParser,
+ "grid-column-start": propertyParser,
+ "background-color": propertyParser,
+ "background-image": propertyParser,
+ "border-top-color": propertyParser,
+ "border-top-style": propertyParser,
+ "border-top-width": propertyParser,
+ "font-size-adjust": propertyParser,
+ "list-style-image": propertyParser,
+ "page-break-after": propertyParser,
+ "transform-origin": propertyParser,
+ "transition-delay": propertyParser,
+ "-ms-touch-action": propertyParser,
+ "-moz-user-select": propertyParser,
+ "animation-delay": propertyParser,
+ "background-clip": propertyParser,
+ "background-size": propertyParser,
+ "border-collapse": propertyParser,
+ "justify-content": propertyParser,
+ "list-style-type": propertyParser,
+ "text-align-last": propertyParser,
+ "text-decoration": propertyParser,
+ "transform-style": propertyParser,
+ "-ms-user-select": propertyParser,
+ "grid-column-end": propertyParser,
+ "grid-column-gap": propertyParser,
+ "animation-name": propertyParser,
+ "border-spacing": propertyParser,
+ "flex-direction": propertyParser,
+ "letter-spacing": propertyParser,
+ "outline-offset": propertyParser,
+ "padding-bottom": propertyParser,
+ "text-transform": propertyParser,
+ "vertical-align": propertyParser,
+ "grid-auto-flow": propertyParser,
+ "grid-row-start": propertyParser,
+ "align-content": propertyParser,
+ "border-bottom": propertyParser,
+ "border-radius": propertyParser,
+ "counter-reset": propertyParser,
+ "margin-bottom": propertyParser,
+ "outline-color": propertyParser,
+ "outline-style": propertyParser,
+ "outline-width": propertyParser,
+ "padding-right": propertyParser,
+ "text-overflow": propertyParser,
+ "justify-items": propertyParser,
+ "border-color": propertyParser,
+ "border-image": propertyParser,
+ "border-right": propertyParser,
+ "border-style": propertyParser,
+ "border-width": propertyParser,
+ "break-inside": propertyParser,
+ "caption-side": propertyParser,
+ "column-count": propertyParser,
+ "column-width": propertyParser,
+ "font-stretch": propertyParser,
+ "font-variant": propertyParser,
+ "margin-right": propertyParser,
+ "padding-left": propertyParser,
+ "table-layout": propertyParser,
+ "text-justify": propertyParser,
+ "unicode-bidi": propertyParser,
+ "word-spacing": propertyParser,
+ "touch-action": propertyParser,
+ "grid-row-end": propertyParser,
+ "grid-row-gap": propertyParser,
+ "justify-self": propertyParser,
+ "align-items": propertyParser,
+ "border-left": propertyParser,
+ "column-fill": propertyParser,
+ "column-rule": propertyParser,
+ "column-span": propertyParser,
+ "empty-cells": propertyParser,
+ "flex-shrink": propertyParser,
+ "font-family": propertyParser,
+ "font-weight": propertyParser,
+ "line-height": propertyParser,
+ "margin-left": propertyParser,
+ "padding-top": propertyParser,
+ perspective: propertyParser,
+ "text-indent": propertyParser,
+ "text-shadow": propertyParser,
+ "white-space": propertyParser,
+ "user-select": propertyParser,
+ "grid-column": propertyParser,
+ "align-self": propertyParser,
+ background: propertyParser,
+ "border-top": propertyParser,
+ "box-shadow": propertyParser,
+ "box-sizing": propertyParser,
+ "column-gap": propertyParser,
+ "flex-basis": propertyParser,
+ "@font-face": propertyParser,
+ "font-style": propertyParser,
+ "@keyframes": propertyParser,
+ "list-style": propertyParser,
+ "margin-top": propertyParser,
+ "max-height": propertyParser,
+ "min-height": propertyParser,
+ "overflow-x": propertyParser,
+ "overflow-y": propertyParser,
+ "text-align": propertyParser,
+ transition: propertyParser,
+ visibility: propertyParser,
+ "word-break": propertyParser,
+ animation: propertyParser,
+ direction: propertyParser,
+ "flex-flow": propertyParser,
+ "flex-grow": propertyParser,
+ "flex-wrap": propertyParser,
+ "font-size": propertyParser,
+ "max-width": propertyParser,
+ "min-width": propertyParser,
+ "nav-index": propertyParser,
+ "nav-right": propertyParser,
+ transform: propertyParser,
+ "word-wrap": propertyParser,
+ "nav-down": propertyParser,
+ "nav-left": propertyParser,
+ overflow: propertyParser,
+ position: propertyParser,
+ "tab-size": propertyParser,
+ "grid-gap": propertyParser,
+ "grid-row": propertyParser,
+ columns: propertyParser,
+ content: propertyParser,
+ display: propertyParser,
+ hyphens: propertyParser,
+ opacity: propertyParser,
+ outline: propertyParser,
+ padding: propertyParser,
+ "z-index": propertyParser,
+ border: propertyParser,
+ bottom: propertyParser,
+ cursor: propertyParser,
+ filter: propertyParser,
+ height: propertyParser,
+ margin: propertyParser,
+ "@media": propertyParser,
+ "nav-up": propertyParser,
+ quotes: propertyParser,
+ resize: propertyParser,
+ clear: propertyParser,
+ color: propertyParser,
+ float: propertyParser,
+ order: propertyParser,
+ right: propertyParser,
+ width: propertyParser,
+ clip: propertyParser,
+ fill: propertyParser,
+ flex: propertyParser,
+ font: propertyParser,
+ left: propertyParser,
+ all: propertyParser,
+ top: propertyParser,
+ gap: propertyParser,
+ "": propertyParser,
+ comment: commentParser,
- [{ regex: /--/, nodeConstructor: variableNode }, { regex: /^\-\w.+/, nodeConstructor: browserPrefixPropertyNode }]
+ [
+ { regex: /--/, parser: variableParser },
+ { regex: /^\-\w.+/, parser: browserPrefixPropertyParser },
+ ]
- get isSelectorNode() {
+ get isSelectorParser() {
- const parentSelector = this.getParent().getSelector()
- return this.getFirstWord()
+ const parentSelector = this.parent.getSelector()
+ return this.firstWord
- .map(part => {
+ .map((part) => {
- const propertyNodes = this.getChildren().filter(node => node.doesExtend("propertyNode"))
- if (!propertyNodes.length) return ""
+ const propertyParsers = this.getChildren().filter((node) => node.doesExtend("propertyParser"))
+ if (!propertyParsers.length) return ""
- ${propertyNodes.map(child => child.compile(spaces)).join("\n")}
+ ${propertyParsers.map((child) => child.compile(spaces)).join("\n")}
- window.hakonNode = hakonNode
+ window.hakonParser = hakonParser
Changed around line 18007: WillowConstants.checkedSelector = ":checked"
- ;(function(CacheType) {
+ ;(function (CacheType) {
Changed around line 18074: class AbstractWillowShadow {
- return this.getShadowStumpNode()
- .getParent()
- .getShadow()
+ return this.getShadowStumpNode().parent.getShadow()
Changed around line 18190: class WillowMousetrap {
- class AbstractWillowBrowser extends stumpNode {
+ class AbstractWillowBrowser extends stumpParser {
Changed around line 18294: class AbstractWillowBrowser extends stumpNode {
- return jtree.Utils.getPathWithoutFileName(this._fullHtmlPageUrlIncludingProtocolAndFileName)
+ return Utils.getPathWithoutFileName(this._fullHtmlPageUrlIncludingProtocolAndFileName)
Changed around line 18353: class AbstractWillowBrowser extends stumpNode {
- const nodes = this.getTopDownArray()
- const titleNode = nodes.find(node => node.getFirstWord() === WillowConstants.titleTag)
- return titleNode ? titleNode.getContent() : ""
+ const nodes = this.topDownArray
+ const titleNode = nodes.find(node => node.firstWord === WillowConstants.titleTag)
+ return titleNode ? titleNode.content : ""
- const nodes = this.getTopDownArray()
- const headNode = nodes.find(node => node.getFirstWord() === WillowConstants.tags.head)
+ const nodes = this.topDownArray
+ const headNode = nodes.find(node => node.firstWord === WillowConstants.tags.head)
Changed around line 18370: class AbstractWillowBrowser extends stumpNode {
- return this.getHtmlStumpNode().toHtmlWithSuids()
+ return this.getHtmlStumpNode().asHtmlWithSuids()
Changed around line 18535: class WillowBrowserShadow extends AbstractWillowShadow {
- this.element.addEventListener(event, function(evt) {
+ this.element.addEventListener(event, function (evt) {
Changed around line 18686: class RealWillowBrowser extends AbstractWillowBrowser {
- return new Promise(function(resolve, reject) {
+ return new Promise(function (resolve, reject) {
- scriptEl.onload = scriptEl.onreadystatechange = function() {
+ scriptEl.onload = scriptEl.onreadystatechange = function () {
Changed around line 18773: class RealWillowBrowser extends AbstractWillowBrowser {
- setTimeout(function() {
+ setTimeout(function () {
Changed around line 18805: class RealWillowBrowser extends AbstractWillowBrowser {
- bodyShadow.onShadowEvent(BrowserEvents.dragenter, function(event) {
+ bodyShadow.onShadowEvent(BrowserEvents.dragenter, function (event) {
Changed around line 18848: class RealWillowBrowser extends AbstractWillowBrowser {
- const hakonProgram = new hakonNode(str)
+ const hakonProgram = new hakonParser(str)
- class AbstractTreeComponent extends jtree.GrammarBackedNode {
+ class AbstractTreeComponentParser extends GrammarBackedNode {
Changed around line 18920: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- if (node.getFirstWord() === "styleTag" || (node.getContent() || "").startsWith("
+ if (node.firstWord === "styleTag" || (node.content || "").startsWith("
- const clone = new jtree.TreeNode(this.willowBrowser.getHtmlStumpNode().toString())
- clone.getTopDownArray().forEach(node => {
- if (node.getFirstWord() === "styleTag" || (node.getContent() || "").startsWith("
+ const clone = new TreeNode(this.willowBrowser.getHtmlStumpNode().toString())
+ clone.topDownArray.forEach(node => {
+ if (node.firstWord === "styleTag" || (node.content || "").startsWith("
Changed around line 18951: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- const parent = treeComponent.getParent()
+ const parent = treeComponent.parent
Changed around line 18973: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- bodyShadow.onShadowEventWithSelector(BrowserEvents.contextmenu, `[${WillowConstants.contextMenuCommand}]`, function(target, evt) {
+ bodyShadow.onShadowEventWithSelector(BrowserEvents.contextmenu, `[${WillowConstants.contextMenuCommand}]`, function (target, evt) {
- bodyShadow.onShadowEventWithSelector(BrowserEvents.click, `[${WillowConstants.clickCommand}]`, function(target, evt) {
+ bodyShadow.onShadowEventWithSelector(BrowserEvents.click, `[${WillowConstants.clickCommand}]`, function (target, evt) {
- bodyShadow.onShadowEventWithSelector(BrowserEvents.dblclick, `[${WillowConstants.doubleClickCommand}]`, function(target, evt) {
+ bodyShadow.onShadowEventWithSelector(BrowserEvents.dblclick, `[${WillowConstants.doubleClickCommand}]`, function (target, evt) {
- bodyShadow.onShadowEventWithSelector(BrowserEvents.blur, `[${WillowConstants.blurCommand}]`, function(target, evt) {
+ bodyShadow.onShadowEventWithSelector(BrowserEvents.blur, `[${WillowConstants.blurCommand}]`, function (target, evt) {
- bodyShadow.onShadowEventWithSelector(BrowserEvents.keyup, `[${WillowConstants.keyUpCommand}]`, function(target, evt) {
+ bodyShadow.onShadowEventWithSelector(BrowserEvents.keyup, `[${WillowConstants.keyUpCommand}]`, function (target, evt) {
- bodyShadow.onShadowEventWithSelector(BrowserEvents.change, `[${WillowConstants.changeCommand}]`, function(target, evt) {
+ bodyShadow.onShadowEventWithSelector(BrowserEvents.change, `[${WillowConstants.changeCommand}]`, function (target, evt) {
Changed around line 19013: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- const app = this.getRootNode()
+ const app = this.root
Changed around line 19029: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- if (!this.isRoot()) return this.getRootNode().getTheme()
+ if (!this.isRoot()) return this.root.getTheme()
Changed around line 19044: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- if (!this._messageBuffer) this._messageBuffer = new jtree.TreeNode()
+ if (!this._messageBuffer) this._messageBuffer = new TreeNode()
Changed around line 19058: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- bern${jtree.TreeNode.nest(errorMessage, 2)}`)
+ bern${TreeNode.nest(errorMessage, 2)}`)
- bern${jtree.TreeNode.nest(message, 2)}`
+ bern${TreeNode.nest(message, 2)}`
Changed around line 19086: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- return this._getJavascriptPrototypeChainUpTo("AbstractTreeComponent")
+ return this._getJavascriptPrototypeChainUpTo("AbstractTreeComponentParser")
- AbstractTreeComponent._mountedTreeComponents++
+ AbstractTreeComponentParser._mountedTreeComponents++
- AbstractTreeComponent._mountedTreeComponents--
+ AbstractTreeComponentParser._mountedTreeComponents--
Changed around line 19105: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- return this.getChildrenByNodeConstructor(AbstractTreeComponent)
+ return this.getChildrenByParser(AbstractTreeComponentParser)
Changed around line 19123: class AbstractTreeComponent extends jtree.GrammarBackedNode {
- ${new stumpNode(this.toStumpCode()).compile()}
+ ${new stumpParser(this.toStumpCode()).compile()}
Changed around line 19141: ${new stumpNode(this.toStumpCode()).compile()}
- const stumpNodeToMountOn = this._htmlStumpNode.getParent()
+ const stumpNodeToMountOn = this._htmlStumpNode.parent
Changed around line 19154: ${new stumpNode(this.toStumpCode()).compile()}
- const currentContent = currentNode === undefined ? undefined : currentNode.getContent()
+ const currentContent = currentNode === undefined ? undefined : currentNode.content
Changed around line 19166: ${new stumpNode(this.toStumpCode()).compile()}
- this.getRootNode().renderAndGetRenderReport()
+ this.root.renderAndGetRenderReport()
Changed around line 19213: ${new stumpNode(this.toStumpCode()).compile()}
- return `div Loading ${this.getFirstWord()}...
+ return `div Loading ${this.firstWord}...
Changed around line 19252: ${new stumpNode(this.toStumpCode()).compile()}
- bern${jtree.TreeNode.nest(css, 2)}`)
+ bern${TreeNode.nest(css, 2)}`)
- return this.getRootNode().willowBrowser.getHeadStumpNode()
+ return this.root.willowBrowser.getHeadStumpNode()
Changed around line 19294: ${new stumpNode(this.toStumpCode()).compile()}
- return new jtree.TreeNode(str)
+ return new TreeNode(str)
- AbstractTreeComponent._mountedTreeComponents = 0
- class TreeComponentFrameworkDebuggerComponent extends AbstractTreeComponent {
+ AbstractTreeComponentParser._mountedTreeComponents = 0
+ class TreeComponentFrameworkDebuggerComponent extends AbstractTreeComponentParser {
Changed around line 19320: class TreeComponentFrameworkDebuggerComponent extends AbstractTreeComponent {
- const app = this.getRootNode()
+ const app = this.root
Changed around line 19330: class TreeComponentFrameworkDebuggerComponent extends AbstractTreeComponent {
- p ${app.getNumberOfLines()} components loaded. ${WillowBrowser._stumpsOnPage} stumps on page.
+ p ${app.numberOfLines} components loaded. ${WillowBrowser._stumpsOnPage} stumps on page.
- class AbstractGithubTriangleComponent extends AbstractTreeComponent {
+ class AbstractGithubTriangleComponent extends AbstractTreeComponentParser {
Changed around line 19357: class AbstractGithubTriangleComponent extends AbstractTreeComponent {
- window.AbstractTreeComponent = AbstractTreeComponent
+ window.AbstractTreeComponentParser = AbstractTreeComponentParser
Changed around line 3: const yodash = {}
+
- const r1 = randomNumberGenerator()
- const r2 = randomNumberGenerator()
- if (r1 > 0.5) return r2 > 0.5 ? Directions.North : Directions.South
- return r2 > 0.5 ? Directions.West : Directions.East
+ const r1 = randomNumberGenerator()
+ const r2 = randomNumberGenerator()
+ if (r1 > 0.5) return r2 > 0.5 ? Directions.North : Directions.South
+ return r2 > 0.5 ? Directions.West : Directions.East
- let newAngle = ""
- if (angle.includes(Directions.North)) newAngle += Directions.South
- else if (angle.includes(Directions.South)) newAngle += Directions.North
- if (angle.includes(Directions.East)) newAngle += Directions.West
- else if (angle.includes(Directions.West)) newAngle += Directions.East
- return newAngle
+ let newAngle = ""
+ if (angle.includes(Directions.North)) newAngle += Directions.South
+ else if (angle.includes(Directions.South)) newAngle += Directions.North
+ if (angle.includes(Directions.East)) newAngle += Directions.West
+ else if (angle.includes(Directions.West)) newAngle += Directions.East
+ return newAngle
- if (operator === "=") return left == right
- if (operator === "<") return left < right
- if (operator === ">") return left > right
- if (operator === "<=") return left <= right
- if (operator === ">=") return left >= right
+ if (operator === "=") return left == right
+ if (operator === "<") return left < right
+ if (operator === ">") return left > right
+ if (operator === "<=") return left <= right
+ if (operator === ">=") return left >= right
- return false
+ return false
- const clone = program.clone()
- clone.filter(node => node.getNodeTypeId() !== NodeTypes.agentDefinitionNode).forEach(node => node.destroy())
- clone.agentKeywordMap = {}
- clone.agentTypes.forEach((node, index) => (clone.agentKeywordMap[node.getWord(0)] = `simAgent${index}`))
- const compiled = clone.compile()
- const agentMap = Object.keys(clone.agentKeywordMap)
- .map(key => `"${key}":${clone.agentKeywordMap[key]}`)
- .join(",")
- return `${compiled}
+ const clone = program.clone()
+ clone.filter(node => node.parserId !== ParserTypes.agentDefinitionParser).forEach(node => node.destroy())
+ clone.agentKeywordMap = {}
+ clone.agentTypes.forEach((node, index) => (clone.agentKeywordMap[node.firstWord] = `simAgent${index}`))
+ const compiled = clone.compile()
+ const agentMap = Object.keys(clone.agentKeywordMap)
+ .map(key => `"${key}":${clone.agentKeywordMap[key]}`)
+ .join(",")
+ return `${compiled}
- const clone = program.clone()
- // drop experiment nodes
- clone.filter(node => node.getNodeTypeId() === NodeTypes.experimentNode).forEach(node => node.destroy())
- // Append current experiment
- if (experiment) clone.concat(experiment.childrenToString())
- // Build symbol table
- const symbolTable = {}
- clone
- .filter(node => node.getNodeTypeId() === NodeTypes.settingDefinitionNode)
- .forEach(node => {
- symbolTable[node.getWord(0)] = node.getContent()
- node.destroy()
- })
- // Find and replace
- let withVarsReplaced = clone.toString()
- Object.keys(symbolTable).forEach(key => {
- withVarsReplaced = withVarsReplaced.replaceAll(key, symbolTable[key])
- })
- return withVarsReplaced
+ const clone = program.clone()
+ // drop experiment nodes
+ clone.filter(node => node.parserId === ParserTypes.experimentParser).forEach(node => node.destroy())
+ // Append current experiment
+ if (experiment) clone.concat(experiment.childrenToString())
+ // Build symbol table
+ const symbolTable = {}
+ clone
+ .filter(node => node.parserId === ParserTypes.settingDefinitionParser)
+ .forEach(node => {
+ symbolTable[node.firstWord] = node.content
+ node.destroy()
+ })
+ // Find and replace
+ let withVarsReplaced = clone.toString()
+ Object.keys(symbolTable).forEach(key => {
+ withVarsReplaced = withVarsReplaced.replaceAll(key, symbolTable[key])
+ })
+ return withVarsReplaced
- let closest = Infinity
- let target
- targets.forEach(candidate => {
- const pos = candidate.position
- const distance = math.distance([pos.down, pos.right], [position.down, position.right])
- if (distance < closest) {
- closest = distance
- target = candidate
- }
- })
- const heading = target.position
- return yodash.angle(position.down, position.right, heading.down, heading.right)
+ let closest = Infinity
+ let target
+ targets.forEach(candidate => {
+ const pos = candidate.position
+ const distance = math.distance([pos.down, pos.right], [position.down, position.right])
+ if (distance < closest) {
+ closest = distance
+ target = candidate
+ }
+ })
+ const heading = target.position
+ return yodash.angle(position.down, position.right, heading.down, heading.right)
- const dy = ey - cy
- const dx = ex - cx
- let theta = Math.atan2(dy, dx) // range (-PI, PI]
- theta *= 180 / Math.PI // rads to degs, range (-180, 180]
- //if (theta < 0) theta = 360 + theta; // range [0, 360)
- let angle = ""
-
- if (Math.abs(theta) > 90) angle += Directions.North
- else angle += Directions.South
- if (theta < 0) angle += Directions.West
- else angle += Directions.East
- return angle
+ const dy = ey - cy
+ const dx = ex - cx
+ let theta = Math.atan2(dy, dx) // range (-PI, PI]
+ theta *= 180 / Math.PI // rads to degs, range (-180, 180]
+ //if (theta < 0) theta = 360 + theta; // range [0, 360)
+ let angle = ""
+
+ if (Math.abs(theta) > 90) angle += Directions.North
+ else angle += Directions.South
+ if (theta < 0) angle += Directions.West
+ else angle += Directions.East
+ return angle
- const maxRight = cols
- const maxBottom = rows
- const right = Math.round(randomNumberGenerator() * maxRight)
- const down = Math.round(randomNumberGenerator() * maxBottom)
- return { right, down }
+ const maxRight = cols
+ const maxBottom = rows
+ const right = Math.round(randomNumberGenerator() * maxRight)
+ const down = Math.round(randomNumberGenerator() * maxBottom)
+ return { right, down }
- const { right, down } = yodash.getRandomLocation(rows, cols, randomNumberGenerator)
- const hash = yodash.makePositionHash({ right, down })
- if (occupiedSpots && occupiedSpots.has(hash))
- return yodash.getRandomLocationHash(rows, cols, occupiedSpots, randomNumberGenerator)
- return hash
+ const { right, down } = yodash.getRandomLocation(rows, cols, randomNumberGenerator)
+ const hash = yodash.makePositionHash({ right, down })
+ if (occupiedSpots && occupiedSpots.has(hash))
+ return yodash.getRandomLocationHash(rows, cols, occupiedSpots, randomNumberGenerator)
+ return hash
- const board = []
- while (rows >= 0) {
- let col = cols
- while (col >= 0) {
- const hash = yodash.makePositionHash({ right: col, down: rows })
- col--
- if (occupiedSpots.has(hash)) continue
- board.push(`${emoji} ${hash}`)
- }
- rows--
- }
- return board.join("\n")
+ const board = []
+ while (rows >= 0) {
+ let col = cols
+ while (col >= 0) {
+ const hash = yodash.makePositionHash({ right: col, down: rows })
+ col--
+ if (occupiedSpots.has(hash)) continue
+ board.push(`${emoji} ${hash}`)
+ }
+ rows--
+ }
+ return board.join("\n")
- let { right, down } = position
- const positions = []
- down--
- positions.push({ down, right })
- right--
- positions.push({ down, right })
- right++
- right++
- positions.push({ down, right })
- down++
- positions.push({ down, right })
- right--
- right--
- positions.push({ down, right })
- down++
- positions.push({ down, right })
- right++
- positions.push({ down, right })
- right++
- positions.push({ down, right })
- return positions
+ let { right, down } = position
+ const positions = []
+ down--
+ positions.push({ down, right })
+ right--
+ positions.push({ down, right })
+ right++
+ right++
+ positions.push({ down, right })
+ down++
+ positions.push({ down, right })
+ right--
+ right--
+ positions.push({ down, right })
+ down++
+ positions.push({ down, right })
+ right++
+ positions.push({ down, right })
+ right++
+ positions.push({ down, right })
+ return positions
- if (width < 1 || height < 1) {
- return ""
- }
- const cells = []
- let row = 0
- while (row < height) {
- let col = 0
- while (col < width) {
- const isPerimeter = row === 0 || row === height - 1 || col === 0 || col === width - 1
- if (isPerimeter)
- cells.push(
- `${character} ${yodash.makePositionHash({
- down: startDown + row,
- right: startRight + col
- })}`
- )
- col++
- }
- row++
- }
- return cells.join("\n")
+ if (width < 1 || height < 1) {
+ return ""
+ }
+ const cells = []
+ let row = 0
+ while (row < height) {
+ let col = 0
+ while (col < width) {
+ const isPerimeter = row === 0 || row === height - 1 || col === 0 || col === width - 1
+ if (isPerimeter)
+ cells.push(
+ `${character} ${yodash.makePositionHash({
+ down: startDown + row,
+ right: startRight + col
+ })}`
+ )
+ col++
+ }
+ row++
+ }
+ return cells.join("\n")
- return {
- down: parseInt(words.find(word => word.includes("⬇️")).slice(0, -1)),
- right: parseInt(words.find(word => word.includes("➡️")).slice(0, -1))
- }
+ return {
+ down: parseInt(words.find(word => word.includes("⬇️")).slice(0, -1)),
+ right: parseInt(words.find(word => word.includes("➡️")).slice(0, -1))
+ }
- const lines = str.split("\n")
- const output = []
- for (let index = 0; index < lines.length; index++) {
- const words = lines[index].split(" ")
- for (let wordIndex = 0; wordIndex < words.length; wordIndex++) {
- const word = words[wordIndex]
- if (word !== "") output.push(`${word} ${yodash.makePositionHash({ down: index, right: wordIndex })}`)
- }
- }
- return output.join("\n")
+ const lines = str.split("\n")
+ const output = []
+ for (let index = 0; index < lines.length; index++) {
+ const words = lines[index].split(" ")
+ for (let wordIndex = 0; wordIndex < words.length; wordIndex++) {
+ const word = words[wordIndex]
+ if (word !== "") output.push(`${word} ${yodash.makePositionHash({ down: index, right: wordIndex })}`)
+ }
+ }
+ return output.join("\n")
- new TreeNode(board).forEach(line => {
- occupiedSpots.add(yodash.makePositionHash(yodash.parsePosition(line.getWords())))
- })
+ new TreeNode(board).forEach(line => {
+ occupiedSpots.add(yodash.makePositionHash(yodash.parsePosition(line.words)))
+ })
- const availablePositions = []
- let down = rows
- while (down >= rowStart) {
- let right = cols
- while (right >= colStart) {
- const hash = yodash.makePositionHash({ right, down })
- if (!occupiedSpots.has(hash)) availablePositions.push({ right, down, hash })
- right--
- }
- down--
- }
- return availablePositions
+ const availablePositions = []
+ let down = rows
+ while (down >= rowStart) {
+ let right = cols
+ while (right >= colStart) {
+ const hash = yodash.makePositionHash({ right, down })
+ if (!occupiedSpots.has(hash)) availablePositions.push({ right, down, hash })
+ right--
+ }
+ down--
+ }
+ return availablePositions
- randomNumberGenerator,
- amount,
- char,
- rows,
- cols,
- occupiedSpots,
- originRow,
- originColumn
+ randomNumberGenerator,
+ amount,
+ char,
+ rows,
+ cols,
+ occupiedSpots,
+ originRow,
+ originColumn
- const availableSpots = yodash.getAllAvailableSpots(rows, cols, occupiedSpots)
- const spots = yodash.sampleFrom(availableSpots, amount * 10, randomNumberGenerator)
- const origin = originColumn
- ? { down: parseInt(originRow), right: parseInt(originColumn) }
- : yodash.getRandomLocation(rows, cols, randomNumberGenerator)
- const sortedByDistance = lodash.sortBy(spots, spot =>
- math.distance([origin.down, origin.right], [spot.down, spot.right])
- )
-
- return sortedByDistance
- .slice(0, amount)
- .map(spot => {
- const { hash } = spot
- occupiedSpots.add(hash)
- return `${char} ${hash}`
- })
- .join("\n")
+ const availableSpots = yodash.getAllAvailableSpots(rows, cols, occupiedSpots)
+ const spots = yodash.sampleFrom(availableSpots, amount * 10, randomNumberGenerator)
+ const origin = originColumn
+ ? { down: parseInt(originRow), right: parseInt(originColumn) }
+ : yodash.getRandomLocation(rows, cols, randomNumberGenerator)
+ const sortedByDistance = lodash.sortBy(spots, spot =>
+ math.distance([origin.down, origin.right], [spot.down, spot.right])
+ )
+
+ return sortedByDistance
+ .slice(0, amount)
+ .map(spot => {
+ const { hash } = spot
+ occupiedSpots.add(hash)
+ return `${char} ${hash}`
+ })
+ .join("\n")
- const semiRand = Math.sin(seed++) * 10000
- return semiRand - Math.floor(semiRand)
+ const semiRand = Math.sin(seed++) * 10000
+ return semiRand - Math.floor(semiRand)
- shuffleArray(collection, randomNumberGenerator).slice(0, howMany)
+ shuffleArray(collection, randomNumberGenerator).slice(0, howMany)
- const clonedArr = array.slice()
- for (let index = clonedArr.length - 1; index > 0; index--) {
- const replacerIndex = Math.floor(randomNumberGenerator() * (index + 1))
- ;[clonedArr[index], clonedArr[replacerIndex]] = [clonedArr[replacerIndex], clonedArr[index]]
- }
- return clonedArr
+ const clonedArr = array.slice()
+ for (let index = clonedArr.length - 1; index > 0; index--) {
+ const replacerIndex = Math.floor(randomNumberGenerator() * (index + 1))
+ ;[clonedArr[index], clonedArr[replacerIndex]] = [clonedArr[replacerIndex], clonedArr[index]]
+ }
+ return clonedArr
- const newTree = tree.clone()
- const map = TreeUtils.arrayToMap(fields)
- newTree.forEach(node => {
- if (!map[node.getWord(0)]) node.destroy()
- })
+ const newTree = tree.clone()
+ const map = Utils.arrayToMap(fields)
+ newTree.forEach(node => {
+ if (!map[node.firstWord]) node.destroy()
+ })
- return newTree
+ return newTree
- const newTree = new jtree.TreeNode()
- tree.forEach(node => node.forEach(child => newTree.appendNode(child)))
- return newTree
+ const newTree = new TreeNode()
+ tree.forEach(node => node.forEach(child => newTree.appendNode(child)))
+ return newTree
Changed around line 292: window.yodash = yodash
- class AbstractContextMenuComponent extends AbstractTreeComponent {
+ class AbstractContextMenuComponent extends AbstractTreeComponentParser {
Changed around line 315: class AbstractContextMenuComponent extends AbstractTreeComponent {
- return new jtree.TreeNode(`div
+ return new TreeNode(`div
- const app = this.getRootNode()
+ const app = this.root
Changed around line 344: class AbstractContextMenuComponent extends AbstractTreeComponent {
- return this.getRootNode().getMouseEvent().clientX
+ return this.root.getMouseEvent().clientX
Changed around line 379: window.AbstractContextMenuComponent = AbstractContextMenuComponent
- class Agent extends jtree.TreeNode {
+ class Agent extends TreeNode {
Changed around line 391: class Agent extends jtree.TreeNode {
- if (!this.behaviors.length) return this.board.simojiProgram.getNode(this.getWord(0))
- const behaviors = yodash.flatten(yodash.pick(this.board.simojiProgram, [this.getWord(0), ...this.behaviors]))
+ if (!this.behaviors.length) return this.board.simojiProgram.getNode(this.firstWord)
+ const behaviors = yodash.flatten(yodash.pick(this.board.simojiProgram, [this.firstWord, ...this.behaviors]))
Changed around line 413: class Agent extends jtree.TreeNode {
- const [emoji, operator, count] = conditionAndCommandsBlock.getWords()
+ const [emoji, operator, count] = conditionAndCommandsBlock.words
Changed around line 431: class Agent extends jtree.TreeNode {
- const targetId = target.getWord(0)
+ const targetId = target.firstWord
Changed around line 447: class Agent extends jtree.TreeNode {
- const targetId = target.getWord(0)
+ const targetId = target.firstWord
Changed around line 459: class Agent extends jtree.TreeNode {
- const commandName = instruction.getWord(0)
+ const commandName = instruction.firstWord
Changed around line 507: class Agent extends jtree.TreeNode {
- this.getParent().appendLine(`${newObject} ${this.positionHash}`)
+ this.parent.appendLine(`${newObject} ${this.positionHash}`)
Changed around line 557: class Agent extends jtree.TreeNode {
- get root() {
- return this.getRootNode()
- }
-
Changed around line 567: class Agent extends jtree.TreeNode {
- return this.getParent()
+ return this.parent
Changed around line 593: class Agent extends jtree.TreeNode {
- return yodash.parsePosition(this.getWords())
+ return yodash.parsePosition(this.words)
Changed around line 601: class Agent extends jtree.TreeNode {
- return this.getParent().gridSize
+ return this.parent.gridSize
Changed around line 642: class Agent extends jtree.TreeNode {
- return `top:${this.top * gridSize}px;left:${this.left *
- gridSize}px;font-size:${gridSize}px;line-height: ${gridSize}px;${opacity};${this.style ?? ""}`
+ return `top:${this.top * gridSize}px;left:${
+ this.left * gridSize
+ }px;font-size:${gridSize}px;line-height: ${gridSize}px;${opacity};${this.style ?? ""}`
Changed around line 680: class Agent extends jtree.TreeNode {
- target.tickStack = new jtree.TreeNode(`1
+ target.tickStack = new TreeNode(`1
Changed around line 713: class Agent extends jtree.TreeNode {
- this.root.log(`${this.getWord(0)} ${command.getContent()}`)
+ this.root.log(`${this.firstWord} ${command.content}`)
Changed around line 800: window.Agent = Agent
- class AgentPaletteComponent extends AbstractTreeComponent {
+ class AgentPaletteComponent extends AbstractTreeComponentParser {
- const root = this.getRootNode()
+ const root = this.root
- .map(item => item.getWord(0))
+ .map(item => item.firstWord)
Changed around line 818: ${items}`
- return this.getRootNode().allAgentTypes.filter(item => !item.has("noPalette"))
+ return this.root.allAgentTypes.filter(item => !item.has("noPalette"))
- this.getRootNode().changeAgentBrushCommand(x)
+ this.root.changeAgentBrushCommand(x)
- return [this.getRootNode().board]
+ return [this.root.board]
Changed around line 845: let nodeJsPrefix = ""
- class BoardErrorNode extends AbstractTreeComponent {
- _isErrorNodeType() {
+ class BoardErrorParser extends AbstractTreeComponentParser {
+ _isErrorParser() {
Changed around line 856: class BoardErrorNode extends AbstractTreeComponent {
- class leftStartPosition extends jtree.TreeNode {
+ class leftStartPosition extends TreeNode {
- class BoardComponent extends AbstractTreeComponent {
+ class BoardComponent extends AbstractTreeComponentParser {
- this._parser = new jtree.TreeNode.Parser(BoardErrorNode, {
+ this._parser = new TreeNode.ParserCombinator(BoardErrorParser, {
Changed around line 907: class BoardComponent extends AbstractTreeComponent {
- const csv = new TreeNode(this._populationCounts).toCsv()
+ const csv = new TreeNode(this._populationCounts).asCsv
Changed around line 937: class BoardComponent extends AbstractTreeComponent {
- .filter(node => node.doesExtend(NodeTypes.abstractInjectCommandNode))
+ .filter(node => node.doesExtend(ParserTypes.abstractInjectCommandParser))
Changed around line 1003: class BoardComponent extends AbstractTreeComponent {
- this.getRootNode().resetAllCommand()
+ this.root.resetAllCommand()
Changed around line 1035: class BoardComponent extends AbstractTreeComponent {
- return this.getParent()
+ return this.parent
Changed around line 1046: class BoardComponent extends AbstractTreeComponent {
- this[command.getNodeTypeId()](command)
+ this[command.parserId](command)
- insertClusterNode(commandNode) {
+ insertClusterParser(commandNode) {
Changed around line 1064: class BoardComponent extends AbstractTreeComponent {
- insertAtNode(commandNode) {
+ insertAtParser(commandNode) {
- rectangleDrawNode(commandNode) {
- const newLines = yodash.makeRectangle(...yodash.parseInts(commandNode.getWords().slice(1), 1))
+ rectangleDrawParser(commandNode) {
+ const newLines = yodash.makeRectangle(...yodash.parseInts(commandNode.words.slice(1), 1))
- pasteDrawNode(commandNode) {
+ pasteDrawParser(commandNode) {
- fillNode(commandNode) {
+ fillParser(commandNode) {
- drawNode(commandNode) {
+ drawParser(commandNode) {
Changed around line 1103: class BoardComponent extends AbstractTreeComponent {
- insertNode(commandNode) {
+ insertParser(commandNode) {
Changed around line 1126: class BoardComponent extends AbstractTreeComponent {
- this[instruction.getWord(0)](instruction)
+ this[instruction.firstWord](instruction)
Changed around line 1136: class BoardComponent extends AbstractTreeComponent {
- this[instruction.getWord(0)](instruction)
+ this[instruction.firstWord](instruction)
Changed around line 1150: class BoardComponent extends AbstractTreeComponent {
- return this.getTopDownArray().filter(node => node instanceof Agent)
+ return this.topDownArray.filter(node => node instanceof Agent)
Changed around line 1242: class BoardComponent extends AbstractTreeComponent {
- return this.root.mainExperiment.findNodes(Keywords.experiment)[this.boardIndex].getContent() ?? ""
+ return this.root.mainExperiment.findNodes(Keywords.experiment)[this.boardIndex].content ?? ""
Changed around line 1289: class BoardComponent extends AbstractTreeComponent {
- const message = command.getContent()
+ const message = command.content
Changed around line 1307: class BoardComponent extends AbstractTreeComponent {
- this.root.log(command.getContent())
+ this.root.log(command.content)
- class BoardStyleComponent extends AbstractTreeComponent {
- createParser() {
- return new jtree.TreeNode.Parser(TreeNode)
+ class BoardStyleComponent extends AbstractTreeComponentParser {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(TreeNode)
Changed around line 1338: window.BoardComponent = BoardComponent
- class BottomBarComponent extends AbstractTreeComponent {
- createParser() {
- return new jtree.TreeNode.Parser(undefined, {
+ class BottomBarComponent extends AbstractTreeComponentParser {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(undefined, {
Changed around line 1353: window.BottomBarComponent = BottomBarComponent
- class EditorHandleComponent extends AbstractTreeComponent {
+ class EditorHandleComponent extends AbstractTreeComponentParser {
- return this.getRootNode().editor.width
+ return this.root.editor.width
- const root = this.getRootNode()
+ const root = this.root
Changed around line 1390: class EditorHandleComponent extends AbstractTreeComponent {
- return [this.getRootNode().editor]
+ return [this.root.editor]
Changed around line 1399: window.EditorHandleComponent = EditorHandleComponent
- const ExampleSims = new jtree.TreeNode()
+ const ExampleSims = new TreeNode()
Changed around line 1412: window.ExampleSims = ExampleSims
- const Categories = new jtree.TreeNode(`🦠 Epidemiology
+
+ const Categories = new TreeNode(`🦠 Epidemiology
Changed around line 1441: class ExampleMenuComponent extends AbstractContextMenuComponent {
- const name = node.getFirstWord()
+ const name = node.firstWord
- const properName = jtree.Utils.ucfirst(name)
+ const properName = Utils.ucfirst(name)
Changed around line 1455: class ExampleMenuComponent extends AbstractContextMenuComponent {
- const evt = this.getRootNode().getMouseEvent()
+ const evt = this.root.getMouseEvent()
- class ExamplesComponent extends AbstractTreeComponent {
+ class ExamplesComponent extends AbstractTreeComponentParser {
- const icon = category.getFirstWord()
- const name = category.getContent()
- const firstFile = category.nodeAt(0).getFirstWord()
+ const icon = category.firstWord
+ const name = category.content
+ const firstFile = category.nodeAt(0).firstWord
Changed around line 1477: ${categories}`
- const root = this.getRootNode()
+ const root = this.root
- const firstFile = category.nodeAt(0).getFirstWord()
- this.getRootNode().toggleAndRender(`${ExampleMenuComponent.name} ${icon}`)
+ const firstFile = category.nodeAt(0).firstWord
+ this.root.toggleAndRender(`${ExampleMenuComponent.name} ${icon}`)
Changed around line 1492: window.ExampleMenuComponent = ExampleMenuComponent
- class GridComponent extends AbstractTreeComponent {
+ class GridComponent extends AbstractTreeComponentParser {
- return this.getParent().insertAgentAtCommand(right, down)
+ return this.parent.insertAgentAtCommand(right, down)
Changed around line 1505: class GridComponent extends AbstractTreeComponent {
- const { cols, rows, gridSize } = this.getParent()
+ const { cols, rows, gridSize } = this.parent
Changed around line 1529: window.GridComponent = GridComponent
- class AbstractModalTreeComponent extends AbstractTreeComponent {
+ class AbstractModalTreeComponent extends AbstractTreeComponentParser {
Changed around line 1567: class AbstractModalTreeComponent extends AbstractTreeComponent {
- return new jtree.TreeNode(`section
+ return new TreeNode(`section
Changed around line 1594: window.HelpModalComponent = HelpModalComponent
- class PlayButtonComponent extends AbstractTreeComponent {
+ class PlayButtonComponent extends AbstractTreeComponentParser {
- return this.getRootNode().isRunning
+ return this.root.isRunning
Changed around line 1611: window.PlayButtonComponent = PlayButtonComponent
- class ReportButtonComponent extends AbstractTreeComponent {
+ class ReportButtonComponent extends AbstractTreeComponentParser {
Changed around line 1625: window.ReportButtonComponent = ReportButtonComponent
- class ResetButtonComponent extends AbstractTreeComponent {
+ class ResetButtonComponent extends AbstractTreeComponentParser {
Changed around line 1634: class ResetButtonComponent extends AbstractTreeComponent {
- this.getRootNode().pauseAllCommand()
- this.getRootNode().resetAllCommand()
+ this.root.pauseAllCommand()
+ this.root.resetAllCommand()
Changed around line 1646: window.ResetButtonComponent = ResetButtonComponent
- class RightBarComponent extends AbstractTreeComponent {
- createParser() {
- return new jtree.TreeNode.Parser(undefined, {
- AgentPaletteComponent
- })
- }
+ class RightBarComponent extends AbstractTreeComponentParser {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(undefined, {
+ AgentPaletteComponent
+ })
+ }
Changed around line 1659: window.RightBarComponent = RightBarComponent
- class ShareComponent extends AbstractTreeComponent {
+ class ShareComponent extends AbstractTreeComponentParser {
Changed around line 1670: class ShareComponent extends AbstractTreeComponent {
- return [this.getRootNode().firstProgram]
+ return [this.root.firstProgram]
- return url.toString() + this.getRootNode().urlHash
+ return url.toString() + this.root.urlHash
Changed around line 1698: class CodeMirrorShim {
- class SimEditorComponent extends AbstractTreeComponent {
+ class SimEditorComponent extends AbstractTreeComponentParser {
Changed around line 1710: class SimEditorComponent extends AbstractTreeComponent {
- createParser() {
- return new jtree.TreeNode.Parser(undefined, {
- value: jtree.TreeNode
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(undefined, {
+ value: TreeNode
Changed around line 1727: class SimEditorComponent extends AbstractTreeComponent {
- const root = this.getRootNode()
+ const root = this.root
- this.program = new simojiCompiler(code)
+ this.program = new simojiParser(code)
Changed around line 1754: class SimEditorComponent extends AbstractTreeComponent {
- this.codeMirrorInstance.addLineWidget(err.getLineNumber() - 1, el, { coverGutter: false, noHScroll: false })
+ this.codeMirrorInstance.addLineWidget(err.lineNumber - 1, el, { coverGutter: false, noHScroll: false })
Changed around line 1769: class SimEditorComponent extends AbstractTreeComponent {
- this.getRootNode().loadNewSim(this._code)
+ this.root.loadNewSim(this._code)
Changed around line 1800: class SimEditorComponent extends AbstractTreeComponent {
- this.codeMirrorInstance = new jtree.TreeNotationCodeMirrorMode(
- "custom",
- () => simojiCompiler,
- undefined,
- CodeMirror
- )
+ this.codeMirrorInstance = new GrammarCodeMirrorMode("custom", () => simojiParser, undefined, CodeMirror)
Changed around line 1862: const MIN_GRID_ROWS = 10
- class githubTriangleComponent extends AbstractTreeComponent {
- githubLink = `https://github.com/publicdomaincompany/simoji`
+ class githubTriangleComponent extends AbstractTreeComponentParser {
+ githubLink = `https://github.com/breck7/simoji`
Changed around line 1883: class githubTriangleComponent extends AbstractTreeComponent {
- class ErrorNode extends AbstractTreeComponent {
- _isErrorNodeType() {
+ class ErrorParser extends AbstractTreeComponentParser {
+ _isErrorParser() {
Changed around line 1894: class ErrorNode extends AbstractTreeComponent {
- class SimojiApp extends AbstractTreeComponent {
- createParser() {
- return new jtree.TreeNode.Parser(ErrorNode, {
+ class SimojiApp extends AbstractTreeComponentParser {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(ErrorParser, {
Changed around line 1953: class SimojiApp extends AbstractTreeComponent {
- .filter(node => node.doesExtend(NodeTypes.abstractInjectCommandNode))
+ .filter(node => node.doesExtend(ParserTypes.abstractInjectCommandParser))
Changed around line 2034: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- const errs = new simojiCompiler(this.simCode).getAllErrors()
- console.log(new jtree.TreeNode(errs.map(err => err.toObject())).toFormattedTable(200))
+ const errs = new simojiParser(this.simCode).getAllErrors()
+ console.log(new TreeNode(errs.map(err => err.toObject())).toFormattedTable(200))
Changed around line 2047: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- return new simojiCompiler(this.simCode)
+ return new simojiParser(this.simCode)
Changed around line 2060: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- this._simojiPrograms = this._simojiPrograms.map(program => new simojiCompiler(program.toString()))
+ this._simojiPrograms = this._simojiPrograms.map(program => new simojiParser(program.toString()))
Changed around line 2104: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- willowBrowser.getMousetrap().bind(key, function(evt) {
+ willowBrowser.getMousetrap().bind(key, function (evt) {
Changed around line 2141: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- const str = this.selection
- .map(agent =>
- agent
- .getWords()
- .slice(0, 3)
- .join(" ")
- )
- .join("\n")
+ const str = this.selection.map(agent => agent.words.slice(0, 3).join(" ")).join("\n")
Changed around line 2200: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- const tree = new jtree.TreeNode()
+ const tree = new TreeNode()
Changed around line 2279: ${styleNode ? styleNode.toString().replace("style", BoardStyleComponent.name) :
- return new jtree.TreeNode(this.simCode).has(Keywords.seed)
+ return new TreeNode(this.simCode).has(Keywords.seed)
- const newCode = new jtree.TreeNode(this.simCode)
+ const newCode = new TreeNode(this.simCode)
Changed around line 2370: SimojiApp.setupApp = (simojiCode, windowWidth = 1000, windowHeight = 1000) => {
- const startState = new jtree.TreeNode(`${githubTriangleComponent.name}
+ const startState = new TreeNode(`${githubTriangleComponent.name}
Changed around line 2400: window.SimojiApp = SimojiApp
- class TitleComponent extends AbstractTreeComponent {
+ class TitleComponent extends AbstractTreeComponentParser {
- return this.getRootNode()
+ return this.root
Changed around line 2430: window.TitleComponent = TitleComponent
- class TopBarComponent extends AbstractTreeComponent {
- createParser() {
- return new jtree.TreeNode.Parser(undefined, {
+ class TopBarComponent extends AbstractTreeComponentParser {
+ createParserCombinator() {
+ return new TreeNode.ParserCombinator(undefined, {
Changed around line 2440: class TopBarComponent extends AbstractTreeComponent {
- class LogoComponent extends AbstractTreeComponent {
+ class LogoComponent extends AbstractTreeComponentParser {
Changed around line 2449: class LogoComponent extends AbstractTreeComponent {
- this.getRootNode().toggleHelpCommand()
+ this.root.toggleHelpCommand()
Changed around line 2496: Directions.East = "East"
- const NodeTypes = {}
+ const ParserTypes = {}
- NodeTypes.agentDefinitionNode = "agentDefinitionNode"
- NodeTypes.experimentNode = "experimentNode"
- NodeTypes.settingDefinitionNode = "settingDefinitionNode"
- NodeTypes.abstractInjectCommandNode = "abstractInjectCommandNode"
+ ParserTypes.agentDefinitionParser = "agentDefinitionParser"
+ ParserTypes.experimentParser = "experimentParser"
+ ParserTypes.settingDefinitionParser = "settingDefinitionParser"
+ ParserTypes.abstractInjectCommandParser = "abstractInjectCommandParser"
Changed around line 2511: window.UrlKeys = UrlKeys
- window.NodeTypes = NodeTypes
+ window.ParserTypes = ParserTypes
Changed around line 2520: const DEFAULT_SIM = "fire"
- class BrowserGlue extends AbstractTreeComponent {
+
+ class BrowserGlue extends AbstractTreeComponentParser {
Changed around line 2539: class BrowserGlue extends AbstractTreeComponent {
- const deepLink = new jtree.TreeNode(decodeURIComponent(hash))
+ const deepLink = new TreeNode(decodeURIComponent(hash))
Changed around line 2567: class BrowserGlue extends AbstractTreeComponent {
- window.simojiCompiler = new jtree.HandGrammarProgram(grammarCode).compileAndReturnRootConstructor()
+ window.simojiParser = new HandGrammarProgram(grammarCode).compileAndReturnRootParser()
Changed around line 9
- "jtree": "^53.8.0",
+ "jtree": "^74.0.0",
Changed around line 21
- "node": ">=14.0.0"
+ "node": ">=16.0.0"
Changed around line 409
- "node_modules/@types/d3-format": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.2.tgz",
- "integrity": "sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ=="
- },
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "mime-types": "~2.1.24",
- "negotiator": "0.6.2"
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
Changed around line 510
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
Changed around line 597
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
- "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+ "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
- "bytes": "3.1.0",
+ "bytes": "3.1.2",
- "depd": "~1.1.2",
- "http-errors": "1.7.2",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
- "on-finished": "~2.3.0",
- "qs": "6.7.0",
- "raw-body": "2.4.0",
- "type-is": "~1.6.17"
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
- "node": ">= 0.8"
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ "dev": true,
Changed around line 667
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
- "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
Changed around line 696
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
Changed around line 858
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
- "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "safe-buffer": "5.1.2"
+ "safe-buffer": "5.2.1"
+ "node_modules/content-disposition/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
Changed around line 909
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
- "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
Changed around line 919
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
- "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA=="
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
Changed around line 965
- "node_modules/d3-format": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
- "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
- },
Changed around line 1020
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "node": ">= 0.6"
+ "node": ">= 0.8"
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/dezalgo": {
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
+ "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "dependencies": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
Changed around line 1067
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
Changed around line 1084
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
Changed around line 1107
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
Changed around line 1139
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
Changed around line 1151
- "version": "4.17.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
- "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
+ "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
- "accepts": "~1.3.7",
+ "accepts": "~1.3.8",
- "body-parser": "1.19.0",
- "content-disposition": "0.5.3",
+ "body-parser": "1.20.1",
+ "content-disposition": "0.5.4",
- "cookie": "0.4.0",
+ "cookie": "0.5.0",
- "depd": "~1.1.2",
+ "depd": "2.0.0",
- "finalhandler": "~1.1.2",
+ "finalhandler": "1.2.0",
+ "http-errors": "2.0.0",
- "on-finished": "~2.3.0",
+ "on-finished": "2.4.1",
- "proxy-addr": "~2.0.5",
- "qs": "6.7.0",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.11.0",
- "safe-buffer": "5.1.2",
- "send": "0.17.1",
- "serve-static": "1.14.1",
- "setprototypeof": "1.1.1",
- "statuses": "~1.5.0",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
Changed around line 1191
+ "node_modules/express/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
Changed around line 1238
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz",
- "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag=="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
Changed around line 1255
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
- "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "on-finished": "~2.3.0",
+ "on-finished": "2.4.1",
- "statuses": "~1.5.0",
+ "statuses": "2.0.1",
Changed around line 1327
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
- "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
Changed around line 1340
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
- "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
+ "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
+ "dependencies": {
+ "dezalgo": "^1.0.4",
+ "hexoid": "^1.0.0",
+ "once": "^1.4.0",
+ "qs": "^6.11.0"
+ },
+ "funding": {
+ "url": "https://ko-fi.com/tunnckoCore/commissions"
+ }
Changed around line 1372
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
Changed around line 1437
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
- "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
+ "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
- "has-symbols": "^1.0.1"
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
Changed around line 1471
+ "dev": true,
Changed around line 1554
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
- "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
Changed around line 1577
+ "node_modules/hexoid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
+ "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
Changed around line 1592
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
- "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.1",
- "statuses": ">= 1.5.0 < 2",
- "toidentifier": "1.0.0"
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
- "node": ">= 0.6"
+ "node": ">= 0.8"
Changed around line 1654
+ "dev": true,
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
Changed around line 2011
- "version": "53.8.0",
- "resolved": "https://registry.npmjs.org/jtree/-/jtree-53.8.0.tgz",
- "integrity": "sha512-HUtrF+0FMakMGbUktqGlwAkURkaRdSa9WBj1lek3T0INT+S2GdyPoZvtIdVZSBqYhqtTamXSMD7WsTt19x+xuA==",
- "dependencies": {
- "@types/d3-format": "^1.3.1",
- "d3-format": "^1.3.2",
- "express": "*",
- "glob": "^7.1.4",
- "mkdirp": "^0.5.6",
- "moment": "^2.29.3",
- "moment-parseformat": "^3.0.0",
- "prettier": "^1.18.2",
+ "version": "74.0.0",
+ "resolved": "https://registry.npmjs.org/jtree/-/jtree-74.0.0.tgz",
+ "integrity": "sha512-jKyvI60geVzmtfqahfG4kszQp2zg50N7JvtLTxaRamZpqi3J+a+3UduSEZvzBN8k7qSvcR7rA0TBbXSBinCOPw==",
+ "dependencies": {
+ "express": "^4.18.2",
+ "glob": "^9.3.4",
+ "mkdirp": "^2.1.6",
+ "prettier": "^2.8.7",
- "semver": "^6.1.1",
- "superagent": "^5.1.0"
+ "superagent": "^8.0.9"
- "bin": {
- "jtree": "products/commandLineApp.node.js"
+ "engines": {
+ "node": ">=16.0"
+ }
+ },
+ "node_modules/jtree/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/jtree/node_modules/glob": {
+ "version": "9.3.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.4.tgz",
+ "integrity": "sha512-qaSc49hojMOv1EPM4EuyITjDSgSKI0rthoHnvE81tcOi1SCVndHko7auqxdQ14eiQG2NDBJBE86+2xIrbIvrbA==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/jtree/node_modules/minimatch": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.3.tgz",
+ "integrity": "sha512-tEEvU9TkZgnFDCtpnrEYnPsjT7iUx42aXfs4bzmQ5sMA09/6hZY0jeZcGkXyDagiBOvkUjNo8Viom+Me6+2x7g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/jtree/node_modules/minipass": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+ "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
+ "engines": {
+ "node": ">=8"
Changed around line 2152
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
- "node": ">=10"
+ "node": ">=12"
Changed around line 2196
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
Changed around line 2204
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
Changed around line 2226
- "version": "1.48.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
- "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "version": "2.1.31",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
- "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "mime-db": "1.48.0"
+ "mime-db": "1.52.0"
Changed around line 2248
+ "dev": true,
Changed around line 2274
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "dependencies": {
- "minimist": "^1.2.6"
- },
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
+ "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==",
- "mkdirp": "bin/cmd.js"
- }
- },
- "node_modules/moment": {
- "version": "2.29.4",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
- "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
- "node": "*"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
- "node_modules/moment-parseformat": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/moment-parseformat/-/moment-parseformat-3.1.1.tgz",
- "integrity": "sha512-uEkXh5w9WDM8xNksZYeGpbZgrcG9qlpTg+f4ftHyOIis4+U08p31zOUzk3YCv2n+c6MUpW+Nb3GLCpjoEuHqJw=="
- },
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
- "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
Changed around line 2396
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
- "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
Changed around line 2527
+ "dev": true,
Changed around line 2541
+ "node_modules/path-scurry": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.3.tgz",
+ "integrity": "sha512-RAmB+n30SlN+HnNx6EbcpoDy9nwdpcGPnEKrJnu6GZoDWBdIjo1UQMVtW2ybtC7LC2oKLcMq8y5g8WnKLiod9g==",
+ "dependencies": {
+ "lru-cache": "^7.14.1",
+ "minipass": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+ "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
Changed around line 2597
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
- "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "version": "2.8.7",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
+ "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
- "node": ">=4"
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
Changed around line 2661
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
- "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
Changed around line 2683
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
- "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "bytes": "3.1.0",
- "http-errors": "1.7.2",
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
Changed around line 2716
- "node_modules/readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
Changed around line 2843
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
Changed around line 2860
+ "dev": true,
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
- "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
- "http-errors": "~1.7.2",
+ "http-errors": "2.0.0",
- "ms": "2.1.1",
- "on-finished": "~2.3.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
- "statuses": "~1.5.0"
+ "statuses": "2.0.1"
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
- "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
- "send": "0.17.1"
+ "send": "0.18.0"
Changed around line 2914
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
- "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
Changed around line 2947
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
Changed around line 3042
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "node": ">= 0.6"
- }
- },
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dependencies": {
- "safe-buffer": "~5.2.0"
+ "node": ">= 0.8"
- "node_modules/string_decoder/node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- },
Changed around line 3084
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz",
- "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==",
+ "version": "8.0.9",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz",
+ "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==",
- "cookiejar": "^2.1.2",
- "debug": "^4.1.1",
- "fast-safe-stringify": "^2.0.7",
- "form-data": "^3.0.0",
- "formidable": "^1.2.2",
+ "cookiejar": "^2.1.4",
+ "debug": "^4.3.4",
+ "fast-safe-stringify": "^2.1.1",
+ "form-data": "^4.0.0",
+ "formidable": "^2.1.2",
- "mime": "^2.4.6",
- "qs": "^6.9.4",
- "readable-stream": "^3.6.0",
- "semver": "^7.3.2"
+ "mime": "2.6.0",
+ "qs": "^6.11.0",
+ "semver": "^7.3.8"
- "node": ">= 7.0.0"
+ "node": ">=6.4.0 <13 || >=14"
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/superagent/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
- "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
Changed around line 3146
- "node_modules/superagent/node_modules/qs": {
- "version": "6.10.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
- "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
- "dependencies": {
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">=0.6"
- }
- },
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
- "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
Changed around line 5196
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
- "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
Changed around line 5312
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
Changed around line 5326
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
Changed around line 5346
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
Changed around line 5927
- "@types/d3-format": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.2.tgz",
- "integrity": "sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ=="
- },
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "mime-types": "~2.1.24",
- "negotiator": "0.6.2"
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
Changed around line 6010
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
Changed around line 6082
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
- "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+ "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
- "bytes": "3.1.0",
+ "bytes": "3.1.2",
- "depd": "~1.1.2",
- "http-errors": "1.7.2",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
- "on-finished": "~2.3.0",
- "qs": "6.7.0",
- "raw-body": "2.4.0",
- "type-is": "~1.6.17"
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ "dev": true,
Changed around line 6139
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
- "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
Changed around line 6294
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
- "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "safe-buffer": "5.1.2"
+ "safe-buffer": "5.2.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ }
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="
Changed around line 6327
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
- "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
- "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA=="
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
Changed around line 6371
- "d3-format": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
- "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
- },
Changed around line 6414
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
+ },
+ "dezalgo": {
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
+ "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "requires": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
Changed around line 6451
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
Changed around line 6468
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
Changed around line 6485
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
Changed around line 6507
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
Changed around line 6516
- "version": "4.17.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
- "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
+ "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
- "accepts": "~1.3.7",
+ "accepts": "~1.3.8",
- "body-parser": "1.19.0",
- "content-disposition": "0.5.3",
+ "body-parser": "1.20.1",
+ "content-disposition": "0.5.4",
- "cookie": "0.4.0",
+ "cookie": "0.5.0",
- "depd": "~1.1.2",
+ "depd": "2.0.0",
- "finalhandler": "~1.1.2",
+ "finalhandler": "1.2.0",
+ "http-errors": "2.0.0",
- "on-finished": "~2.3.0",
+ "on-finished": "2.4.1",
- "proxy-addr": "~2.0.5",
- "qs": "6.7.0",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.11.0",
- "safe-buffer": "5.1.2",
- "send": "0.17.1",
- "serve-static": "1.14.1",
- "setprototypeof": "1.1.1",
- "statuses": "~1.5.0",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ }
Changed around line 6585
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz",
- "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag=="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
Changed around line 6599
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
- "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "on-finished": "~2.3.0",
+ "on-finished": "2.4.1",
- "statuses": "~1.5.0",
+ "statuses": "2.0.1",
Changed around line 6656
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
- "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
Changed around line 6666
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
- "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
+ "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
+ "requires": {
+ "dezalgo": "^1.0.4",
+ "hexoid": "^1.0.0",
+ "once": "^1.4.0",
+ "qs": "^6.11.0"
+ }
Changed around line 6689
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
Changed around line 6739
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
- "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
+ "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
- "has-symbols": "^1.0.1"
+ "has-symbols": "^1.0.3"
Changed around line 6767
+ "dev": true,
Changed around line 6829
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
- "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
Changed around line 6843
+ "hexoid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
+ "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g=="
+ },
Changed around line 6855
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
- "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.1",
- "statuses": ">= 1.5.0 < 2",
- "toidentifier": "1.0.0"
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
Changed around line 6901
+ "dev": true,
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
Changed around line 7184
- "version": "53.8.0",
- "resolved": "https://registry.npmjs.org/jtree/-/jtree-53.8.0.tgz",
- "integrity": "sha512-HUtrF+0FMakMGbUktqGlwAkURkaRdSa9WBj1lek3T0INT+S2GdyPoZvtIdVZSBqYhqtTamXSMD7WsTt19x+xuA==",
- "requires": {
- "@types/d3-format": "^1.3.1",
- "d3-format": "^1.3.2",
- "express": "*",
- "glob": "^7.1.4",
- "mkdirp": "^0.5.6",
- "moment": "^2.29.3",
- "moment-parseformat": "^3.0.0",
- "prettier": "^1.18.2",
+ "version": "74.0.0",
+ "resolved": "https://registry.npmjs.org/jtree/-/jtree-74.0.0.tgz",
+ "integrity": "sha512-jKyvI60geVzmtfqahfG4kszQp2zg50N7JvtLTxaRamZpqi3J+a+3UduSEZvzBN8k7qSvcR7rA0TBbXSBinCOPw==",
+ "requires": {
+ "express": "^4.18.2",
+ "glob": "^9.3.4",
+ "mkdirp": "^2.1.6",
+ "prettier": "^2.8.7",
- "semver": "^6.1.1",
- "superagent": "^5.1.0"
+ "superagent": "^8.0.9"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "9.3.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.4.tgz",
+ "integrity": "sha512-qaSc49hojMOv1EPM4EuyITjDSgSKI0rthoHnvE81tcOi1SCVndHko7auqxdQ14eiQG2NDBJBE86+2xIrbIvrbA==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ }
+ },
+ "minimatch": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.3.tgz",
+ "integrity": "sha512-tEEvU9TkZgnFDCtpnrEYnPsjT7iUx42aXfs4bzmQ5sMA09/6hZY0jeZcGkXyDagiBOvkUjNo8Viom+Me6+2x7g==",
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ },
+ "minipass": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+ "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q=="
+ }
Changed around line 7294
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="
Changed around line 7326
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
Changed around line 7344
- "version": "1.48.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
- "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
- "version": "2.1.31",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
- "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "mime-db": "1.48.0"
+ "mime-db": "1.52.0"
+ "dev": true,
Changed around line 7380
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "requires": {
- "minimist": "^1.2.6"
- }
- },
- "moment": {
- "version": "2.29.4",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
- "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
- },
- "moment-parseformat": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/moment-parseformat/-/moment-parseformat-3.1.1.tgz",
- "integrity": "sha512-uEkXh5w9WDM8xNksZYeGpbZgrcG9qlpTg+f4ftHyOIis4+U08p31zOUzk3YCv2n+c6MUpW+Nb3GLCpjoEuHqJw=="
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
+ "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A=="
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
- "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
Changed around line 7469
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
- "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
Changed around line 7569
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
Changed around line 7578
+ "path-scurry": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.3.tgz",
+ "integrity": "sha512-RAmB+n30SlN+HnNx6EbcpoDy9nwdpcGPnEKrJnu6GZoDWBdIjo1UQMVtW2ybtC7LC2oKLcMq8y5g8WnKLiod9g==",
+ "requires": {
+ "lru-cache": "^7.14.1",
+ "minipass": "^4.0.2"
+ },
+ "dependencies": {
+ "minipass": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+ "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q=="
+ }
+ }
+ },
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
Changed around line 7621
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
- "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew=="
+ "version": "2.8.7",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
+ "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw=="
Changed around line 7667
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
- "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
Changed around line 7680
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
- "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "bytes": "3.1.0",
- "http-errors": "1.7.2",
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
Changed around line 7707
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
Changed around line 7812
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
Changed around line 7828
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
- "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
- "http-errors": "~1.7.2",
+ "http-errors": "2.0.0",
- "ms": "2.1.1",
- "on-finished": "~2.3.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
- "statuses": "~1.5.0"
+ "statuses": "2.0.1"
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
- "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
- "send": "0.17.1"
+ "send": "0.18.0"
Changed around line 7876
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
- "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
Changed around line 7982
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
- },
- "string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "requires": {
- "safe-buffer": "~5.2.0"
- },
- "dependencies": {
- "safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- }
- }
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
Changed around line 8012
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz",
- "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==",
+ "version": "8.0.9",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz",
+ "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==",
- "cookiejar": "^2.1.2",
- "debug": "^4.1.1",
- "fast-safe-stringify": "^2.0.7",
- "form-data": "^3.0.0",
- "formidable": "^1.2.2",
+ "cookiejar": "^2.1.4",
+ "debug": "^4.3.4",
+ "fast-safe-stringify": "^2.1.1",
+ "form-data": "^4.0.0",
+ "formidable": "^2.1.2",
- "mime": "^2.4.6",
- "qs": "^6.9.4",
- "readable-stream": "^3.6.0",
- "semver": "^7.3.2"
+ "mime": "2.6.0",
+ "qs": "^6.11.0",
+ "semver": "^7.3.8"
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
- "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg=="
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="
- "qs": {
- "version": "6.10.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
- "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
- "requires": {
- "side-channel": "^1.0.4"
- }
- },
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
- "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
Changed around line 9493
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
- "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
Changed around line 9587
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
Changed around line 9598
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
Changed around line 9612
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
Changed around line 23
- "jtree": "^53.8.0",
+ "jtree": "^74.0.0",
Changed around line 32
+ "build": "./build.js",
+ "local": "./server.js",
Changed around line 54: startColumns 2
- 1. Start the dev server with `node server.js`.
+ 1. Start the dev server with `npm run local`.
Changed around line 4: const express = require("express")
- const { jtree } = require("jtree")
+ const { TreeNode } = require("jtree/products/TreeNode.js")
Changed around line 46: propertyNameCell
- errorNode
- baseNodeType errorNode
- simojiNode
+ errorParser
+ baseParser errorParser
+ simojiParser
- inScope abstractIgnoreNode abstractSetupNode abstractInjectCommandNode onTickNode onExtinctNode behaviorDefinitionNode experimentNode settingDefinitionNode
- catchAllNodeType agentDefinitionNode
+ inScope abstractIgnoreParser abstractSetupParser abstractInjectCommandParser onTickParser onExtinctParser behaviorDefinitionParser experimentParser settingDefinitionParser
+ catchAllParser agentDefinitionParser
Changed around line 69: simojiNode
- return this.filter(node => node.getNodeTypeId() === "agentDefinitionNode")
+ return this.filter(node => node.parserId === "agentDefinitionParser")
- experimentNode
- crux experiment
+ experimentParser
+ cruxFromId
- inScope abstractIgnoreNode abstractSetupNode abstractInjectCommandNode onTickNode onExtinctNode settingDefinitionNode
+ inScope abstractIgnoreParser abstractSetupParser abstractInjectCommandParser onTickParser onExtinctParser settingDefinitionParser
- abstractSetupNode
- atTimeNode
- crux atTime
+ abstractSetupParser
+ atTimeParser
+ cruxFromId
- extends abstractSetupNode
- inScope abstractInjectCommandNode
- abstractSetupNumberNode
+ extends abstractSetupParser
+ inScope abstractInjectCommandParser
+ abstractSetupNumberParser
- extends abstractSetupNode
+ extends abstractSetupParser
- sizeNode
+ sizeParser
- extends abstractSetupNumberNode
- crux size
- rowsNode
+ extends abstractSetupNumberParser
+ cruxFromId
+ rowsParser
- extends abstractSetupNumberNode
- crux rows
- columnsNode
+ extends abstractSetupNumberParser
+ cruxFromId
+ columnsParser
- extends abstractSetupNumberNode
- crux columns
- seedNode
+ extends abstractSetupNumberParser
+ cruxFromId
+ seedParser
- extends abstractSetupNumberNode
- crux seed
- ticksPerSecondNode
+ extends abstractSetupNumberParser
+ cruxFromId
+ ticksPerSecondParser
- extends abstractSetupNumberNode
- crux ticksPerSecond
- reportNode
- crux report
+ extends abstractSetupNumberParser
+ cruxFromId
+ reportParser
+ cruxFromId
- catchAllNodeType ohayoLineNode
- extends abstractSetupNode
+ catchAllParser ohayoLineParser
+ extends abstractSetupParser
- styleNode
+ styleParser
- extends abstractSetupNode
+ extends abstractSetupParser
- crux style
- catchAllNodeType styleLineNode
+ cruxFromId
+ catchAllParser styleLineParser
- questionNode
- crux question
+ questionParser
+ cruxFromId
- extends abstractSetupNode
- abstractInjectCommandNode
- fillNode
+ extends abstractSetupParser
+ abstractInjectCommandParser
+ fillParser
- extends abstractInjectCommandNode
+ extends abstractInjectCommandParser
- crux fill
- drawNode
- extends abstractInjectCommandNode
+ cruxFromId
+ drawParser
+ extends abstractInjectCommandParser
- crux draw
- catchAllNodeType drawLineNode
- insertNode
- extends abstractInjectCommandNode
+ cruxFromId
+ catchAllParser drawLineParser
+ insertParser
+ extends abstractInjectCommandParser
- crux insert
- insertAtNode
- extends insertNode
+ cruxFromId
+ insertAtParser
+ extends insertParser
- crux insertAt
- insertClusterNode
- extends insertNode
- crux insertCluster
+ cruxFromId
+ insertClusterParser
+ extends insertParser
+ cruxFromId
- rectangleDrawNode
- extends abstractInjectCommandNode
+ rectangleDrawParser
+ extends abstractInjectCommandParser
- pasteDrawNode
- extends abstractInjectCommandNode
+ pasteDrawParser
+ extends abstractInjectCommandParser
- catchAllNodeType pasteLineNode
- drawLineNode
+ catchAllParser pasteLineParser
+ drawLineParser
- pasteLineNode
+ pasteLineParser
- catchAllNodeType pasteLineNode
- agentDefinitionNode
- inScope abstractIgnoreNode abstractEventNode abstractAgentAttributeNode abstractBehaviorAttributeNode
+ catchAllParser pasteLineParser
+ agentDefinitionParser
+ inScope abstractIgnoreParser abstractEventParser abstractAgentAttributeParser behaviorAttributeParser
- catchAllNodeType errorNode
+ catchAllParser errorParser
- const root = this.getRootNode()
- const name = root.agentKeywordMap[this.getWord(0)]
+ const root = this.root
+ const name = root.agentKeywordMap[this.firstWord]
- const behaviors = this.filter(node => node.getNodeTypeId() === "abstractBehaviorAttributeNode")
+ const behaviors = this.filter(node => node.parserId === "behaviorAttributeParser")
- icon = "${this.getWord(0)}"
+ icon = "${this.firstWord}"
- abstractCommandNode
+ abstractCommandParser
- abstractSubjectObjectCommandNode
- extends abstractCommandNode
- replaceWithCommandNode
- extends abstractSubjectObjectCommandNode
+ abstractSubjectObjectCommandParser
+ extends abstractCommandParser
+ replaceWithCommandParser
+ extends abstractSubjectObjectCommandParser
- kickItCommandNode
- extends abstractSubjectObjectCommandNode
+ kickItCommandParser
+ extends abstractSubjectObjectCommandParser
- shootCommandNode
- extends abstractSubjectObjectCommandNode
+ shootCommandParser
+ extends abstractSubjectObjectCommandParser
- pickItUpCommandNode
- extends abstractSubjectObjectCommandNode
+ pickItUpCommandParser
+ extends abstractSubjectObjectCommandParser
- spawnCommandNode
+ spawnCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- moveToEmptySpotCommandNode
+ moveToEmptySpotCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- removeCommandNode
+ removeCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- javascriptCommandNode
+ javascriptCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- catchAllNodeType javascriptLineNode
+ catchAllParser javascriptLineParser
- alertCommandNode
- extends abstractCommandNode
+ alertCommandParser
+ extends abstractCommandParser
- logCommandNode
- extends abstractCommandNode
+ logCommandParser
+ extends abstractCommandParser
- narrateCommandNode
- extends abstractCommandNode
+ narrateCommandParser
+ extends abstractCommandParser
- pauseCommandNode
- extends abstractCommandNode
+ pauseCommandParser
+ extends abstractCommandParser
- decreaseCommandNode
- extends abstractCommandNode
+ decreaseCommandParser
+ extends abstractCommandParser
- increaseCommandNode
- extends abstractCommandNode
+ increaseCommandParser
+ extends abstractCommandParser
- moveCommandNode
- extends abstractCommandNode
+ moveCommandParser
+ extends abstractCommandParser
- turnRandomlyCommandNode
- extends abstractCommandNode
+ turnRandomlyCommandParser
+ extends abstractCommandParser
- jitterCommandNode
- extends abstractCommandNode
+ jitterCommandParser
+ extends abstractCommandParser
- turnTowardCommandNode
+ turnTowardCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- turnFromCommandNode
+ turnFromCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- learnCommandNode
+ learnCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- unlearnCommandNode
+ unlearnCommandParser
- extends abstractCommandNode
+ extends abstractCommandParser
- abstractAgentAttributeNode
+ abstractAgentAttributeParser
- abstractStringAttributeNode
- extends abstractAgentAttributeNode
+ stringAttributeParser
+ extends abstractAgentAttributeParser
- return `${this.getWord(0)} = "${this.getWord(1)}"`
+ return `${this.firstWord} = "${this.getWord(1)}"`
- angleNode
- extends abstractStringAttributeNode
+ angleParser
+ extends stringAttributeParser
- crux angle
- agentStyleNode
+ cruxFromId
+ agentStyleParser
- extends abstractStringAttributeNode
+ extends stringAttributeParser
- agentHtmlNode
+ agentHtmlParser
- extends abstractStringAttributeNode
+ extends stringAttributeParser
- abstractBooleanAttributeNode
+ abstractBooleanAttributeParser
- extends abstractAgentAttributeNode
+ extends abstractAgentAttributeParser
- return `${this.getWord(0)} = true`
+ return `${this.firstWord} = true`
- noPaletteNode
- extends abstractBooleanAttributeNode
+ noPaletteParser
+ extends abstractBooleanAttributeParser
- solidTraitNode
+ solidTraitParser
- extends abstractBooleanAttributeNode
+ extends abstractBooleanAttributeParser
- bouncyTraitNode
+ bouncyTraitParser
- extends abstractBooleanAttributeNode
+ extends abstractBooleanAttributeParser
- abstractIntegerAttributeNode
- extends abstractAgentAttributeNode
+ abstractIntegerAttributeParser
+ extends abstractAgentAttributeParser
- return `${this.getWord(0)} = ${this.getWord(1)}`
+ return `${this.firstWord} = ${this.getWord(1)}`
- customIntegerAttributeNode
+ customIntegerAttributeParser
- extends abstractIntegerAttributeNode
- healthNode
- extends abstractIntegerAttributeNode
- crux health
- settingDefinitionNode
+ extends abstractIntegerAttributeParser
+ healthParser
+ extends abstractIntegerAttributeParser
+ cruxFromId
+ settingDefinitionParser
- ohayoLineNode
+ ohayoLineParser
- styleLineNode
+ styleLineParser
- catchAllNodeType styleLineNode
- targetEmojiNode
- inScope abstractCommandNode
+ catchAllParser styleLineParser
+ targetEmojiParser
+ inScope abstractCommandParser
- abstractEventNode
+ abstractEventParser
- abstractInteractionEventNode
- extends abstractEventNode
- catchAllNodeType targetEmojiNode
- onHitNode
- extends abstractInteractionEventNode
- crux onHit
+ abstractInteractionEventParser
+ extends abstractEventParser
+ catchAllParser targetEmojiParser
+ onHitParser
+ extends abstractInteractionEventParser
+ cruxFromId
- onTouchNode
- extends abstractInteractionEventNode
- crux onTouch
+ onTouchParser
+ extends abstractInteractionEventParser
+ cruxFromId
- onNeighborsNode
+ onNeighborsParser
- extends abstractInteractionEventNode
- inScope emojiAndNeighborConditionNode
- crux onNeighbors
- onDeathNode
- extends abstractEventNode
- crux onDeath
- inScope abstractCommandNode
+ extends abstractInteractionEventParser
+ inScope emojiAndNeighborConditionParser
+ cruxFromId
+ onDeathParser
+ extends abstractEventParser
+ cruxFromId
+ inScope abstractCommandParser
- onTickNode
- extends abstractEventNode
- crux onTick
- inScope abstractCommandNode
+ onTickParser
+ extends abstractEventParser
+ cruxFromId
+ inScope abstractCommandParser
- emojiAndNeighborConditionNode
- inScope abstractCommandNode
+ emojiAndNeighborConditionParser
+ inScope abstractCommandParser
- onExtinctNode
- crux onExtinct
- inScope abstractCommandNode
+ onExtinctParser
+ cruxFromId
+ inScope abstractCommandParser
- abstractIgnoreNode
+ abstractIgnoreParser
- commentNode
- extends abstractIgnoreNode
+ commentParser
+ extends abstractIgnoreParser
- crux comment
- catchAllNodeType commentLineNode
- commentAliasNode
+ cruxFromId
+ catchAllParser commentLineParser
+ commentAliasParser
- extends commentNode
- blankLineNode
- extends abstractIgnoreNode
+ extends commentParser
+ blankLineParser
+ extends abstractIgnoreParser
- commentLineNode
+ commentLineParser
- javascriptLineNode
+ javascriptLineParser
- abstractBehaviorAttributeNode
+ behaviorAttributeParser
- behaviorDefinitionNode
- inScope abstractIgnoreNode abstractEventNode
+ behaviorDefinitionParser
+ inScope abstractIgnoreParser abstractEventParser
- catchAllNodeType errorNode
+ catchAllParser errorParser
Changed around line 1
- const { Directions, NodeTypes } = require("./components/Types.js")
+ const { Utils } = require("jtree/products/Utils.js")
+ const { Directions, ParserTypes } = require("./components/Types.js")
Changed around line 34: yodash.compare = (left, operator, right) => {
- clone.filter(node => node.getNodeTypeId() !== NodeTypes.agentDefinitionNode).forEach(node => node.destroy())
+ clone.filter(node => node.parserId !== ParserTypes.agentDefinitionParser).forEach(node => node.destroy())
- clone.agentTypes.forEach((node, index) => (clone.agentKeywordMap[node.getWord(0)] = `simAgent${index}`))
+ clone.agentTypes.forEach((node, index) => (clone.agentKeywordMap[node.firstWord] = `simAgent${index}`))
Changed around line 49: yodash.compileAgentClassDeclarationsAndMap = program => {
- clone.filter(node => node.getNodeTypeId() === NodeTypes.experimentNode).forEach(node => node.destroy())
+ clone.filter(node => node.parserId === ParserTypes.experimentParser).forEach(node => node.destroy())
- .filter(node => node.getNodeTypeId() === NodeTypes.settingDefinitionNode)
+ .filter(node => node.parserId === ParserTypes.settingDefinitionParser)
- symbolTable[node.getWord(0)] = node.getContent()
+ symbolTable[node.firstWord] = node.content
Changed around line 201: yodash.draw = str => {
- occupiedSpots.add(yodash.makePositionHash(yodash.parsePosition(line.getWords())))
+ occupiedSpots.add(yodash.makePositionHash(yodash.parsePosition(line.words)))
Changed around line 270: const shuffleArray = (array, randomNumberGenerator) => {
- const map = TreeUtils.arrayToMap(fields)
+ const map = Utils.arrayToMap(fields)
- if (!map[node.getWord(0)]) node.destroy()
+ if (!map[node.firstWord]) node.destroy()
- const newTree = new jtree.TreeNode()
+ const newTree = new TreeNode()
Link update
Changed around line 5: title Simoji Quickstart Guide
- https://github.com/publicdomaincompany/simoji open source
+ https://github.com/breck7/simoji open source
Changed around line 120: pipeTable
- https://github.com/publicdomaincompany/simoji Github
+ https://github.com/breck7/simoji Github
Changed around line 32: const MIN_GRID_ROWS = 10
- githubLink = `https://github.com/publicdomaincompany/simoji`
+ githubLink = `https://github.com/breck7/simoji`
Changed around line 17
+ "engineStrict": true,
Changed around line 38
- "url": "git+https://github.com/publicdomaincompany/simoji.git"
+ "url": "git+https://github.com/breck7/simoji.git"
- "url": "https://github.com/publicdomaincompany/simoji/issues"
+ "url": "https://github.com/breck7/simoji/issues"
- "homepage": "https://github.com/publicdomaincompany/simoji#readme"
+ "homepage": "https://github.com/breck7/simoji#readme"
Prettier
Changed around line 27: ourPaths.unshift(__dirname + "/yodash.js")
- .map(path => {
- const code = Disk.read(path)
+ .map(path => {
+ const code = Disk.read(path)
- return new TypeScriptRewriter(code)
- .removeRequires()
- .removeNodeJsOnlyLines()
- .changeNodeExportsToWindowExports()
- .getString()
- })
- .join("\n\n")
+ return new TypeScriptRewriter(code)
+ .removeRequires()
+ .removeNodeJsOnlyLines()
+ .changeNodeExportsToWindowExports()
+ .getString()
+ })
+ .join("\n\n")
- grammar: Disk.read(__dirname + "/simoji.grammar"),
- examples: getExamples()
+ grammar: Disk.read(__dirname + "/simoji.grammar"),
+ examples: getExamples()
Changed around line 9: const VERSION = packageJson.version
- execute(args = []) {
- this.log(`\n🧫🧫🧫 WELCOME TO SIMOJI (v${VERSION}) 🧫🧫🧫`)
- const command = args[0]
- const filename = args[1]
- const commandName = `${command}${CommandFnDecoratorSuffix}`
- const cwd = process.cwd()
- if (this[commandName]) return this[commandName](cwd, filename)
-
- if (Disk.exists(cwd + "/" + command)) return this.runCommand(cwd, command)
-
- if (!command) this.log(`\nNo command provided. Running help command.`)
- else this.log(`\nUnknown command or file '${commandName}' provided. Running help command.`)
- return this.helpCommand()
- }
-
- get _allCommands() {
- return Object.getOwnPropertyNames(Object.getPrototypeOf(this))
- .filter(word => word.endsWith(CommandFnDecoratorSuffix))
- .sort()
- }
-
- async runCommand(cwd, filename) {
- const fullPath = cwd + "/" + filename
- if (!Disk.exists(fullPath)) return this.log(`❌ file '${fullPath}' not found.`)
- this.log(`\n⏳ Running '${fullPath}'...\n`)
- const code = Disk.read(filename)
- const app = SimojiApp.setupApp(code)
- app.verbose = false
- await app.runUntilPause()
- }
-
- helpCommand() {
- return this.log(
- `\nThis is the Simoji help page.\n\nCommands you can run:\n\n${this._allCommands
- .map(comm => `➡️ ` + comm.replace(CommandFnDecoratorSuffix, ""))
- .join("\n")}\n`
- )
- }
-
- verbose = true
- log(message) {
- if (this.verbose) console.log(message)
- return message
- }
+ execute(args = []) {
+ this.log(`\n🧫🧫🧫 WELCOME TO SIMOJI (v${VERSION}) 🧫🧫🧫`)
+ const command = args[0]
+ const filename = args[1]
+ const commandName = `${command}${CommandFnDecoratorSuffix}`
+ const cwd = process.cwd()
+ if (this[commandName]) return this[commandName](cwd, filename)
+
+ if (Disk.exists(cwd + "/" + command)) return this.runCommand(cwd, command)
+
+ if (!command) this.log(`\nNo command provided. Running help command.`)
+ else this.log(`\nUnknown command or file '${commandName}' provided. Running help command.`)
+ return this.helpCommand()
+ }
+
+ get _allCommands() {
+ return Object.getOwnPropertyNames(Object.getPrototypeOf(this))
+ .filter(word => word.endsWith(CommandFnDecoratorSuffix))
+ .sort()
+ }
+
+ async runCommand(cwd, filename) {
+ const fullPath = cwd + "/" + filename
+ if (!Disk.exists(fullPath)) return this.log(`❌ file '${fullPath}' not found.`)
+ this.log(`\n⏳ Running '${fullPath}'...\n`)
+ const code = Disk.read(filename)
+ const app = SimojiApp.setupApp(code)
+ app.verbose = false
+ await app.runUntilPause()
+ }
+
+ helpCommand() {
+ return this.log(
+ `\nThis is the Simoji help page.\n\nCommands you can run:\n\n${this._allCommands
+ .map(comm => `➡️ ` + comm.replace(CommandFnDecoratorSuffix, ""))
+ .join("\n")}\n`
+ )
+ }
+
+ verbose = true
+ log(message) {
+ if (this.verbose) console.log(message)
+ return message
+ }
Changed around line 3: const { jtree } = require("jtree")
- createParser() {
- return new jtree.TreeNode.Parser(undefined, {
- AgentPaletteComponent
- })
- }
+ createParser() {
+ return new jtree.TreeNode.Parser(undefined, {
+ AgentPaletteComponent
+ })
+ }
components/SimojiApp.test.node.js
Changed around line 11: const simojiCompiler = jtree.compileGrammarFileAtPathAndReturnRootConstructor(gr
- const errs = new grammarNode(Disk.read(grammarPath)).getAllErrors().map(err => err.toObject())
- if (errs.length) console.log(new jtree.TreeNode(errs).toFormattedTable(60))
- areEqual(errs.length, 0, "no grammar errors")
+ const errs = new grammarNode(Disk.read(grammarPath)).getAllErrors().map(err => err.toObject())
+ if (errs.length) console.log(new jtree.TreeNode(errs).toFormattedTable(60))
+ areEqual(errs.length, 0, "no grammar errors")
- const errs = Disk.getFiles(examplesPath)
- .map(path => {
- const code = Disk.read(path)
- const program = new simojiCompiler(code)
- const errors = program.getAllErrors()
- areEqual(errors.length, 0)
- return errors.map(err => {
- return { filename: path, ...err.toObject() }
- })
- })
- .flat()
- if (errs.length) console.log(new jtree.TreeNode(errs).toFormattedTable(60))
+ const errs = Disk.getFiles(examplesPath)
+ .map(path => {
+ const code = Disk.read(path)
+ const program = new simojiCompiler(code)
+ const errors = program.getAllErrors()
+ areEqual(errors.length, 0)
+ return errors.map(err => {
+ return { filename: path, ...err.toObject() }
+ })
+ })
+ .flat()
+ if (errs.length) console.log(new jtree.TreeNode(errs).toFormattedTable(60))
- const app = SimojiApp.setupApp("")
- areEqual(!!app, true)
+ const app = SimojiApp.setupApp("")
+ areEqual(!!app, true)
- // Arrange
- const app = SimojiApp.setupApp("")
- app.verbose = false
- await app.start()
+ // Arrange
+ const app = SimojiApp.setupApp("")
+ app.verbose = false
+ await app.start()
- // Act
- app.pasteCodeCommand(`😃
+ // Act
+ app.pasteCodeCommand(`😃
- const boardState1 = app.board.toString()
+ const boardState1 = app.board.toString()
- areEqual(app.board.populationCount["😃"], 200)
+ areEqual(app.board.populationCount["😃"], 200)
- // Act
- app.resetAllCommand()
+ // Act
+ app.resetAllCommand()
- const boardState2 = app.board.toString()
+ const boardState2 = app.board.toString()
- // Race condition is possible but pigs more likely to fly first.
- areEqual(boardState1 === boardState2, false, "Boards should have changed")
- areEqual(app.simojiPrograms[0].getAllErrors().length, 0, "program is valid")
+ // Race condition is possible but pigs more likely to fly first.
+ areEqual(boardState1 === boardState2, false, "Boards should have changed")
+ areEqual(app.simojiPrograms[0].getAllErrors().length, 0, "program is valid")
- // Act
- app.pasteCodeCommand(`😃
+ // Act
+ app.pasteCodeCommand(`😃
- areEqual(app.simojiPrograms[0].getAllErrors().length, 2, "invalid programs dont crash")
+ areEqual(app.simojiPrograms[0].getAllErrors().length, 2, "invalid programs dont crash")
- const tap = require("tap")
- Object.keys(testTree).forEach(key => {
- testTree[key](tap.equal)
- })
+ const tap = require("tap")
+ Object.keys(testTree).forEach(key => {
+ testTree[key](tap.equal)
+ })
Changed around line 2: const stamp = require("jtree/products/stamp.nodejs.js")
- Disk.getFiles(__dirname + "/examples/")
- .map(path => {
- const name = Disk.getFileName(path.replace(".simoji", ""))
- return name + `\n ` + Disk.read(path).replace(/\n/g, "\n ")
- })
- .filter(i => i)
- .join("\n")
- .trim()
+ Disk.getFiles(__dirname + "/examples/")
+ .map(path => {
+ const name = Disk.getFileName(path.replace(".simoji", ""))
+ return name + `\n ` + Disk.read(path).replace(/\n/g, "\n ")
+ })
+ .filter(i => i)
+ .join("\n")
+ .trim()
Changed around line 7
+ "useTabs": false,
+ "tabWidth": 2,
+ "semi": false,
- "semi": false
+ "trailingComma": "none",
+ "arrowParens": "avoid"
- "node": ">=14.0.0"
+ "node": ">=16.0.0"
Changed around line 54: startColumns 2
-
Changed around line 8: const { jtree } = require("jtree")
- start(port = 80) {
- const app = express()
+ start(port = 80) {
+ const app = express()
- app.get("/*.js", (req, res) => {
- const filename = req.path.substr(1)
- readFile(__dirname + "/" + filename, "utf8", (err, code) => {
- if (err) throw err
- res.send(
- new TypeScriptRewriter(code)
- .removeRequires()
- .removeNodeJsOnlyLines()
- .changeNodeExportsToWindowExports()
- .getString()
- )
- })
- })
+ app.get("/*.js", (req, res) => {
+ const filename = req.path.substr(1)
+ readFile(__dirname + "/" + filename, "utf8", (err, code) => {
+ if (err) throw err
+ res.send(
+ new TypeScriptRewriter(code)
+ .removeRequires()
+ .removeNodeJsOnlyLines()
+ .changeNodeExportsToWindowExports()
+ .getString()
+ )
+ })
+ })
- app.get("/examples", (req, res) => {
- res.send(getExamples())
- })
+ app.get("/examples", (req, res) => {
+ res.send(getExamples())
+ })
- app.use(express.static(__dirname + "/"))
+ app.use(express.static(__dirname + "/"))
- app.listen(port, () => {
- console.log(`Running Simoji Dev Server. cmd+dblclick: http://localhost:${port}/dev.html`)
- })
- }
+ app.listen(port, () => {
+ console.log(`Running Simoji Dev Server. cmd+dblclick: http://localhost:${port}/dev.html`)
+ })
+ }
Changed around line 1
- const tap = require("tap")
- Object.keys(testTree).forEach(key => {
- testTree[key](tap.equal)
- })
+ const tap = require("tap")
+ Object.keys(testTree).forEach(key => {
+ testTree[key](tap.equal)
+ })
Changed around line 6: const { Directions, NodeTypes } = require("./components/Types.js")
- const r1 = randomNumberGenerator()
- const r2 = randomNumberGenerator()
- if (r1 > 0.5) return r2 > 0.5 ? Directions.North : Directions.South
- return r2 > 0.5 ? Directions.West : Directions.East
+ const r1 = randomNumberGenerator()
+ const r2 = randomNumberGenerator()
+ if (r1 > 0.5) return r2 > 0.5 ? Directions.North : Directions.South
+ return r2 > 0.5 ? Directions.West : Directions.East
- let newAngle = ""
- if (angle.includes(Directions.North)) newAngle += Directions.South
- else if (angle.includes(Directions.South)) newAngle += Directions.North
- if (angle.includes(Directions.East)) newAngle += Directions.West
- else if (angle.includes(Directions.West)) newAngle += Directions.East
- return newAngle
+ let newAngle = ""
+ if (angle.includes(Directions.North)) newAngle += Directions.South
+ else if (angle.includes(Directions.South)) newAngle += Directions.North
+ if (angle.includes(Directions.East)) newAngle += Directions.West
+ else if (angle.includes(Directions.West)) newAngle += Directions.East
+ return newAngle
- if (operator === "=") return left == right
- if (operator === "<") return left < right
- if (operator === ">") return left > right
- if (operator === "<=") return left <= right
- if (operator === ">=") return left >= right
+ if (operator === "=") return left == right
+ if (operator === "<") return left < right
+ if (operator === ">") return left > right
+ if (operator === "<=") return left <= right
+ if (operator === ">=") return left >= right
- return false
+ return false
- const clone = program.clone()
- clone.filter(node => node.getNodeTypeId() !== NodeTypes.agentDefinitionNode).forEach(node => node.destroy())
- clone.agentKeywordMap = {}
- clone.agentTypes.forEach((node, index) => (clone.agentKeywordMap[node.getWord(0)] = `simAgent${index}`))
- const compiled = clone.compile()
- const agentMap = Object.keys(clone.agentKeywordMap)
- .map(key => `"${key}":${clone.agentKeywordMap[key]}`)
- .join(",")
- return `${compiled}
+ const clone = program.clone()
+ clone.filter(node => node.getNodeTypeId() !== NodeTypes.agentDefinitionNode).forEach(node => node.destroy())
+ clone.agentKeywordMap = {}
+ clone.agentTypes.forEach((node, index) => (clone.agentKeywordMap[node.getWord(0)] = `simAgent${index}`))
+ const compiled = clone.compile()
+ const agentMap = Object.keys(clone.agentKeywordMap)
+ .map(key => `"${key}":${clone.agentKeywordMap[key]}`)
+ .join(",")
+ return `${compiled}
- const clone = program.clone()
- // drop experiment nodes
- clone.filter(node => node.getNodeTypeId() === NodeTypes.experimentNode).forEach(node => node.destroy())
- // Append current experiment
- if (experiment) clone.concat(experiment.childrenToString())
- // Build symbol table
- const symbolTable = {}
- clone
- .filter(node => node.getNodeTypeId() === NodeTypes.settingDefinitionNode)
- .forEach(node => {
- symbolTable[node.getWord(0)] = node.getContent()
- node.destroy()
- })
- // Find and replace
- let withVarsReplaced = clone.toString()
- Object.keys(symbolTable).forEach(key => {
- withVarsReplaced = withVarsReplaced.replaceAll(key, symbolTable[key])
- })
- return withVarsReplaced
+ const clone = program.clone()
+ // drop experiment nodes
+ clone.filter(node => node.getNodeTypeId() === NodeTypes.experimentNode).forEach(node => node.destroy())
+ // Append current experiment
+ if (experiment) clone.concat(experiment.childrenToString())
+ // Build symbol table
+ const symbolTable = {}
+ clone
+ .filter(node => node.getNodeTypeId() === NodeTypes.settingDefinitionNode)
+ .forEach(node => {
+ symbolTable[node.getWord(0)] = node.getContent()
+ node.destroy()
+ })
+ // Find and replace
+ let withVarsReplaced = clone.toString()
+ Object.keys(symbolTable).forEach(key => {
+ withVarsReplaced = withVarsReplaced.replaceAll(key, symbolTable[key])
+ })
+ return withVarsReplaced
- let closest = Infinity
- let target
- targets.forEach(candidate => {
- const pos = candidate.position
- const distance = math.distance([pos.down, pos.right], [position.down, position.right])
- if (distance < closest) {
- closest = distance
- target = candidate
- }
- })
- const heading = target.position
- return yodash.angle(position.down, position.right, heading.down, heading.right)
+ let closest = Infinity
+ let target
+ targets.forEach(candidate => {
+ const pos = candidate.position
+ const distance = math.distance([pos.down, pos.right], [position.down, position.right])
+ if (distance < closest) {
+ closest = distance
+ target = candidate
+ }
+ })
+ const heading = target.position
+ return yodash.angle(position.down, position.right, heading.down, heading.right)
- const dy = ey - cy
- const dx = ex - cx
- let theta = Math.atan2(dy, dx) // range (-PI, PI]
- theta *= 180 / Math.PI // rads to degs, range (-180, 180]
- //if (theta < 0) theta = 360 + theta; // range [0, 360)
- let angle = ""
+ const dy = ey - cy
+ const dx = ex - cx
+ let theta = Math.atan2(dy, dx) // range (-PI, PI]
+ theta *= 180 / Math.PI // rads to degs, range (-180, 180]
+ //if (theta < 0) theta = 360 + theta; // range [0, 360)
+ let angle = ""
- if (Math.abs(theta) > 90) angle += Directions.North
- else angle += Directions.South
- if (theta < 0) angle += Directions.West
- else angle += Directions.East
- return angle
+ if (Math.abs(theta) > 90) angle += Directions.North
+ else angle += Directions.South
+ if (theta < 0) angle += Directions.West
+ else angle += Directions.East
+ return angle
- const maxRight = cols
- const maxBottom = rows
- const right = Math.round(randomNumberGenerator() * maxRight)
- const down = Math.round(randomNumberGenerator() * maxBottom)
- return { right, down }
+ const maxRight = cols
+ const maxBottom = rows
+ const right = Math.round(randomNumberGenerator() * maxRight)
+ const down = Math.round(randomNumberGenerator() * maxBottom)
+ return { right, down }
- const { right, down } = yodash.getRandomLocation(rows, cols, randomNumberGenerator)
- const hash = yodash.makePositionHash({ right, down })
- if (occupiedSpots && occupiedSpots.has(hash))
- return yodash.getRandomLocationHash(rows, cols, occupiedSpots, randomNumberGenerator)
- return hash
+ const { right, down } = yodash.getRandomLocation(rows, cols, randomNumberGenerator)
+ const hash = yodash.makePositionHash({ right, down })
+ if (occupiedSpots && occupiedSpots.has(hash))
+ return yodash.getRandomLocationHash(rows, cols, occupiedSpots, randomNumberGenerator)
+ return hash
- const board = []
- while (rows >= 0) {
- let col = cols
- while (col >= 0) {
- const hash = yodash.makePositionHash({ right: col, down: rows })
- col--
- if (occupiedSpots.has(hash)) continue
- board.push(`${emoji} ${hash}`)
- }
- rows--
- }
- return board.join("\n")
+ const board = []
+ while (rows >= 0) {
+ let col = cols
+ while (col >= 0) {
+ const hash = yodash.makePositionHash({ right: col, down: rows })
+ col--
+ if (occupiedSpots.has(hash)) continue
+ board.push(`${emoji} ${hash}`)
+ }
+ rows--
+ }
+ return board.join("\n")
- let { right, down } = position
- const positions = []
- down--
- positions.push({ down, right })
- right--
- positions.push({ down, right })
- right++
- right++
- positions.push({ down, right })
- down++
- positions.push({ down, right })
- right--
- right--
- positions.push({ down, right })
- down++
- positions.push({ down, right })
- right++
- positions.push({ down, right })
- right++
- positions.push({ down, right })
- return positions
+ let { right, down } = position
+ const positions = []
+ down--
+ positions.push({ down, right })
+ right--
+ positions.push({ down, right })
+ right++
+ right++
+ positions.push({ down, right })
+ down++
+ positions.push({ down, right })
+ right--
+ right--
+ positions.push({ down, right })
+ down++
+ positions.push({ down, right })
+ right++
+ positions.push({ down, right })
+ right++
+ positions.push({ down, right })
+ return positions
- if (width < 1 || height < 1) {
- return ""
- }
- const cells = []
- let row = 0
- while (row < height) {
- let col = 0
- while (col < width) {
- const isPerimeter = row === 0 || row === height - 1 || col === 0 || col === width - 1
- if (isPerimeter)
- cells.push(
- `${character} ${yodash.makePositionHash({
- down: startDown + row,
- right: startRight + col
- })}`
- )
- col++
- }
- row++
- }
- return cells.join("\n")
+ if (width < 1 || height < 1) {
+ return ""
+ }
+ const cells = []
+ let row = 0
+ while (row < height) {
+ let col = 0
+ while (col < width) {
+ const isPerimeter = row === 0 || row === height - 1 || col === 0 || col === width - 1
+ if (isPerimeter)
+ cells.push(
+ `${character} ${yodash.makePositionHash({
+ down: startDown + row,
+ right: startRight + col
+ })}`
+ )
+ col++
+ }
+ row++
+ }
+ return cells.join("\n")
- return {
- down: parseInt(words.find(word => word.includes("⬇️")).slice(0, -1)),
- right: parseInt(words.find(word => word.includes("➡️")).slice(0, -1))
- }
+ return {
+ down: parseInt(words.find(word => word.includes("⬇️")).slice(0, -1)),
+ right: parseInt(words.find(word => word.includes("➡️")).slice(0, -1))
+ }
- const lines = str.split("\n")
- const output = []
- for (let index = 0; index < lines.length; index++) {
- const words = lines[index].split(" ")
- for (let wordIndex = 0; wordIndex < words.length; wordIndex++) {
- const word = words[wordIndex]
- if (word !== "") output.push(`${word} ${yodash.makePositionHash({ down: index, right: wordIndex })}`)
- }
- }
- return output.join("\n")
+ const lines = str.split("\n")
+ const output = []
+ for (let index = 0; index < lines.length; index++) {
+ const words = lines[index].split(" ")
+ for (let wordIndex = 0; wordIndex < words.length; wordIndex++) {
+ const word = words[wordIndex]
+ if (word !== "") output.push(`${word} ${yodash.makePositionHash({ down: index, right: wordIndex })}`)
+ }
+ }
+ return output.join("\n")
- new TreeNode(board).forEach(line => {
- occupiedSpots.add(yodash.makePositionHash(yodash.parsePosition(line.getWords())))
- })
+ new TreeNode(board).forEach(line => {
+ occupiedSpots.add(yodash.makePositionHash(yodash.parsePosition(line.getWords())))
+ })
- const availablePositions = []
- let down = rows
- while (down >= rowStart) {
- let right = cols
- while (right >= colStart) {
- const hash = yodash.makePositionHash({ right, down })
- if (!occupiedSpots.has(hash)) availablePositions.push({ right, down, hash })
- right--
- }
- down--
- }
- return availablePositions
+ const availablePositions = []
+ let down = rows
+ while (down >= rowStart) {
+ let right = cols
+ while (right >= colStart) {
+ const hash = yodash.makePositionHash({ right, down })
+ if (!occupiedSpots.has(hash)) availablePositions.push({ right, down, hash })
+ right--
+ }
+ down--
+ }
+ return availablePositions
- randomNumberGenerator,
- amount,
- char,
- rows,
- cols,
- occupiedSpots,
- originRow,
- originColumn
+ randomNumberGenerator,
+ amount,
+ char,
+ rows,
+ cols,
+ occupiedSpots,
+ originRow,
+ originColumn
- const availableSpots = yodash.getAllAvailableSpots(rows, cols, occupiedSpots)
- const spots = yodash.sampleFrom(availableSpots, amount * 10, randomNumberGenerator)
- const origin = originColumn
- ? { down: parseInt(originRow), right: parseInt(originColumn) }
- : yodash.getRandomLocation(rows, cols, randomNumberGenerator)
- const sortedByDistance = lodash.sortBy(spots, spot =>
- math.distance([origin.down, origin.right], [spot.down, spot.right])
- )
+ const availableSpots = yodash.getAllAvailableSpots(rows, cols, occupiedSpots)
+ const spots = yodash.sampleFrom(availableSpots, amount * 10, randomNumberGenerator)
+ const origin = originColumn
+ ? { down: parseInt(originRow), right: parseInt(originColumn) }
+ : yodash.getRandomLocation(rows, cols, randomNumberGenerator)
+ const sortedByDistance = lodash.sortBy(spots, spot =>
+ math.distance([origin.down, origin.right], [spot.down, spot.right])
+ )
- return sortedByDistance
- .slice(0, amount)
- .map(spot => {
- const { hash } = spot
- occupiedSpots.add(hash)
- return `${char} ${hash}`
- })
- .join("\n")
+ return sortedByDistance
+ .slice(0, amount)
+ .map(spot => {
+ const { hash } = spot
+ occupiedSpots.add(hash)
+ return `${char} ${hash}`
+ })
+ .join("\n")
- const semiRand = Math.sin(seed++) * 10000
- return semiRand - Math.floor(semiRand)
+ const semiRand = Math.sin(seed++) * 10000
+ return semiRand - Math.floor(semiRand)
- shuffleArray(collection, randomNumberGenerator).slice(0, howMany)
+ shuffleArray(collection, randomNumberGenerator).slice(0, howMany)
- const clonedArr = array.slice()
- for (let index = clonedArr.length - 1; index > 0; index--) {
- const replacerIndex = Math.floor(randomNumberGenerator() * (index + 1))
- ;[clonedArr[index], clonedArr[replacerIndex]] = [clonedArr[replacerIndex], clonedArr[index]]
- }
- return clonedArr
+ const clonedArr = array.slice()
+ for (let index = clonedArr.length - 1; index > 0; index--) {
+ const replacerIndex = Math.floor(randomNumberGenerator() * (index + 1))
+ ;[clonedArr[index], clonedArr[replacerIndex]] = [clonedArr[replacerIndex], clonedArr[index]]
+ }
+ return clonedArr
- const newTree = tree.clone()
- const map = TreeUtils.arrayToMap(fields)
- newTree.forEach(node => {
- if (!map[node.getWord(0)]) node.destroy()
- })
+ const newTree = tree.clone()
+ const map = TreeUtils.arrayToMap(fields)
+ newTree.forEach(node => {
+ if (!map[node.getWord(0)]) node.destroy()
+ })
- return newTree
+ return newTree
- const newTree = new jtree.TreeNode()
- tree.forEach(node => node.forEach(child => newTree.appendNode(child)))
- return newTree
+ const newTree = new jtree.TreeNode()
+ tree.forEach(node => node.forEach(child => newTree.appendNode(child)))
+ return newTree
Changed around line 5: const { yodash } = require("./yodash.js")
- areEqual(yodash.getRandomAngle(Math.random).match(/(East|West|North|South)/).length, 2)
+ areEqual(yodash.getRandomAngle(Math.random).match(/(East|West|North|South)/).length, 2)
- const expected = `😀 0⬇️ 0➡️
+ const expected = `😀 0⬇️ 0➡️
- areEqual(yodash.makeRectangle("😀", 2, 2), expected)
- areEqual(
- yodash.makeRectangle("🚪", 2, 1, 1, 1),
- `🚪 1⬇️ 1➡️
+ areEqual(yodash.makeRectangle("😀", 2, 2), expected)
+ areEqual(
+ yodash.makeRectangle("🚪", 2, 1, 1, 1),
+ `🚪 1⬇️ 1➡️
- )
+ )
- const tap = require("tap")
- Object.keys(testTree).forEach(key => {
- testTree[key](tap.equal)
- })
+ const tap = require("tap")
+ Object.keys(testTree).forEach(key => {
+ testTree[key](tap.equal)
+ })
Update docs
Changed around line 2
-
+
-
+
-
+
Changed around line 303: h4.scrollQuestion {
+
+
Changed around line 443: experiment
+
+
+
Changed around line 1
- metaTags
- gazetteCss
+ import header.scroll
+ startColumns 3
+
Changed around line 124: pipeTable
+
+ import footer.scroll
Changed around line 1
+ keyboardNav
Changed around line 1
- gazetteHeader
+ gazetteHeader
+ description Design quick simulations with Emojis
+ git https://github.com/breck7/simoji
+ baseUrl https://simoji.pub/
+ email breck7+simoji@gmail.com
Changed around line 0
- title Simoji
- description Design quick simulations with Emojis
- github https://github.com/publicdomaincompany/simoji
- git https://github.com/publicdomaincompany/simoji/blob/main
- twitter https://twitter.com/publicdomainpub
- email simoji@publicdomaincompany.com
- baseUrl https://simoji.pub/
- ignoreGrammarFiles