potatOS/copy-cat/main.js

20 lines
25 KiB
JavaScript
Raw Permalink Normal View History

2023-11-12 14:57:16 +00:00
/**
* copy-cat: Copyright SquidDev 2023
*
*
* @license
*/define(["require","./persist-7dd7de50"],function(e,t){"use strict";var o;let i=()=>t.__awaiter(void 0,void 0,void 0,function*(){return new(yield new Promise((t,o)=>e(["./jszip.min-7c1798d8"],t,o))).default}),r="_812j-G_iconFont "+t.iconFont,n="_812j-G_actionButton "+t.actionButton,s="_812j-G_tinyText",a="_812j-G_active",l="_812j-G_dialogueBox";t.styleInject('html{--color-dark-1:#1e1e1e;--color-dark-2:#202020;--color-dark-3:#292929;--color-dark-4:#3b3b3b;--color-dark-5:#555;--color-light-1:#fff;--color-light-2:#eee;--color-light-3:#e7e7e7;--color-light-4:#ddd;--color-light-5:#ccc;--color-yellow-1:#dede6c}._812j-G_lightTheme{--text-color:var(--color-dark-2);--text-accent:var(--color-dark-4);--bg-color:var(--color-light-1);--bg-file-tree:var(--color-light-2);--bg-file-tree-item:var(--color-light-3);--bg-file-tree-item-highlight:var(--color-light-4);--bg-file-tree-item-highlight-active:var(--color-light-5);--link-color:#03c5c5;--bg-dialogue:var(--color-light-1);--bg-input:var(--color-light-4);--bg-code-block:var(--color-light-5);--bg-button:var(--color-dark-1)}._812j-G_darkTheme{--text-color:var(--color-light-2);--text-accent:var(--color-light-4);--bg-color:var(--color-dark-1);--bg-file-tree:var(--color-dark-2);--bg-file-tree-item:var(--color-dark-3);--bg-file-tree-item-highlight:var(--color-dark-4);--bg-file-tree-item-highlight-active:var(--color-dark-5);--link-color:var(--color-yellow-1);--bg-dialogue:var(--color-dark-2);--bg-input:var(--color-dark-5);--bg-code-block:var(--color-dark-5);--bg-button:var(--color-light-1)}@media (prefers-color-scheme:dark){body._812j-G_lightTheme{--text-color:var(--color-light-2);--text-accent:var(--color-light-4);--bg-color:var(--color-dark-1);--bg-file-tree:var(--color-dark-2);--bg-file-tree-item:var(--color-dark-3);--bg-file-tree-item-highlight:var(--color-dark-4);--bg-file-tree-item-highlight-active:var(--color-dark-5);--link-color:var(--color-yellow-1);--bg-dialogue:var(--color-dark-2);--bg-input:var(--color-dark-5);--bg-button:var(--color-dark-1)}}._812j-G_actionButton{}._812j-G_iconFont{fill:var(--bg-button);}._812j-G_infoDescription{padding:5px 10px}._812j-G_tinyText{color:var(--text-accent);font-size:.8em;font-weight:300}._812j-G_errorView{color:#670000;background-color:#ffb6b6}._812j-G_termLine:before{content:"> "}._812j-G_computerView{height:100%}._812j-G_computerSplit{flex-wrap:nowrap;justify-content:space-between;height:100%;display:flex}._812j-G_terminalView,._812j-G_editorView{background:var(--bg-color);color:var(--text-color);flex-grow:1;flex-shrink:1;overflow:hidden}._812j-G_fileList{background-color:var(--bg-file-tree);color:var(--text-color);scrollbar-width:thin;flex-basis:200px;max-width:200px;font-size:.8em;line-height:1.4em;position:relative;overflow-y:auto}._812j-G_fileTree{margin:0;padding:0;list-style:none}._812j-G_fileEntryHead{cursor:pointer;background-color:var(--bg-file-tree-item);padding:5px 15px}._812j-G_fileComputerControl{background-color:var(--bg-file-tree-item);color:var(--text-color);position:relative}._812j-G_fileComputer{cursor:pointer;background-color:var(--bg-file-tree-item);color:var(--text-color);padding:10px 15px;font-size:1.3em}._812j-G_fileComputerActions{pointer-events:none;justify-content:flex-end;align-items:center;display:flex;position:absolute;inset:0}._812j-G_fileComputerActions ._812j-G_actionButton{pointer-events:all;text-align:center;width:2em;height:2em;margin:5px}._812j-G_fileComputerActions ._812j-G_actionButton:hover{background:#0000001a}._812j-G_fileEntryHead:hover,._812j-G_fileComputer:hover{background:var(--bg-file-tree-item-highlight)}._812j-G_fileEntryHead._812j-G_active,._812j-G_fileComputer._812j-G_active,._812j-G_fileEntryHead._812j-G_active:hover,._812j-G_fileComputer._812j-G_active:hover{background:var(--bg-file-tree-item-highlight-active)}._812j-G_fileEntryName{text-overflow:ellipsis;overflow:hidden}._812j-G_fileEntryIcon{width:1em;padding:0 5px;display:inline-block}._812j-G_fileDropMarker{display:none}._812j-G_fileList._812j-G_dragging ._812j-G_fileDropMarker{pointer-events:none;background:#00000080;flex-direction:colum
fs.delete("startup.lua")
local fn, err = load("${t}", "@startup.lua", nil, _ENV)
if not fn then error(err, 0) end
fn()`)}}this.setState({terminal:r,terminalChanged:n,computer:s,activeFile:null,openFiles:new Map,id:0,on:!1,label:s.getLabel(),dragging:!1})}componentDidMount(){this.state.computer.start(this.props.computerSettings)}componentWillUnmount(){for(let[e,{model:t,monitor:o}]of(this.state.computer.shutdown(),this.state.openFiles))t.resolved&&t.text.dispose(),e.getSemaphore().detach(o)}shouldComponentUpdate({focused:e,settings:t},{id:o,label:i,on:r,activeFile:n,dragging:s}){return e!==this.props.focused||t!==this.props.settings||o!==this.state.id||i!==this.state.label||r!==this.state.on||n!==this.state.activeFile||s!==this.state.dragging}render({settings:e,focused:o},{terminal:i,terminalChanged:r,computer:s,activeFile:l,id:d,label:c,on:h,dragging:u}){return t.y("div",{class:"_812j-G_computerView"},t.y("div",{class:"_812j-G_computerSplit"},t.y("div",{class:`_812j-G_fileList ${u?"_812j-G_dragging":""}`,onDragOver:this.startDrag,onDragLeave:this.stopDrag,onDrop:this.dropFile},t.y("div",{class:"_812j-G_fileComputerControl"},t.y("div",{class:`_812j-G_fileComputer ${null==l?a:""}`,onClick:this.openComputer},d?`Computer #${d}`:"Computer"),t.y("div",{class:"_812j-G_fileComputerActions"},t.y("button",{class:n,type:"button",onClick:this.saveZip,title:"Download all files as a zip"},t.y(p,null)))),t.y(G,{computer:s,entry:s.getEntry(""),path:"",opened:null===l?null:l.path,open:this.openFile}),t.y("div",{class:"_812j-G_fileDropMarker"},t.y("span",null,"Upload to your computer!"))),null==l?t.y("div",{class:"_812j-G_terminalView"},t.y(t.Terminal,{terminal:i,changed:r,focused:o,computer:s,font:e.terminalFont,id:d,label:c,on:h})):t.y(k,{model:l.model,settings:e,focused:o,doSave:e=>l.file.setContents(e)})))}addOneFile(e,t){let o=e.lastIndexOf("."),i=o>0?e.substring(0,o):e,r=o>0?e.substring(o):"",n=this.state.computer;for(let o=0;o<100;o++){let s=0===o?e:`${i}.${o}${r}`;if(n.getEntry(s))continue;let a=this.state.computer.createFile(s);if(a.value){a.value.setContents(t);return}}console.warn(`Cannot write contents of ${e}.`)}addFile(e){if(e.name.endsWith(".zip"))i().then(o=>t.__awaiter(this,void 0,void 0,function*(){let t;yield o.loadAsync(e);let i=this.state.computer,r=e.name.substring(0,e.name.length-4);for(let e=0;e<100;e++){if(t=0===e?r:`${r}.${e}`,i.getEntry(t))continue;let o=this.state.computer.createDirectory(t);if(o.value)break}let n=q(o,r)?r.length+1:0;for(let e in o.files){if(!Object.prototype.hasOwnProperty.call(o.files,e)||e.length===n)continue;let r=`${t}/${e.substr(n)}`,s=o.files[e];s.dir?(r.endsWith("/")&&(r=r.substring(0,r.length-1)),i.createDirectory(r)||console.warn(`Cannot create directory ${r}.`)):this.addOneFile(r,(yield s.async("arraybuffer")))}})).catch(e=>console.error(e));else{let t=new FileReader;t.onload=()=>this.addOneFile(e.name,t.result),t.readAsArrayBuffer(e)}}}t.y("div",{class:"_812j-G_infoDescription"},t.y("p",null,"Think you've found a bug? Have a suggestion? Why not put it on ",t.y("a",{href:"https://github.com/SquidDev-CC/copy-cat",title:"The GitHub repository"},"the GitHub repo"),"?"));let F=()=>t.y("div",{class:l},t.y("h2",null,"About"),t.y("p",null,"Copy Cat is a web emulator for the popular Minecraft mod ",t.y("a",{href:"https://github.com/cc-tweaked/CC-Tweaked",target:"_blank",title:"CC: Tweaked's source code"},"CC: Tweaked")," (based on ComputerCraft by Dan200). Here you can play with a ComputerCraft computer, write and test programs and experiment to your heart's desire, without having to leave your browser!"),t.y("p",null,"However, due to the limitations of Javascript, some functionality may not be 100% accurate (most notably, that to do with HTTP and filesystems). For even closer emulation, I'd recommend ",t.y("a",{href:"https://emux.cc/",target:"_blank",title:"The CCEmuX emulator"},"CCEmuX"),"."),t.y("p",null,"If you need help writing a program, I'd recommend checking out the ",t.y("a",{href:"https://forums.computercraft.cc/",target:"_blank",title:"The CC: Tweaked forums"},"forums")," or ",t.y("a",{href:"https://discord.computercraft.cc",title:"The Minecraft Computer Mods Discord",target:"_blank"},"Disco
This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
This product includes software developed by Joda.org (http://www.joda.org/).`));class D{constructor(){this.data={};let e=t.get("settings");if(null!==e)try{this.data=JSON.parse(e)}catch(e){console.error("Cannot read settings",e)}}get(e){return e.id in this.data?this.data[e.id]:e.def}set(e,o){this.get(e)!==o&&(this.data[e.id]=o,e.changed(o),t.set("settings",JSON.stringify(this.data)))}}class T{constructor(e,t,o){this.properties=[],this.name=e,this.description=t,this.store=o}add(e){this.properties.push(e);let t=this.store.get(e);return t!==e.def&&e.changed(t),e}addString(e,t,o,i,r){return this.add({type:"string",id:e,name:t,description:i,def:o,changed:r})}addBoolean(e,t,o,i,r){return this.add({type:"boolean",id:e,name:t,description:i,def:o,changed:r})}addOption(e,t,o,i,r,n){return this.add({type:"option",id:e,name:t,description:r,choices:i,def:o,changed:n})}addInt(e,t,o,i,r,n,s){return this.add({type:"int",id:e,name:t,description:n,def:o,min:i,max:r,changed:s})}}function z(e,t,o){return i=>{let r=o(i.target);void 0!==r&&e.set(t,r)}}let M=e=>e.value,O=e=>{let t=parseInt(e.value,10);return Number.isNaN(t)?void 0:t},E=e=>e.checked,A=(e,t)=>o=>{for(let{key:e}of t)if(e===o.value)return e;return e},B=({store:e,configGroups:o})=>t.y("div",{class:l},t.y("h2",null,"Settings"),o.map(({name:o,description:i,properties:r})=>[t.y("h3",null,o),i?t.y("p",{class:s},i):null,t.y("div",{class:"_812j-G_formGroup"},r.map(o=>{switch(o.type){case"string":return t.y("label",null,o.name,t.y("input",{type:"text",value:e.get(o),onChange:z(e,o,M)}),t.y("p",{class:s},o.description));case"int":return t.y("label",null,o.name,t.y("input",{type:"number",value:e.get(o),min:o.min,max:o.max,step:1,onChange:z(e,o,O)}),t.y("p",{class:s},o.description));case"boolean":return t.y("label",null,t.y("input",{type:"checkbox",checked:e.get(o),onInput:z(e,o,E)}),o.name,t.y("p",{class:s},o.description));case"option":return t.y("label",null,o.name,t.y("select",{value:e.get(o),onInput:z(e,o,A(o.def,o.choices))},o.choices.map(({key:e,value:o})=>t.y("option",{value:e},o))),t.y("p",{class:s},o.description))}}))])),I=(...e)=>e.filter(e=>!!e).join(" ");class V extends t.b{constructor(e,o){super(e,o),this.openSettings=()=>{this.setState({dialogue:({settingStorage:e,configGroups:o})=>t.y(B,{store:e,configGroups:o})})},this.closeDialogueClick=e=>{e.target===e.currentTarget&&this.setState({dialogue:void 0})},this.computerVDom=({settings:e,dialogue:o})=>t.y(S,{settings:e,focused:void 0===o,computerSettings:this.configFactory}),this.configFactory=(e,t)=>{let o=this.state.configGroups.find(t=>t.name===e);if(o)return o.description!==t&&console.warn(`Different descriptions for ${e} ("${t}" and "${o.description}")`),o;let i=new T(e,t,this.state.settingStorage);return this.setState(e=>({configGroups:[...e.configGroups,i]})),i}}componentWillMount(){let e=new D,o=new T("Editor","Configure the built-in editor",e),i=new T("Terminal","Configure the terminal display",e),r={settingStorage:e,configGroups:[o,i],settings:{showInvisible:!0,trimWhitespace:!0,darkMode:!1,terminalFont:t.termFont},currentVDom:this.computerVDom};this.setState(r),o.addBoolean("editor.invisible","Show invisible",r.settings.showInvisible,"Show invisible characters, such as spaces and tabs.",e=>this.setState(t=>({settings:Object.assign(Object.assign({},t.settings),{showInvisible:e})}))),o.addBoolean("editor.trim_whitespace","Trim whitespace",r.settings.trimWhitespace,"Trim whitespace from files when saving.",e=>this.setState(t=>({settings:Object.assign(Object.assign({},t.settings),{trimWhitespace:e})}))),o.addBoolean("editor.dark","Dark mode",r.settings.darkMode,"Enables dark mode.",e=>{this.setState(t=>({settings:Object.assign(Object.assign({},t.settings),{darkMode:e})}))});let n={standard:t.termFont,hd:t.termFontHd,[t.termFontHd]:t.termFontHd,"term_font_hd.png":t.termFontHd,[t.termFont]:t.termFont,"term_font.png":t.termFont};i.addOption("terminal.font","Font","standard",[{key:"standard",value:"Standard font"},{key:"hd",value:"High-definition font"}],"Which font the we should use within the terminal",e=>this.setState(o=>({s
self.MonacoEnvironment = {
baseUrl: "https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/"
};
importScripts("https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/vs/base/worker/workerMain.js");
`)}`};let e=document.getElementById("page");t.B(t.y(V,null),e,null!==(o=e.lastElementChild)&&void 0!==o?o:void 0)}});