-
Notifications
You must be signed in to change notification settings - Fork 0
/
.eslintcache
1 lines (1 loc) · 50.5 KB
/
.eslintcache
1
[{"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/index.tsx":"1","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/HomePage.tsx":"2","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/EditorPage.tsx":"3","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/Examples/Lilac.tsx":"4","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/FavoritePage.tsx":"5","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/Examples/TextGarden.tsx":"6","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/lib/utils.ts":"7","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/ExamplesPage.tsx":"8","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/data/intro.tsx":"9","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/ui/PageLayout.tsx":"10","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSPreview.tsx":"11","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/ui/TableOfContents.tsx":"12","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditAndView.tsx":"13","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/LSImageViewer2D.tsx":"14","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/index.ts":"15","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/data/examples.ts":"16","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/drawChar.ts":"17","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/codeSyntax.tsx":"18","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/ui/RangeSlider.tsx":"19","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSEditor.tsx":"20","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/LSImageViewerBasic.tsx":"21","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/lib/worker/index.ts":"22","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSTextViewer.tsx":"23","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSViewerController.tsx":"24","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSCodeEditor.tsx":"25","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSStatusConsole.tsx":"26","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSGFXEditor.tsx":"27","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/lib/worker/worker.ts":"28","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/index.tsx":"29","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/LSImageViewer3D.tsx":"30"},{"size":1101,"mtime":1634794929985,"results":"31","hashOfConfig":"32"},{"size":476,"mtime":1685024516724,"results":"33","hashOfConfig":"32"},{"size":1236,"mtime":1634669308383,"results":"34","hashOfConfig":"32"},{"size":3085,"mtime":1634794799397,"results":"35","hashOfConfig":"32"},{"size":807,"mtime":1634669298780,"results":"36","hashOfConfig":"32"},{"size":2188,"mtime":1634794899477,"results":"37","hashOfConfig":"32"},{"size":3423,"mtime":1634793306469,"results":"38","hashOfConfig":"32"},{"size":1173,"mtime":1634796540658,"results":"39","hashOfConfig":"32"},{"size":17654,"mtime":1634797133420,"results":"40","hashOfConfig":"32"},{"size":783,"mtime":1634783923725,"results":"41","hashOfConfig":"32"},{"size":4509,"mtime":1634791941043,"results":"42","hashOfConfig":"32"},{"size":897,"mtime":1634797506031,"results":"43","hashOfConfig":"32"},{"size":2029,"mtime":1634790090722,"results":"44","hashOfConfig":"32"},{"size":1018,"mtime":1632800684164,"results":"45","hashOfConfig":"32"},{"size":265,"mtime":1633390898779,"results":"46","hashOfConfig":"32"},{"size":1952,"mtime":1634797167556,"results":"47","hashOfConfig":"32"},{"size":2973,"mtime":1631045417779,"results":"48","hashOfConfig":"32"},{"size":3066,"mtime":1634791691219,"results":"49","hashOfConfig":"32"},{"size":664,"mtime":1634162436783,"results":"50","hashOfConfig":"32"},{"size":8772,"mtime":1634672101105,"results":"51","hashOfConfig":"32"},{"size":5231,"mtime":1634669302923,"results":"52","hashOfConfig":"32"},{"size":735,"mtime":1634672279001,"results":"53","hashOfConfig":"32"},{"size":316,"mtime":1634790535241,"results":"54","hashOfConfig":"32"},{"size":8177,"mtime":1634669314620,"results":"55","hashOfConfig":"32"},{"size":1404,"mtime":1634669315525,"results":"56","hashOfConfig":"32"},{"size":3148,"mtime":1634669292724,"results":"57","hashOfConfig":"32"},{"size":2302,"mtime":1634669316378,"results":"58","hashOfConfig":"32"},{"size":661,"mtime":1634672282601,"results":"59","hashOfConfig":"32"},{"size":141,"mtime":1633390837983,"results":"60","hashOfConfig":"32"},{"size":2522,"mtime":1634618902280,"results":"61","hashOfConfig":"32"},{"filePath":"62","messages":"63","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"64","usedDeprecatedRules":"65"},"yrsu92",{"filePath":"66","messages":"67","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"68","usedDeprecatedRules":"65"},{"filePath":"69","messages":"70","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"71","messages":"72","errorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"73","usedDeprecatedRules":"65"},{"filePath":"74","messages":"75","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"76","usedDeprecatedRules":"65"},{"filePath":"77","messages":"78","errorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"79","usedDeprecatedRules":"65"},{"filePath":"80","messages":"81","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"82","usedDeprecatedRules":"65"},{"filePath":"83","messages":"84","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"85","usedDeprecatedRules":"65"},{"filePath":"86","messages":"87","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"88","messages":"89","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"90","messages":"91","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"92","messages":"93","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"94","messages":"95","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"96","messages":"97","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"98","usedDeprecatedRules":"65"},{"filePath":"99","messages":"100","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"101","messages":"102","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"103","messages":"104","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"105","usedDeprecatedRules":"65"},{"filePath":"106","messages":"107","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"108","messages":"109","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"110","messages":"111","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"112","messages":"113","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"114","usedDeprecatedRules":"65"},{"filePath":"115","messages":"116","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"117","messages":"118","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"119","messages":"120","errorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"121","usedDeprecatedRules":"65"},{"filePath":"122","messages":"123","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"124","messages":"125","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"126","usedDeprecatedRules":"65"},{"filePath":"127","messages":"128","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"129","messages":"130","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"131","messages":"132","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},{"filePath":"133","messages":"134","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"65"},"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/index.tsx",["135"],"import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Examples from './pages/ExamplesPage';\nimport \"./global.css\"\nimport { BrowserRouter as Router, Route } from \"react-router-dom\";\nimport InteractiveEditor from './pages/EditorPage';\nimport Lilac from './pages/Examples/Lilac';\nimport textGarden from './pages/Examples/TextGarden';\n\nimport FavoritePage from './pages/FavoritePage';\nimport Home from './pages/HomePage';\n\nReactDOM.render(\n <Router>\n <Route path=\"/edit\" component={InteractiveEditor} />\n <Route exact path=\"/\" component={Home} />\n <Route exact path=\"/examples/Lilac\" component={Lilac} />\n <Route exact path=\"/examples/Text\" component={textGarden} />\n <Route exact path=\"/favorites\" component={FavoritePage} />\n </Router>,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\n//reportWebVitals();\n\n//Useful tings\n//<P5Draw commandString=\"FFF+F\" length={10} />",["136","137"],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/HomePage.tsx",["138"],"\nimport { Table } from \"p5\";\nimport React from \"react\"\nimport PageLayout from \"../components/ui/PageLayout\";\nimport TableOfContents from \"../components/ui/TableOfContents\";\nimport intro from '../data/intro';\nimport Examples from \"./ExamplesPage\";\n\n\nconst Home: React.FunctionComponent<{}> = () => {\n return (\n <PageLayout>\n <TableOfContents/>\n <div className=\"centered narrow markdown\">\n {intro}\n <Examples/>\n </div>\n </PageLayout>\n );\n}\n\n\n\n\nexport default Home;\n\n","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/EditorPage.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/Examples/Lilac.tsx",["139","140","141","142","143"],"import LSystem, { ParamsValue } from \"@bvk/lsystem\"\nimport p5 from \"p5\"\nimport {LSImageViewer3D} from \"../../components/LSViewer\"\nimport { CompleteLSExample, completeGfxProps, GFXProps } from \"../../lib/utils\"\n\nconst lilacData: CompleteLSExample = {\n name: \"lilac\",\n code: \"!(0.9) #(120) [ -(44) ^(20) F(50) AK ]\\n\\nA: P I(0) /(90) A\\nI(t) {t!=2}: F I(t+1)\\nI(t) {t==2}: ^(rnd(5,15)) #(rnd(60,150)) I(t+1)[-(45)FFA][+(45)FFA][FFA]\\nP: [-(45)/(45)K][+(45)/(45)K]\\nK: [F #(100) F [~ M(0.05)]]\\nM(s) {s<0.1}: M(s+0.05)\\nM(s) {s>=0.1}: M(0.1)\",\n gfxProps: {\n length: 3,\n renderType: [\"3d\"],\n width: 1200,\n height: 850,\n angle: 8,\n iterations: 16\n },\n};\nexport default function Lilac() {\n return (<div> todo </div>)\n // let ls = new LSystem(lilacData.lsProps.axiom, lilacData.lsProps.productions, lilacData.lsProps.iterations);\n // let gfxProps = lilacData.gfxProps; \n\n // return (\n // <div > \n // <DrawLilac axiom={ls.getIterationAsObject()} gfxProps={completeGfxProps(gfxProps)} /> \n \n // </div>)\n}\n\nconst flowerHue = 325; \nclass DrawLilac extends LSImageViewer3D {\n windAngle = 0;\n animationSpeed = 600;\n preload = (p: p5) => {\n p.loadModel(\n process.env.PUBLIC_URL + \"/assets/lily-flat.obj\",\n true,\n (m) => {\n this.models.push(m);\n this.startIterationAnimation()\n },\n (e) => {\n console.log(\"Fail to load model\");\n }\n );\n }\n moveToCenter = () => {\n //Do nothing, were already there\n let p = this.p5Context;\n if (!p) return;\n p.background(200, 100,100,0.0);\n \n let pos = [-180,-150,-320];\n p.ambientLight(flowerHue - 95, 80, 100);\n p.pointLight(flowerHue, 80, 90, -500, -500, -900);\n p.pointLight(flowerHue + 200, 80, 65, 200, 200, -300);\n \n p.camera(pos[0], pos[1], pos[2], pos[0], pos[1],0, 0,1,0);\n \n }\n simulateWind = () => {\n let maxBlows = Math.floor(Math.random() * 100 + 20);\n for (var i = 0; i < maxBlows; i++) {\n setTimeout(() => {\n this.redraw();\n }, i * 100);\n }\n }\n drawModel = (p:p5, params: ParamsValue | undefined) => {\n let scaleValue = params && params[0] ? parseFloat(params[0] as string) : 0.1;\n let model = this.models[0];\n if (!model) return;\n p.push();\n\n p.noStroke();\n p.fill(100,100,100); \n p.specularMaterial(flowerHue,0,100)\n p.scale(scaleValue);\n p.model(model);\n p.pop();\n }\n moveCamera = () => {\n //Do nothing\n }\n render() {\n return (\n <div style={{backgroundImage: \"linear-gradient(white 30%, rgb(255,220,250))\"}}>\n <div\n style={{\n position: \"fixed\",\n top: \"12px\",\n right: \"12px\",\n width: \"24px\",\n height: \"24px\",\n borderRadius: \"100%\",\n cursor: \"ne-resize\",\n background: \"rgb(250,120,200)\"\n }}\n onClick={() => this.startIterationAnimation()}\n >\n {\" \"}\n </div>\n <div onClick={(e) => this.simulateWind()} ref={this.containerRef} style={{marginLeft: \"10%\"}}/>\n </div>\n );\n }\n}","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/FavoritePage.tsx",["144","145"],"import { LSPreview } from \"../components/LSPreview\";\nimport PageLayout from \"../components/ui/PageLayout\";\nimport { codeToProps, getFave } from \"../lib/utils\";\n\nconst FavoritePage: React.FunctionComponent = ({}) => {\n\n const favorites = localStorage.getItem(\"favorites\");\n if (! favorites || favorites === \"\") {\n return <PageLayout><div> No favorites yet </div></PageLayout>\n }\n\n const faveList = JSON.parse(favorites);\n let links = Object.keys(faveList).map( (key) => {\n const fave = getFave(faveList[key]);\n if (fave) {\n return <div> <LSPreview code={fave.code} gfxProps={fave.gfx} /></div>\n } else {\n return <div> <li> Fave corrupted, sorry </li></div>\n }\n })\n return (<PageLayout><div className=\"grid padded\"> {links} </div> </PageLayout>)\n}\n\nexport default FavoritePage;","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/Examples/TextGarden.tsx",["146","147","148","149","150","151"],"import LSystem, { ParamsValue } from \"@bvk/lsystem\";\nimport p5 from \"p5\";\nimport LSImageViewer2D from \"../../components/LSViewer/LSImageViewer/LSImageViewer2D\";\nimport { CompleteLSExample, completeGfxProps } from \"../../lib/utils\";\n\n\nconst textFlower: CompleteLSExample = {\n name: \"textFlower\",\n code: \"[S]\\nS: A(rnd(5,10))\\nA(a) {a>=1}: F B(0) B(1) + A(a-1)\\nB(b) {b==0}: [+(75) F(20) f(10) T(0)]\\nB(b) {b==1}: [-(75) F(20) f(50) +(180) T(1)]\\nA(a) {a<1}: FFFF -(120) P(rnd(8,19))\\nP(p) {p>0}: [F(40) f(10) T(2)] [+(rnd(40,60)) P(p-1)]\\nP(p) {p==0}: X\",\n gfxProps: {\n length: 40,\n renderType: [\"2d\"],\n width: 600,\n height: 760,\n angle: 5,\n center: [0,0.4],\n iterations: 30,\n },\n};\n\nconst text = [{t:\"you\", s: 16},{t:\"thank\", s:16}, {t:\"☼\", s: 18}]\nconst defaultText = {t: \"\", s: 12};\n\nexport default function textGarden() {\n \n return <div>todo</div>\n // let ls = new LSystem(textFlower.lsProps.axiom, textFlower.lsProps.productions, textFlower.lsProps.iterations);\n // let gfxProps = textFlower.gfxProps\n // console.log(ls.getAllIterationsAsString());\n\n // return (<TextTurtle axiom={ls.getIterationAsObject()} gfxProps={completeGfxProps(gfxProps)} />)\n}\nfunction drawText(p: p5, params: ParamsValue | undefined) {\n let index = params && params.length == 1 ? parseInt(params[0] as string) : -1;\n let textObj = index > -1 ? text[index] : defaultText;\n p.push();\n p.noStroke();\n p.fill(0,0,0);\n p.textSize(textObj.s);\n p.text(textObj.t, 0,0);\n p.pop();\n}\n\nclass TextTurtle extends LSImageViewer2D {\n xPercent = 1;\n preload = (p:p5) => { \n p.textFont(\"helvetica\");\n }\n customRules = {\n \"T\": drawText \n }\n mouseMove = (e: React.MouseEvent) => {\n let mouseX = e.pageX;\n let mousePercentage = e.pageX / window.innerWidth - 0.5;\n console.log(mousePercentage);\n this.xPercent = mousePercentage;\n this.redraw();\n }\n render() {\n return (\n <div onMouseMove={this.mouseMove} className=\"full-bleed\" style={{backgroundImage: \"linear-gradient(white 80%, rgba(140,255,100,0.6))\"}} >\n <div ref={this.containerRef} style={{display: \"inline-block\", marginLeft: \"50%\", transform: \"translate(-50%, 0)\"}}/>\n </div>)\n }\n}\n\n","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/lib/utils.ts",["152","153"],"\nimport qs from \"qs\";\nimport { lineIsComment, splitLines } from \"../components/LSEditor/codeSyntax\";\n\n\n\nexport const defaultLSData = {\n axiom: \"A\",\n productionText: [\"A:FA\"],\n iterations: 10\n}\n\nexport type P5CanvasType = \"webgl\" | \"p2d\"\nexport type renderTypes = \"auto\" | \"2d\" | \"3d\" | \"text\" | \"pixel\";\n\nexport interface CompleteLSExample {\n code: string,\n gfxProps?: GFXProps\n name?: string\n}\n\nexport interface LSError {\n lineNum: \"global\" | number,\n error: Error\n}\nexport interface LSStatus {\n state : \"compiling\" | \"compiled\" | \"error\" | \"ready\" | \"redrawing\"\n errors?: LSError[],\n message?: string\n}\nexport interface LSProps {\n axiom: string\n productions: string[]\n iterations: number\n}\n\nexport interface GFXPropsComplete {\n renderType: renderTypes[]\n length: number\n angle: number\n center: number[]\n width: number \n height: number\n strokeWeight: number\n backgroundColor: string\n animationWaitTime: number,\n iterations: number\n}\n\nconst defaultGFXProps: GFXPropsComplete = {\n renderType: [\"auto\"],\n length: 10,\n angle: 30,\n center: [0,0],\n width: 600,\n height: 600,\n strokeWeight: 1,\n backgroundColor:\"#eee\",\n animationWaitTime: 500,\n iterations: 3\n}\n\nexport const completeGfxProps = (gfxProps: GFXProps | undefined) : GFXPropsComplete => {\n if ( gfxProps === undefined) return defaultGFXProps\n return {...defaultGFXProps, ...gfxProps};\n}\n\nexport type GFXProps = Partial<GFXPropsComplete>\n\n\nexport function flattenLSProps(ls: LSProps, delimiter: string) {\n let stringArr = [ls.axiom, ...ls.productions];\n return stringArr.reduce((str, t) => str + t + delimiter, \"\")\n}\n\nfunction cleanParam(o: string | string[]): string {\n if (o instanceof Array) {\n return o[0] as string\n }\n else return o as string\n}\nexport function decodeParams(paramString: string): { initCode?: string, gfxProps?: GFXProps} {\n const parsedDictionary = qs.parse(paramString, {ignoreQueryPrefix: true});\n //console.log(\"Parsed from \" + paramString , parsedDictionary)\n return {initCode: parsedDictionary.code as string, gfxProps: parsedDictionary.gfx}\n} \n\nexport function encodeParams(code?: string, gfxProps?: GFXProps) {\n const fullProps = { code: code, gfx: gfxProps}\n const urlString = \"?\" + qs.stringify(fullProps);\n //console.log(\"Stringifying props into querystring\" + urlString, fullProps);\n return urlString;\n}\n\n//temp solution\nexport function encodePropsParams(lsProps: LSProps, gfxProps?: GFXProps) {\n let code = lsProps.axiom + \"\\n\";\n code = code + lsProps.productions.join(\"\\n\")\n\n let gfx = {...gfxProps || {}, iterations: lsProps.iterations};\n return encodeParams(code, gfx);\n}\n\nexport function encodeCodeParams(code: string, gfxProps?: GFXProps) {\n return encodeParams(code, gfxProps || {});\n}\n\nexport function createFave(code?: string, gfxProps?: GFXProps) {\n return {code: code, gfx: gfxProps};\n}\n\nexport function getFave(fave: any) {\n if (fave && fave.code) {\n console.log(\"Getting fave\", fave);\n return {code: fave.code, gfx: fave.gfx}\n }\n return undefined;\n}\n\nexport function propsToCode(lsProps: LSProps) : string {\n return lsProps.axiom + \"\\n\" + lsProps.productions.join(\"\\n\");\n}\n\nexport function codeToProps(code: string): LSProps {\n let lines = code.split(\"\\n\")\n lines = lines.filter(line => !lineIsComment(line));\n lines = lines.filter(line => line.trim() !== \"\");\n return {\n axiom: lines[0],\n productions: lines.slice(1),\n iterations: 1\n }\n}","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/pages/ExamplesPage.tsx",["154","155","156"],"import { LSPreview } from \"../components/LSPreview\";\nimport PageLayout from \"../components/ui/PageLayout\";\nimport { propsToCode } from \"../lib/utils\";\nimport examples from \"../data/examples\";\n\n//staticExamples.js\n\nconst StaticExamples: React.FunctionComponent = ({}) => {\n \n function drawExamples() {\n let examplesDOM: JSX.Element[] = [];\n examples.forEach((example, index) => {\n //let lS = new LSystem(example.axiom, example.productions, example.iterations);\n let preview = (\n <p >\n <h2 id={example.name}> {example.name} </h2>\n <LSPreview\n code={example.code}\n gfxProps={example.gfxProps}\n key={\"eg-\" + example.name}\n name={example.name}\n />\n </p>\n );\n examplesDOM.push(preview);\n });\n return <> <h1> Examples </h1> {examplesDOM} </>;\n }\n return drawExamples();\n}\n\nexport default StaticExamples\n\n// {\n// name: \"fern\",\n// lsProps:{\n// axiom: \"A(0,1)\",\n// iterations: 12,\n// productions: [\"A(d,D){d>0}: A(d-1,D)\", \"A(d,D){d==0}: F(1)[+(45)A(D,D)][-(45)A(D,D)]F(1)A(0,D)\", \"F(a): F(a*1.48)\"],\n// },\n// gfxProps: {length: 2, center: [0,0.4]}\n// },\n\n","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/data/intro.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/ui/PageLayout.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSPreview.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/ui/TableOfContents.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditAndView.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/LSImageViewer2D.tsx",["157"],"import p5, { PrintWriter } from \"p5\"\nimport LSImageViewerBasic from \"./LSImageViewerBasic\";\nimport { draw2DChar } from \"./drawChar\";\n\nexport default class LSImageViewer2D extends LSImageViewerBasic {\n drawCharFunct = draw2DChar;\n \n drawCurrentAxiom = (p : p5) => {\n if (this.props.axiom !== undefined) {\n let cS = this.props.axiom\n \n p.background(100,0,100);\n p.noFill();\n p.stroke(0, 0, 0);\n p.strokeWeight(this.props.gfxProps.strokeWeight);\n let steps = cS.length;\n p.push();\n for (let i = 0; i < steps; i++) {\n let letter = cS[i];\n let char = letter.symbol;\n let params = letter.params;\n let param = letter.params && letter.params.length === 1 ? letter.params[0] + \"\" : undefined;\n let val = param && !isNaN(parseFloat(param)) ? parseFloat(param) : undefined\n this.drawCharFunct(p, char, val || this.props.gfxProps.length, val || this.props.gfxProps.angle, params);\n }\n p.pop();\n p.noLoop();\n }\n }\n\n\n}\n\n\n","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/index.ts",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/data/examples.ts",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/drawChar.ts",["158"],"import p5 from \"p5\";\nimport { ParamsValue } from \"@bvk/lsystem\";\n\nexport const draw2DChar = (p : p5, char: string, l: number, a: number, params: ParamsValue | undefined) => {\n if (!p) return;\n switch (char) {\n case \"F\":\n p.line(0, 0, l, 0);\n p.translate(l, 0);\n break;\n case \"f\":\n p.translate(l, 0);\n break;\n case \"+\":\n p.rotate(a);\n break;\n case \"-\":\n p.rotate(-a);\n break;\n case \"[\":\n p.push()\n break;\n case \"]\":\n p.pop();\n break;\n case \"E\":\n p.ellipse(0, 0, l, l);\n break;\n case \"!\":\n p.strokeWeight(l)\n break;\n case \"~\":\n p.rotate(Math.random() * a);\n break;\n case \"#\":\n if (!l || l == 0) p.stroke(0, 0, 0);\n else {\n let h = params && params[0] ? parseFloat(params[0] as string) : 0;\n let s = params && params[1] ? parseFloat(params[1] as string) : 100;\n let b = params && params[2] ? parseFloat(params[2] as string) : 100;\n p.stroke(h, s, b);\n }\n break;\n default:\n //console.log(char + \" isn't turtle command\");\n break;\n }\n}\n\nexport const draw3DChar = (p: p5, char: string, l: number, a: number, params: ParamsValue | undefined) => {\n if (!p) return\n switch (char) {\n case \"F\":\n p.line(0, 0, 0, l);\n p.translate(0, l);\n break;\n case \"f\":\n p.translate(0, l);\n break;\n case \"[\":\n p.push();\n break;\n case \"]\":\n p.pop();\n break;\n //Here: Yaw is around Z axis, giving you +/- on the YX plane \n //What that means, is a 2d curve will be drawn on the YX plane \n case \"+\":\n p.rotateZ(a);\n break;\n case \"-\":\n p.rotateZ(-a);\n break;\n //PITCH is around X axis, giving you &/^ (pitch down/up) \n //So pitching up down gives you rotation \"up/down\" w.r.t to up axis \n case \"&\":\n p.rotateX(a);\n break;\n case \"^\":\n p.rotateX(-a)\n break;\n //ROLL is around Y axis, gives you a roll around itself\n //Without any PITCH, Roll is meaningless for a line (just rolls around itself)\n case '\\'':\n p.rotateY(a);\n break;\n case '/':\n p.rotateY(-a);\n break;\n case \"E\":\n if (params && params[1]) {\n p.fill(parseFloat(params[1] as string), 100,100 );\n }\n p.ellipse(0, 0, l, l);\n p.noFill();\n break;\n case \"!\":\n p.strokeWeight(l)\n break;\n case \"~\":\n p.rotateX(Math.random() * a);\n p.rotateY(Math.random() * a);\n p.rotateZ(Math.random() * a);\n break;\n case \"#\":\n p.stroke(l, 100, 100);\n break;\n case \"M\":\n draw3DModel(p, params)\n break;\n default:\n //console.log(char + \" isn't turtle command\");\n break;\n }\n }\n\nconst draw3DModel = (p:p5, params: ParamsValue | undefined) => {\n let scaleValue = params && params[0] ? parseFloat(params[0] as string) : 0.1;\n p.push();\n //p.specularMaterial(255);\n p.scale(scaleValue);\n p.box(100);\n p.pop();\n}","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/codeSyntax.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/ui/RangeSlider.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSEditor.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/LSImageViewerBasic.tsx",["159"],"import React from \"react\"\nimport { GFXPropsComplete, P5CanvasType } from \"../../../lib/utils\";\nimport {Axiom} from \"@bvk/lsystem\"\nimport p5 from \"p5\";\nimport ReactScrollWheelHandler from \"react-scroll-wheel-handler\";\n\n//Props should control all the things coming into the viewer\nexport interface LSImageViewerBasicProps {\n axiom: Axiom | undefined,\n gfxProps: GFXPropsComplete\n}\n\n//State should control anything needed for the panning + zooming \nexport interface LSImageViewerBasicState {\n localScale: number,\n localCenter: number[] \n}\n\n\nexport default class LSImageViewerBasic< S extends LSImageViewerBasicState = LSImageViewerBasicState> extends React.Component<LSImageViewerBasicProps,S> {\n\n p5Context: p5 | undefined\n containerRef = React.createRef<HTMLDivElement>();\n canvasType : P5CanvasType = \"p2d\"\n canvasID : string = \"P5-BASIC-CANVAS\" \n\n constructor(props: LSImageViewerBasicProps) {\n super(props);\n //TODO: When to bind\n this.state = {\n localScale: props.gfxProps.width / 600,\n localCenter: props.gfxProps.center\n } as S\n }\n componentDidMount() {\n if (this.containerRef.current) \n new p5(this.sketch, this.containerRef.current);\n }\n componentDidUpdate(prevProps: LSImageViewerBasicProps) {\n if (this.props.gfxProps.center !== prevProps.gfxProps.center) {\n this.setState({localCenter: this.props.gfxProps.center})\n }\n if (this.props.gfxProps.width !== prevProps.gfxProps.width || this.props.gfxProps.height !== prevProps.gfxProps.height ) {\n if (this.p5Context) {\n this.p5Context.resizeCanvas(this.props.gfxProps.width, this.props.gfxProps.height);\n this.setState({ localScale: this.props.gfxProps.width / 600})\n } else {\n console.log(\"⛔️⛔️⛔️⛔️ tried resizing canvas but p5 context doesnt exist yet\")\n }\n }\n this.redraw();\n }\n\n defaultSetup = (p: p5) => {\n console.log(\"🦋🦋🦋🦋🦋🦋🦋🦋 creating canvas\", this.props.gfxProps);\n let cnv = p.createCanvas(this.props.gfxProps.width, this.props.gfxProps.height, this.canvasType);\n cnv.id(this.canvasID);\n p.angleMode(p.DEGREES);\n p.colorMode(p.HSB);\n p.noLoop();\n p.textFont(\"monospace \", 12);\n p.strokeCap(\"butt\")\n \n }\n preload = (p: p5) => {\n //Do nothing in the base case\n }\n redraw = () => {\n console.log(\"Redrawing graphic\");\n if (this.p5Context !== undefined) {\n this.p5Context.clear();\n this.p5Context.background(this.props.gfxProps.backgroundColor);\n this.drawCurrentGraphic(this.p5Context);\n this.p5Context?.noLoop();\n } else {\n console.log(\"Couldnt redraw\");\n console.log(this.p5Context);\n }\n }\n moveToCanvasCenter = (p: p5) => {\n if (!p) return\n p.translate(p.width / 2, p.height / 2);\n }\n scaleToZoomLevel = (p: p5) => {\n if (!p) return;\n p.scale(this.state.localScale);\n }\n rotateToUp = (p : p5) => {\n if (p) p.rotate(-90);\n }\n drawCurrentGraphic = (p:p5) => {\n p.push();\n this.moveToCanvasCenter(p);\n this.scaleToZoomLevel(p);\n p.translate(this.state.localCenter[0] * p.width, this.state.localCenter[1] * p.height);\n this.rotateToUp(p);\n this.drawCurrentAxiom(p);\n p.pop();\n }\n drawCurrentAxiom = (p: p5) => {\n p.fill(Math.random() * 100 , 100 , 100);\n p.ellipse(0,0,100,100);\n }\n startIterationAnimation = () => {\n //TODO\n }\n sketch = (p: p5) => {\n \n p.setup = () => {\n console.log(\"💖💖💖💖 RUNNING SETUP NOW FOR P5\")\n this.defaultSetup(p);\n this.preload(p);\n this.p5Context = p;\n this.redraw();\n };\n p.draw = () => {\n\n }\n };\n handleZoom = (zoomAmount: number) => {\n if (zoomAmount && zoomAmount !== 0) {\n let scale = this.state.localScale;\n scale = scale + zoomAmount * scale;\n console.log(\"Setting new scale\" + scale);\n this.setState({localScale: scale})\n }\n }\n handlePan = (panX: number, panY: number) => {\n let center = this.state.localCenter;\n center = [center[0] + panX, center[1] + panY];\n this.setState({localCenter: center})\n }\n getZoomControls = () => {\n return (\n <div key=\"zoom-controls\">\n <div className=\"clickable\" onClick={(e) => this.handleZoom(+0.1)}>\n +\n </div>\n <div className=\"clickable\" onClick={(e) => this.handleZoom(-0.1)}>\n -\n </div>\n </div>);\n }\n getPanControls = () => {\n return ( <div key=\"pan-controls\">\n <div className=\"clickable\" onClick={(e) => this.handlePan(0, -0.01)}>\n up\n </div>\n <div className=\"clickable\" onClick={(e) => this.handlePan(0, 0.01)}>\n dw\n </div>\n <div className=\"clickable\" onClick={(e) => this.handlePan(0.01, 0)}>\n lf\n </div>\n <div className=\"clickable\" onClick={(e) => this.handlePan(-0.01, 0)}>\n rt\n </div>\n </div>)\n }\n getCanvasControls = (): JSX.Element[] => {\n return [ this.getZoomControls(), this.getPanControls()];\n }\n render() {\n return (\n <div style={{ position: \"absolute\" }}>\n <div style={{ position: \"absolute\", right: 0, top: 0, zIndex: 2 }} className=\"padded\" >\n {this.getCanvasControls()}\n </div>\n <div ref={this.containerRef} />\n </div>\n );\n }\n}","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/lib/worker/index.ts",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSTextViewer.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSViewerController.tsx",["160","161","162","163"],"import React, { CSSProperties, useCallback, useMemo, useRef, useState } from \"react\";\nimport LSystem, { Axiom } from \"@bvk/lsystem\";\nimport { completeGfxProps, GFXProps, renderTypes } from \"../../lib/utils\";\nimport LSImageViewer2D from \"./LSImageViewer/LSImageViewer2D\";\nimport LSImageViewer3D from \"./LSImageViewer/LSImageViewer3D\";\nimport { useEffect } from \"react\";\nimport { LSTextViewer } from \".\";\nimport ReactDropdown from \"react-dropdown\";\nimport RangeSlider from \"../ui/RangeSlider\";\nimport { useHotkeys } from \"react-hotkeys-hook\";\nimport useMeasure from \"react-use-measure\";\n\ninterface LSViewerControllerProps {\n lSystem: LSystem;\n gfxProps?: GFXProps;\n autoResize?: boolean;\n className?: string\n style?: CSSProperties\n hideControls?: boolean\n}\n\nconst viewerTypeDropdownOptions: { value: renderTypes; label: string }[] = [\n { value: \"auto\", label: \"Image: Auto\" },\n { value: \"2d\", label: \"Image: 2D\" },\n { value: \"3d\", label: \"Image: 3D\" },\n { value: \"text\", label: \"Text\" },\n];\n\n/**\n * Component to manage viewing an LSystem as an image.\n * NOTE: IF the Lsystem has not been \"iterated\", this component will iterate it on the main thread. It is recommended to iterate before initializing component\n * @param props\n * @returns\n */\nconst LSViewerController: React.FunctionComponent<LSViewerControllerProps> = (props) => {\n //State to update renderers\n const [viewerType, setViewerType] = useState<renderTypes>(extractViewerTypeFromProps(props.gfxProps));\n const [currentAxiom, setCurrentAxiom] = useState<Axiom>();\n const [allCurrentAxioms, setAllCurrentAxioms] = useState<Axiom[]>();\n const [currentIteration, setCurrentIteration] = useState<number>(props.lSystem.iterations);\n const [currentGFXProps, setCurrentGFXProps] = useState<GFXProps>(props.gfxProps || {});\n useHotkeys(\"ctrl+/, command+/\", () => { currentlyAnimating.current ? stopIterationAnimation() : startIterationAnimation(); return false});\n\n //State to update animations\n const currentlyAnimating = useRef<boolean>(false);\n const activeInterval = useRef<NodeJS.Timeout>();\n const [measureRef, bounds] = useMeasure({debounce: 200})\n\n //Trigger re-render if the gxfProps, current axiom, or viewer type change\n const currentContainerSize = useMemo(() => {\n if (props.autoResize) {\n return {width: bounds.width, height: bounds.height}\n } else {\n return {}\n }\n }, [props.autoResize, bounds.width, bounds.height])\n const getViewer = useCallback(() => {\n if (currentAxiom) {\n const viewerProps = { gfxProps: completeGfxProps({...currentGFXProps, ...currentContainerSize}), axiom: currentAxiom };\n switch (viewerType) {\n case \"2d\":\n return <LSImageViewer2D {...viewerProps} key=\"controller-viewer-2d\" />;\n case \"3d\":\n return <LSImageViewer3D {...viewerProps} key=\"controller-viewer-3d\" />;\n case \"text\":\n const axiomsAsText = props.lSystem.getAllIterationsAsString();\n return LSTextViewer(axiomsAsText);\n case \"auto\":\n const autoViewerType = getAutoViewerType(props.lSystem);\n if (autoViewerType === \"3d\") {\n return <LSImageViewer3D {...viewerProps} key=\"controller-viewer-3d\" />;\n } else {\n return <LSImageViewer2D {...viewerProps} key=\"controller-viewer-2d\" />;\n }\n }\n }\n }, [currentAxiom, currentGFXProps, currentContainerSize, viewerType, props.lSystem]);\n\n //When the lsystem changes, cancel any anim timers and set current iterations + all current axioms\n useEffect(() => {\n if (activeInterval.current) clearTimeout(activeInterval.current);\n setCurrentIteration(props.lSystem.iterations);\n setAllCurrentAxioms(props.lSystem.getAllIterationsAsObject());\n }, [props.lSystem, props.lSystem.iterations]);\n\n //When the currentIteration or all current Axioms change, change current axiom (trigger-re-render)\n useEffect(() => {\n if (allCurrentAxioms) setCurrentAxiom(allCurrentAxioms[currentIteration]);\n }, [currentIteration, allCurrentAxioms]);\n\n //If ls or gfx props change, viewer type may change\n useEffect(() => {\n if (props.gfxProps) {\n const newViewerType = extractViewerTypeFromProps(props.gfxProps);\n setViewerType(newViewerType);\n setCurrentGFXProps(props.gfxProps);\n }\n }, [props.gfxProps]);\n\n //Helper functions for animations\n const stopIterationAnimation = () => {\n console.log(\"Anim stop\", currentIteration);\n currentlyAnimating.current = false;\n };\n const startIterationAnimation = () => {\n console.log(\"Anim start\");\n currentlyAnimating.current = true;\n setCurrentIteration(0);\n };\n //Animation is just powered by changes to currentIteration.\n //The currentIteration changes itself every x seconds.\n //STOP IF: the LS changes the iters set to the stopping point OR forced stop\n useEffect(() => {\n if (currentIteration === props.lSystem.iterations || currentlyAnimating.current === false) {\n stopIterationAnimation();\n } else {\n activeInterval.current = setTimeout(\n () => setCurrentIteration(currentIteration + 1),\n props.gfxProps?.animationWaitTime || completeGfxProps(undefined).animationWaitTime\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentIteration]);\n\n\n\n return (\n <div className=\"stack no-gap\">\n {!props.hideControls && (\n <div className=\"toolbar horizontal-stack small edit-surface border-bottom visible-overflow\">\n <div>\n <ReactDropdown\n options={viewerTypeDropdownOptions}\n value={viewerType}\n onChange={(opt) => setViewerType(opt.value as renderTypes)}\n arrowClosed={<span>▾</span>}\n arrowOpen={<span>▾</span>}\n controlClassName={\"horizontal-stack smaller clickable\"}\n menuClassName={\"border floating padded edit-surface-light-tone clickable stack\"}\n />\n </div>\n <div className=\"horizontal-stack padded:right \">\n Iteration\n <span style={{ width: \"2.2ch\", textAlign: \"right\", display: \"inline-block\" }}> {currentIteration} </span>\n <div style={{ width: \"10ch\" }}>\n <RangeSlider\n min={0}\n max={props.lSystem.iterations}\n onChange={(n: number) => {\n stopIterationAnimation();\n setCurrentIteration(n);\n }}\n currentValue={currentIteration}\n />\n </div>\n </div>\n <div\n onClick={() => (currentlyAnimating.current ? stopIterationAnimation() : startIterationAnimation())}\n className=\"clickable minwidth\"\n >\n {currentlyAnimating.current ? \"stop\" : \"animate\"}{\" \"}\n <div className=\"gray subtext padded:left:smallest\">(⌘+/)</div>\n </div>\n </div>\n )}\n <div ref={measureRef} className={props.className} style={props.style}>\n {getViewer()}\n </div>\n </div>\n );\n};\n\nexport default LSViewerController;\n\n// Helper functions to automatically choose character\nfunction charIs3D(l: string) {\n let is3D = l == \"&\" || l == \"^\" || l == \"/\" || l == \"\\\\\";\n return is3D;\n}\nfunction extractViewerTypeFromProps(gfxProps?: GFXProps): renderTypes {\n if (gfxProps && gfxProps.renderType && !gfxProps.renderType.includes(\"auto\")) {\n if (gfxProps.renderType.includes(\"text\")) return \"text\";\n if (gfxProps.renderType.includes(\"2d\")) return \"2d\";\n if (gfxProps.renderType.includes(\"3d\")) return \"3d\";\n }\n return \"auto\";\n}\n\nfunction getAutoViewerType(lSystem: LSystem): renderTypes {\n for (let i = 0; i < lSystem.axiom.length; i++) {\n if (charIs3D(lSystem.axiom[i].symbol)) {\n return \"3d\";\n }\n }\n for (let i = 0; i < lSystem.productions.length; i++) {\n let p = lSystem.productions[i];\n let successors = Array.isArray(p.successor) ? p.successor : [p.successor];\n for (let j = 0; j < successors.length; j++) {\n let s = successors[j];\n for (let k = 0; k < s.letters.length; k++) {\n if (charIs3D(s.letters[k].symbol)) {\n return \"3d\";\n }\n }\n }\n }\n return \"2d\";\n}\n","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSCodeEditor.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSStatusConsole.tsx",["164","165"],"import { LSStatus } from \"../../lib/utils\";\nimport React, {useState, useEffect, useCallback, useRef} from \"react\"\n\ninterface LSConsoleProps {\n status?: LSStatus,\n className?: string\n}\n\ninterface StatusLog {\n timecode: string,\n status: LSStatus\n}\n\nconst getNow = (): string => {\n return new Date().toLocaleTimeString(undefined, {\n hour12: true,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit'\n })\n}\n\n\nconst LSConsole : React.FunctionComponent<LSConsoleProps> = ( {status, className}) => {\n \n const [ statusLog, setStatusLog] = useState<StatusLog[]>([]);\n //const [ currentStatus, setCurrentStatus] = useState<JSX.Element>( statusToEl(status));\n\n useEffect(() => {\n if (status) {\n //const statusEl = statusToEl(status);\n //setCurrentStatus(statusEl);\n\n if (status.state === \"compiling\") {\n setStatusLog([{timecode: getNow(), status}])\n } else {\n setStatusLog((prev) => [...prev, { timecode: getNow(), status }]);\n }\n \n }\n }, [status])\n\n return <div className={className}> {statusLog.map((logStatus) => statusToEl(logStatus.status, logStatus.timecode, statusLog[statusLog.length - 1]) )} </div>\n}\n\nconst statusToEl = (status: LSStatus | undefined, timecode: string, currentStatus: StatusLog) : JSX.Element => {\n let stringEl;\n \n if (!status) {\n stringEl = <div> No status available </div>\n } else {\n switch (status.state) {\n case \"error\":\n stringEl = (\n <div>\n <span className=\"red\"> Whoops, we have an error!</span>\n <ul>\n {status.errors &&\n status.errors.map((err, i) => (\n <li key={`error-${i}`} >\n <span>{err.lineNum === \"global\" ? \"\" : \"Error parsing line: \" + err.lineNum}</span>\n <span>{err.error.message}</span>\n </li>\n ))}\n </ul>\n </div>\n ); \n break;\n case \"compiling\":\n stringEl = <div> Generating L-System {currentStatus.status.state === \"compiling\" ? <ScrollingDots/> : \"\"} </div>\n break;\n case \"compiled\":\n stringEl = <div> L-System generated {status.message} </div>\n break;\n case \"ready\":\n stringEl = <div> Ready to compile </div>\n break;\n case \"redrawing\":\n stringEl = <div> No changes to L-System, just redrawing </div>\n break;\n default:\n stringEl = <div> idk lol </div>\n break;\n }}\nlet timecodeEl = timecode ? <span className=\"gray\"> {timecode} </span> : \"\";\n return <div className=\"horizontal-stack\" > {timecodeEl} {stringEl} </div>\n}\n\nconst ScrollingDots : React.FunctionComponent = ({}) => {\n const [numDots, setNumDots] = useState<number>(3);\n\n const incrementDots = useCallback(() => {\n setNumDots((n) => n > 3 ? 0 : n + 1);\n }, [setNumDots])\n \n useEffect(() => {\n const interval = setInterval(incrementDots, 500);\n return () => {clearInterval(interval)}\n }, [incrementDots])\n\n const getDots = useCallback(() => {\n let str = \"\";\n for (var i=0; i <numDots; i++){\n str += \".\"\n };\n return str;\n }, [numDots]) \n\n return (<span> {getDots()}</span>)\n}\n\n\nexport default LSConsole;","/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSEditor/LSGFXEditor.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/lib/worker/worker.ts",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/index.tsx",[],"/Users/bhavik/Documents/Archive/tend/lsystem-examples/src/components/LSViewer/LSImageViewer/LSImageViewer3D.tsx",[],{"ruleId":"166","severity":1,"message":"167","line":3,"column":9,"nodeType":"168","messageId":"169","endLine":3,"endColumn":17},{"ruleId":"170","replacedBy":"171"},{"ruleId":"172","replacedBy":"173"},{"ruleId":"166","severity":1,"message":"174","line":2,"column":10,"nodeType":"168","messageId":"169","endLine":2,"endColumn":15},{"ruleId":"166","severity":1,"message":"175","line":1,"column":8,"nodeType":"168","messageId":"169","endLine":1,"endColumn":15},{"ruleId":"166","severity":1,"message":"176","line":4,"column":29,"nodeType":"168","messageId":"169","endLine":4,"endColumn":45},{"ruleId":"166","severity":1,"message":"177","line":4,"column":47,"nodeType":"168","messageId":"169","endLine":4,"endColumn":55},{"ruleId":"166","severity":1,"message":"178","line":6,"column":7,"nodeType":"168","messageId":"169","endLine":6,"endColumn":35},{"ruleId":"166","severity":1,"message":"179","line":31,"column":7,"nodeType":"168","messageId":"169","endLine":31,"endColumn":16},{"ruleId":"166","severity":1,"message":"180","line":3,"column":10,"nodeType":"168","messageId":"169","endLine":3,"endColumn":21},{"ruleId":"181","severity":1,"message":"182","line":5,"column":48,"nodeType":"183","messageId":"184","endLine":5,"endColumn":50},{"ruleId":"166","severity":1,"message":"175","line":1,"column":8,"nodeType":"168","messageId":"169","endLine":1,"endColumn":15},{"ruleId":"166","severity":1,"message":"176","line":4,"column":29,"nodeType":"168","messageId":"169","endLine":4,"endColumn":45},{"ruleId":"166","severity":1,"message":"185","line":7,"column":7,"nodeType":"168","messageId":"169","endLine":7,"endColumn":36},{"ruleId":"186","severity":1,"message":"187","line":34,"column":40,"nodeType":"188","messageId":"184","endLine":34,"endColumn":42},{"ruleId":"166","severity":1,"message":"189","line":44,"column":7,"nodeType":"168","messageId":"169","endLine":44,"endColumn":17},{"ruleId":"166","severity":1,"message":"190","line":53,"column":9,"nodeType":"168","messageId":"169","endLine":53,"endColumn":15},{"ruleId":"166","severity":1,"message":"191","line":3,"column":25,"nodeType":"168","messageId":"169","endLine":3,"endColumn":35},{"ruleId":"166","severity":1,"message":"192","line":76,"column":10,"nodeType":"168","messageId":"169","endLine":76,"endColumn":20},{"ruleId":"166","severity":1,"message":"193","line":2,"column":8,"nodeType":"168","messageId":"169","endLine":2,"endColumn":18},{"ruleId":"166","severity":1,"message":"194","line":3,"column":10,"nodeType":"168","messageId":"169","endLine":3,"endColumn":21},{"ruleId":"181","severity":1,"message":"182","line":8,"column":50,"nodeType":"183","messageId":"184","endLine":8,"endColumn":52},{"ruleId":"166","severity":1,"message":"195","line":1,"column":14,"nodeType":"168","messageId":"169","endLine":1,"endColumn":25},{"ruleId":"186","severity":1,"message":"187","line":36,"column":19,"nodeType":"188","messageId":"184","endLine":36,"endColumn":21},{"ruleId":"166","severity":1,"message":"196","line":5,"column":8,"nodeType":"168","messageId":"169","endLine":5,"endColumn":31},{"ruleId":"186","severity":1,"message":"187","line":177,"column":16,"nodeType":"188","messageId":"184","endLine":177,"endColumn":18},{"ruleId":"186","severity":1,"message":"187","line":177,"column":28,"nodeType":"188","messageId":"184","endLine":177,"endColumn":30},{"ruleId":"186","severity":1,"message":"187","line":177,"column":40,"nodeType":"188","messageId":"184","endLine":177,"endColumn":42},{"ruleId":"186","severity":1,"message":"187","line":177,"column":52,"nodeType":"188","messageId":"184","endLine":177,"endColumn":54},{"ruleId":"166","severity":1,"message":"197","line":2,"column":50,"nodeType":"168","messageId":"169","endLine":2,"endColumn":56},{"ruleId":"181","severity":1,"message":"182","line":89,"column":50,"nodeType":"183","messageId":"184","endLine":89,"endColumn":52},"@typescript-eslint/no-unused-vars","'Examples' is defined but never used.","Identifier","unusedVar","no-native-reassign",["198"],"no-negated-in-lhs",["199"],"'Table' is defined but never used.","'LSystem' is defined but never used.","'completeGfxProps' is defined but never used.","'GFXProps' is defined but never used.","'lilacData' is assigned a value but never used.","'DrawLilac' is defined but never used.","'codeToProps' is defined but never used.","no-empty-pattern","Unexpected empty object pattern.","ObjectPattern","unexpected","'textFlower' is assigned a value but never used.","eqeqeq","Expected '===' and instead saw '=='.","BinaryExpression","'TextTurtle' is defined but never used.","'mouseX' is assigned a value but never used.","'splitLines' is defined but never used.","'cleanParam' is defined but never used.","'PageLayout' is defined but never used.","'propsToCode' is defined but never used.","'PrintWriter' is defined but never used.","'ReactScrollWheelHandler' is defined but never used.","'useRef' is defined but never used.","no-global-assign","no-unsafe-negation"]