diff --git a/demos/stefan/active-expressions/aexpr-diss-check-ast-nodes/README.md b/demos/stefan/active-expressions/aexpr-diss-check-ast-nodes/README.md new file mode 100644 index 000000000..735781d60 --- /dev/null +++ b/demos/stefan/active-expressions/aexpr-diss-check-ast-nodes/README.md @@ -0,0 +1,57 @@ +# Number of AST Nodes + + + \ No newline at end of file diff --git a/demos/stefan/active-expressions/aexpr-diss-check-ast-nodes/results.md b/demos/stefan/active-expressions/aexpr-diss-check-ast-nodes/results.md new file mode 100644 index 000000000..f6313f8b5 --- /dev/null +++ b/demos/stefan/active-expressions/aexpr-diss-check-ast-nodes/results.md @@ -0,0 +1,69 @@ +# Convention +- ast nodes 136 = 18 + 118 +- sloc (29) = (1) + (28) + +[aexpr-ticking](https://github.com/active-expressions/aexpr-ticking.git) +e9b4034 +e9b4034606dd286ac494f20293cf7e7e9649e0ac + +- https://lively-kernel.org/lively4/aexpr/../aexpr-ticking/src/./aexpr-ticking.js 18 (1) +- https://lively-kernel.org/lively4/aexpr/../aexpr-ticking/src/./ticking/ticking-active-expressions.js 118 (28) + +# Interpretation +- ast nodes 787 = 12+182+224+369 +- sloc (170) = (1)+(43)+(51)+(75) + +[aexpr-interpretation](https://github.com/active-expressions/aexpr-interpretation.git) +46d1d17 +46d1d175b4cb040bda636fe871ef5d2f70f5e3e8 + +- https://lively-kernel.org/lively4/aexpr/../aexpr-interpretation/src/./aexpr-interpretation.js 12 (1) +- https://lively-kernel.org/lively4/aexpr/../aexpr-interpretation/src/./interpretation/property-accessor.js 182 (43) +- https://lively-kernel.org/lively4/aexpr/../aexpr-interpretation/src/./interpretation/listener.js 224 (51) +- https://lively-kernel.org/lively4/aexpr/../aexpr-interpretation/src/./interpretation/interpretation-active-expressions.js 369 (75) + +# Compilation +- ast nodes 2281 = 730+1551 +- sloc (471) = (169)+(302) + +[aexpr-source-transformation-propagation](https://github.com/active-expressions/aexpr-source-transformation-propagation.git) +3154d05 +3154d05af0ce410b041eb312ba57f7d32a6e7672 + +- https://lively-kernel.org/lively4/aexpr/../aexpr-source-transformation-propagation/src/./aexpr-source-transformation-propagation.js 730 (169) + +[babel-plugin-aexpr-source-transformation](https://github.com/active-expressions/babel-plugin-aexpr-source-transformation.git) +54a712a +54a712a45175f98c0f0a627770ae811759b195da + +- https://lively-kernel.org/lively4/aexpr/../babel-plugin-aexpr-source-transformation/./index.js 1551 (302) + +--- + +--- + +2820 + null + +all ref + 5794 = 1707 + 1267 + 2820 + +all aexpr + 3038 = 274 + 672 + 2092 + +interpret aexpr + 926 = 787 + 139 + +sum aexprs + 3964 = 3038 + 926 + +1707 - 274 +1267 - 672 +2820 - 2092 + +subsec:impl_comparison + subsec:impl_complexity + subsec:impl_qualitative_analysis + subsec:impl_quantitative_analysis + + +3018 = 2092 + 787 + 139 diff --git a/demos/stefan/handwritten-text-recognition/eng_bw.png b/demos/stefan/handwritten-text-recognition/eng_bw.png new file mode 100644 index 000000000..2e1ddbe38 Binary files /dev/null and b/demos/stefan/handwritten-text-recognition/eng_bw.png differ diff --git a/demos/stefan/handwritten-text-recognition/htr-test.png b/demos/stefan/handwritten-text-recognition/htr-test.png new file mode 100644 index 000000000..10f79c325 Binary files /dev/null and b/demos/stefan/handwritten-text-recognition/htr-test.png differ diff --git a/demos/stefan/jspdf-complex-use-case.js b/demos/stefan/jspdf-complex-use-case.js index e2d8db974..3c4767783 100644 --- a/demos/stefan/jspdf-complex-use-case.js +++ b/demos/stefan/jspdf-complex-use-case.js @@ -615,7 +615,7 @@ const tapSVG = do { const C_FRONTCARD_FILL = "black"; const C_FRONTCARD_STROKE = "black"; - const svg = ( @@ -627,7 +627,7 @@ svg }; { - const hedronTemp = document.getElementById('tap-icon-ubg') + const hedronTemp = document.getElementById('tap-icon-ubg1') if (hedronTemp) { hedronTemp.remove() } diff --git a/demos/stefan/untitled-board-game/ubg-cards-exporter.js b/demos/stefan/untitled-board-game/ubg-cards-exporter.js index c1f2e6edd..3bc8db038 100644 --- a/demos/stefan/untitled-board-game/ubg-cards-exporter.js +++ b/demos/stefan/untitled-board-game/ubg-cards-exporter.js @@ -16,7 +16,7 @@ export default class CardExporter { const title = document.title try { - await Promise.race([fn(), lively.sleep(10000)]) + await Promise.race([fn(), lively.sleep(5 * 60 * 1000)]) document.querySelectorAll('lively-notification-list').forEach(list => list.remove()) const mutationIndicator = document.querySelector('#mutationIndicator') diff --git a/doc/journal/2024-07-18.md/index.md b/doc/journal/2024-07-18.md/index.md new file mode 100644 index 000000000..7b57af08c --- /dev/null +++ b/doc/journal/2024-07-18.md/index.md @@ -0,0 +1,99 @@ +## 2024-07-18 Handwritten Text Recognition using AI +*Author: @onsetsu* + + + +### Using OpenAI + + + +![alt text](http://tesseract.projectnaptha.com/img/eng_bw.png "Handwritten Text"){width=400} + + + +![alt text](./../../../demos/stefan/handwritten-text-recognition/htr-test.png "Handwritten Text"){width=400} + + + +### Using the OCR lib tesseract.js + +- Good for OCR, not for HTR +- Has fine-grained feedback on where Words, lines, etc. are + +```javascript +import { createWorker } from 'https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js' + +const worker = await createWorker('eng'); +const ret = await worker.recognize(lively4url + '/demos/stefan/htr-test.png'); +await worker.terminate(); +ret.data.text +``` + + + +Good for OCR-friendly text: + + + +Bad for handwritten notes: + + + diff --git a/doc/journal/2024-07-18.md/index.md.l4a b/doc/journal/2024-07-18.md/index.md.l4a new file mode 100644 index 000000000..b8c4cb5e0 --- /dev/null +++ b/doc/journal/2024-07-18.md/index.md.l4a @@ -0,0 +1,3 @@ +{"type":"Reference","version":"156251caf7bed39b90b263003775f7d9efb574f3","content":"## 2024-07-18 Handwritten Text Recognition using AI\n*Author: @onsetsu*\n\n\n\n### Using OpenAI\n\n\n\n![alt text](http://tesseract.projectnaptha.com/img/eng_bw.png \"Handwritten Text\"){width=400}\n\n\n\n![alt text](./../../../demos/stefan/handwritten-text-recognition/htr-test.png \"Handwritten Text\"){width=400}\n\n\n\n### Using the OCR lib tesseract.js\n\n- Good for OCR, not for HTR\n- Has fine-grained feedback on where Words, lines, etc. are\n\n```javascript\nimport { createWorker } from 'https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js'\n\nconst worker = await createWorker('eng');\nconst ret = await worker.recognize(lively4url + '/demos/stefan/htr-test.png');\nawait worker.terminate();\nret.data.text\n```\n\n\n\nGood for OCR-friendly text:\n\n\n\nBad for handwritten notes:\n\n\n\n"} +{"from":1552,"to":1552,"name":"color","color":"#9ecae1"} +{"from":1138,"to":1138,"name":"color","color":"#9ecae1"} \ No newline at end of file diff --git a/src/client/reactive/babel-plugin-sample-data-bindings/sample-data-bindings.js b/src/client/reactive/babel-plugin-sample-data-bindings/sample-data-bindings.js index 31ef596f9..ad5b10619 100644 --- a/src/client/reactive/babel-plugin-sample-data-bindings/sample-data-bindings.js +++ b/src/client/reactive/babel-plugin-sample-data-bindings/sample-data-bindings.js @@ -1,56 +1,23 @@ -console.log(123) export default function ({ template, types: t }) { return { name: 'sample data bindings (<~)', visitor: { Program(program) { // handle squiggly arrow operator - function leftRightOfSquigglyArrow(path) { - if (!path.isBinaryExpression()) { return [] } - if (path.node.operator !== '<') { return [] } - - let right - const expression = path.get('right') - if (expression.isUnaryExpression() && expression.node.operator === '~') { - right = expression.get('argument') - } else { - expression.traverse({ - UnaryExpression(unary) { - if (unary.node.operator !== '~') { return } - if (expression.node.loc.start.index !== unary.node.loc.start.index) { return } - unary.stop() - unary.replaceWith(unary.get('argument').node) - right = expression - } - }) - } - debugger - if (!right) { return [] } - - const left = path.get('left') - if (!left.isLVal()) { - throw left.buildCodeFrameError("Unassignable left-hand side of data binding") - } - - return [left, right] - } - program.traverse({ - ExpressionStatement(expressionStatementPath) { - const path = expressionStatementPath.get('expression'); + ExpressionStatement(stmt) { + const path = stmt.get('expression'); const [left, right] = leftRightOfSquigglyArrow(path); - if (!left || !right) { - // path.replaceWith(t.numberLiteral(123)) - return - } - - const valueName = right.scope.generateUidIdentifier('value') - const bindingTemplate = template(`aexpr(() => EXPRESSION) -.dataflow(${valueName.name} => REFERENCE = ${valueName.name})`) - path.replaceWith(bindingTemplate({ - REFERENCE: left.node, - EXPRESSION: right.node, - })) + if (!left || !right) { return } + + // path.replaceWith(t.numberLiteral(123)) + + // const name = path.scope.generateUidIdentifier('value').name; + // const db = template(`ae(EXPR).onChange(${name} => REF = ${name})`)({ + // EXPR: right, + // REF: left + // }); + // path.replaceWith(db) } }) } @@ -59,7 +26,35 @@ export default function ({ template, types: t }) { } +function leftRightOfSquigglyArrow(path) { + if (!path.isBinaryExpression()) { return [] } + if (path.node.operator !== '<') { return [] } + + let right + const expression = path.get('right') + if (expression.isUnaryExpression() && expression.node.operator === '~') { + right = expression.get('argument') + } else { + expression.traverse({ + UnaryExpression(unary) { + if (unary.node.operator !== '~') { return } + if (expression.node.loc.start.index !== unary.node.loc.start.index) { return } + unary.stop() + unary.replaceWith(unary.get('argument').node) + right = expression + } + }) + } + if (!right) { return [] } + + const left = path.get('left') + if (!left.isLVal()) { + throw left.buildCodeFrameError("Unassignable left-hand side of data binding") + } + console.warn('squiggly arrow found') + return [left.node, right.node] +} @@ -68,10 +63,8 @@ export default function ({ template, types: t }) { -// const valueName = right.scope.generateUidIdentifier('value') -// const bindingTemplate = template(`aexpr(() => EXPRESSION) -// .dataflow(${valueName.name} => REFERENCE = ${valueName.name})`) -// path.replaceWith(bindingTemplate({ -// REFERENCE: left.node, -// EXPRESSION: right.node, -// })) + // const db = template(`aexpr(() => SOURCE).dataflow(v => TARGET = v)`)({ + // SOURCE: right, + // TARGET: left, + // }); + // path.replaceWith(db) \ No newline at end of file diff --git a/src/client/reactive/babel-plugin-sample-data-bindings/scribbles.js b/src/client/reactive/babel-plugin-sample-data-bindings/scribbles.js new file mode 100644 index 000000000..50c7aee27 --- /dev/null +++ b/src/client/reactive/babel-plugin-sample-data-bindings/scribbles.js @@ -0,0 +1,12 @@ +const target = document.getElementById('target'); + +target.style.width <~ that.style.width + + + + + + +ae(that.style.width).onChange(v => target.style.width = v) +import { AExprRegistry } from 'src/client/reactive/active-expression/ae-registry.js' +AExprRegistry.allAsArray().last.dispose() \ No newline at end of file diff --git a/src/components/widgets/jspdf-example.js b/src/components/widgets/jspdf-example.js index 1f8b192bf..0cea721ee 100644 --- a/src/components/widgets/jspdf-example.js +++ b/src/components/widgets/jspdf-example.js @@ -785,7 +785,7 @@ const tapSVG = do { const C_FRONTCARD_FILL = "black"; const C_FRONTCARD_STROKE = "black"; - const svg = ( @@ -797,7 +797,7 @@ svg }; { - const hedronTemp = document.getElementById('tap-icon-ubg') + const hedronTemp = document.getElementById('tap-icon-ubg2') if (hedronTemp) { hedronTemp.remove() } diff --git a/src/components/widgets/lively-code-mirror-hint.js b/src/components/widgets/lively-code-mirror-hint.js index ea839e099..a2d917103 100644 --- a/src/components/widgets/lively-code-mirror-hint.js +++ b/src/components/widgets/lively-code-mirror-hint.js @@ -106,9 +106,11 @@ class Completions { }; CodeMirror.on(completionsObject, "shown", () => { - // lively.warn("shown"); + // lively.warn("shown " + completionsObject); }); CodeMirror.on(completionsObject, "select", (completion, element) => { + // lively.warn("select " + element); + debugger if (!element.parentElement.querySelector('li.shortcut-present')) { element.classList.add('shortcut-present'); const hints = element.parentElement.querySelectorAll('li.CodeMirror-hint'); diff --git a/src/components/widgets/lively-code-mirror.js b/src/components/widgets/lively-code-mirror.js index de310651a..ecc398a7c 100644 --- a/src/components/widgets/lively-code-mirror.js +++ b/src/components/widgets/lively-code-mirror.js @@ -442,6 +442,7 @@ export default class LivelyCodeMirror extends HTMLElement { }, // #KeyboardShortcut Ctrl-Space auto complete "Ctrl-Space": cm => { + // lively.notify("fix hints position") this.fixHintsPosition(); cm.execCommand("autocomplete"); }, @@ -646,60 +647,61 @@ export default class LivelyCodeMirror extends HTMLElement { } registerExtraKeys(options) { - if (options) this.addKeys(options); - var keys = {}; - keys = Object.assign(keys, CodeMirror.keyMap.sublime); - keys = Object.assign(keys, this.ensureExtraKeys()); - this.editor.setOption("extraKeys", CodeMirror.normalizeKeyMap(keys)); + if (options) this.addKeys(options) + var keys = {} + keys = Object.assign(keys, CodeMirror.keyMap.sublime) + keys = Object.assign(keys, this.ensureExtraKeys()) + this.editor.setOption("extraKeys", CodeMirror.normalizeKeyMap(keys)) } setupEditorOptions(editor) { - editor.setOption("matchBrackets", true); - editor.setOption("styleSelectedText", true); - editor.setOption("autoCloseBrackets", true); - editor.setOption("autoCloseTags", true); - editor.setOption("scrollbarStyle", "simple"); - editor.setOption("scrollbarStyle", "simple"); + editor.setOption("matchBrackets", true) + editor.setOption("styleSelectedText", true) + editor.setOption("autoCloseBrackets", true) + editor.setOption("autoCloseTags", true) + editor.setOption("scrollbarStyle", "simple") + editor.setOption("scrollbarStyle", "simple") + editor.setOption("autoRefresh", {delay: 10 }) - editor.setOption("autoRefresh", {delay: 10 }); - - - editor.setOption("tabSize", indentationWidth()); - editor.setOption("indentWithTabs", false); - editor.setOption("indentUnit", indentationWidth()); - editor.setOption("highlightSelectionMatches", { showToken: /\w/, annotateScrollbar: true + editor.setOption("tabSize", indentationWidth()) + editor.setOption("indentWithTabs", false) + editor.setOption("indentUnit", indentationWidth()) - // editor.setOption("keyMap", "sublime") - - });editor.on("cursorActivity", cm => { + editor.setOption("highlightSelectionMatches", { + showToken: /\w/, + annotateScrollbar: true + }) + + editor.on("cursorActivity", cm => { if (this.ternLoaded) { this.ternWrapper.then(tw => tw.updateArgHints(cm, this)); } - }); + }) // http://bl.ocks.org/jasongrout/5378313#fiddle.js editor.on("cursorActivity", cm => { // this.ternWrapper.then(tw => tw.updateArgHints(cm, this)); - const widgetEnter = cm.widgetEnter; - cm.widgetEnter = undefined; + const widgetEnter = cm.widgetEnter + cm.widgetEnter = undefined if (widgetEnter) { // check to see if movement is purely navigational, or if it // doing something like extending selection - var cursorHead = cm.getCursor('head'); - var cursorAnchor = cm.getCursor('anchor'); + var cursorHead = cm.getCursor('head') + var cursorAnchor = cm.getCursor('anchor') if (posEq(cursorHead, cursorAnchor)) { - widgetEnter(); + widgetEnter() } } - }); + }) + editor.setOption("hintOptions", { container: this.shadowRoot.querySelector("#code-mirror-hints"), codemirror: this, closeCharacters: /\;/ // we want to keep the hint open when typing spaces and "{" in imports... - }); + }) - this.registerExtraKeys(); + this.registerExtraKeys() } // Fires when an attribute was added, removed, or updated @@ -1189,7 +1191,7 @@ export default class LivelyCodeMirror extends HTMLElement { } fixHintsPosition() { - lively.setPosition(this.shadowRoot.querySelector("#code-mirror-hints"), pt(-document.scrollingElement.scrollLeft, -document.scrollingElement.scrollTop).subPt(lively.getClientPosition(this))); + // #TODO not needed any more, beccause we fix it directly src/external/code-mirror/addon/hint/show-hint.js } diff --git a/src/components/widgets/ubg-card.js b/src/components/widgets/ubg-card.js index ba9afd679..20d2af318 100644 --- a/src/components/widgets/ubg-card.js +++ b/src/components/widgets/ubg-card.js @@ -217,6 +217,14 @@ ${mainElements}`, bounds); } +function previewSVG(svg) { + const hedronTemp = document.getElementById(svg.id) + if (hedronTemp) { + hedronTemp.remove() + } + document.body.insertAdjacentHTML("afterbegin", svg.outerHTML) +} + const hedronSVG = do { function point(pt) { return `${pt.x} ${pt.y}`; @@ -253,14 +261,7 @@ const hedronSVG = do { ; }; - -{ - const hedronTemp = document.getElementById('hedron') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", hedronSVG.outerHTML) -} +// previewSVG(hedronSVG) const upgradeSVG = do { const svg = (); svg }; - -{ - const hedronTemp = document.getElementById('upgradeSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", upgradeSVG.outerHTML) -} +// previewSVG(upgradeSVG) function rectToViewBox(rect) { @@ -438,7 +432,7 @@ const tapSVG = do { const C_FRONTCARD_FILL = "black"; const C_FRONTCARD_STROKE = "black"; - const svg = ( @@ -448,14 +442,8 @@ const tapSVG = do { ); svg }; +// previewSVG(tapSVG) -{ - const hedronTemp = document.getElementById('tap-icon-ubg') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", tapSVG.outerHTML) -} @@ -477,14 +465,8 @@ const tradeSVG = do { ); svg }; +// previewSVG(tradeSVG) -{ - const hedronTemp = document.getElementById('tradeSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", tradeSVG.outerHTML) -} const CARD_COST_ONE_VIEWBOX = lively.rect(0, 0, 270, 270); const cardCostOneSVG = do { @@ -510,14 +492,8 @@ const cardCostOneSVG = do { ); svg }; +// previewSVG(cardCostOneSVG) -{ - const hedronTemp = document.getElementById('cardCostOneSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", cardCostOneSVG.outerHTML) -} const CARD_COST_VIEWBOX = lively.rect(0, 0, 376, 326); const cardCostTwoSVG = do { @@ -539,13 +515,6 @@ const cardCostTwoSVG = do { svg }; -{ - const hedronTemp = document.getElementById('cardCostTwoSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", cardCostTwoSVG.outerHTML) -} class FileCache { @@ -647,7 +616,16 @@ ${SVG.elementSymbol(others[2], lively.pt(12.5, 8.5), 1.5)}`, lively.rect(0, 0, 1 }); printedRules = printedRules.replace(/blitz/gmi, ''); - printedRules = printedRules.replace(/passive/gmi, ''); + printedRules = printedRules.replace(/passive/gmi, ``); printedRules = printedRules.replace(/start of turn,?/gmi, ''); printedRules = printedRules.replace(/ignition/gmi, ''); printedRules = printedRules.replace(/\btrain\b/gmi, ''); @@ -810,7 +788,11 @@ ${SVG.elementSymbol(others[2], lively.pt(12.5, 8.5), 1.5)}`, lively.rect(0, 0, 1 it = 'it' } - return `Pay (${cost}) to play ${thatCard}, but trash ${it} at end of turn.` + if (cost === 'action') { + return `To dash, play ${thatCard}, but trash ${it} at end of turn.` + } else { + return `Pay (${cost}) to play ${thatCard}, but trash ${it} at end of turn.` + } }, @@ -900,6 +882,10 @@ ${SVG.elementSymbol(others[2], lively.pt(12.5, 8.5), 1.5)}`, lively.rect(0, 0, 1 return 'Blitz You may cast this.' }, + reap: (...args) => { + return `To reap, gain vp equal to a card's base vp.` + }, + resonance: (...args) => { if (args.includes('all')) { // keyword granted @@ -1393,9 +1379,19 @@ background: ${color}; // #TODO: wait for image to be loaded async _setBackgroundImage(filePath) { + await this.loadImage(filePath) this.get('#bg').style.backgroundImage = `url(${filePath})` } + async loadImage(filePath) { + return new Promise((resolve, reject) => { + const image = new Image(); + image.addEventListener('load', resolve); + image.addEventListener('error', reject); + image.src = filePath; + }); + } + /*MD ## Rendering MD*/ async renderMagicStyle(cardDesc, outsideBorder, assetsInfo) { const [BOX_FILL_COLOR, BOX_STROKE_COLOR, BOX_FILL_OPACITY] = this.colorsForCard(cardDesc); diff --git a/src/components/widgets/ubg-cards-entry.js b/src/components/widgets/ubg-cards-entry.js index 0431b62cc..ef84d3454 100644 --- a/src/components/widgets/ubg-cards-entry.js +++ b/src/components/widgets/ubg-cards-entry.js @@ -112,30 +112,8 @@ export default class UBGCardEntry extends Morph { this.classList.toggle('out-of-range', !inRange); } - updateToFilter(filter) { - let matching - - if (filter.startsWith('>')) { - let functionBody = 'return ' + filter.substring(1).trim(); - let filterFunction = new Function('c', functionBody); - matching = !!filterFunction(this.card) - } else { - filter = filter.toLowerCase(); - - const card = this.card; - const id = card.getId(); - const name = card.getName(); - const cardType = card.getType() - const element = card.getElement(); - const cost = card.getCost(); - const text = card.getText(); - const notes = card.getNotes(); - const tags = card.getTags().join(' '); - const aspects = [id, name, cardType, element, cost, text, notes, tags]; - - matching = aspects.some(aspect => (aspect + '').toLowerCase().match(new RegExp(filter, 'gmi'))); - } - + updateToFilter(filterFunction) { + const matching = filterFunction(this.card) this.classList.toggle('match', matching); this.classList.toggle('hidden', !matching); } diff --git a/src/components/widgets/ubg-cards.html b/src/components/widgets/ubg-cards.html index c89330ecc..c201836e4 100644 --- a/src/components/widgets/ubg-cards.html +++ b/src/components/widgets/ubg-cards.html @@ -126,7 +126,7 @@
- + diff --git a/src/components/widgets/ubg-cards.js b/src/components/widgets/ubg-cards.js index 3053f7c69..174c62984 100644 --- a/src/components/widgets/ubg-cards.js +++ b/src/components/widgets/ubg-cards.js @@ -239,188 +239,12 @@ ${mainElements}`, bounds); } -const hedronSVG = do { - function point(pt) { - return `${pt.x} ${pt.y}`; - } - - const topB = lively.pt(11.5, 14.401); - const topL = topB.addXY(-11.5, -4.758); - const topT = topL.addXY(11.5, -9.66); - const topR = topT.addXY(11.5, 9.66); - const topB2 = topR.addXY(-11.5, 4.758); - const topLeftData = `M${point(topB)} L ${point(topL)} ${point(topT)} z`; - const topRightData = `M${point(topB)} L ${point(topT)} ${point(topR)} z`; - - const bottomB = lively.pt(11.5, 16.036); - const bottomL = bottomB.addXY(-11.5, -5.050); - const bottomT = bottomL.addXY(11.5, 12.030); - const bottomR = bottomT.addXY(11.5, -12.030); - const bottomB2 = bottomR.addXY(-11.5, 5.050); - const bottomLeftData = `M${point(bottomB)} L ${point(bottomL)} ${point(bottomT)} z`; - const bottomRightData = `M${point(bottomB)} L ${point(bottomT)} ${point(bottomR)} ${point(bottomB2)} z`; - - const greenHedron = true; - - - - - - ; -}; - -{ - const hedronTemp = document.getElementById('hedron') +function previewSVG(svg) { + const hedronTemp = document.getElementById(svg.id) if (hedronTemp) { hedronTemp.remove() } - document.body.insertAdjacentHTML("afterbegin", hedronSVG.outerHTML) -} - -const upgradeSVG = do { - const svg = ( - - - - - - - - -); -svg -}; - -{ - const hedronTemp = document.getElementById('upgradeSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", upgradeSVG.outerHTML) + document.body.insertAdjacentHTML("afterbegin", svg.outerHTML) } @@ -428,118 +252,6 @@ function rectToViewBox(rect) { return `${rect.x} ${rect.y} ${rect.width} ${rect.height}` } -const TAP_VIEWBOX = lively.rect(2 ,20 ,103 ,103); -const tapSVG = do { - function toPair(pt) { - return `${pt.x} ${pt.y}` - } - - const size = 18 - const tip = lively.pt(83.5, 65) - const anchor = tip.subY(size); - const tail = anchor.subXY(20, 25) - const tipLeft = tip.subXY(size, size) - const tipRight = tip.addXY(size, -size) - const anchorLeft = tipLeft.addX(12.5) - const anchorRight = tipRight.subX(12.5) - const controlLeft = anchorLeft.subY(18) - const controlRight = anchorRight.subY(18) - const controlTail = tail.addX(5) - const path = -; - const C_BACKCARD_FILL = "transparent"; - const C_BACKCARD_STROKE = "black"; - const C_FRONTCARD_FILL = "black"; - const C_FRONTCARD_STROKE = "black"; - - const svg = ( - - - {path} - ); -svg -}; - -{ - const hedronTemp = document.getElementById('tap-icon-ubg') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", tapSVG.outerHTML) -} - - - - -const tradeSVG = do { - const path1 = "M19.335 11.943c1.463 0.801 2.775 2.074 4.369 4.148 0.005-0.056 0.010-0.113 0.016-0.171 0.309-3.338 0.912-9.84-9.249-13.17 0.113 0.146 0.508 0.575 0.958 1.064 0.75 0.815 1.651 1.795 1.651 1.901-0.903-0.529-5.419-1.906-9.333 0.847s-5.189 6.67-4.616 11.329c0.455 3.7 3.289 6.799 6.95 8.289-2.584-1.464-4.341-4.342-4.341-7.654 0-4.795 3.684-8.682 8.229-8.682 2.050 0 3.925 0.791 5.366 2.099z"; - const path2 = "M12.665 20.057c-1.463-0.801-2.775-2.074-4.369-4.148-0.005 0.056-0.010 0.113-0.016 0.171-0.309 3.338-0.912 9.839 9.249 13.17-0.113-0.145-0.508-0.575-0.958-1.064-0.75-0.815-1.651-1.795-1.651-1.901 0.903 0.529 5.419 1.906 9.333-0.847s5.189-6.67 4.616-11.329c-0.454-3.7-3.289-6.799-6.95-8.289 2.584 1.464 4.341 4.342 4.341 7.654 0 4.795-3.684 8.682-8.229 8.682-2.050 0-3.925-0.791-5.366-2.099z"; - const svg = ( - - - - - - - - - - -); -svg -}; - -{ - const hedronTemp = document.getElementById('tradeSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", tradeSVG.outerHTML) -} - -const CARD_COST_ONE_VIEWBOX = lively.rect(0, 0, 270, 270); -const cardCostOneSVG = do { - '#d3d3d3' - const C_OUTER = '#252525' - const C_INNER = '#d1d1d1' - const C_TOP = '#e1e5e4' - const C_IMAGE = '#f4f4f4' - - const outer = lively.rect(0, 0, 190, 270) - const inner = outer.insetBy(15) - const top = inner.insetBy(10) - const image = top.insetByRect(lively.rect(0, 30, 0, 45)) - const svg = ( - - - - - - - - -); -svg -}; - -{ - const hedronTemp = document.getElementById('cardCostOneSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", cardCostOneSVG.outerHTML) -} const CARD_COST_VIEWBOX = lively.rect(0, 0, 376, 326); const cardCostTwoSVG = do { @@ -561,13 +273,7 @@ const cardCostTwoSVG = do { svg }; -{ - const hedronTemp = document.getElementById('cardCostTwoSVG') - if (hedronTemp) { - hedronTemp.remove() - } - document.body.insertAdjacentHTML("afterbegin", cardCostTwoSVG.outerHTML) -} +// previewSVG(cardCostTwoSVG) class FileCache { @@ -699,10 +405,35 @@ export default class Cards extends Morph { }); } + functionForFilter(filter) { + if (filter.startsWith('>')) { + let functionBody = `return !!(${filter.substring(1).trim()})`; + return new Function('c', functionBody); + } + + filter = filter.toLowerCase(); + const regex = new RegExp(filter, 'gmi') + + return function filterFunction(card) { + const id = card.getId(); + const name = card.getName(); + const cardType = card.getType() + const element = card.getElement(); + const cost = card.getCost(); + const text = card.getText(); + const notes = card.getNotes(); + const tags = card.getTags().join(' '); + + const aspects = [id, name, cardType, element, cost, text, notes, tags]; + return aspects.some(aspect => (aspect + '').toLowerCase().match(regex)); + } + } + updateItemsToFilter() { const filterValue = this.filterValue; + const filterFunction = this.functionForFilter(filterValue); this.allEntries.forEach(entry => { - entry.updateToFilter(filterValue); + entry.updateToFilter(filterFunction); }); } @@ -886,7 +617,7 @@ export default class Cards extends Morph { return; } - if (evt.ctrlKey && !evt.repeat && evt.key == "/") { + if (evt.ctrlKey && !evt.repeat && ['f', '/'].includes(evt.key)) { evt.stopPropagation(); evt.preventDefault(); @@ -1038,7 +769,10 @@ export default class Cards extends Morph { tagCount.set(tag, (tagCount.get(tag) || 0) + 1); }) }) - this._allTags = [...tagCount.entries()].sortBy('second', false).map(pair => pair.first); + this._allTags = [...tagCount.entries()].sortBy('first', true).map(pair => ({ + value: pair.first, + string: `${pair.first} (${pair.second})` + })); } return this._allTags } diff --git a/src/external/code-mirror/addon/hint/show-hint.js b/src/external/code-mirror/addon/hint/show-hint.js index aaf1f643f..a0aaf5541 100644 --- a/src/external/code-mirror/addon/hint/show-hint.js +++ b/src/external/code-mirror/addon/hint/show-hint.js @@ -258,22 +258,36 @@ var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); var left = pos.left, top = pos.bottom, below = true; var offsetLeft = 0, offsetTop = 0; + + // BEGIN #Lively #Hack because new CodeMirror version.... if (container !== ownerDocument.body) { + + // We offset the cursor position because left and top are relative to the offsetParent's top left corner. - var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1; - var offsetParent = isContainerPositioned ? container : container.offsetParent; - var offsetParentPosition = offsetParent.getBoundingClientRect(); - var bodyPosition = ownerDocument.body.getBoundingClientRect(); - offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft); - offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop); + + // var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1; + // var offsetParent = isContainerPositioned ? container : container.offsetParent; + // var offsetParentPosition = offsetParent.getBoundingClientRect(); + // var bodyPosition = ownerDocument.body.getBoundingClientRect(); + // offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft); + // offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop); } - hints.style.left = (left - offsetLeft) + "px"; - hints.style.top = (top - offsetTop) + "px"; + + + offsetLeft = -document.scrollingElement.scrollLeft; + offsetTop = -document.scrollingElement.scrollTop; + + container.appendChild(hints); + lively.setClientPosition(hints, lively.pt(left + offsetLeft, top + offsetTop)) + + // hints.style.left = (left - offsetLeft) + "px"; + // hints.style.top = (top - offsetTop) + "px"; + // END #Lively #Hack #Lukas was here too (#Jens) + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth); var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight); - container.appendChild(hints); cm.getInputField().setAttribute("aria-autocomplete", "list") cm.getInputField().setAttribute("aria-owns", this.id) cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint) diff --git a/src/plugin-babel.js b/src/plugin-babel.js index eb3167ce5..7388df95f 100644 --- a/src/plugin-babel.js +++ b/src/plugin-babel.js @@ -417,13 +417,11 @@ async function aexprViaDirectivePlugins(options = {}) { await importDefaultOf('babel-plugin-syntax-async-generators'), await importDefaultOf('babel-plugin-syntax-object-rest-spread'), await importDefaultOf('babel-plugin-syntax-class-properties'), + await importDefaultOf('babel-plugin-sample-data-bindings'), await importDefaultOf('babel-plugin-var-recorder'), [await importDefaultOf('babel-plugin-ILA'), { executedIn: 'file' }], - [await importDefaultOf('babel-plugin-sample-data-bindings'), { - executedIn: 'file' - }], [await importDefaultOf('babel-plugin-databindings'), { executedIn: 'file' }], @@ -492,17 +490,19 @@ async function workspacePlugins(options = {}) { ]) + const enableAExprsInWorkspace = localStorage.getItem("DisableAExpWorkspace") !== "true"; + if (enableAExprsInWorkspace) { + result.push(await importDefaultOf('babel-plugin-sample-data-bindings')) + } + result.push(...await doitPlugins()) result.push(await importDefaultOf('babel-plugin-var-recorder')) - if (localStorage.getItem("DisableAExpWorkspace") !== "true") { + if (enableAExprsInWorkspace) { result.push([await importDefaultOf('babel-plugin-ILA'), { executedIn: 'file' }]) - result.push([await importDefaultOf('babel-plugin-sample-data-bindings'), { - executedIn: 'file' - }]) result.push([await importDefaultOf('babel-plugin-databindings'), { executedIn: 'file' }])