>,\r\n}\r\n\r\nconst SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {\r\n\r\n return (\r\n \r\n \r\n setSpeed(+e.target.value)}/>\r\n {speed}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n )\r\n}\r\n\r\nconst ManualControlButtons = ({interpreter, rerender}: { interpreter: Interpreter, rerender: (() => void) }) => {\r\n\r\n const run = (char: string) => {\r\n try {\r\n interpreter.execute(char);\r\n } catch {\r\n }\r\n rerender();\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n )\r\n}\r\n\r\nexport default Runner;","import './App.scss';\nimport CodeInput, {CodeOptions} from \"./components/CodeInput\";\nimport ProgramOutput from \"./components/ProgramOutput\";\nimport React, {useCallback, useState} from \"react\";\nimport Runner from \"./components/Runner\";\n\nexport const OptionContext = React.createContext({});\n\nfunction App() {\n const [out, setOut] = useState(\"\");\n const [input, setInput] = useState<[string, CodeOptions]>([\"\", {}]);\n const [running, setRunning] = useState(false);\n\n const outHandler = useCallback((char: number) => {\n setOut(oldOut => oldOut + String.fromCharCode(char))\n }, []);\n\n const runHandler = (run: boolean) => {\n setRunning(run);\n if (!run) {\n setOut(\"\");\n }\n }\n\n\n const inputHandler = (code: string, options: CodeOptions) => setInput([code, options]);\n return (\n \n
\n {\n !running && \n }\n \n {\n running && \n }\n \n
\n );\n}\n\nexport default App;","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);"],"sourceRoot":""}
\ No newline at end of file
diff --git a/static/js/main.cb19c05d.chunk.js b/static/js/main.cb19c05d.chunk.js
deleted file mode 100644
index 09f62f7..0000000
--- a/static/js/main.cb19c05d.chunk.js
+++ /dev/null
@@ -1,2 +0,0 @@
-(this["webpackJsonpibfi-ts"]=this["webpackJsonpibfi-ts"]||[]).push([[0],{12:function(t,e,n){},13:function(t,e,n){},15:function(t,e,n){"use strict";n.r(e);var r=n(1),i=n.n(r),c=n(5),a=n.n(c),s=(n(12),n(2)),o=(n(13),n(4)),u=n(0),l=function(t){var e=t.code,n=t.setInput,i=Object(r.useState)(40),c=Object(s.a)(i,2),a=c[0],l=c[1],d=Object(r.useState)({}),h=Object(s.a)(d,2),j=h[0],b=h[1];return Object(u.jsx)("div",{children:Object(u.jsxs)("div",{className:"bf-input",children:[Object(u.jsxs)("div",{children:[Object(u.jsxs)("span",{children:[Object(u.jsx)("label",{htmlFor:"bf-input-fontsize-range",children:"Font Size"}),Object(u.jsx)("input",{type:"range",id:"bf-input-fontsize-range",onChange:function(t){return l(+t.target.value)}})]}),Object(u.jsx)("input",{type:"checkbox",checked:j.minify,id:"input-options-minify",onChange:function(t){b((function(e){return Object(o.a)(Object(o.a)({},e),{},{minify:t.target.checked})})),n(e,j)}}),Object(u.jsx)("label",{htmlFor:"input-options-minify",children:"Minify Code"})]}),Object(u.jsx)("textarea",{value:e,onChange:function(t){return n(t.target.value,j)},style:{fontSize:a},className:"code-input",placeholder:"Input your code here..."}),Object(u.jsx)("div",{children:Object(u.jsx)("button",{onClick:function(){n("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.",j)},children:"Set Hello World"})})]})})},d=function(t){var e=t.text;return Object(u.jsx)("div",{className:"bf-output",children:Object(u.jsx)("textarea",{readOnly:!0,className:"output-area",value:e})})},h=n(6),j=n(7),b=function(){function t(e,n,r,i){Object(h.a)(this,t),this._array=void 0,this._pointer=void 0,this._code=void 0,this._programCounter=void 0,this._inHandler=void 0,this._outHandler=void 0,this._errorHandler=void 0;var c=new ArrayBuffer(32e3);this._array=new Uint8Array(c),this._pointer=0,e[1].minify?this._code=f(e[0]):this._code=e[0],this._programCounter=0,this._inHandler=r,this._outHandler=n,this._errorHandler=i}return Object(j.a)(t,[{key:"next",value:function(){switch(this._code[this._programCounter++]){case"+":this._array[this._pointer]++;break;case"-":this._array[this._pointer]--;break;case">":this._pointer++;break;case"<":if(0===this._pointer){this._errorHandler("Cannot wrap left");break}this._pointer--;break;case".":this._outHandler(this.value);break;case",":try{this._array[this._pointer]=this._inHandler()}catch(n){this._programCounter--,this._errorHandler("Could not read input, trying again next time.")}break;case"[":if(0===this.value)for(var t=0;"]"!==this.lastInstruction||t>-1;)this._programCounter++,"["===this.lastInstruction?t++:"]"===this.lastInstruction&&t--;break;case"]":if(0!==this.value)for(var e=0;"["!==this.lastInstruction||e>-1;)this._programCounter--,"["===this.lastInstruction?e--:"]"===this.lastInstruction&&e++;break;case void 0:this._pointer=this._code.length,console.warn("reached end")}console.log("char: ".concat(this.code[this.programCounter-1]," pointer: ").concat(this.pointer," value: ").concat(this.array[this.pointer]))}},{key:"prev",value:function(){}},{key:"reachedEnd",get:function(){return this._programCounter===this._code.length}},{key:"lastInstruction",get:function(){return this._code[this._programCounter-1]}},{key:"value",get:function(){return this._array[this._pointer]}},{key:"array",get:function(){return this._array}},{key:"pointer",get:function(){return this._pointer}},{key:"code",get:function(){return this._code}},{key:"programCounter",get:function(){return this._programCounter}}]),t}(),p=["+","-","<",">",".",",","[","]"],f=function(t){return t.split("").filter((function(t){return p.includes(t)})).join("")},O=function(t){var e=t.code,n=t.index,r=e.substr(0,n),i=e.substr(n+1,e.length-n+1);return Object(u.jsxs)("div",{className:"code-display-wrapper",children:[Object(u.jsx)("span",{children:r}),Object(u.jsx)("span",{style:{backgroundColor:"red"},children:e[n]||" "}),Object(u.jsx)("span",{children:i})]})},x=function(t){var e,n=t.interpreter,r=n.pointer;e=r<10?0:r-10;var i=Array(20).fill(0).map((function(t,n){return n+e}));return Object(u.jsx)("div",{children:Object(u.jsxs)("table",{className:"memory-display-table",children:[Object(u.jsx)("thead",{children:Object(u.jsx)("tr",{children:i.map((function(t){return Object(u.jsx)("th",{children:t},t)}))})}),Object(u.jsxs)("tbody",{children:[Object(u.jsx)("tr",{children:i.map((function(t){return Object(u.jsx)("td",{className:"cell",children:n.array[t]},t)}))}),Object(u.jsx)("tr",{children:i.map((function(t){return Object(u.jsx)("td",{className:"pointer",children:n.pointer===t&&"^"},t)}))})]})]})})},v=function(t){var e=t.setRunning,n=t.running,i=t.outHandler,c=t.input,a=Object(r.useState)(0),o=Object(s.a)(a,2),l=o[0],d=o[1],h=Object(r.useState)(null),j=Object(s.a)(h,2),p=j[0],f=j[1],v=Object(r.useState)(null),g=Object(s.a)(v,2),m=g[0],_=g[1],y=Object(r.useState)(0),k=Object(s.a)(y,2)[1],C=Object(r.useRef)(null),S=function(){if(!C.current)throw new Error("Could not read input");var t=C.current.value;if(t.length<1)throw new Error("No input found");var e=t.charCodeAt(0);return C.current.value=t.substr(1),e},I=function(t){return _(t)},N=Object(r.useCallback)((function(){d(0),f(new b(c,i,S,I)),e(!1),e(!0)}),[c,i,e]),w=Object(r.useCallback)((function(){_(null),null===p||void 0===p||p.next(),(null===p||void 0===p?void 0:p.reachedEnd)&&d(0),k((function(t){return t+1}))}),[p]);return Object(r.useEffect)((function(){if(n){if(0===l)return;var t=setInterval((function(){w()}),1e3/l);return function(){return clearInterval(t)}}}),[n,w,l]),Object(u.jsxs)("div",{className:"bf-run",children:[n&&p&&Object(u.jsxs)(u.Fragment,{children:[Object(u.jsx)(O,{code:p.code,index:p.programCounter}),Object(u.jsx)(x,{interpreter:p})]}),Object(u.jsxs)("div",{children:[Object(u.jsx)("button",{onClick:function(){return e(!1)},children:"Back"}),Object(u.jsx)("button",{onClick:N,children:"Start"}),Object(u.jsx)("button",{onClick:w,children:"Next"})]}),n&&Object(u.jsx)(u.Fragment,{children:Object(u.jsxs)("div",{children:[Object(u.jsx)("label",{htmlFor:"run-info-speed-range",children:"Speed"}),Object(u.jsx)("input",{type:"range",id:"run-info-speed-range",value:l,onChange:function(t){return d(+t.target.value)}}),Object(u.jsxs)("span",{children:[" ",l]})]})}),m&&Object(u.jsx)("div",{className:"error",children:m}),n&&Object(u.jsxs)("div",{children:[Object(u.jsx)("div",{children:"Input:"}),Object(u.jsx)("textarea",{className:"program-input-area",ref:C})]})]})};var g=function(){var t=Object(r.useState)(""),e=Object(s.a)(t,2),n=e[0],i=e[1],c=Object(r.useState)(["",{}]),a=Object(s.a)(c,2),o=a[0],h=a[1],j=Object(r.useState)(!1),b=Object(s.a)(j,2),p=b[0],f=b[1],O=Object(r.useCallback)((function(t){i((function(e){return e+String.fromCharCode(t)}))}),[]);return Object(u.jsxs)("div",{className:"App-header",children:[!p&&Object(u.jsx)(l,{code:o[0],setInput:function(t,e){return h([t,e])}}),Object(u.jsx)(v,{running:p,setRunning:function(t){f(t),t||i("")},input:o,outHandler:O}),p&&Object(u.jsx)(d,{text:n})]})};a.a.render(Object(u.jsx)(i.a.StrictMode,{children:Object(u.jsx)(g,{})}),document.getElementById("root"))}},[[15,1,2]]]);
-//# sourceMappingURL=main.cb19c05d.chunk.js.map
\ No newline at end of file
diff --git a/static/js/main.cb19c05d.chunk.js.map b/static/js/main.cb19c05d.chunk.js.map
deleted file mode 100644
index 17f17d5..0000000
--- a/static/js/main.cb19c05d.chunk.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["components/CodeInput.tsx","components/ProgramOutput.tsx","brainfuck/Interpreter.ts","components/CodeDisplay.tsx","components/RunDisplay.tsx","components/Runner.tsx","App.tsx","index.tsx"],"names":["CodeInput","code","setInput","useState","fontSize","setFontSize","codeOptions","setCodeOptions","className","htmlFor","type","id","onChange","v","target","value","checked","minify","e","old","style","placeholder","onClick","ProgramOutput","text","readOnly","Interpreter","input","outHandler","inHandler","errorHandler","_array","_pointer","_code","_programCounter","_inHandler","_outHandler","_errorHandler","buf","ArrayBuffer","this","Uint8Array","level","lastInstruction","undefined","length","console","warn","log","programCounter","pointer","array","CHARS","split","filter","c","includes","join","CodeDisplay","index","firstCodePart","substr","secondCodePart","backgroundColor","RunDisplay","offset","interpreter","MAX_TABLE_COLUMNS","arrayWithIndex","Array","fill","map","_","i","n","Runner","setRunning","running","speed","setSpeed","setInterpreter","error","setError","setRerenderNumber","inputArea","useRef","inputHandler","current","Error","char","charCodeAt","msg","startHandler","useCallback","nextHandler","next","reachedEnd","useEffect","interval","setInterval","clearInterval","ref","App","out","setOut","String","fromCharCode","options","run","ReactDOM","render","StrictMode","document","getElementById"],"mappings":"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","file":"static/js/main.cb19c05d.chunk.js","sourcesContent":["import React, {useState} from 'react';\r\n\r\nexport interface CodeOptions {\r\n minify?: boolean\r\n}\r\n\r\ninterface CodeInputProps {\r\n setInput: ((code: string, options: CodeOptions) => void),\r\n code: string\r\n}\r\n\r\nconst CodeInput = ({code, setInput}: CodeInputProps) => {\r\n const [fontSize, setFontSize] = useState(40);\r\n\r\n const [codeOptions, setCodeOptions] = useState({});\r\n\r\n\r\n const setStart = () => {\r\n setInput(\r\n \"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.\",\r\n codeOptions);\r\n }\r\n\r\n const changeMinify = (e: React.ChangeEvent) => {\r\n setCodeOptions(old => ({...old, minify: e.target.checked}))\r\n setInput(code, codeOptions);\r\n }\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport default CodeInput;","import React from 'react';\r\n\r\ninterface ProgramOutputProps {\r\n text: string\r\n}\r\n\r\nconst ProgramOutput = ({text}: ProgramOutputProps) => {\r\n return (\r\n \r\n
\r\n );\r\n};\r\n\r\nexport default ProgramOutput;","import {CodeOptions} from \"../components/CodeInput\";\r\n\r\ntype InHandler = (() => number);\r\ntype OutHandler = ((char: number) => void);\r\ntype ErrorHandler = ((msg: string) => void);\r\n\r\nexport default class Interpreter {\r\n private readonly _array: Uint8Array;\r\n private _pointer: number;\r\n private readonly _code: string;\r\n private _programCounter: number;\r\n\r\n private readonly _inHandler: InHandler;\r\n private readonly _outHandler: OutHandler;\r\n private readonly _errorHandler: ErrorHandler;\r\n\r\n constructor(input: [string, CodeOptions], outHandler: OutHandler, inHandler: InHandler, errorHandler: ErrorHandler) {\r\n const buf = new ArrayBuffer(32000);\r\n this._array = new Uint8Array(buf);\r\n this._pointer = 0;\r\n\r\n if (input[1].minify) {\r\n this._code = minify(input[0])\r\n } else {\r\n this._code = input[0];\r\n }\r\n\r\n this._programCounter = 0;\r\n this._inHandler = inHandler;\r\n this._outHandler = outHandler;\r\n this._errorHandler = errorHandler;\r\n }\r\n\r\n public next() {\r\n switch (this._code[this._programCounter++]) {\r\n case '+':\r\n this._array[this._pointer]++;\r\n break;\r\n case '-':\r\n this._array[this._pointer]--;\r\n break;\r\n case '>':\r\n this._pointer++;\r\n break;\r\n case '<':\r\n if (this._pointer === 0) {\r\n this._errorHandler(\"Cannot wrap left\");\r\n break;\r\n }\r\n this._pointer--;\r\n break;\r\n case '.':\r\n this._outHandler(this.value);\r\n break;\r\n case ',':\r\n try {\r\n this._array[this._pointer] = this._inHandler();\r\n } catch {\r\n this._programCounter--;\r\n this._errorHandler(\"Could not read input, trying again next time.\")\r\n }\r\n break;\r\n case '[':\r\n if (this.value === 0) {\r\n let level = 0;\r\n while (this.lastInstruction !== ']' || level > -1) {\r\n this._programCounter++;\r\n if (this.lastInstruction === '[') level++;\r\n else if (this.lastInstruction === ']') level--;\r\n }\r\n }\r\n break;\r\n case ']':\r\n if (this.value !== 0) {\r\n let level = 0;\r\n while (this.lastInstruction !== '[' || level > -1) {\r\n this._programCounter--;\r\n if (this.lastInstruction === '[') level--;\r\n else if (this.lastInstruction === ']') level++;\r\n }\r\n }\r\n break;\r\n case undefined:\r\n this._pointer = this._code.length;\r\n console.warn(\"reached end\");\r\n break;\r\n default: {\r\n }\r\n }\r\n console.log(`char: ${this.code[this.programCounter - 1]} pointer: ${this.pointer} value: ${this.array[this.pointer]}`)\r\n }\r\n\r\n public prev() {\r\n\r\n }\r\n\r\n get reachedEnd(): boolean {\r\n return this._programCounter === this._code.length;\r\n }\r\n\r\n get lastInstruction(): string {\r\n return this._code[this._programCounter - 1];\r\n }\r\n\r\n get value(): number {\r\n return this._array[this._pointer];\r\n }\r\n\r\n get array(): Uint8Array {\r\n return this._array;\r\n }\r\n\r\n get pointer(): number {\r\n return this._pointer;\r\n }\r\n\r\n get code(): string {\r\n return this._code;\r\n }\r\n\r\n get programCounter(): number {\r\n return this._programCounter;\r\n }\r\n}\r\n\r\nconst CHARS = ['+', '-', '<', '>', '.', ',', '[', ']'];\r\nconst minify = (code: string): string =>\r\n code.split(\"\")\r\n .filter(c => CHARS.includes(c))\r\n .join(\"\");\r\n\r\n","import React from 'react';\r\n\r\ninterface CodeDisplayProps {\r\n code: string,\r\n index: number,\r\n}\r\n\r\nconst CodeDisplay = ({code, index}: CodeDisplayProps) => {\r\n\r\n const firstCodePart = code.substr(0, index);\r\n const secondCodePart = code.substr(index + 1, code.length - index + 1);\r\n\r\n return (\r\n \r\n {firstCodePart}\r\n {code[index] || \" \"}\r\n {secondCodePart}\r\n
\r\n );\r\n};\r\n\r\nexport default CodeDisplay;","import React from 'react';\r\nimport Interpreter from \"../brainfuck/Interpreter\";\r\n\r\nconst MAX_TABLE_COLUMNS = 20;\r\n\r\ninterface RunDisplayProps {\r\n interpreter: Interpreter,\r\n}\r\n\r\nconst RunDisplay = ({interpreter}: RunDisplayProps) => {\r\n\r\n const index = interpreter.pointer;\r\n\r\n let offset: number;\r\n\r\n if (index < MAX_TABLE_COLUMNS / 2) {\r\n offset = 0;\r\n } else {\r\n offset = index - MAX_TABLE_COLUMNS / 2;\r\n }\r\n\r\n const arrayWithIndex = Array(MAX_TABLE_COLUMNS).fill(0)\r\n .map((_, i) => i + offset);\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n {\r\n arrayWithIndex.map((n => | {n} | ))\r\n }\r\n
\r\n \r\n \r\n \r\n {\r\n arrayWithIndex.map((n) => | {interpreter.array[n]} | )\r\n }\r\n
\r\n \r\n {\r\n arrayWithIndex.map((n) => | {interpreter.pointer === n && \"^\"} | )\r\n }\r\n
\r\n \r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default RunDisplay;","import React, {useCallback, useEffect, useRef, useState} from 'react';\r\nimport Interpreter from \"../brainfuck/Interpreter\";\r\nimport CodeDisplay from \"./CodeDisplay\";\r\nimport RunDisplay from \"./RunDisplay\";\r\nimport {CodeOptions} from \"./CodeInput\";\r\n\r\ninterface RunInfoProps {\r\n input: [string, CodeOptions],\r\n setRunning: (running: boolean) => void,\r\n running: boolean\r\n outHandler: (char: number) => void,\r\n}\r\n\r\nconst Runner = ({setRunning, running, outHandler, input}: RunInfoProps) => {\r\n const [speed, setSpeed] = useState(0);\r\n const [interpreter, setInterpreter] = useState(null);\r\n const [error, setError] = useState(null);\r\n\r\n const [, setRerenderNumber] = useState(0);\r\n\r\n const inputArea = useRef(null);\r\n\r\n\r\n const inputHandler = () => {\r\n if (!inputArea.current) {\r\n throw new Error(\"Could not read input\")\r\n }\r\n const value = inputArea.current.value;\r\n if (value.length < 1) {\r\n throw new Error(\"No input found\");\r\n }\r\n const char = value.charCodeAt(0);\r\n inputArea.current.value = value.substr(1);\r\n return char;\r\n }\r\n\r\n const errorHandler = (msg: string) => setError(msg);\r\n\r\n const startHandler = useCallback(() => {\r\n setSpeed(0);\r\n setInterpreter(new Interpreter(input, outHandler, inputHandler, errorHandler));\r\n setRunning(false);\r\n setRunning(true);\r\n }, [input, outHandler, setRunning]);\r\n\r\n const stopHandler = () => setRunning(false);\r\n\r\n const nextHandler = useCallback(() => {\r\n setError(null);\r\n interpreter?.next();\r\n if (interpreter?.reachedEnd) {\r\n setSpeed(0);\r\n }\r\n setRerenderNumber(n => n + 1);\r\n }, [interpreter]);\r\n\r\n useEffect(() => {\r\n if (running) {\r\n if (speed === 0) {\r\n return;\r\n }\r\n const interval = setInterval(() => {\r\n nextHandler();\r\n }, 1000 / (speed));\r\n\r\n return () => clearInterval(interval);\r\n }\r\n }, [running, nextHandler, speed]);\r\n\r\n\r\n return (\r\n \r\n {\r\n running && interpreter && <>\r\n
\r\n \r\n >\r\n }\r\n \r\n \r\n \r\n \r\n
\r\n {\r\n running && <>\r\n \r\n \r\n setSpeed(+e.target.value)}/>\r\n {speed}\r\n
\r\n >\r\n }\r\n {\r\n error && {error}
\r\n }\r\n {\r\n running && \r\n }\r\n \r\n );\r\n};\r\n\r\nexport default Runner;","import './App.scss';\nimport CodeInput, {CodeOptions} from \"./components/CodeInput\";\nimport ProgramOutput from \"./components/ProgramOutput\";\nimport React, {useCallback, useState} from \"react\";\nimport Runner from \"./components/Runner\";\n\nfunction App() {\n const [out, setOut] = useState(\"\");\n const [input, setInput] = useState<[string, CodeOptions]>([\"\", {}]);\n const [running, setRunning] = useState(false);\n\n const outHandler = useCallback((char: number) => {\n setOut(out => out + String.fromCharCode(char))\n }, []);\n\n const runHandler = (run: boolean) => {\n setRunning(run);\n if (!run) {\n setOut(\"\");\n }\n }\n\n const inputHandler = (code: string, options: CodeOptions) => setInput([code, options]);\n\n return (\n \n {\n !running &&
\n }\n \n {\n running && \n }\n \n );\n}\n\nexport default App;","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);"],"sourceRoot":""}
\ No newline at end of file