From b0b062a2b052f6350facee24779de71408729ee8 Mon Sep 17 00:00:00 2001 From: kaylee Date: Fri, 15 Dec 2023 19:43:36 +0000 Subject: [PATCH] initial spaghetti code --- WORKING_SETUP.json | 1 + build/.DS_Store | Bin 0 -> 6148 bytes build/._.DS_Store | Bin 0 -> 4096 bytes build/alu/full/index.html | 66 ++ build/alu/index.html | 42 + build/css/._ibm.woff | Bin 0 -> 4096 bytes build/css/ibm.woff | Bin 0 -> 9788 bytes build/css/style.css | 104 ++ build/editor/.DS_Store | Bin 0 -> 6148 bytes build/editor/._.DS_Store | Bin 0 -> 4096 bytes build/editor/css/style.css | 15 + build/editor/img/.DS_Store | Bin 0 -> 6148 bytes build/editor/img/._.DS_Store | Bin 0 -> 4096 bytes build/editor/img/gates copy/and.png | Bin 0 -> 5873 bytes build/editor/img/gates copy/nand.png | Bin 0 -> 7289 bytes build/editor/img/gates copy/nor.png | Bin 0 -> 7742 bytes build/editor/img/gates copy/not.png | Bin 0 -> 4273 bytes build/editor/img/gates copy/or.png | Bin 0 -> 6725 bytes build/editor/img/gates copy/xnor.png | Bin 0 -> 8349 bytes build/editor/img/gates copy/xor.png | Bin 0 -> 7729 bytes build/editor/img/gates/._and.png | Bin 0 -> 4096 bytes build/editor/img/gates/._nand.png | Bin 0 -> 4096 bytes build/editor/img/gates/._nor.png | Bin 0 -> 4096 bytes build/editor/img/gates/._not.png | Bin 0 -> 4096 bytes build/editor/img/gates/._or.png | Bin 0 -> 4096 bytes build/editor/img/gates/._xnor.png | Bin 0 -> 4096 bytes build/editor/img/gates/._xor.png | Bin 0 -> 4096 bytes build/editor/img/gates/and.png | Bin 0 -> 2063 bytes build/editor/img/gates/nand.png | Bin 0 -> 2634 bytes build/editor/img/gates/nor.png | Bin 0 -> 3678 bytes build/editor/img/gates/not.png | Bin 0 -> 2628 bytes build/editor/img/gates/or.png | Bin 0 -> 3887 bytes build/editor/img/gates/xnor.png | Bin 0 -> 6970 bytes build/editor/img/gates/xor.png | Bin 0 -> 3843 bytes build/editor/index.php | 22 + build/editor/js/bk/chips.js | 187 ++++ build/editor/js/bk/components.js | 205 ++++ build/editor/js/bk/index.js | 229 ++++ build/editor/js/chips.js | 188 ++++ build/editor/js/chips_old.js | 188 ++++ build/editor/js/components.js | 177 +++ build/editor/js/index.js | 425 ++++++++ build/editor/js/items/CPU_ALU.js | 10 + build/editor/js/items/CPU_MUX.js | 10 + build/editor/js/items/alu.js | 6 + build/editor/js/items/alu1.js | 5 + build/editor/js/items/alu10.js | 5 + build/editor/js/items/alu11.js | 5 + build/editor/js/items/alu2.js | 5 + build/editor/js/items/alu3.js | 5 + build/editor/js/items/alu4.js | 5 + build/editor/js/items/alu5.js | 5 + build/editor/js/items/alu6.js | 5 + build/editor/js/items/alu7.js | 5 + build/editor/js/items/alu8.5.js | 5 + build/editor/js/items/alu8.js | 5 + build/editor/js/items/alu9.js | 5 + build/editor/js/items/md5.js | 0 build/editor/js/items/mux1.js | 5 + build/editor/js/items/mux2.js | 5 + build/editor/js/items/mux3.js | 5 + build/editor/js/items/mux4.js | 5 + build/editor/js/layouts/21mux.js | 6 + build/editor/js/layouts/84mux.js | 7 + build/editor/js/layouts/addsub.js | 7 + build/editor/js/layouts/alu.js | 7 + build/editor/js/layouts/and.js | 6 + build/editor/js/layouts/challenge1.js | 6 + build/editor/js/layouts/fourpin.js | 6 + build/editor/js/layouts/fulladder.js | 8 + build/editor/js/layouts/not.js | 6 + build/editor/js/layouts/or.js | 6 + build/editor/js/layouts/rca.js | 7 + build/editor/js/layouts/sub.js | 7 + build/editor/js/layouts/xor.js | 6 + build/editor/js/md5.js | 171 +++ build/editor/js/test.c | 3 + build/img/._flags_diagram.png | Bin 0 -> 4096 bytes build/img/._flags_diagram.psd | Bin 0 -> 4096 bytes build/img/flags_diagram.png | Bin 0 -> 40129 bytes build/img/flags_diagram.psd | Bin 0 -> 431039 bytes build/js/page.js | 20 + build/multiplexer/index.html | 28 + build/registers/index.html | 23 + cheat/index.html | 3 + css/generator_config.txt | 5 + css/specimen_files/grid_12-825-55-15.css | 129 +++ css/specimen_files/specimen_stylesheet.css | 396 +++++++ css/style.css | 87 ++ css/stylesheet.css | 12 + css/vcr_osd_mono_1.001-demo.html | 602 +++++++++++ css/vcr_osd_mono_1.001-webfont.woff | Bin 0 -> 19632 bytes css/vcr_osd_mono_1.001-webfont.woff2 | Bin 0 -> 15040 bytes css/webfontkit-20220220-160412.zip | Bin 0 -> 47572 bytes img/pencil.png | Bin 0 -> 5563 bytes img/question.png | Bin 0 -> 5651 bytes index.html | 97 ++ js/assembler copy.js | 294 +++++ js/assembler.js | 294 +++++ js/index.js | 1129 ++++++++++++++++++++ js/index_mod.js | 1129 ++++++++++++++++++++ js/index_old.js | 1112 +++++++++++++++++++ js/opcodes.js | 152 +++ readme.md | 0 simulator/asm.html | 5 + simulator/assembler.js | 283 +++++ simulator/opcodes.js | 163 +++ simulator/opcodes.json | 134 +++ simulator/sim.js | 188 ++++ uncheat/index.html | 1 + 110 files changed, 8500 insertions(+) create mode 100755 WORKING_SETUP.json create mode 100755 build/.DS_Store create mode 100755 build/._.DS_Store create mode 100755 build/alu/full/index.html create mode 100755 build/alu/index.html create mode 100755 build/css/._ibm.woff create mode 100755 build/css/ibm.woff create mode 100755 build/css/style.css create mode 100755 build/editor/.DS_Store create mode 100755 build/editor/._.DS_Store create mode 100755 build/editor/css/style.css create mode 100755 build/editor/img/.DS_Store create mode 100755 build/editor/img/._.DS_Store create mode 100755 build/editor/img/gates copy/and.png create mode 100755 build/editor/img/gates copy/nand.png create mode 100755 build/editor/img/gates copy/nor.png create mode 100755 build/editor/img/gates copy/not.png create mode 100755 build/editor/img/gates copy/or.png create mode 100755 build/editor/img/gates copy/xnor.png create mode 100755 build/editor/img/gates copy/xor.png create mode 100755 build/editor/img/gates/._and.png create mode 100755 build/editor/img/gates/._nand.png create mode 100755 build/editor/img/gates/._nor.png create mode 100755 build/editor/img/gates/._not.png create mode 100755 build/editor/img/gates/._or.png create mode 100755 build/editor/img/gates/._xnor.png create mode 100755 build/editor/img/gates/._xor.png create mode 100755 build/editor/img/gates/and.png create mode 100755 build/editor/img/gates/nand.png create mode 100755 build/editor/img/gates/nor.png create mode 100755 build/editor/img/gates/not.png create mode 100755 build/editor/img/gates/or.png create mode 100755 build/editor/img/gates/xnor.png create mode 100755 build/editor/img/gates/xor.png create mode 100755 build/editor/index.php create mode 100755 build/editor/js/bk/chips.js create mode 100755 build/editor/js/bk/components.js create mode 100755 build/editor/js/bk/index.js create mode 100755 build/editor/js/chips.js create mode 100755 build/editor/js/chips_old.js create mode 100755 build/editor/js/components.js create mode 100755 build/editor/js/index.js create mode 100755 build/editor/js/items/CPU_ALU.js create mode 100755 build/editor/js/items/CPU_MUX.js create mode 100755 build/editor/js/items/alu.js create mode 100755 build/editor/js/items/alu1.js create mode 100755 build/editor/js/items/alu10.js create mode 100755 build/editor/js/items/alu11.js create mode 100755 build/editor/js/items/alu2.js create mode 100755 build/editor/js/items/alu3.js create mode 100755 build/editor/js/items/alu4.js create mode 100755 build/editor/js/items/alu5.js create mode 100755 build/editor/js/items/alu6.js create mode 100755 build/editor/js/items/alu7.js create mode 100755 build/editor/js/items/alu8.5.js create mode 100755 build/editor/js/items/alu8.js create mode 100755 build/editor/js/items/alu9.js create mode 100755 build/editor/js/items/md5.js create mode 100755 build/editor/js/items/mux1.js create mode 100755 build/editor/js/items/mux2.js create mode 100755 build/editor/js/items/mux3.js create mode 100755 build/editor/js/items/mux4.js create mode 100755 build/editor/js/layouts/21mux.js create mode 100755 build/editor/js/layouts/84mux.js create mode 100755 build/editor/js/layouts/addsub.js create mode 100755 build/editor/js/layouts/alu.js create mode 100755 build/editor/js/layouts/and.js create mode 100755 build/editor/js/layouts/challenge1.js create mode 100755 build/editor/js/layouts/fourpin.js create mode 100755 build/editor/js/layouts/fulladder.js create mode 100755 build/editor/js/layouts/not.js create mode 100755 build/editor/js/layouts/or.js create mode 100755 build/editor/js/layouts/rca.js create mode 100755 build/editor/js/layouts/sub.js create mode 100755 build/editor/js/layouts/xor.js create mode 100755 build/editor/js/md5.js create mode 100755 build/editor/js/test.c create mode 100755 build/img/._flags_diagram.png create mode 100755 build/img/._flags_diagram.psd create mode 100755 build/img/flags_diagram.png create mode 100755 build/img/flags_diagram.psd create mode 100755 build/js/page.js create mode 100755 build/multiplexer/index.html create mode 100755 build/registers/index.html create mode 100755 cheat/index.html create mode 100755 css/generator_config.txt create mode 100755 css/specimen_files/grid_12-825-55-15.css create mode 100755 css/specimen_files/specimen_stylesheet.css create mode 100755 css/style.css create mode 100755 css/stylesheet.css create mode 100755 css/vcr_osd_mono_1.001-demo.html create mode 100755 css/vcr_osd_mono_1.001-webfont.woff create mode 100755 css/vcr_osd_mono_1.001-webfont.woff2 create mode 100755 css/webfontkit-20220220-160412.zip create mode 100755 img/pencil.png create mode 100755 img/question.png create mode 100755 index.html create mode 100755 js/assembler copy.js create mode 100755 js/assembler.js create mode 100755 js/index.js create mode 100644 js/index_mod.js create mode 100644 js/index_old.js create mode 100755 js/opcodes.js create mode 100644 readme.md create mode 100755 simulator/asm.html create mode 100755 simulator/assembler.js create mode 100755 simulator/opcodes.js create mode 100755 simulator/opcodes.json create mode 100755 simulator/sim.js create mode 100755 uncheat/index.html diff --git a/WORKING_SETUP.json b/WORKING_SETUP.json new file mode 100755 index 0000000..d8899f2 --- /dev/null +++ b/WORKING_SETUP.json @@ -0,0 +1 @@ +{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"half adder":{"type":"half adder","groups":[[0],[1],[2],[3]],"inputs":2,"tooltips":["A","B","sum","carry"],"pins":[0,0,0,0],"subComponents":["and","xor"],"positions":[{"x":336,"y":269},{"x":556,"y":482}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2},"wireId":4},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":5},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":6},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":7}]},"full adder":{"type":"full adder","groups":[[0],[1],[2],[3],[4]],"inputs":3,"tooltips":["A","B","carry in","sum","carry out"],"pins":[0,0,0,0,0],"subComponents":["half adder","half adder","or"],"positions":[{"x":337,"y":330},{"x":804,"y":440},{"x":1159,"y":673}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":4},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0},"wireId":5},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":3},"wireId":6},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":7},{"source":{"component":2,"pin":3},"destination":{"component":3,"pin":0},"wireId":9},{"source":{"component":1,"pin":3},"destination":{"component":3,"pin":1},"wireId":10}]},"8 bit ripple carry adder":{"type":"8 bit ripple carry adder","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[17,18,19,20,21,22,23,24],[25]],"inputs":17,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","carry in","sum","sum","sum","sum","sum","sum","sum","sum","carry out"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["full adder","full adder","full adder","full adder","full adder","full adder","full adder","full adder"],"positions":[{"x":383,"y":351},{"x":352,"y":281},{"x":329,"y":222},{"x":311,"y":155},{"x":476,"y":584},{"x":430,"y":502},{"x":428,"y":423},{"x":301,"y":100}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":8,"pin":0},"wireId":0},{"source":{"component":0,"pin":8},"destination":{"component":8,"pin":1},"wireId":1},{"source":{"component":0,"pin":1},"destination":{"component":4,"pin":0},"wireId":2},{"source":{"component":0,"pin":9},"destination":{"component":4,"pin":1},"wireId":3},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":4},{"source":{"component":0,"pin":10},"destination":{"component":3,"pin":1},"wireId":5},{"source":{"component":0,"pin":3},"destination":{"component":2,"pin":0},"wireId":6},{"source":{"component":0,"pin":11},"destination":{"component":2,"pin":1},"wireId":7},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":0},"wireId":8},{"source":{"component":0,"pin":12},"destination":{"component":1,"pin":1},"wireId":9},{"source":{"component":0,"pin":5},"destination":{"component":7,"pin":0},"wireId":10},{"source":{"component":0,"pin":13},"destination":{"component":7,"pin":1},"wireId":11},{"source":{"component":0,"pin":14},"destination":{"component":6,"pin":1},"wireId":12},{"source":{"component":0,"pin":6},"destination":{"component":6,"pin":0},"wireId":13},{"source":{"component":0,"pin":7},"destination":{"component":5,"pin":0},"wireId":14},{"source":{"component":0,"pin":15},"destination":{"component":5,"pin":1},"wireId":15},{"source":{"component":5,"pin":4},"destination":{"component":0,"pin":25},"wireId":16},{"source":{"component":5,"pin":3},"destination":{"component":0,"pin":24},"wireId":17},{"source":{"component":6,"pin":3},"destination":{"component":0,"pin":23},"wireId":18},{"source":{"component":7,"pin":3},"destination":{"component":0,"pin":22},"wireId":19},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":21},"wireId":20},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":20},"wireId":21},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":19},"wireId":22},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":18},"wireId":23},{"source":{"component":8,"pin":3},"destination":{"component":0,"pin":17},"wireId":24},{"source":{"component":8,"pin":4},"destination":{"component":4,"pin":2},"wireId":25},{"source":{"component":4,"pin":4},"destination":{"component":3,"pin":2},"wireId":26},{"source":{"component":3,"pin":4},"destination":{"component":2,"pin":2},"wireId":27},{"source":{"component":2,"pin":4},"destination":{"component":1,"pin":2},"wireId":28},{"source":{"component":1,"pin":4},"destination":{"component":7,"pin":2},"wireId":29},{"source":{"component":7,"pin":4},"destination":{"component":6,"pin":2},"wireId":30},{"source":{"component":6,"pin":4},"destination":{"component":5,"pin":2},"wireId":31},{"source":{"component":0,"pin":16},"destination":{"component":8,"pin":2},"wireId":32}]},"2-1 mux":{"type":"2-1 mux","groups":[[2]],"inputs":3,"tooltips":["A","B","select","output"],"pins":[0,0,0,0],"subComponents":["not","and","and","or"],"positions":[{"x":272,"y":210},{"x":429,"y":281},{"x":445,"y":66},{"x":611,"y":173}],"wires":[{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":0},"wireId":8},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":9},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":10},{"source":{"component":1,"pin":1},"destination":{"component":3,"pin":1},"wireId":11},{"source":{"component":0,"pin":0},"destination":{"component":3,"pin":0},"wireId":12},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":0},"wireId":13},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":1},"wireId":14},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":3},"wireId":15}]},"16:8 mux":{"type":"16:8 mux","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[17,18,19,20,21,22,23,24]],"inputs":17,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","select","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["2-1 mux","2-1 mux","2-1 mux","2-1 mux","2-1 mux","2-1 mux","2-1 mux","2-1 mux"],"positions":[{"x":428,"y":140},{"x":487,"y":225},{"x":549,"y":295},{"x":603,"y":349},{"x":661,"y":427},{"x":690,"y":504},{"x":763,"y":588},{"x":775,"y":659}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":9},"destination":{"component":2,"pin":1},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":3},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":4},{"source":{"component":0,"pin":10},"destination":{"component":3,"pin":1},"wireId":5},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":6},{"source":{"component":0,"pin":11},"destination":{"component":4,"pin":1},"wireId":7},{"source":{"component":0,"pin":4},"destination":{"component":5,"pin":0},"wireId":8},{"source":{"component":0,"pin":12},"destination":{"component":5,"pin":1},"wireId":9},{"source":{"component":0,"pin":5},"destination":{"component":6,"pin":0},"wireId":10},{"source":{"component":0,"pin":13},"destination":{"component":6,"pin":1},"wireId":11},{"source":{"component":0,"pin":6},"destination":{"component":7,"pin":0},"wireId":12},{"source":{"component":0,"pin":14},"destination":{"component":7,"pin":1},"wireId":13},{"source":{"component":0,"pin":7},"destination":{"component":8,"pin":0},"wireId":14},{"source":{"component":0,"pin":15},"destination":{"component":8,"pin":1},"wireId":15},{"source":{"component":0,"pin":16},"destination":{"component":8,"pin":2},"wireId":16},{"source":{"component":0,"pin":16},"destination":{"component":7,"pin":2},"wireId":17},{"source":{"component":0,"pin":16},"destination":{"component":6,"pin":2},"wireId":18},{"source":{"component":0,"pin":16},"destination":{"component":5,"pin":2},"wireId":19},{"source":{"component":0,"pin":16},"destination":{"component":4,"pin":2},"wireId":20},{"source":{"component":0,"pin":16},"destination":{"component":3,"pin":2},"wireId":21},{"source":{"component":0,"pin":16},"destination":{"component":2,"pin":2},"wireId":22},{"source":{"component":0,"pin":16},"destination":{"component":1,"pin":2},"wireId":23},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":17},"wireId":24},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":18},"wireId":25},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":19},"wireId":26},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":20},"wireId":27},{"source":{"component":5,"pin":3},"destination":{"component":0,"pin":21},"wireId":28},{"source":{"component":6,"pin":3},"destination":{"component":0,"pin":22},"wireId":29},{"source":{"component":7,"pin":3},"destination":{"component":0,"pin":23},"wireId":30},{"source":{"component":8,"pin":3},"destination":{"component":0,"pin":24},"wireId":31}]},"8-bit not":{"type":"8-bit not","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15]],"inputs":8,"tooltips":["input","input","input","input","input","input","input","input","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["not","not","not","not","not","not","not","not"],"positions":[{"x":113,"y":635},{"x":134,"y":545},{"x":175,"y":464},{"x":230,"y":363},{"x":175,"y":137},{"x":169,"y":47},{"x":395,"y":411},{"x":381,"y":192}],"wires":[{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":0},"wireId":1},{"source":{"component":0,"pin":5},"destination":{"component":3,"pin":0},"wireId":2},{"source":{"component":0,"pin":4},"destination":{"component":7,"pin":0},"wireId":3},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":4},{"source":{"component":0,"pin":2},"destination":{"component":8,"pin":0},"wireId":5},{"source":{"component":0,"pin":1},"destination":{"component":5,"pin":0},"wireId":6},{"source":{"component":0,"pin":0},"destination":{"component":6,"pin":0},"wireId":7},{"source":{"component":6,"pin":1},"destination":{"component":0,"pin":8},"wireId":8},{"source":{"component":5,"pin":1},"destination":{"component":0,"pin":9},"wireId":9},{"source":{"component":8,"pin":1},"destination":{"component":0,"pin":10},"wireId":10},{"source":{"component":4,"pin":1},"destination":{"component":0,"pin":11},"wireId":11},{"source":{"component":7,"pin":1},"destination":{"component":0,"pin":12},"wireId":12},{"source":{"component":3,"pin":1},"destination":{"component":0,"pin":13},"wireId":13},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":14},"wireId":14},{"source":{"component":1,"pin":1},"destination":{"component":0,"pin":15},"wireId":15}]},"8-bit subtractor":{"type":"8-bit subtractor","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[17,18,19,20,21,22,23,24],[25]],"inputs":17,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","borrow in","difference","difference","difference","difference","difference","difference","difference","difference","borrow out"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["8 bit ripple carry adder","not","8-bit not","not"],"positions":[{"x":736,"y":333},{"x":251,"y":723},{"x":250,"y":583},{"x":1308,"y":676}],"wires":[{"source":{"component":0,"pin":16},"destination":{"component":2,"pin":0},"wireId":0},{"source":{"component":3,"pin":15},"destination":{"component":1,"pin":15},"wireId":2},{"source":{"component":3,"pin":14},"destination":{"component":1,"pin":14},"wireId":3},{"source":{"component":3,"pin":13},"destination":{"component":1,"pin":13},"wireId":4},{"source":{"component":3,"pin":12},"destination":{"component":1,"pin":12},"wireId":5},{"source":{"component":3,"pin":11},"destination":{"component":1,"pin":11},"wireId":6},{"source":{"component":3,"pin":10},"destination":{"component":1,"pin":10},"wireId":7},{"source":{"component":3,"pin":9},"destination":{"component":1,"pin":9},"wireId":8},{"source":{"component":3,"pin":8},"destination":{"component":1,"pin":8},"wireId":9},{"source":{"component":0,"pin":8},"destination":{"component":3,"pin":0},"wireId":10},{"source":{"component":0,"pin":9},"destination":{"component":3,"pin":1},"wireId":11},{"source":{"component":0,"pin":10},"destination":{"component":3,"pin":2},"wireId":12},{"source":{"component":0,"pin":11},"destination":{"component":3,"pin":3},"wireId":13},{"source":{"component":0,"pin":12},"destination":{"component":3,"pin":4},"wireId":14},{"source":{"component":0,"pin":13},"destination":{"component":3,"pin":5},"wireId":15},{"source":{"component":0,"pin":14},"destination":{"component":3,"pin":6},"wireId":16},{"source":{"component":0,"pin":15},"destination":{"component":3,"pin":7},"wireId":17},{"source":{"component":2,"pin":1},"destination":{"component":1,"pin":16},"wireId":18},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":19},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":20},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":21},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":22},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":23},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":24},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":25},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":26},{"source":{"component":1,"pin":17},"destination":{"component":0,"pin":17},"wireId":27},{"source":{"component":1,"pin":18},"destination":{"component":0,"pin":18},"wireId":28},{"source":{"component":1,"pin":19},"destination":{"component":0,"pin":19},"wireId":29},{"source":{"component":1,"pin":20},"destination":{"component":0,"pin":20},"wireId":30},{"source":{"component":1,"pin":21},"destination":{"component":0,"pin":21},"wireId":31},{"source":{"component":1,"pin":22},"destination":{"component":0,"pin":22},"wireId":32},{"source":{"component":1,"pin":23},"destination":{"component":0,"pin":23},"wireId":33},{"source":{"component":1,"pin":24},"destination":{"component":0,"pin":24},"wireId":34},{"source":{"component":1,"pin":25},"destination":{"component":4,"pin":0},"wireId":35},{"source":{"component":4,"pin":1},"destination":{"component":0,"pin":25},"wireId":36}]},"add/subtract unit":{"type":"add/subtract unit","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[18,19,20,21,22,23,24,25],[26]],"inputs":18,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","carry/borrow in","operation select","result","result","result","result","result","result","result","result","carry/borrow out"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["8-bit subtractor","8 bit ripple carry adder","16:8 mux","2-1 mux"],"positions":[{"x":795,"y":579},{"x":881,"y":165},{"x":1401,"y":247},{"x":1560,"y":700}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":1},{"source":{"component":0,"pin":3},"destination":{"component":2,"pin":3},"wireId":3},{"source":{"component":0,"pin":4},"destination":{"component":2,"pin":4},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":5},"wireId":5},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":6},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":2,"pin":7},"wireId":7},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":2},"wireId":8},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":8},"wireId":9},{"source":{"component":0,"pin":9},"destination":{"component":2,"pin":9},"wireId":10},{"source":{"component":0,"pin":10},"destination":{"component":2,"pin":10},"wireId":11},{"source":{"component":0,"pin":11},"destination":{"component":2,"pin":11},"wireId":12},{"source":{"component":0,"pin":12},"destination":{"component":2,"pin":12},"wireId":13},{"source":{"component":0,"pin":13},"destination":{"component":2,"pin":13},"wireId":14},{"source":{"component":0,"pin":14},"destination":{"component":2,"pin":14},"wireId":15},{"source":{"component":0,"pin":15},"destination":{"component":2,"pin":15},"wireId":16},{"source":{"component":0,"pin":16},"destination":{"component":2,"pin":16},"wireId":17},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":18},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":19},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":20},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":21},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":22},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":23},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":24},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":25},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":8},"wireId":26},{"source":{"component":0,"pin":9},"destination":{"component":1,"pin":9},"wireId":27},{"source":{"component":0,"pin":10},"destination":{"component":1,"pin":10},"wireId":28},{"source":{"component":0,"pin":11},"destination":{"component":1,"pin":11},"wireId":29},{"source":{"component":0,"pin":12},"destination":{"component":1,"pin":12},"wireId":30},{"source":{"component":0,"pin":13},"destination":{"component":1,"pin":13},"wireId":31},{"source":{"component":0,"pin":14},"destination":{"component":1,"pin":14},"wireId":32},{"source":{"component":0,"pin":15},"destination":{"component":1,"pin":15},"wireId":33},{"source":{"component":0,"pin":16},"destination":{"component":1,"pin":16},"wireId":34},{"source":{"component":2,"pin":17},"destination":{"component":3,"pin":0},"wireId":35},{"source":{"component":2,"pin":18},"destination":{"component":3,"pin":1},"wireId":36},{"source":{"component":2,"pin":19},"destination":{"component":3,"pin":2},"wireId":37},{"source":{"component":2,"pin":20},"destination":{"component":3,"pin":3},"wireId":38},{"source":{"component":2,"pin":21},"destination":{"component":3,"pin":4},"wireId":39},{"source":{"component":2,"pin":22},"destination":{"component":3,"pin":5},"wireId":40},{"source":{"component":2,"pin":23},"destination":{"component":3,"pin":6},"wireId":41},{"source":{"component":2,"pin":24},"destination":{"component":3,"pin":7},"wireId":42},{"source":{"component":1,"pin":17},"destination":{"component":3,"pin":8},"wireId":44},{"source":{"component":1,"pin":18},"destination":{"component":3,"pin":9},"wireId":45},{"source":{"component":1,"pin":19},"destination":{"component":3,"pin":10},"wireId":46},{"source":{"component":1,"pin":20},"destination":{"component":3,"pin":11},"wireId":47},{"source":{"component":1,"pin":21},"destination":{"component":3,"pin":12},"wireId":48},{"source":{"component":1,"pin":22},"destination":{"component":3,"pin":13},"wireId":49},{"source":{"component":1,"pin":23},"destination":{"component":3,"pin":14},"wireId":50},{"source":{"component":1,"pin":24},"destination":{"component":3,"pin":15},"wireId":51},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":26},"wireId":52},{"source":{"component":1,"pin":25},"destination":{"component":4,"pin":1},"wireId":53},{"source":{"component":2,"pin":25},"destination":{"component":4,"pin":0},"wireId":54},{"source":{"component":0,"pin":17},"destination":{"component":4,"pin":2},"wireId":56},{"source":{"component":0,"pin":17},"destination":{"component":3,"pin":16},"wireId":57},{"source":{"component":3,"pin":17},"destination":{"component":0,"pin":18},"wireId":58},{"source":{"component":3,"pin":18},"destination":{"component":0,"pin":19},"wireId":59},{"source":{"component":3,"pin":19},"destination":{"component":0,"pin":20},"wireId":60},{"source":{"component":3,"pin":20},"destination":{"component":0,"pin":21},"wireId":61},{"source":{"component":3,"pin":21},"destination":{"component":0,"pin":22},"wireId":62},{"source":{"component":3,"pin":22},"destination":{"component":0,"pin":23},"wireId":63},{"source":{"component":3,"pin":23},"destination":{"component":0,"pin":24},"wireId":64},{"source":{"component":3,"pin":24},"destination":{"component":0,"pin":25},"wireId":65}]},"8-bit nand":{"type":"8-bit nand","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16,17,18,19,20,21,22,23]],"inputs":16,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["8-bit not","and","and","and","and","and","and","and","and"],"positions":[{"x":1390,"y":364},{"x":840,"y":712},{"x":419,"y":313},{"x":388,"y":193},{"x":564,"y":630},{"x":511,"y":515},{"x":476,"y":431},{"x":712,"y":802},{"x":1077,"y":782}],"wires":[{"source":{"component":1,"pin":8},"destination":{"component":0,"pin":16},"wireId":0},{"source":{"component":1,"pin":9},"destination":{"component":0,"pin":17},"wireId":1},{"source":{"component":1,"pin":10},"destination":{"component":0,"pin":18},"wireId":2},{"source":{"component":1,"pin":11},"destination":{"component":0,"pin":19},"wireId":3},{"source":{"component":1,"pin":12},"destination":{"component":0,"pin":20},"wireId":4},{"source":{"component":1,"pin":13},"destination":{"component":0,"pin":21},"wireId":5},{"source":{"component":1,"pin":14},"destination":{"component":0,"pin":22},"wireId":6},{"source":{"component":1,"pin":15},"destination":{"component":0,"pin":23},"wireId":7},{"source":{"component":0,"pin":0},"destination":{"component":4,"pin":0},"wireId":13},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":1},"wireId":14},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":0},"wireId":15},{"source":{"component":0,"pin":9},"destination":{"component":3,"pin":1},"wireId":16},{"source":{"component":0,"pin":2},"destination":{"component":7,"pin":0},"wireId":17},{"source":{"component":0,"pin":10},"destination":{"component":7,"pin":1},"wireId":18},{"source":{"component":4,"pin":2},"destination":{"component":1,"pin":0},"wireId":19},{"source":{"component":3,"pin":2},"destination":{"component":1,"pin":1},"wireId":20},{"source":{"component":7,"pin":2},"destination":{"component":1,"pin":2},"wireId":21},{"source":{"component":0,"pin":11},"destination":{"component":6,"pin":1},"wireId":22},{"source":{"component":0,"pin":3},"destination":{"component":6,"pin":0},"wireId":23},{"source":{"component":6,"pin":2},"destination":{"component":1,"pin":3},"wireId":24},{"source":{"component":5,"pin":2},"destination":{"component":1,"pin":4},"wireId":25},{"source":{"component":0,"pin":4},"destination":{"component":5,"pin":0},"wireId":26},{"source":{"component":0,"pin":12},"destination":{"component":5,"pin":1},"wireId":27},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":0},"wireId":28},{"source":{"component":0,"pin":13},"destination":{"component":2,"pin":1},"wireId":29},{"source":{"component":2,"pin":2},"destination":{"component":1,"pin":5},"wireId":30},{"source":{"component":0,"pin":6},"destination":{"component":8,"pin":0},"wireId":31},{"source":{"component":0,"pin":14},"destination":{"component":8,"pin":1},"wireId":32},{"source":{"component":8,"pin":2},"destination":{"component":1,"pin":6},"wireId":33},{"source":{"component":0,"pin":15},"destination":{"component":9,"pin":1},"wireId":34},{"source":{"component":0,"pin":7},"destination":{"component":9,"pin":0},"wireId":35},{"source":{"component":9,"pin":2},"destination":{"component":1,"pin":7},"wireId":36}]},"8-bit xor":{"type":"8-bit xor","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16,17,18,19,20,21,22,23]],"inputs":16,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["xor","xor","xor","xor","xor","xor","xor","xor"],"positions":[{"x":470,"y":747},{"x":488,"y":524},{"x":490,"y":626},{"x":490,"y":432},{"x":489,"y":336},{"x":491,"y":217},{"x":484,"y":122},{"x":474,"y":19}],"wires":[{"source":{"component":0,"pin":15},"destination":{"component":1,"pin":1},"wireId":0},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":0},"wireId":2},{"source":{"component":0,"pin":14},"destination":{"component":3,"pin":1},"wireId":3},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":0},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":0},"wireId":5},{"source":{"component":0,"pin":13},"destination":{"component":2,"pin":1},"wireId":6},{"source":{"component":0,"pin":4},"destination":{"component":4,"pin":0},"wireId":7},{"source":{"component":0,"pin":12},"destination":{"component":4,"pin":1},"wireId":8},{"source":{"component":0,"pin":3},"destination":{"component":5,"pin":0},"wireId":9},{"source":{"component":0,"pin":11},"destination":{"component":5,"pin":1},"wireId":10},{"source":{"component":0,"pin":10},"destination":{"component":6,"pin":1},"wireId":11},{"source":{"component":0,"pin":2},"destination":{"component":6,"pin":0},"wireId":12},{"source":{"component":0,"pin":0},"destination":{"component":8,"pin":0},"wireId":13},{"source":{"component":0,"pin":8},"destination":{"component":8,"pin":1},"wireId":14},{"source":{"component":0,"pin":1},"destination":{"component":7,"pin":0},"wireId":15},{"source":{"component":0,"pin":9},"destination":{"component":7,"pin":1},"wireId":16},{"source":{"component":8,"pin":2},"destination":{"component":0,"pin":16},"wireId":17},{"source":{"component":7,"pin":2},"destination":{"component":0,"pin":17},"wireId":18},{"source":{"component":6,"pin":2},"destination":{"component":0,"pin":18},"wireId":19},{"source":{"component":5,"pin":2},"destination":{"component":0,"pin":19},"wireId":20},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":20},"wireId":21},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":21},"wireId":22},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":22},"wireId":23},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":23},"wireId":24}]},"left shift":{"type":"left shift","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15]],"inputs":8,"tooltips":["input","input","input","input","input","input","input","input","output","output","output","output","output","output","output","output","overflow"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":0,"pin":9},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":0,"pin":10},"wireId":1},{"source":{"component":0,"pin":2},"destination":{"component":0,"pin":11},"wireId":2},{"source":{"component":0,"pin":3},"destination":{"component":0,"pin":12},"wireId":3},{"source":{"component":0,"pin":4},"destination":{"component":0,"pin":13},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":0,"pin":14},"wireId":5},{"source":{"component":0,"pin":6},"destination":{"component":0,"pin":15},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":0,"pin":16},"wireId":7}]},"right shift":{"type":"right shift","groups":[[0,1,2,3,4,5,6,7],[9,10,11,12,13,14,15,16]],"inputs":8,"tooltips":["input","input","input","input","input","input","input","input","underflow","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":0,"pin":8},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":0,"pin":9},"wireId":1},{"source":{"component":0,"pin":2},"destination":{"component":0,"pin":10},"wireId":2},{"source":{"component":0,"pin":3},"destination":{"component":0,"pin":11},"wireId":3},{"source":{"component":0,"pin":4},"destination":{"component":0,"pin":12},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":0,"pin":13},"wireId":5},{"source":{"component":0,"pin":6},"destination":{"component":0,"pin":14},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":0,"pin":15},"wireId":7}]},"1:2 demux":{"type":"1:2 demux","groups":[[1]],"inputs":2,"tooltips":["input","select","output A","output B"],"pins":[0,0,0,0],"subComponents":["and","not","and"],"positions":[{"x":1363,"y":603},{"x":1227,"y":400},{"x":1333,"y":278}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":3},{"source":{"component":2,"pin":1},"destination":{"component":3,"pin":1},"wireId":4},{"source":{"component":0,"pin":0},"destination":{"component":3,"pin":0},"wireId":5},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2},"wireId":6}]},"1:8 demux":{"type":"1:8 demux","groups":[[1,2,3]],"inputs":4,"tooltips":["input","select","select","select","output A","output B","output C","output D","output E","output F","output G","output H"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["or","or","1:2 demux","1:2 demux","1:2 demux","or","1:2 demux","1:2 demux","or","1:2 demux","1:2 demux"],"positions":[{"x":123,"y":576},{"x":294,"y":377},{"x":488,"y":221},{"x":730,"y":341},{"x":957,"y":422},{"x":710,"y":504},{"x":1203,"y":499},{"x":1458,"y":591},{"x":641,"y":678},{"x":1639,"y":698},{"x":1850,"y":834}],"wires":[{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":2},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1},"wireId":4},{"source":{"component":0,"pin":0},"destination":{"component":3,"pin":0},"wireId":5},{"source":{"component":3,"pin":3},"destination":{"component":4,"pin":0},"wireId":6},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":7},{"source":{"component":1,"pin":2},"destination":{"component":4,"pin":1},"wireId":8},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":5},"wireId":9},{"source":{"component":5,"pin":2},"destination":{"component":0,"pin":6},"wireId":10},{"source":{"component":4,"pin":3},"destination":{"component":5,"pin":0},"wireId":11},{"source":{"component":0,"pin":1},"destination":{"component":6,"pin":0},"wireId":15},{"source":{"component":0,"pin":3},"destination":{"component":6,"pin":1},"wireId":16},{"source":{"component":6,"pin":2},"destination":{"component":5,"pin":1},"wireId":17},{"source":{"component":5,"pin":3},"destination":{"component":7,"pin":0},"wireId":18},{"source":{"component":0,"pin":3},"destination":{"component":7,"pin":1},"wireId":19},{"source":{"component":7,"pin":2},"destination":{"component":0,"pin":7},"wireId":20},{"source":{"component":7,"pin":3},"destination":{"component":8,"pin":0},"wireId":21},{"source":{"component":0,"pin":1},"destination":{"component":9,"pin":0},"wireId":22},{"source":{"component":0,"pin":2},"destination":{"component":9,"pin":1},"wireId":23},{"source":{"component":9,"pin":2},"destination":{"component":8,"pin":1},"wireId":24},{"source":{"component":8,"pin":2},"destination":{"component":0,"pin":8},"wireId":25},{"source":{"component":8,"pin":3},"destination":{"component":10,"pin":0},"wireId":26},{"source":{"component":10,"pin":2},"destination":{"component":0,"pin":9},"wireId":27},{"source":{"component":0,"pin":2},"destination":{"component":10,"pin":1},"wireId":28},{"source":{"component":10,"pin":3},"destination":{"component":11,"pin":0},"wireId":29},{"source":{"component":0,"pin":1},"destination":{"component":11,"pin":1},"wireId":30},{"source":{"component":11,"pin":3},"destination":{"component":0,"pin":11},"wireId":31},{"source":{"component":11,"pin":2},"destination":{"component":0,"pin":10},"wireId":32}]},"8:1 or":{"type":"8:1 or","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15]],"inputs":16,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["or","or","or","or","or","or","or","or","or","or","or","or","or","or","or"],"positions":[{"x":797,"y":125},{"x":755,"y":224},{"x":750,"y":364},{"x":704,"y":485},{"x":649,"y":643},{"x":612,"y":758},{"x":594,"y":861},{"x":534,"y":950},{"x":978,"y":166},{"x":1005,"y":432},{"x":933,"y":640},{"x":922,"y":830},{"x":1372,"y":274},{"x":1252,"y":726},{"x":1594,"y":428}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":2},{"source":{"component":0,"pin":9},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":4},{"source":{"component":0,"pin":10},"destination":{"component":3,"pin":1},"wireId":5},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":6},{"source":{"component":0,"pin":11},"destination":{"component":4,"pin":1},"wireId":7},{"source":{"component":0,"pin":4},"destination":{"component":5,"pin":0},"wireId":8},{"source":{"component":0,"pin":12},"destination":{"component":5,"pin":1},"wireId":9},{"source":{"component":0,"pin":5},"destination":{"component":6,"pin":0},"wireId":10},{"source":{"component":0,"pin":13},"destination":{"component":6,"pin":1},"wireId":11},{"source":{"component":0,"pin":6},"destination":{"component":7,"pin":0},"wireId":12},{"source":{"component":0,"pin":14},"destination":{"component":7,"pin":1},"wireId":13},{"source":{"component":0,"pin":7},"destination":{"component":8,"pin":0},"wireId":14},{"source":{"component":0,"pin":15},"destination":{"component":8,"pin":1},"wireId":15},{"source":{"component":1,"pin":2},"destination":{"component":9,"pin":0},"wireId":16},{"source":{"component":2,"pin":2},"destination":{"component":9,"pin":1},"wireId":17},{"source":{"component":3,"pin":2},"destination":{"component":10,"pin":0},"wireId":18},{"source":{"component":4,"pin":2},"destination":{"component":10,"pin":1},"wireId":19},{"source":{"component":5,"pin":2},"destination":{"component":11,"pin":0},"wireId":20},{"source":{"component":6,"pin":2},"destination":{"component":11,"pin":1},"wireId":21},{"source":{"component":7,"pin":2},"destination":{"component":12,"pin":0},"wireId":22},{"source":{"component":8,"pin":2},"destination":{"component":12,"pin":1},"wireId":23},{"source":{"component":9,"pin":2},"destination":{"component":13,"pin":0},"wireId":24},{"source":{"component":10,"pin":2},"destination":{"component":13,"pin":1},"wireId":25},{"source":{"component":11,"pin":2},"destination":{"component":14,"pin":0},"wireId":26},{"source":{"component":12,"pin":2},"destination":{"component":14,"pin":1},"wireId":27},{"source":{"component":13,"pin":2},"destination":{"component":15,"pin":0},"wireId":28},{"source":{"component":14,"pin":2},"destination":{"component":15,"pin":1},"wireId":29},{"source":{"component":15,"pin":2},"destination":{"component":0,"pin":16},"wireId":30}]},"shift one":{"type":"shift one","groups":[[0,1,2,3,4,5,6,7],[9,10,11,12,13,14,15,16]],"inputs":9,"tooltips":["input","input","input","input","input","input","input","input","left/right?","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["not","and","and","and","or","or","or","or","or","or","and","and","and","and","and","and","and","and","and","and","and"],"positions":[{"x":161,"y":924},{"x":1299,"y":-1},{"x":1297,"y":134},{"x":1295,"y":201},{"x":1682,"y":182},{"x":1580,"y":303},{"x":1582,"y":482},{"x":1583,"y":663},{"x":1564,"y":756},{"x":1574,"y":909},{"x":1300,"y":320},{"x":1299,"y":386},{"x":1303,"y":479},{"x":1302,"y":542},{"x":1309,"y":636},{"x":1310,"y":701},{"x":1309,"y":814},{"x":1314,"y":877},{"x":1317,"y":980},{"x":1320,"y":1048},{"x":1081,"y":963}],"wires":[{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":5,"pin":2},"destination":{"component":0,"pin":10},"wireId":6},{"source":{"component":6,"pin":2},"destination":{"component":0,"pin":11},"wireId":11},{"source":{"component":7,"pin":2},"destination":{"component":0,"pin":12},"wireId":12},{"source":{"component":8,"pin":2},"destination":{"component":0,"pin":13},"wireId":15},{"source":{"component":9,"pin":2},"destination":{"component":0,"pin":14},"wireId":18},{"source":{"component":10,"pin":2},"destination":{"component":0,"pin":15},"wireId":21},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":25},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":1},"wireId":27},{"source":{"component":2,"pin":2},"destination":{"component":5,"pin":0},"wireId":28},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":9},"wireId":29},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1},"wireId":30},{"source":{"component":0,"pin":1},"destination":{"component":4,"pin":0},"wireId":31},{"source":{"component":1,"pin":1},"destination":{"component":3,"pin":0},"wireId":32},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":1},"wireId":33},{"source":{"component":0,"pin":2},"destination":{"component":11,"pin":1},"wireId":34},{"source":{"component":0,"pin":2},"destination":{"component":12,"pin":0},"wireId":35},{"source":{"component":1,"pin":1},"destination":{"component":11,"pin":0},"wireId":36},{"source":{"component":0,"pin":8},"destination":{"component":12,"pin":1},"wireId":37},{"source":{"component":4,"pin":2},"destination":{"component":6,"pin":0},"wireId":38},{"source":{"component":11,"pin":2},"destination":{"component":5,"pin":1},"wireId":39},{"source":{"component":12,"pin":2},"destination":{"component":7,"pin":0},"wireId":40},{"source":{"component":13,"pin":2},"destination":{"component":6,"pin":1},"wireId":41},{"source":{"component":14,"pin":2},"destination":{"component":8,"pin":0},"wireId":42},{"source":{"component":1,"pin":1},"destination":{"component":13,"pin":0},"wireId":43},{"source":{"component":0,"pin":8},"destination":{"component":14,"pin":1},"wireId":44},{"source":{"component":0,"pin":3},"destination":{"component":13,"pin":1},"wireId":45},{"source":{"component":0,"pin":3},"destination":{"component":14,"pin":0},"wireId":46},{"source":{"component":1,"pin":1},"destination":{"component":15,"pin":0},"wireId":47},{"source":{"component":0,"pin":8},"destination":{"component":16,"pin":1},"wireId":48},{"source":{"component":0,"pin":4},"destination":{"component":15,"pin":1},"wireId":49},{"source":{"component":0,"pin":4},"destination":{"component":16,"pin":0},"wireId":50},{"source":{"component":15,"pin":2},"destination":{"component":7,"pin":1},"wireId":51},{"source":{"component":16,"pin":2},"destination":{"component":9,"pin":0},"wireId":52},{"source":{"component":17,"pin":2},"destination":{"component":8,"pin":1},"wireId":53},{"source":{"component":18,"pin":2},"destination":{"component":10,"pin":0},"wireId":54},{"source":{"component":1,"pin":1},"destination":{"component":17,"pin":0},"wireId":55},{"source":{"component":0,"pin":8},"destination":{"component":18,"pin":1},"wireId":56},{"source":{"component":0,"pin":5},"destination":{"component":18,"pin":0},"wireId":57},{"source":{"component":0,"pin":5},"destination":{"component":17,"pin":1},"wireId":58},{"source":{"component":19,"pin":2},"destination":{"component":9,"pin":1},"wireId":59},{"source":{"component":20,"pin":2},"destination":{"component":0,"pin":16},"wireId":60},{"source":{"component":0,"pin":6},"destination":{"component":19,"pin":1},"wireId":61},{"source":{"component":0,"pin":6},"destination":{"component":20,"pin":0},"wireId":62},{"source":{"component":1,"pin":1},"destination":{"component":19,"pin":0},"wireId":63},{"source":{"component":0,"pin":8},"destination":{"component":20,"pin":1},"wireId":64},{"source":{"component":21,"pin":2},"destination":{"component":10,"pin":1},"wireId":65},{"source":{"component":0,"pin":7},"destination":{"component":21,"pin":0},"wireId":66},{"source":{"component":1,"pin":1},"destination":{"component":21,"pin":1},"wireId":67}]},"shift unit":{"type":"shift unit","groups":[[0,1,2,3,4,5,6,7],[8,9,10],[12,13,14,15,16,17,18,19]],"inputs":12,"tooltips":["input","input","input","input","input","input","input","input","shift by","shift by","shift by","left/right?","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["shift one","shift one","shift one","shift one","shift one","shift one","shift one","16:8 mux","16:8 mux","16:8 mux","or","or","or","16:8 mux","and","or","or","16:8 mux","16:8 mux","and","16:8 mux","and","and","not"],"positions":[{"x":181,"y":217},{"x":473,"y":36},{"x":1655,"y":329},{"x":1003,"y":501},{"x":1181,"y":148},{"x":894,"y":129},{"x":772,"y":281},{"x":1925,"y":341},{"x":420,"y":191},{"x":604,"y":186},{"x":106,"y":707},{"x":179,"y":816},{"x":295,"y":736},{"x":912,"y":227},{"x":636,"y":729},{"x":853,"y":668},{"x":586,"y":555},{"x":1082,"y":304},{"x":1198,"y":368},{"x":946,"y":812},{"x":1412,"y":525},{"x":1177,"y":845},{"x":1558,"y":820},{"x":50,"y":1002}],"wires":[{"source":{"component":8,"pin":17},"destination":{"component":0,"pin":12},"wireId":0},{"source":{"component":8,"pin":18},"destination":{"component":0,"pin":13},"wireId":1},{"source":{"component":8,"pin":19},"destination":{"component":0,"pin":14},"wireId":2},{"source":{"component":8,"pin":20},"destination":{"component":0,"pin":15},"wireId":3},{"source":{"component":8,"pin":21},"destination":{"component":0,"pin":16},"wireId":4},{"source":{"component":8,"pin":22},"destination":{"component":0,"pin":17},"wireId":5},{"source":{"component":8,"pin":23},"destination":{"component":0,"pin":18},"wireId":6},{"source":{"component":8,"pin":24},"destination":{"component":0,"pin":19},"wireId":7},{"source":{"component":0,"pin":0},"destination":{"component":9,"pin":0},"wireId":8},{"source":{"component":0,"pin":1},"destination":{"component":9,"pin":1},"wireId":9},{"source":{"component":0,"pin":2},"destination":{"component":9,"pin":2},"wireId":10},{"source":{"component":0,"pin":3},"destination":{"component":9,"pin":3},"wireId":11},{"source":{"component":0,"pin":4},"destination":{"component":9,"pin":4},"wireId":12},{"source":{"component":0,"pin":5},"destination":{"component":9,"pin":5},"wireId":13},{"source":{"component":0,"pin":6},"destination":{"component":9,"pin":6},"wireId":14},{"source":{"component":0,"pin":7},"destination":{"component":9,"pin":7},"wireId":15},{"source":{"component":1,"pin":9},"destination":{"component":9,"pin":8},"wireId":16},{"source":{"component":1,"pin":10},"destination":{"component":9,"pin":9},"wireId":17},{"source":{"component":1,"pin":11},"destination":{"component":9,"pin":10},"wireId":18},{"source":{"component":1,"pin":12},"destination":{"component":9,"pin":11},"wireId":19},{"source":{"component":1,"pin":13},"destination":{"component":9,"pin":12},"wireId":20},{"source":{"component":1,"pin":14},"destination":{"component":9,"pin":13},"wireId":21},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":24},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":25},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":26},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":27},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":28},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":29},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":30},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":31},{"source":{"component":1,"pin":15},"destination":{"component":9,"pin":14},"wireId":33},{"source":{"component":1,"pin":16},"destination":{"component":9,"pin":15},"wireId":34},{"source":{"component":9,"pin":17},"destination":{"component":2,"pin":0},"wireId":36},{"source":{"component":9,"pin":18},"destination":{"component":2,"pin":1},"wireId":37},{"source":{"component":9,"pin":19},"destination":{"component":2,"pin":2},"wireId":38},{"source":{"component":9,"pin":20},"destination":{"component":2,"pin":3},"wireId":39},{"source":{"component":9,"pin":21},"destination":{"component":2,"pin":4},"wireId":40},{"source":{"component":9,"pin":22},"destination":{"component":2,"pin":5},"wireId":41},{"source":{"component":9,"pin":23},"destination":{"component":2,"pin":6},"wireId":42},{"source":{"component":9,"pin":24},"destination":{"component":2,"pin":7},"wireId":43},{"source":{"component":9,"pin":17},"destination":{"component":10,"pin":0},"wireId":45},{"source":{"component":9,"pin":18},"destination":{"component":10,"pin":1},"wireId":46},{"source":{"component":9,"pin":19},"destination":{"component":10,"pin":2},"wireId":47},{"source":{"component":9,"pin":20},"destination":{"component":10,"pin":3},"wireId":48},{"source":{"component":9,"pin":21},"destination":{"component":10,"pin":4},"wireId":49},{"source":{"component":9,"pin":22},"destination":{"component":10,"pin":5},"wireId":50},{"source":{"component":9,"pin":23},"destination":{"component":10,"pin":6},"wireId":51},{"source":{"component":9,"pin":24},"destination":{"component":10,"pin":7},"wireId":52},{"source":{"component":2,"pin":9},"destination":{"component":10,"pin":8},"wireId":53},{"source":{"component":2,"pin":10},"destination":{"component":10,"pin":9},"wireId":54},{"source":{"component":2,"pin":11},"destination":{"component":10,"pin":10},"wireId":55},{"source":{"component":2,"pin":12},"destination":{"component":10,"pin":11},"wireId":56},{"source":{"component":2,"pin":13},"destination":{"component":10,"pin":12},"wireId":57},{"source":{"component":2,"pin":14},"destination":{"component":10,"pin":13},"wireId":58},{"source":{"component":2,"pin":15},"destination":{"component":10,"pin":14},"wireId":59},{"source":{"component":2,"pin":16},"destination":{"component":10,"pin":15},"wireId":60},{"source":{"component":0,"pin":8},"destination":{"component":11,"pin":0},"wireId":62},{"source":{"component":0,"pin":9},"destination":{"component":11,"pin":1},"wireId":63},{"source":{"component":0,"pin":9},"destination":{"component":12,"pin":0},"wireId":64},{"source":{"component":0,"pin":10},"destination":{"component":12,"pin":1},"wireId":65},{"source":{"component":11,"pin":2},"destination":{"component":13,"pin":0},"wireId":66},{"source":{"component":12,"pin":2},"destination":{"component":13,"pin":1},"wireId":67},{"source":{"component":13,"pin":2},"destination":{"component":9,"pin":16},"wireId":68},{"source":{"component":10,"pin":17},"destination":{"component":7,"pin":0},"wireId":69},{"source":{"component":10,"pin":18},"destination":{"component":7,"pin":1},"wireId":70},{"source":{"component":10,"pin":19},"destination":{"component":7,"pin":2},"wireId":71},{"source":{"component":10,"pin":20},"destination":{"component":7,"pin":3},"wireId":72},{"source":{"component":10,"pin":21},"destination":{"component":7,"pin":4},"wireId":77},{"source":{"component":10,"pin":22},"destination":{"component":7,"pin":5},"wireId":78},{"source":{"component":10,"pin":23},"destination":{"component":7,"pin":6},"wireId":79},{"source":{"component":10,"pin":24},"destination":{"component":7,"pin":7},"wireId":80},{"source":{"component":10,"pin":17},"destination":{"component":14,"pin":0},"wireId":82},{"source":{"component":10,"pin":18},"destination":{"component":14,"pin":1},"wireId":83},{"source":{"component":10,"pin":19},"destination":{"component":14,"pin":2},"wireId":84},{"source":{"component":10,"pin":20},"destination":{"component":14,"pin":3},"wireId":85},{"source":{"component":10,"pin":21},"destination":{"component":14,"pin":4},"wireId":86},{"source":{"component":10,"pin":22},"destination":{"component":14,"pin":5},"wireId":87},{"source":{"component":10,"pin":23},"destination":{"component":14,"pin":6},"wireId":88},{"source":{"component":10,"pin":24},"destination":{"component":14,"pin":7},"wireId":89},{"source":{"component":7,"pin":9},"destination":{"component":14,"pin":8},"wireId":90},{"source":{"component":7,"pin":10},"destination":{"component":14,"pin":9},"wireId":91},{"source":{"component":7,"pin":11},"destination":{"component":14,"pin":10},"wireId":92},{"source":{"component":7,"pin":12},"destination":{"component":14,"pin":11},"wireId":93},{"source":{"component":7,"pin":13},"destination":{"component":14,"pin":12},"wireId":94},{"source":{"component":7,"pin":14},"destination":{"component":14,"pin":13},"wireId":95},{"source":{"component":7,"pin":15},"destination":{"component":14,"pin":14},"wireId":96},{"source":{"component":7,"pin":16},"destination":{"component":14,"pin":15},"wireId":97},{"source":{"component":0,"pin":8},"destination":{"component":15,"pin":0},"wireId":99},{"source":{"component":0,"pin":9},"destination":{"component":15,"pin":1},"wireId":100},{"source":{"component":15,"pin":2},"destination":{"component":16,"pin":0},"wireId":102},{"source":{"component":0,"pin":10},"destination":{"component":16,"pin":1},"wireId":103},{"source":{"component":16,"pin":2},"destination":{"component":14,"pin":16},"wireId":104},{"source":{"component":0,"pin":9},"destination":{"component":17,"pin":0},"wireId":105},{"source":{"component":0,"pin":10},"destination":{"component":17,"pin":1},"wireId":106},{"source":{"component":17,"pin":2},"destination":{"component":10,"pin":16},"wireId":107},{"source":{"component":14,"pin":17},"destination":{"component":6,"pin":0},"wireId":108},{"source":{"component":14,"pin":18},"destination":{"component":6,"pin":1},"wireId":109},{"source":{"component":14,"pin":19},"destination":{"component":6,"pin":2},"wireId":110},{"source":{"component":14,"pin":20},"destination":{"component":6,"pin":3},"wireId":111},{"source":{"component":14,"pin":21},"destination":{"component":6,"pin":4},"wireId":112},{"source":{"component":14,"pin":22},"destination":{"component":6,"pin":5},"wireId":113},{"source":{"component":14,"pin":23},"destination":{"component":6,"pin":6},"wireId":114},{"source":{"component":14,"pin":24},"destination":{"component":6,"pin":7},"wireId":115},{"source":{"component":14,"pin":18},"destination":{"component":18,"pin":1},"wireId":118},{"source":{"component":14,"pin":18},"destination":{"component":18,"pin":0},"wireId":127},{"source":{"component":14,"pin":19},"destination":{"component":18,"pin":2},"wireId":128},{"source":{"component":14,"pin":20},"destination":{"component":18,"pin":3},"wireId":129},{"source":{"component":14,"pin":21},"destination":{"component":18,"pin":4},"wireId":130},{"source":{"component":14,"pin":22},"destination":{"component":18,"pin":5},"wireId":131},{"source":{"component":14,"pin":23},"destination":{"component":18,"pin":6},"wireId":132},{"source":{"component":14,"pin":24},"destination":{"component":18,"pin":7},"wireId":133},{"source":{"component":6,"pin":9},"destination":{"component":18,"pin":8},"wireId":134},{"source":{"component":6,"pin":10},"destination":{"component":18,"pin":9},"wireId":135},{"source":{"component":6,"pin":11},"destination":{"component":18,"pin":10},"wireId":136},{"source":{"component":6,"pin":12},"destination":{"component":18,"pin":11},"wireId":137},{"source":{"component":6,"pin":13},"destination":{"component":18,"pin":12},"wireId":140},{"source":{"component":6,"pin":14},"destination":{"component":18,"pin":13},"wireId":141},{"source":{"component":6,"pin":15},"destination":{"component":18,"pin":14},"wireId":142},{"source":{"component":6,"pin":16},"destination":{"component":18,"pin":15},"wireId":143},{"source":{"component":0,"pin":10},"destination":{"component":18,"pin":16},"wireId":144},{"source":{"component":18,"pin":17},"destination":{"component":4,"pin":0},"wireId":145},{"source":{"component":18,"pin":18},"destination":{"component":4,"pin":1},"wireId":146},{"source":{"component":18,"pin":19},"destination":{"component":4,"pin":2},"wireId":147},{"source":{"component":18,"pin":20},"destination":{"component":4,"pin":3},"wireId":148},{"source":{"component":18,"pin":21},"destination":{"component":4,"pin":4},"wireId":149},{"source":{"component":18,"pin":22},"destination":{"component":4,"pin":5},"wireId":150},{"source":{"component":18,"pin":23},"destination":{"component":4,"pin":6},"wireId":151},{"source":{"component":18,"pin":24},"destination":{"component":4,"pin":7},"wireId":152},{"source":{"component":4,"pin":16},"destination":{"component":19,"pin":15},"wireId":155},{"source":{"component":4,"pin":15},"destination":{"component":19,"pin":14},"wireId":156},{"source":{"component":4,"pin":14},"destination":{"component":19,"pin":13},"wireId":157},{"source":{"component":4,"pin":13},"destination":{"component":19,"pin":12},"wireId":158},{"source":{"component":4,"pin":12},"destination":{"component":19,"pin":11},"wireId":159},{"source":{"component":4,"pin":11},"destination":{"component":19,"pin":10},"wireId":160},{"source":{"component":4,"pin":10},"destination":{"component":19,"pin":9},"wireId":161},{"source":{"component":4,"pin":9},"destination":{"component":19,"pin":8},"wireId":162},{"source":{"component":18,"pin":17},"destination":{"component":19,"pin":0},"wireId":163},{"source":{"component":18,"pin":18},"destination":{"component":19,"pin":1},"wireId":164},{"source":{"component":18,"pin":19},"destination":{"component":19,"pin":2},"wireId":165},{"source":{"component":18,"pin":20},"destination":{"component":19,"pin":3},"wireId":166},{"source":{"component":18,"pin":21},"destination":{"component":19,"pin":4},"wireId":167},{"source":{"component":18,"pin":22},"destination":{"component":19,"pin":5},"wireId":168},{"source":{"component":18,"pin":23},"destination":{"component":19,"pin":6},"wireId":169},{"source":{"component":18,"pin":24},"destination":{"component":19,"pin":7},"wireId":170},{"source":{"component":0,"pin":10},"destination":{"component":20,"pin":1},"wireId":171},{"source":{"component":11,"pin":2},"destination":{"component":20,"pin":0},"wireId":172},{"source":{"component":20,"pin":2},"destination":{"component":19,"pin":16},"wireId":173},{"source":{"component":19,"pin":17},"destination":{"component":5,"pin":0},"wireId":174},{"source":{"component":19,"pin":18},"destination":{"component":5,"pin":1},"wireId":175},{"source":{"component":19,"pin":19},"destination":{"component":5,"pin":2},"wireId":176},{"source":{"component":19,"pin":20},"destination":{"component":5,"pin":3},"wireId":177},{"source":{"component":19,"pin":21},"destination":{"component":5,"pin":4},"wireId":178},{"source":{"component":19,"pin":22},"destination":{"component":5,"pin":5},"wireId":179},{"source":{"component":19,"pin":23},"destination":{"component":5,"pin":6},"wireId":180},{"source":{"component":19,"pin":24},"destination":{"component":5,"pin":7},"wireId":181},{"source":{"component":19,"pin":17},"destination":{"component":21,"pin":0},"wireId":183},{"source":{"component":19,"pin":18},"destination":{"component":21,"pin":1},"wireId":184},{"source":{"component":19,"pin":19},"destination":{"component":21,"pin":2},"wireId":185},{"source":{"component":19,"pin":20},"destination":{"component":21,"pin":3},"wireId":186},{"source":{"component":19,"pin":21},"destination":{"component":21,"pin":4},"wireId":187},{"source":{"component":19,"pin":22},"destination":{"component":21,"pin":5},"wireId":188},{"source":{"component":19,"pin":23},"destination":{"component":21,"pin":6},"wireId":189},{"source":{"component":19,"pin":24},"destination":{"component":21,"pin":7},"wireId":190},{"source":{"component":5,"pin":9},"destination":{"component":21,"pin":8},"wireId":191},{"source":{"component":5,"pin":10},"destination":{"component":21,"pin":9},"wireId":192},{"source":{"component":5,"pin":11},"destination":{"component":21,"pin":10},"wireId":193},{"source":{"component":5,"pin":12},"destination":{"component":21,"pin":11},"wireId":194},{"source":{"component":5,"pin":13},"destination":{"component":21,"pin":12},"wireId":195},{"source":{"component":5,"pin":14},"destination":{"component":21,"pin":13},"wireId":196},{"source":{"component":5,"pin":15},"destination":{"component":21,"pin":14},"wireId":197},{"source":{"component":5,"pin":16},"destination":{"component":21,"pin":15},"wireId":198},{"source":{"component":0,"pin":10},"destination":{"component":22,"pin":1},"wireId":199},{"source":{"component":0,"pin":9},"destination":{"component":22,"pin":0},"wireId":200},{"source":{"component":22,"pin":2},"destination":{"component":21,"pin":16},"wireId":201},{"source":{"component":21,"pin":17},"destination":{"component":3,"pin":0},"wireId":202},{"source":{"component":21,"pin":18},"destination":{"component":3,"pin":1},"wireId":203},{"source":{"component":21,"pin":19},"destination":{"component":3,"pin":2},"wireId":204},{"source":{"component":21,"pin":20},"destination":{"component":3,"pin":3},"wireId":205},{"source":{"component":21,"pin":21},"destination":{"component":3,"pin":4},"wireId":206},{"source":{"component":21,"pin":22},"destination":{"component":3,"pin":5},"wireId":207},{"source":{"component":21,"pin":23},"destination":{"component":3,"pin":6},"wireId":208},{"source":{"component":21,"pin":24},"destination":{"component":3,"pin":7},"wireId":209},{"source":{"component":21,"pin":17},"destination":{"component":8,"pin":0},"wireId":211},{"source":{"component":21,"pin":18},"destination":{"component":8,"pin":1},"wireId":212},{"source":{"component":21,"pin":19},"destination":{"component":8,"pin":2},"wireId":213},{"source":{"component":21,"pin":20},"destination":{"component":8,"pin":3},"wireId":214},{"source":{"component":21,"pin":21},"destination":{"component":8,"pin":4},"wireId":215},{"source":{"component":21,"pin":22},"destination":{"component":8,"pin":5},"wireId":216},{"source":{"component":21,"pin":23},"destination":{"component":8,"pin":6},"wireId":217},{"source":{"component":21,"pin":24},"destination":{"component":8,"pin":7},"wireId":218},{"source":{"component":3,"pin":12},"destination":{"component":8,"pin":11},"wireId":222},{"source":{"component":3,"pin":13},"destination":{"component":8,"pin":12},"wireId":223},{"source":{"component":3,"pin":14},"destination":{"component":8,"pin":13},"wireId":224},{"source":{"component":3,"pin":15},"destination":{"component":8,"pin":14},"wireId":225},{"source":{"component":3,"pin":9},"destination":{"component":8,"pin":8},"wireId":226},{"source":{"component":3,"pin":10},"destination":{"component":8,"pin":9},"wireId":227},{"source":{"component":3,"pin":11},"destination":{"component":8,"pin":10},"wireId":228},{"source":{"component":3,"pin":16},"destination":{"component":8,"pin":15},"wireId":229},{"source":{"component":15,"pin":2},"destination":{"component":23,"pin":0},"wireId":230},{"source":{"component":0,"pin":10},"destination":{"component":23,"pin":1},"wireId":231},{"source":{"component":23,"pin":2},"destination":{"component":8,"pin":16},"wireId":232},{"source":{"component":0,"pin":11},"destination":{"component":24,"pin":0},"wireId":233},{"source":{"component":24,"pin":1},"destination":{"component":1,"pin":8},"wireId":234},{"source":{"component":24,"pin":1},"destination":{"component":2,"pin":8},"wireId":235},{"source":{"component":24,"pin":1},"destination":{"component":7,"pin":8},"wireId":236},{"source":{"component":24,"pin":1},"destination":{"component":6,"pin":8},"wireId":237},{"source":{"component":24,"pin":1},"destination":{"component":5,"pin":8},"wireId":238},{"source":{"component":24,"pin":1},"destination":{"component":4,"pin":8},"wireId":239},{"source":{"component":24,"pin":1},"destination":{"component":3,"pin":8},"wireId":240}]},"nand/xor":{"type":"nand/xor","groups":[],"inputs":3,"tooltips":["A","B","nand/xor?","output"],"pins":[0,0,0,0],"subComponents":["nand","xor","2-1 mux"],"positions":[{"x":490,"y":253},{"x":668,"y":441},{"x":1098,"y":387}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0},"wireId":4},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1},"wireId":5},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":2},"wireId":6},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":3},"wireId":7}]},"8-bit nand/xor":{"type":"8-bit nand/xor","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[17,18,19,20,21,22,23,24]],"inputs":17,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","nand/xor?","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["nand/xor","nand/xor","nand/xor","nand/xor","nand/xor","nand/xor","nand/xor","nand/xor"],"positions":[{"x":488,"y":697},{"x":488,"y":579},{"x":485,"y":492},{"x":491,"y":400},{"x":491,"y":318},{"x":489,"y":241},{"x":485,"y":168},{"x":502,"y":807}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":7,"pin":0},"wireId":0},{"source":{"component":0,"pin":8},"destination":{"component":7,"pin":1},"wireId":1},{"source":{"component":0,"pin":1},"destination":{"component":6,"pin":0},"wireId":2},{"source":{"component":0,"pin":9},"destination":{"component":6,"pin":1},"wireId":3},{"source":{"component":0,"pin":2},"destination":{"component":5,"pin":0},"wireId":4},{"source":{"component":0,"pin":10},"destination":{"component":5,"pin":1},"wireId":5},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":6},{"source":{"component":0,"pin":11},"destination":{"component":4,"pin":1},"wireId":7},{"source":{"component":0,"pin":12},"destination":{"component":3,"pin":1},"wireId":8},{"source":{"component":0,"pin":4},"destination":{"component":3,"pin":0},"wireId":9},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":0},"wireId":10},{"source":{"component":0,"pin":13},"destination":{"component":2,"pin":1},"wireId":11},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":0},"wireId":12},{"source":{"component":0,"pin":7},"destination":{"component":8,"pin":0},"wireId":13},{"source":{"component":0,"pin":15},"destination":{"component":8,"pin":1},"wireId":14},{"source":{"component":0,"pin":14},"destination":{"component":1,"pin":1},"wireId":15},{"source":{"component":0,"pin":16},"destination":{"component":8,"pin":2},"wireId":16},{"source":{"component":0,"pin":16},"destination":{"component":1,"pin":2},"wireId":17},{"source":{"component":0,"pin":16},"destination":{"component":2,"pin":2},"wireId":18},{"source":{"component":0,"pin":16},"destination":{"component":3,"pin":2},"wireId":19},{"source":{"component":0,"pin":16},"destination":{"component":4,"pin":2},"wireId":20},{"source":{"component":0,"pin":16},"destination":{"component":5,"pin":2},"wireId":21},{"source":{"component":0,"pin":16},"destination":{"component":6,"pin":2},"wireId":22},{"source":{"component":0,"pin":16},"destination":{"component":7,"pin":2},"wireId":23},{"source":{"component":7,"pin":3},"destination":{"component":0,"pin":17},"wireId":24},{"source":{"component":6,"pin":3},"destination":{"component":0,"pin":18},"wireId":25},{"source":{"component":5,"pin":3},"destination":{"component":0,"pin":19},"wireId":26},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":20},"wireId":27},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":21},"wireId":28},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":22},"wireId":29},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":23},"wireId":30},{"source":{"component":8,"pin":3},"destination":{"component":0,"pin":24},"wireId":31}]},"logic unit":{"type":"logic unit","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[18,19,20,21,22,23,24,25]],"inputs":18,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","operation select - nand/xor or shift","operation select - nand/left or xor/right","result","result","result","result","result","result","result","result"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["8-bit nand/xor","shift unit","16:8 mux"],"positions":[{"x":1130,"y":98},{"x":1007,"y":751},{"x":1665,"y":293}],"wires":[{"source":{"component":0,"pin":17},"destination":{"component":1,"pin":16},"wireId":0},{"source":{"component":0,"pin":17},"destination":{"component":2,"pin":11},"wireId":1},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":2},"wireId":4},{"source":{"component":0,"pin":3},"destination":{"component":2,"pin":3},"wireId":5},{"source":{"component":0,"pin":4},"destination":{"component":2,"pin":4},"wireId":6},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":5},"wireId":7},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":6},"wireId":8},{"source":{"component":0,"pin":7},"destination":{"component":2,"pin":7},"wireId":9},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":8},"wireId":10},{"source":{"component":0,"pin":9},"destination":{"component":2,"pin":9},"wireId":11},{"source":{"component":0,"pin":10},"destination":{"component":2,"pin":10},"wireId":12},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":13},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":14},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":15},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":16},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":17},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":18},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":19},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":20},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":8},"wireId":23},{"source":{"component":0,"pin":9},"destination":{"component":1,"pin":9},"wireId":24},{"source":{"component":0,"pin":10},"destination":{"component":1,"pin":10},"wireId":25},{"source":{"component":0,"pin":11},"destination":{"component":1,"pin":11},"wireId":26},{"source":{"component":0,"pin":12},"destination":{"component":1,"pin":12},"wireId":27},{"source":{"component":0,"pin":13},"destination":{"component":1,"pin":13},"wireId":28},{"source":{"component":0,"pin":14},"destination":{"component":1,"pin":14},"wireId":29},{"source":{"component":0,"pin":15},"destination":{"component":1,"pin":15},"wireId":30},{"source":{"component":1,"pin":17},"destination":{"component":3,"pin":0},"wireId":31},{"source":{"component":1,"pin":18},"destination":{"component":3,"pin":1},"wireId":32},{"source":{"component":1,"pin":19},"destination":{"component":3,"pin":2},"wireId":33},{"source":{"component":1,"pin":20},"destination":{"component":3,"pin":3},"wireId":34},{"source":{"component":1,"pin":21},"destination":{"component":3,"pin":4},"wireId":35},{"source":{"component":1,"pin":22},"destination":{"component":3,"pin":5},"wireId":36},{"source":{"component":1,"pin":23},"destination":{"component":3,"pin":6},"wireId":37},{"source":{"component":1,"pin":24},"destination":{"component":3,"pin":7},"wireId":38},{"source":{"component":2,"pin":12},"destination":{"component":3,"pin":8},"wireId":39},{"source":{"component":2,"pin":13},"destination":{"component":3,"pin":9},"wireId":40},{"source":{"component":2,"pin":14},"destination":{"component":3,"pin":10},"wireId":41},{"source":{"component":2,"pin":15},"destination":{"component":3,"pin":11},"wireId":42},{"source":{"component":2,"pin":16},"destination":{"component":3,"pin":12},"wireId":43},{"source":{"component":2,"pin":17},"destination":{"component":3,"pin":13},"wireId":44},{"source":{"component":2,"pin":18},"destination":{"component":3,"pin":14},"wireId":45},{"source":{"component":2,"pin":19},"destination":{"component":3,"pin":15},"wireId":46},{"source":{"component":0,"pin":16},"destination":{"component":3,"pin":16},"wireId":47},{"source":{"component":3,"pin":17},"destination":{"component":0,"pin":18},"wireId":48},{"source":{"component":3,"pin":18},"destination":{"component":0,"pin":19},"wireId":49},{"source":{"component":3,"pin":19},"destination":{"component":0,"pin":20},"wireId":50},{"source":{"component":3,"pin":20},"destination":{"component":0,"pin":21},"wireId":51},{"source":{"component":3,"pin":21},"destination":{"component":0,"pin":22},"wireId":52},{"source":{"component":3,"pin":22},"destination":{"component":0,"pin":23},"wireId":53},{"source":{"component":3,"pin":23},"destination":{"component":0,"pin":24},"wireId":54},{"source":{"component":3,"pin":24},"destination":{"component":0,"pin":25},"wireId":55}]},"ALU":{"type":"ALU","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16,17,18,19],[20],[21,22,23,24,25,26,27,28],[29,30,31,32]],"inputs":21,"tooltips":["operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","opcode","opcode","opcode","opcode","carry/borrow in","result","result","result","result","result","result","result","result","overflow flag","negative flag","carry/borrow flag","zero flag"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["logic unit","add/subtract unit","16:8 mux","16:8 mux","and","and","8-bit not","and","and","and","and","and","and","and","not","not","and","and","not","xor","xnor","and","and","or","and","and","and","not","not"],"positions":[{"x":811,"y":374},{"x":759,"y":42},{"x":1570,"y":705},{"x":1236,"y":162},{"x":82,"y":1105},{"x":2114,"y":1161},{"x":1850,"y":1060},{"x":2118,"y":1096},{"x":2121,"y":1031},{"x":2120,"y":983},{"x":2268,"y":1136},{"x":2276,"y":1029},{"x":2398,"y":1080},{"x":1267,"y":1040},{"x":1061,"y":1105},{"x":1001,"y":1044},{"x":1471,"y":987},{"x":1615,"y":571},{"x":946,"y":763},{"x":125,"y":337},{"x":1197,"y":528},{"x":1517,"y":443},{"x":1759,"y":456},{"x":2102,"y":838},{"x":1620,"y":284},{"x":1756,"y":236},{"x":1549,"y":152},{"x":1359,"y":466},{"x":663,"y":314}],"wires":[{"source":{"component":3,"pin":17},"destination":{"component":0,"pin":21},"wireId":0},{"source":{"component":3,"pin":18},"destination":{"component":0,"pin":22},"wireId":1},{"source":{"component":3,"pin":19},"destination":{"component":0,"pin":23},"wireId":2},{"source":{"component":3,"pin":20},"destination":{"component":0,"pin":24},"wireId":3},{"source":{"component":3,"pin":21},"destination":{"component":0,"pin":25},"wireId":4},{"source":{"component":3,"pin":22},"destination":{"component":0,"pin":26},"wireId":5},{"source":{"component":3,"pin":23},"destination":{"component":0,"pin":27},"wireId":6},{"source":{"component":3,"pin":24},"destination":{"component":0,"pin":28},"wireId":7},{"source":{"component":4,"pin":17},"destination":{"component":3,"pin":0},"wireId":8},{"source":{"component":4,"pin":18},"destination":{"component":3,"pin":1},"wireId":9},{"source":{"component":4,"pin":19},"destination":{"component":3,"pin":2},"wireId":10},{"source":{"component":4,"pin":20},"destination":{"component":3,"pin":3},"wireId":11},{"source":{"component":4,"pin":21},"destination":{"component":3,"pin":4},"wireId":12},{"source":{"component":4,"pin":22},"destination":{"component":3,"pin":5},"wireId":13},{"source":{"component":4,"pin":23},"destination":{"component":3,"pin":6},"wireId":14},{"source":{"component":4,"pin":24},"destination":{"component":3,"pin":7},"wireId":15},{"source":{"component":0,"pin":8},"destination":{"component":3,"pin":8},"wireId":17},{"source":{"component":0,"pin":9},"destination":{"component":3,"pin":9},"wireId":18},{"source":{"component":0,"pin":10},"destination":{"component":3,"pin":10},"wireId":19},{"source":{"component":0,"pin":11},"destination":{"component":3,"pin":11},"wireId":20},{"source":{"component":0,"pin":12},"destination":{"component":3,"pin":12},"wireId":21},{"source":{"component":0,"pin":13},"destination":{"component":3,"pin":13},"wireId":22},{"source":{"component":0,"pin":14},"destination":{"component":3,"pin":14},"wireId":23},{"source":{"component":0,"pin":15},"destination":{"component":3,"pin":15},"wireId":24},{"source":{"component":0,"pin":19},"destination":{"component":3,"pin":16},"wireId":25},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":28},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":29},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":2},"wireId":30},{"source":{"component":0,"pin":3},"destination":{"component":2,"pin":3},"wireId":31},{"source":{"component":0,"pin":4},"destination":{"component":2,"pin":4},"wireId":32},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":5},"wireId":33},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":6},"wireId":34},{"source":{"component":0,"pin":7},"destination":{"component":2,"pin":7},"wireId":35},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":8},"wireId":36},{"source":{"component":0,"pin":9},"destination":{"component":2,"pin":9},"wireId":37},{"source":{"component":0,"pin":10},"destination":{"component":2,"pin":10},"wireId":38},{"source":{"component":0,"pin":11},"destination":{"component":2,"pin":11},"wireId":39},{"source":{"component":0,"pin":12},"destination":{"component":2,"pin":12},"wireId":40},{"source":{"component":0,"pin":13},"destination":{"component":2,"pin":13},"wireId":41},{"source":{"component":0,"pin":14},"destination":{"component":2,"pin":14},"wireId":42},{"source":{"component":0,"pin":15},"destination":{"component":2,"pin":15},"wireId":43},{"source":{"component":0,"pin":16},"destination":{"component":2,"pin":17},"wireId":44},{"source":{"component":0,"pin":17},"destination":{"component":5,"pin":0},"wireId":45},{"source":{"component":0,"pin":20},"destination":{"component":5,"pin":1},"wireId":46},{"source":{"component":5,"pin":2},"destination":{"component":2,"pin":16},"wireId":47},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":48},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":49},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":50},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":51},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":52},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":53},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":54},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":55},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":8},"wireId":56},{"source":{"component":0,"pin":9},"destination":{"component":1,"pin":9},"wireId":57},{"source":{"component":0,"pin":10},"destination":{"component":1,"pin":10},"wireId":58},{"source":{"component":0,"pin":11},"destination":{"component":1,"pin":11},"wireId":59},{"source":{"component":0,"pin":12},"destination":{"component":1,"pin":12},"wireId":60},{"source":{"component":0,"pin":13},"destination":{"component":1,"pin":13},"wireId":61},{"source":{"component":0,"pin":14},"destination":{"component":1,"pin":14},"wireId":62},{"source":{"component":0,"pin":15},"destination":{"component":1,"pin":15},"wireId":63},{"source":{"component":2,"pin":21},"destination":{"component":4,"pin":3},"wireId":67},{"source":{"component":2,"pin":22},"destination":{"component":4,"pin":4},"wireId":68},{"source":{"component":2,"pin":23},"destination":{"component":4,"pin":5},"wireId":69},{"source":{"component":2,"pin":24},"destination":{"component":4,"pin":6},"wireId":70},{"source":{"component":2,"pin":25},"destination":{"component":4,"pin":7},"wireId":71},{"source":{"component":2,"pin":18},"destination":{"component":4,"pin":0},"wireId":74},{"source":{"component":2,"pin":19},"destination":{"component":4,"pin":1},"wireId":75},{"source":{"component":2,"pin":20},"destination":{"component":4,"pin":2},"wireId":76},{"source":{"component":1,"pin":18},"destination":{"component":4,"pin":8},"wireId":82},{"source":{"component":1,"pin":19},"destination":{"component":4,"pin":9},"wireId":83},{"source":{"component":1,"pin":20},"destination":{"component":4,"pin":10},"wireId":84},{"source":{"component":1,"pin":21},"destination":{"component":4,"pin":11},"wireId":85},{"source":{"component":1,"pin":22},"destination":{"component":4,"pin":12},"wireId":86},{"source":{"component":1,"pin":23},"destination":{"component":4,"pin":13},"wireId":87},{"source":{"component":1,"pin":24},"destination":{"component":4,"pin":14},"wireId":88},{"source":{"component":1,"pin":25},"destination":{"component":4,"pin":15},"wireId":89},{"source":{"component":0,"pin":18},"destination":{"component":4,"pin":16},"wireId":90},{"source":{"component":0,"pin":16},"destination":{"component":1,"pin":17},"wireId":92},{"source":{"component":0,"pin":17},"destination":{"component":1,"pin":16},"wireId":93},{"source":{"component":3,"pin":17},"destination":{"component":7,"pin":0},"wireId":94},{"source":{"component":3,"pin":18},"destination":{"component":7,"pin":1},"wireId":95},{"source":{"component":3,"pin":19},"destination":{"component":7,"pin":2},"wireId":96},{"source":{"component":3,"pin":20},"destination":{"component":7,"pin":3},"wireId":97},{"source":{"component":3,"pin":21},"destination":{"component":7,"pin":4},"wireId":98},{"source":{"component":3,"pin":22},"destination":{"component":7,"pin":5},"wireId":99},{"source":{"component":3,"pin":23},"destination":{"component":7,"pin":6},"wireId":100},{"source":{"component":3,"pin":24},"destination":{"component":7,"pin":7},"wireId":101},{"source":{"component":7,"pin":15},"destination":{"component":6,"pin":1},"wireId":104},{"source":{"component":7,"pin":14},"destination":{"component":6,"pin":0},"wireId":105},{"source":{"component":7,"pin":13},"destination":{"component":8,"pin":1},"wireId":106},{"source":{"component":7,"pin":12},"destination":{"component":8,"pin":0},"wireId":107},{"source":{"component":7,"pin":11},"destination":{"component":9,"pin":1},"wireId":108},{"source":{"component":7,"pin":10},"destination":{"component":9,"pin":0},"wireId":109},{"source":{"component":7,"pin":9},"destination":{"component":10,"pin":1},"wireId":110},{"source":{"component":7,"pin":8},"destination":{"component":10,"pin":0},"wireId":111},{"source":{"component":8,"pin":2},"destination":{"component":11,"pin":0},"wireId":112},{"source":{"component":6,"pin":2},"destination":{"component":11,"pin":1},"wireId":113},{"source":{"component":10,"pin":2},"destination":{"component":12,"pin":0},"wireId":114},{"source":{"component":9,"pin":2},"destination":{"component":12,"pin":1},"wireId":115},{"source":{"component":12,"pin":2},"destination":{"component":13,"pin":0},"wireId":116},{"source":{"component":11,"pin":2},"destination":{"component":13,"pin":1},"wireId":117},{"source":{"component":13,"pin":2},"destination":{"component":0,"pin":32},"wireId":118},{"source":{"component":3,"pin":24},"destination":{"component":0,"pin":30},"wireId":119},{"source":{"component":0,"pin":19},"destination":{"component":15,"pin":0},"wireId":120},{"source":{"component":15,"pin":1},"destination":{"component":14,"pin":1},"wireId":121},{"source":{"component":0,"pin":18},"destination":{"component":16,"pin":0},"wireId":122},{"source":{"component":16,"pin":1},"destination":{"component":14,"pin":0},"wireId":123},{"source":{"component":17,"pin":2},"destination":{"component":0,"pin":31},"wireId":124},{"source":{"component":14,"pin":2},"destination":{"component":17,"pin":1},"wireId":125},{"source":{"component":2,"pin":26},"destination":{"component":17,"pin":0},"wireId":126},{"source":{"component":16,"pin":1},"destination":{"component":18,"pin":1},"wireId":127},{"source":{"component":0,"pin":16},"destination":{"component":19,"pin":0},"wireId":129},{"source":{"component":19,"pin":1},"destination":{"component":18,"pin":0},"wireId":130},{"source":{"component":0,"pin":7},"destination":{"component":20,"pin":0},"wireId":133},{"source":{"component":0,"pin":15},"destination":{"component":20,"pin":1},"wireId":134},{"source":{"component":0,"pin":15},"destination":{"component":21,"pin":1},"wireId":135},{"source":{"component":2,"pin":25},"destination":{"component":21,"pin":0},"wireId":136},{"source":{"component":22,"pin":2},"destination":{"component":23,"pin":0},"wireId":139},{"source":{"component":18,"pin":2},"destination":{"component":23,"pin":1},"wireId":140},{"source":{"component":24,"pin":2},"destination":{"component":0,"pin":29},"wireId":141},{"source":{"component":23,"pin":2},"destination":{"component":24,"pin":1},"wireId":142},{"source":{"component":16,"pin":1},"destination":{"component":25,"pin":1},"wireId":143},{"source":{"component":0,"pin":16},"destination":{"component":25,"pin":0},"wireId":144},{"source":{"component":25,"pin":2},"destination":{"component":26,"pin":1},"wireId":145},{"source":{"component":26,"pin":2},"destination":{"component":24,"pin":0},"wireId":146},{"source":{"component":20,"pin":2},"destination":{"component":27,"pin":1},"wireId":147},{"source":{"component":21,"pin":2},"destination":{"component":27,"pin":0},"wireId":148},{"source":{"component":21,"pin":2},"destination":{"component":28,"pin":0},"wireId":149},{"source":{"component":28,"pin":1},"destination":{"component":22,"pin":1},"wireId":150},{"source":{"component":20,"pin":2},"destination":{"component":29,"pin":0},"wireId":151},{"source":{"component":29,"pin":1},"destination":{"component":22,"pin":0},"wireId":152},{"source":{"component":27,"pin":2},"destination":{"component":26,"pin":0},"wireId":153}]}} diff --git a/build/.DS_Store b/build/.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..940e942902c4c95c53cc11d73aa9ce43019c31f2 GIT binary patch literal 6148 zcmeH~J!%6%427R!7lt%jx}3%b$PET#pTHMLVK4#Pfk0Bv(ew1vWSu%J;R&QS(yZ9s zuh>}uu>I%x1(*PA=&sm#n3*wO;SD!jzD^(a>-+t}idTWBh?%i6VYXk}5)lvq5fA|p z5P<~|$Wt7f=LJ2J9z_I1U>OAb`_SmFy>z6;r-LCz0P33MFs@^kpf)d1d+A7Jg=RH9 zShZS=AzqJmYOCvd=}66XSPdUmcQ&75XqN4;#)M`)L_q{ZU`Ak-`Q+#Sk^bBKKWkAc z0wVCw2-x~?I_&vUb+$gdp4VTi>gz$L#^nq@egc^IQM{#xaliS3+Dk_&D>VHG1O^2W H_)`MkK;;pJ literal 0 HcmV?d00001 diff --git a/build/._.DS_Store b/build/._.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..2fa28b3a2f61d0194c5655c9dc024a76dd92bb4b GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIhYCu0iY;W;207T z1eDkT(ZNuGRne&6Xb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&ot`f#!iQ z7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF37MdN7 literal 0 HcmV?d00001 diff --git a/build/alu/full/index.html b/build/alu/full/index.html new file mode 100755 index 0000000..f6bbd5b --- /dev/null +++ b/build/alu/full/index.html @@ -0,0 +1,66 @@ + + + + + + + Build an ALU + + + + +

Time to put it all together

+

Now we've built the constituent parts, it's now time to put everything together into our ALU chip.

+

The ALU has two outputs: the 8-bit result of the operation that was performed, and a 4-bit "flags" value which contains information about the calculation.

+ flags +

You should set the flags according to the following logic:

+
+ + + + + + + + +
FlagLogic
Overflow1 if the addition of two numbers with the same sign bit produces a result with a different sign, or if the subtraction of two numbers with different signs produces a result with the same sign as the number being subtracted.
0 otherwise.
Carry / Borrow1 if an addition or subtraction operation results in a carry / borrow.
0 otherwise.
Negative flag1 if the sign bit (most significant bit) of the result is 1.
0 otherwise.
Zero flag1 if every bit of the result is 0.
0 otherwise.
+
+

The ALU has three inputs: the first and second 8-bit operands, and a 4-bit "opcode" which selects the operation to be performed.
This processor's ALU will use the following opcodes:

+
+ + + + + + + + + + + + + + +
OpcodeOperationExplaiation
0000add Adds the second operand to the first, setting the carry in to 0.
0001subtract (sub)Subtracts the second operand from the first, setting the carry in to 0.
0010add with carry
(adc)
Adds the second operand to the first, setting the carry in to the value of the carry flag.
0011subtract with borrow
(subb)
Subtracts the second operand from the first, setting the carry in to the value of the carry flag.
0100nandEach bit of the output is the result of NANDing together the respective bits of each operand.
0101xorEach bit of the output is the result of XORing together the respective bits of each operand.
0110shift left
(sll)
Each bit of operand 1 is shifted to the left by the number of places specified by operand 2.
0111shift right
(srl)
Each bit of operand 1 is shifted to the right by the number of places specified by operand 2.
1XXXmove
(mov)
Operand 2 is passed straight through to the result. No operation is performed.
+
+

This is the most complicated part of the process, and it's OK if you don't quite understand everything yet. You can use the green links to get more information about certain words, and now might be a good time to ask your tutor for help if you are truly stuck.

+ +

Start building

+ +

+ Once you are finished, you can return to the CPU. +

+ + diff --git a/build/alu/index.html b/build/alu/index.html new file mode 100755 index 0000000..3d8ab70 --- /dev/null +++ b/build/alu/index.html @@ -0,0 +1,42 @@ + + + + Build an ALU + + + + +

Build an ALU!

+

The ALU is the chip that's responsible for performing all the calculations this processor can do. It's far too complex to build all in one go, however, so we have to break it down into component parts.

+

+ Below is a list of all the parts that we need to make. They have to be done in order, because each one builds on the one before! Make sure you have a multiplexer built first, because we will need this! +

+

Addition

+
    +
  1. half adder
  2. +
  3. full adder
  4. +
  5. 8-bit ripple carry adder
  6. +
+

Subtraction

+
    +
  1. 8-bit inverter
  2. +
  3. subtract unit
  4. +
  5. add / subtract unit
  6. +
+

Logic

+
    +
  1. nand/xor gate
  2. +
  3. 8-bit nand/xor unit
  4. +
  5. left/right shift bit
  6. +
  7. shift n bits unit
  8. +
  9. logic unit
  10. +
+

Final boss

+
    +
  1. full ALU
  2. +
+

+ Once you are finished, you can return to the CPU. +

+ + diff --git a/build/css/._ibm.woff b/build/css/._ibm.woff new file mode 100755 index 0000000000000000000000000000000000000000..b54e590bb25beb4781be2c9f41548cd992c1df84 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103v0xFpZ z(ZMhS$hJh&!U*I;#YL0zbM+Dn3UX5Q3QH4<67xzj^HLcM3@i+-&5TTp4Na3RterE8 z@^e$I4b07*jV%nEbS*4R4RuW%on3V;Ok5px4b9x#oGp!=&0P%L&@39|j)uT!2#kin zXb6mkz-S1JhQMeDjE2By2#kinXb6m)5CC;HK^P3=LNYRo6^c@e^Gl18Qx($ki?S6m s^GZ^I-Ol{H#GIT;g`Cv15{0Ck#Jp@^Ul^)uNK>f(hkHeaLGJ&507T+4^8f$< literal 0 HcmV?d00001 diff --git a/build/css/ibm.woff b/build/css/ibm.woff new file mode 100755 index 0000000000000000000000000000000000000000..1f1508d1d8276d85aeb98cd2753e79dd46584204 GIT binary patch literal 9788 zcmZv?V{oO<^FDln-E3^z#>Td}NjA346P$QAHaEtJZDV75W81d%&*xjes^`r!Q&;tU zbzjpx^Jc2%u69?FlmtKkJ_i*)0O>z#P6B}Zoc}*VQu3$5r;g+^MDQQ{#LkGN#3dv@ zecwJg&j0+F01PEnW>x?IqW+W1eZmk(jsDHV&d3n}fcymjK&b!#(51u{32-KEE+hcJ zm)TDZ^#8yCb!TA&{M1o>Qow&XzkPfFpe$@X%s)Rr^J7;70E)AeN@gUMW=5u;HN-zP z9G~F)dc_=Q`RV-hd4KZ%_D2CT4UuSR=K}hy`$+*lpH`NV0I%QH!Q@l-W$}{>e?oi` zW#@;T5$LlnM9QZQ_Y))##t*YDq2zkfr>v$AGGVgV#eAszlN_7fTn34x@m?-#(61QGz(3`qRH zbw=uj8C_i?U0wU1v#YBdkcX?1LWU#!D*@tb3T~`$iheAS7!*{1Hs@%t-xmY~2K-<9 z0Ei!0!DdVZ-v)a&t9rkTl{q&mYGtR_`d( zD115|W67t{YmpX)^8adCj*n03CRxCOdh|U;Vn3p?G6pMSEyD=Ia;T_8kSr{kNI2El zR3UDO@)c3@YT7#2I6KF*QD}Fv}gxGkHNEymJND7qq_Pkq10FS*uqu zsmg|S_opcghyST6N4Q|M1#b@waU=RS9P>I>^{R+Gvd3{&u3o8Th21c^%uyj?Gq+q{ zrGS+%_tUnN6U=5%3$5wTxRt~$S4zp&$I-{v$AD7VqY8p2-lB$-C=Nx5>!EX&2;-)e z?U&mwFUDxdRb&rK&sFdyCpuCWkc^pAy>$_gn^Z2FFqc^e4q(X)BKCuLK2L<)kB47_3AI%+$gcyAAV4GOc?PE>_xLXOq-Mhbanp(=J z#v3<^_#K*MVCX`VyrDaV#e_8Q2Q;ryBzeY_Jc)mpyfLe4$_RTQ`Y?hyYs8W`>Nr99 zm>JPcm=Qz`gDGl+R*%ZI=76($b-Y?%T^jU!b&_j2bsPm}b)15&IlPXHIsS?aX(Idd zFi8S~TXlk-X@VG&$Ei88*V3TxHIFa^3{RgC98ZsOIQM|l&Ril6_NG0!V83N-*7jR?n?%1D|cij0pf=quXSCzDVlpUElUJTRtJmzR5> zc`%VqTu0)zmD?|uG{C6SVZ2xRI0tJpU#SC5sW;jw9M@^2a#+cVPfN;*OKmVYs65SB z{k!IMf4&0t%ii3~=?#*K#vMZnmGXXyDQBVeAkDs`%6991eaP#8(@we?^y`6aDLH~S>a(Fn^H2!@kHQ_Bz zo^@DeA~oSOhAly!m8VW9KI46nc$mk6DwPMwIxO$37%#6_D?~L+A>$@U3@zfxmqi*O zjmaZ!{{xXweDEKEwrFQga!M#=4S!>}S`C$3)aWCIV2EE|*`we(6^ba8ig@sl8w1)& zAM$qeDOJ(1$2F7|Wy}!#HI|_;^cx9$xFJ5lZ@!W2EEUyRIJG>y+3!(Pcmkr6)1xj? z_ERyDgORMjG2WZhC5s8Iv@_$7rDWTs^7F4EDMkkK*Sg%b9!Ty-*x>x>> z=#729Yd>gxX}Fyp{2Yc;IL0k~jD8}gpBbph{ox>zb=kC8X0!Z^da5(o&H^c|q?g_L zj0?>;o9h~X8eGaMTRM(CVXHFXyICVwdB$S!>`W{n9ui|aI`#~dS9q))YCXh=Znousm|bh)cA^wSC4+ZoLm398F+~c$>nQCxvFyqx7S1% zaBo!%53d>@sRtn=7~T=rzKak9P}*vM*PT>ov2tJbIjd~dv0t-m^%Ll+YbSN+p$Abq zjFx#>tXD8U`@91?HvH%G6tVOy!xTZ zJ5i4kkQAP1N8;x~eayMupo}$L1xvFf_4R|Se6cw8Ek}XEh};rgB+|bNR{|rWq)M&n z_B9fHXsD>I6|^Wr2%>>Ijgpl4^tw-qCBTfDrC$AJOndZ1^L6btn})nrB648O@mwFgG15r)^1#g;&VJS&M@% z;@&u+c%A!J9;ldyiWA2^xw!V~;(2>8%6l6`oh}>(laa%qA8KgwCWd%@YEY>6@&SJE zyzf$nyWqdrMHF&7l81(3Y1$jVQ=9o?G@)yNf!OsTQlmF}Pr_{!HpaXQmtuUPU=|_e zK#|d~`u-l+s-&Yn6l&@O^mq^MF33Q64ZZ6xo}`cZ>tzpIL}*BE-4Ep@rhJz2D|0XP zsLJLZduvKUSs7P`$sVv07^IjPbH+Dk$;$M(FBz^MIhvXRdI|~R5qZD8;I92!X zR{-{Cu#i z;4dQO8f+KKg69} zv)Gy^^ssCV)=t<+VqKC1waVEBM$xg0ceh$PQ&7w8GCE(*x3fRG)%*4oF=7EJngXO4 z4hn>s=dlc&=a3NYcw!|p1kZ`%<}UWDj6Vwrz||835ffWn`=oOP{6f#tG(Y`C)^{8c zy16oEu+eglnX959@{qs()J&-`BR`|JWnY;w!Bg~HJw2+krSL7y8^)C}0A~{Vaj_%MqUmQ_@(O4haJiHGv)Hd<6K-6cxs9BXzZvs=f*ZeFvB^J`e>@@DS zjNdK#(om^v7gH_xNLmEsBm$Omb43V*P9t7=*J}{f#huM#qy%IT8e6Gf+1r9M z-=(iBPT@|!OI8=qe{JPa>M49&z&)FyEWxYj+@)Q4b<@8ru(=kp)`|D^FlZcIHh7G# zAJ2vQ9$D$ocR=lDQJa;K@XZU=Q|$#+FlFGsy-0Agn)ejrq zb%=WNv!6(RE9fetGSs5$3HPagof;&0EeGok7b{Ixo1cM6mV z=E!Q&t7+1diX1K|iZXQK-Ec$cFzjH|`evzLrE)xnP!oir!_Z1iM_UsjEF*-9@7Jf4 zqI}6Cd}H-NV_mMPKtmLmB@S(F+glnKRU!`6`fniL`qm0%wLu(INNjK0_;E9D+@cxU z{WW5J_C?Eqw?DLbyTw@CHWt*3v(RT>O|EQ`>QtUDgqPk=eUX4JIotWbD1f){mvyL@=}?fXG|p6pJzQlE1r~LEnOOZAMIT} z%ttI>$w=h)22os7*Tm9_h6i};c!nt5Vy^}RobRglE16G0A8VA6RLyr-Dbz>Q)K))> zoy3U4WU!xb`yprWpRr|yO5vTXDRvD#2xo3@!qA#8WdcbNyi9hypBQ#Omfq`8)s}r_ z$Uf6=N-EkY@WpSY&miE|YX5OLC(t%zM`SAuM|TfqNo83k>5obZ`gg3UY>Gvf@bSj_ zl3lTF8MmTZcCw)bsW>m6-^v(q3?NdYz>+@=d%w7V(`;N?15|G44NQ?6nD;i;Ez=A+ z7`5|v-vy$N=D0#FP#qMjgl$DXrh@W?LRYfe5#*+rIP*kau?*_^@z%rrZ(QNO!=Ysj zMqa6Iy0zwp)85l<&tOPh!9zJ3nGV5_X;a|$dXx25#wy6&k4Zib*(#@faPKkT!B-9} z&VUQLSM03LmyS=zq>qS}~8sq%eNp>bRpAS?D+r#3wU&@I;YukcTe&Dp73~ z9l0w}88SOo@9*o--SA{=4y@%E0i*Z7j-=Q!l~1qxt`1sM{}Pu9aLx|x|K{Q760fg! zmla{nmkcSBjfjnJr(k7~(=06iqx-Y4!JV;UeoCugd%=ZmtTGN`)Upo!T2Y+^E?M^* z&ahl=bfzqFU<`N#;N&PMM=338r>|+A!(C*O zqSxqJ)||3xf2FKabcIgREe$t&viVUaD?Y4>b7dGh&w;knJNRlqu;%-32 z4|c*%`8eh%$<^a(G&^@a7_FH@4Rgy0ptfgr8*SCAo!a+}G-0j(a$Z!R9)G&bYeiA5 zc1T{Hv)gAd?3r+oSr-GU+n(+9?rRZe2@5F>+X!F7*Mcc0E@{^aIRu5B!VfF42}$si z3kp~q=8dg-^E>2?cF8Cz8>ba};8gkkdEuIBm`Jt?Bd4D1{U(*mcWtwj5;^GLBWsRF^b%>V@ zG`m#5SR)tOGKB6QGBmRPM!O*BgE+3yE!om3jxZ2*s)#c_s2+aZA+d{zUR4A*LJj(}7m6*0+LWN3Cb`p; zsZ%)OMb%ACogdd86nM->wc10~UaFQsb)=U!7eubied^;whjdDGyM?~)Iw==zq8*n4 z0;%cFQ6vk37&gWd&F*1qkt8;<6GKJTh^k;mitUHzMflnOcu+90BCDby8?>9)5`=x2 z`Ui+=KJlRX_VtY8AH;D)e6KI{XCBi^)qx?jEZ?1BJeX#SdQgr{D)oPqk#VoTb&3ff zxq^NKXYLQV%V!>ls~ONsji9C@+$U8xISM2sY#u9cIS+(gsn~7*+Ty<+<6dfwT^{gy}D?l@I4+mA0uRTH`^9qd8C zscX`J&hTdTYKYXx8AJSI2nwokr@D@Ejt{p$zcy^!Di?M}{CGfM1$<)TdA~@qW|nIG z&8QbbH%@ruv6+`5_SXqp`>4w^YGc0f7-v^D2ZbPlmQ#MGU5|GH1yUU|s)WRKpJryh`;#_iT|WhTh;C8u%uj6@<6TzpQaz8w$#A98ZJMLE&*CxcxYV zv07zX*ht%5@nIxDWg`j_QsTU%efM^T#1{t|ST9w^Ze`Y*H>td^fmI%X4w1FkqmL=i zDU$S1?E{=p$%@>X(3KDoD(~#?t{O@wAh}Wh8F`erRc^{+r=c-Q@ZJu5Lm8n|Ok{en zND^Cm?kZ}&;P2&t4EinGP&pbEaMxYL6hS0*Ya-1S4iowHPV@HbKH^7>(F93Nq#O8+B&S5BqFst17BMJ`ky+?ryyQ<=4r zc=tdxr^7(hP#tr}Olxra{maz$oBqYKI0=!n`2JOZ=5tqOPH4Y_NheT(XYLP=O{}LE zfw%C8X1IFeLTS(d{YLD87YCiimRqy5j}UPc2HcP(3u zm>*q|&t7-w!)XFywQJv8aCo4)Kwf+uo4BVQ8&3op`jH3!yR1zt8!f#J?nfa5n#0ZX zjK^8WE&uA4c1F@`*q|qv;rD4CfJxT&hn|YJ*Mdf9n=+$UrR!-5D_HE^vy?Wgs|x2A5Ct04OQ;j?1p z;T7%PXL9dri8I3)=knY44z+w?0(Uu4u%&54Q*Y6^4N!CYKG*Lz900bpRD-*yLzJT- zn>(_l;t6od+SjBx(Om4YQ|&9;a-~Y_>hF&gDW)nZyvgYj$ml|HY2x&%>v0f0vO-QZ znql^$g@T+L)~M(wPE(YqmQd2CewO#UEK|!E8PUi-t&Rb;I@oOT8)piSOX1A?SUzBL zfJ}B4z2YbE^X&~C_k0VQeYUApkT$wKL`o-z`(=?wGV!PrN6vRu2l|k1YH9=6o{tk` z#3niKOgE1IXhK$0PJp$Bt!vM81_I$oDs#;H+*^Oll@K;=>2cIoZvt!BQek6=S3p zl1a%UO4_LD&~s}%Bp_U{dRA5ZkWZiuFk>jg3=edg5>0XCeH-K9|2jWW!`lD8Xn#o% zGMQ##k2`bBACR(tVvd*Dx%)oVP&bDs6J-$xa9Tq^BDPkjG>~!Dc#Gup(?cAVm07S= zNJVy~*O$*~ct`LU*SVrk(+cYvE9;}#m%{_n6#fK%wDz~vkM7LtUTZz{HPj|*30aTH|Gk%>p^`Buvw_~pGxGx$lnuH zxkRb`AdfVzOwXV#A1hpUQ2#Eu#$Z11ilMvc=z)Sz-IvX1{Ey&NQFWZ|W~@e) z)fwHMiule~%VzE52rgsmapmsZ)4jX(>r(v75OO@l@UUn~OVOiQ*b29|*fe~{!D5xb z`oJ*qhC)kO1=GKJi`yyWYQ;!W`j)DbM)eVruP7(K)GBm;3>B2eZ8SG%_v4ZKAs!Y~ zCPIAJrUgk5&A3p+3^XcRt#?G5hn>52G10P}MIIHsm`L2f#fqp*j09HiLuz9eH>mpW zf`r+T8}f`jV%i`${M}Ag;%B_e)IE@STodVC^}a7uVE{G2nxrS5X^QW2a0&+KY*EtU z0^vzt+KI#GsopT&l4 zSG#t_VdCeYU@&WVCK#d%RJQOqdJ_M_TlFF8y;s9%;M|y65c#KN_;?AK;r8452A|Q& zK)YqYJlsRM&@At=d5MAPza&o1GLZDM#oty>;w73|B{s%Dl7pQ^e|8L*`FMwNp_9XF z0pi6vhA(_amq2zig+vP*RanM@9%mv0o6P+`4@Ok3PSN)a?z6neaDTmC?WIMOTN(RW ziBj1*T;UaL!FRq{*neY0Y()A~r)!9$t*{vvrcQr`d`UW^pE$BV;laAUr^0wOPrN{i ztu(bmWlPMnq}dLxiNK+}nI&v$2fcT^9JCZ|dR!ob;=EAx>n}d`)?jX0R#$TF2IUO= z{<_?G-OIIk#>Y^>(u&<3Ug-{L-S~f-FA7cB)BT!~u=cFj=UbGD}?R3<6qFr^&P4xsBl~-H*#8kM~ z=x^;B_YzdIem{ja<*DgCY7XU^?J@xcMM=W))$-~IX3r)aw?ccoHF4avHVMXzkL&4) z+;E_OR$IlCA!9q1zsRZuO}k2B5>hp#E*}gg9OC=I23O~>G5opN(!@b79=;5rkw=FU zwtJ3Mr(Zkxj;Ig}g4z-`!Fr33 zBNx#le%6vQrLM{=lLc4VsImr4^rPQPih2u4Lu6I9q-pWHd;6zBUaJCQ30U=}$dO!a z>dO%^f27j0-WL4rMC}L&E~7W`+6N^n#i)P-UcGCwG`#!+FZ6Vn?M(^ zBZ?v$d6b2IUgb;hNQeMJD$^h9vM-!!$;?2uH3bo}A^ZK4mZMmvEjWlg(qRLTRX*fE zJE>uS86W?1Xz`7!_r)+`uLAXfSwK!mOUjVzK!C0X4LkPgU4@3!zjjAZTaMQh)mSF{ zIX8FmTh#e-%hv`JCSnX4QQAcmEeZmMl{p;(lx@#SsDC6W{(QBaDXC^gUX0eZOqVA2=M$Hdpu$DN zH58&Y*=KS5N+emrS zbYKHsD*Z>fi=WmDas58}C>Mz69x@?$6+5U&j(W*H5L*J?5UcD6&N$x~-&}3tlI^gIs_q&Hfkb>DZb4_#?+-!Ljd-Kt$4LdvX+ zo741QpbqU=4JigryKer!K60~nStZM(%mlYi=%_>^XO3~GurF!QLl4W~!<}j|_4da1V0hss6Q22*ke2zx%QNf2 z%U`hS;^FDz@=fhSV`Jrp$2&y%xZ5Ljqv5u;1OBAImurD*@gYiJ(!H}i@FL^cpqJ2N z0+dmZFlj#{j4~iZZDn;t9Cq)IB1(@`ka)~3L$2)%^eU!P4p*VoMTxVkKr5@%TS_lZ z+~jF?-W*7j+FZnE?)ptmO$4~|V5`ryrW7~fc|SXy@Mhcj{wqWg8HuWs8bo_)h)Wzu z-yFc)qgKw19B8BIX1ql^#&;1^WF>^1)&1v243zXL2SR$FE9<%0Mk%qA(l5mJYYLQQomZPyIQAy63d7EL878s%# zSDk~dJ(*1NE!H_k4g`_%Xhqr;(XOVo-U?B!`h8lZJ#2Fk=xcf!6_OD!22)((`1p(Y zA4H8c4teK22f&C->uuVYqw4mWlKaL7HHU@IYefOC?Us<`0vdu%Oaoa`M!0#bsd*Wn@e>*uezuk>|ix_KM8O~;H)ZrHZ1D>~|K7UO{X)=Ynh7#!gA)n9Io@qy~By?~Fq<*n#_FSc8pm9Ukq zBNP2S7fjt3PWy?se-rzr=eh)}&W7zid{t8OZ3+#+cHSihiq>>fY;v%aK*AJI`JAGg zcSb?bb=2^VqbYat`4-Di1GrC0yWs?}AsH{TNTdamLc=Dqa+l~W@d;cikgnJFHeKrB zb)W7e1K|;0<35!sJsm-{lxTMy&pmCG1JBG4jOa2kU$3A#<6@88EdJ~l&`Zz&u1I18 zP1Zmw=ZAY;w68#Zlg({wZ8MWQ$D|O3#QG*o^GA0ZZH3k$bv8tvHFZ|TSA?qSNp2Vj z8Q+#6@Ama^!uVnxh~3yccR{I z0$tD}lHfiniFhFN_hZd2vaD^`tSuhjLAk$O^nVA4A5+^}LcCgHUOaxmcziRsVTrk< z5!?l+S&yk&{0<=4W{Kbr24B*~+(7$o$#_RIgTjkEg2@T?a0Yq0WfZR%Ca?IJFUgp% zSgRbz4)$`BPsBe&t>wWB+}^&@p^P>xo8Y?Utu+h7GiaSZ`E7BSZfh zTY_~S;a5CSOyg|EYZXhCLlp!$yZ~H@|t{`vUi{N zTI8P@@qcQwHBB4iM0gM^1zXXMdktjRuJB8vR*6Uhs3Gv1{ zlGaANlH(6!S=wk}g|*Kgc{A%D*s4EMvOk*z01%%&R*?VeH~Ix2`ilA$i)0+SFA@a- d067Yv`!D{VXgMD0;XgagibVK7>$d{;{{XkP;Ryf$ literal 0 HcmV?d00001 diff --git a/build/css/style.css b/build/css/style.css new file mode 100755 index 0000000..4512be2 --- /dev/null +++ b/build/css/style.css @@ -0,0 +1,104 @@ +html { + background-color: #3A0000; + display: flex; + justify-content: center; +} +body { + margin-top: 15px; + line-height: 1; + padding: 30px; + font-family: sans-serif; + background-color: white; + box-shadow: rgb(142 47 47) 15px 15px; + margin-bottom:20px; +} +* { + margin-top: 5px; + margin-bottom: 5px; + font-family: "IBM VGA"; + } +a { + border-bottom: 1px; + --fgcolor: blue; + color: var(--fgcolor); +} +img { + display: block; + margin: 0 auto; + max-width: 600px; +} +a:hover { + background-color: var(--fgcolor); + color: white; +} +a[href*="//"] { + border-bottom: 1px double; + --fgcolor: green; + target-name: new; + target-new: tab; +} +h1,ul,ol { + margin-top: 13px; + margin-bottom: 13px; +} +ol[data-bin="1"]{ + list-style: none; + padding-left:0; + margin-left: 0; + padding-right:0; + margin-right: 0; +} +ol[data-bin="1"] li { + padding-left: 1rem; + text-indent: -0.7rem; +} +li:before { + font-weight: bolder; + color: red; + content: attr(data-before); + padding-right:10px; +} +p { + margin-bottom: 15px; +} + +table{ + margin: 25px; + width: 50%; + min-width: 500px; + border-collapse: collapse; + +} +thead tr { + background-color: black; + color: white; + border-bottom: 1px solid; +} +td { + padding: 5px; +} +tbody tr:not(:last-child){ + border-bottom: 1px solid; +} +tbody td:not(:first-child) { + border-left: 1px solid; +} +table.c1c td:first-child { + text-align: center; +} +table.c1c tbody td:first-child { + color: red; +} +@media screen and (max-width:600px) { + body { width: 100%; } + img { width: 100%; } +} +@media screen and (min-width:600px) { + body { width: 40%; min-width:600px; max-width:960px; } +} +@font-face { + font-family: 'IBM VGA'; + src: url('../css/ibm.woff'); + font-weight: normal; + font-style: normal; +} diff --git a/build/editor/.DS_Store b/build/editor/.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..5bb0a97e8dae60386ed5c708073aafae853e99b3 GIT binary patch literal 6148 zcmeHK-AcnS6i(c99Yg4af_N41c3=xr2Huo9U%-l9sLYm*S?rpzcJ^Wn`T+VuK8Vlb zIY|l*doAM5f#f^CN%KMT!x-cKGIklW8DkbSM2<>>pt~`&W0Da$j*-u!R7PNZL~|4S z>ww?hVhNkEX;gmy{xr!8$NA(tt@iF-$Ld%;>oItiWl)60GWWy9Jz6(Xrctej(QPs* z$M(Uc%!)9{CJR-N#1lw)xJ$BFmcCqOajt3u9k9AqcWfW8R_@So`oeY3+;v~9hAtR` z^TB%EwGK~CFRsTg=`53PnotgWE7><#!#gNuJ+HwcOJz0%Pn}(75fTH$05L!eY%>Gq zRIqy6OaiT)7$6238NmHPKtuElRvOjT0UchSG2TW*0Uh5Gh{B*}u+j(-5UxuBbtyMb z46e(;FHD|iu+pf@8CNsIIA-Sh@xs;Y;1?>LaZe-l!~ij{$v{h+HlF`i@XItl@;6J! zA_j$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIhYCu0iY;W;207T z1eDkV(ZNuGRne&6Xb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&ot`f#!iQ z7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3RW2Qp literal 0 HcmV?d00001 diff --git a/build/editor/css/style.css b/build/editor/css/style.css new file mode 100755 index 0000000..33e0a8b --- /dev/null +++ b/build/editor/css/style.css @@ -0,0 +1,15 @@ +html, body { + width:100%; + height: 100%; + margin: 0; + overflow: hidden; +} +body { + display: flex; + align-items: center; + justify-content: center; + background-color:black; +} +canvas { + background-color:#36393E; +} diff --git a/build/editor/img/.DS_Store b/build/editor/img/.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..72faf3af26be81e2ed0a790ce2ebfec8890ac1cb GIT binary patch literal 6148 zcmeHK!Ab)$5S`d+w=F^s3gRi?wP+Vq1TSl?2d}Q^L8b1tMHkmi>257j3i|>2E#CbQ ze@ADM6t}isi-c>x(}6h(O=}b|3QQ`HQ^N|?|C8U} z|C1y$G71<47D@q@Z@7&*Zb{eHsm)QX<>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIhYCu0iY;W;207T z1e7=d(ZNuGRne&6Xb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&ot`f#!iQ z7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF35cwUR literal 0 HcmV?d00001 diff --git a/build/editor/img/gates copy/and.png b/build/editor/img/gates copy/and.png new file mode 100755 index 0000000000000000000000000000000000000000..96e6a0072bc06a52ff696e9b4785351d2b14d134 GIT binary patch literal 5873 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 Hu0mjfAs6!4 literal 0 HcmV?d00001 diff --git a/build/editor/img/gates copy/nand.png b/build/editor/img/gates copy/nand.png new file mode 100755 index 0000000000000000000000000000000000000000..fb6eec7fd261075f39ce92dde25140c8d287de31 GIT binary patch literal 7289 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 T6nnaX00000NkvXXu0mjf$o`K) literal 0 HcmV?d00001 diff --git a/build/editor/img/gates copy/nor.png b/build/editor/img/gates copy/nor.png new file mode 100755 index 0000000000000000000000000000000000000000..a739ef4a6dd5eed0f088c5c8d4f90650b32ed5b0 GIT binary patch literal 7742 zcmV-E9>L*>P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D9n(ofK~#8N?Oh49 zT~&GB?_~rM5@d{sVGv~$5FCqwF0ERvf{N7Y5~Q~1s*ASPWxHxyP?rm(wbWu;hbq*y zM8P(IC}_n28H36g2nfL-3rQr9i3~5vd#~U3o&VeSKPT_KJkU(wm;Cpi_jvX`=bn4+ zeSM|DD$tINxK*$Q^dRWbpvQtQN%F5jcZB{sYyzCvKL>qQ+V%lX@a>>mKzD_FGw63n z;KWV^Edx!VVJl!5TN#Vey_;CQ%$4%;tJC z`nm^$7h?q4Jq)2Qe8aSdBfVa=>r!DNqtIUsJ;mx0#O@Ki(|u4y2imu6Bqzi(*U=fpYuklg#b;(;!|r zK2F0^2_7or??9hu#PY!4#F?}EJ?LJ!Od*T$ZUnNh%LX_{u+fO*Y^JH!6}q{h_(*bl zLTy30P4WUv@>d7fmWwtFl)FZrWWJT+1fK_b%1m%~SX!(0f=N4-QzmfLBCHND2a|)E zWT6?zhWA(!fE?Swi19$K%b-ZIU2O=14!%%Z=qvLE*O!YotSuj3zv|~OJh!n|aDx8@ z^lzZ;eu6jZKJX8qk2PYscW~;i2ljI*jWAHH0Tm$IL}*e%u}w${MWsWi2MNHu{>XO> zxd6pmzEc##7m&(vLd12-{vIaytbxbN_1LmI;0+M2;O%;Xqt`98R_&EjW|r4Yn2bn- za%?!*Lg*?2LM_R97#I^K2{q1+KeEnl>3J^lwabU9N=5PH-L@@{Q$HA zwB3L`90|V%y0#I^%7N*#rcc(OlhV8I-l%7cTvc_r)%`cu$y&`)XDR)L<3ieo@OX+&(tyFGjQ3&Df*7X)5}qPScXmj6nl&zSx+ZmTe~> z`{1xGPpBu|gD!-v0(xJZ+?7WiLTziva&l$br(gy&Xyp*j=_?C2tSj$%Y*G2q0C(pK z-go{((ACnmA&j*Z6T5?6PN5%z_0}DyH(MAx>@AW5#f7ZFL~+^%LzfREAE_hftrGv6 zc>BljIgj@2m+ah#u}r(Kq{$tZ%hle9 z1(j`Ebp)&{s1eDkYQa9}>JLaO+6X^z&$@wf&_nlfH=Es9R0wa!`a_hhj$Ug=2XDU} zNa2UO?^BMSk}nc-=aVeP)sgk^vqtKgAlju+Xn1!p<<2nxbDQMG+&!?Yk`IOAGHO}i z+IB66S*St{6=ZGi$KX~{T<);IDs;A=1AYNRJ`$OZ+g-vb6!~vj}P&jPzl=3p3 zXE_*^yxoxpX{%!fIeeyW9%E#WINHgT2a*oe@ztO7oWtI@Jo_ZmZXR}*QR}0LF%g&Z z?Gta}cbd>&-aYLZWgg!5-h(UWz)>LH*!f>jy_DV>U{g1Rp9L?x^w&UW;(|Ds6JR5G zP&3c5En*DMX(4xgl^m0N7}Ta-ys#d2gY}au9y0AD#xai*A`YT4$B9pD$7QPRB*Cw~ z_Lr%XCX`F|KA^mRrk+nQUJtqk#Osr-2DEUKI0STOBbEij`yGBjYg^NHX5IufpyEA@ zNO7UII3Zu;Xl0OtWC}qHFK$Dy5y3K|I6-mF&7dQf#}`autq;^B0}&^H>l&k!^B((k zIb-pI+=7`%@Pg{apsjK%(k&bdY$z}5b#h(0-=VldcR8dwO?cs>fo)4%p1k2=x%17H>z79aZ{UG4JZ28i1!h`qm zsSMtxBYq5e4QQiJ7&bS2bd3cbg?!Xg_}O~2TichnCv>d7&7mBe+ZE;37L5Y5wNW(;#>wfE0LXbMx4sE%$WZ2 z<{7(|@9lRGCv`oDcm;?L(;;Zfg2OT%90B6CQVyBCLpgRD-p{h5mC!LBz4d({boNzt z@`%x3(-wZdSgz$bj|9a7Ob2Dz98Wn&<&e|Ic7SVAlE22&9J&ZH?T%GE^{`v-Qp?`N z?vL>~c*+hF{%3i8uKi%pE}-v7+d>%c#O?t)kpj2jx6j}NRo1hMwbWq=>H(@tdv z#9g(Lx0D4g3f|PXLE098nl=s`3Yyo5W#RB)$L!lXUpB^`U~XUNIzK_SyMhMzY8+n} zXPXQmMvTqmI?qL0h?)W+!X>DFQZ)wXBjZb_Pc*3<1yE@qmAV4LWxW@F`oeq57nUrd zlc4b(po^q!W~A1R3HG>m0d>gHy2aM&FlDM$2kF8`#s&%xTfP9v&7jDe3gpRL(JHeO zK($skLR|LeRLZ`QLFBt>H7E3u?zCBDTy^!8p`qdOwgq>UOP1B=)p_oHHHa5gn-!fF zj*06*FQstPfrpnD?#L%-0Iz`BDG1p{P|btk1?EXrT=>Ppo#U{w?Lk$LqTu3de%@1+(#jk16pw zhfj0xGvV7n{94Yah?b5EzX)EI^6?Q})FjdsDSE^U7Z$7Y8Hwkj@Hx)DdNplAs#Y|8 zVWTb%QZ99nuSRRGMN6x zd&R*=l!K<$Td_NXE(h_^n@!;?5XXHfh!aYkoI362g7j=!7i{);Q4hIgI11GPb)KCf zQRYCnbKn}R;Fb~MPB(+&82Xr>V{M}!HrJtea8HQ+l}AkVgCsi-yiNdP(I%Ch?CuNw z946ICJN+z!JmTxcp>x7V4*xEbreF5UiV!i7xu%Kgg3^ZRzQI@3>>R`uWG~$?*$tQuM%J2d9EK zS)5#B`EfILDQC_;ppa9SwE-vihai?$fttsS`YnO8pS6Ga+h;zz>0my$RIo#|L-e_h zA(nkEqhCHK)dw4$BbCcIfjML;E{ED~Bbim(dD|u2Le6nqtv?4QWOJNDU63#R_2P2kyqh_}Ga9474{rfn#W(t6~=%p+MxGh%4-k)2nk;-P!>&_-Q3!JY52o!6?Dxe=FR z>uQS_+9p=iHZpu3v~El;gEBeuq|?s2z#Z#2$@GD{-8oM&FpQ<^ zV1w*-i5L?)eA6aRDwiMe!n`H(u~u%o+=7pzfwNr2jL`oY}^$0(N+xs`{nHHef$ zcMi+R@v?(tPr4|TRpVf@Ph_8Ex3{BL3VR)o3FVD@%qk~g#RXt2Uj=a+70%rMdF4o+ zOO*rC&XCJ=9erhAyzM;qd57igSQk?8jvKwLcmua$R@fBYROHIZ>4Pmds16o=w7YRZ zI@-Z&xu&c$j|7=E)#19qIa!%#QygWJ%S&acJjluko5~KKa;%5ngI*_$wurA~CGvQv zJ$>c8gP+f#^kU&hqi=0Q%*?L4At%aYp6YNp9{ zL>;6$NMX0WQClaJJ$Kl#oPXHSd8O6aIexdjqCA%oytc1h=DyQ(v&aVtFTiHPJ8sl( zf3M>&1E_+igcVL?CFrawYbvah;W*pWC={eYp$s3%vAK-Qt36RG2iymZ>@oOknuQ%tlcR7p5(ZWvibkt3A$vgGAo;-& z()bt`d}2q}1ca^uWx2?sk9un$>5I5}w~8`ssvEM8auIz&)ZGW$TV*CcDd&;v075Kz zw?5^toLts~^0^1@FV`*QcdZ3ZYJKSZ))knW+6EYqTI=$ddG*5nqb02$#d*T-V|B}e zn2AgFrtz#X8mvhGSI4P`O`WnHHv8*9lQY(h4PAp4`5vrVPRJfS>K@$M2I}ODqs{pd zqxdMlQsl_ac*dfeu8)-4Z@(Y_4k#t?rD9V@PsF}y<)w(IDl$A9O@J+Z935C^aa(4qusG7r)6Wj?a8P5 zC`XKK)FIZg*dWD3oF_Wxr$~|lT9p$#=_4LYomh&W6EGJegBRWj(4thX1@#;|6 z)hNfOM%KnAzhw<@_Ji1D*2g^M23K2>T^CH?-8PU^PuNv{Cnll3|lC?A1>Sy9YsX#1k4I z5DQT($oaLL$aSnzBaX6s5mPDU*k)O|WMQjyQ;a-LRJJ*;mKSm6U^(W2)vL;DuDOa^ zFu(UhoDI6L5d}W7$_1nc^zUA|qI~L}JC`kAzkcfCfwcv^T)kv*x$L0_%j>WC{=yp{ zTT*vXfWKQ+KL}v0F9~C_C3%mbN%lpuF&@oD?exJ+`GLFO|!E$hzNOGlq^D!#t4dCb>T?V%gwsf3-)s z_T@IPD%C@oaix6Zj$87i<}G+6aFTe7kzf283-rGd#Fg55q5`#!8{Y@Lioy?H@#=Cs zKT0B4f>)enwHv+RAB}$JtM^Jld+a-*CPi)dyWZ8Yq)> z{DKXU-vp*O2x!Nb?z^YF_eOqCy5e-ucz@4=_kOvuNxZAXb0~>VQt%46HK9gr!Z^T3 zF<5X}`1%veY~IFlcJ8$Mta%Ni7#ytur!fzR5&rH$pm4k}-)XfBGRUekoN|#fo(j#7 z>ts?_P%qBqNoN2MrX&E#Z^#`n4n_Ij;rZ|f-|>-7@Nt$8Hsa<(w|S$1cb$A>EFXUR zDKnZ(b^?O?OC#+bB%Qyiv+?OA{2FxHVs#se1L}nEg?`6H88r^XZIHufn`10yXyU@( z^$8tggf_4Ot^5OM%pt)> zyV{jvY8~WZV+%s8zQ*5w#$XA&$ayWO^)2bm3AS)N&?9!lQTnVf zI#pK?W!l&|$_R9)H8^4S0M<#jJ#kGSWH7~xGbhI;QoW3!>@vb9at?wdvn-YycILZ{ z^?ifsPoH^;WL)T?YM;?};o8 zF1+A=SoUum!XJUQ$ai(Rz+tyZ)NT01yYDfnUmuC_XeB`wM@M~h%Ln^Ls{p#=t@8l! z(eG8Bsg{GvU0$vylglG_tlJ3Ii-k`%`WPFw8c#oMAeZSp%d$tCP}bZ>7I9MfbiOB* zACPXbFJO%XHg8ktY{TqK?jSkHgHbsrC3F&FMajlE5z7HpTa+uCC!tfG{hpX=kNE0G z!m@;8FMp2%}TVFW+@q*+<`I zM_+XFfz+I1dgm>23_`xG=xVy>F}b>B&~BM=ot$b)@su52%Yy83$cgM16x53)>@upa z*Pp?m;d0tlSC+5vGt(aU%WS;m>W9I%D%jGoz(*oAsmJWTN7-j*Tt|6@=!mCGj*e^f z1ZSyQDbRhSw^mGWtqkWRpI3~C<=PLzs zU%7Y1vU1EtU+GRNS14ENHZiFLT0JJ-9=x1<;6X7M?r3lg2<6}!oHTgmCg+n|=j7Hh zt-d0&?c#h2zN7=cW?9ffh2|Hw74SnJ#Hx{d7jfp$ z5%CprHavgUD?2IQL~Hw|M;|RGUp}YYv4q3X0zWhLAI8|GfKeP3ysxQA zeaT+4%0B$cfsbsh3?9*xL-%T8Ov^`^M0PVFg*6H z5i>_Au4RVet*`a?2*_KoKpXVDU5D7>%}X2Ap7IRVQEj!5DlS{Qww!(awdI_-tq;Zt z-pD@<#J}jV%_Da?gP-t!j>55fKdW5x$EQGw(0cx}-mnn|OFZIj$~K`odZLPO9C#9I zs$(}YW;yg43*?Ee2U0&KbX7U$hU+n@*YMYI@|R8-^zWb#gSObGGruWvmow^PFz3Dc zb>#y`*N)-wNnXOx5ZRlgXs7V0Eu85qk$4Q0oW| zeZ{~)nKOT0`Nq6E$`$wC!_P>&f6khB9R3-^za_ifoJYq(8WDj%dHxm(Cm(Wn`TE=V zabjn1J$W8L=_y9`u+@jLX-wO+;=-qR5(G^yK_B%-6cif@nIDvsJ!~!$Sg~epx%BQk z%f<6(8-Td^$H|jI^Lx<;p_=gF%%Pn^_#4reXwGJ)#ix2hhzsoav1Lg@4a#~>2 zNpK!s7}LrPUyf}I!2>x($T6TeC>~#j$()bLyyLcV`Q7vRL;dMbR=2=UVK||DPult; zc25=LA-fdxW(w~({D^YlN&K8R4W4BWe!aa%UGKL)#afT%gfCVVG=Qc zm)&(Ip8)j3Vq<|1lJUz*Ujto9!_x&G+M7Unv-Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D5JpKvK~#8N?V4Se zR!5b`tDmRorW@!t5u6B-OJf$jhuVj3R*zyGc}&pA&wNuwF3yXpP(K2^1A*RHDn*}G2F zIh`_%i9a9Nb^2@Qnz$o=Ui<|F>$H3VFu<$xe~R(Sby@~31t5%9{)>2>K7{TDVBurp z^|1Z`ssL=a+nu4IVe->OR^#=sz6&(~92p(yjEV<0ZbUX)>M|47-w>};rdCcXYW1~J zU#l+-Z`_y!=IDkE8*+^a5B#S1jCeh)MNI(v`V3xQUt8Qt{q6p=Wy==v<|OaTN~Yan zwmd(|`TLd{0QQMn{FG@4O!=aK>`Q|KgK2DRJPmK!gxVaJOkWc7khyQedQk`$4@~Xw zMnal=OUdx?P};h6>*(Od!K`h%ufw|OfrPLC11wU5sXSgu9bmTm+i7%kG)+v5r=Iok zz6|RIfKbaGNEj=Qod$SCW-z6*VQ?T#Y~7khMn-AY8`gLuVZG+JJ&OSZEV-b=*B&Uy zG8cKf(@t%m6sVgv52x+hcZ?2i8qO9fBCJ^-0d&pMq7Wv21(R412_Ri^_yT6+Nzr4e zMBd-uO5@|>>A?pdOalW0*_w$^CZq}NH5t}-@j$V_slv7bFFX*o+)rs_fZj?xT()oD zo+id8FjWt09xiJ#ta|{=K-uw1nn6?A1~i9pcxxBn(21~4X|wi?4?nz9+whTWx1ti( z|LoElpay`#B7kYJkp>vTxC@YF`WZO94)&%y>KxXz0n8lM4?Xly8XRnFdkE$4hzaWh z2v#%ocwl&(K{7buWdOs^DL{&&4$uN%1C2G;Qw|=`)B58NeO#fv4fAKYWFoBb#&3yN zZCLjJ7@(Ap1v@kd-2xgyp2611vhc{I~(bpt@~ zAtVKlfiY78jO>xc0|7EXMn>c8wYfe*Jlk-4!g?S*@W2CU_vG$0G_)}~4Z;IgWmxxk zpm6|2PdESpSfzLs$2-6f`+<@{YXFQc@|?$DN47Aer4?fi>z%uH=|S@_T`m>YtLEKf z6F?lRfDnNg0O3gnDua^&j<5}#;%RP~ZRld1csgS(r^r>>ym@naWd9?RI$zU!ecSUD zF=4&pKPfZ-WQu^n#0^S21LHE_7I0K9dFo2JfbBdWg^uOc$6n4`MqOXpwryM5w|DR8 z76Do#Jn-9MJaWapq-c7e$be;FG{Zdc0K=1a7?*91%76qIIlLuwo;qwewJvg*w5)h~ zwlBfJ&|um%Ihl6v_JO4y)~t!FjVm&&S(O+uA(I9+3~28*=E)V{%)o3wlo+r`{hF)j z*n1-%z>-Eg1BYBPm$M%E(4kIpr2`u{&1@U%q)wW@IZs%Zrwu@UO?*rIGJ^jjqM!X@ zaH-$OC5hn^9^BzHJUpECOzugYzK&|d9VQt{{vx6r`3?ZOj2H!7t*dD}aSKuCTTUuD z<*cd;oalV(}pr^%53_$-H!pnHsv7D_F;BnLFv!a-3CZ^*xisvTY;ZVyVr(bzs5X;`@ zdE(SZ>h+GFRYI3K)hgO`E!!aV8hTMr*=BX|rd=HCXQU$|Bk9pcAN8?N^ih3MVA-N= z1H7T3A@2_09%B6kY`7xsapi%VHf>6K_wKcn3c}NlqC68cxk48UyZ%zuXCJDHR;3hS zZkv5~WJ2IzTUFWlOvoW$vzJmR<5;+TJI&0@q^obgjYggBC9DAr@CwcC+_`gf$BrGo zd3g#-I_dg5@1!@+zM1CVeK$0N{!L8Sdz=jb_kD7o2OS}$3Fk?m=!qaxw$)+n3OS67 zOh>u^Q=tRl=hAnk0tG;+ls(sz4_od-Am@hCqnztqdKUs{Rj3mw;?hyC0RS+T=dq%bl*njU%VF|FBq z82P=1m&)FHLD`!dVSRata(CO(^PQz_)@^t@sp`!30@d?lD7F<{cQ^B4 zqkmvP9q%Jn>)H1SRFu=`EY)>%sR9ltNQNcE1P`O^eXzwvv7K5c7b=VN+ zCwEmY{h?FpBFv1=L4#3Qg}p8)d)kj!GOWShH{6hpsq~9;2=lW`eFm6IycS(Q9cHX4HimyQ}KMs z%lk*$mb6vgkgF|&h`y-9^P}G`0IjrR`^VB#PdzodbJxy1tBU?9rv}13R`y8gBW%Q+ z=q}f1IeX7q-S(v}^jxiD;7x6HuEwP9LLPT%o9)q9_cHQ4C|!r;s9(@}TcbI3)uk{b zw$W(Z^r$>&(o(0q{nP^wS+wigks$P>r)}i~(P!8$bIPg8e}3=1Y{4|$01&D?5Tmeu zv@~dFd(yd{PO@>!To-wjEN@H_IVqrI{TQ%h0jC+GnIP6eHoiPSc@D|l8| zymIuFbn5geW>Me!eOJt>!>0xjTbS~OW$f&kY1_t@{<7WZ&wb|p${cP8yqR+|xw+|u z27pqF1{f3rmIO|1Bo8?5Jmp|_=5{c5OU?9SF^NH7CTw`Hyr`9oa>o(gtt$Yzowz(u zN}X~ptC-%qbt_Fxy_Sw2Kb~$hPb7a3e^JbNxA#QCM=aBs=`(H@a|!#5Ir^t8CRIIq z%@Ze1p?XmZ9HI2^scE zJt=K-yZRWSuf8-b@A=J3FU?-LaygIOM7Xlf;dOUA6SJvi@}`%MygYkZHW*XAk8<-> zNY}4lPe+d)t=}a2@jFy$bWb9qqhslbC*tLVnrjE1cl+3hT&5^-^$8_1l~TzTvB^q7 zje`lqz?E?Bj`xZo?%K@CO0HhLmVSTqC|<>yRwu$0?^^WEZV4jHu~BV`AKbPr?U~%A zW8JW}DjOM0di(0tboJV`bo!K+hB|#&?9&Y+s{kAu8%v*kLT6-2W9%M%lO&46eL3bt zIpp-4+Y~T7@hr1;=y&|aK|K^58|Y?Tr-DuE^6stq^v6H`Z@PTB;c*b*3UK%OaurYE zp;FGp%OO0E^^|WlrbQuKT)2cygk+O(?>L_2Fw0>Ti@%J*1O+nJl`v#|L_fFXXC2AB zjmY}h9)|Ad{CWC~)9F{g`t@uNcua=ZS05CvA4I&7p)F77<=LyE)a`$j7YbNapx$+$$c2YNRZW$+fg381Ol5F`u*u7TORNK~CCWJ2DMZRv4#xu(00fC*+kvW3|BX6EO*kk?n zw=bnvUOCDL>T4b0%4_rGZcYAQs0pCR9;OL8RE;H*6&U&ffCK>sfZEBzyDFB9iekrp zW_tjNeK1$J>gjso#Q&tjhYqK=n;(ccYO&8+apAfYEdsDi)>vgwDvxoUQ42tGUGYeB z(T8cD&$Z!k(dOLDx%9K2{&e<@H{Qs-R>YQqr(omT>q@2ufCV6XS^+VaD}a=*&c;F1)2*9nna9xTPhp;9u1O!C(K>w3vcvOI-Jm^th zepR_Iz5o9E2JP_S!)b07N2`c%voyY#%CuCud^<*d9?UsK__ z6fFs$0dky1UKh(tsPgnZapJY~>`#6&d*%!u{3{|{KkSwInxY1PfF%d>-i;8hzF`o~ zIlXl0a{9p!emKqRCQ+H*d_RgFpYd&#t0X_m1xGO&sL;8qpaaAMYGEaKQN<1}uL_ zUZ=%W0eBZCOzYvhPCaxt0C_O*fLNywp4X T?+z7@00000NkvXXu0mjf_>MUw literal 0 HcmV?d00001 diff --git a/build/editor/img/gates copy/or.png b/build/editor/img/gates copy/or.png new file mode 100755 index 0000000000000000000000000000000000000000..3bcadfd75a8fe522c4465da76a59bb77806b0d3a GIT binary patch literal 6725 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 bMJfLeWzFl95^;cN00000NkvXXu0mjfD7KvU literal 0 HcmV?d00001 diff --git a/build/editor/img/gates copy/xnor.png b/build/editor/img/gates copy/xnor.png new file mode 100755 index 0000000000000000000000000000000000000000..ab8cfe5a7ed459d759865521f3d1446825f8a02b GIT binary patch literal 8349 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 literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/._nand.png b/build/editor/img/gates/._nand.png new file mode 100755 index 0000000000000000000000000000000000000000..fb1c285d01b4309d24ef8e77e8a85a977f7549e8 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1XRfj(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3Ekqsf literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/._nor.png b/build/editor/img/gates/._nor.png new file mode 100755 index 0000000000000000000000000000000000000000..f44c99269fbbdc16268931ddb077b3fe74130ece GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1XRfd(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3{ze__ literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/._not.png b/build/editor/img/gates/._not.png new file mode 100755 index 0000000000000000000000000000000000000000..c38b15965d7c6f71ddcc9d414c140d77c1a2689a GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1XL*i(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3Tr(Z= literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/._or.png b/build/editor/img/gates/._or.png new file mode 100755 index 0000000000000000000000000000000000000000..534b34a21ab2ad8051dac9fc78c0fb4c086de846 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1eE##(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3dgmV5 literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/._xnor.png b/build/editor/img/gates/._xnor.png new file mode 100755 index 0000000000000000000000000000000000000000..b556ca402392d3e8a0262e59f808f58c5895c4f8 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1XRfm(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3&sQDk literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/._xor.png b/build/editor/img/gates/._xor.png new file mode 100755 index 0000000000000000000000000000000000000000..83f6eb47039d07154accf75c14696f31ee6827df GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1eE#&(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF39SI)O literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/and.png b/build/editor/img/gates/and.png new file mode 100755 index 0000000000000000000000000000000000000000..ca5be7b4de30eb6e381ac18e5af95040c443401d GIT binary patch literal 2063 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 Zua71$Yp-T&gFWAQs?>DF;pC-j{s$*%-dq3x literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/or.png b/build/editor/img/gates/or.png new file mode 100755 index 0000000000000000000000000000000000000000..d34225eab2f62231f54118d05d04db650389ca28 GIT binary patch literal 3887 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%0DZbX~4ZE0vaG+E|}s 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 literal 0 HcmV?d00001 diff --git a/build/editor/img/gates/xor.png b/build/editor/img/gates/xor.png new file mode 100755 index 0000000000000000000000000000000000000000..59d2bc822e45ee771c99a0a2865da9ea2f2ff719 GIT binary patch literal 3843 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 literal 0 HcmV?d00001 diff --git a/build/editor/index.php b/build/editor/index.php new file mode 100755 index 0000000..f8c742e --- /dev/null +++ b/build/editor/index.php @@ -0,0 +1,22 @@ + + + Component editior +\n"); + } + if(!isset($_GET['edit'])) { echo("\n"); } +?> + + + + + + + + + + + + + diff --git a/build/editor/js/bk/chips.js b/build/editor/js/bk/chips.js new file mode 100755 index 0000000..96cd480 --- /dev/null +++ b/build/editor/js/bk/chips.js @@ -0,0 +1,187 @@ +chips = { + "nand": { + image: "img/gates/nand.png", + inputs: 2, + pins : [0,0,0], + subComponents : [], + wires : [] + }, + "not": { + image: "img/gates/not.png", + inputs: 1, + pins: [0,0], + subComponents: ["nand"], + wires: [ + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 0 } + }, + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 1 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 0, pin: 1 } + } + ] + }, + "and": { + image: "img/gates/and.png", + inputs: 2, + pins : [0,0,0], + subComponents : ["nand", "nand"], + wires : [ + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 0 }, + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 1, pin: 1 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 2, pin: 0 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 2, pin: 1 } + }, + { + source: { component: 2, pin: 2 }, + destination: { component: 0, pin: 2 } + } + ] + }, + "or": { + image: "img/gates/or.png", + inputs: 2, + pins: [0,0,0], + subComponents : ["nand","nand","nand"], + wires : [ + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 0 }, + }, + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 1 } + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 2, pin: 0 } + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 2, pin: 1 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 3, pin: 0 } + }, + { + source: { component: 2, pin: 2 }, + destination: { component: 3, pin: 1 } + }, + { + source: { component: 3, pin: 2 }, + destination: { component: 0, pin: 2 } + } + ] + }, + "xor": { + image: "img/gates/xor.png", + inputs:2, + pins: [0,0,0], + subComponents: ["nand","nand","nand", "nand"], + wires : [ + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 0 } + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 1, pin: 1 } + }, + { + source: { component: 0, pin: 0 }, + destination: { component: 2, pin: 0 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 2, pin: 1 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 3, pin: 0 } + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 3, pin: 1 } + }, + { + source: { component: 2, pin: 2 }, + destination: { component: 4, pin: 0 } + }, + { + source: { component: 3, pin: 2 }, + destination: { component: 4, pin: 1 } + }, + { + source: { component: 4, pin: 2 }, + destination: { component: 0, pin: 2 } + } + + ] + }, + "nor": { + inputs:2, + image: "img/gates/nor.png", + pins: [0,0,0], + subComponents: ["or","not"], + wires: [ + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 0 } + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 1, pin: 1 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 2, pin: 0 }, + }, + { + source: { component: 2, pin: 1 }, + destination: { component: 0, pin: 2 } + } + ] + }, + "xnor": { + image: "img/gates/nor.png", + pins: [0,0,0], + subComponents: ["xor","not"], + wires: [ + { + source: { component: 0, pin: 0 }, + destination: { component: 1, pin: 0 } + }, + { + source: { component: 0, pin: 1 }, + destination: { component: 1, pin: 1 } + }, + { + source: { component: 1, pin: 2 }, + destination: { component: 2, pin: 0 }, + }, + { + source: { component: 2, pin: 1 }, + destination: { component: 0, pin: 2 } + } + ] + } + + +} diff --git a/build/editor/js/bk/components.js b/build/editor/js/bk/components.js new file mode 100755 index 0000000..58fdd77 --- /dev/null +++ b/build/editor/js/bk/components.js @@ -0,0 +1,205 @@ +class Component { + type; + image; + inputs=0; + pins = []; + subComponents = [this]; + zIndex = []; + wires = []; + position = { x: 0, y: 0 }; + constructor(name){ + this.type = name; + if (!(name in chips)) { + return; + } + var chip = JSON.parse(JSON.stringify(chips[name])); + this.image = chip.image; + this.pins = chip.pins; + this.wires = chip.wires; + this.inputs = chip.inputs; + chip.subComponents.forEach((sc,i)=>{ + this.subComponents.push(new Component(sc)); + this.zIndex.push(this.subComponents[i]); + }); + this.process(); + } + process(){ + if (this.type=="nand"){ + this.pins[2] = (this.pins[0] && this.pins[1])?0:1; + } else { + this.subComponents.forEach(s=>{if(s != this) {s.process()}}); + this.wires.forEach(w=>{ + this.subComponents[w.destination.component].pins[w.destination.pin] = this.subComponents[w.source.component].pins[w.source.pin] + }); + } + return this.pins; + } + addComponent(name){ + var nc = new Component(name); + this.subComponents.push(nc); + this.zIndex.unshift(nc); + } + removeComponent(index){ + this.zIndex = this.zIndex.filter(zEntry=> this.getProperIndex(zEntry) !== index); + this.wires.forEach(w=>{ + if(w.source.component == index) + this.subComponents[w.destination.component].pins[w.destination.pin] = 0; + }); + this.wires = this.wires.filter(w=>w.source.component != index && w.destination.component != index).map(w => { if(w.destination.component>index){w.destination.component-=1};if(w.source.component>index){w.source.component-=1}; return w }); + + this.subComponents.splice(index,1); + console.log("hi"); + console.log(this.subComponents); + + } + sendToFront(index){ + this.zIndex=this.zIndex.filter(zEntry=>this.getProperIndex(zEntry)!==index); + this.zIndex.push(this.subComponents[index]); + } + getProperIndex(zEntry){ + return this.subComponents.indexOf(zEntry); + } + connect(source,destination,wid){ + var sourceIsInput,destinationIsOutput; + sourceIsInput=destinationIsOutput=0; + if (source.pin < this.subComponents[source.component].inputs) + sourceIsInput = true; + if (destination.pin >= this.subComponents[destination.component].inputs) + destinationIsOutput = true; + source = {component:source.component, pin:source.pin}; + destination={component:destination.component,pin:destination.pin}; + if(source.component == 0){ // if the source is the chip itself + if(destination.component == 0){ // should be direct connection between input and output pins + if(!(sourceIsInput&&destinationIsOutput)){ // if not, + if((!sourceIsInput&&!destinationIsOutput)){ // is it backwards? + var tmp=source; + source=destination; + destination=tmp; + } else { // no, so it's wrong + console.log("1"); + return false; + } + } else { + // connection between chip and component - both should be inputs or both should be outputs + if(!((sourceIsInput&&!destinationIsOutput)||(!sourceIsInput && destinationIsOutput))){ + // if not, we know something must be wrong. there is no reason ever for an output pin on a component to go to an input pin or vice versa. + console.log("2"); + return false; + } else if(!sourceIsInput&&!destinationIsOutput) { + + } + } + } + } else { + if(destination.component == 0){ + //connection between component and chip! both inputs or both outputs + if(!((sourceIsInput&&!destinationIsOutput)||(!sourceIsInput && destinationIsOutput))){ + console.log("3"); + return false; + } + } else { // connection between two components. source must be an output and destination must be input. cannot be same type. + //if same type + + if(!((sourceIsInput&&destinationIsOutput)||(!sourceIsInput&&!destinationIsOutput))){ + console.log("4"); + return false; + } + if(sourceIsInput&&destinationIsOutput){ // if that happened its mixed up + var tmp = source; + tmp=destination; + destination=tmp; + } + } + + } + /* + var sourceShouldBeInput,destinationShouldBeOutput,sourceIsInput, destinationIsOutput; + sourceShouldBeInput = destinationShouldBeOutput = sourceIsInput = destinationIsOutput = false; + if (source.pin < this.subComponents[source.component].inputs) + sourceIsInput = true; + if (destination.pin >= this.subComponents[destination.component].inputs) + destinationIsOutput = true; + if(source.component==0) + sourceShouldBeInput=true; + if(destination.component==0) + destinationShouldBeOutput=true; + + if(sourceIsInput&&!sourceShouldBeInput){ + if(destinationIsOutput&&!destinationShouldBeOutput){ + var tmp = source; + source = destination; + destination = tmp; + } else { + if( + console.log("no bc source is input xor destination is output"); + console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput}); + return false; + } + } else if(destinationIsOutput&&!destinationShouldBeOutput) { + console.log("no bc destination is output"); + console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput}); + return false; + } + if(!sourceIsInput&&sourceShouldBeInput){ + if(!destinationIsOutput&&destinationShouldBeOutput){ + var tmp=source; + source=destination; + destination=tmp; + } else { + console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput}); + console.log("no bc source is output xor destination is input"); + return false; + } + } else if(!destinationIsOutput&&destinationShouldBeOutput) { + console.log("no bc destination is input"); + console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput}); + return false; + } + console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput}); + /* + if (sourceIsInput && destinationIsOutput) { + if (source.component==0||destination.component==0) + return false; + var tmp = source; + source=destination; + destination = tmp; + } else if (sourceIsInput || destinationIsOutput) { + if (!((sourceIsInput && source.component==0)||(destinationIsOutput && destination.component==0))) + return false; + } else { + if(source.component==0||destination.component==0){ + var tmp=source; + source=destination; + destination=tmp; + } + } + */ + this.wires = this.wires.filter(w=>JSON.stringify(w.destination)!=JSON.stringify(destination)); + this.wires.push({ source: source, destination: destination, wireId:wid }); + return true; + + } + disconnect(source,destination){ + this.wires = this.wires.filter(w=>JSON.stringify(w)!=JSON.stringify({source:source,destination:destination})); + } + addPin(isInput){ + if(isInput){ + this.inputs++; + this.pins.unshift(0); + this.wires.forEach(w=>{ if(w.source.component==0){w.source.pin+=1} }); + } else { + this.pins.push(0); + } + } + removePin(i){; + this.wires = this.wires.filter(w=>!((w.source.component==0 && w.source.pin == pin)||(w.destination.component==0 && w.destination.pin == pin))); + if(i{ if(w.source.component==0){w.source.pin-=1}}); + } else { + this.pins.pop(); + } + } +} + + diff --git a/build/editor/js/bk/index.js b/build/editor/js/bk/index.js new file mode 100755 index 0000000..d03a4e9 --- /dev/null +++ b/build/editor/js/bk/index.js @@ -0,0 +1,229 @@ +var canvas, ctx +var selectedItem +var mouseisdown +var chip = new Component("main"); +var pinImages = []; +var wireVisuals = []; +var wireBeingDrawn = []; +images = {}; +var x; +document.addEventListener("DOMContentLoaded", function(event){ + canvas = document.getElementById('logicsim'); + canvas.addEventListener("mousedown",selectItem); + canvas.addEventListener("mouseup", function(){mouseisdown=false}); + canvas.addEventListener("mousemove",mousemove); + document.addEventListener("keydown",checkKey); + ctx = canvas.getContext('2d'); + preloadAssets(); + requestAnimationFrame(drawCanvas); + x=setInterval(function(){chip.process()},1); +}); +function getMousePos(c,e){ + var rect = c.getBoundingClientRect(); + return { + x: e.clientX - rect.left, + y: e.clientY - rect.top + } +} +function checkKey(e){ + e=e||window.event; + if(e.keyCode==27){ + selectedPin={component:-1,pin:-1}; + wireBeingDrawn=[]; + } +} +function isInside(c,point){ + return ( point.x > c.position.x && point.x < c.position.x + images[c.type].width) && + ( point.y > c.position.y && point.y < c.position.y + images[c.type].height); +} +function isInsidePin(p,point){ + return Math.sqrt(Math.pow((p.position.x-point.x),2)+Math.pow((p.position.y-point.y),2)) < p.radius; +} +var clickpos; +var nWireAttempts=0; +var selectedPin = {component:-1,pin:-1}; +var hoveredPin = {component:-1,pin:-1,type:-1}; +function selectItem(e){ + pos = getMousePos(canvas, e) + if(hoveredPin.component>=0){ + if(hoveredPin.type==1){ + chip.pins[hoveredPin.pin]=1-chip.pins[hoveredPin.pin]; + } else { + if(wireBeingDrawn.length>0){ + if(chip.connect(selectedPin, hoveredPin, nWireAttempts)){ + wireBeingDrawn[wireBeingDrawn.length-1]={component:hoveredPin.component,pin:hoveredPin.pin}; + wireVisuals.push({wireId:nWireAttempts,path:wireBeingDrawn.slice()}); + wireBeingDrawn=[]; + selectedPin={component:-1,pin:-1}; + nWireAttempts+=1; + } else { + console.log("noooo"); + } + } else { + wireBeingDrawn.push({component:hoveredPin.component,pin:hoveredPin.pin}); + wireBeingDrawn.push({x:pos.x,y:pos.y}); + selectedPin = {component:hoveredPin.component,pin:hoveredPin.pin}; + } + } + } else { + if(wireBeingDrawn.length>0){ + wireBeingDrawn[wireBeingDrawn.length-1]={x:pos.x,y:pos.y}; + wireBeingDrawn.push({x:pos.x,y:pos.y})//slice()); + } + } + chip.zIndex.forEach(function(c,i){ + if (isInside(c, pos) && ctx.getImageData(pos.x,pos.y,1,1).data[3]) { + mouseisdown = true; + clickpos = pos; + chip.sendToFront(chip.getProperIndex(c)); + // DELETE THIS LATER // + return; + } + + }); +} +var pos; +function mousemove(e){ + pos = getMousePos(canvas,e); + if(wireBeingDrawn.length>0){ + wireBeingDrawn[wireBeingDrawn.length-1]={x:pos.x,y:pos.y}; + } + if(mouseisdown){ + last = chip.zIndex.length-1; + chip.zIndex[last].position.x -= (clickpos.x - pos.x); + chip.zIndex[last].position.y -= (clickpos.y - pos.y); + clickpos = pos; + } + if(!pinImages.some(pi=>{ + if(isInsidePin(pi,pos)){ + hoveredPin = {component:pi.component,pin:pi.pin,type:pi.type} + return true; + } + })){ + hoveredPin={component:-1,pin:-1}; + } +} +function preloadAssets(){ + Object.entries(chips).forEach(function(c){ + if (!(c[1].image in images)){ + images[c[0]] = new Image(); + images[c[0]].src = c[1].image; + } + }); +} +function makeArr(startValue, stopValue, cardinality) { + var arr = []; + var step = (stopValue - startValue) / (cardinality - 1); + for (var i = 0; i < cardinality; i++) { + arr.push(startValue + (step * i)); + } + return arr; +} +function drawCircle(x,y,radius,colour){ + ctx.beginPath(); + ctx.arc(Math.floor(x),Math.floor(y),radius,0,2*Math.PI,false); + ctx.fillStyle=colour; + ctx.fill(); +} +function drawLine(origin,destination,width,colour){ + ctx.beginPath(); + ctx.moveTo(origin.x,origin.y); + ctx.lineTo(destination.x,destination.y); + ctx.strokeStyle=colour; + ctx.lineWidth=width; + ctx.stroke(); +} +function drawCanvas() { + pI = []; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.canvas.width = 600; + ctx.canvas.height = 600; + ctx.fillStyle="lightgray"; + ctx.fillRect(0,0,20,canvas.height); + //components.slice().reverse().forEach(function(c){ + for(var i=0;ip.component==wireBeingDrawn[0].component && p.pin==wireBeingDrawn[0].pin && p.type==0).position; + else + p1=wireBeingDrawn[i]; + //if(i==wireBeingDrawn.length-2) + // p2=pinImages.find(p=>p.component==wireBeingDrawn[i+1].component&&p.pin==wireBeingDrawn[i+1].pin&&p.type==0).position; + //else + p2=wireBeingDrawn[i+1] + drawLine(p1,p2,3,["black","red"][chip.subComponents[wireBeingDrawn[0].component].pins[wireBeingDrawn[0].pin]]); + } + wireVisuals=wireVisuals.filter(wv=> {return chip.wires.findIndex(w=>w.wireId==wv.wireId)>=0}); + wireVisuals.forEach(wv=>{ + for(var i=0;ip.component==wv.path[0].component && p.pin==wv.path[0].pin && p.type==0).position; + else + p1=wv.path[i]; + if(i==wv.path.length-2) + p2=pinImages.find(p=>p.component==wv.path[i+1].component&&p.pin==wv.path[i+1].pin&&p.type==0).position; + else + p2=wv.path[i+1]; + drawLine(p1,p2,3,["black","red"][chip.subComponents[wv.path[0].component].pins[wv.path[0].pin]]); + } + }); + chip.pins.forEach((p,i)=>{ + if(i{ + img = images[c.type]; + ctx.drawImage(img,c.position.x,c.position.y); + c.pins.forEach((p,i)=>{ + //trueCenterY = (c.position.y+(c.position.y + c.height))/2 + centerX = c.position.x+img.width+5; + otherpins = c.pins.length - c.inputs; + pindex = i - c.inputs; + if(i{ + if (c!==this){ + niceStructure.subComponents.push(c.type); + niceStructure.positions.push(c.position); + } + }); + return JSON.stringify(niceStructure); + + } + constructor(name,direct=false,djson=""){ + this.type = name; + if (!(name in chips) && !direct) { + return; + } + var chip; + if(!direct){ + chip = JSON.parse(JSON.stringify(chips[name])); + } else { + chip = JSON.parse(djson); + } + this.image = chip.image; + this.groups = [1,2,3]//chip.groups || []; + this.pins = chip.pins; + this.wires = chip.wires; + this.inputs = chip.inputs; + this.tooltips = chip.tooltips; + chip.subComponents.forEach((sc,i)=>{ + this.subComponents.push(new Component(sc)); + this.zIndex.push(this.subComponents[i+1]); + if(chip.type=="main"){ + this.subComponents[i+1].position = chip.positions[i]; + } + + }); + this.process(); + } + process(){ + //var startTime = performance.now() + if (this.type=="nand"){ + this.pins[2] = (this.pins[0] && this.pins[1])?0:1; + } else { + this.subComponents.forEach(s=>{if(s != this) {s.process()}}); + this.wires.forEach(w=>{ + this.subComponents[w.destination.component].pins[w.destination.pin] = this.subComponents[w.source.component].pins[w.source.pin] + }); + } + //var endTime = performance.now() + //if(this.type=="main") + // console.log(`Updating ${this.type} took ${endTime - startTime} milliseconds`) + return this.pins; + } + addComponent(name){ + var nc = new Component(name); + this.subComponents.push(nc); + this.zIndex.unshift(nc); + } + removeComponent(index){ + this.zIndex = this.zIndex.filter(zEntry=> this.getProperIndex(zEntry) !== index); + this.wires.forEach(w=>{ + if(w.source.component == index) + this.subComponents[w.destination.component].pins[w.destination.pin] = 0; + }); + this.wires = this.wires.filter(w=>w.source.component != index && w.destination.component != index).map(w => { if(w.destination.component>index){w.destination.component-=1};if(w.source.component>index){w.source.component-=1}; return w }); + + this.subComponents.splice(index,1); + console.log("hi"); + console.log(this.subComponents); + + } + sendToFront(index){ + this.zIndex=this.zIndex.filter(zEntry=>this.getProperIndex(zEntry)!==index); + this.zIndex.push(this.subComponents[index]); + } + getProperIndex(zEntry){ + return this.subComponents.indexOf(zEntry); + } + connect(source,destination,wid){ + var sourceIsInput,destinationIsOutput; + sourceIsInput=destinationIsOutput=0; + if (source.pin < this.subComponents[source.component].inputs) + sourceIsInput = true; + if (destination.pin >= this.subComponents[destination.component].inputs) + destinationIsOutput = true; + source = {component:source.component, pin:source.pin}; + destination={component:destination.component,pin:destination.pin}; + if(sourceIsInput){ + if(source.component == 0){ + if((destinationIsOutput&&destination.component!=0)||(!destinationIsOutput && destination.component==0)){ + console.log(1); + return false; + } + } else { + if(destinationIsOutput && destination.component==0){ + console.log({n:2,c:source.component}); + return false; + } else if (destinationIsOutput||destination.component==0){ + console.log("swap"); + var tmp = source; + source=destination; + destination = tmp; + } else if(!destinationIsOutput&&destination.component==0) { + } else { + console.log(3); + return false; + } + } + } else { + if(source.component==0){ + if((destinationIsOutput&&destination.component!=0)||(!destinationIsOutput&&destination.component==0)){ + console.log("swap"); + var tmp=source; + source=destination; + destination=tmp; + } else { + console.log(4); + return false; + } + + } else { + if(destinationIsOutput&&destination.component!=0){ + console.log(5); + return false; + /* + } else if (!destinationIsOutput){ + console.log("swap"); + var tmp=source; + source=destination; + destination=tmp; +*/ + } else if(destination.component==0&&!destinationIsOutput){ + console.log(6); + return false; + } + } + } + this.wires = this.wires.filter(w=>JSON.stringify(w.destination)!=JSON.stringify(destination)); + this.wires.push({ source: source, destination: destination, wireId:wid }); + return true; + + } + disconnect(source,destination){ + this.wires = this.wires.filter(w=>JSON.stringify(w)!=JSON.stringify({source:source,destination:destination})); + } + addPin(isInput){ + if(isInput){ + this.inputs++; + this.pins.unshift(0); + this.wires.forEach(w=>{ if(w.destination.component==0){w.destination.pin+=1} }); + } else { + this.pins.push(0); + } + } + removePin(i){; + this.wires = this.wires.filter(w=>!((w.source.component==0 && w.source.pin == pin)||(w.destination.component==0 && w.destination.pin == pin))); + if(i{ if(w.source.component==0){w.source.pin-=1}}); + } else { + this.pins.pop(); + } + } +} + + diff --git a/build/editor/js/index.js b/build/editor/js/index.js new file mode 100755 index 0000000..97241fa --- /dev/null +++ b/build/editor/js/index.js @@ -0,0 +1,425 @@ +var canvas, ctx +var selectedItem +var mouseisdown +var chip = new Component("main"); +var pinImages = []; +var wireVisuals = []; +var wireBeingDrawn = []; +images = {}; +var chipoffset=0; +var numUpdates = 0; +var x; +document.addEventListener("DOMContentLoaded", function(event){ + canvas = document.getElementById('logicsim'); + canvas.addEventListener("mousedown",selectItem); + canvas.addEventListener("mouseup", function(){mouseisdown=false}); + canvas.addEventListener("mousemove",mousemove); + document.addEventListener("keydown",checkKey); + document.addEventListener("keyup",function(e){shifted=e.shiftKey}); + ctx = canvas.getContext('2d'); + preloadAssets(); + requestAnimationFrame(drawCanvas); + //x=setInterval(function(){var st = performance.now(); chip.process(console.log(performance.now()-st))},1.1); + y=0 + x=setInterval(function(){chip.process();numUpdates+=1},0.3); + storedChips = localStorage.getItem('chips'); + if(storedChips) chips = JSON.parse(storedChips); +}); +function getMousePos(c,e){ + var rect = c.getBoundingClientRect(); + return { + x: e.clientX - rect.left, + y: e.clientY - rect.top + } +} +function checkKey(e){ + e=e||window.event; + if(e.keyCode==27){ + selectedPin={component:-1,pin:-1}; + wireBeingDrawn=[]; + } else if(e.key=="n"){ + var name = prompt('name new chip or cancel'); + if (name.length){ + chips[name]=JSON.parse(chip.getJSONandName(name)); + localStorage.setItem('chips',JSON.stringify(chips)); + chip = new Component(); + close(); + } + } else if(e.keyCode==8 || e.keyCode==46){if(selectedItem>=0){chip.removeComponent(selectedItem); + wireVisuals.forEach(wv=>{ + wv.path.forEach(p=>{if(p.component>selectedItem){p.component-=1}}); + });}} else if (e.keyCode==37) { + chipoffset+=10; + } else if (e.keyCode==39) { chipoffset-=10}; + shifted=e.shiftKey; +} +function isInside(c,point){ + return ( point.x > c.position.x && point.x < c.position.x + images[c.type].width) && + ( point.y > c.position.y && point.y < c.position.y + images[c.type].height); +} +function isInsidePin(p,point){ + return Math.sqrt(Math.pow((p.position.x-point.x),2)+Math.pow((p.position.y-point.y),2)) < p.radius; +} +var clickpos; +var shifted = 0; +var nWireAttempts=0; +var selectedPin = {component:-1,pin:-1}; +var hoveredPin = {component:-1,pin:-1,type:-1}; +function selectItem(e){ + pos = getMousePos(canvas, e) + + if(pos.y>canvas.height-60){ + chipMenu.forEach(cm=>{ + if((pos.x>cm.topLeft.x && pos.x < (cm.topLeft.x+cm.width))&&(pos.y>cm.topLeft.y&&pos.y<(cm.topLeft.y+40))){ + console.log(cm.type); + chip.addComponent(cm.type); + //.position = {x:pos.x,y:pos.y} + + } else { + } + }); + return; + } + + if(hoveredPin.component>=0){ + if(hoveredPin.type==1){ + if(hoveredPin.pin0){ + if(chip.connect(selectedPin, hoveredPin, nWireAttempts)){ + wireBeingDrawn[wireBeingDrawn.length-1]={component:hoveredPin.component,pin:hoveredPin.pin,shift:shifted,offset:wireBeingDrawn[1].offset}; + wireVisuals.push({wireId:nWireAttempts,path:wireBeingDrawn.slice()}); + wireBeingDrawn=[]; + selectedPin={component:-1,pin:-1}; + nWireAttempts+=1; + } else { + console.log("noooo"); + } + } else { + inp = chip.subComponents[hoveredPin.component].inputs; + defaultOffset = 10; + if(hoveredPin.component == 0 && hoveredPin.pin < inp){ + o = 7*hoveredPin.pin; + rev = 1 + } else if(hoveredPin.component == 0) { + o = 7*(hoveredPin.pin-inp); + rev = -1 + } else if (hoveredPin.component>0 && hoveredPin.pin < inp) { + o = 7*hoveredPin.pin; + rev = -1 + } else { + o = 7*(hoveredPin.pin-inp) + rev = 1 + } + wireBeingDrawn.push({component:hoveredPin.component,pin:hoveredPin.pin,shift:shifted,rev:rev}); + wireBeingDrawn.push({x:pos.x,y:pos.y,shift:shifted,offset:o}); + selectedPin = {component:hoveredPin.component,pin:hoveredPin.pin}; + } + } + } else if(pos.x<20){ + if(typeof editDisabled == 'undefined') + chip.addPin(1); + + //wireVisuals.forEach(wv=>{if(wv.path[0].component==0){wv.path[wv.path.length-1].pin+=1;}}); + return true; + } else if(pos.x>canvas.width-20){ + if(typeof editDisabled == 'undefined') + chip.addPin(); + return true; + } else { + if(wireBeingDrawn.length>0){ + wireBeingDrawn[wireBeingDrawn.length-1]={x:pos.x,y:pos.y,shift:shifted,offset:wireBeingDrawn[1].offset}; + wireBeingDrawn.push({x:pos.x,y:pos.y,shift:shifted,offset:wireBeingDrawn[1].offset})//slice()); + } + } + selectedItem=-1; + chip.zIndex.forEach(function(c,i){ + if (isInside(c, pos) && ctx.getImageData(pos.x,pos.y,1,1).data[3]) { + mouseisdown = true; + clickpos = pos; + chip.sendToFront(chip.getProperIndex(c)); + selectedItem = chip.getProperIndex(c); + console.log(selectedItem); + // DELETE THIS LATER // + return; + } + + }); +} +var pos; +function mousemove(e){ + pos = getMousePos(canvas,e); + if(wireBeingDrawn.length>0){ + o = wireBeingDrawn[wireBeingDrawn.length-1].offset; + wireBeingDrawn[wireBeingDrawn.length-1]={x:pos.x,y:pos.y,shift:shifted,offset:o}; + } + if(mouseisdown){ + last = chip.zIndex.length-1; + chip.zIndex[last].position.x -= (clickpos.x - pos.x); + chip.zIndex[last].position.y -= (clickpos.y - pos.y); + clickpos = pos; + } + if(!pinImages.some(pi=>{ + if(isInsidePin(pi,pos)){ + hoveredPin = {component:pi.component,pin:pi.pin,type:pi.type} + return true; + } + })){ + hoveredPin={component:-1,pin:-1}; + } +} +function preloadAssets(){ + Object.entries(chips).forEach(function(c){ + if (!(c[1].image in images)){ + images[c[0]] = new Image(); + images[c[0]].src = c[1].image; + } + }); + if(typeof loadChip == 'function'){ + loadChip(); + } +} +function makeArr(startValue, stopValue, cardinality) { + var arr = []; + var step = (stopValue - startValue) / (cardinality - 1); + for (var i = 0; i < cardinality; i++) { + arr.push(startValue + (step * i)); + } + return arr; +} +function drawCircle(x,y,radius,colour){ + ctx.beginPath(); + ctx.arc(Math.floor(x),Math.floor(y),radius,0,2*Math.PI,false); + ctx.fillStyle=colour; + ctx.fill(); +} +function drawLine(origin,destination,width,colour,taxi,offset,rev){ + if(!taxi||destination.shift){ + ctx.beginPath(); + ctx.moveTo(origin.x,origin.y); + ctx.lineTo(destination.x,destination.y); + ctx.strokeStyle=colour; + ctx.lineWidth=width; + ctx.stroke(); + } else { + ctx.beginPath(); + ctx.moveTo(origin.x,origin.y); + if(destination.y>origin.y){ + offset = offset*-rev; + } else { + offset = offset * rev; + } + multip = 0.4; + if(rev<0) { + multip = 1-multip; + } + ctx.lineTo(origin.x+(destination.x-origin.x)*multip+offset,origin.y); + ctx.lineTo(origin.x+(destination.x-origin.x)*multip+offset,destination.y); + ctx.lineTo(destination.x,destination.y); + ctx.strokeStyle=colour; + ctx.lineWidth=width; + ctx.stroke(); + } +} +chipMenu = []; +tt = null; +class Tooltip { + constructor(x,y,message,persist=false){ + this.x=x; + this.y=y; + this.message=message; + this.persist=persist; + } + draw(offset){ + //ctx.fillStyle='pink'; + //ctx.fillRect(0,0,canvas.width,canvas.height); + //return; + ctx.fillStyle="rgba(0,0,0,0.65)"; + ctx.font="20px vcr_osd_monoregular"; + ctx.textBaseline="bottom"; + ctx.textAlign="left"; + var width=ctx.measureText(this.message).width+6; + offset=0 + ctx.fillRect(this.x{ + ctx.font = "20px vcr_osd_monoregular" + ctx.fillStyle="#1A3060"; + width=ctx.measureText(chip[0]).width+8; + ctx.fillRect(curX+chipoffset,canvas.height-50,width,40); + ctx.fillStyle="white"; + ctx.fillText(chip[0],curX+chipoffset+4,canvas.height-25); + cm.push({type:chip[0],topLeft:{x: curX+chipoffset, y: canvas.height-50},width:width}); + curX+=width+5; + }); + chipMenu=cm; + + //components.slice().reverse().forEach(function(c){ + for(var i=0;ip.component==wireBeingDrawn[0].component && p.pin==wireBeingDrawn[0].pin && p.type==0).position; + else + p1=wireBeingDrawn[i]; + //if(i==wireBeingDrawn.length-2) + // p2=pinImages.find(p=>p.component==wireBeingDrawn[i+1].component&&p.pin==wireBeingDrawn[i+1].pin&&p.type==0).position; + //else + p2=wireBeingDrawn[i+1] + o=0.5; + if(wireBeingDrawn[i+1].offset != undefined){ + o=wireBeingDrawn[i+1].offset; + } + drawLine(p1,p2,3,["lightgray","red"][chip.subComponents[wireBeingDrawn[0].component].pins[wireBeingDrawn[0].pin]],true,o,wireBeingDrawn[0].rev); + } + wireVisuals=wireVisuals.filter(wv=> {return chip.wires.findIndex(w=>w.wireId==wv.wireId)>=0}); + wireVisuals.forEach(wv=>{ + for(var i=0;ip.component==wv.path[0].component && p.pin==wv.path[0].pin && p.type==0).position; + else + p1=wv.path[i]; + if(i==wv.path.length-2) + p2=pinImages.find(p=>p.component==wv.path[i+1].component&&p.pin==wv.path[i+1].pin&&p.type==0).position; + else + p2=wv.path[i+1]; + drawLine(p1,p2,3,["lightgray","red"][chip.subComponents[wv.path[0].component].pins[wv.path[0].pin]],true,wv.path[1].offset,wv.path[0].rev); + } + }); + currentGroup=-1; + groupn=1; + chip.pins.forEach((p,i)=>{ + if(i{ + if(group.includes(i)) newGroup = n; + }); + if(newGroup>-1 && newGroup==currentGroup) { + centerY -=20*groupn; + groupn++; + } else {groupn=1}; + pI.push({component:0,pin:i,position:{x:centerX,y:centerY},radius:7,type:1}); + secondaryX=(i-1){ + ctx.fillStyle="white"; + old=[ctx.textAlign, ctx.textBaseline]; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.font='11px monospace' + if(!chip.no) + ctx.fillText(Math.pow(2,groupn-1), centerX, centerY); + else if(!chip.no.includes(i)) ctx.fillText(Math.pow(2,groupn-1), centerX, centerY); + ctx.textAlign=old[0]; + ctx.textBaseline=old[1]; + } + currentGroup=newGroup; + }) + chip.zIndex.forEach(c=>{ + img = images[c.type]; + if(img!==undefined&&img.dummy!=1) + ctx.drawImage(img,c.position.x,c.position.y); + else { + ctx.font = "20px vcr_osd_monoregular" + ctx.fillStyle="#1A3060"; + h = parseInt(md5(c.type).substring(1,10),16); + poss_colors = ["white","red","lightblue","pink","yellow","lightgreen","orange","violet"]; + ctx.fillStyle = poss_colors[h%poss_colors.length]; + width = ctx.measureText(c.type).width + 30; + if (c.inputs>c.pins.length/2){ + height = c.inputs * 15 + } else { + height = (c.pins.length-c.inputs)*15; + } + ctx.fillRect(c.position.x,c.position.y,width,height); + ctx.fillStyle="black"; + ctx.fillText(c.type,c.position.x+15,c.position.y+(height/2)+4); + img = {width,height,dummy:1}; + images[c.type]=img; + } + + c.pins.forEach((p,i)=>{ + //trueCenterY = (c.position.y+(c.position.y + c.height))/2 + centerX = c.position.x+img.width+5; + otherpins = c.pins.length - c.inputs; + pindex = i - c.inputs; + if(i=0){ + try{ + drawTooltip(chip.subComponents[hoveredPin.component].tooltips[hoveredPin.pin]); + } catch(ex){console.log(ex)} + } else { + } + if(tt) tt.draw(); + + requestAnimationFrame(drawCanvas); +} diff --git a/build/editor/js/items/CPU_ALU.js b/build/editor/js/items/CPU_ALU.js new file mode 100755 index 0000000..6fa6a50 --- /dev/null +++ b/build/editor/js/items/CPU_ALU.js @@ -0,0 +1,10 @@ +function loadChip(){ + setTimeout(function(){ + chip = new Component("main", true, '{"type":"main","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16,17,18,19],[20],[21,22,23,24,25,26,27,28],[29,30,31,32]],"inputs":21,"tooltips":["operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","opcode","opcode","opcode","opcode","carry/borrow in","result","result","result","result","result","result","result","result","overflow flag","negative flag","carry/borrow flag","zero flag"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["ALU"],"positions":[{"x":467,"y":673}],"wires":[{"source":{"component":1,"pin":32},"destination":{"component":0,"pin":32},"wireId":0},{"source":{"component":1,"pin":31},"destination":{"component":0,"pin":31},"wireId":1},{"source":{"component":1,"pin":30},"destination":{"component":0,"pin":30},"wireId":2},{"source":{"component":1,"pin":29},"destination":{"component":0,"pin":29},"wireId":3},{"source":{"component":1,"pin":28},"destination":{"component":0,"pin":28},"wireId":4},{"source":{"component":1,"pin":27},"destination":{"component":0,"pin":27},"wireId":5},{"source":{"component":1,"pin":26},"destination":{"component":0,"pin":26},"wireId":6},{"source":{"component":1,"pin":25},"destination":{"component":0,"pin":25},"wireId":7},{"source":{"component":1,"pin":24},"destination":{"component":0,"pin":24},"wireId":8},{"source":{"component":1,"pin":23},"destination":{"component":0,"pin":23},"wireId":9},{"source":{"component":1,"pin":22},"destination":{"component":0,"pin":22},"wireId":10},{"source":{"component":1,"pin":21},"destination":{"component":0,"pin":21},"wireId":11},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":12},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":13},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":15},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":16},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":17},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":18},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":19},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":20},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":8},"wireId":21},{"source":{"component":0,"pin":9},"destination":{"component":1,"pin":9},"wireId":22},{"source":{"component":0,"pin":10},"destination":{"component":1,"pin":10},"wireId":23},{"source":{"component":0,"pin":11},"destination":{"component":1,"pin":11},"wireId":24},{"source":{"component":0,"pin":12},"destination":{"component":1,"pin":12},"wireId":25},{"source":{"component":0,"pin":13},"destination":{"component":1,"pin":13},"wireId":26},{"source":{"component":0,"pin":14},"destination":{"component":1,"pin":14},"wireId":27},{"source":{"component":0,"pin":15},"destination":{"component":1,"pin":15},"wireId":28},{"source":{"component":0,"pin":16},"destination":{"component":1,"pin":16},"wireId":29},{"source":{"component":0,"pin":17},"destination":{"component":1,"pin":17},"wireId":30},{"source":{"component":0,"pin":18},"destination":{"component":1,"pin":18},"wireId":31},{"source":{"component":0,"pin":19},"destination":{"component":1,"pin":19},"wireId":32},{"source":{"component":0,"pin":20},"destination":{"component":1,"pin":20},"wireId":33}]}'); + chip.groups = [] + chip.tooltips = ["A","B","nand/xor?","output"]; + },1000) + setTimeout(function(){ + wireVisuals = JSON.parse('[{"wireId":0,"path":[{"component":1,"pin":32,"shift":false,"rev":1},{"component":0,"pin":32,"shift":false,"offset":77}]},{"wireId":1,"path":[{"component":1,"pin":31,"shift":false,"rev":1},{"component":0,"pin":31,"shift":false,"offset":70}]},{"wireId":2,"path":[{"component":1,"pin":30,"shift":false,"rev":1},{"component":0,"pin":30,"shift":false,"offset":63}]},{"wireId":3,"path":[{"component":1,"pin":29,"shift":false,"rev":1},{"component":0,"pin":29,"shift":false,"offset":56}]},{"wireId":4,"path":[{"component":1,"pin":28,"shift":false,"rev":1},{"component":0,"pin":28,"shift":false,"offset":49}]},{"wireId":5,"path":[{"component":1,"pin":27,"shift":false,"rev":1},{"component":0,"pin":27,"shift":false,"offset":42}]},{"wireId":6,"path":[{"component":1,"pin":26,"shift":false,"rev":1},{"component":0,"pin":26,"shift":false,"offset":35}]},{"wireId":7,"path":[{"component":1,"pin":25,"shift":false,"rev":1},{"component":0,"pin":25,"shift":false,"offset":28}]},{"wireId":8,"path":[{"component":1,"pin":24,"shift":false,"rev":1},{"component":0,"pin":24,"shift":false,"offset":21}]},{"wireId":9,"path":[{"component":1,"pin":23,"shift":false,"rev":1},{"component":0,"pin":23,"shift":false,"offset":14}]},{"wireId":10,"path":[{"component":1,"pin":22,"shift":false,"rev":1},{"component":0,"pin":22,"shift":false,"offset":7}]},{"wireId":11,"path":[{"component":1,"pin":21,"shift":false,"rev":1},{"component":0,"pin":21,"shift":false,"offset":0}]},{"wireId":12,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":0}]},{"wireId":13,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":7}]},{"wireId":15,"path":[{"component":0,"pin":2,"shift":false,"rev":1},{"component":1,"pin":2,"shift":false,"offset":14}]},{"wireId":16,"path":[{"component":0,"pin":3,"shift":false,"rev":1},{"component":1,"pin":3,"shift":false,"offset":21}]},{"wireId":17,"path":[{"component":0,"pin":4,"shift":false,"rev":1},{"component":1,"pin":4,"shift":false,"offset":28}]},{"wireId":18,"path":[{"component":0,"pin":5,"shift":false,"rev":1},{"component":1,"pin":5,"shift":false,"offset":35}]},{"wireId":19,"path":[{"component":0,"pin":6,"shift":false,"rev":1},{"component":1,"pin":6,"shift":false,"offset":42}]},{"wireId":20,"path":[{"component":0,"pin":7,"shift":false,"rev":1},{"component":1,"pin":7,"shift":false,"offset":49}]},{"wireId":21,"path":[{"component":0,"pin":8,"shift":false,"rev":1},{"component":1,"pin":8,"shift":false,"offset":56}]},{"wireId":22,"path":[{"component":0,"pin":9,"shift":false,"rev":1},{"component":1,"pin":9,"shift":false,"offset":63}]},{"wireId":23,"path":[{"component":0,"pin":10,"shift":false,"rev":1},{"component":1,"pin":10,"shift":false,"offset":70}]},{"wireId":24,"path":[{"component":0,"pin":11,"shift":false,"rev":1},{"component":1,"pin":11,"shift":false,"offset":77}]},{"wireId":25,"path":[{"component":0,"pin":12,"shift":false,"rev":1},{"component":1,"pin":12,"shift":false,"offset":84}]},{"wireId":26,"path":[{"component":0,"pin":13,"shift":false,"rev":1},{"component":1,"pin":13,"shift":false,"offset":91}]},{"wireId":27,"path":[{"component":0,"pin":14,"shift":false,"rev":1},{"component":1,"pin":14,"shift":false,"offset":98}]},{"wireId":28,"path":[{"component":0,"pin":15,"shift":false,"rev":1},{"component":1,"pin":15,"shift":false,"offset":105}]},{"wireId":29,"path":[{"component":0,"pin":16,"shift":false,"rev":1},{"component":1,"pin":16,"shift":false,"offset":112}]},{"wireId":30,"path":[{"component":0,"pin":17,"shift":false,"rev":1},{"component":1,"pin":17,"shift":false,"offset":119}]},{"wireId":31,"path":[{"component":0,"pin":18,"shift":false,"rev":1},{"component":1,"pin":18,"shift":false,"offset":126}]},{"wireId":32,"path":[{"component":0,"pin":19,"shift":false,"rev":1},{"component":1,"pin":19,"shift":false,"offset":133}]},{"wireId":33,"path":[{"component":0,"pin":20,"shift":false,"rev":1},{"component":1,"pin":20,"shift":false,"offset":140}]}]'); + },2000); +} diff --git a/build/editor/js/items/CPU_MUX.js b/build/editor/js/items/CPU_MUX.js new file mode 100755 index 0000000..e3af947 --- /dev/null +++ b/build/editor/js/items/CPU_MUX.js @@ -0,0 +1,10 @@ +function loadChip(){ + setTimeout(function(){ + chip = new Component("main", true, '{"type":"main","groups":[[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[17,18,19,20,21,22,23,24]],"inputs":17,"tooltips":["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","select","output","output","output","output","output","output","output","output"],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["16:8 mux"],"positions":[{"x":690,"y":308}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":2},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":3},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":4},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":5},"wireId":5},{"source":{"component":0,"pin":6},"destination":{"component":1,"pin":6},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":1,"pin":7},"wireId":7},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":8},"wireId":8},{"source":{"component":0,"pin":9},"destination":{"component":1,"pin":9},"wireId":9},{"source":{"component":0,"pin":10},"destination":{"component":1,"pin":10},"wireId":10},{"source":{"component":0,"pin":11},"destination":{"component":1,"pin":11},"wireId":11},{"source":{"component":0,"pin":12},"destination":{"component":1,"pin":12},"wireId":12},{"source":{"component":0,"pin":13},"destination":{"component":1,"pin":13},"wireId":13},{"source":{"component":0,"pin":14},"destination":{"component":1,"pin":14},"wireId":14},{"source":{"component":0,"pin":15},"destination":{"component":1,"pin":15},"wireId":15},{"source":{"component":0,"pin":16},"destination":{"component":1,"pin":16},"wireId":16},{"source":{"component":1,"pin":17},"destination":{"component":0,"pin":17},"wireId":17},{"source":{"component":1,"pin":18},"destination":{"component":0,"pin":18},"wireId":18},{"source":{"component":1,"pin":19},"destination":{"component":0,"pin":19},"wireId":19},{"source":{"component":1,"pin":20},"destination":{"component":0,"pin":20},"wireId":20},{"source":{"component":1,"pin":21},"destination":{"component":0,"pin":21},"wireId":21},{"source":{"component":1,"pin":22},"destination":{"component":0,"pin":22},"wireId":22},{"source":{"component":1,"pin":23},"destination":{"component":0,"pin":23},"wireId":23},{"source":{"component":1,"pin":24},"destination":{"component":0,"pin":24},"wireId":24}]}'); + chip.groups = [] + chip.tooltips = ["A","B","nand/xor?","output"]; + },1000) + setTimeout(function(){ + wireVisuals = JSON.parse('[{"wireId":0,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":0}]},{"wireId":1,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":7}]},{"wireId":2,"path":[{"component":0,"pin":2,"shift":false,"rev":1},{"component":1,"pin":2,"shift":false,"offset":14}]},{"wireId":3,"path":[{"component":0,"pin":3,"shift":false,"rev":1},{"component":1,"pin":3,"shift":false,"offset":21}]},{"wireId":4,"path":[{"component":0,"pin":4,"shift":false,"rev":1},{"component":1,"pin":4,"shift":false,"offset":28}]},{"wireId":5,"path":[{"component":0,"pin":5,"shift":false,"rev":1},{"component":1,"pin":5,"shift":false,"offset":35}]},{"wireId":6,"path":[{"component":0,"pin":6,"shift":false,"rev":1},{"component":1,"pin":6,"shift":false,"offset":42}]},{"wireId":7,"path":[{"component":0,"pin":7,"shift":false,"rev":1},{"component":1,"pin":7,"shift":false,"offset":49}]},{"wireId":8,"path":[{"component":0,"pin":8,"shift":false,"rev":1},{"component":1,"pin":8,"shift":false,"offset":56}]},{"wireId":9,"path":[{"component":0,"pin":9,"shift":false,"rev":1},{"component":1,"pin":9,"shift":false,"offset":63}]},{"wireId":10,"path":[{"component":0,"pin":10,"shift":false,"rev":1},{"component":1,"pin":10,"shift":false,"offset":70}]},{"wireId":11,"path":[{"component":0,"pin":11,"shift":false,"rev":1},{"component":1,"pin":11,"shift":false,"offset":77}]},{"wireId":12,"path":[{"component":0,"pin":12,"shift":false,"rev":1},{"component":1,"pin":12,"shift":false,"offset":84}]},{"wireId":13,"path":[{"component":0,"pin":13,"shift":false,"rev":1},{"component":1,"pin":13,"shift":false,"offset":91}]},{"wireId":14,"path":[{"component":0,"pin":14,"shift":false,"rev":1},{"component":1,"pin":14,"shift":false,"offset":98}]},{"wireId":15,"path":[{"component":0,"pin":15,"shift":false,"rev":1},{"component":1,"pin":15,"shift":false,"offset":105}]},{"wireId":16,"path":[{"component":0,"pin":16,"shift":false,"rev":1},{"component":1,"pin":16,"shift":false,"offset":112}]},{"wireId":17,"path":[{"component":1,"pin":17,"shift":true,"rev":1},{"component":0,"pin":17,"shift":true,"offset":0}]},{"wireId":18,"path":[{"component":1,"pin":18,"shift":true,"rev":1},{"component":0,"pin":18,"shift":true,"offset":7}]},{"wireId":19,"path":[{"component":1,"pin":19,"shift":false,"rev":1},{"component":0,"pin":19,"shift":false,"offset":14}]},{"wireId":20,"path":[{"component":1,"pin":20,"shift":false,"rev":1},{"component":0,"pin":20,"shift":false,"offset":21}]},{"wireId":21,"path":[{"component":1,"pin":21,"shift":false,"rev":1},{"component":0,"pin":21,"shift":false,"offset":28}]},{"wireId":22,"path":[{"component":1,"pin":22,"shift":false,"rev":1},{"component":0,"pin":22,"shift":false,"offset":35}]},{"wireId":23,"path":[{"component":1,"pin":23,"shift":false,"rev":1},{"component":0,"pin":23,"shift":false,"offset":42}]},{"wireId":24,"path":[{"component":1,"pin":24,"shift":false,"rev":1},{"component":0,"pin":24,"shift":false,"offset":49}]}]'); + },2000); +} diff --git a/build/editor/js/items/alu.js b/build/editor/js/items/alu.js new file mode 100755 index 0000000..1eafa86 --- /dev/null +++ b/build/editor/js/items/alu.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":21,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16,17,18,19],[20],[21,22,23,24,25,26,27,28],[29,30,31,32]]; + chip.no=[29,30,31,32]; + chip.tooltips = ["operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 0","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","operand 1","opcode","opcode","opcode","opcode","carry/borrow in","result","result","result","result","result","result","result","result","overflow flag","negative flag","carry/borrow flag","zero flag"]; +} diff --git a/build/editor/js/items/alu1.js b/build/editor/js/items/alu1.js new file mode 100755 index 0000000..a33c6f0 --- /dev/null +++ b/build/editor/js/items/alu1.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":2,"tooltips":[],"pins":[0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0],[1],[2],[3]] + chip.tooltips = ["A","B","sum", "carry"] +} diff --git a/build/editor/js/items/alu10.js b/build/editor/js/items/alu10.js new file mode 100755 index 0000000..04274f8 --- /dev/null +++ b/build/editor/js/items/alu10.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":12,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10],[12,13,14,15,16,17,18,19]]; + chip.tooltips = ["input","input","input","input","input","input","input","input","shift by","shift by","shift by","left/right?","output","output","output","output","output","output","output","output"]; +} diff --git a/build/editor/js/items/alu11.js b/build/editor/js/items/alu11.js new file mode 100755 index 0000000..bfd8781 --- /dev/null +++ b/build/editor/js/items/alu11.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":18,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[18,19,20,21,22,23,24,25]]; + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","operation select - nand/xor or shift", "operation select - nand/left or xor/right","result","result","result","result","result","result","result","result"]; +} diff --git a/build/editor/js/items/alu2.js b/build/editor/js/items/alu2.js new file mode 100755 index 0000000..89887dc --- /dev/null +++ b/build/editor/js/items/alu2.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":3,"tooltips":[],"pins":[0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0],[1],[2],[3],[4]]; + chip.tooltips = ["A","B","carry in", "sum", "carry out"]; +} diff --git a/build/editor/js/items/alu3.js b/build/editor/js/items/alu3.js new file mode 100755 index 0000000..f7451b1 --- /dev/null +++ b/build/editor/js/items/alu3.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":17,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[17,18,19,20,21,22,23,24],[25]]; + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","carry in","sum","sum","sum","sum","sum","sum","sum","sum","carry out"]; +} diff --git a/build/editor/js/items/alu4.js b/build/editor/js/items/alu4.js new file mode 100755 index 0000000..84c02e9 --- /dev/null +++ b/build/editor/js/items/alu4.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":8,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15]]; + chip.tooltips = ["input","input","input","input","input","input","input","input","output","output","output","output","output","output","output","output"]; +} diff --git a/build/editor/js/items/alu5.js b/build/editor/js/items/alu5.js new file mode 100755 index 0000000..a1f9743 --- /dev/null +++ b/build/editor/js/items/alu5.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":17,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[17,18,19,20,21,22,23,24],[25]]; + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","borrow in","difference","difference","difference","difference","difference","difference","difference","difference","borrow out"]; +} diff --git a/build/editor/js/items/alu6.js b/build/editor/js/items/alu6.js new file mode 100755 index 0000000..5658827 --- /dev/null +++ b/build/editor/js/items/alu6.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":18,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[16],[18,19,20,21,22,23,24,25],[26]]; + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","carry/borrow in","operation select","result","result","result","result","result","result","result","result","carry/borrow out"]; +} diff --git a/build/editor/js/items/alu7.js b/build/editor/js/items/alu7.js new file mode 100755 index 0000000..94d7c3e --- /dev/null +++ b/build/editor/js/items/alu7.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":3,"tooltips":[],"pins":[0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = []; + chip.tooltips = ["A","B","nand/xor?","output"]; +} diff --git a/build/editor/js/items/alu8.5.js b/build/editor/js/items/alu8.5.js new file mode 100755 index 0000000..a9080fd --- /dev/null +++ b/build/editor/js/items/alu8.5.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":16,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15]]; + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","output"]; +} diff --git a/build/editor/js/items/alu8.js b/build/editor/js/items/alu8.js new file mode 100755 index 0000000..cb4c9d8 --- /dev/null +++ b/build/editor/js/items/alu8.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":17,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15],[17,18,19,20,21,22,23,24]]; + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","nand/nor?","output","output","output","output","output","output","output","output"]; +} diff --git a/build/editor/js/items/alu9.js b/build/editor/js/items/alu9.js new file mode 100755 index 0000000..1cd809f --- /dev/null +++ b/build/editor/js/items/alu9.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":9,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[9,10,11,12,13,14,15,16]]; + chip.tooltips = ["input","input","input","input","input","input","input","input","left/right?","output","output","output","output","output","output","output","output"]; +} diff --git a/build/editor/js/items/md5.js b/build/editor/js/items/md5.js new file mode 100755 index 0000000..e69de29 diff --git a/build/editor/js/items/mux1.js b/build/editor/js/items/mux1.js new file mode 100755 index 0000000..2afda38 --- /dev/null +++ b/build/editor/js/items/mux1.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":3,"tooltips":[],"pins":[0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[2]] + chip.tooltips = ["A","B","select", "output"] +} diff --git a/build/editor/js/items/mux2.js b/build/editor/js/items/mux2.js new file mode 100755 index 0000000..2ee8b01 --- /dev/null +++ b/build/editor/js/items/mux2.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":17,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[0,1,2,3,4,5,6,7],[8,9,10,11,12,13,14,15], [16], [17,18,19,20,21,22,23,24]] + chip.tooltips = ["A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","select","output","output","output","output","output","output","output", "output"] +} diff --git a/build/editor/js/items/mux3.js b/build/editor/js/items/mux3.js new file mode 100755 index 0000000..5e7e7f5 --- /dev/null +++ b/build/editor/js/items/mux3.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":2,"tooltips":[],"pins":[0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[1]] + chip.tooltips = ["input","select","output A", "output B"] +} diff --git a/build/editor/js/items/mux4.js b/build/editor/js/items/mux4.js new file mode 100755 index 0000000..65c881d --- /dev/null +++ b/build/editor/js/items/mux4.js @@ -0,0 +1,5 @@ +function loadChip(){ + chip=new Component('main',true,'{"type":"main","inputs":4,"tooltips":[],"pins":[0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); + chip.groups = [[1,2,3]] + chip.tooltips = ["input","select","select","select","output A", "output B", "output C", "output D", "output E", "output F", "output G", "output H"] +} diff --git a/build/editor/js/layouts/21mux.js b/build/editor/js/layouts/21mux.js new file mode 100755 index 0000000..42e7401 --- /dev/null +++ b/build/editor/js/layouts/21mux.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":3,"pins":[0,0,0,0],"subComponents":["and","not","or","and"],"positions":[{"x":255,"y":136},{"x":126,"y":364},{"x":536,"y":179},{"x":291,"y":240}],"wires":[{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":0},"wireId":0},{"source":{"component":2,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":2},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0},"wireId":3},{"source":{"component":0,"pin":1},"destination":{"component":4,"pin":0},"wireId":4},{"source":{"component":0,"pin":2},"destination":{"component":4,"pin":1},"wireId":5},{"source":{"component":4,"pin":2},"destination":{"component":3,"pin":1},"wireId":6},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":3},"wireId":7}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":0,"path":[{"component":0,"pin":2,"shift":0,"rev":1},{"component":2,"pin":0,"shift":0,"offset":14}]},{"wireId":1,"path":[{"component":2,"pin":1,"shift":0,"rev":1},{"component":1,"pin":1,"shift":0,"offset":0}]},{"wireId":2,"path":[{"component":0,"pin":0,"shift":0,"rev":1},{"component":1,"pin":0,"shift":0,"offset":0}]},{"wireId":3,"path":[{"component":1,"pin":2,"shift":0,"rev":1},{"component":3,"pin":0,"shift":0,"offset":0}]},{"wireId":4,"path":[{"component":0,"pin":1,"shift":0,"rev":1},{"component":4,"pin":0,"shift":0,"offset":7}]},{"wireId":5,"path":[{"component":0,"pin":2,"shift":0,"rev":1},{"component":4,"pin":1,"shift":0,"offset":14}]},{"wireId":6,"path":[{"component":4,"pin":2,"shift":0,"rev":1},{"component":3,"pin":1,"shift":0,"offset":0}]},{"wireId":7,"path":[{"component":3,"pin":2,"shift":0,"rev":1},{"component":0,"pin":3,"shift":0,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/layouts/84mux.js b/build/editor/js/layouts/84mux.js new file mode 100755 index 0000000..0ab5d64 --- /dev/null +++ b/build/editor/js/layouts/84mux.js @@ -0,0 +1,7 @@ +function loadChip(){ + chips=JSON.parse('{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"2-1 mux":{"type":"2-1 mux","inputs":3,"pins":[0,0,0,0],"subComponents":["and","not","or","and"],"positions":[{"x":255,"y":136},{"x":126,"y":364},{"x":536,"y":179},{"x":291,"y":240}],"wires":[{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":0},"wireId":0},{"source":{"component":2,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":2},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0},"wireId":3},{"source":{"component":0,"pin":1},"destination":{"component":4,"pin":0},"wireId":4},{"source":{"component":0,"pin":2},"destination":{"component":4,"pin":1},"wireId":5},{"source":{"component":4,"pin":2},"destination":{"component":3,"pin":1},"wireId":6},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":3},"wireId":7}]}}'); + chip = new Component("main",true,'{"type":"main","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["2-1 mux","2-1 mux","2-1 mux","2-1 mux"],"positions":[{"x":259,"y":17},{"x":438,"y":112},{"x":590,"y":194},{"x":610,"y":296}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":2},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":3},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":5},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":6},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":7},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":8},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":2},"wireId":9},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":10},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":11},{"source":{"component":0,"pin":8},"destination":{"component":3,"pin":2},"wireId":12},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":13},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":14},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":2},"wireId":15},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":16}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":0,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":0}]},{"wireId":2,"path":[{"component":1,"pin":2,"shift":false,"rev":-1},{"component":0,"pin":8,"shift":false,"offset":14}]},{"wireId":3,"path":[{"component":0,"pin":4,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":28}]},{"wireId":4,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":2,"pin":0,"shift":false,"offset":7}]},{"wireId":5,"path":[{"component":0,"pin":5,"shift":false,"rev":1},{"component":2,"pin":1,"shift":false,"offset":35}]},{"wireId":6,"path":[{"component":1,"pin":3,"shift":false,"rev":1},{"component":0,"pin":9,"shift":false,"offset":0}]},{"wireId":7,"path":[{"component":2,"pin":3,"shift":false,"rev":1},{"component":0,"pin":10,"shift":false,"offset":0}]},{"wireId":8,"path":[{"component":3,"pin":3,"shift":false,"rev":1},{"component":0,"pin":11,"shift":false,"offset":0}]},{"wireId":9,"path":[{"component":2,"pin":2,"shift":false,"rev":-1},{"component":0,"pin":8,"shift":false,"offset":14}]},{"wireId":10,"path":[{"component":3,"pin":0,"shift":false,"rev":-1},{"component":0,"pin":2,"shift":false,"offset":0}]},{"wireId":11,"path":[{"component":0,"pin":6,"shift":false,"rev":1},{"component":3,"pin":1,"shift":false,"offset":42}]},{"wireId":12,"path":[{"component":3,"pin":2,"shift":false,"rev":-1},{"component":0,"pin":8,"shift":false,"offset":14}]},{"wireId":13,"path":[{"component":0,"pin":3,"shift":false,"rev":1},{"component":4,"pin":0,"shift":false,"offset":21}]},{"wireId":14,"path":[{"component":0,"pin":7,"shift":false,"rev":1},{"component":4,"pin":1,"shift":false,"offset":49}]},{"wireId":15,"path":[{"component":4,"pin":2,"shift":false,"rev":-1},{"component":0,"pin":8,"shift":false,"offset":14}]},{"wireId":16,"path":[{"component":4,"pin":3,"shift":false,"rev":1},{"component":0,"pin":12,"shift":false,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/layouts/addsub.js b/build/editor/js/layouts/addsub.js new file mode 100755 index 0000000..6763354 --- /dev/null +++ b/build/editor/js/layouts/addsub.js @@ -0,0 +1,7 @@ +function loadChip(){ + chips = JSON.parse('{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"half adder":{"type":"half adder","inputs":2,"pins":[0,0,0,0],"subComponents":["and","xor"],"positions":[{"x":413,"y":299},{"x":293,"y":132}],"wires":[{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":0},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":4},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2},"wireId":5}]},"full adder":{"type":"full adder","inputs":3,"pins":[0,0,0,0,0],"subComponents":["half adder","half adder","or"],"positions":[{"x":110,"y":127},{"x":403,"y":212},{"x":827,"y":287}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":6},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":7},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":9},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":3},"wireId":10},{"source":{"component":1,"pin":3},"destination":{"component":3,"pin":1},"wireId":12},{"source":{"component":2,"pin":3},"destination":{"component":3,"pin":0},"wireId":13},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":14}]},"ripple carry adder":{"type":"ripple carry adder","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["full adder","full adder","full adder","full adder"],"positions":[{"x":157,"y":30},{"x":364,"y":150},{"x":546,"y":224},{"x":734,"y":300}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":11},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":12},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":13},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":18},{"source":{"component":1,"pin":4},"destination":{"component":2,"pin":2},"wireId":20},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":21},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":22},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":25},{"source":{"component":2,"pin":4},"destination":{"component":3,"pin":2},"wireId":26},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":27},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":28},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":29},{"source":{"component":3,"pin":4},"destination":{"component":4,"pin":2},"wireId":30},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":31},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":32},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":33},{"source":{"component":4,"pin":4},"destination":{"component":0,"pin":13},"wireId":34}]},"subtractor":{"type":"subtractor","inputs":8,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["ripple carry adder","not","not","not","not","not","not"],"positions":[{"x":405,"y":151},{"x":288,"y":357},{"x":858,"y":341},{"x":147,"y":347},{"x":164,"y":273},{"x":137,"y":201},{"x":135,"y":135}],"wires":[{"source":{"component":2,"pin":1},"destination":{"component":1,"pin":8},"wireId":0},{"source":{"component":3,"pin":1},"destination":{"component":0,"pin":12},"wireId":1},{"source":{"component":1,"pin":13},"destination":{"component":3,"pin":0},"wireId":2},{"source":{"component":1,"pin":9},"destination":{"component":0,"pin":8},"wireId":3},{"source":{"component":1,"pin":10},"destination":{"component":0,"pin":9},"wireId":4},{"source":{"component":1,"pin":11},"destination":{"component":0,"pin":10},"wireId":5},{"source":{"component":1,"pin":12},"destination":{"component":0,"pin":11},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":0},"wireId":0},{"source":{"component":4,"pin":1},"destination":{"component":1,"pin":7},"wireId":1},{"source":{"component":0,"pin":6},"destination":{"component":5,"pin":0},"wireId":2},{"source":{"component":5,"pin":1},"destination":{"component":1,"pin":6},"wireId":3},{"source":{"component":6,"pin":1},"destination":{"component":1,"pin":5},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":6,"pin":0},"wireId":5},{"source":{"component":0,"pin":4},"destination":{"component":7,"pin":0},"wireId":6},{"source":{"component":7,"pin":1},"destination":{"component":1,"pin":4},"wireId":7},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":9},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":10},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":11}]},"2-1 mux":{"type":"2-1 mux","inputs":3,"pins":[0,0,0,0],"subComponents":["not","and","or","and"],"positions":[{"x":161,"y":182},{"x":317,"y":128},{"x":527,"y":198},{"x":263,"y":289}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":17},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":0},"wireId":18},{"source":{"component":1,"pin":1},"destination":{"component":2,"pin":1},"wireId":19},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":0},"wireId":20},{"source":{"component":0,"pin":1},"destination":{"component":4,"pin":0},"wireId":21},{"source":{"component":0,"pin":2},"destination":{"component":4,"pin":1},"wireId":22},{"source":{"component":4,"pin":2},"destination":{"component":3,"pin":1},"wireId":23},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":3},"wireId":24}]},"8-4 mux":{"type":"8-4 mux","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["2-1 mux","2-1 mux","2-1 mux","2-1 mux"],"positions":[{"x":279,"y":91},{"x":326,"y":171},{"x":361,"y":249},{"x":497,"y":320}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":25},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":26},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":27},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":28},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":29},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":2},"wireId":30},{"source":{"component":0,"pin":8},"destination":{"component":3,"pin":2},"wireId":31},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":32},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":33},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":2},"wireId":34},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":35},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":36},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":37},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":38},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":39},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":40}]}}'); + chip = new Component("main",true,'{"type":"main","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["2-1 mux","subtractor","ripple carry adder","8-4 mux"],"positions":[{"x":642,"y":373},{"x":250,"y":239},{"x":221,"y":57},{"x":672,"y":131}],"wires":[{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":13},"wireId":4},{"source":{"component":0,"pin":0},"destination":{"component":3,"pin":0},"wireId":5},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1},"wireId":6},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":2},"wireId":7},{"source":{"component":0,"pin":3},"destination":{"component":3,"pin":3},"wireId":8},{"source":{"component":0,"pin":4},"destination":{"component":3,"pin":4},"wireId":9},{"source":{"component":0,"pin":5},"destination":{"component":3,"pin":5},"wireId":10},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":6},"wireId":11},{"source":{"component":0,"pin":7},"destination":{"component":3,"pin":7},"wireId":12},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":14},{"source":{"component":4,"pin":9},"destination":{"component":0,"pin":9},"wireId":20},{"source":{"component":4,"pin":10},"destination":{"component":0,"pin":10},"wireId":21},{"source":{"component":4,"pin":11},"destination":{"component":0,"pin":11},"wireId":22},{"source":{"component":4,"pin":12},"destination":{"component":0,"pin":12},"wireId":23},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":8},"wireId":24},{"source":{"component":3,"pin":9},"destination":{"component":4,"pin":0},"wireId":25},{"source":{"component":3,"pin":10},"destination":{"component":4,"pin":1},"wireId":26},{"source":{"component":3,"pin":11},"destination":{"component":4,"pin":2},"wireId":27},{"source":{"component":3,"pin":12},"destination":{"component":4,"pin":3},"wireId":28},{"source":{"component":3,"pin":13},"destination":{"component":1,"pin":0},"wireId":29}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( +'[{"wireId":4,"path":[{"component":1,"pin":3,"shift":false,"rev":1},{"component":0,"pin":13,"shift":false,"offset":0}]},{"wireId":5,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":3,"pin":0,"shift":false,"offset":0}]},{"wireId":6,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":3,"pin":1,"shift":false,"offset":7}]},{"wireId":7,"path":[{"component":0,"pin":2,"shift":false,"rev":1},{"component":3,"pin":2,"shift":false,"offset":14}]},{"wireId":8,"path":[{"component":0,"pin":3,"shift":false,"rev":1},{"component":3,"pin":3,"shift":false,"offset":21}]},{"wireId":9,"path":[{"component":0,"pin":4,"shift":false,"rev":1},{"component":3,"pin":4,"shift":false,"offset":28}]},{"wireId":10,"path":[{"component":0,"pin":5,"shift":false,"rev":1},{"component":3,"pin":5,"shift":false,"offset":35}]},{"wireId":11,"path":[{"component":0,"pin":6,"shift":false,"rev":1},{"component":3,"pin":6,"shift":false,"offset":42}]},{"wireId":12,"path":[{"component":0,"pin":7,"shift":false,"rev":1},{"component":3,"pin":7,"shift":false,"offset":49}]},{"wireId":14,"path":[{"component":0,"pin":8,"shift":false,"rev":1},{"x":354.085227265954,"y":393.81534092128277,"shift":false,"offset":56},{"component":1,"pin":2,"shift":false,"offset":56}]},{"wireId":20,"path":[{"component":4,"pin":9,"shift":false,"rev":1},{"component":0,"pin":9,"shift":false,"offset":0}]},{"wireId":21,"path":[{"component":4,"pin":10,"shift":false,"rev":1},{"component":0,"pin":10,"shift":false,"offset":7}]},{"wireId":22,"path":[{"component":4,"pin":11,"shift":false,"rev":1},{"component":0,"pin":11,"shift":false,"offset":14}]},{"wireId":23,"path":[{"component":4,"pin":12,"shift":false,"rev":1},{"component":0,"pin":12,"shift":false,"offset":21}]},{"wireId":24,"path":[{"component":4,"pin":8,"shift":false,"rev":-1},{"x":310.085227265954,"y":393.81534092128277,"shift":false,"offset":56},{"component":0,"pin":8,"shift":false,"offset":56}]},{"wireId":25,"path":[{"component":3,"pin":9,"shift":false,"rev":1},{"component":4,"pin":0,"shift":false,"offset":0}]},{"wireId":26,"path":[{"component":3,"pin":10,"shift":false,"rev":1},{"component":4,"pin":1,"shift":false,"offset":7}]},{"wireId":27,"path":[{"component":3,"pin":11,"shift":false,"rev":1},{"component":4,"pin":2,"shift":false,"offset":14}]},{"wireId":28,"path":[{"component":3,"pin":12,"shift":false,"rev":1},{"component":4,"pin":3,"shift":false,"offset":21}]},{"wireId":29,"path":[{"component":3,"pin":13,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":28}]}]'); +},50); +} diff --git a/build/editor/js/layouts/alu.js b/build/editor/js/layouts/alu.js new file mode 100755 index 0000000..debb27b --- /dev/null +++ b/build/editor/js/layouts/alu.js @@ -0,0 +1,7 @@ +function loadChip(){ + chips = JSON.parse('{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"half adder":{"type":"half adder","inputs":2,"pins":[0,0,0,0],"subComponents":["and","xor"],"positions":[{"x":413,"y":299},{"x":293,"y":132}],"wires":[{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":0},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":4},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2},"wireId":5}]},"full adder":{"type":"full adder","inputs":3,"pins":[0,0,0,0,0],"subComponents":["half adder","half adder","or"],"positions":[{"x":110,"y":127},{"x":403,"y":212},{"x":827,"y":287}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":6},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":7},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":9},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":3},"wireId":10},{"source":{"component":1,"pin":3},"destination":{"component":3,"pin":1},"wireId":12},{"source":{"component":2,"pin":3},"destination":{"component":3,"pin":0},"wireId":13},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":14}]},"ripple carry adder":{"type":"ripple carry adder","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["full adder","full adder","full adder","full adder"],"positions":[{"x":157,"y":30},{"x":364,"y":150},{"x":546,"y":224},{"x":734,"y":300}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":11},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":12},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":13},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":18},{"source":{"component":1,"pin":4},"destination":{"component":2,"pin":2},"wireId":20},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":21},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":22},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":25},{"source":{"component":2,"pin":4},"destination":{"component":3,"pin":2},"wireId":26},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":27},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":28},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":29},{"source":{"component":3,"pin":4},"destination":{"component":4,"pin":2},"wireId":30},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":31},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":32},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":33},{"source":{"component":4,"pin":4},"destination":{"component":0,"pin":13},"wireId":34}]},"subtractor":{"type":"subtractor","inputs":8,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["ripple carry adder","not","not","not","not","not","not"],"positions":[{"x":405,"y":151},{"x":288,"y":357},{"x":858,"y":341},{"x":147,"y":347},{"x":164,"y":273},{"x":137,"y":201},{"x":135,"y":135}],"wires":[{"source":{"component":2,"pin":1},"destination":{"component":1,"pin":8},"wireId":0},{"source":{"component":3,"pin":1},"destination":{"component":0,"pin":12},"wireId":1},{"source":{"component":1,"pin":13},"destination":{"component":3,"pin":0},"wireId":2},{"source":{"component":1,"pin":9},"destination":{"component":0,"pin":8},"wireId":3},{"source":{"component":1,"pin":10},"destination":{"component":0,"pin":9},"wireId":4},{"source":{"component":1,"pin":11},"destination":{"component":0,"pin":10},"wireId":5},{"source":{"component":1,"pin":12},"destination":{"component":0,"pin":11},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":0},"wireId":0},{"source":{"component":4,"pin":1},"destination":{"component":1,"pin":7},"wireId":1},{"source":{"component":0,"pin":6},"destination":{"component":5,"pin":0},"wireId":2},{"source":{"component":5,"pin":1},"destination":{"component":1,"pin":6},"wireId":3},{"source":{"component":6,"pin":1},"destination":{"component":1,"pin":5},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":6,"pin":0},"wireId":5},{"source":{"component":0,"pin":4},"destination":{"component":7,"pin":0},"wireId":6},{"source":{"component":7,"pin":1},"destination":{"component":1,"pin":4},"wireId":7},{"source":{"component":0,"pin":3},"destination":{"component":1,"pin":3},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":2},"wireId":9},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":10},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":11}]},"2-1 mux":{"type":"2-1 mux","inputs":3,"pins":[0,0,0,0],"subComponents":["not","and","or","and"],"positions":[{"x":161,"y":182},{"x":317,"y":128},{"x":527,"y":198},{"x":263,"y":289}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":17},{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":0},"wireId":18},{"source":{"component":1,"pin":1},"destination":{"component":2,"pin":1},"wireId":19},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":0},"wireId":20},{"source":{"component":0,"pin":1},"destination":{"component":4,"pin":0},"wireId":21},{"source":{"component":0,"pin":2},"destination":{"component":4,"pin":1},"wireId":22},{"source":{"component":4,"pin":2},"destination":{"component":3,"pin":1},"wireId":23},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":3},"wireId":24}]},"8-4 mux":{"type":"8-4 mux","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["2-1 mux","2-1 mux","2-1 mux","2-1 mux"],"positions":[{"x":279,"y":91},{"x":326,"y":171},{"x":361,"y":249},{"x":497,"y":320}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":25},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":26},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":27},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":28},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":29},{"source":{"component":0,"pin":8},"destination":{"component":2,"pin":2},"wireId":30},{"source":{"component":0,"pin":8},"destination":{"component":3,"pin":2},"wireId":31},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":32},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":33},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":2},"wireId":34},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":35},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":36},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":37},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":38},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":39},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":40}]},"add/sub unit":{"type":"add/sub unit","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["2-1 mux","subtractor","ripple carry adder","8-4 mux"],"positions":[{"x":642,"y":373},{"x":250,"y":239},{"x":221,"y":57},{"x":672,"y":131}],"wires":[{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":13},"wireId":4},{"source":{"component":0,"pin":0},"destination":{"component":3,"pin":0},"wireId":5},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1},"wireId":6},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":2},"wireId":7},{"source":{"component":0,"pin":3},"destination":{"component":3,"pin":3},"wireId":8},{"source":{"component":0,"pin":4},"destination":{"component":3,"pin":4},"wireId":9},{"source":{"component":0,"pin":5},"destination":{"component":3,"pin":5},"wireId":10},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":6},"wireId":11},{"source":{"component":0,"pin":7},"destination":{"component":3,"pin":7},"wireId":12},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":14},{"source":{"component":4,"pin":9},"destination":{"component":0,"pin":9},"wireId":20},{"source":{"component":4,"pin":10},"destination":{"component":0,"pin":10},"wireId":21},{"source":{"component":4,"pin":11},"destination":{"component":0,"pin":11},"wireId":22},{"source":{"component":4,"pin":12},"destination":{"component":0,"pin":12},"wireId":23},{"source":{"component":0,"pin":8},"destination":{"component":4,"pin":8},"wireId":24},{"source":{"component":3,"pin":9},"destination":{"component":4,"pin":0},"wireId":25},{"source":{"component":3,"pin":10},"destination":{"component":4,"pin":1},"wireId":26},{"source":{"component":3,"pin":11},"destination":{"component":4,"pin":2},"wireId":27},{"source":{"component":3,"pin":12},"destination":{"component":4,"pin":3},"wireId":28},{"source":{"component":3,"pin":13},"destination":{"component":1,"pin":0},"wireId":29},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":1},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":2},"wireId":2},{"source":{"component":0,"pin":3},"destination":{"component":2,"pin":3},"wireId":3},{"source":{"component":0,"pin":4},"destination":{"component":2,"pin":4},"wireId":4},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":5},"wireId":5},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":6},"wireId":6},{"source":{"component":0,"pin":7},"destination":{"component":2,"pin":7},"wireId":7},{"source":{"component":2,"pin":8},"destination":{"component":4,"pin":4},"wireId":8},{"source":{"component":2,"pin":9},"destination":{"component":4,"pin":5},"wireId":9},{"source":{"component":2,"pin":10},"destination":{"component":4,"pin":6},"wireId":10},{"source":{"component":2,"pin":11},"destination":{"component":4,"pin":7},"wireId":11},{"source":{"component":2,"pin":12},"destination":{"component":1,"pin":1},"wireId":12}]},"bitwise and":{"type":"bitwise and","inputs":8,"pins":[0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["and","and","and","and"],"positions":[{"x":315,"y":190},{"x":380,"y":311},{"x":477,"y":424},{"x":324,"y":86}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":4,"pin":0},"wireId":13},{"source":{"component":0,"pin":4},"destination":{"component":4,"pin":1},"wireId":14},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":0},"wireId":15},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":1},"wireId":16},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":0},"wireId":17},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":1},"wireId":18},{"source":{"component":0,"pin":3},"destination":{"component":3,"pin":0},"wireId":19},{"source":{"component":0,"pin":7},"destination":{"component":3,"pin":1},"wireId":20},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":8},"wireId":21},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":9},"wireId":22},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":10},"wireId":23},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":11},"wireId":24}]},"bitwise xor":{"type":"bitwise xor","inputs":8,"pins":[0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["xor","xor","xor","xor"],"positions":[{"x":527,"y":220},{"x":680,"y":355},{"x":576,"y":89},{"x":670,"y":520}],"wires":[{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":8},"wireId":25},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":9},"wireId":26},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":10},"wireId":27},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":11},"wireId":28},{"source":{"component":0,"pin":6},"destination":{"component":2,"pin":1},"wireId":29},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":0},"wireId":30},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":31},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":32},{"source":{"component":0,"pin":5},"destination":{"component":1,"pin":1},"wireId":33},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":0},"wireId":34},{"source":{"component":0,"pin":4},"destination":{"component":3,"pin":1},"wireId":35},{"source":{"component":0,"pin":0},"destination":{"component":3,"pin":0},"wireId":36}]}}'); + chip = new Component("main",true,'{"type":"main","inputs":10,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["add/sub unit","bitwise and","bitwise xor","8-4 mux","not","and","and","and","not","not","not","8-4 mux","2-1 mux"],"positions":[{"x":187,"y":62},{"x":190,"y":234},{"x":195,"y":380},{"x":559,"y":62},{"x":717,"y":543},{"x":1017,"y":508},{"x":829,"y":415},{"x":829,"y":524},{"x":717,"y":475},{"x":716,"y":416},{"x":716,"y":349},{"x":411,"y":293},{"x":1221,"y":426}],"wires":[{"source":{"component":4,"pin":9},"destination":{"component":0,"pin":10},"wireId":37},{"source":{"component":4,"pin":10},"destination":{"component":0,"pin":11},"wireId":38},{"source":{"component":4,"pin":11},"destination":{"component":0,"pin":12},"wireId":39},{"source":{"component":4,"pin":12},"destination":{"component":0,"pin":13},"wireId":40},{"source":{"component":6,"pin":2},"destination":{"component":0,"pin":15},"wireId":41},{"source":{"component":7,"pin":2},"destination":{"component":6,"pin":0},"wireId":42},{"source":{"component":8,"pin":2},"destination":{"component":6,"pin":1},"wireId":43},{"source":{"component":5,"pin":1},"destination":{"component":8,"pin":1},"wireId":44},{"source":{"component":9,"pin":1},"destination":{"component":8,"pin":0},"wireId":45},{"source":{"component":10,"pin":1},"destination":{"component":7,"pin":1},"wireId":46},{"source":{"component":11,"pin":1},"destination":{"component":7,"pin":0},"wireId":47},{"source":{"component":2,"pin":8},"destination":{"component":12,"pin":0},"wireId":49},{"source":{"component":2,"pin":9},"destination":{"component":12,"pin":1},"wireId":50},{"source":{"component":2,"pin":10},"destination":{"component":12,"pin":2},"wireId":51},{"source":{"component":2,"pin":11},"destination":{"component":12,"pin":3},"wireId":52},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":8},"wireId":53},{"source":{"component":0,"pin":8},"destination":{"component":12,"pin":8},"wireId":54},{"source":{"component":13,"pin":3},"destination":{"component":0,"pin":14},"wireId":55},{"source":{"component":0,"pin":9},"destination":{"component":13,"pin":2},"wireId":56}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( +'[{"wireId":37,"path":[{"component":4,"pin":9,"shift":false,"rev":1},{"component":0,"pin":10,"shift":false,"offset":0}]},{"wireId":38,"path":[{"component":4,"pin":10,"shift":false,"rev":1},{"component":0,"pin":11,"shift":false,"offset":7}]},{"wireId":39,"path":[{"component":4,"pin":11,"shift":false,"rev":1},{"component":0,"pin":12,"shift":false,"offset":14}]},{"wireId":40,"path":[{"component":4,"pin":12,"shift":false,"rev":1},{"component":0,"pin":13,"shift":false,"offset":21}]},{"wireId":41,"path":[{"component":6,"pin":2,"shift":false,"rev":1},{"component":0,"pin":15,"shift":false,"offset":0}]},{"wireId":42,"path":[{"component":7,"pin":2,"shift":false,"rev":1},{"component":6,"pin":0,"shift":false,"offset":0}]},{"wireId":43,"path":[{"component":8,"pin":2,"shift":false,"rev":1},{"component":6,"pin":1,"shift":false,"offset":0}]},{"wireId":44,"path":[{"component":5,"pin":1,"shift":false,"rev":1},{"component":8,"pin":1,"shift":false,"offset":0}]},{"wireId":45,"path":[{"component":9,"pin":1,"shift":false,"rev":1},{"component":8,"pin":0,"shift":false,"offset":0}]},{"wireId":46,"path":[{"component":10,"pin":1,"shift":false,"rev":1},{"component":7,"pin":1,"shift":false,"offset":0}]},{"wireId":47,"path":[{"component":11,"pin":1,"shift":false,"rev":1},{"component":7,"pin":0,"shift":false,"offset":0}]},{"wireId":49,"path":[{"component":12,"pin":0,"shift":false,"rev":-1},{"component":2,"pin":8,"shift":false,"offset":0}]},{"wireId":50,"path":[{"component":12,"pin":1,"shift":false,"rev":-1},{"component":2,"pin":9,"shift":false,"offset":7}]},{"wireId":51,"path":[{"component":12,"pin":2,"shift":false,"rev":-1},{"component":2,"pin":10,"shift":false,"offset":14}]},{"wireId":52,"path":[{"component":12,"pin":3,"shift":false,"rev":-1},{"component":2,"pin":11,"shift":false,"offset":21}]},{"wireId":53,"path":[{"component":0,"pin":8,"shift":false,"rev":1},{"component":1,"pin":8,"shift":false,"offset":56}]},{"wireId":54,"path":[{"component":0,"pin":8,"shift":false,"rev":1},{"x":272.914772734046,"y":528.170454531908,"shift":false,"offset":56},{"component":12,"pin":8,"shift":false,"offset":56}]},{"wireId":55,"path":[{"component":13,"pin":3,"shift":false,"rev":1},{"component":0,"pin":14,"shift":false,"offset":0}]},{"wireId":56,"path":[{"component":0,"pin":9,"shift":false,"rev":1},{"x":512.914772734046,"y":560.170454531908,"shift":false,"offset":63},{"x":742.914772734046,"y":336.17045453190804,"shift":false,"offset":63},{"x":835.914772734046,"y":336.17045453190804,"shift":false,"offset":63},{"x":1036.914772734046,"y":394.17045453190804,"shift":false,"offset":63},{"component":13,"pin":2,"shift":false,"offset":63}]}]'); +},50); +} diff --git a/build/editor/js/layouts/and.js b/build/editor/js/layouts/and.js new file mode 100755 index 0000000..c7494a7 --- /dev/null +++ b/build/editor/js/layouts/and.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":2,"pins":[0,0,0],"subComponents":["and"],"positions":[{"x":300,"y":178}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":2},"wireId":2}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":0,"path":[{"component":1,"pin":0,"shift":false,"rev":-1},{"component":0,"pin":0,"shift":false,"offset":0}]},{"wireId":1,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":7}]},{"wireId":2,"path":[{"component":1,"pin":2,"shift":false,"rev":1},{"component":0,"pin":2,"shift":false,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/layouts/challenge1.js b/build/editor/js/layouts/challenge1.js new file mode 100755 index 0000000..43f28e0 --- /dev/null +++ b/build/editor/js/layouts/challenge1.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":6,"pins":[0,0,0,0,0,0,0,0,0,0,0],"subComponents":["not","and","xor","and","not","or","not"],"positions":[{"x":124,"y":232},{"x":272,"y":291},{"x":276,"y":163},{"x":689,"y":126},{"x":458,"y":354},{"x":405,"y":22},{"x":878,"y":82}],"wires":[{"source":{"component":0,"pin":2},"destination":{"component":1,"pin":0},"wireId":1},{"source":{"component":1,"pin":1},"destination":{"component":2,"pin":0},"wireId":7},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":10},"wireId":8},{"source":{"component":0,"pin":4},"destination":{"component":2,"pin":1},"wireId":9},{"source":{"component":1,"pin":1},"destination":{"component":3,"pin":1},"wireId":10},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":0},"wireId":11},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":9},"wireId":12},{"source":{"component":0,"pin":0},"destination":{"component":4,"pin":0},"wireId":13},{"source":{"component":0,"pin":5},"destination":{"component":5,"pin":0},"wireId":14},{"source":{"component":5,"pin":1},"destination":{"component":4,"pin":1},"wireId":15},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":8},"wireId":16},{"source":{"component":0,"pin":5},"destination":{"component":6,"pin":1},"wireId":17},{"source":{"component":0,"pin":3},"destination":{"component":6,"pin":0},"wireId":18},{"source":{"component":6,"pin":2},"destination":{"component":0,"pin":6},"wireId":19},{"source":{"component":4,"pin":2},"destination":{"component":7,"pin":0},"wireId":20},{"source":{"component":7,"pin":1},"destination":{"component":0,"pin":7},"wireId":21}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":1,"path":[{"component":0,"pin":2,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":14}]},{"wireId":7,"path":[{"component":1,"pin":1,"shift":false,"rev":1},{"component":2,"pin":0,"shift":false,"offset":0}]},{"wireId":8,"path":[{"component":2,"pin":2,"shift":false,"rev":1},{"component":0,"pin":10,"shift":false,"offset":0}]},{"wireId":9,"path":[{"component":0,"pin":4,"shift":false,"rev":1},{"component":2,"pin":1,"shift":false,"offset":28}]},{"wireId":10,"path":[{"component":1,"pin":1,"shift":false,"rev":1},{"component":3,"pin":1,"shift":false,"offset":0}]},{"wireId":11,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":3,"pin":0,"shift":false,"offset":7}]},{"wireId":12,"path":[{"component":3,"pin":2,"shift":false,"rev":1},{"component":0,"pin":9,"shift":false,"offset":0}]},{"wireId":13,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":4,"pin":0,"shift":false,"offset":0}]},{"wireId":14,"path":[{"component":0,"pin":5,"shift":false,"rev":1},{"component":5,"pin":0,"shift":false,"offset":35}]},{"wireId":15,"path":[{"component":5,"pin":1,"shift":false,"rev":1},{"component":4,"pin":1,"shift":false,"offset":0}]},{"wireId":16,"path":[{"component":4,"pin":2,"shift":false,"rev":1},{"component":0,"pin":8,"shift":false,"offset":0}]},{"wireId":17,"path":[{"component":0,"pin":5,"shift":false,"rev":1},{"component":6,"pin":1,"shift":false,"offset":35}]},{"wireId":18,"path":[{"component":0,"pin":3,"shift":false,"rev":1},{"component":6,"pin":0,"shift":false,"offset":21}]},{"wireId":19,"path":[{"component":6,"pin":2,"shift":false,"rev":1},{"component":0,"pin":6,"shift":false,"offset":0}]},{"wireId":20,"path":[{"component":4,"pin":2,"shift":false,"rev":1},{"component":7,"pin":0,"shift":false,"offset":0}]},{"wireId":21,"path":[{"component":7,"pin":1,"shift":false,"rev":1},{"component":0,"pin":7,"shift":false,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/layouts/fourpin.js b/build/editor/js/layouts/fourpin.js new file mode 100755 index 0000000..08c5d35 --- /dev/null +++ b/build/editor/js/layouts/fourpin.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":2,"pins":[0,0,0,0],"subComponents":[],"positions":[],"wires":[]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[]'); +},50); +} diff --git a/build/editor/js/layouts/fulladder.js b/build/editor/js/layouts/fulladder.js new file mode 100755 index 0000000..7aa9f26 --- /dev/null +++ b/build/editor/js/layouts/fulladder.js @@ -0,0 +1,8 @@ +function loadChip(){ + chips = JSON.parse('{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"half adder":{"type":"half adder","inputs":2,"pins":[0,0,0,0],"subComponents":["and","xor"],"positions":[{"x":413,"y":299},{"x":293,"y":132}],"wires":[{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":0},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":4},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2},"wireId":5}]}}'); + + chip = new Component("main",true,'{"type":"main","inputs":3,"pins":[0,0,0,0,0],"subComponents":["half adder","half adder","or"],"positions":[{"x":110,"y":127},{"x":403,"y":212},{"x":827,"y":287}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":6},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":7},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":9},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":3},"wireId":10},{"source":{"component":1,"pin":3},"destination":{"component":3,"pin":1},"wireId":12},{"source":{"component":2,"pin":3},"destination":{"component":3,"pin":0},"wireId":13},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":14}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":6,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":0}]},{"wireId":7,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":7}]},{"wireId":8,"path":[{"component":1,"pin":2,"shift":false,"rev":1},{"component":2,"pin":0,"shift":false,"offset":0}]},{"wireId":9,"path":[{"component":0,"pin":2,"shift":false,"rev":1},{"component":2,"pin":1,"shift":false,"offset":14}]},{"wireId":10,"path":[{"component":2,"pin":2,"shift":false,"rev":1},{"component":0,"pin":3,"shift":false,"offset":0}]},{"wireId":12,"path":[{"component":1,"pin":3,"shift":false,"rev":1},{"x":468.085227265954,"y":342.81534092128277,"shift":false,"offset":7},{"component":3,"pin":1,"shift":false,"offset":7}]},{"wireId":13,"path":[{"component":3,"pin":0,"shift":false,"rev":-1},{"component":2,"pin":3,"shift":false,"offset":0}]},{"wireId":14,"path":[{"component":3,"pin":2,"shift":false,"rev":1},{"component":0,"pin":4,"shift":false,"offset":0}]}]' ); +},50); +} diff --git a/build/editor/js/layouts/not.js b/build/editor/js/layouts/not.js new file mode 100755 index 0000000..75de906 --- /dev/null +++ b/build/editor/js/layouts/not.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":1,"pins":[0,0],"subComponents":["not"],"positions":[{"x":300,"y":178}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":1,"pin":1},"destination":{"component":0,"pin":1},"wireId":1}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":0,"path":[{"component":1,"pin":0,"shift":false,"rev":-1},{"component":0,"pin":0,"shift":false,"offset":0}]},{"wireId":1,"path":[{"component":1,"pin":1,"shift":false,"rev":1},{"component":0,"pin":1,"shift":false,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/layouts/or.js b/build/editor/js/layouts/or.js new file mode 100755 index 0000000..0b32f45 --- /dev/null +++ b/build/editor/js/layouts/or.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":2,"pins":[0,0,0],"subComponents":["or"],"positions":[{"x":300,"y":178}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":2},"wireId":2}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":0,"path":[{"component":1,"pin":0,"shift":false,"rev":-1},{"component":0,"pin":0,"shift":false,"offset":0}]},{"wireId":1,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":7}]},{"wireId":2,"path":[{"component":1,"pin":2,"shift":false,"rev":1},{"component":0,"pin":2,"shift":false,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/layouts/rca.js b/build/editor/js/layouts/rca.js new file mode 100755 index 0000000..8f8f821 --- /dev/null +++ b/build/editor/js/layouts/rca.js @@ -0,0 +1,7 @@ +function loadChip(){ + chips = JSON.parse('{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"half adder":{"type":"half adder","inputs":2,"pins":[0,0,0,0],"subComponents":["and","xor"],"positions":[{"x":413,"y":299},{"x":293,"y":132}],"wires":[{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":0},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":4},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2},"wireId":5}]},"full adder":{"type":"full adder","inputs":3,"pins":[0,0,0,0,0],"subComponents":["half adder","half adder","or"],"positions":[{"x":110,"y":127},{"x":403,"y":212},{"x":827,"y":287}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":6},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":7},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":9},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":3},"wireId":10},{"source":{"component":1,"pin":3},"destination":{"component":3,"pin":1},"wireId":12},{"source":{"component":2,"pin":3},"destination":{"component":3,"pin":0},"wireId":13},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":14}]}}'); + chip = new Component("main",true,'{"type":"main","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["full adder","full adder","full adder","full adder"],"positions":[{"x":157,"y":30},{"x":364,"y":150},{"x":546,"y":224},{"x":734,"y":300}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":11},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":12},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":13},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":18},{"source":{"component":1,"pin":4},"destination":{"component":2,"pin":2},"wireId":20},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":21},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":22},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":25},{"source":{"component":2,"pin":4},"destination":{"component":3,"pin":2},"wireId":26},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":27},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":28},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":29},{"source":{"component":3,"pin":4},"destination":{"component":4,"pin":2},"wireId":30},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":31},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":32},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":33},{"source":{"component":4,"pin":4},"destination":{"component":0,"pin":13},"wireId":34}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":11,"path":[{"component":0,"pin":0,"shift":false,"rev":1},{"component":1,"pin":0,"shift":false,"offset":0}]},{"wireId":12,"path":[{"component":0,"pin":4,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":28}]},{"wireId":13,"path":[{"component":0,"pin":8,"shift":false,"rev":1},{"component":1,"pin":2,"shift":false,"offset":56}]},{"wireId":18,"path":[{"component":2,"pin":0,"shift":false,"rev":-1},{"component":0,"pin":1,"shift":false,"offset":0}]},{"wireId":20,"path":[{"component":1,"pin":4,"shift":false,"rev":1},{"component":2,"pin":2,"shift":false,"offset":7}]},{"wireId":21,"path":[{"component":2,"pin":1,"shift":false,"rev":-1},{"component":0,"pin":5,"shift":false,"offset":7}]},{"wireId":22,"path":[{"component":1,"pin":3,"shift":false,"rev":1},{"component":0,"pin":9,"shift":false,"offset":0}]},{"wireId":25,"path":[{"component":2,"pin":3,"shift":false,"rev":1},{"component":0,"pin":10,"shift":false,"offset":0}]},{"wireId":26,"path":[{"component":2,"pin":4,"shift":false,"rev":1},{"component":3,"pin":2,"shift":false,"offset":7}]},{"wireId":27,"path":[{"component":0,"pin":2,"shift":false,"rev":1},{"component":3,"pin":0,"shift":false,"offset":14}]},{"wireId":28,"path":[{"component":0,"pin":6,"shift":false,"rev":1},{"component":3,"pin":1,"shift":false,"offset":42}]},{"wireId":29,"path":[{"component":3,"pin":3,"shift":false,"rev":1},{"component":0,"pin":11,"shift":false,"offset":0}]},{"wireId":30,"path":[{"component":3,"pin":4,"shift":false,"rev":1},{"component":4,"pin":2,"shift":false,"offset":7}]},{"wireId":31,"path":[{"component":0,"pin":7,"shift":false,"rev":1},{"component":4,"pin":1,"shift":false,"offset":49}]},{"wireId":32,"path":[{"component":0,"pin":3,"shift":false,"rev":1},{"component":4,"pin":0,"shift":false,"offset":21}]},{"wireId":33,"path":[{"component":4,"pin":3,"shift":false,"rev":1},{"component":0,"pin":12,"shift":false,"offset":0}]},{"wireId":34,"path":[{"component":4,"pin":4,"shift":false,"rev":1},{"component":0,"pin":13,"shift":false,"offset":7}]}]'); +},50); +} diff --git a/build/editor/js/layouts/sub.js b/build/editor/js/layouts/sub.js new file mode 100755 index 0000000..f3fa85f --- /dev/null +++ b/build/editor/js/layouts/sub.js @@ -0,0 +1,7 @@ +function loadChip(){ + chips = JSON.parse('{"nand":{"image":"img/gates/nand.png","inputs":2,"pins":[0,0,0],"subComponents":[],"wires":[]},"not":{"image":"img/gates/not.png","inputs":1,"pins":[0,0],"subComponents":["nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":1}}]},"and":{"image":"img/gates/and.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2}}]},"or":{"image":"img/gates/or.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":2,"pin":2},"destination":{"component":3,"pin":1}},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":2}}]},"xor":{"image":"img/gates/xor.png","inputs":2,"pins":[0,0,0],"subComponents":["nand","nand","nand","nand"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":3,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":3,"pin":1}},{"source":{"component":2,"pin":2},"destination":{"component":4,"pin":0}},{"source":{"component":3,"pin":2},"destination":{"component":4,"pin":1}},{"source":{"component":4,"pin":2},"destination":{"component":0,"pin":2}}]},"nor":{"inputs":2,"image":"img/gates/nor.png","pins":[0,0,0],"subComponents":["or","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"xnor":{"inputs":2,"image":"img/gates/xnor.png","pins":[0,0,0],"subComponents":["xor","not"],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0}},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1}},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0}},{"source":{"component":2,"pin":1},"destination":{"component":0,"pin":2}}]},"half adder":{"type":"half adder","inputs":2,"pins":[0,0,0,0],"subComponents":["and","xor"],"positions":[{"x":413,"y":299},{"x":293,"y":132}],"wires":[{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":0},{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":3},"wireId":2},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":1},"wireId":3},{"source":{"component":0,"pin":0},"destination":{"component":2,"pin":0},"wireId":4},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":2},"wireId":5}]},"full adder":{"type":"full adder","inputs":3,"pins":[0,0,0,0,0],"subComponents":["half adder","half adder","or"],"positions":[{"x":110,"y":127},{"x":403,"y":212},{"x":827,"y":287}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":6},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":7},{"source":{"component":1,"pin":2},"destination":{"component":2,"pin":0},"wireId":8},{"source":{"component":0,"pin":2},"destination":{"component":2,"pin":1},"wireId":9},{"source":{"component":2,"pin":2},"destination":{"component":0,"pin":3},"wireId":10},{"source":{"component":1,"pin":3},"destination":{"component":3,"pin":1},"wireId":12},{"source":{"component":2,"pin":3},"destination":{"component":3,"pin":0},"wireId":13},{"source":{"component":3,"pin":2},"destination":{"component":0,"pin":4},"wireId":14}]},"ripple carry adder":{"type":"ripple carry adder","inputs":9,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["full adder","full adder","full adder","full adder"],"positions":[{"x":157,"y":30},{"x":364,"y":150},{"x":546,"y":224},{"x":734,"y":300}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":11},{"source":{"component":0,"pin":4},"destination":{"component":1,"pin":1},"wireId":12},{"source":{"component":0,"pin":8},"destination":{"component":1,"pin":2},"wireId":13},{"source":{"component":0,"pin":1},"destination":{"component":2,"pin":0},"wireId":18},{"source":{"component":1,"pin":4},"destination":{"component":2,"pin":2},"wireId":20},{"source":{"component":0,"pin":5},"destination":{"component":2,"pin":1},"wireId":21},{"source":{"component":1,"pin":3},"destination":{"component":0,"pin":9},"wireId":22},{"source":{"component":2,"pin":3},"destination":{"component":0,"pin":10},"wireId":25},{"source":{"component":2,"pin":4},"destination":{"component":3,"pin":2},"wireId":26},{"source":{"component":0,"pin":2},"destination":{"component":3,"pin":0},"wireId":27},{"source":{"component":0,"pin":6},"destination":{"component":3,"pin":1},"wireId":28},{"source":{"component":3,"pin":3},"destination":{"component":0,"pin":11},"wireId":29},{"source":{"component":3,"pin":4},"destination":{"component":4,"pin":2},"wireId":30},{"source":{"component":0,"pin":7},"destination":{"component":4,"pin":1},"wireId":31},{"source":{"component":0,"pin":3},"destination":{"component":4,"pin":0},"wireId":32},{"source":{"component":4,"pin":3},"destination":{"component":0,"pin":12},"wireId":33},{"source":{"component":4,"pin":4},"destination":{"component":0,"pin":13},"wireId":34}]}}'); + chip = new Component("main",true,'{"type":"main","inputs":8,"pins":[0,0,0,0,0,0,0,0,0,0,0,0,0],"subComponents":["ripple carry adder","not","not"],"positions":[{"x":405,"y":151},{"x":288,"y":357},{"x":858,"y":341}],"wires":[{"source":{"component":2,"pin":1},"destination":{"component":1,"pin":8},"wireId":0},{"source":{"component":3,"pin":1},"destination":{"component":0,"pin":12},"wireId":1},{"source":{"component":1,"pin":13},"destination":{"component":3,"pin":0},"wireId":2},{"source":{"component":1,"pin":9},"destination":{"component":0,"pin":8},"wireId":3},{"source":{"component":1,"pin":10},"destination":{"component":0,"pin":9},"wireId":4},{"source":{"component":1,"pin":11},"destination":{"component":0,"pin":10},"wireId":5},{"source":{"component":1,"pin":12},"destination":{"component":0,"pin":11},"wireId":6}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( +'[{"wireId":0,"path":[{"component":2,"pin":1,"shift":0,"rev":1},{"component":1,"pin":8,"shift":0,"offset":0}]},{"wireId":1,"path":[{"component":3,"pin":1,"shift":0,"rev":1},{"component":0,"pin":12,"shift":0,"offset":0}]},{"wireId":2,"path":[{"component":3,"pin":0,"shift":0,"rev":-1},{"component":1,"pin":13,"shift":0,"offset":0}]},{"wireId":3,"path":[{"component":1,"pin":9,"shift":0,"rev":1},{"x":1007.085227265954,"y":68.81534092128277,"shift":0,"offset":0},{"component":0,"pin":8,"shift":0,"offset":0}]},{"wireId":4,"path":[{"component":1,"pin":10,"shift":0,"rev":1},{"component":0,"pin":9,"shift":0,"offset":7}]},{"wireId":5,"path":[{"component":1,"pin":11,"shift":0,"rev":1},{"component":0,"pin":10,"shift":0,"offset":14}]},{"wireId":6,"path":[{"component":1,"pin":12,"shift":0,"rev":1},{"component":0,"pin":11,"shift":0,"offset":21}]}]'); +},50); +} diff --git a/build/editor/js/layouts/xor.js b/build/editor/js/layouts/xor.js new file mode 100755 index 0000000..ba4fe44 --- /dev/null +++ b/build/editor/js/layouts/xor.js @@ -0,0 +1,6 @@ +function loadChip(){ + chip = new Component("main",true,'{"type":"main","inputs":2,"pins":[0,0,0],"subComponents":["xor"],"positions":[{"x":300,"y":178}],"wires":[{"source":{"component":0,"pin":0},"destination":{"component":1,"pin":0},"wireId":0},{"source":{"component":0,"pin":1},"destination":{"component":1,"pin":1},"wireId":1},{"source":{"component":1,"pin":2},"destination":{"component":0,"pin":2},"wireId":2}]}'); +setTimeout(function(){ wireVisuals = JSON.parse( + '[{"wireId":0,"path":[{"component":1,"pin":0,"shift":false,"rev":-1},{"component":0,"pin":0,"shift":false,"offset":0}]},{"wireId":1,"path":[{"component":0,"pin":1,"shift":false,"rev":1},{"component":1,"pin":1,"shift":false,"offset":7}]},{"wireId":2,"path":[{"component":1,"pin":2,"shift":false,"rev":1},{"component":0,"pin":2,"shift":false,"offset":0}]}]'); +},50); +} diff --git a/build/editor/js/md5.js b/build/editor/js/md5.js new file mode 100755 index 0000000..2cca30f --- /dev/null +++ b/build/editor/js/md5.js @@ -0,0 +1,171 @@ +function md5 ( str ) { + + var RotateLeft = function(lValue, iShiftBits) { + return (lValue<>>(32-iShiftBits)); + }; + + var AddUnsigned = function(lX,lY) { + var lX4,lY4,lX8,lY8,lResult; + lX8 = (lX & 0x80000000); + lY8 = (lY & 0x80000000); + lX4 = (lX & 0x40000000); + lY4 = (lY & 0x40000000); + lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF); + if (lX4 & lY4) { + return (lResult ^ 0x80000000 ^ lX8 ^ lY8); + } + if (lX4 | lY4) { + if (lResult & 0x40000000) { + return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); + } else { + return (lResult ^ 0x40000000 ^ lX8 ^ lY8); + } + } else { + return (lResult ^ lX8 ^ lY8); + } + }; + + var F = function(x,y,z) { return (x & y) | ((~x) & z); }; + var G = function(x,y,z) { return (x & z) | (y & (~z)); }; + var H = function(x,y,z) { return (x ^ y ^ z); }; + var I = function(x,y,z) { return (y ^ (x | (~z))); }; + + var FF = function(a,b,c,d,x,s,ac) { + a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac)); + return AddUnsigned(RotateLeft(a, s), b); + }; + + var GG = function(a,b,c,d,x,s,ac) { + a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac)); + return AddUnsigned(RotateLeft(a, s), b); + }; + + var HH = function(a,b,c,d,x,s,ac) { + a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac)); + return AddUnsigned(RotateLeft(a, s), b); + }; + + var II = function(a,b,c,d,x,s,ac) { + a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac)); + return AddUnsigned(RotateLeft(a, s), b); + }; + + var ConvertToWordArray = function(str) { + var lWordCount; + var lMessageLength = str.length; + var lNumberOfWords_temp1=lMessageLength + 8; + var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64; + var lNumberOfWords = (lNumberOfWords_temp2+1)*16; + var lWordArray=Array(lNumberOfWords-1); + var lBytePosition = 0; + var lByteCount = 0; + while ( lByteCount < lMessageLength ) { + lWordCount = (lByteCount-(lByteCount % 4))/4; + lBytePosition = (lByteCount % 4)*8; + lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount)<>>29; + return lWordArray; + }; + + var WordToHex = function(lValue) { + var WordToHexValue="",WordToHexValue_temp="",lByte,lCount; + for (lCount = 0;lCount<=3;lCount++) { + lByte = (lValue>>>(lCount*8)) & 255; + WordToHexValue_temp = "0" + lByte.toString(16); + WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2); + } + return WordToHexValue; + }; + + var x=Array(); + var k,AA,BB,CC,DD,a,b,c,d; + var S11=7, S12=12, S13=17, S14=22; + var S21=5, S22=9 , S23=14, S24=20; + var S31=4, S32=11, S33=16, S34=23; + var S41=6, S42=10, S43=15, S44=21; + + x = ConvertToWordArray(str); + a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476; + + for (k=0;k +printf("hello world"); diff --git a/build/img/._flags_diagram.png b/build/img/._flags_diagram.png new file mode 100755 index 0000000000000000000000000000000000000000..0cf051a048e359f05c347d21b176729d56041dfb GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207T1k?}+(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3WcnU7 literal 0 HcmV?d00001 diff --git a/build/img/._flags_diagram.psd b/build/img/._flags_diagram.psd new file mode 100755 index 0000000000000000000000000000000000000000..e7e5dbc53882d42e91afc5001decddcec19031a6 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWISZ$NU<)TtU!WKc z;207T1k~UU(ZNuGL)obCXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP&EV? zfu?~l7|4ZWWELwFr55Lx7A2=Dq~#Z7D`e)Cq~?`m=I15m4jn|NjF3Zn7Q( literal 0 HcmV?d00001 diff --git a/build/img/flags_diagram.png b/build/img/flags_diagram.png new file mode 100755 index 0000000000000000000000000000000000000000..ffe378079aee55985bf7bf192109fdd8ddebc67a GIT binary patch literal 40129 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 literal 0 HcmV?d00001 diff --git a/build/img/flags_diagram.psd b/build/img/flags_diagram.psd new file mode 100755 index 0000000000000000000000000000000000000000..7e70a0e7ad6dee6368af706411c4a99c1c1fd015 GIT binary patch literal 431039 zcmeD^2V7HE_b-dR1l%j`O#%oiifjc1LBKsj2oMPg%|O7qM~AJp)={h0I_loLT1VA7 zYMm?<2TsHR$X+4;bKlE*8GvHP|NGkSz5MdVz31M0&bjN{aqj8w8y0~vFydli7-K$$ zu`Dq&4BpWd)vCX5PzbvV{$YpT^=`OdXXN0ybdXnaqCglgQgWk2v0|xb$AS~5J95R* zo*l=yh44cX{X}u%z*M;?B6UQhFg0E{AiAU1V2eS?9?1!b2_mI{o17q#Dm;=sI|`y@ zQ6dj`N6x&CTpUCh@7d7@d2q*ugmL|3auK(mlXD*-pU>y^8{ibhkLe#J8o=+(b>X`> z^PF9H&Tf5NoIPCJJe=LQ+NC>I2yE@6_ zu{`Gi0|xN;E<6{PJ^;~2ks?(JlKV&%orp-tc>F~QpL<^}z6IF5vPFu8) zCz6N~L{g;!!a3KQFyu-|2oIUhzcgX`kz&+V^SIw ziw;sR4l2_;m|xOMRR53yM&kjqi#*Db{F=P{63hl~$m^Pfyy zpT}Gxt~&VqhuA6=#X=!W5;eft6t0XYrbZ=&s|{C&j1OY#pG;iDO%g~{qB=PIhgg{^ zlFL4njW_{ZSqwL|E*T%h%0HR7T=r+UNHnsBeVBfHC`0OWeR{oxpG+c?hsdHugI)E5 z>6~@VpqH$Y7lW)Xkm$i6 z>_0S#dZMY5RG?S^(qM{Vr;E!o5u%R_T~W{WM+6;Qa`hnk(!oL`eu|<8@eEvbXz4^0 z0zmvnGq6tZhSQiHCz8HPekG#9p&E`vA&XH?7sy3Eu}~%&Az2fV8iq2Cy?&91a5c;x zvcMW;CjqKAn!10PNU=_4Q(5s>z8I7ESH?}nMJGbBqA@QtyBfnK3WjDE z#frwf(ClgqmnayTT@))C^Fp($F}m{`C>WYu6e}9@LbIzeT%urTc2TTo%nQw~#&C&(q1i>TqA@QtyBfnK z3WjDE#frwf(ClgqmnayTT@))C^Fp($FAy%tG9;d(k~R%5ts zwg=M9W^{lX(%mNXye$*upfww+Qi292IC9{Rg(;K~QJ`pxLj*~cB9T;;fIQGUdiqJ^ z=-U<#8zD|c5WZq13WL0fI7M=#UlbWIHWHlLV}V#0#>GOh82E`XAtu6x!Cwh(E*Kwv zTr32WVNu{G0e3DI0e3lki7*9FsnhWmINvL*H14v)1M|2D_(aAV-1x}ma(VHVoj3w?Ew0pA#^S(F~tPVn~+8; zj9LVt5+#kJj;aw=R>9GztYf}Zoj^x_Kx;x3d4w8fq5zFXkz%wY7*$$^K{_1V51j4c zZ;F2e`Rk=+8Y`En5)GV8WVpg0*&YW(px6oRKZwIxpi;_)ilj)1T@(!t7&@Ln3v59E zBNyZoln~2>$KOpq3(m~Yc4*pML(DgH2~ot7ogM*WB9JH}1+fNDHbN1E1Etj;y`$E*JHRIbkAOQ^|0umUWA)wzf+#9}fgqN8 zC+LEZfP_}t8UOezZwV3=@D9Ja!rdxP9vBW!N8sP>c-e63T^cnalyn#4RiA)~Qw5G9 z-GvH2)Mw#gqXquM$##iiArB8twaf4PjLQ-Btt28 zMN$M6RtbfZj3-eUM)7c(U|1OGj`@SkodCZSj0^poJLZ86P(tel{+OREF$J&hTpy@y zB5sgW=!Bok?rm#_6v3ayMo=oGO%nc2YZIS!V0l6tQrIhQ-(Fe zfzguDp3#NTi{ZlP<=IU<5P58RHmJ8LAdTFKhT+QT}|y2wgn<*;6} zD%mD%2R4`8hdq!T$R5QOvOi+aVt>K@j=hb2gngc!#(u;uWY==6Ic+$-I3AoJ&R9+? zXF6vQXC-F~=P>72P6p>0r_98}q?t)KlYSH%*?Hl$x5F zwlwW!>S-EkDlk==E;3zhy36#m=`GV|rWIzEX6?;f%!ZhaH5tbJh>6D{LHWoNR(@qHSi|tg$&_bIT^**4(y>t&i_?wg+vm+rG9lx9e)> zXD6_mWw*xeC%Y`W(k2c~oSTF;Noev#lO0ViH+f-iYTwm9z&_f3f&C`?bM{XhSPq>W z{2YW1^Bp!j{Oa(`(ZsQvW02!C$Hk7j9j`eSHnnfsx9RAn$xYWZJ=rv;8LL^>WwsWVEPi$!!_XGQQ>4EswUm z--_L;XRDE|rnmaO)vv8yw{~nju(h!D=dBO4zT1Y`re~Y*HZ$66YV&)W(zfl|4sDy* zc6HlxZC|%**3P@#w06teoobiY-l6^A_Tu)-+n;X#lG~K)!u%lMtNTaYH+E0&VbY_2kN6(zdfe#A?CI7s zuIHMb*LyL0x%U$HTG#7lZ%*$4y`{Z3_Ri{K)yJn#QlFiD9yv903U-?3bkr%I*O@n- z_ciY#ua@t|m+&|9vz_gohdIx4KJHxP($hugvc@Id)!KE4>ulF!u5bJH>MQE|ec#(| z4sIcCpSYcMQ@i(bm%HzA&+FH@-_(9<`(^ca>>t+ui~g4ea0d7em_6X<0hJ!^9!ie` z9t8vY42&PRW8jNH-3EyUZ65T*v!kcLbAxBjVD8|lgMS#DLEPe>ePbaL-_Q@bM64$gq%aLhg;| zGD14yXebsM6#7l*{jhFfABCM5X)-cw`~oE zsYab0Z9976=QEW4T5D{)a`&PN^}t@x-=K3u*@uQhOGdIj)%!-ZAiMwv>_TPPMPoF&-_BPwQcptV; zweRKrsrxez3_o!8VE==A4s|)S_OQd@&yO&Uq#P+c8h143*tlaie;W4F+2aF`A3ou9 zV(ZTxeqM93>B*(1EKV&rr8%8?y7Wxqnb*I>{_^DPl(X6A#-2+*Kl1#wUx)vC>B5i; z=PvqOJblUY($AMYF8}mf|KE;YaldlpcemdUUv;~B_?r8*BiH*~KXzlljpH{5-8^;6 z>((!6{%IG|gVL{LjL5i|IV$sZ*2Juw+tIgQ+>zXQdpGHBb@rTloO_?&x4XacL7N8~ zANF{-H^)8a$-TN+mSpe&)Ry8QEsmKED7 z`&VA98dH^9J-x=X=38|S_3_%_wf8g$8Vww1C%|O^7TlRI1A-N81=$$ph#WvJx0pc4 z);I)%8kaNR8~xE`^iIg%xQ{!AZ2(zpj0J`bUx;DfJ;JbVdm!E;Fpp&o!_)y7)76#w z<3TV?5#tIH4_pi@ko!0fG@4?Nfla@`F!fg&P4z~NM!gASoqHH|MoP%^2)M8iWM2L zY@4=laA@k_(4vVIerX@Xhw+_ZZE0z3V{K<+W9MjNW8;W!HjYG)CXI0)>(Pr@x#dkTCKIq_<2ad`aNKYdIyl?20fUb^I&fU( ze(i`b_$B;ip=;-;NAh{g{34nP6@A}!F+m8Jc6B>@3y|2MyHfO+LZM*{y6I5R z+{LU|c$!TxFRV0jSx}cAotFg-3+lWqd|6QE<(s>Sq7LTWpCI&eVvRi3PJ>-a?U_5I zZSN!3L)%C{o*Q>I`L^HbM>ZD^?^3Pt8d?w(>YcU!iK0!LK|Wt?-p^kz?b7k{@nvI9 z7MQ-yYJ1`OtlY!-4=1etD))9l;jE=ErfIPG-LGD8>Rmc{%IHU8X`eOyX1KqR{gmyV zy0msiy1L7h5r>w)>U>~HXxI@}A63BaRU^7A3%r><@s*`#^--5Yt5>i2neSO(YnOGx zKJ!iIFP9vcd|h^{s(tDC$f+1)3^gO zc4xfW^X0>mmA#yHjmp=?`263&e$W{elWdO7By`8t%+*c?y@SkR(B^gmAF40J#!6r%*7uM-i*Cb zI~}6AFi!oo(9G@T80+Bwb{+i z{{HIW&Hbkf^SjmFi~KsGcbgG=my}r^_-Nf1mWyACntihD&9$=V39FMX9Jx6Ahgw<5 zF{J2#3gXy@J$B&L1KJ#$3 z*V$eg?11UkypS$)65>?WN|RWS00I&Uewe9^VpzVo5SW+mRcUVL|L zcEqf2?)F_5_$YSCiWy(r7uhgwwSLieN$bfc?iCbDgfl-|8c>^XRb@RhIG%Ot+AYzX zzH$u~@6|81%BygDj~mTz1Y5QWKF=KB`E}D_9?~w7y)*kBzgt?`I$}cpy6oHclV+%Y zyE`l#YT0_t&63w^_a0odKB(-Iwn^r52EH;ItM-o`dm$^}he1-_4DUFxP4C&=^4<*J zmO3?E5|d;3#p@ZD((-04ezC)eab(W(Lt`)Ywcd5?a`cQt(@*Uvn|-$PRuT94_hw$4 zwZHeeB)r{2Y~5k=k<0eOPc2+hHR1b$E$hn^zkW9+bW4XH);-HMJ>>S_&7Rxmm!s(> zGuE7g>(WxcF;}%6pSR49w`Xw+hU?Li$R|@Y*g>g7ad=fk!tciyojPFcba8L| z%l+kQufwyqXfTsQHzFpmJbr#HJ2W~gv)`QwJNIGFPi;NjE_0xG#>^w>8te!4=X)pD ze)**a`{X09vd5cG?ftq8a=tKMR(n6XOV*`oclXm}M{S|3^%%Z!o!d8Q+c%f)*)86^ z<$CzsmkF(Z7&*~egAG5Pv0`;vpn7*ksRpwQtxewE)Z_E5qjw)sR)3po;&x{E+TyWQ zAyuRK1F|El7Wuv1=OT}vS2blgFx+!=d#+}9ZgK09*cr`OvL zMcz^P47B{{{#V!4p9X~l&p!C%X;@8cR>IYL?rl!A|M{59@$#|HS5`f|mQcE;YD%ux z+S+(;RqXK%!V&$BnPSz8z1v^Cf9%LkuQityJ!Dk@8#5OjvYE>07A`!$b9XnPS)Y`wuV{5-Sx^tn zty0Uk*~yIS``5%)9{p);MU`lqyYjc*oIM9}Zrwk@*=zmf#?u?y9(}Peq4VSFcLyJ zA7x)|J^kd0*_&cC*tOKxsm;SK=1m!OeCx>5ZJxK{S;HygGrqsueaGJL%O$s8B}j8; z&!4#XxH4OKZt(=gchwX2Ne2ebx^TZ__2jZW*IyP4-MU*n=H)tGm+L!rowzdm&ZfCm z8!sFS%|E$2Xv9+Qmldn;`)w;(^;nqkP1?DTJs0;qjU0Y-e@0c7@bSQm4W+LSf4Td$ z23t@%)4%;LPldzQr!&8rI&%7*eHW4f?lk+ZMXPf4npU5CT77(F@0C+8U*DPX2dGr!oeEA_tYWcfqYk@3}Do~FCh5l6SF z21ySuTzSuF)6%77F?W&%%E#Xb-F9W$j;xFq&qkMfl>jd*4lRFCa;5P2N*mj-oox?i ztsX9oZdN%Yy4UYcke$Ec13Z}Z(Yok4NJe7IqJ>c_BHLR`h3>oL}t;8yowBq!kw2- zxb}Ko>YSg@^k{ZW$kC_KlKmMGLk7ELo)(S1Q~BAc?W!-Fj?R~k80@AT*t|o=`bHd(NCYS2Qzt&UkPC0mM z<|z$!vrp2%motNpANM#l!gWLh%Q_{$_56i4GiP0n-4N0K>(INqw`;J?o2sUj%F<8g zoPP0R)vB82YRAZm&@nH+|0MGArmdwPFD|^D)8puyq!WpK#IsMUCLFmv`T7QE+%%ZS z_S(BwTiI;=x_!m8hw7fE=BbC*TGoC(W&7-3X5So^UQ=Bi-*5fharXVy$a{U+gXy*7 zp3Z(f>U7npnJglu)8QIyo(9{vVtZwIS!SFDJ2~h}RqYB{?TSgJ={7r8&(3mMJ-m3& z$)){dyUXtg16x$ulslJso(|+i5s4+uT$Ow$ui(v*ZqLlef75wcpdN$o5UW5PaDg4o zxHHfY#TN5{g;lg?1nn0IgK1nDEVs&FzX*Cu1PI6XKoEORTwq!lq9oGj2(K8!B_ssv z2`^@tDZ?HgUEyOyMk{=S3`#tT(VBXn#^|nvVM17Ed?^;;DrdOh?`Wj;%_m}ftcAj& zv0OUVv=Sb$ey@GL?@)UTomB6^clB@?z$H(rhX`0dFo?7@8Vvh^Nv6TF{DDQj6HB=O zYr=pjV|X$!6Sz^dFgogJVf56eg~_1eaA8t$Lkz?PV_8?ZatN6?tRDSqZJ7mr7xl8PZb;Z0&O5dS&Zi_n3Ir$9~(~bm7{beDfr3~8vo*}|3XQW1o@*3LjGcDOfve0KmHvr zjhE?vOB9JPr=atf2qh?fL8{$s@%HBD8%oSlB;#gcSq#^-(S8f47r|i12GgM_W{5w$#pN_d?$kI%+C=F zV;JH(+)?{GjO6-Rn6iTX3Lhf~xEfu)Ez$lkfixBtEAf^kNg;$)a!eT^^Fu8Fs(D1M zCAZ$-U$7^VYp@}v{;hbS8chyFfG%n)o}L@E6;JDiXh~AwYrvnRoa1)R|2BcwOQYDHP>JfBX@>GH~dZ>+-D}^|_bYvLE=-Y@Gb;x6l zh|%v4#;9YRF^>L?h_ODZbunU*a%qe<77N%(AP0#<3ZiEWh@NuTPk>(t23}BsWF{vg zzUj4Q%;Xg0LO|koW(p2t;DW>Ghf?A&XJ!zsBZ^sx!<=!V!r4#-I7k{TN+$Pd;k^XW zi=dv&5(@_jNeCh{!aP>H?b=9MQa}yB!|D2H+y>ZxeQ(m&oM>+pO4Pm}$x_$0SSplq zS-dDhnIaKsJ?!gfK(7A5k-@Gi7ml0ghbB`H7|~O@dS&dqA}uVWgJy! zEsl+RwXoeWfNN<4=Pyvig~r5yL_`2fQR6~hP4$37#7Yq~feB(IUJYS6OM5lb141eL z2@>_T^fllMVf88ZRVkGa4qTfX#WqYPmg+^#>E^;3%w3M8UnnJ}KrAbl(&@GSR8~FxVj0Q=&@Iq*E)csx z^u7{Mr$9DD$i3^n5@`qm8X-?WZG}D~L&5l+SeZiPrNPd0eJDQ}qF!mx7TH3lB#y>6 zUgAPFM2vUZjTA3j7tHu#DujWH5-;4+d;P}6ok0D8*y&Gv;dlMQRezU=>c2wj5(eO? z2VtOZaujmLNJ=BxiX@aZ2zDO)kzCvq{?+i`MM!N9xFl^YLZrbRs+hG1h1AK){d)s6 zx*9FDwSSKhG8BJgN<*v`8#vi{$2h;80#5i8fvyF? zB9ns=jkvrOnXKe$H|&mw9p6$I=cu4nwT6Ejd@C?6^a>JaWn}5< z&m&Uf!qiAG>{2Is4J));Z>U@hmc*oB2n5&mF>pid(QW|7LgiGY#ov)1k`>U?N2>H8 z>xYjNZ^di`pn(CkR-gcJ3Lm@Hw@q8?22r4LqbC{}w1j%1lvH`TtjAOYi!PmLBvpC~ z2bi2ej&SKjDR3WamxDV(--mCM2U?9~JADs;Z8R=kuLgK)<2J-4YV(mZS`PzU!rkR_ z2zPUQAGm%;4ek~JQZS{13=ayF(P&!0CBwpE&>#zQp4LMwR9cuL2XF!NZ!$T&;h*L_ z6d$*Htwyi3{8P%Jbq^q8@L)t$80_DOl?xK%!c|foZT`eIcW^_j0e3CYdhii(A`$RL z=Vi{*hQd31+?&hC0U#8p1Hry{u}DEU5G>T0}pa9w!b!7h~WSH}YL4PNX(b}OR$u{Q= z5z7@y)aM}y5oCVAkwDv=7oil$m35s1q|tR9BcPuX`HH~emB=6pU2Z}l9V!8O zbTBCU$-lN3nDY?X!6E@_S;3Q{LFNLb67%NE)k*(@Gp%cdolD*TtFW?s!28G)PC28(e4TM+gB7mzEkS zeCZ@Byc?p#Bb_@bu2GT>*$Fj5Cep>y_}D?jfzh?DTSQ;DT;bebCk6}=sFHnUpwX_B zt0-9nIR+^Opo^;Ca~k&JdR;1#6ttbYo`3@Zv;m)4O9NJk3NSD+9{K%R?;6UP{cbBJ)5(@_|*f&|yOjsihYj$$yR z8s<&J@gij$DDTF`8F~ea!LqLkOb;8d&tKPw1b z(WB;wbfRA{NJuI{EELqfBtu8Ye8D<+QaGq9A6I{y_ZoNs+o}$LTVG#E%y!hMnglR0&Zqt8Yl+ zaG0(VM+-B5qu0MKHYqS8T9p!+ur<1h)Ap%?jqc>-+TSMbF zG{1cmK1M4W6o0@QOtp9Ui(JRCX5ad9DfFWiw5fJs49 zPqfy_)%r3oH9<~fg?`iq68j&H5Faw2>CZqBI%FnNhR7Kr5ya|*XM#PjQbnvvanV46 zH%cKI0^=_zz@m-x=+_(eW zom|{q-TRSgqW~~Y)kduscfFCrNKGz~DqwLTAq=J`lzhE~7IH`iF&Y9nYZ0Le8cu}~ zkc%F+R7@mes8&Mjpnc$Q_&d6xKNJatOeGhJ{Ph;&w3G6%jR4PHf_*%65+c4NS9h2C zaD16g0gJWquv8le%fxal8ZCpF^G3+!LQ*q<+kLu z)tK{}YCJWQ_~v{|zBS*L--NH`*Yel#zvpxKK72oZ0DmYyh%e;N=P%@c!e7GQz~99G zk-wF{oqvx1g#V16%g^VR^2_*Z_-jF_vjaA<2Q~?tiS>r1VGnFz2UZ7jY@>$5<&!wU zLJ-1;+k)FhW5##X4Ae~EoAE99R(u=29X7E$HUXQVd8T1wn>1W(E8kwjB0>%qi4yUE zO}SkN7jm^jOCKcI8+qVN{!qq600Uz%C5hxa823J=kx{&pP6Ft|NJ1ru7b2S`9`%ny@)ySC`WMF4mx>E#Vq~0X z1hfh;hlaLr=~i@kln1qXtmkRyW|RRG<3~V2LL2x5uw{b_TjYjfz9{hq7mJw^jd ztVR?1y!S1yHezx0{Y$I$F07K1v3kp@JhGY5jj?(4E~)bBSy1J@V>y-T49xLDsVj>g zT(opS$!T)37@e*bQwO@ZqTARa$)6qJi8ObmD zf-^3DkfKSQ`R6|s8Nv%m$a>8LF+9Q@_4tefqKzYZkaec4d2rk#%3NH0rq(?`5QY6b zLg?gl9M*EGfeCJ&;p_s>Un~$Jfm#Ud62Ww%`iIXCG$3{jg`N^M>#@*l3g8^LAm}$y z0}lsL6ODTW#GR;JF2W0*P7dcqq)3%-ijG0BuP+JkR$xPb zA~<9AUHIc1*2BNS_(Nc4AUbSY0J{u{^R)ZmyTfBa(m*>G<$ov@qFGeI1}g>5UcB*g za_f)UGhT$w9dZ;h76v)60Y~c>Rc{EbYh8E{1tidP5DE0tis$|^A*?G&K~;kg(_z?z z*AudxZ>X83WpoV;Eod2?meFAkY2C`u&^Uya(Frk)meF-{F9u>Kx%rWlI%yf*aF2-r zvvk5UIr9qAAW^_*8J*lgLd)nPT1H2eLQlq}7C?wGk#6dhmeKXNM2!UgqcZy7!A4r& z?CFGt5K^l)NALJ}TdPo{a{ym6^%XR^Ldcmklr?d6{uMtMzqdgk} z7M-FA4L$1Y6Fc<%U$4z8Z;I1FX&ug)wPGJI_jFEi>8MfRIq(_{|AFvd4+@GFgqEQr zX#T=+BsWkQgF9#$GH~j3T83^209}pOGL(UOMT|r?ovVxk&7T-FZ30gP%sYr4(J3M`^wKhc~9Z2!qTzBGKJ=ibnLk{ilGc2|*Klaf7wzs3e43lu zkwt4F;`Iv+WN3|ATBBCG&PUV{ZKF$ThSQqi|7gu{dl*TRz#!~5s`od zJz#xXJW$8@Kc`GVH%}o16^C5;}Ks^OGJS_+AWh^RxaIsDG*! zFSV|Nc&F9uCDwJof!ysxEAgU23)yY3V@j`Byt{lm(RGJlAKE-fDCElV9iTmtOaJ5xYT*!9N}@HVXw50DmKLeKq@A(?rK-P6 zbIQfJpOcF#-x&%htvQ9xHUu3gT5}5IL|Su-)|~od+F|srOnkIi@4Py#IRz7n^sY?u zumoJ2s?Nz@^sY?p(P*^hl+ii9#QX%UIYnzu!7e9SbE;lt5&Cok^7ID!bOZWyg9c7; zpk;JgMmIh<-azc6Wpr9buX6$~eYycy+#}EJt-GYHovp>!5NR2mmeK!RGW!37=9IA> z0b%W`F&4G{3N4rSX-+x(BQ&SxbvM+UN?rSXghr!26EShrv>iJ(gUZK`@IMd#d{990 z*V;19f^Uq`6=_bv9cfN=Mbr|SQ^=~W3DUPhSEDtjO!4Cl{|1Y?A87Ip(V?}di>UwO z7Il#=_4+O9vaz)n6qtCXTb(Bxn{m(|_c4C5F>f9L#!Dqs$rD1= zm;i>3U5VbwPK@e`<*%qMggfe;hUj`HWRkP*83X}WqkE_JLV;YK(tuJgSAgpc6V^jr z3LBxg^B*dmVxwM5)+CpgEL-1)! zx3FE3)-R{^%kjlDC<}GZ4+lqDznr$%OltcPOC$}bNw{NOFuR+)0Hj-2vg0>YCvp>;T))G3Ej-K_- zdJKC&+xEwM9=)g=IzAZUuiwZAcu;0O>NicT-#gMu?SGSH-G5ET(}2Ki-vzluYun4Pw)As_x!^- zJhVkaFe{A==IKmuH+X z;F}5c*jJ{lj_VfpXshEQ+UhtyNGDZk39I0`1E;CwF8#x%4VV0AyUh) z(CYaAgkG*rPvHMoBbTsL_ddPcX8#Bc!>@}C^>U~7k}lO~YR*Ir6sSgx3Immnsi4<% z1D;=i=F=)d^U0J9sYyNE-u4Ffu+#b{s*o9LF<3iJFNzD zGIDXeNJ-m#Fq}{@91+ob%jmsj4eFQt3-^}6(Md9)DnTSwl481omeH;FHhep5Vs|(o zdWMFU(KUQpMyF+TTK{7L*Qr04HbxS*t1GSlA;%K%-Hlu<92<)H63S+E7x>5}L3AV) zm)8HF^*@NIMD2Vb8kNZ6MYR5hwu3>;Ay)51O6~;s(9Q~t5G2q#+PsJqsWMKa6btc% zJiG`Q^XFeEqyPK#KhXYv31ROE*`M;NXXm^UEI>8ZD%+pkssBFhkJkSP?T-!ihT0!} zPpUNcO%GbrBS|DrL8d+ZWC@8fg-EV<>KnOV zha7JEL{C#GlxV&m=K0~$&dz|LiDa?9-E%a}rQP$x8#}JfMj#?O;*Nvy!d22>ku+8r z=OdR3QXqgE*WH=c^q@68P$`2s4O-KK*7P778|`j&TGNBp^gwL`RV)lQW`w8BIheA2nn9nZh3<7q(LbmsQ0SKy>IJ;bq6G&l$p z(V8B#r4Q8K!bNL(2>J8*3;Cb$m+&|6H}QYuZ{=_2pW{E_KjY`}^ZBLxGX5I+6k+-l zVYI77f1Q~=MVQ*^<1dO4s3c0=jvqqi;)Tg&i6XgDOw3Gbg?nCombB?pgy~&m^e!@; zmD-3naf}k3AdL_Cj7K>5x6$~f-f1;j(}Nl<8yp>BIGsRideE94w5G=(XliI}Y+BO; z887HwOKW=kh4MbFjZKI#$To(^R|LmOz}|OKw!s~JV!(8U&do=qlo3ZZ3Y2hiv|L3T zR>-5=qQ}S#w!FYlLwm*}7ftg)OBNEvb@1mlG4{q^u{)kUn(*xfK z&7LlhC&C*C{^sZ%pKTLKRS5#;dN7CRG(B2?pGh==fUD7(9;Oj-f%iba6-l>oPW z!o^&*{!)b;{MZV}a)iGmMU2V|8~$z4w@?y=a+!_NLEmC&OtRJ=|Bjc&qjG`Z@o$MD zF~;CqC_(X4d4u9m#3i6K0^!fV(}2CJ@Q$v&@YnIoEJ36c0I33SMF^Nn1SukUq&NX@ z;(Ts@b))T)eTmv~q6EIP1{s96RN!i;c+oa5(aJbN(I#2qZEthU*1z!yU6Q|_x$Dq)umxHdP6Z5SL8 zs25#B-Vjos130oMD7d#UiqS^`TNTjOWG#jb`a@WK?D24ZC>$z4`l&?-1rkxPOc;+U z0QeaY5rJnpu_2oD*N+yl3}r%uh^%xd2L0%LB_e5bh%B09DYQ${5Ck+ro`90mXJjZE zS}IeByp#*Qb=jm31*27wis1E{Qn&P8 zzj1LVswpMD@VkEDLZ`w=VDv1L;)P2qOyG4>>JkRvs6OL$GbS0ARP4^A+`wb;D#RZ| zT~A5E+YWG<2mj>|G>ome^WjWKX5RB(qX#+Zguk-}k=8thN?PJK~4{}a8_ zGVZr{@1*}^W3fM`W5~t$$;O1+FJYTrdm2A+e*IH=C+G(dzLJJ}r*_EyzrS}{NcT>9 z-HCBS41Eytg*HOJxukn1x_A1}-l;mXmtV?QueUzvnuE6;hP~4j=zFT5ph54%>_PNS zjNPbr!j|A2?-E=~ehCWs7xYeUD4zd`-f3&V7`%7Vf3mSJ2HnGui}90%W)s$CmZ{0 z)yLR?dDD%bIKKas-pTpBy^}qn=fA&q+Di9Mbnis>POxzDAD-FM_JZ06Tcd$DG+mDF zXws62e=$+3q8mFgV7&>y;E6)K|8F`}E>k6P@!rW`-C`(y;+G0mF1VOc>n4Gjbd;{% zx&;^iRtV9Wf*t&Eyb=Wpw7`P5DF6R!6npV>8=6Z69@@}9ngjpq9GI)o{mS&-=W6IL zk~1_XXim`efh+?wCumL}4$!S4Sq^AU(43&_16c-WPSBh{9H3i8vK-KypgBR;2eJ&% zoS->@I6$|GWI3QY@lW6cy<+gcK37iDk2pZqRk{tQIYDrM?!U;AKy!lT1TEQ;Wq{@c z%?ZQ-x>Y300nG`T6Lftb%K*&@niGfvbgM{~1DX>wC+PY>mI0a*G$#-T{;91Zy<$Mm znA04fR}9Ej{GZy6k@)|U+hUpqf&+9JBufI#37QlCT-lP$JM^SWGRX~^6Er92`aqTe zniDi95C`a1kt_!^CumO4^?@t{G$&|IAP&&2B3Tap)107J4CwiCngjHT!GBA8MB+jB z5;P|W4*aKkNIDGM0+X!4_ek zVn2XI=T9&f?Jo&S!e(HfW8Yxw!RIRcuEXyhb`5^#;ddFkfaPEhut)gsG4>d{i2Z_{ z!~L_dY#jO;29}H=hHoIIBy2hrH<`w}o|hR`SS_O&qbb9I!DcWS%^4O9J9st$mzMC> zgkjCFfoC&t=P`@q~8Orb_^fFbgsZv(NR%r<7Jg|}H*8NZ*%Kgc|M>{8)v z)2v&+oj82_*R+z`tn{mA4}<%O^EV1_W9gjV&Kx;@{#x;E=C!lO^AEC)p1YP&c-!RK z>0<|fxtZP;iDI_-rmMCnQhF!D$p?1Mfda5 zm|6GU6lzRsEAsDWX1}N`(XgsZax)9kSm_V)$_h1Dl}Y~NtnA$4+7b=3^aTW9-Oekm zDb$!0Kf06lq@)T0)V|8jgoqxNstYt&o+gcPyPz0iFMSBWnc1&u-)b;5N-|%=C`BpW zd01eWVoiBo7D_SaO@&d4Wv@{rcV1Pf4O4vc@OFM0Bc~#tOt479sK`OcJ$$2=9;^J> z-HgIC=Dpk!gB01dHTl`#!AgHtQe~86Rq>O8Ge{RLx_y*+)BMvS(UkX zMA^@a^wX_;^C+t*O_R=iR0t$d+%3{Dfo*To*y&j>tAHeZ?y}WYxf$t2fYaS4rTG+p zi#4qB{DH%ONH$huJk{FYl%o0|D82m5@z(Nwdn|hd@D@O19xmP0yZ z`kY#I@#DK0WoexBjC;@C))wevz^*RKyPH{>#?HukQh@TVk}Od2|OM|L|3*y4C=T+NxqGOyy~ujJvr-)wOzP zaB8cIa0AWYngarDxu`_b9ih zsup4(YGI+qthTBs_tCvOnd!A@rWv=hb8-u-0RaNPR~oxoKrlDwPG(wK#$E73VJYMa zfQ^+UFCX23q_gfndjky7#|?0=ttol^^j@YqjdS<$>(Z*)R}^Li8as7)!SjcAfbh(_ zKz5ZHe6?tSC!|~S;?Z45H~r4T=LHpNh#Akjml{p2Rb@%x>z8?XFJBjyRH$F+Fv^Dv zsxEu`TAjy!m0wa`{Zfxr2;1uNqWqWO`Q~j|wfZH63<_3JT=2R!kMrtHVM$eO9*GHF zQc4QnysFJ(zb+_7i4kc0s!Q~;ULu#NI4_Y=fH#gf6(YCtLqojy`$D{i*5l=qhb0eK zkDeP;#<$RH7v?-He!$EvL^V;b5-_2b7D0ggN~j%VQ&6N~sY_lxDS4oI$jC)ylq_Ma z%GXbFQ2fty6%bN=`RjqLB|ozE9KQ?Ik}6UVOKnZ&_M#t|KWDr)O11de*`gm=yKd?? zKmcF$=<Y~O@Y z#gWW8d$Wy_&Asw@Q6x*S<$kdNv1J!lNy;NlBO)V5jhdOEYjhy#hpQ6CLn4Bdy+vfw z1yC2%HK!xmb4oBy^8sH&RY7%=>QkXrEYDwLR)n#=7hFL7ijLnU8t9B}?;cTvaU7B_ z<)N0DijK&P7uuFWJL{XSIFK~Q_HUTUC_}Cl5^<0-~~#KD2CADS3EhhWPDd^ zW(j6u(ZWx)<3VAO0WNuG*QNNdi!hVc115iZrAl37h|SG!l_R?VHs<}KKRJ-A!=@D4 zs=|HBke;^S*=EAxeHo~;CJ-vom{vc#xI)m|mJO+zHS?5hzLO8};xz-MUYU39^M2N> zLh!T~9nUVSh7crs%Au92F1_|;L|aS7Tg;SU(`W6gk}7qH9$FOuQd3d#V?Y;6P7!9t zFm2ZFqbsFV>SBslQ^SC#Y2cQKtg4De)`3|o3IJzoz!ly-Igjg7JWZP*2v38z)^>9ptNM%Y#6-@o*6 z=O%3CTg;4U!43W4#`6-OfXqq2uJFNy9V1PF17-|PhtT=Q?^o3pljxOcOw~^=te5u2 zQDB<*e7fi6OC5fkl4J9uJRQ^+v&~??>HwC%S1$`S#_lyX`THybM6J}N8LLE|?Kl`_ zV%w)OfaS?=#jM3RRzb5jUIdzSrLIC__4dwzg~MzBl;zmfqcXtCxwRF%+w_TEb@3T6 zM~6E5{-LGQ_-c%0*`=RvRe+UOdovbTPwW$xw7;lIj|NWl=}%*PTL79ZJbV$F-aH#X zvrB|>)eSvjUe4yVv1S9*=u=m#GgvpyE#Lx_xnr;JV}`_3y*fConYAexk#y+ud1VIc z#PU!M5W}+TId$zLBVwMPNbYIJ0#FN2#evEUtCf*m!CErQqS>&uH!BQ?IhQh|IdG5F zNxtp3stl`hQ(Ks07~8_WmFj7!J~0(vI=8ps0GdJje+M*gp8vWxplN2`Jz%Gf7^@eu z=4QZbdoF+B%kpaIx$+N$cWY+Bz!*&j?KL2WRrz8^Ux>lB!{8}LD{HNuotfRg4F@b` zI)r?6-;f&ClLN6$fKq1b0g?^(D{I+j=STKv0yy{m>IxJ*UCuC1h@ESp%vyJe{2?9s zHO`x_0-aiz0@9+K514N-V9B!~ayo}9SKqAESQTXLp5<=^rKw?Z*gmP>pUbP%uy5~O9M!!Z za;$(H$ThR}? zojW%!9#9WaW_VtibQ*WAQe#&5@EpL+AJe)HLFPosYddvw9-vwE@WSDpJHH&$+w`5( zyxN&G(#OZ8oo&O_NK4HXS+K8vo4${l?1M@lA5Z5F&`KC( zk0CY12WO1-@p0?W1f{ND?)36Ttud)CeSAtez`hD&HB^ZZF=~xzP4SED?_4aI0QqiW z)EZ9ti(5a%m{inl5_I`etzqZi-958^`8%ip^lHkVUYs?!c_qedh=y9|s*AF}o9f=& z^u0uwlxFOmJE9q@vJo^q-n($JGwXdc{5o^IN2~YHQ2b=0XkbfoV;UTFbws17D!zXr zuDhcNVsAqkVFekX(WpxwADJJ>H3Q5V%m-^!MKtQlqKorJ_HLxclWK_JG;(t`D# zU7K3ep~F#EKLEv&oD1@v%}klbggEFE@;2w}w>}&u16cfSI;x*vTrr8uM#wcthZUj& z#*p{6P3UdGEU#Oh^vS3ye407KhQngiA;UqRjN&I3HU$Gzg;9~R)2HIfijRWZt1*if z{{GJI=wB@G94Xu+8rBD72@9tfPdn6hG}L9dFTb)R+x}$zn%k%;{kJ4*E>Z7nfEP-2A4G8Z%+AI{1HiXjnbu z*-+%ED>J^01jd;#?Seo4LJqtzqRxh-Zc}b``Ho-!0GxX*SROwR06=6e^u zpV|qGXERJ3dJ6V!Q4C_gi@aa29zY$4jajpBFD&Xo$czlfF5#emvhAiSu?n z#x1%0%YvaG&exZN9VRZ?A#H1ogk?*f=)i-wzs`Oafk7L;nc?5m90=?pTKoHp+V>GS z>-y}$9guu)GJMO$N4f7HkkdYN&!Ip^T*Bux`8eyzJVs26wzjb#w2({jke=-@D{Ioq|sb?7lAGL@sol&0E=1n&QsT2E!Sw?O`$y} z^0VN!P&-WQJA2H(onKp0FNqd-93)`pB6kV!^LQA5IHt9cV+E7bC zo7r|?^olzgP5NgIQOLHmbF^XrsO_Y6C+-x#k3w^YCe|Q7GR<5*KYizQ&3h?i*tWDm zBNKa<*dMRKeB!$(WU$SfHZ?&_v*_y+ITVF4y75P0nMO+?%fi;d8pfk`oQT!OG79UZ zkcINF5_4dgI`mm|CFgDRJBh2n92pjlUB({GeOpocZn`QkD-(OCG0QUERI3}H2o0yo zF)NFfVPBnmUP94gD5A4aZUKT!lO`Q!TzXJg`7Sa{Ol^CH?|{_{joCX2VFe6ooAnNy za~ovtcNIQ>v+fc4@!{fHm`1BVQwS2+Ej(0*@2NGcddr)Z0uvMKZbR4Sl>u(`lr(KV zm~;r3b?9yx8nwKe0LvjWHeAYoKLMRp+s;3%dN%=;n2Cv9@Vavk3*SdV8?WhmGhwc` zUJ|tZG0WVpd5ac-AD@ST$~$OKV`ipyO^%vtl(!}n6tZA`+P zIiDT5S8PNLwdPWx(M~j&vjb9R&6&IQPPw{aY6zi%Y1>0EXU?LpPn5ie8k^ps$~kjZ z9lHBYYMOgVe>i$E<4KWPV+9LGPxdABYgkq?bCoaOfBM=ZSWD1YRhPbch|5Zj4atIL zCKER8`xzEIfhczAtGh>s*VEM!RIwc0=j=Uk;pS7wO-@aI)?Q`jIvuSxm+U>_zB~MD z+M~i6jitKu*)f%;v7n^QD0`Rj3yl zY1EwkPl|AaYb$g1&J6BmJn5jF?y_j(8oVmM5++`%-=3N_xKopc$LZ`AZjsZ^!u(L) zZ_6Tkqj|#yWg`x&SLED%k70i3%8GcOR`rlX&JVR1l&~ke4CaRlf0*ju&8kjTX{Wo) zTJeLvc!JQZDZZrg>E>WOPS=vdV6r*Wp22X=s`BNAUTh`^Mhy+D*i3e7k1drN&cg#y zmMrLj8yZ=`L?5e3$d{Qw&EYs_4znI=w3By`I&blBFp0y-OX^_5V$`9=nh+0Qc)*#E zSqk}RQuTVD2aKVp4M;Gnt$coZ>6qST449H<*vD=^ zf4|faag*{FHx5o~Zk~^savVGtpMFqiI3NG=#^DwIObBkuXyN_Qk2fk{F+sapP^K|a z-#)PT|JZvE_$tb*e|(ag3ZVqB?25V@R}(ITn{eq;B@|szEWxgb8i|Ur62XSLY7{AU zaaUc}N>CKAN5z6t3|QzT(xk&BJ-KCO{@?F8GdBqe`|kVxUSD_r`P|H%nWvn7&U2n; za-X>*O_2Av<*%P@YoIGJ5?DKTV&?=tEQm`w@3p17Y8z2jhn4)Aogd#hv|T(1OG3w^V;Rv9TH>k5GKCWiGzy1+tc*X&z9K} zvG|EcKdq1JdC~j9gCG5TT5#$~sd%~*cTCSq9{;h)qo4Y{kL7ee5>K$=+jP71(S`ia zkm#eI;D)!a>2Y)tA2`LO{IUPtOLw}Den3*BYR8J1r~Ho3h1zA_^3{)(!KNhD?OgT6 zb%`L!pa1vo_nLfW6BQPojqP7E@1X(2dfAH$w*advC_K?IgPT8pU}Q&Bc75jC%>n)s zLX;%4X7{R>M;?<1tZls4lx!%kcS*vt$>oJ3dsX{A!^X}EHF-+t3D^9+Z>2x>>K9fX z^pJ4tXE#OsM)!KZXULPQ%bPqXtS-54RFyxj`xVRh{{jvLcuKhL-cfylWXPp2l)Fy} zfqLuPPZd=^;Cbw&Ws#<+&G6zWl@G+ex@gBir~@0`sC>XP{j;65P0$9{y!Uj~1D*$8 z+S=r?=!AO~u*~gC7FB&6yJ|b0em2M*|E5wG zSX=qE=bNq7_~!{%=6D(#*;n>$_1E^In3a`{p8?mDeY*q*zFDyy&s`6C9xhL}qe;hq za`hPi^t>pjQN|HLpkD5C55&T(GjYmuzVH~`6&nz>i znvd91?MEV0lOCB`^q1QUCry61R>}>OX?wP-$HDvHRO8|Jzua}(q{$Cf;Wjii_K~Rq za3AihsR<9>HF3h-MN?c9JnzL}PK_faQ!Ns5uRS5|w)=6b1Xv(|ebEA+dJ-aS*_vqa zpQTA=tGJX__*ktB9EmBdc+)B+(#lRrXqCe2Ru(D}aK$>7TR7}iF)64paM-vtTct`j zHjzI3vQpX-lzT6A>}$13W*P4lV6rx1ON->7+)9aI9iijdu+SDxiIYB-lp=+0=-(>RY#oo zcP#%c%}rc~a0GD>M2dD|2mD#b#^T$QZ|m5Yj{Gw_COEYw z+PCC2KJpgX+`OACTRLA>G*3r;{u=+&dEve!mh2wmEN z6j=a?R%V8WxGVy9zRiqewpFgB0?-qrC)8B0zO9SBT+_nG65reZ;I*CFFN=?OH3zBSCGUx&RMSNtIHI9K< z>4^>n888*mg(wb8kR=gzB%`emz=oupXSH5O7qrk0EZ2jLoI49JlC%e^X-gr%RVC3- zLe-bPkc?9&KK%F-PfWY}G?0E23%d;%_xJ-h4`rQ8 z1F#91!VGC}G-E*`c1CMOt|a1`rfs|01|=cbKq4XYk7{<^i3COjaz?!)Hg#Yz`Bnl@ zNkDH4e9#+AbTJ!SlPPvgW91*cUAQO5uvXw?IjNuri~FGjbocaRqQ=T-(euo^-u>#E z(r*^czdVuw*U#v8?xRZ=ym}FOxzs}KuDgg;)d@~V9MmHX2mu9DCK4NQQcGF{7mz08 zR(%e!08Om)ps+)=xQ952`T|LD=~rtBt5jA0B3U*W3gd?I+ z4@iiJdZ$Ff=^z)M=vRu`NJm6j@IMYyl_XQA3W2 zwzLQeM0{9yQZP!2GUW0} z)25lz?P;;&{GG%_yI*$aL(`^Dv!*9LFlnUl6OKlGM_7=J%U_+4V>#oHnvm$mX8ZzC z4A*Wfj=&{Q8EGUa)G`{o%u?Az(r`G|LZ@*Yk|9;i!HMXA?}R7EziBEkETyVF2H8$o zJ^KwFe9O00X64qEOFo-@sYQPW*5TK^4{6-s%04~)k|)0i@36P0%sRVwmrfa-ygkl& z_M0EWJ5ttuIk8_hI%IgWdJQrMw;VKh(7;~VULoAIdo!b@a00+QlLu1D@g;(5cRXev zYB)-vj2VsFh}21SZV{7VOGJWUW z_3}p_EenLLP)+&Xo!?!@)+9^iaU*XLsPgBm3e~o%*|cEt0AEICzln2J?yCydwyM~@ z@YzeVyy+SJ#uUx_F#OTcbBf0F?Iiv6i?9TqYuHefl+;2XOgrju@a$L-I1qD|u;EHG zS`SDROi=W%t{Op!Yl}|WMEQu}>0r$P)TTShC*)YL3OJ!>kIZi4U*A+`A7O64l_DeA z!^YDT=okC}wDSG~QvF3ew(tSsAIZB=cUaZb<7zL!0@ zhzrn_i=MiqZ)eeo00W=mii8cM!m8+-u}e84_mXTh$c!?AsgO5~j&7{wh^%RnV-k*c z36qQmQqA5p5r$KBJNo1Al|6iuH4+p(qZNpXFyqSfkAHo0otpv4lZ+B?%0E5lG|oN<*W%h76bvn0o04 zgp$Hxd?iSss6h+vI7Zpo&`%I&Bcpw?as3Fy$NhWF|O;eqaD|xJ_%o&#ehw+R7H6ycI&%S+bSYBn8P8-{&cTeP| zW_kx_aJfN+OsoTPZ?GOb>467}?!Wh~%3#IRE_ZyfBeeJPTZd(J^7cLB=}i?B%lV5! zmKlC+u+_Kq$T?MrNgtotnFLc$(d?8ygj9u`SQ%n9xKgT7?mBwINRvpe(EzPE^>7A= zkT_oi;&hW329%J*Qjt;w*{?XN`m97GMjj%@NkWR?rJK@RjP!UIN_u)H%iHFPrIqI5 z`*XdWyqyF&COX4(xCJHBx!Zv2UwG%Mh2~dTAJ17*OFOycgUylZ4aE;!KW^N_X$u1N z5Xk5YmPRbg{N#pfuDS4>Tb^4J41GGPvnY;HK_eTz0jNa=a>;zsb$&N^kV3~~lvKxK zq6vvwhS&xqDAKHVMa8f}ksCT>y8#G%(7?nbM8u>+2PZW<%o<=I5t!82CFSO#d(UA5 zPBo5zc{ro3pz;p7_$55diCDg>ExW>yMdxv^tPYuVJC?uu=9{0c*=yUu4YSWX_Y?dW z&D!wR8?zr7f9j~Wx9@suWEY(xi$a2$OgeK*H@&4}m@@22kWtI zdgl)d7k;&5U1h|kEHeDpzO=HU)~xSXhn%IBw$Y{Mm2WOvx2rB})*o2^$<(p^yL19d z8m>}iH=1%X2V<&`A`$@}5`oq(e-TwH4OJNj2(YeBrPD+0qJm@qAeBnnYl`M=IS>kms&}t=^^#s*Cl8@jCJFCk zU8Yn{qTsUNxI`r51aM9|9G!`vyaqw%%@4doB12aJ>8(tcpfV`k;tC% zF}eET;zDmY4(42cmwd6%7E_*}{Atq1BOHLISwych7fC^LXi%{tNH8Z-o*gpu^A z4#nwR#u!@|8>En-#*HHkgsNf6M^>LiUiIJ>jcGAX>=c1=;Q?4h!f3%IH;Gj!A|%)` zQdN~F`dplIO`+;s4h7&st&VRiEk}%Ux>eQ`QpOgEZ+_z8f z3Ge<0Nt}1)>)(F|m4aWmijVV`BzYiUj48M7%9j%X-N9HLL0vLY_(nGtHVh<`e615_?DR_D*BP)VsVx%@iZT82#R#GI zoCBQnPBY^Ic!@iKLwyd!5GsHDszI2hbAjm54rX&{1?#rx5swrlGS&@+Av0%M=~;c-uLCUjW3NqIkU@|lRl1^ z!S%C7U-*q>*Y0|e@pvN9Z1;R+_9-XbHQvu*+cBtYo+ zq-MZtO(7_4-nl~6MaNpAMue@5k@PLWI2BEe0)F1Yhul;=XE3dq>Xqy?@H*eC= zGhSX_8?O1`RqK^DZ*GiO)f=84#z`-wtd_yBVK_4lYOv9IbUI|^tl2{XCaSt8*ex!_Klh+W=NW>ZJlngZh20Zm-%^#R)t0A~cX=tyBoUV6BZ-QdH5>HTg3RG<` zI=6A;Lze3_RJ(@ex~izJJw_WqK{K_Kvw7(ZhDp%{5ssdnx{et4>efo6tgS27Z$ruo zzwuo>?T4U=5<61!{vGFZ&&(Qn`9yxkT3BwBQNMvM2q-iKG+~#vB810^s?(1`N@q*>c%;l{={l}Y2mV9w5@{;}+ zKljx)C|S0A>F4(h?~d7#cf@TkE;5%VFI&F+%NK7OinTRo0YHaD%|aO)crVV*Azp2R z6mfvjX{u1+hEZ_LHq@)O<}^qWQi&TJ8$q)OLBuXq@W2QxQWtmKCc>abU)7N;Rm!>< zyW2gFKse#2_qk*9NB75Cpn`=DcI|ccHCJBPk7{j~;q5Zutjn&w_PXn?y>84Ix#O-L zGX%k^bFVWm&o{68-L=={U6$iRb_cQbA2kkb__=D-fGlU^K!qxa3X`k^NxUQ%z~=@D zFhN|JTWKRa0606G&w(fRrb~q~+GP6s4jMQRe|@w31N!yNX5{YV?=!$0 zlr(Tq|K2{d0<`$f-3FkMHOMotpTBdhj*-kHfkbs8PnFnM2yjVJrX;3I9ck2nqxl(q zMdrxvNUc-VL}3EJoMeVw#BszJh=NSQp&a89Q>EuIsynMAZgRsR#hw2F9G2a2D`B}4 zCnN4t2S;!jkdkT)=@!p2lU8@4_Hn% z!9kf&;zXe2tDPpgl(JgscPVTb+huJ5lAr`=){%_HPwWMW=urZe;vgQ$Gl_;XiA0eH z+SXG90>r>DK~5nTclJUm2DR`0qPuf-|SGZJ9|V3=525~Cwy z^di|&GAL1H9c@_dCT>o|6FHFwm9`tG9cm@9ab&Cipdg4K9}XEjM1d886Vj$L<66cC zoLy1tD2f8*gC-wcPE$H`Py)XskE;i?Am%cFueqn7Vu(soX7SAycq&UV@Y4NH2{#05 z3}+svJt!eG6o}NFnmLiEvQ;uASwn@`i>#26P3lu8eULEVQ&~*b@oxqE z$e&&~S_03F42f!#^-O2tp|ei)Y!w&KIVup@Bm$U#rVohl8iqI*mQtmQ>3k$l3lZwX zGD#nvyznCpg=9(r@Cj6n2Y9rN+BK^I$FUBw;&_!vwoT7o*G zx_GoGHj@>0rqRX9w7T%l!j%VeF8v!H>=UAYKQ5bBMDD4GX zTj{L;lnAp+yxuAqVYj0J%81q`0YZpkMq{f>Dha?9Px>bWTjU_KO9U;*QgTCeSSV}3 zTK2;i(Eau|mAuHf!Z^;zGX@%G8W$Ls8fRf!%1Oq3#$T|}Az=1nF4EjN`shTC>FZz`EQqj^)w=x@$^rjpH@N;YpQ*}SP_^QMw^bYoj=u;Fa_*}SQw(Y&c- z^QMxGHpcvS+*A^C;Yz!CQ_1E{C7U;uY~EDTFpeG5ys4z^Yzx}FsU%;X6ixV=HgKK|=H@Lt=05l3?meQNw0dQIkUP=o*f zwZvbA^Y~GrX~y(r(-NmXeE%J{-G1*B6Sn~z!D*i9)28wAk@)-Xo_PB`57uePc2rhP zODMW)QXzJRtiat)9M#jX4`gA?#QW=UvtpVtHU8MxE?rLMS{izLJbc-{uBRE3N zQQantt8g1nTQsc3rGK|36^)k9r)nI1WhbHMsf-2jQ%h64tRDq3-vR$e=g2 z=djbQGvh{%=t+7Kx^^3U=4m-S_6YI2(9Xg^%65A9;(McWx5P_Wr0FN6CFG6k)4Ll% zB>nmJN1lA@$?22N2znE`54!fr2X8r*oRc_`vQj&kUQ!aku^PvI9Fzkwm3!IrM;s~@ z(isN$vnRjzwN)Cs=$)|JYnl%)gx^r8ja!Ynqjy%1!ddj0!m&4!!4M!gB}JG`Xt2OPDytHzlJA=G(eI(cne zY{o&dt3<3}Z;K1w+{o>}eq8ruJ^>bdfS-)tT<47)dc_@~8J_9a_Us(?dU}t&drEjl z{DZfj33XB{1VK^>yUM%OH53*t#X)W;GOCc)MJ~x*$lD%5>e8*xpdmvhe8;V}RxkZx z&KPzxqsZ&Q{AEvl5!%sedvWf`UAuTYckP|~SKVUkt2+kt=+fEi?b`k1Q$j=H2A|x$ zYv-NhjWQ%LV``uKbak zNo{;Iw{KRzF;6d+&7>ATeOZ5B7+R)ZSzZd9tkUx~;n*Pev;opVfw(@I(5F{+&l_e5 z4Lih!ROLZ$Tqp0q(N~!_pHO&DvFzYDAjt4H+`#FCSymq>XQ0c-mv!G^y+z zYhLn)vT4$cp_!d&qAHd>xGKXz-T5WT+BU+ULVrG|9~^! z;vPkxobBtp%ew-YXc{g(#Lf_+p@c5ZJ33XJP~z>(-#z4gQ)w=F;C%cDqBAHNp*o7d zV!Yn&gKl{7-SF30pT4ye+XGGWP559dwg;O1(2e=|x6k+t+XI1?i)4GCPj4E3-Nm^R zo?nOUfzI)Drfg}f)Q2kvmQfZok7YROyi_8*R)Sf=mDsLm(S5l!Q4a}w6FX<-T=w#= z8vJ}Yt7gk?{KR=$*K1#0!(Dm4dvDI1&)4q5t~?;&Jl&ON?wmKK6^uN0?#^9v&+OWn z)=`Z>#GtSe*Yq0-!jh67aTW2dmv6R%Umu!|{@n-O^yZ4_b~u&X4rf}IoGV^jCEMX_ z+O(q_Z~Gx70}Ec+jO}nXZ~AfBN6$Sx^`YCx^yvb{P~>Et;-G?fPjT@0&dZp)jz+6A zSl$$f-Vp~3IV_>wao@1_n3K-%m=wRIt%|O3X3bl-pLgDcW2VZcFw;7DyAHVY@5{<$Q}^WtS+l(uGw8Q)_|jxXPM?bUY|Z^f1z^Y0ij>J_{}zV?ULtyh!h$d(*0 zoSG@bsLen+TLHcvM&ufWOCt?tm*|fJ2y1tHC6$eMU8f^u49d|skd)o;mVD=?>5FAAjXyOk5fQBiU-IT>CMGU zzMOzGZQz&}zAg=ao3iwad;i?q+o^Nc(Flh5wj1yldy(qyxz=a{?WLe!!Xc z%xoeWY3jU{yr3zo2O+D{!Kv@)E3dm?P>c7@G^+eOPQ== ztP*-iAFUMH04WZBU!VSi`(|a*vMm@vm#)1}8Q3=)IZIZLe&JJE_xJZ2G^n4SAt|$G zzd_+sVh5hw4S7(Pu002ZaMPnJ!%w*~M~84yDblf8OC8Q5m}!7_p;1IZ!w3l(A#Vf& zh}Ai!i?D*(N@v4ckLw!b4Z+T_;FtDIUvq~P+BaoPx~nB|-iRxW*9?@TiaKY`%A?%N z^xetj*oh5DB=c(usuIR3WU<#Skku=j)sz=YJ`-!>RfHzRVnU%vm*b$gYgwUsk76PS zN`(`^UftHoonT=H`bZ5sQDI_6V!%6;j!j;6ri0U}e?;DGU}mO7Qwl7l%@aIkmXK?O z_#4}B_}Zpm+(|E+!z1uby1#YQPh+uUWLYHj?8=ZD1ONgea2^yXv#ZULa8L|eymlX> z`~EB=dovCT#|9jGahO>#S=m40B7$Q#j<6K6!pIKcVEOi}HTXV|^>6UI*r$yp#`c)D zF|A^bh>4A96O$a%9-kB`IWp!b`5b||4l&2a93AtgnBT>u;e32dV$2`Vre#cgOakhX z(Z5aX@xT7>VvkRnRKC`;W>slPV1DeoA1p3ko4DqOr6uov^wo;$wVsvBzIYeqB@4eR zUu&$4U;5d5A1z#7wKjJ77as-Yd*1(Y`Kt1@3CkCJF#q#!SEBivuit0$PnNGfu-5p> zo*(o6QZ!z@{1Y^O_kFy3aILXA_7BN34q$RvSr%9kyJq8lyc5f+cYinI3IDJBF7|l- zYBQ#W7}sq&&=g~&Zugo4D?BSV@2|%jvl_i?E4Fsuroal%I=rs5;XPZ`c)jKRO=|-y zVm8-DUvE`u$JB2|)3uxSTNQlYli>5zZC}5td`0ZWoz+b+##xcT22^-fZm$j{D1hnSQu5nj>kJQx2|7R zyCQz&s*T$#4tlv)xOVsY)io>PR;}4~fVzvmgR9bxtAof^p>EB_y>*cW{wwWxv;3zG zt5(*c+xnks%>AwiD(pD3<|hZ&hM&q!dCwQ*|C{(-ETpl|Zf}Mvc5L3TcJ;~?D^{*v zyJ5?&$_QS`7PSW$b*N^~=8fxCnJW@ju32BU{XiXFVixs)3N)?V|5MreH7n6z^}4bx z`)b1bqHjNAb+~*d5UjFRB&}S%ZsV4ncsX*T*PtExcd?*vFV=!V;LgqKR%w~)kwa?3b(MiVsN7$HDfyl#G5_lCVqrr6;?oxp9__I+ z_+NR7^snRiZ}q@a;JQ8AHvO8viv^v)y63BTuT{U|ne)+lxMkGd5w)zy>RFYq#D2VL zAN)URObm?Mzo>l0^TzjqU}NX^gtjc1SM`eLwU75Sd8^=orSo40{5L*aRqwhzu&$nV z?fKQ`dak_veZ2Iq5!SfK|Kjgr!SDh2f*DzG&hhcpM*LBI9)+vWH=|=JqGDa(0lca* zZqQ%8j#vi;ek-!}%`@=M$o97_-fg1NeYs&3%suex)Qt++_( zXYIoH~m?}4UL1~f|u30|yoMT(YRN&pGtuz0&w>pGZqc)gFy`5x5>Z@NFdSc7? zN+T&I@yK2`ep3^|`%zt4)!`+k_50Qr9FbgZB*wMwUNC!SJzw0Z0>i60gMr0Q3~n6< z3KCNreiy6cg*JcwY~G*Z`TkT-!fDgzuM9LIkGR8u@BVRh@78g6folBkZ(FcpN8Lfx z1p{S^@Ay+{Tx$?aEu?d5V=6t_L-k~b=#aDlD-`M``@fO{V1BQf$dU6JKZh^Pcc0T{M=hrkLG{vl0 z_4HN!kHbrD6WU}3hkE*F{T?s3k54)E?td%-PmKkdQn7B{{ipGLxSkFt^$iY9$v!3p z*R3Zeb33Ji=I%4Tf#Ef1#(7_}r`3t) z{(WV2$co=TV?@`Z6CvBHHdi;&jPv&C__oJ&omf^2GQ$Txy|h!4-^E7RNj8i&ozJ*+ zUR9WHsjmHY`lUU7cj&i-$NlNdTV{TbmuVkZ^X6SSDX^wPzf3!B@TBLz+>O^yuYGIE z*oHTvCR$ZlP`Vd4DQvmY3herU#G z&w8gUXt&<|#k@CW&mPkrYCfcM6o;;-%Mv_#s^SNPz2lelM#4lK0Qb~R`UnhRSmq9ye!~9$R z+rNuFm>bhh2-j@=^p-yDLWbv1uW%%=pqmI4OVWs?#!&OSI^k*S~GzVSK$EeLb}Ms|U~R(g87{_3=Y~o!`X@f6fmg zP8#<{d8qFBA;+0UN{pxH^yzs$Jck@^63%*OLpb>3MW)d@Ce{--cGcuRwmA%ciOExH z>JNPXc&2G2#CZOgGxeR*ej%E*jz%*xxayhz`R`(dJLgxGCyje~^q-{)$Gfrau)m9y-8Y_edCWOu~>mURm(&gPjh=V8=@y|Llbevsy8oZ`b-JO&Iv&(7WDQUmN+S4740}`-_VM|D1t8-TL~%O`*dxK-$`# z{@jM<(I3Jm#|@oy*W`Qt zwyw^M9MZBhsfcaU>GH{wA9%FnzyG_~#@rk=@cO^Mzi8FAO4ClkgQIP4kMDKpTq((a z(-U(SEZ>4>33f`jX747+l{y@1-j|ec(MxZCj0c`zDz0Yl`uG3*3q!4P<>}CK@>?Ze zfB#cBV#h}UYu>u$Pd^)ITWcoKuJ5>K-~DREmh#9i{4TaJYwfySc>nvmtLou8DQ5lp zS%t&W4m~+f@?LV!E8kUPjTfz}wtV)t(W%Jy4>=1=j6Z$K>tAiHjbM(q<@1;B^dFM5 z*fw3Rd4A!ha{Nb?9bdcT`H3UBKG$@0$lT$7g z$Mk(QXvc4wH@2k*Bk-YS>R8eAq>h}r8mnFJj?0dZ{RIU%i+8~8o3gYLt6jS%{IRts z=4a|@rG|&;LHtFlYoN!3(7w0(#uIz2s~ue?E`M?Ca4%BJ*zEDQh9`L@6r7H=v$*5> zUpV=jrYozFip7(Ldyhb3+46U11Sff}IXBaTmDMEwrA6=UZn}t)vVYm%#&&OkrU@sU za#e6r%IK^km`WTwbkh4jh8izM#;thn=F|QNMmr21b8~1?Ni;6ANTQG6s_nQ>3r;;L6%V4~j_G;H<3Bb$h{EHO`n`|kbUqSKu;SbNSAQ3)Bt@!r zteAPq@8UpGyUbg@`Vs%x+Mvj4tYqz6^~H6GAjzNq_wV;0Y~Pp&R+@_e$oiR9_$&a_I}@jUG_`+P{m14#4oQ{<~P9jXn?G#pmJCq+?0+ z@x@|SSg01wH0=>Jf`6|bh{XR9eEdv<|5P8p2Iv1NIR16%{_8z{4O#svRK=eanr_Uf z!cm7~$Ml3L58O5Jj{6=laaV&QJl!*6`t%tQJ+W==bYp7r1NTh4^WLIqsBs!tsHvMC zJ7f9`UWMd}tn&K8acu6YhS_okF-oryY6YP(c4h{ZQ=V^XChFHNV=(=L@Q;(1~t zT;S6#m};Wb27&|@prjt4YXl9Ug>V(bQAIGR5xFxJ9ceIAlbmh@E{I90nQFC*>vrM^ zX(xoztP_H1#tBwhEbc71GES&YvvF;oV4~J$O`3T^BrOgt(okaHh)F|b0t!%aLKxj5 zILtH;ORO{&nCy2#tpf$^Ev+@(hKi0&Lukaa5CPy3LCgDifB-~O=rN=b`;*RyKn6lm zqE!~i1fmczD~+)O`}Z(?FC1m-0S-z~SdY^}<2_R{e4A6w;;Via+ z=xv|M&LvKXNn|7H#8lnj(#i^}(D3i;xG@B*v{Ph?K}2Gbap_DJEMgGZQZM#^6MBfU zQFiiaXP$k|*`r4GWos7td*+;T#;JX9MN42e3fpc_WUUCrRT}yPL7@RQA}VVjQ_=yD z#ip8*z^4GLtkxvVxhGP!3R((2REHRbMZ;i29#k|9*`&bPP8vJs5USMjXa=^36)jb$ z%DU-mC5@#cA-Kv^+lBt)VIgQ@!i+}UHSOtVo__Q%XPLg%#M67|^-oVJJYBny4m2m3 zW>%t02w6}}VGz)WW#NcKwNOR~4~j6dgk4v-6t!A7&CF5`>eO4&z8;nF+CL&HVH@}Z zsv@95OgW+jxMd~P?D~4t$w_)rRDAWmmeFf~0^I{r9kUoP`Y-PCh2V2JCu)gG1fo7q`6yD_7j0L-#t!J;lNE8J zrhHz7tpO4u+b5C>D0k#dA7Oid32YZe3$;4e;1stj9QA;R#Kn;C=_m^Q2;FtEuo!3q zbHb0rMu%M#NTj13N9CL)rW9uABV+tfY-kv97y*r9rlj1LMM@zch8zvTmM9cOCPSm5 z7Z8r`q0Fa(fYWAO@)q_q2<+IrZsB!8e21(vZu$uO8Wd_*Ha_j@yRFBp$J;*k==FWG z6=1)s?w$JB;8LE0R!ZGbv8sp2#I?@FZg(cOXj+C8<;WfKg z{~;qrO#HsutomuqHw)jo!tJ3lnIK>=s``9mpZSuTF1&fcpl;b&+1>hG_=n%^x7~OpBNt?hI1bSCTRj7lBz?>>G>!bnwd-S^a zzSlqgczGatv{zP-A$QMRwZAG{n^Li7 z(eqdK?&ixHa@8a6gg%a&`$*p4?2s=-FaU}`BK_nLfmd0#K#X`E7@%2GZj4b4(L^i& zwPHf#kOoNMIvEeDM06Ztq?(}+g_N7x2ZM`af;3Kz^|s_KQTA;PTJ$~=kN{cqy=gY~ zf;ht5al1pQ4^acYB2mN4>f+0~`h`!{tj0%nrub~asH{`3oxi6(T(M)_>eZX~)L>_d zCoUM!WAIhaF2T+eEi0EiJ9e;Nq#zU!lMVs&c=99aCwUTKz@{ZJSl)$2&1s* z1x-0p=-}xlO%O-a_8@jO5{`FHE@!KI3a>|_H$MDo{D=FH3S2@_0^H@~n`dvq|16t3 zArCrUl8U2{hHLpcXXRXQP2q$Ig_G`^z1PO36_fopzqLMOR{ZeheG>|w_^=FnWGtPT zJMgNRt1C?W|6ioyhneI0D`KFwK#~l1a;*_rl2|1S2pIYF(C9&Ji%lrA41Q#!!9yrW zCl8^3RSKeGy{vbHr0KOY)(S7Cnh}VS9FV=)C@A)6WOW!gphwRO@A~`v`HQ(d$I36} z&wJ@of#1?~6vk5-Dt%e~Prvj!>)O5rw?6h6_vx6?eezd3&APH#lg=4F{K^MDtqO%U z&bjoACzo=cj`!xzf9IpkA@jgDkDuzqUNEKPGAWUPLGxGMFaYWRM8TLad!89^G(>9> zuFmD;o%90=1>$zN1X#MAq}%Ez5QSK2eM8h?Dj-ppF&&`^Q~?u$l3vm>+rvb%dh{N6 z%HUhEf6em8#^FB~d(h}wM1zO2g6_jEo-oCF*q(C2!w=5Kt|5@g!kwYL3n!kAjc5j+ z`z)T9K_-_j;jSUGM_8w{IQMPt8uICAzmASHexZ<(VYF~34k$H!N1;;bVl({+!OZt0 ztP%=kBRn&IX9BE|gJO+_UJfDn=%1Xmz;UCnI*5!#L5M@->gFHlRLlB!7>m!BZFOst zUs`D{edwZY*%(7e59T{gK*5a(>+du4=9k`I99h(T!CY=j-FIjM&UkKEYPKiiR@li`a!)V47-W@X6syynye%9KMS-PsJPuj9h)#@A0vWmZ=2oLlFt#0D?*m6cW1)w03Mqgkisy|lVKQnP>CX8bI!HeyjOIXAr~8@z1Z zw7lenN2X7?>x%xGLaAmfcQ!%AN+t&A^3gAuxC%W^DAfU4GZ4s&!*Ey)f=0yPLR%we zZZ5*o#v_zSSpn$K6>+BYV2HSv&Xci!QqC zsu^plO^C(k>o#QUKbHS!Zcp93{=3CHXers<2j$-I$a`DMt#Crk-j%bi9MDb7oklBW zBGyaC0PPz2S>nV%Auz&75fz@;fCeGBkFd)jn+8J_H=20Mm|U;iGQHINj{z&Xj0KUX zKqwTdf|)ZvdNPqif&>q}N0x}xd(L+_pnW7b6P<{!W7cUm%)<^l?-Y*A@@4lNJ9{m5 z*m;yfA5ie<^XAKceBs&GKiEW>^uOeq>#n-&_7^`{yPaF?tbX?D0m>hh;Mghfapdqd zFce0S4k01}QmYYJB8iL-(gC%uh3gg4b!A6osEstuak3LxM_|OF{g41BT!}>}8R~_O zQ^GVG=8l{O_Ar@IsvBLvN{ed|HI7TCl9{8DjSVCwk&!I8MIOjBAU&~ghgYGbY$ev zxs*2NeRL_#0j%SFBm08~MX|czCDK8FDnugVgv^<%*J@mfE>|(uz_pIT;u`6u@l;{N zK3}eJ&ne2tn@VI}M0IDKRxp>FA!q*{nfcW6y*f1+h#O09asphc<2|?Jk3bovFOe9+}zF2eIndLmDT!gA+Q^ zI3amQE)>h4tbwDS;=W9qK7H-AS#!RYeVJzXe1jfav9EmH!a1+M_WshJurJfQcl|l{ zHSWu_qWHDfUY}bQv8p$|I5Hb@Zbo7fux$roU|5O02}u z92ry_VAQ5el`ri0Kf6BO!NYkCj?? zS%K^&^%`9G!G>VOHqA&%s4ggm;~O|_d7~YomOnCjz=*r&Z>zJcNTdb)YV-WNa){p5 zB_}~J0T#G{#~nBtLbi^-vNYp#r7+b#T*h^VKrKsJuhoo~x(qEMpv>Hi2*F#+^aQv9 zn)-n*=&2MJbwUhmbTmdQLdfzta^a`S**(si|1dZy&;Ohg>ya+f7kl6SKj(&>B33KZm`$k zqGjRlQoi}}fiwC6Mz@i7zPu##UHn(C+;O@;TOF7x2d$coP&aNkq$I=&Kn|UbAt|g< zLkUSDowBSh*Y3UPJHn~dlS>|&QvI+3&bf(+GqOlSa)X8%l1U3|Kvu{}A+V-@1mX)n z11`F{;NqO#A`_6n6sqUI3vRgP@*H=uGuuD({Ja}(xbemtZp=I9qVd<|od$38_a8m( z`WtSvZfJeuwO9SQ2bUFmy@sB59ZC|=@S4#%z1-ASb*0|HYyxye7iHXWSJZ3!>h;-< z5au%H%mbO>N&Z9eY4p%lP}0n(>x}wt!ptJ1-;fIp!Ckf{atDWq)AF@(ITy+xb+|?55*a>5} zvNUN>29eQ8rc7^*#Zoqvk(~|vG`x7EZ`s)n8{!3M!4Ew^f|wHuqwCJ%J-UwOMq8(e zJBsUIpqgi((J<(&^?@edyLlLctuxng_;%M3bVfjf5rd=y3f~|~hij=3A}zH(dL|zk zN1QBxl8SN`k{M}OhKhzXz%gG)PIMZ5dP#k7bve#`=@rnJV!f99Ig>$(g+o@7DndOLY&^hg9tH>qYMB` zLP8Sc!0Ii}0)*Nnxui+8s0*yJpv5#oEuXwN>jCJgw(bsVG$&|L0Fn+`w8T3^3kB@B zHQPi~6tWtP9?+MwB&pEU?bIK1fey5b@Mw~f-f+G^qvzQP5q`asM8 z4=h94t1&XR$P8Y)sdHk+(a=e;0tQ8*&aCR?sHXq$!8H?T-OQ>J$R?-~t_jUqETA2! ze^`=|DmwX&{-1?dh4bWy$^sEOY)fD#MJ&)2I?d&&IF^F0RP7*l{6Zlk3uI3!;K%sj zg2}0HKA;7MSk~fOol_k_EzYs6HiW}Jw2}*VKIN)is&pAxI27tc^E60mhD!tD5;Al( zdWsVk0wtWe7T|;<5*eg3aRNhIQ?b)F7!{(1qp7@_G;ZiNrPn2~vx)=`{ z_ZxQ`_ZYX}e4lZIakTM!<5;7k(FUKVj7N>B#tfs#c+7YL(ApXujN^>o8ONi=AY%xQ z0Y+bAm@yP>TjTh>(cL&1C3hN=jk}CVfcr46ZZ%pNDMm~DRxr;Fq!t-_3|to3w!h4X zEwoGDl7iUOqQZ?vY>7RS_p6QAGCPk~os44JE;Wq8fF1DjGS$c}we7+Z+b&5p{5a(r zMy_qA8YL0iD4L5dNk$QhQ;ouzmVH7g`s5k8MFF%2&SJxl%Ob$D%kWiV2a1aP>|~Rc zfMq24ZB_^DLhPy$uxA=Z5sMSc>_Wo;b@%_K+YhAR1PFFkSy2k0F*>=7qm1U)DbbU=mD7NgFGQ5)@HrFVzY$HJZB^#+lMF5&x1VOaSD=JC_yt2ZgqTH}y z7bO)MX}APVtH?-Y`vYPFPvNTE@T5UiybK#2NT@Jk#H3;;0V9BY0Mej3JFwS?&9MtN zp-&k%x|#{23K=$9)Sy?0D)mQ<*wmVD0lpBws!uJ05CX;0EpL+%Qv%lQ;#wmnP|O~- zk(g`ysq)nQMnWNe)R1Zyerv=O1!{>XCu}5?78@um($=Uz|I&RZE}<3r(YBP}itMnF zh`ub$Wm_ZFwA&S>+Qp?%Mrx^z<~e1MgNd^Vffd=1U!i3ulR!TVyexp-e*9u}V7(+K zVx-8K>MQdbxe!CHWyH;dM;W*-LiZwUW|dlG!=-ZYTUKe7(-H<)3OXRJ($rexC^AH2 zC`m1(ot3~21BFIuNyIqHPfsdF0YCtW-|z=YQ`79?u#p6h@Y^|Q0g&5PFO1?ce;OUj z_CqLzuy-R+6sDvsqjgCjFEs!Toi-^sc4?knm|9kvnrElgA;yT1*~#e$s!GyA#!>Dq zbP6)y4JE3A2!0$1>T>Ow&?&wxBRSX3$;k_(p;gF8Ak}C9{H4XfAD{ylp}96e4?hG_ z6iCf2Dup7^$1+mc$LR-O3_v`PL9uvXE<^w;fU2P|QDMYL658krVWTxq5RqLv6MUBz zg94%yW9uLSCbc}=HjoQ`h>R_%iVJH%Kq*|Sg+nD}fL|=<*?GWE>ms6=$i4|EjeXiEMaaLye@ENmM; zqb&^hb4rSTpxm~jd>6w`Ag{uR%fTozbEVcTA;0YS$B-hu|XEiFFK#NkcjM7Xd-6$mM>gdF1wgh2d` zSA$=UK*#2l*(H#^xV**{BMns$1SJC7cOyzi2|Yi9=OBvlJ7FaS!p{MOLdek%ei{Nm z#5iLn^@{^uod&Cg`pa@KNT;y?Zth2H%LR>aQ~H+^10={8#U<#O>ZkLR!LUkk3DfyK zqtMTwDH_NU0ty=~b7Q)?lkB~6%K!y{Q77M5+#j2OqjC8bm(L@Ckb z(87-b_y1X$q2ei06-hq30so^x1W8NSp2w1J4E<3^zqKQu%Y zm!)FdPPNNYjp9N!%nOu(AjU9NLL+Dn8V~FV0U?F;N;D*t41Cd0a!hKmU4jUdL-C|C z(JMuSC`B}bksw|$Fkw*5z&QYYXvAS5f--L?H@ghhj}x4-Gz~m5p#2P-gC{=630EmZ zCK4buTNxz^=gW6B0t@cJ0`Bq6`)v>?QmMRmoilR@CmX6XJO~EZtsn`xF-L6M{~l^J z>#2Zc1hA(-A%tcW7tcpUqvVFQ#Z|~q;Fge7j#k6A=@k`1OqCPci|l#m%k(9|Nnem> zF{*@(wz)R)?3t86nrMPaU#V%gLav1XZ3Oh%Ml!;!V|SL(j=gD@kZT&F2D*I;5_H&4bcTKS zS)XP@uUvrQb?JSut$P5Beo9C|n3A?V1jqVtWxI9>X<^ z5GfCmJ{dLHA007|VQ^tcgfYXI1jxE*PAXHLbw)xF&7-vVZD82I=}rkEvR%YH{2Les z)X9x?XyKSy!1i-DNljcDq8$w0gXvchYM|}3{oofdjdK74jKnaRjScYIK=OtdM9L!OTk*jr#f?@Qov7{y9Kc}q_4kOl*IS)p`Ab9Bw2&0!Xjh8;^NJX%vg z<_H{tk++x}c_C8FRdQ^94VZ<8!6#9Wh$NUfcYx%WOjclUzz_AJ91$A0F-|5Rufntf zc3}rnke(xIi^JQ9sO*~vhJZ8xDn0B`Z@>crzzzWj_A(m-OH5u_wQ*!B=9y(k&m}?> zl>!&inY zDAnl_GUAZ}BfAogAq5YtsSJe7tcEDs1vuvMfP+C+IFLSfga8o-kvJm?75R-o0BLj? z03*&bthOnn10Y2b<1D5jQ}Qs)GFUpubb287WAvD5V-^DafkaL{p~jf9!fGrNppP7g z5uzzFjHwwm2#F(2u&vmcoW&%=NFhD8MFz`3A(b+NAb}`sv=U9H0SFJYk10hqU=(An z4<*DFGi&yM3f`pIImFB!JaSdN7}{ly!v2r~JcHJYEVKmHhdCOMp*3)mHiI7^nf?#mQfvk zCWpFYfK;h9XpnIkCY>56OATU;hf0LmV|s_+4I768BOf*VmK~4FQa=pZQvwEXDorzr z!G>QNv zw+NcCiVzJ8nINPV1;d7-i1~AVza*Wf3jwH)43v^-3EGRRq z0!CoStze^bz1le&XlEOB1%@0ET${KK6>tU1Fd|Ml>se>v&^lfdhn`u^`-ZcwPPt`l zr-$Ox@}_OHj4%y>qwU#-eHz1duU(v6L}H(&^eAn=)JAEj7nm+=g+YGFLnZ2zXUeUC zW|d7CZL};Ray@{1U0*Wg90t7+$f@247wkpdCLE*<_E^Ali)YpcakdTHX=9^}T~Lcd zmx5H5`_YCpeJgcV0R|G0wYJed`^ zh19ZzKBP9rC0+LiHAt9Co#~KCbs>D;ktf$eCID#^9@XT^0hD4EAMQ<3@1$7Qo z?MFH)HH$M za%iEJJ$SF&vZu;kvC%BDSu^l7@fO-WET?MhgM7ZDwlHF7b6sNEaz18t{5455ass`-S0*%cBE-c@=% zTIjWhN(mPv^Q3>_0x47br%v2%32cCa_o{8m&;r@OHFc2xB8ny!Od>lGOZ@AtDXz$`+>}DvcbPi(F z$+!g{VsKDl=|o#q#PTXBCp^y2)rcxkrsZ}4=iVCM!%(#HL5?}vk*81rr^b|u8(ds< zx{}p8g-j_s{?O1(1?cESy~!$Y4UpIC_|24(zMis+_vi+GMGN; zwOycd;h>}n-=IAQ-#s{V>f3O?A9SiQsbO;DWjNi8gJ#GygW_XK@Xy+jhX8P>AM%b) zP$MY-O;fR|U^P^dtHvhb#(bs%^#?(+VYWd)(O^q{2uU4)Mim5J*YFuRC?np75h*A? zmazxDpA$>hm(_Au(-6A|uOZSjxTCfue}t#H)zOaq55}SNX&==uakzM0`m~-n*q-fZ zBZ^bY$VV7Q1AJap3pXwf7rqO}!U)P%EN>iY*uE)j6K2dLP1~}b`mSmM-E~<~p%@Q9 znmVL4g%*N*RT9LkRI!KN5tmBM4P~^JD!?RM4P6qlpj~ZO3u-7SwqYw;h6}@$IL87y zDTiAV_^EN8BWUSLn-mb23(L*QIN8!juXC+%fzGqcg5U5YE8m%9<(C;&zB9?n-{@Rp zk|kx(Sw1FN`3SQ(BDgkj4&^(OET`P9vrw;f&{RI;hPh|sJMmxff zhzt?^@|{VRoH01&Bg*7sl9i81R{ka&)d!PX!dV%BzqM}9E;=gOtRn+6a*$&P0BE_ z%9lx2zD%;B*J{Hmj9L&#Vep_0t6kH^-Ka*Bpxt8xaoVXsLTF7^)fmFStb%5wbJaqj zxT^F}DdGHNp7bxAFJ)@~jk_hV0S}4J@}1cd zpr|xmb-I$}nX1viYN_pq8+B7bJ9=@$t!tQWFIT=g$!ZAGl%lJTB*%ReBf)Cu)k#+4 zK9)0BvjI?19pDs^O*jJY;SavC#5RIGC*S&ncRw>eOT9KWP#sR_AlF|iWy zJCiJd=}fXDRlp<*aLs&7vXB<=$z#JkCRwPXF{xp4pid`?z=-;)qM1 z))NQYvmI?jacUX)!1SgOd}5MGmh^G^@$ACEBum;8o@?4JJxyVoFk@;+akCBeEt9M$ zbk}7`g+e(1Y3h*H6j})KRY?%Da?KukM_ej3H#||tRe(vj8oH?AhOxdD)KF4v!&bBm z7ltcwjsl<7=W>TU4ZQBm zyCKktBMKxAB+Zko=1CT_R@znbBum^!UCVVJb+_h8mIj!{^ATs!p5Zm=fhm_i6$PEhJD7rFkUo!0@U- zYzQQA>?F@^d9Q5@6!TgNer2eEP*X|+0?`7228%Mbgn}4NAcV+a3Lpp~gEH6}&inqg z&OYbdYgv{O(uRZ;1@5M=0oZ>xzN!D5e{$cVFo*T}$zvlwn`)&T7 z9-abTc`cB>b1<{5g-`HzUHEwT2;jqy0|z__lh`)QWgpGozlSe|f8*az@w@?JgjGQQ z9$|l{h3#g1`)A<~F|~a)&`k_SHFXD>sRFUY(&`*J0ILV4os5_@3eZ&Wq$61KnOhr(Nh~3NGPi-@TxPh{ z=};DCS_T3joyS4C0x<_Hnw;}hQcJ>Vc*@LHmRK-vKTt3tsn6Ad&gK}c*=NMAGR#UvNp@!;rJ zvb0VygHYHcvkw5Sb%UQ77uxgjg5iliY zrBJrSZ794Q&7vK*FA@7@(8g5!2Y4L?B%BOWN$=+)Gc5+?4sd-rrY+;ie#``h%|c-t zh6fn;sUacTfN{)noy2QoACn{44B)%bxfIl z8YX1cM(s9_AY~X+SsJ@;qKsyQgB)RijBSCL;-p5!OR&PUn3g9N%Zik2+p9>j=1N9> zk=u8C&HS)L9vS`#xsj@e=3lH-_QDtJkvF9F$OSWF3bqY6{t6~Oev=sFbF*T6oxMKJ>ilwRy2Fxr`++U~ogOEL9 ztuBqYw%~$M5ZuR}$jo)ziplNguw%r$*G-p@LfIU-Asob}rq4UZ!N)J*--79L!SEOZ zVXUs*C^5B!VmbMoN7N^Vu9l8*13n9k9W=&E8`QMjMp1cBh1CU@`=D6`JT|qQA|Mq_ z6=AP&0tR|w8lMO|>B{hv56CflX{i7VG>)++tTcmZWHwqY50ck0(bmxk8?m<6Gm$J=PUZq&zzb%!FKa~;SUD zlcU+T=`?!Of^|3D6hKT4I+BEyYT@9rYnC zUC~-x;|V%$&MZhq=(^7_i%wi*3WOP#Ql^4qRKzoLxmPyfBN(kqzwVW$yp3)FlW=my zBz%xkjG$y?AubPW!XcuHP53r?if!10%S8M~_+U3l=HI0=8g2QEdd6+x>t>=!VD%9D z6#`-Zu8y7fv;u4jUqjx;?~pe-zzr`E!4ZtfrP@DjL`)LOj-7y@pD7SeWDKF%ns2?}(lyx{3w0zNLW1TylEFZS}f9& z4dRujRe`&sjS7bCOWo*v9TjE`$P7khMlEs?y6Mmo6}XfyK1Rkm^d0u%>S$zAZ*ix? z`bXY9zN zzS5je@`Ez09Z98#-BQ9vstrPp%CtGo8lGvWu0BRKwj>knbc?E5UEi8ykoIi`w-#k} z>`|bNV@_1eQG^tVN2BVrhGN6Ln2t*f|cCv=n%n_8#O$RK@_l~jhm zR&&&|jJFj#n#L>iE;@h{OnoZ>>nGI7IJ2;8lln$Z80%3>B z!_M+d&#TMlxDM0eG&Tf@aS*~JCc&(!a8lIbW+7=@F#BUNqYUv(5UiLf1M(7v*N(Tf zjW8=SUaGJ6T7Fb&+nn}4R5-JTbjabODRoekB<+lpdpOli>KPG^qg`l~j2W>AwR0;F zv#IcysP?79nJ<`5m-?p=vJy64N!v3ZO?CPP#*{M9OiiFEDCX9v6}OO9H$++-ZF4kv zX#ndIFp8-&=k`p6M@kTpC#6PjlpPZw*^PY(y%lOLxAq@Yd%BrUfS1t`y?lVGXBIK~ zUEWdf)(z`mq901x4}MG5qIhq+BYJbL3qyMI-Sus^+b52^Z%;?{ub-7y3;%!V z-V!G9;isbF8`+^O@yBKCN7h(#S>UFICj~}rnM`U^gx*qR!wsG>xb#~~B>(x}vW<%yv z<2gYZXZw$CiTpVn#2Vo$=}*_{)1f=6b7>NUIz3KE5hdbkU1~D%_>tISR5^m?IvpR9 zkJvcYB30GQgrz22Rk#|EPpTEIA<5)FRmdzKWU5%fLV}IA&Jf1IkId$Dd#wLEmv{A80l$KEO5SEV=G>EA5F^ZItF+gVpDZ2AO+8ezxxXqLeU4W=F z?FH+j-m-q1#Qjhq#fAi_B9%WLBZ6ksDIv(>avJ#PXv_6sb<_Z+4{G@UQDxS7L7rVY zdQEkJHTXD!97fgA6QOk&9%v~G6=TN=X?!*1XE(4)huu3XUraoh0wvo>XoN11t zM>=f#u--U(VT=~~PMxeU%*_77Zka6mV_6KJ$={PXrB8oP{VF~55k=lUtuN){vKdm>AgFAtl;E3jVv!*HJa z-5BmK`6}c6C0||i=eNUjiLE(v`!-K767~)`Jy-%JTSODTjq`T0A@6?12sx1=R5 zAbU1`Ly9%jbU*1P}otu&mLm~Z}^v3#PhsJzE0V6VuYqFTAAB#ISt z5p~5_2|oKR6nk%0);v$e^b`~;_jT&0N{ZpJJP*$+#!53jUdV=ay;CFSC&X-#a#!eT879aAN+dlp_L(^{6o zc`b=Tt$!s}11x?S-JnlOK>Q0~6;4ZD3YV0?{aLuL@x)A^q_wWZ`03&9NjWnGU8-Bj z?IiEw{S=f*R>fVHXFXk>50Hkt%I97}D7NzttUBKwLb;2>lATE_X_PwgApTUwJnhNS zl2C&4UP4fT#P_h`YK-Gg_lu>C;bNFP{3P@$RhNZ46%b~|C&h3oonJAg>Ial#14SO+ zOOjBkP!g>wgU61kMS4^d(XSaQh>-GP#!}W2l4$c(6iZx>H6K%pDL8FjJK~z$Rhyzf zejeY`YNV~0gWiku&Xi`SO&o~vJO{M~#a(7)$+;nlKi?Ss~dn}*x z)5{Sli+oWSkCoTgeYh!Hj32`|b;?QFRC4ItS6cF0DykJtLg56(>W;~YIA^RUu7sR0 zXN6}PGmNqIeP61I0VGgF5vwMqob;`Rp>(AnM3@?mR6-~@slh@=#h!N*-VoK)v6nC< zK@%_eI?PN7dkLESjD7!<^stvGVJ}hgMVFbj z$z+L<0b%v?@S<2XEAjH~G57JvN=Rq0zC}~3|Z-vmnOWNa19rPMtc*{gew~%+zaDkzD{|;!+d}BLb&W&6|%Z z)vT11ON3O9-X#TILF)Nq82Km{DJ8K&-wNg91f?RyrO<=;`-I+~AHdJ&@~-oLNYTGV zEWRG8^FDrgbrqxO-J0xmyf`bp zoy#Ma)4X|RosoOTv|RKfsZxomjlBMqR17P>`s_Sh)BsL~+!RMe^_HvnY5)qiA}Tp) zT-RP6+`V(Kf}|-iSChqN zUaX7h(sD(L!zcF=`yzWH?J1|Da){osm?Fu?BiAEY8UagkJaQC|*pA%KTZ4B|YD-GV z>&U}l!vQmAN}ATr&_!xe>(6(R@_+Jtww%sq%jta9p3G;V{HFLR{DCYi{fD_LjTqL$%vjob_n*EM)@h0P=Fb_+C;E!Y zdyE43Z%xo6n{+@6YI08JN!+waUxObU)9Tayp;2nqfX`lq&~jn)n~!d5?ur zPRwV?eHu5X0y!s5FOU4w`D{6z&z95qEP2nAna`G)&z8T(Pu#NkY?_OwX7gDK%X}6( zrpnA`Exbx*^I3BDS`vjepS3bEpEbIf&z70b7Q!l=&1VUhl$p<3IOem2OUgE%HGX=y zds5C!L6_=Qay!Ypcs~VYl2z5S%d?&?&j(1uUFCBxAr#yB$9&fKs1V9s9G2`%T1lhS z$uIs?#ysuG@{&-7^Ik&wPvU!6aW%&Ar~4^Ql{SWpVe;^k(5qBk7V=aW`B_ZGa4MZ& zF(&#R{{syad3-NPLa9Pod8-T_JEj)t@wVfB%}_yvlovCWvgWg*%~Men9mv&PQ7zq?@pa^k~Wp3x}VaL-%?SnC|om;1{mnrXe|)$ZakVX64L*Pm+3Q!Re`y9=!-$^9hY zO{#Kbt%OuvCMT2Sl@b^Gd3aH*nw5BY2NP3@k(HVRExN1D<)-f_VS0B#jj4L)}sv4!P)Reju zmA>OoG2~ZIV`R3(BWePVA1QT7&C`kLDV_LUe7Y*~jxka=nW#p>OfEE7!2R>g~vJ+UaOb@?csyklA}`W{51dl$^S{)=JdSD&4S^ZJft zc(yJh-g1?f8i2yBh)PZx*R_|DRS8#$Td?^sSfKN>R{-{1b#{k!C9G+FcOzxBb_4)nDAU*5yVCzIx%erng& zXSFTasqgRIlQiG|^}$y^zqc8UcpZyuG2X6Y{jthHR{xy6vG_UJ>@$3HSI|p$6*{641@$5$~ z{ZjZ!XkPx<|FP|zH;m(Y|2N+M>KAsc{W|tZ&E=1hExj+^@sBrAiX}h$EY}h?FMrH= z+phWi_`Oub>qGPLPucjF*WEIO4FXpiHm%qS$}0SM2+v=9{^#-GYC&5ba+l3sU3#ef zJtVnQzWO2d_mJcg9rQ!%4=y=)tUH_qXzXnM+PO`2HP^KEgUqY(_b*tfek^=~(ZwF# zj>lT{WUN(N!z20och2GZ0+yjaq`0*lOEKz;5?b}806USyGjF)Dci zm<8516V{vAYuchTVsu$dZC!Zw22zbnK-QK{hTfFqB~;K>bZ#88S% zPO^Tqf6dC3lI>FPC9pHS#)Xa$v&!XMua;YEveZi*=|-nb3eBk3ZeCd<1In;X2C;2B zR1p4U8o>1|L{-2W!xBt!|B1Jo&8k*5k!|{9wg|Ral#jMdz;a9otFrWL8m(gL2;liv zgFu6u#Nc?_&q0bAI-1*FAe$;Dgx_0sQ@|EZrj6Lh0Oi8kX_+vhGU?=kM%l^Ss@tDr zg(CRm-C$qI7W*b{mK)dYp!jLo-7jASGR-}%TyQ3E?N<#vEvv9`EHH^_*$i@@pP{DX z^=ROziIZZ~K{Csbj!RNA*tc$NoC;mhQYW*X#9)d_`_ru|O=Fnd6BK(v%EMPECnV0%;piT9-|(0{BfNk7(CVE_WAf`@D!5-dl00%2DbR zQzp28gBwsH@ow-4Js1+h(e#4aqwR@!q*v2rci%$gF-3s6vXX(^BgovcjRuriAWPP4 zrHYtwvCN_#mBGmQypQ=<5gFqiZi$p_jA5@+(->jcN6~Tw03S|Jf?*V+o61tt zm}DfqE|+w%TFq=^%$fvbdT4uub62=+ryUzyt^ot}RSyURb91XieT6Sc-4W@$cUZsZb)-}_}w_TAdYccNQLmMF{s$0@WzB9`h zGs;m*ZK*}$%4k68Vd(LctVxZ@Mta$$oAVHJb%tBl?a^g7a*=olmo8%$DHRM)-EI|a ztOFHNgBif%BQ!Ui5D;(EZAp!4WN?dE3B)esy`bs3s`uC&2~QR><-odv;+u74W5u1a)ZC3jI)DaWo+Y%B$Rmj||# z^yEA4GuPtmx@QDozx-+gR``! zsk{DnDam5eWvy6k&oq;j26Cx2T7A^vGJ`?vjE*@}bcq&j`VegtO?spnkIK3c&{u#HRD)Xq>5`D8J3=A8rJx<<_L$a~)2ocvsoM}sWh|v9vFMZNhcMoga`k>A$N*B7iHvjHVo?@G zIySht}jLWtx0+R92GM_mVg_g^LRq=BE9Pb@%F$&RL67!5q^@ zm($@rcj*Xtqk8rBerl2-aoa7tU)}Ia;uYtUT=nXgp)+hg!H3OgOp3y3Mmnje zjV5U`yA_;@W9NKe@hM%1gcL@svIqCOhmGOPDm1}c!I;7<<=_DFj>&ISG}1ei7&+y> zd(BveM>Jt#8e-y#E7y~9y=H?IAdQ1te6bv+= zo#uBa|Cy3Fuk_dvGn$+p5ASKjFfo5eR>nL;pQj=Eh0YbqSr#<=&0TamqSMQxc>5`< z;@rr)YV2mh>d6kG(LDhlfm~q4HB-8kpVH90T$WN!g+gjNE_1p7Q0jtKAUVP#q&3_l z%-JC#9Z>Fqr_>ZX7Cffz;T+Se!W_uN#Y1}xF<0N7N(}AQBi6`}PX(2Kqy%h2mZRMD zo#z_U%E8AHZgAEz29e)iGF=Kbz*dpGUt%OxV!xCwXmwr+}+=m4l`9V13B2_ z$~l$iA9MCt%GD{Urz`pvYq7{l(Zx13e0Gb9oGzy+hDCVl%u|ZI^Y_Rn(J`A@iRPgZ zyB*6L?Q4pu$(Bd{UL$OJ!(Rz}G}m$da=^WXQ8=efA-v9`PtFtf^HgKKE9Sk_VT689 zq;;f*hp+J!-MwuwFDreDpXO@L8BONACCI2ksTmT^DAX)2 zT3wCfqK1AqKPi=>)t0`U2i}>u+SyO(#9OtkXagpy1frMOi0WxJ3m+f`_~vz-s)#7C zUO5tl7(`j?=Y~?MC^g1B2^rKWNoDHp3gh9TLJ~71HVPpj@(|7<&(V7?xyMvoK<94u z9$t)ds=VU8S*9jjIjJfVcZESf?&gHZ;5c^^nK_R5e8g)h_%4AG3yQ>n#JULjGiy!esPF_gl)Sh-H}bbZJtCb${Cbd)nlL%(m5j}P9RVt=11 z{ih7#fm#X1_%nlNrGt3Bg{qa?OgSCI^DS(cK!Jj731X(7@;LFC zr{`ct8ni*ZPy+xFmDY5c-=X|x%02+kVSi4KhxasMn3%uA$zmR&&(je7f+V`h3xjxb z7u^nH^Rg)(gLv~}5MNepF^IP(TGZ%f5KlS>FkP7`-^x#E*dRVjNg-_zZ#Z8D@#L-F z6ex6$Bi`5`-cl6DJWk}Xo1`QdB?&Dr@F#-~d8x1LTkcMTSE(R_Vjuv+|L}YFn zJbid&s)!Cs6p@aib-`0=&P1=Mn7W6Hai$xw9_KyDz>K*Lpwvo8d)!?pz@ED z(9p9S<*si%J&l-F1W!9!RAp1%F`Rf2ziqHgig^mo{32zM>Ikk@<=ksjs5%w5ktzo9 zhJDZBr;$Dvkv#vHv;0v|871{}Mc-mAI^XmB6`Mgkw8*?6y8APRMR@8k`9h6&k385<_RfohzAtXc|Lar`Y%3Z0( zZ-sLKjZY6JcL`)J-Y$@e=kYxa`KNX(IjNE;2JsM(yE!4UvdrB?rg&Z~OeCY8%z9Gt z6p9+ai{x?`i|EBIkQke&)T3*BRcpQ4QN=Yh&;rq3kVvK*=)^h|IXTA;RtOQF9_y+| zrqakbnUm=m2vENUJ>temdb$pcIwKNgGUgqCg2-9)NPwNq-pAFmT&g5ifrm?B_Obp% zT1H-stEZZq2a46G^d)t zyHa;ERS&NQt+W+hO_o7?IUU5?lR-R+WwuQK+3hI}DYrO+lv2(buAE(GxL(eKIrF?O zoLrITqg@4vwimN`31@icu@IN>s?>wH*wr77h*8r4H z3cca+>`Vwi`OknSKf>F`*`qiEx6=Sou4lL6+VEb^-+K=`9(of9Pd2b=Y~<>6{#$ z-x7wWl4EwT$;D=;_V6IV5 zTU?SczGFvKw|uaDhg-ufA4)I@kKt|$-Gd;+1lT^drnKRy9YJ;@ZNE~lpeWhX=FSCn zr3mYpw`u1vzv9EwE88j3gw*Eqh>)MdN|^2U73O2Ff;^HQ4y0$-ZSXJDA62~HL+Py% zu9J;!iwYp|GynzK0~7i}|N5(-k?ufp1hu4r8Rd6-jF8qb3T;<<5F4@pX9;QtZp=`i z{%WXFHksM(Em;np4@F2X_V{;FTFI8R7%WCm6j+n&Dv4>NWhM7lhns={f+|vE?;qw8 zr0!x5m2xG!%layOdtz%^pgxnc`7tyO6LQ z;T*2xfZ5u76=IYdNCZu68u!aOcwI`>6LcwC>V?ZaxV1w}TNQQyt_>~R)tw&*jzy#oX( z={w{UI38Qe>~8+t4pzPu&?3i*3T`w0v+!jBKnL&4uj>FeN=!qTvb*Znb_`m~O}B<- zZg=r3J1pKV?voax0XBj`k)+Z9r%kwf3h0f2M|G}hh4VIWS4!Y~`Lhrf%% z0C;3ceibMLS*13 zKi_?+js)hcYd;Pi+10Hc5!9Gn#sQLZo|kcWFi>_W_{WhzY;=PUOfiO2w4rzzM|z4o z!pBklK>0Y%Jz|RDaqj8a!LuFbKHK#i4R>)k;%Odtaex*8Xw1Jk=!fn06p9JuP#poI zXhT2lU5E|j4g|pZ`ZI(9OM=_dA?yaP$qy=a$cv${Xo^C8qo^RzB(Tomuj4?W zDj3LIv_*>ZAy>eeg2U)Cj^iU`0~FIruKPG5Y6AT)bdY`$AT?1y zH}T}+ctAUl4WJZts3Zd_rDq)jy2`KTXuOXDC{&8cne#plovWXQP}ZK-p|o^Bgc;cA2lT#>>i^p&3-q>&%(0mF3?tC7s&q6kuM$MqK>h! z3`M7#p8RlNlsJa~L7oG$e%rHK@CemX*mmbWp5*F6YH;Wy10sF2JFq=p6i zpNs$}EGDAcOgP4Ipt@3nYm`VZ-o3Qu-9p$?kXy`UZD~w+VT2c)msWujY zaPK~D3r|RqPbsD|RnMCUpg^u~=<=hQM-V9sa$+F==2T%Dz*A1hGXUabQ))q=QC;Dh zjWt64ORoSIY#Ci~wSY#Q+LxCrVqq8uxT zN?$GfU&>@eI74x@MaHM#O$Yc3`UPtoB})!#Qf=iYzAx30?^B`87%{vd3!17U(?4l) z+#*9N(_xu`F=s-_G_L^?;k$tnA%JnFE9T-=8`N{u#Z%#QFV?u!svxB=T{4_}Uws9-;!%#C zOf@J{VFOuxA~2Fg2G!#zc`mF%rcL=%H9*~U{5z=l)7{C1j$1HNoIjB@?1f#LS1_Vc z-au!eVI)~9ye9Q)$H!}ClLi&|GD1XCU2eAoF;07A3XPQ3Q`_>ZCfcMDZ7^l-jMAh! zjkDeyS40Im6WTN9RM~>V2iFgC>h7(O3Rks3b(8W8s$x>nuq_KIXl1;%!c)5qV`?Dz zKV-!G4;c>Mzf$P^5Ab5*>qpP8#0s#D!{-IxtMTk*T6-pbEA0?^f&88y{vW6Py*a#* z-vE={lQCKl2vC2&A1(?1n_Dbj6aG(lp2b=@!d9$La{t71^I5N%WaWf^K#qGDJ5Nj-ek+$-f1b`TUg*s0D%Y12`<~!X=pNS!9 zCTTeBtqWA>;pDEe9DH=Vj#$-f%)t;2N}MSPIpjyivxh0@Bc*eyUH$}RP$}K59$qMH zi%&x`<41xnU@AU`AiXS^F8T}We10`lYH$4F{|pN9MnH2fTa zHP)Zz)MlOCEC}Ie&Fv@rD>tvN>-o~?KDvpZ>+#dTKH(H-aa&|Ma?hFJ@W4rH&QhLI zBd!>nNk*n?M@5jX5oi5f-zqQ5jOOA=x&SGp3zMFzWW~HMJ6$`5&D%YKXrd8)JP(OU z{7shNCsarW>*)fR3!w@u{SXBu3Qm0L$mpDU4;S;dJ|Lx7Oe&_T@*W^>3AhkT&L)M3 zKhad*{$s<-^R7RtI>s%wX=^}fQ_N||`7sHvorZ*RW+3oLtg_16R#YtxH;vh;-HJU? zAIRO?oL8HYXV_~+D~5?ImH+qCd?ZbN3b*3s&8(3I6~I-a=k0Oon`p!!E@fy&Ex3e< z>rS{t*E3KnQXP1|?Kd}w5bt>;sS;xm#v{1i6E$>S-m4mY+@V;Vlf7-D|P%lA+f zk6M7H{pEC|nbPY>vx8~#xN=w7(vfC?4yEN~nXOD7&;6aoSOzbr;(C04=H-fKicY6x zQ#|qZ0Q8IB!gy&DRzKC!fwVjd=ZCjV;ZCzm(^ok0z~NKrNVA-dH0>!^mBMSkT9^Sw znueHDJR512ZKRoo(ecX4D@nuoZn%v!2`6`z<={h|b@-u;H1VJ9FlR=Z!slgFyZmXt zU8NK!8!>P$r+%O#EfxC2r^r9a!d>L$yt9!eE^>9Ghf1t>uPNU!Rw^hBQc<4T29F0g zyT9+c$220!L9vQIM?omx++AgE%qikh6wavS2)2-R8NY_Xs*sLrXSPt zdU6`%mI8E?jH)OW-kXJIlbxODv?+bhL$V;wH0BX$bAQRQg9n^8-{@BuPbZHbY4dzk zXGNl1hMX^j105A4CrL@fWFqh+vQng~f^~kko{eb1VmgXbpN`|#iueTaE3!o4fhvq={QnW~7N5qe^r0qB7DXgWOF7G14SuMw*<@DsGERhnG3e9K*&i z(2AqZ##O*wDU*y$*N$EVj_>hzRf)yeJms7plknPUNYH~BE-407R-UaQM%Ch& z$e102IAd4T2Xgl|=PXh3j5IBNF-&Bs{26Jc6(tp}?pATV>h<18gWQ}ou|SGb-$Wzc zZ7FSnrtNhU1G%E`3>axz9e6F>OG4iIyyuamY78KPl!;`n*hE9(K>D04rz6c@5ftiba(g)aSlxXLprt49CxdF4WuFdMN!;n=WVpxk=WwP^WN@a( za$ejioC+sX?YHvxCJea$D(nh7L3OO=id&S%WKw2hflV!)PL>_>#$q&pkf!0be}GBH zgMb;`p}hvKjAqAh80dkW>~<7T9+uhd*tb!I)NxbX9xFT%z!Z$lg?TwPp614~wgFi- zTuabLhc-I_PP-a_qez`C0mIvHmKzJ=tire8rl5BIf!6xlrjn)+!G<`x&Gs}v!01Ss zO$wFxHXyJGTz0Xn&c2_nxaIHwLa~5fRj4&0Y!^gtP&`r|*(8_~NFWcm1R_|9mCen?TDkFoi;K8i`&@L(7n>g z5xhL2XQ!oiUuzRpFt@g)+BKRA>0vz7gwSph9@~=@tYsAGN%1o5#~x>tHJrs0&rTyz z+yB${))72Ajotio-_y5MZMREs9iS4~(L3CX&5>3}SbFr1Uxc0EWwa%@PIN_-ObVbm z-nRa1ug&)JwDC4Fa%9dJC~(tgo8IhiEbE4!7B$Hs|G?w z`gQnjs-AOnHhr1(ZNR7FAYW*4K<)!G8%q(D|6=wdvb>{Sh0^fS-m1Zn1{F zWBdz7*N+gaJ#sa@KQf3bZLitPRL~V zJ9JZz_mj%fvn%}|%P@+lOCHrqtvFGquM#ec7#v9m5@&>5bQb36I(UjBN;93ScsWi6 zbOR{G)q{i{fqGQeR9H_hG(6g%v(v-WZiXyVDXU=}$Np{5nPHrADRvvn)f%PN83>`T z9ggAc70iP}R~Q4FE-KC$iANQ=s*DN(*a=ueIIWYvAc;P4gu%et!SObd7P3WI058{B zmQBgv&GD?wQ{c88I%(&B!5u+0=qEL>lFnY1Dq}+fr4&O|dhFy>IK|q^h8>x<^q6D^ zNdO6(cIj9yF%+R_lhOfLvP;9JqOx5PRk7%zh8WCI?gIk(sWEAQX^e(n8k3ohHSCXS zlOGfbpJH#PsSIHltWl~A6<_^|D5XVk5bdsnAzq3GB)J^|KLeBDl@bC-x2Uwao6(oz z+N08=BK>$S#x#ITkX1y)5k>I;%GE;uxcnm%z>(VE9&c?D$6+Xlm_WshsFxJ{N8O=2 z5k^M@agLKdtD|*F(hxA`j1PVX!gO9&n}*-jV9+<~H+Sh|N#XD81TZx}BAr=#kQ19?1vunF zrH(*~Sc&=;N3_GH&ChJZE^fl9{`?ouuJNL3lTBe#JVN>qvy_;giX~}LqIwsD-AzyJ zeCamsd~45hiINh-I#a}Gh0Wu~eB`D|@=am+M;aswiWBqq_>pcG82RR>K6vV)s6HpB zOsN&Aa!^7}mGebmJZJgOeO6P9E6(I;OB|gm(XB{NhNFnY#v&?_Vx_se7heR)|8R#i z#SH5S%1^{mtBm=@uzF@hiMu&x#Vzfu=XKyjFZ_fiHP=Q7^14U`Pn3D$IV)qe`IF_d zl*s~BD3sch#7!s;xy21zhZ3kLTvJFm+6QmiQkO9MruS3|a#HJbP6%XBJg`ZSiWv|R zf?C95n*_?TlWE+`Ar*dt)6YogZhjg{`Wa0(@njH5xiy4LfK&)Hk(3xEvH`8pqgTck zc*;#9$J|B4Xs=TRRNH7gZ^;WU6)0R*gv_`^%Fh`j=#9mDGDY!S!{9DmoSvVp@13NVi-RK=_+#8<0qnc2d*!)>* zrTE^Uy;%M&x9A?_-HEbVLDue<^(E~IwobOGEn&7{N}WDxnH-(U(6Ja)x4x|Kf&MwVuuhPb)TN zPg`&X#ZH@`vQX*Ny-H^Cq#|dOa2hy$#7flQO8tqXP5k;f4Ne(5R>JWtLI}F-Im$^n zIleD8$tez5e2r0{A(5!jfJg&}U(slY^>ppM=oo|p<#aT}x3-qFt+YRN^PMnwf}1w= z9UW8FkshCQ*kTWy|j%Yci3b*eELpDL%8`}%+vty?(SJ=Ti*8;+;7InP)dIL zHKQR2m^N4Csl5kn*BmI@Xvk8ds@PPSE;o#Z2&LPdC)t`W9+SgpNT*uxuXZ-#(KtCU zK*!=R8nO+4-yLBzM6Si7a2O5QhJW<;668nVI3NJ=fOauGZgi*w+SpL3RmR3`{}}G> zG>&ild#U4Qf2>4(D?RN3Da~wCiKb?ssyF||LqOynPn*d0%;z}%Mu{o~G1#R*Pwmd= zF4uhf$#aR462m$bVzk2M@%>xO7h~pg@QugU2A0a^0;AOZNROO4_bcY)lzBC|yW;uA zc}|t{MWvMxy8qmV-o&`dJ95c|-?vC@>d|C}KCAMUi9m|;CZ zv9f)4KBgJN>X{KG?&h3T9UhsZZq!^GCCDWt6+G#S$f8J@zVn}yl>2DoUkq0}k+|g- zHmlO)E;x;fqDz}iOYx>{U$qe5m}N9XOmAtPsy4!B3Mb!4E6lKqFE{|2!p^^uey}4x z+)G>fcao^?Z)P+E7+?xa6Jr|N_GdK2ZY1~ZmTfd-Zj6Sw=^1G#+h_=Kk}{(qbF6{S4CpkRM|#DsPXK7y=6bK z*JU<}q_fjOB2ua8K_v=StS@h#dA%vRD+@<0*k}l1?&TM2+~r)~QB5dSuj738J4%A* z7~6&u8RgxHvV@%%LKsM%ZD?XVkO0J_oJ$Jfx*)p8GDkfS3mCKZR^e^lvJ^viKe_wyZdp$6x&=SUn8;TW{o zB&Rs7j?obAHX5=gqaliEqoE_bmml{}AF5AQ!mK=Tm?W14)+&>S#?G3Nmw(0qDyFXbs{)2CQY50SG_m&-h zbm@yXoZENS=`G6?d?s18z51vV*X*MX750Z^VIari~h04K=(nb%t+i@Ri z6x~=_{F|Eti&AuWnZ2>R_%}BP7Nuw&QpB}7i+^)*z@+GC5WOwz(68t3IJ@>~Rm150 zp*5db^7-)fu)67_+Ig3~?meH|cP*D*tvs=I-lea5&u91T-=8#nku5D8o_p!*{vL-r zlBS1*Hp*->0q{&Md}-}WbeaPH$) zA7Hk-vfTOHOJ4i#&)kyv44nJ8qqODTlsbLvZGUp%xsO}J8OY&oB7gH^Z~M~=&wc!w zTltA)L}uX*2B@5XuZmh0bi>9Zca z42X63@|`$L?c4K~%ljX*{1>bO-kYqL{@y44X6thw*ZgBXG3A;0!6)B#<#}hWyw%nS zo332VVx)D=-+tIVzj4G={WnTS;_pZ`(r=WH#NQF4CVb-v{24XJFw{QIj$}I-XsrHx z=)HO#L+>Sn3?Wwye(!VF{>5d_>t4U)V|<1$?N3%6`2N3M`od*ACXzo75rrC;ar(3PdLpL6l6-u20w z% zOSkX-#JAk*^Y4Gd*57&JsmpE;`|vumf78{w_qf+>H+Dz7?dgB$p_oUO7&w%1sdF&IOweip1`SBa^S~`8(zlYC-l}A6}Sugps zYp%cX&bufPXJ{Y&glE3wPv3Fc=5m9r#PX#QkUr(s*VlUX(>HIvDT7!%M@( z;lglMcoyLH3prx(;_#BkwVvJC+R=J;wY5`O`2U{gkw|yJN&W`d{LNtUH$voP;eSEm z72z4UTo$f0QY#Cm^0xr;Z?%$N#0?BvN$e~RmD~t7u7U>_hOG}Y;R{IgQWCl%JePmB zk?3Z=FND_f!ujF1!UZXFGbX&qYO!;c`m=g^Tw1mlsg7gqT7f-c^-vMX?`7nDCBG}| z?efq~{+q+gp|GD~Udr=)XuLAips6cOr*g<@cd?m&s@29+YqM3;LR0N*OtpF>QtfC= zwd2sK{yw$&3ge$7a5MHGs@+$(>jKhwCL-vvaV0f$73Z5SAl*4ieYkX=Pn{o<-Z|>1 zk-j<8DJYJECD&DnvDjZNw7*)x{MBgj*Dh6uzjo)ZrU1Pe)DGDUo(q#N3mXd+gZAUA zLt2n$XZozB&syuO>f}&z+D|LGjQZPbG9g*m8ZN5O3}eL?K8}NK+rtyXlfqNOi#Wjc z?^;W(C$*m1S~-2`>8mPDl_izsl~t9aDr+mpR9Y&>SAL`N^vb!FXI7q7c}e9}mDf~W zTluTX+bi#=TvK^x(w(`Ep=PEy}+*bKXWxR4v<=)C<<>m35U;vNTzitV~*y zCnYaPZi}pe&_}nP!Iv>eq$+8?YjhEr7W2CCf7QDjtS0Iibv_K+Wa>LA9%6|jv+zP? zo=i)2h;lU)rbIC)#5{^nkkiH@EY>As3)SUAu&y4QPH~kH1uu50x$sJ5Y_(qd5-bLv z$582Mh*Ec|Vye;|9i8p;l%1`cF1+N5jcOa|ORe?FtykgD)ml-2?$!=Hdi>FgYB{^l zeL5=Xle9>%Q(hfa`&Sz1><&`k-){T2Ck@-1rryyP^Xsf+ZyniNMpkD=S7$Br?aJP| zv$vk?tv7qi@~A>8MahIq)%g1x3Rp(DzK-cwT38?isJPkYxc}4 zt|t?Wo=h-$dQwVzB7Hr5)(rB39h$LXZe(!A*xsyEy;iE;&ep2v=&h#DjGkU=0lnVr z^8B8D)fHE6zVsOzFTC=qts9M_i6{a_(@{rw9aWEj}sVrIGIhBg*jHmVu?E9h!BLyCsV5Ag5}kkuv=;N2mQX24Gh(Bzp;p z`#c+rUC5knD{q&Fm!ZTTbcLjP{=aCA(BoV8)@iyW)25l4KN8)WNlx0aMXgfTp`~(G z6u^}03+T_%L^9#&EQ+JV%4Llvf>Qj??k&2lwWFrh{%2LwsWS9|fcg;Hv`Vq?c7xK3 z6P$S{ytvj>RCxJXQ`98!+0lhAuXac|pi3UeS6_E~XLprOERVcEC*_<)S-?jugPyMJ zUp;sQzjPouh{#H`eNN{8L z4bo%m$JboB#3AMUa(NC51lt}!E^*a%ez_c6mV7h8`8QXI;!5uP@;bOg3(3po>~($J zTy_66>i!a|Z#4li+HdQLyw$WM*m_c-2n>%r ziUKx9A>b@gjMw7i`(u*?4dWog3w#lIiIRu`|`j zDxIfUSrgS|g^n)wpR;~vS3xZEEx2szts2WFZqB8)SqAYq3uqTC04*XGc?K2$!L9L%3@>qaRnT>ocLFUwftUY zbD&n{NWvezl=W-PiCS$AbESQ4;$MZ+>}F%;ulz5^WivA#!HzWNxyXED>PqRdEN&}6 zs;kIllcm#+`&xVj6l%pi#(pvLu$WsbbExNp4d53v@QtOfFHcsgEJV6Msby9%fSpi1 zoficRM{x)aQ|1@FFvfo%@#(6d!zZq@@95MQhgK4Unecb?vRuJX*VmW}i{ojnQ)b(h zY25u)w;H#9ZIqtv;;0?YcU?To@34Eihg}2Dme^F$sh5aD?w8~u z;oG&g+m-_Y7Db|h5Ij6Y;xJn0P%<%xmRJ;tLtrupDVDocDC~-6o_?gB+hhW(E$?(pOwr zpJnTfVUIy^v=1f<758}}^l-5j9O0mBo?|3-RNH&IDm@zCvFFy&#dcX&ufDokyV`4A zy%jp<$a|+Li{brzBsGtl7c-_nDU0-;Z^?W0F!1jbEF#5OsCH1@4cvSt5mJui+0?q* zd#hbt9T}a*%NMi)vH=0Z8Xf%)2o{5AM1%(5rfM%yYCY}Mo?0JB%f9w%r5A(_k+oQ- zs)~WSYVBQ>D#P+(piB_Gz8q>3N2LY|vU;~+kP+RTj)&-!U15PU$qOO8N#v4hAPv%$ zlG5GY(bpw1d)m9Zx)~RA_O|y`x&A(9z!AUFlItjDto({3ptmS9)hp zU8Q&EO9QYjpiiB(E+}lM^DIJRou^UrDvt@wQRSM%pa31FF$uV$lt|YGhSoQLML*F!JiF5~c%qU|&yrA1*?Mbs{!hOvySb z-R;N>*>_Mjq!dJ92W_SowSsSFcYAkV1>>5ID#TPP5@)2BmIV(Po=y{^()%wgr0dg$rxq;)pPZ6=%W+LcyUE66<%D-u-`TwZ{#xER;z zHN}-jL1wG))nzu%5HWs0GFw}?%+}g#s$e9dy$6BB)(MvmsjJS;_MTdAALIhU>+M!s z>yx@dR8U~GN(G@s-*)u%^&z4aG<&7XM6?H4p^+l;)e0P`v{!50%z%5rb#(U8QT25p z&YehcUtfDC$`TZ3rAo@3pgKDM6L(tD9i5f-t{zErhilM2e5)i{>tUI&qe?@n)QsLv znq3cYx{j_2WJwiDw|U*oLqxl}7N}XX2uDIh=}ge9`nO(0!Nnd{M0=<+y3@QZQQCrL zm2w31N}np_%KxS_sadJff&|uJs!3p$9<`YXVC-V^P*M(kfRBrz7NS}yY|6R1{x#DL z3)8WPNk>mFy+S9$A_hW~nv}YGfa{{NkR^>By4owf9Y}etuf4CkgI=Z!ty@D4ccUa3 zT_C^=FVszBJV1UCMjK@uu5a!}aTW$-SwZrOY3Q4?2uDJKwAn!4%)j*#MAaWwf;wvI z5&9}QrBQ@XTZoHfMPoAShE1iBDh;vF4I@n549?&v-Cez4b+I;-cE>RrX@#iTqGT0< zF|_NbRuI)fum;gO{O}D{JaGA9u!e3yANC+JeOP^Vws%*$K$@#hWFXqrTJ1uiNe98Z zO0^G6E>eYJgIQJ*_0QdSNfk+)YBh}jdPta|09>Urrdx%r?X}(>dTzRB&~C!ASLkVa zdZoWAy)c4K8hyxH7cz?$>|tC`qx$rU&m;!#-GEjUTi9!(h_~ z_5QDxVmD(|s%2Fzz6#ng{{>mu{qw5Y4_m*A#_UthG9J(<#dnOT)8g_l_B_4Kkdd&CxJ`!vNYGALuyycTDBA7uQ+ zwON~29>(0}SF<)->FH(#7A1gU(-hNM57O|U&0&t%y6jriWO=_+itbekqE29^8{@jp zR{p6U?pedlS0w9}V&W1ZgOExWlixxnHeX<**OyKYd>w|dU!TlhpdzlV#3iZ> zwsekSF;sR$S{LbH z{@bTTJSM<3rnfBYX?3xy69v%G-PPX5+BNC*uzu3VT&Dy12P4aLrGqxzN6R1!78ZMY z`>04J*Q`DFG1JZ~Z5|CJTjKNmi^ETsvj}OmW{du5)P*$^TX3O74Gl$jnPTIrQ=nN! zOy_#KnGrX(6l9xOAB!zLl59zSWfqx_YcOgd^$o(-vbA_fOi#rY#c@!3DX8IWxv&!r zm(ub8mkZ&+g4;a2P2v7o`xIANN*h(AsZ6=d%RB9t=}aR&i`{3R9RL*AN}% z$Hb~unCf=*wO4wosD^IVVS1`8v-Hp>*^IXbFH&Swp@s1tB$V~SPGnVUlq~giO3IlZ zvuKXsks-_GRr<6JC_&z>HFUFb*^R!@dSMrfkJbb#y=1_fJZ);Ng?8ExQCZ2Vc5BVN z1A54uo}dGQD#Yi7**)`qa%GLZ*4f3PKt~@dZ#AtAcl6cTX=6&H51MM7%-(Tlk)uzG z2U#7>qgiCjit}w2S%f3eEDp7b1dk8fEVN6YrHq4CktFB7#bcW`*t=^D(j=eu;r+mD z1CPdqq-^am&#Ach7>6H)V64co{_?=rC?Dh+63ao-o`?`jMv@IlTDP`=y0zl1-Jc!? z8ZZnc-7Up!LlD-|wd+&uV@FrJKCEY=$-7x8V%?oViNwDX{ftPmRL{19_Ltb$K?u7$ zZ1KLrZfRGa7R}k=>8wgO)2cKSVv*h!lh}%*C80)Gbf=U#N42Eh*~MbsJY+Rnz?`qF zW)Y5rtlEO-LF=8YeH~U(HKk}!-F4bETZ&Y`;v!@eu`B@HXIGUhi-8(OxO46=KA1I1 zI(rkISu4sIJlj7FD_L6VlU>+W{{HA8waC|6N7q9HXGw3;z`%tq1r}z)5iM7oWkF?Nd!bp}^GG7EJKh>QAkaiNZWb`}`&;zHej$%Q&r zIaot$T)h^;_Hd1&)(couaE6B71NG0s^c>@cY+Wr&Vb0YzfkL~rOj``KkhKwkm~3ac zZq$(N6U>PZ>=hJCYj5my0F7k)(hI_`8|)tduHN1ni7RC-f6Oe3Sa5q^7Z#Ii(!P;_A+o1q# ztq0}T3fxY2O`d!?ttDG*G2R_~xbuUx34Z7=RvkvV78k43u-F;pU-n_>m>-OZ_(NYDirQj0uK&e*1?`^1rk`C>gkgm5>_XDwH_Aa zK-+KxyNq#Jx9XFf6H95;UhM;eF6ir!gO8MAp&s# zm_hKe&c03%KOO9ocl3aD08vxJSN4Pgm33mNM-0%F*sTdZ1HP;WD4BpXpcD+QARLX& z+&Y2#xY*2NHkM(;<~tk9BBXQ82L&qAA!Go54w{yO-Z<=htV71UojnH|nhH9DcpnNB zX4CdVt5#I3)^*+fPZnE+){ue73V9bmWKr7|f?+}oR0_OGAy|XPofGZ=YaaNV9>f+H zE6E%acW{o<`+ZdzMPV7**@KgrQ)8TrF&bv~;AueUu}50z5Xx7E_&uOzfY|VjQ5EYF zm~x?fkWCD=nKXl}!DgS~S`Vn1E;G-1kYY~pfwaS z%V5swZDA{OaeBKry@dn5^x?CL!${ZS^!C5m^tPZa7C61NW5?0kb5Cy@S9rx;p*!(~X;FukRV*Er2i0m+70X9=9ocqC41v&h9c zs|H$)0d)=x2WBuFcrd_=%mk)x3uT_b3kKlTPGR5~#B(eMlUy*#oT8PcSUX~muu@exdE+g|fbN{~vXs zEEf>?!VAOZ#k*W-kf3Pki+DK_ce#e%r#!US6xadd*`w8C7Un3{OOywZsh&wjh9{c;!8F@J#|S# zHoGhSD>nJ{$h@}H2Yu#w8|Dgqe0}H(UIuX&T`^aTVHAo3~yW!+NP8VAU0= z$3=Xsi=m<8P!Wzvi9hG!D^y5DYYImnvA?H=r-onWuQ&9BC-T=DIzuU(#NBhx3BShQ z=fl5+PxBiNpX2?s&=wxa%?D2iXNI%F-taAc-^5*SCH~48T~7{A2~XnhiQ&oodt5j% z^Luo7OgNSJ9pPk_qc5?W9yWz{g%5|Jw9_n*KC=H~at^ZVoqv6Zl&Xb^1G#^xhr*F8l-O z|0DmN!Cx!1JSi=;O8iVpdTw|IVb2V|&%F-6&24-?3AcrxhP%n{7fmH>Bmaa2>{meP zg&beDFWefg3wy}x2ju>2XudYQExbMaRrp)ppF-^44KE4<;d!KVQ}`m>`Aqm2Jp4qc z^4G)d5l;?JgX6-ST|{~>3NNR`o$#YG^o0+T_CJUHP0O2__#NAHO4AulEu{XN(5ZTQ zRd{uHU3hEQ4Zl7>`ZvRsTcGzl{C$PLZ}9s$-?xWf@OL}!Ux!m)A>>Wr$Nb$wxbKF) z5AP#|cahSo;Iz`6@8A2IPHI}&)Y^1f)2U6zG_7rVR8tw3HBBeuc1F{Bo+t3Vp05+A zyBcq2HXTRk)~3_(TiLX%sl?xUd{4||<;Y3%15IhM6)d)b`L+Os+X#m9acrgahv(Zt zhc60$7IuU;q66L%-h}pgYxwK%dRo{AY5A|?duMo0_*0&5BE*}*3(yUJfSz~(zvnHs zg2lezVcHk`4gKF8rtu#^Pq4n}c(nYco#784j}&pVRihf1X_cupkyYNh_&#N3nIu)8)>YO0l% zZnw8JwbJ%|yK5wz43+xdT!?;6vTk3gG?Z*F)sl(+(m;~zDV4@%lI6UQl}g9$OcH;y zm!TxtS=w12zh!5sKOw_CBwgBP8O$Wj#NC?=?LKZIN#D{JQX8s|zofskb28!IEi=iI zEv23Odqb%os^b*cUw%J#8eH4QS~ufwv=i&Q2wE0OKD(2^`e;MY%zHfbD*?cY}i>J zvuR&#y0jGL?VT=#{+ZJ90afGJbh6BzlS!c7m)5AbV!XE}GrI$U*6iE8`v!PP{IT6b zQ^`_2_T#zq1`;X8xH`EjSpo@vT`2L@$$duF7}SpyJ>HrmrBH)|Tly#NORy^0IbB+^ zFX^8yHTCbCNR~|0w%;n2?wd)L4#DeNlQ4mpLJ*}y#PC00{(nJkE{ktTnrho8lcp{G z_fmby_9R)hU3Et}hM;Vsw)56x#ZYMs=Jro~H)$Fm`{vyU4L+9ESf189k`)uMI+-Z# z9#2-lr@cusu>GqNihcJft)ZLK+_u-I$gF91?KK%8L?#$gS-L@ycbAmT&{q}cUZt@2 zyQCoTX&TsWkq5Ttk*`U@z)We~0MUj@1AD3Q8p2DNcTXkL{7ZCN3Dw_E0Vimr{o>K; zi2;+h{!%}6v}UiKloPQ?Ca86UbU7_+Z=$9?FqP2UORM^aNOovvX<*-Ea`HZM=!aWr ziV{Fl9E9^^Qd@gVH&C$ylgZI= z2iCykQvcqu($1;ml(E{t*cc69q8|ZLQMMCvyMmDDiR8tb;_oBV8;G67Tw8G2Q!5nW z8mp$6{W-*%`Q7}$FtIboj@g6L2tm z@%D;_-C{W}{HBuf7OGlbp4fKCwIFKeyOSjZrW%#NK>tj#N=1z^o8+?GT?VsCxF#uE zsYR?2tTIs1{rjep6KGmiC}V}l7%)MwOo+vX$%}V?G)8QyVx;Ni!g6OZJrZ9FXMifuppv0jL)b$d8ikEIIG35_Z#! zPaSi9laBfn2;Yge5R)xu+AQs;g#;|z9x@gIin+Sr^1cH9o3>D8En=87k(%!I{)q`S z(G$cr)$?8$v0Ka-sExs9SiVXMqqd!b?470+*vk#Db!=c?QbNHs8%4WmE=LcQZkX5t z9aaegH0)C+Y6Hn0e#w^F7*#z+9tuL&tyE7ii88Sv%wE#YVy;%q)TLO26(-8!486b}DJg;D3>9)3)KkSbaD!e*twnTNN-?wskWCe{R%^A`uCkQhS!88prnaah`K6s8p=zt zJqb57mG+IJvWNCsqyBd)DfS!q4utJ@CC&RN+s^(8LhSCJD28}VvXo)U?mLs^W0Ydc z*f$fp%PkXMC?xV%bW^3$4fiLvS+DeI>)3vjj9bj@cbMY`vMgUu7Nvb@;IU7u&-!8V z3&grKWI@M@LFqOo6MEZy$BItqzuY3IbD`+-Mi{lM-4>Wf}iHA!`D8B+h1 z_E)>$_eu0zLg_oEOUoy$W1CKnLO}K^ zih8e)WaYmmIeDlyp=P#|(yGKan1(U^nj~kT@=@@Jp!XfSU9gRfv-S*+jXeXb8KYmJ zZyA`_L!;UPvC7E1FLFYuxq_0yQ==ZBF>6TXId1PiY2R3B4=sAEHe~99s_;HVahKt! zE^oD{Nc*K?sg~@n4NWH{sSN#0AEv6)Di|FTdlRWtqpzUiO>@#J2|97ZZZw8e z^HEucW}nj3O3`{E@rfVG72@fW;B)idJ+(1-3~{Nirz$EZXebAg)nbbZ%dc3Z6H!W# zsg`T3kd9ObAa-bw#gHcU94Oi;3G<;kj`dl`p}bIhjPgs{VXu*SRMx@Sr_{GJHzg61 zBqa<&EyE?W?UM#}lEiL=-PtUqnU;WRO8dmsA~r2=UZ%GvWyUd9eg=MCxl-^015B-U z*QS%zvBROeqHm(;hv-e#WxdIEnkJ*0q=axdk*!%@XPIQZ-%g6|^1-lDxiP6o4kYW; zgNfV$eonS}M`V+J23Djj_;A*Q-kF@FkpW{hxJ0AhM}cR)L2~Ar9R7Qo*b8uV=KDP{B20@T`0Zb zgh%%7bB!XYnONU=T~<+7Ck&?$!cXE7dopuF66)Q)U^9v^_Nls%zRa=EMUHnQ%YCMR zYD1}Sk)~$ysHwzprog4rO_d{e)K~qaxj7x9Gjx<JzQ@?!o=&=&MJQMn`<7)-0lOeM=}nrG~; zkIGsCwI^?4Qg5qbD^7L?9IZjvyo3sFh?$PXrWoT$RJRYsc9SsPh;qP;KqIP&V%%$B zE-FYPAVz?&w1%e4hDkxvLu;X|Nc8qC1Akptv3D}c*(w*XkC(!k#bB>amYiNH-BJpz*Cwnnu;?=Je@Vr~^VP{r>8GVN>(8kE zdjIddc*`sQeCNA9@V=yJh^g!}gB_Gqeb~v;x<{S;#BclvQGxftI&>=yi38FMI9R_Ki*KNSgXfVb6B+dK=4OTPFWMd+z}rRhjpJPBN21 zNT_iD1=qR>2r7^O(gXzriDChV*2J}7Ac_V{ zNa%^wm;gygCYek*^WNX@|DH250fOH9-TU18+~*_A%$alE^6%|^&zw}7=Lo(M0NXoj z5v9P86fl?p3u3CIZia(G6jf08@E|E;Tr(AiOte*M*8)UXFub%WENubYIOODDYrahK zqDrgrt~W-_6I)w=8i0KTPQyhY!d?c~1Vh7k4M#Yc!b7~E2ZhT}p(^N8RRGvv zO>nY`4h))!3y8*6gy(`@))o{&WFm8|R%tn@Fw2P2;4d>E>X?nX2gAkaO<>0%s$}rX zD_G$|Y6TxnsA_58IN4PAp41#Y&r1wdGe8T})DX;C#9OVL_|7ZOKCWPiO^Oi1-_kgQW^1=0@>7ZYa-pi&Jtf_qBRPMB>k@pih9zi8JL#wB3&uo z^&u-@`UECIQ-K!_*}iP5Dhj5?EUVIy@>i;xa0~-RaZ#Tm+2Bq<=Gwwwsso7^D~Bnt ze@KU(x2%k2sS- ze|D?{2}5#lzKEb824o3Jm?zQ*9RdkT0W6#h{B1j6>2Cobh}IVw2qGBt1d|!*a|}5I zc_7C2Wsp2eun4S~AmbDB$EgfD?fN#lD>s1J451qqVMRSb!EL>;%OZilNjk!Upa|$*3xb2NOL71%%Cm z8Y(Ii3ej0iD!g7&VL^dHVHidR3JhZbS2Zf5FtW_5Gl~>l zSVqpHxV9d3bBGU&C3{+;5x)#gK}}$dcU}`wf>~qOK|w>o1NC-@kOjxvY$~Z;1~kMb zHFH#Hs%S|va!fFas#QG9BaB($e>4y)2t*00E1?2^H1h!=mSlv#aJY6ZA(*40E~*M* z3bFQ3ij$9+WLV7rOhnal7=8y__oNoKD%99rm^>Ci|0lYH^AP5HS=s3dYQTT(n9-Zr zp>iE&peNj^YE?VTL1J9X{-dzDAR`BTUsZ8X2biw|;ofU8vXR=O)RUS+8-h3s^MlLF z5MY6_sR$QR0X)K72jlo62VFeqn1rw&-=!r=?(!-61dj+_zymrclU#H`#j=+Uo5Lj! z#9j2=r1`1gVh9e9rm)DqLTc<*1qKsCd=w%A02flpu;dw7-@<|rT>A4s>x-}$L0CMd z^qdYpFKZC_@v9nB!t4~GDv6rF8Lp`~=*Cc*rcCWIDZ0k29G9cYCB+<=)S?zvv?<4bgv8a89w-Xe zKvXhd3n0r76c}gJRb7ApS%;8fMT8V0nkco>ok6iOus)i)!UvOt#6AVztTaS|d<&Tvoz6>>19oRDu-UETCg36oIXRKiW!dg~|r|hy>+i53rV@Wl|KjU9coBsg|HN zV$F$;HuyWPUp%X$4g2mDYrX+D;19D8nkFf~56-ujOR$vieS)}lT?_f7Z zw(wrdHt?WH1eGr!B%vrWv7TrxCom-qI)W$qGYA3-6*;KB!^xuL1+|Bg;TzC_R0-v{ z&}U_mSWwcC>ajpKL-ml6hzW%f$bu*7>oXTCWUR-s9`jJ@BxbXUjrXA%mwYGdJnAgWDKGnhjlxHA0VP1ne zB1>K-%A zO&U2+1%;2W*(`(tLC%8ech+!)P&TQZS?ixtOqR0gaf~F&e-X23&w-J*nBbJ!7olbN ziy^00!M9C?Rnvx0ie_dp0wCBkR#40nS?@R7b(2pD4(nU=W)OaaMMdCYKsg~BQrZB~ zm;l1SyHX1?z(@K}T`Gfg!fImg1#CVU2L@m?StbJcoDfce1@d!+9A_{KhNt0QZ$e4< z`JymI%ykcFv}HQYO1EXLrNqt$o;q zOtP-PgH$k~5HDSKk62~PLeVUDjhJO^p@J&2oslQnF1)BbW;q#JNg5wzgn?kx8I9oc zVra1wBgf^5Ep%}u4yz$`s3@+0?OxH0@{3C&ilAPMuvDl?eapBaj*_W~c{>|ynqcf{ zVGSN7q&R*?Sz)0St#DVfo~Mz(XhD@8845Ha=GOYJcmRr*aPug$3x(jBIBkeEj{j74 zRPCycz^%HF!xdts5Vo?YRykNSMrbCxSg_cqbC;tGUc`<8(c>9BZSRuMj*cEhdi;a7 z$sz4P*x=DX32t4(29M)GRJ;78c!duFXh*``@5}Q%I5e`G*^$}V{85CLoF(_Rv zgJRhMLk)`>FcncX{6mJhl1zhxGpx%WYe8TYIhEKHGZ1=4A|zsnMcQ>laK$cJsMYwr zMV&-Y38igR`>3l0;f{hIF1IQW2B2=0cij&O7tS=HTn)47Ds14oF|;AlIi7L|hOjdR z+QPTPLefG@#vG8bjKX@vvLa+Jn-i~9r<+xHa}^e-BAWq~^kxQfSr${}G!|2trdW%q z0jt1|jaJq6!Hjp z55?mnCdw{Ep^%<7wNa9lABbNnbjapGSo(;>25Zy+y)h* zXTSulwKfM?3l9Nxx;_PyB58@a^N40tuL*-Vu-J5%3`1ee%?S;42A3HbTv$!@rU*>R ziS=-Xg%k|w4hoD{<5YyrUpX0#g3$^KBMJaqjk){^Cxs}7L-A#rE4maU5uL@>l5cpy zmxdQY&M?oRndBGR`5=5jQyE95=w>=F(8Hr=3#v1OWXnp!E#^Fd%mxF`^KLEJzy`5IKG znT*p8T%v91JgOU$E8<%!CkS{E@bRxL(-8wNhdv6SnexER?NOdwo zM`X>|%G%eLflwB;U>DUL5(Xx52S%LUf)P-sf-4zVg3X}8q}`R>gR}uw8A7Xk&t+2g zK$OT zAsXrlp%ocZRkOu2FfyN?uEuljN72!%i4bW4X#S$}#u(rWy z`2vvoJT`AF>jbpT+Dn-Fpr@hEggg-+2IC+vRxfZ=h;=HgXR|OR=efreq9%HvZGL#g zGNjH8pEf-!M ziOk8}y(BVxrNPao5`n|K(A(F7OCUcq$wR9|!&e#yaT4QmayT3(sj!a_jb+!SbP7lL zVyz%G*!hQ{7UNQsBtobkSirt0~E;In1fJl~ekJ z_t=QkN^M~(nsq|#jM?}SyDzod)ZQ$@==6caW&<4`L*N~99uaX>YNF|i3o@P(t9jUSZih}L^Cvkmbo2J zZ#CJVPDK)i03^IWB_{)cZ3a_9i{9PC(KtOdqICw_DKukN@xhboAl(a4kFcU`s~%zP z0XUGdgqpFAuxTMMzM0d<>1-dC15FrWm!eQ4X+CTK1_S2} zb$VFynHFF$7b8;^r^M4UX6I%N%y=dR83M_{B3pZ~E(8B(MfNC9n6Gt~*!>9;!2TOhtezqvA!EgZ$Y<}ygk!f+IfZrGYnbVWdD+_Zs% z{_`weD6+@VzB77}lC^ji#PDI45*=xq8v##YC?>sOR6+k0mhk}runA4q2;K*PKLEf5 z0Ps+1+?ivpTlU185hx>On(pd%B%auNqRp2GkV#UIoV)lTkGw+PfMCdS3iL@je%5v! zYbb&(`ieUtBD9l4xO~NbP3S%abU%Ll;zJ9vh61|8Gsj%J?1@#MZ)=S#`$kH?G`u=H zpxG9B>TUfx0p$vYX>6rR4ChJ#5IYY>TNb{3%t?+IDB{9slbG}mvI!q9t;h^U5#D*$ znc%Khi3bJT%QB+DZP{#RKzk<3anD^APrZ*R%)os>aJ--#bR0o5twh}aALQS ztHC%U;z%@uLR#Jwxl@ z_`0=BTq@zn7agA8i_k2P>VyTA9XzNT!$0vhNQOPwfDyB-b{#rL_N3X~v4-5oEjm*R z=*SqerLI_p)m^#wv2zC07R2J6ktiQ^)V&)$l#4sD;K8s{kNar4S+_nS2xh#RTKZLo z{m-hEn0wXmc9dlc@20|2TPJD*(GCxOrb%80y{dyr7f zE9$5xXiw%df(O=IOT*od=n0pCp14$H^(;ep;g~CY>Hx(?VT@BHNzfl*pAwa zQceZ?;}XA)7)XzUy>%{&bj8XxBaj;3f7E60{_?1!%n;2uPhvY-G#4z~9p53pkoO(FN>a+Hr% zysu)-)AKGq4da|Te(n?Rm3x0V3Lq;wS*_ytf0=*x^z%<@PK`fl@Qiz3URP7!LEE=f ze9KRTkIo*~7vr8Wap7Ozuk^JX)wWvptl+*87U58##?BC1)gg&va7lt!d}O2+qF9F( z6$0?HaCdRGhTE|q+ z2fV&n2F+LTM>hTYFRsxiH>Jj%J!NU$M>}o)hed5IV(v8~BIpb5fH}^6ng3y->U$aP zc@-b5Dth+ztTe#bXT&WzZ+zSE#L=UPkATO)Xta!;b~kE%B4$dD_BRz@zj5V*Hx2LO zOZBJ5r(M4M+2ZP8Uc2%3$?lpSE(EL4fLhqwjQ?kD-s};%d6Oj-*=rqC=3O`ta_$X< zYnFN}d{Dbu5XwV6+t+|}5oVtd?Qxap-~PdhC6mv>UMeWZm{||MwW;|Z?a;a`#7&I!GdyA49b=YQxkLyvmZ9%-InK?U4hiyPF}+t*_{Y0DIUv(0RN2C} zRy8{S@6#|;I4k8J`D|2Ui^VLHt=HPnAEB9YJv=<~~(3N+- z_}QM&%k5BwWrs-UH7<#n7(V>Z?g52sg*wFWCQ!ZpL+8&)WFozN9f=EX>4fhE$v{v9 zIl6Mo2o1TdRoakh$MNpcG4U*RyKAsqQR2=kft5k{;;UTy^!y35GX2KSe*C?kT2~&0 zuD)edQx0Hqa^wL2vs*?TBwAIBEWk$xr8*qVKxV-``6n?o$02w8z!!n#@V~4hA64@J znGp5?uyAOqE3A8kwXxpflAS6x-@S$yW9R#Ub@_MC7;M_gd;YcVz}rV*+*RUDf+%4A z&+adEkYK#00L%>+AT)e*AY6>b9+$`+J~V?|ZWOO6n4K0belR8wT38{jS%4s-U#i$# zcNtM^RPn7pz5Ceg@%_Nm(dTpg|?NKP|`%np51_X*3#QzQVp~i{4Vq+bapTnh9 zDUpDb=3Nck$Yh1IE5!XG&7>|%E)!CxMHNKgVcSbdNjISaHO(T5E@M!+52}P>;O$i zgJAAlyyd&Ii;HVWmAxvyY13N|yT-u7#-BBL$%+qm_&;w)m2afZVBRVl!(Da z45@|hVd6TPlWau&HEzz3?JmLA<81dDrHXkvA=h1^6x0t<!h$Q+;C5GA?6Eitp~>9hWKD}(x3Iex`_bS&u_}z?kUD@c z40ll!2yg8~M2HEx3c?^}9tybm!q9dQFr58H#UI-6>iySc^fHc`Y6G~(`;W2f5o^fY zWQ?t#*bn(HnMY%gh}p`N67+iHl9km^F5zO-?3@Q{(Z1(GM@>;`X2k^=UyGD*3bia> zPq4s29lOm1Gt9b2jLLvC9(t>y8?-=|LFG8SVsS@UA0 z3ai^Jd6@+bg&o3irL084Pw72#=E4`Y&zM`@4CO>s40k6k6OSpYZipzM%t_{t2vDD~ z{S&EH2I^~ikFYHVKk9*1BpL^(xenCOFm>6dLcc_BaWRNiSqzEpTvlA{1-)`hii;}) z(6_`A)qq3LG*oQ!c7)zuH9+65Y%VED2nMGEPe5x;rzhmKBDhX;!`8A=oC~n>r#VhS zK?v~{vNZiO8`7^RwXGIjusYF*3<}3$<~qLCmNiUTE@o2l}G55V<}m zkFBe8P^^1c6+33`@(Uf&cS-|0ss?ZYb`shw!|%0#k>rMi#2Ez%j0E9`kse3ytwL&w z4dDm`BT*7CLsvKjVurmlCGHwb>b>i4(1a47iudNier2x`)XJ(=Og^lTT4mst=$PzP z9ib&_cxRdGEQpl2m;tlL3 zTK5DWI>VDwbY)X1M9x~?5rSY77izLo+r>t*pp9Z64MCkss03G_{9YugCD~r(b(dhn zLUA^3kEnK6^GBfK^HwRGF76OJ{=~o;tWi~Q;hng!y1zndg4hkiU)7MsmVm;qfVn(+ zZH@~r2@HNvBgE=3_Sc~&wlG^kidi~L(wj3W^|;E{o7ZsnDE7Kn<-vV< z^V}G&Iv17_yPvBKcz|Lz970LR-HCEhgV-@Q8$76yUF|Z=w58NRg<0PZE&vwIT2{pxT_noflfDlpjPG9G%)0I*T4mpAoNk$ z#n1pnik_06UFOXO3Cu>-?z}R0i8nXTTjp+ftpg|z>1|~%2$-oNZ5-Ad8obDFzz-i; zUtur+C_g? zzc|}lS)A7q8JW!;q{yQ?hckynES3%8gMh054uL49ra&1W4I(}eB>|g}27WY$AE2*0 zZw-i+w+g@!7%?E4I~;>At4%RP#gU7sy5yA(Xs1C_2x*c`#7H+(`pVp80E~)B2-di% zppX_44<}%XSLJ~uYuq3$>@K8;M$BCdmJ$Gv4)8(&baxJs??yc>4~8tpo&T>BLgOU% z8Wpk%Q)eSBpsDC3GPnw7O5By+d<^eJK#BMgo0Xu4HGmEl2FZzeM0u>v^Md7o3mhZW zklcV`nhB)4*#;xy9_Ktje30$rka>LsGbt5D-SdMpIn?lsvU zN+PukXL6yf-Q|<2?p}pKR^bZD8;D!W00W?_rXe6RfLDXr3b2EdP%JRCoQ%81XXxHPs#xeOHhGq0 z*Hq`P`iY$LtDjV-TL({_^XC`dFRL+%j?2SFl@QwZWx=0s9*O&aY(w;D<@Dd#Wk-~w zdKCzQt;IFSz?dF-%@tO=(!ZXZ0P6D;!#_b?VLu8eBPzA@8ih9?~Xe%=w7@2^@nDS?RO+Kq0g|H z_q_C3b?|kepA261ZwmD)85@Q{#%^fEop^s)bj7f~hf+KBK5xox_x)q-#sk5M<4l0f zvj@L^!~U1s#{CZC_s*E{#}_}{70@^7{*|mLVMz~sI-n8{Z~o+8k1V=kgp7Lbl-sgp z)T-l*ip}&F;SM=ZYC^9e)9?I8(GLG}0x?Den`OkjRl6`^#U}-iEV^n$Kfu{*(3Dx( z|5&|of1u{LBL-6gsR_=(SN-9+kGJ{$D#IOW=VT0ZHr$4II(m+LiZ0&3PH33vN+7sQ zaQl_zy7Qr6;%2ljQw_KTiKb}7T3TK#LEIg>JKGOv&1AZ=&d{Q2j8FoFsM)U)>nn;1 zau;7UGK|=Bt2gcoG#(c*oX#3=>U8zVO`?r8LQoWjvCIIM>H|1nwAmP zpuxRnClIPEdgal@(=|c^C%f)_?!9mJ`F+Pl2=VhXt$INPRR&r~faX)D&{Fe78^o7b zkTRG&d_nw~my28$b~P^-SJs%$i=L5Dj15si3hZZPUa{pBfd@@crMvf0!&&ptHzv^v z(j?nzsh9;U8rgxXooYBLD=b>RsqDM9^{s}6SMx+jo#)NYgPtQYk>ISvbeh^PugdizY4N&qy=qkn z8ed;ORRqlMa;%bH* zUe@&T;4Aas@U`cphejZrj?ZiehjzU@iI9e0$P;%iv>zWZYIzM{1U);3JGuRM)HGaw^#|KCj1JhI;X{t`Q&AzFj@ksP^(sb{oDFRWs4kO zRkKR)!q~!|R{!P^%+w5bGJ&|wX53foF8yr~=!7iZOvteEO`nAyd#rS$X1#{;(I7g) zx?G;&PC@++?$7dpmA`G0gQ|x}zLiaBAA${|#Tcp>N>^rC@l}Y-yHUwYa3yz*>6L!_ zG~xlr{6jQ(-X0D7!-EHr}~OhU;>9TqJ4rV(Lr*Gu&_VM|8Gf8ZoSMk=|?Yf}_zTWxAgf8sbWHXvnJpsU%G*+4fs!>fSDK5QBr;{gB4M z@}MrkrA`_o&Vj+PPC@rZ_lwvc+W%W8DuK?B*dWP<-v(LCXA!}wNmGu^Ru?RMVvBjso)hSH%UR?CXf5&G8PVL2=h zAplF|He|W1ki=#yyxX!7cK40#-#A%a5;I|J+bHj-*wJGyYMh*K$)tqo_o9X}E0CtW-arzc$EnH)P|+*t3Zwo&#m_}Vx*e!_)gMva@u4wqash8-@P za7n{t$3>$?jk&maa_l7&E^Ha)A7#hzmmI-^dvs*KjcG|Sa)kyr+#u?EW%wxzoI#|O z-K^wHK9V^^$$5~VBrFG_vIE?5vFH=qcj)Eyvtwr6)OKU*jWIXPYM32=+pL>DELvag z*=pZhw(i6F_hXAoerVhpzj@;q9~G5sYTg>VXD0{$DQ`t~%-&|GOirmm&zh}#in&uFe#ae#Z}EDJ*oPqM@VoHTfF}XIkRo?}b~Y5y&K?G^ zSNSR%$V2dee6AZob4*z-7P5hR{n8i{^*M7Fwnshat=&S@e?HvS9`)8k)q?uAgKb88 z)DKs0tuK%Hxvk#Byh+8h{Va%Ytv=iiai_N!99hG)J1A6f9`J;DDTYLyidEA};82DO z`N+}mkzJgdt-!&2xbz0xNeqj&26W^4YB4Ua!OwU}XCyw^poZ7%5<=t5d>kIKk=!*IsLbKu;m7R@h zUM_G$V9m(1YYEL`HYi5}zlsinau4&K3y%UynLR=Z(!%g#jT;43C^A(8G)3T^TM{9_ zf_a(%^A;|SA^`3dhe#hOcWmBL=LeUgMBicfYbrMTh|uQkdt2(m!r!dy-umjzN1zmY z>jO~)2-NT0>MakTeRaJTH)EROe^B)V+(a729+FQAfbV`FfJX?BF0i?=xM;XL!I40G z*%pO4#`a!{4rCd~22_gZdIS3Nh4wLdU^!PJu`2QgS$G6{gTBC=J;>( z-R77*Xa3?P?eMpI5C6Qmsob%B?-2uBjwV3JXxP0?2vD)79-Owczgang-kR-|%^=&( z!(Jmo0*B!}ymNC~c@R>wy~YcR5k&+7&sQa+8B9kKE45{!0+PUy(u1I6mk%2Z-w3?X z8e|}=aTc+OG(?n#j?^a>?pWH(N9hh5o+{m;Vo(4Q(wPKPUKou$u5!neAnnptKrOK^ zf+_@W^OF|y7A|Rsn87CH2(;F2uWTuIRBYMX0PRljnT8OTyoYyhsR)3(jx9S6dV>*a zp!{Yu?%PqZxfT7k?`ts*n^pmZG^1tT_6lEls61|S#g2WAFqKjC(DKj70lAnPh3ss% zH=z2VPym}qg)f2B*OVb)^X9JtJsPm6jYX)g&~0yJHjGCZ$~*ZiM)pKcoeDw+a9Vo6 zFsjO2Py=BYWlZ)Du)e`XaZs%o6w1!^;4BTUHf)K-Bo z+xOH5!0)h>fG~#t@a}B^usm*a^}!Y+)Q&PCfAjwBunKV%+iRKvp$KW>LV>25?G=8~ zregd4W`8J}Hq;DMc|idL@9}U7*@#A9_-jJ$I2`8HzysLx!C`#lHKIbsKsm?lLx0DK?o88eqH0|II094Ab~7+A{rw>4lPXtLFUh$Gkf-J zq1)8#xHYnuF_L#FgJs>G1Lsb=@iZIzot zn!-_su?2CEcj$`;5Rcx=UDK5cJ zs1@4~qB*?9mATnI)vW{#OE3nmK^V|fNL(BXnG6-jl$804xkd%57uz6ss${*8=HODb zBu>*t-4;K4&fNJ67cV&!5tjxP7xH=Pc5ee+w(Qz}7%~w>7vdH49NM?Dl4Ob7zUNSj zKZF{YNtFiG&G0rHsNM#uRc_z?OOxNgRUKe7sHBkLZ~A5TcJ$pGx2^g>Lz{t2(6qBF zvA{!fux2lQhK)R|1E7w@ixw_epysOu_JxZUFF6rKR)H)8C{EDXI@R8Plf$d%gsw`PwC+1{mlBY=DpnYe}#_yKo2!b8kOC5Xz$Oysvz3$kG8)S2@Wl_FL2#(UGQ4pwf5_8 zn$zAN*h9g}e>bg+{j}mxdl;Jcuk)?+ue87OW3*oc4F28UtZiOtU-fBS*wz7thK=vP z>022@`%fy`B6cnchS^tNIw?5OH_<-j@*CU309U*Eh8fM%V;^{LM|&V@zJ1&`-9Ozv z>y2H_?FiAj;rYeh=?Pa)pFU&8eHCGU1VE~vUvj-~dJui?d9UeMKpK{Yme_BeIATa} zuy1hOu(4Oe;vI{SacTVGdAD3WX=FwK zaK#TDHvY2f<}Pe%2UzX8{Cmbbnr!i>TyXQF-};TFcA)+Ek2|hBTR`hHVs`G@nh0nu zu;PuY@3?G0*CtzB-y5D-U4bk>L+4Qmf&Hb=&KlU&LGa=eonzduZ>w(#Yoi5U)6)1Q zi|5~R)z}Q*U@zdyoO08g#Y;R9_`I-rftF2AUEQy9%n@5cOqW3~9rXAOOkl}%8?9oS zXXV7RJI4{u#Fzx<@MYh&_zjfCOoQOXHpjL@+ubL1YP2Odx@5TDu4xOw0gLeg9=`go zpBdl9;YIiOgznd`-O?Js-4>>CjDmIX+*_`ha={Sa;MT!$LoT}d#@iM~fl5FE^*_8i zZ$uYIgDpPpV$Zq!g?uw&Gu%dVN-4(Mc~rQ-QHV@{2;+2Xqnf*y@I|K!+^EiQS=pIagu;(Is(6lg;Kx>T&X&`&yzfYkO+&@4CbRvngx73syKPek@rr5SS(QNT2xj@i6N$ zf9kNIg9i`E95MRJ1&fy~F_y$HUUA{*?qsfm4VT^o<8=LkA0!! z{a^ffMBlhrV0zi#cC|yzzIW}s?!Y?slnWNWvdah=A;-FhruXj-1Ty~iE#x!8v)JMV zgG07>d&=3<3pT?&#~uFL+C#-2U%_0o+lk z4DXibZyVW{)1MHx;TK;)+qHD5Lj1dM{v6kJ(=NK;1lWy!r0~Z&MB1$fwtoBZtJif; zJOO?Q3qJc1=@Bhmebu-BdG*1}4l#7}y72F1`}xu(<-afg=?ZGs@fdj0r0lg@ zTMg6}jg+RET^kD@nwB2lA)1}Ec#gdE`b9zFxOk51#_O-Ya>B@tag4q4gIzw=rFPxg zciw*6)e~CM5eMy^o@fnV7fH}t`R?0qzxu=l$H6aAI2eECbzk|gf?53)+C4P$l%sL$ zq=mDe>vi18Z}X>AZ}{--x1X9hFyS{Nw&429CX5?5W<!R`F&q{z{`!&Q` zYVs$IA2%lBq+dg9$NP7TA3tXB=`b+unbsb$=9KrduNgl+^YreV{P=4ZAsjs zc{gW`&GdC>OvoC(lE<~nY=bY$j`whoa=25*!y zTK0VO(B#t+0b)n2=|oLZhOenK$A0C2o-xP4re|1@Fru%e;pH*EKPl;Ggt|xcNGZSP z=MBpT#5xlYw{*mxb{H+3drRz$aYI^v1)soy(r0fv%|Refh!3*;op0U{J1{BMd#tEM zqvLPfSDD=<&W`Y?z4o+2r+M#&*RtYb?3njAVKZxbR?NkWF@}vFKl%h7D@mBt_}ZLH z2O)+@I(P1vZZta`cx2&}zjl4@^nr<~(Bdw?yLjfA$1xAxqS$rt>zDs9#sP00f9A-G zhr@@T0L!0Vyz8p7Z6RAy&#{w+{<{ByC@x&Q_?qz}0)ri6ufBT9n2ya~{FNW<2>7aQ zFl=37V(pGwD;_w#>k08}X>0iL?}KbMWs8ropFZKK4=z0po?XIt8or8uOa}$yW4mSj z>B;3FN_#ZBShD$AO~CtB)|nw&3L>?0{_@PCQHV=AupeRhympT3n#mVrh6bk$$s9HL zhHJAf95Q%t2k{j!U0=4A?x;(m^Y_CZJNV@9yPpu#`tRO)^!if-)9$~Y;(n*}$`fI_ zuIBxRZyb^svL(cxdf{F9ul_mhXjH>;n_uzmYxB~3AcRSY>z01)8}Hn6apzyfb;=Ca z^a-Pe4pD=<49OgQ$&A}>nl|nP$WB}R?yG;8*cZt57&`rq5B$$^z7EAV@zK4nFS)dT ziXfXd^G~mAEWhSB$oA1}J>!~BzrSnz04D@JCjR0-t^EAM-2NRP+xMowfARA5=ch2w zNa@!9x~ISS@-LSl%{Vb*FSz8&>!yy#7(5ur4jnz^hPew}Cq#D2tAEd)a8f5Ad-j}{ zzWXKgE6Cpe{h!C4p5hQ>r@m3TyXFMQ#{F*EyB|zWmCPfq`=7S#-LtMkWKW)+v-0k= zt`5Y`2`K|^cynj{rrZ-C+gV3p!!DdOb=;89;BG@M7`DG}0pBUM=>5paggC@oINIYxgLtE=Zp5r2$B%HOUX8hp}sAy8RvxZ->TB)Y5 zkHxjKR@m+%W-Pp}R(rwfV6V;F@G6L_;$(GmOFAGA_C1raADICq}hX z&+aJ*Vq+7BJpTE%LnytT7}c1reY!Ah>MY2pbHinC)wXEH6!T#->hmYW z#?gD^ogeN*TzNccw2+BUNxS6bT3ahpr4!1bFbB9?Fn*f-Mx=PZic9B7*{^(E|Esv1 zb?2KUG1dMPm2F+(#$!(uPG+~qqVXAE0n zLbsE8_fEg(vl^sbCtwa_Jtn1BsJDH}$Mr~@PsE>)EzzFXqj&E!hCF!Ce|#R9F5aHl z)!DoEMR#Cb6Ss<-kV~e2&m2AR@@dnqxoPgN;*~aY$pa5O_R-Gfqwum;F58q@I_cz? zc<=oWJowT!uhB7HI(mui+JDvq4?MD>*mGjMx(u9l#{&;M|H1a(jMuPnQ)k}jnmuok z!KIl+^KO_rw&MUTap>}A)_lHcH+5(nJ$;L0C7sEPy2=G|Ysbj^v1D4pW6o_KTpo>sU7 zl!%fKoDyeStg@9%2H~+flvSVr}CYD{!o$o{fP8$K0Rz4q45_LxvdIUuT>_U@NGRVjFV zIDc?l>~ZiiOP4XRj`N<_*aW<4?>fDUJ?3bRzMRSaMjeC=?IsYUEF8wCn`*9WaiACzN zj`I9JTzWdNP95+1ga6)S_i)zWJO6IPRWBTBi_~S~{BO^_^xSS}*MH8P_Zas&?)~HK zSN8$=PQKupKdw7oSvGF*ZP#Bpad_L{mcfn-FQ4g}-wvC^knh0ff1NonF$T*SF+Jw} zyJS~OI~?M@zx?q2!d{)cwl-TrT+cC2d|uVqel4T!hYz2f5R3i^F}=qvTlqs97GHgA#pL8cf9z;-s8a-zhvR;8!jJ(LJt;*h76r_-K_bGqrmiHNu;Ib z)B7g&hy#>~XFR#>Kob@sqLzo^gRO`6{5`XmK$(>8`lP1Ghy8gG^2U1)?<$>@5{DI+ z*o5?3UZ^-6j9zgGHSYT8q09u79`|h&R<~U{8O@FUyx6;;jFmJ*+PAnhB zbsci^iV|!!46n5LcC22Q**g)X8LYH9l20G==Z!VTuC#II(xUmd%@{XamMG&hM`gL@ zE?V3kKyOXOy2S|qaOi@99}gN>A`8prdhA~c18B6=R=j@MDG35#*8vNQcQm#g3m}%0Z@ui|vB5FEG4}D3uUp)1 zdyzfRQZTYjZ;gfr zOS#)}t{CYX8bpViUv4~hDHluY^KO_CxYBo}efqVxwqH`V8-cH%XnG{}jnV_{;i%v7 zj_(owBlf?3QG*|-wCI9mZQquUo^O7{p8MLK=wPjvu>N;9tKCq*#Avw^M=@p{aCyXGYISZ-ukV+4gL-GZ})hxxh@Kb;GtdLdp6+5 zk2W_&t?#$&`u-c=h9KIP?++Xc#L+t~thngcc3N2LrAPO-7Ht2w|A}|1{4f3V9;E-3 zpZ{w+o&HyT{{J99LniFKYR^^iS6*@XAMbtO@z$qoPa1dy@d}y8ZRU61Q}K`g<^H?x zeIU0PXZ%k&o_y-br=DW#LwJRriqF0Op1c11=o10?W_yyK2k|o45=}!mO31nEuDc(` zH+C~{N=aiG3PS{*N|ZtQ7J8Bs>)R8wsKq84DURe6{Do3%cqJsK@JmW^5MS{nnO{;u zxDqd4ctPQtN>(W`$+%#{3n@mjk z2#@rQ;ba^=lpGM?0?7_sU=uxOFvZTV0r`qU4Udr=C!?WRqKw3E28N173quAX^wK#w z*)OMwd@vv&ui4zd zu^%rVUK}D>cVY+p5A}=1yCLtPes+#x^o=(!8fc!vWBi%_Lzuwmmw+?o)G>W=hF}Hz z#ha}{{epcJx+-&KLZfG}=CPr*eud`@VO|+nCPH5sxSk&oIyi=B4oXW4rQ7gQX}0uG zT16z9Ihm}7VN3jP zLn9?a#G-o$6S1{Qv-4_anM5~~VHK_f@Jb{s1VE-Y(j79j^%=rAHh@Mz1olK3LN_N$ z2Bze6L?k9nT89WSp_E}mX>kHwdH^kCkO+O^hi9Iv(d?>0;JErP0N_bBgVP%6c1|1O zOy;|h-ia+aw0R11$4g(f7Xsp2AT3E+5ka0;LKV_6nBK!0fS>04#5RN}Y-xVZNp11XR6?u8Ql%$x zJQ>td5|e1As1rBJj23EsMu?L-eAv0{O?al<^Z4JNdFJUqUy2zMd2-0u`G0?;%O584 zqCmn)LRyGKmI#f>t&j+27Y&FEryG-5rUU>gKfY0-`JbF8V+j_KqMlLW+i-?wMN-m4 zBT{5Q4FXz(ARAN`1AUBW2{WZxx27QwLU6bQnG;xW213C(p`&OTNQ;m|4YLnIqfmO% zuxa;yxc=MkzAb%!mROqf(bHFK{M_-z4d`P*F7(x$7OC?J+fB-lKcqY-3~_!9K3S(v z5ogMH&=eL84Yh_?ks4Y)_$d_BssdwW;UbW75V@>{LWqnB1jrO=DOi%^dH{-(B@E<_ zHa}rpBE*OtmU%7>mt#uqXH7;Z)HSgG4h$n>PFnnt(Gs(LnZ^=kNB?OoDTWqbHF=1o z$hja3^vD3eATNdzvv4MMBXI(0U1h+iw*b}9{El`)ENS1(Y81vbkk$$3?jr@lj%_c6AS$bq<5bA&JLgV@cvy}*Ud#M z+Jj4$e5AaNoy*Wo{Lsa-?tS`ckYp^1c(-RK6|M|m4j~{=>_svGrp3UEU@%GIjlY^Hm{+N`x-C{{v z+D*@{3mj1UlmC6yh=Kjn`wz&x`h{<+0tb?}es$02!KD0v^M{W!#&;e!e%yt_2M-V& zEZs2D>Al&A60QxBmgyicq;umX{813aAXqfi#v2G|o+ro{Xs)pmX|*gTof!wUJOsuR zJx%MWJDFWM5&nB6gotu=5yGfprw%%A=KZf16_wQoLjIP%X_VL;%35z|^ts{+{o-?V+PYz`zT%50Ig;p^y05^2|_wK<40T6QSw=u0|@FlxU~ zXRPf!q4AqitqC2WMf|YLK|_|jS?yI_js16$a71F#5=aM#K#0Xc&w8=g*nDQi*8RSa z@!9ez>Eq|DuJs0v?BBY1^R8M?sCmcVt{ygMa z!9MCxOn)_vE5nFnHqyQDsd2O%t+vqtbk$LqDI|(92Z(D~4jqHgP>2n|C+DZKChC## zPC0^I#-E-GN1{W)D64{iZqU#rZ~jcu9JteLnm&n&6SH%fC@T1W)of$=nRos9-*qZf z_fz&cOWxk*H;(-9@B5c6U-8jS6>R$Y*~>4u<++L@h97yxksqJCbr|R5A8j0LB#s0M zf=iwW3y<-&68Clw18YHJk|0qA;TuPZj^DIF)ue&t(fH!C4Fn-!s8onF(NzN!VTerv zK$EHpO??>J78SMh96oH&c~{?^zh?D@gSdh1r!UvM`|@>1*%zo0ra7O(51Tl1?wq-E z7c6`FvueMu>8XL)>kb&+oh$FUeBAh(9xQJ5`F6ZBbMlIBnnK3T_d{!X{-@e+G;Dl& ze1E}JKs2!6QhjM@aNbaK#=e*bCJMz@PKdn39KltUHlg{ryVC3b`S05pbt}XS4jKHe# zp^;rKd$$<|?9*xI2oQiqn^R$0B&HEzA`3K@hMBYBt4??5sSKgrj_Dz$A5kfdUm|^$kO@q?|J(3`Zkc} zn(HiF#X<3XGnpg-;5E6ImH;qPV&ehr# zC=nT0pRRP<6qob?<8FMd#-oCv^O|@65&%`snZL5qZ+H)E`mnI@vn>ae^6hwg=JfwI z`a_`|@4fT(lS`&tv3mb6?_D-97*2@*moT3LQi-$%=y=oyVW3K-C+G?34ag1=55Xm3 zJxr+p!!*Z$K0C2FiKv|yDeKn>0rOinVG>7u5DUlQCGMjc)Fh3vINh0IOQ&1EIYPov zH+485@-h)_TP8h!jQj1MTKz_AQ&Y3Y)7TmUY0@upy}Y?0&~j)`)vf~#Edhf9GiLGY z)h)jI>Z)C3pS<+w6OZ0|bEdX~T3jV%(1--n$bACLKmBHE5>IHZ>ug!03j}CP16o6L zV9juw^ku@P%*;pEHmoo~tiK+By*;8ytTs??(G?6yumFgtQa7j)V8dmLFjPW+n!^l$ zZ^xBT+9|`QJ+sdf^3?oPQnLP=ZB0Q%vZN1P^xEbltwvj4FCw8<3e3P^vkS|%{o)N6 zZ4KN1`_!#t2KLA7M3E4XqfrrUP%JF{wg5mN(3pseF%D{OYc5;zL5i#LVIE>UZM5Wd?&5KmI$>AamJ=3 z!a-v;ijyuP3AfYJ$(wMpg(FILL~M|C4-&GObfGS5nMcm8ymm?rL!FBkul9Ru9~lCV zp3r~%f;W$VEJoVz`wtm@!Kjg=MqV)Dt`Dm~mYLJu{Qie$#tpq-{y#tb=}^dM+55&6 zxH@VQ-82&<0a7P>C?!z}w2Z!ZJ zhCdM!wVEc0Lgc{+k@z4g81BX}hG3@6`WmM9!K*QVwq$WoBsit3C6`2l2_T8T@y$8o z;GWK%@!UqQNXofaExGUBTPB^CmNqnKJ6bE)`hKt)sAr*2oRwM-9xw>rpLw^VsA!DhAwi1=fnZ8>xv=f zwEO@mu2}#PHmk!@*by$VJK&M?5h3bjx~sJGTS+szD`Bh5ZsrlU(=m*>c+q>-9Ye4)=! zq0g^4$FvlhAKJf|WqCpsfCx~fL^6WmEKn?pMotS0k0Ua{Zx)4h9ko^PqX9RK5v?!I zF|QTm8B*yalmsNb7*1(sakyZVdc{GSq*J2k*Mp!8sV6Edgs~$k#@E5=!>9ed`bem; z>eH1g-*~G8Kiwf_dBjsc9ctYA<=ZP)eo(sC@E=-x@5IYr-`*N%`RR?&%C3bwgCWn3 ze@*JIsf}?61uc!08I!@L(gAt_)Fxbq+hJW&$Nt2JB4$aKcx*J+WMhA}zz3-tlya8P zK;F;`mWO}1n4p{L;Ye38abmq>Jj-#QIWAGJB2v`V3VPDDExO7qMggJr?mh9mk;^~c zj$M9+5lr@beG>Gf4}a{tL!nS8*cG)yqqgkPX~V|fvwDvgXM*@G5pVVCyGIjBqCmX; z_>2UEI8CYG;)-TB4y{m5i-$If7(k~GH5j>%wycl6c^Qg$U-w zn)}`5boh-2qAD~Sq#@~tkMPnJM_{yTmSnXN7PF+g(ne8C`QqAwOpS?!J}7qTnKU>Q z>j-sDV=&0}Y13a__uZ?DF44W&AuavF8=l*=q1$Sg9xgrYybJ#D*5{kbj7?oWd$sVJ zZ`R$3m}kt5`Rl*MnX*kAzkKkL4CH77Cg1%^sj;b3*``fjy>jep z9XopDU>4o_54~WlF)r~!+;n{&g$-OjXUJGI3XQX0IC|(gt=j2QIxwG+-b=s}m@K#m z9_4}PiHOnK(6bOj9@FaZGps4pPLhNXTml>NzZopCsi}AEti6^w8K26jMc9-$T$3qi zqjdxy9T(cM(trzM+50movKC!TTBd_sdQ}8b9jfT~OG7&X2tM}*^!;ftSc~efFZZW% zh*E27K$r<1@nVtA%pWEB@u8!3vpTaRpT+1U3WfMa2@x$JiOj_}qGHt?0J#u}cx&Hm zC3EI!(hKXPGOYO#u!5zCh+s1SGVyRU5M*hU1KE4!cd=NCLK8xmt3s>k#vJHCQC_aX)S~w zl7mK=lie7w%aOSVY$R?F z@e_Qt+*8DLo{g>q7j4BD3d1d{Ab~9j+D;?dOmHYTt=gG~Ar&Ax3pgg3^!5gY;8Chq z#8L!;A)2LuJT}9E2u%_o7Xn%+O$Ic_Lw~Z(Oi+c;k)0#djBuQ&l_z53$P1E>_E9@g z;cQQn0GbSX7EHiYl`patEt)Z_h!AOoW2@Xro{;F~fEG@aE>j?^1wWmBi}FC6nO?B3 zxt#*s!WS_yWJMw;5w@^RgeF+dCQW!!EIgW6`0>+P2W4OW*HCG!wH|OnEdiFs>XcZF zX!wv+3QF{9S~76Vbf%nGze15kSJH%8vF0Z!tb|M&3&F!eh*0T2>q8?TN=WXR!lT<; z*4tdm()wiS5`cI>lw8(HsU|gf$czEIHT0O8t|k>V6{6&eycOdjjM1eNa$9qY z2x@q>sn?PxBU43$iV<&V4W)t73kcla5HX_KVY3=5V@N}hIxV{#Q`0m-^OGipmt^%5 z(s7-56-#Wy4Di@(;A@Q?Y}1K@GAE3=IkmGV7&C}~t)QYRHUoy&32qpC8USq11>q)H1iL(Z5?r#(lGk~5t- zRRx(CSQR?6o{j3BuX3=XCbOQy}z_9N>Y9dCt7{ z{k!Kmv+$730z8t_>8z3o@blZ~izm(&^zcIcuhrs$lP zql6qFC$Po5c+4(l#3y=^10+=Yp52!_GfRPgp<3>AdB_*`#LUtYpXljw=8z0|?R&;l zWg1R9h*xenZCN2_oQrI%!~MGQ8BjLx-JS`?MfZDAg$itFlw4I%PzqY2e_a6{18V1o z4;SsF7$myKg9>*`0ffItVf>)Nt%NvN2k7gfFFcRu6WKCB!R1*VFMl#T&v3?8sVu`8 zlU2osZ)fJ<0j-5jJp9;R2wGPwn+IYFfG`|H4A=4CMO=RZvuRm;PQ_&63Ai!Kvsyt+ zJYYgOa>zU2Q3%L9nRu{ILZPz`#Le>Tz@s!VeS86g23KUPy2w~BsRR#5tvt>G+zkdg z$>Vjur%+URIac9zbGDpJ-21Fz3NjxK1A@+I2B~zGvU7ox;}qgip9PtCdTFV%d71`@u8^~b3*8Excv5=kV?!vDs7lxdjvI;S5VV=`f6;P*CVTLSF%N&sc zh>`J7XbfvBHJm;19TS(M*>Zwo_DhbO$Z;+&j3NPW!*eT_XBK%fp$LVr4>`+KL8b?f zV^oo_l3;VKD%v4CDV zVJINUNdYI==3EX|^P3(l2jEH*>UjYkBnqpl;y8dS3s1Hos#eb!o{7_E-U>4zUpWP9 z0xJL$2QWGdPbBUI)e)qG6a>R1pa8N?(zYlQW+sT|-trT&la+_|1(|qyD5+3Ic)L=0 z1}{VP^8g4Th#syGVr;hIsIh2`=LTVfIvP2TGf&z|*Ur(WqLIKfpc(Pz3&Y^K zHdUEmc`t&^VT*+Lm^cgEzzIB=0Zq}Y$XSFPaCiqrp=mBaPa0r8V3w!#QZu0dYTU0* z(;MT^rvUIgSPK$aW`@o}kGf+3X;*}a2>^R0MViQ&qu1DQecPBa*qc!sbO&mZop4@yDSIy}eN2?G}|5EVdOx)eG~J<9=y zFu?`I?&ryLsUp18^2|E0x(;)&30yZv?IjW=VuLp27(3iEi9O9T(I}i$n1$Y?8Y~3_ z*;zzm1iNMP&~pPRT!xWCGk~1wT<(H;Cc=GHmBXa~)9&)g?yxijBMWj8?|~!4+|&}6 z(*@&F2)rpJHWB+Q}xm_r%_Jw*@fCwJ%uTpRc7P5FX*%Os>2X# zXQ4E$i*5?H5m4~9Rd}#6jz6c{s6y*_o&pVDiW(M|(3WC}wyqq20c52y&*3=I7@-@y zM-DJDh27(HQP=4&auQ+TVbCF>;wUJp&OA@Ye&Fn|A1H8vUznbp1Ur`((tnx$ssMgO z{24qjxd~nsEqCUC)zamC8!P0V4>fTv`B&LDSqh?9k*ZEj33JPeeN5 z1>*|f;gdk;`0}F6I?x!vnOF6wgp%G5&&VWMh%8>wDD{R>0+`fXAq8zD9RSI}APXUl zkgb3k4Jvvb(N$yb_hT5e!MBGG&!2$czAq1%02c^IMq z!mi0oqiJFQHkm##iNKopMsRvjIT6PQ{s{aub7|mRE~HikNGXymhXZ#7-_)@;=@IrO zIZ#bRH;4>Cbpi6Uu&pE4Tk!?<#s4^@Jby!l|Esol9g3g=gO*6E{s^1 zgJ}(QTG;hTEJC&AnL<-LKp%;afeIA%bcCL;jtFTzD$7+zXQOmr31eY7%OnvcA%iP| zQoia6S#!aYGem`UsREtwI_Qf$F;3`Ky5)sv=-{SKD7>LZch>GRnVrH8?t?I+9#jaYAQGS9 zjOAA393-LrxvwRou+@FuuB9$ZXm_NKBcpVD?IjhbGXTQO{=nXwnnR%AYQ<{gQ2A({| zNNc$(Ix+nhlR3zXT#tpdfWNVf3x2+Xy`VDqQL0Sl83paTqLu*e@iKaXZ=EbHRs}Yk z6orty1Pnf^rx}X{5#vx)a|$iJQHVDzIY36hh{_Y)Hy^|`BOpY8AZaEnWjIW-QF@>) zz!egmv)uLfc8tXnP%{hKpTeWiJ$Vp&m*?p74hD0}SF{_TW9}avu9uzJ|g{q)WRRLgwHNnX$IxuJ^E+87iV^m2<%muxyD=31<{2%PS2Y6Lg z+BUpTNu?J9h`mHP6lpiX|{t-VhP3G!a=cm3~oUEizM=IrdV_F7N9pJzR5?R|n{ zZ4y_li32PnOGCUwodr%JeGkCJ>`l^+Q&h#fj$(NNHYG)PEk*~2+0*>kLZF>ihtE9D`4sZ20~LwFQ#{v)icEwZ=7j$ zrOK4Q7G0&r&|!!c)isI@;RIqnzR??J#l(x1!%o0IOowEVCgHe7gKx$i+EydcNxFU<6XIhX{$QoSVLQ;?e_LNG5 zw4^n{haiGt5X-t2OfHmI##_(@phm1dP51s$ovkV zBa7mYr)ka1=XLjamHxW67Tpupi~%lyVX>fihUL-NiZK!-?ic6L%HGU#}pP36=s0Un~snmMX8l|+(+H98qv z4v0v=BfxB9z9M2RiP(nfihl!s%rB^XP>3ZNsb2(K3zrb|UQrhn8%!Iq_E3zA&*);< z!~{&5s^b*m4z!L;zFDBgo{YiGNcsy@2`3%ny&)_N1=Y~M3e32hvqO=5O0U`@(Q6j_ z^iE94tMi41WNi)ZeM>~Z9pDR9fx9=$`gZqXq=>{2*;N z$8WJR#6ym;Nc-`(Y>AS){FMHLhzMOE0$OR4Ty#OjvX@Gm10@gSU67=d`9*&_R6FFYdbMNCOqM>7L8JJ}TV;K=mr<>U*T_-{v<{eCGt(=s;slUI6xKXB`Q)({ z!U`|mIOLjTcP<#LfiRL~v{?g~KK?2M@|9uFWpP`YSka~({{a?POL?FuTn$q}x=&k% zp#YpwS4{>5m~}`|tPP4nnkGuE3}rKuvGUjht>py_NkB*P#H4arJC)KRRHj$%6W;J2Uvi@k##qBVNJiX<`;_#~1R zOoq-tEVqabAeaR!*=5h^^DDJHL4mQ<1D(oGpg&|!4?$8#nW;68;?WGvKVY% zNM2Ki{S`2PGICMH^`K%0PY=ml7rarO0Ziry6bCT5SDTnDAz4-6Au2#9%uChXgQ#pE z6k)kb5SA4}c>#g+JNy+WqccjsT3CZe2`Pe~At)?mMHKF$ z*Ygw;=*=sx4tB+9C3I)3|Ed)lidl^q2D@+w0&#=_V#VWY!h*%g%F_s|$(X}!#7ZHs zatnTvnMGryW^xw`7W>rPr4`@>aSV*M1$YYYV$qI)9z}Zm2XB+7VSq<~lDu^Z03Q2; z%K0EW0r6d%VuAB>e` z0uHXQE`KJ102Miu#1uUd`m4;4$RQSK3(4Tx3b|0L_{*hFBB_Ma){7(b)eV6gC4cz3 zSwJu#b+`Oi-G>Pmt~8)r4cJWHSjTl^cth~!NZKJ3!kf|2F8*^$igcr4V^-K$!p2(U zveL-j&`YJ3~#cT#rQkxm5Wx1FtFJm#4(-h1{Hlm0FeAWy6*l1;318T^G zzzFW}223b1C-KE~=Zu8?bIBDEgK7gqVGH+jH)$Z2nUGGfXOrzV6G476PIzBk;#S8RDy%C(5$-i8B764 z_t9XSil;5u{Iw>bUUIb7;D`nQK+%_95u}jisJNowMk0}%M0Ai?OTFO$H-Uwa%k*n- zY&pMB!3XIJno4=dA-d`T4DxWO(Y)d^DYDhYftK=bh5ANsA>1HKfg#rrm$8>l?SuOc zGbY$5hHwNY4a`_MLtXLE<1-{1iSI9~UP4pM+L2pljsBlvj5rTRq}ikv*C zki&g4Di+DyABi56&dwdlYQ-1YB?O3M%-HpYv;r=kQBJC}fZbsXmR;gDf-9VpE4Ub# zVq1*R7-WhWpeb&(OD(5Dn(R`ip3A97#9;IRBjjR{k?bS8Gjz&m)Lq}91Y%SGl1Y6h zgG{k;3)XsDz=A+N%E^=7%9w&NXIdTCBFzlhrrZvJ6kZQo8{&Xom}>hFYET?NX3gBn z*w@ER2B-xm)7@cVP!e}wM5rwo9&r)0f{8SsLoY+f-GjscqYR;3zQ<}=_du3NbVe<8 zW5P_VCU-DKWWEO%k~4{b%fmi_7Lgm|5(dj-0O%N|*=qDmeF8vr_{0^-P~XNidLj?E zLvpuKx*i;o&MudMA#tYl(o4AY30sQf)+bnjG-HU6o{BkuzOxE9hve|x7$R9(*ocN| zKzK#MOi?D6L-dxM(i;omdT+`ribQY96MG>shO`*&VPqA8^HL=HOsNCeI=-WIFndFi z%gj{YClaBmAIL$BY}}}N==&besCp2dXwX;$KThgUK}EXa5jHiXUM$fk5e7Ob`+`}k z>)5=tItFa(wU>bOAy1#U9QK4hK_j4&A2RL6Iu+KlS(uX7xyKZyCjCHReqhDYF9roJ z>k(UR3!|e3a(DN{mjsq2_nE+YVNB9U zfpf^FB`H8*?$W{RPttVd#RNTrb?+NU&kya~f z3p3Fy2Dvjv;~{Zh)^6i^vk22_+YTcO4c;oRBO|Vii`GN&hJ+01)oaAgz}7m&;n$)s zDjZTQgl}n_FlAz!lDFDUN!(mZ%#@%`{|OXHlC9vM*}TlaJ0Sx%>L&0yIZ*{V1i+I! zaJZ96ZVzP?rxtN2_y-sv2x6;D=_p2!>ZA z@z`NQ{2}n67N^YO3cZY>&k_tUlbHgoNL{DQU}`e~C!PtD_(tzi4T7b@y znVGUUB_ll{gPS!l;^j1C7$iFjZtcOk4C0@W*`quH&Bbt@pawVGP4V>5uX3^R^}d9y6lxq z7@?W4re@?Ru)QyJ+Fuhf{$oFVnzd%xjl-8XbOjWN^B8OO?fu-b87O647<{0BkGk+c zjsx1TK!BkDT}<6oxb=yVMw|`L<#{9TGmad+Y*3g>3iDrIV+V!xaa#Wn3Ika%Zo}4mvMUXQ;HCf${?Ds8P-KrFz7x!4 z$y!Dh z$#B`)f9uqJ0qRQgU;pFsn-V}>^p)f9SpBDeY~72Wn=-I3So$UKs@VZyTgp>y>sJ#{ zu3#87VZRX&KC)&_iuwj0q?GO`dcQwtDVEKE9;^H%@q-K~2a`*kXx5(nkXD@W(5 zSTsWP@qlG`c*(EjlwdFpx24 zi(9)ItGn{q#}3%mL}BsCNR*G-yS*zTR5EvBA%bD29{167H6DFL63kpZuK4SA@4w=> ze25aXV?{)5>0$Yv4?*(b9UunxAGCM>A%W-MK!7-oolnWwCxO%f&WL#}_aLE|x23&1 zA$uyH89cb=S{j~y#GME!xD#Jh8h3s!A|D@<{KxlxsQWQQQQF3>sG4DqHn8J(LNSK| z{v^w|jvPq!gS~ahhUh*Q+FVauWdEBVSog)RzVcRG9Tjn$YcMM~4$DXKup0Rnw+qRo zNyq`|LRm;(L!06vFPOOKnT$^}#&Hy})`MpdDas8SkmO){ALaoT?4jAnJ-O`VGZE=3 z|L~<{Q!hh5mrP#zr%h$fW331>yke7xJX-kohi@Cwt1&LJ*Rb0k-SBmFZ98pqMP$=2 zA3VP}@gnql#k7={KicJPYSs3D+_Qq`Mp%SHg&I3Uw91n*kHJ?mdBq3H0w~s@MY$w6 zM@0G$eVO(9TLz-zKG)8FBB%JIr&Y(5vQCN_1nvUva-}rk1p8ep`#sLJj+u^+`TY*r z>3R`)`lsBd?;Y2-Aub~R`uqR#*?!Iav~*iTn1=&fJc{uIOdHQ-=Ce@slk9Gti1b!& z`P=Vq>IWM8j!sU0x1{dH*1gFXfqWUg5gCD+vJQk@CrF(NBuuH^UKWvc-@miw?omht z+;NfpZhqizpC9n94eRfS++EW>8ObU<;5hIWSr`*o*z*6;hc~+iAKqk1Meeos3jHY@ z7&-TbA~ef-EMibtEePeI9^o}0RfIVrh4zAocJKXUEq*o=d#T_Y6Ba)6{!fjshOv2A zEktz#;>#?E(O5m*iH8^&XL!MQIz}(Ca)}TyCW|Img;B+m(1$y%GRc#R>AgbIKR(^b z4mpiNl`Zf{4w5`%aBy?|ksOuN1u8CbcL2#SQb4`dK_+X2rNo}#QXRE@9TOKm(%BQi zL*|l5a`ZYeQY_4Ejnam!cC_`Bj?QO+-Cl*|ib8wlHlPgB7uU|sFWILNWiFn)_{B}X zG{4h|UG>PQk{rmSHZceI?>#bVrO+zzpanP%O-fZds&?J`#Ce>WLkQgQgIENWBmT0E z+^XgQeIV@vVS&_CW}TRNQMG1gLE(O3&a&r`W9)pd`ugvW%pEGRa_HPg-}t)f{Z<^S z=SxYVB=f)be5sWJ<1+NF&cYZf=~FcV#Vb~BWp#mDX>7voIuLLNOAQ7 z1R4F0FsIu~$Rd6)w)vO57Zy*x7)rft+VYn+?{sZ$#iDu+m85ZGnb);C{#=^Xyqn|0)oN4}AW&)w5(A z9(8y6JKxt8wHg#Y9{L2XX#?gFCotPmkF8*IIJ-VNdi9HofZ#&Z+3m0z^=~1Cp-xln zB^VuqaCB53>q_29zh^X(3RAzER3c%d6D2aeJ>$vV<3c?c(}<0uDB^6{r1(aUU@(uC zh~Y7W{I`c3xsvoiBsx7D`DYR7-uLO+`>&60h9|QaWDJW(x3Iex`_X{^SQW;(UsNFt z!&4L+q;4%_L<$pfl?+3enJD09Nri?{z;yOo5qWa^+fU3N(Z|!=)zf`2oe<>}-mDif9pbEU0h*|Ru6p)5?bmX`6TGx|rq<`*c2!5Y;F z8tgx+Kv{a7&u(&-c({DGIi!8rgOC?&i)&CK3374^$tI0JlR;sYN z&61a1&=7d?Iigr5a#$~iuktM{a^VZxXY?&^K0F}FF60UyQa-+d0vRQoIaYs(0R0); zKQYzf?p?JQqJ)Ur}UGHB(iInLvL z9_+shWLUg!OI!!F`l3p3SZ*+uv5-J`#rY`fuAbQ{MboQo{|0+|Wt@J$9ku9LCLikL zQjA*f=}ctip_kbFU_!$iIn?T_D$rvskYyKe2eL_KSu(2QA*Ce7W4SD=%5rig5mQbk znQM|=c(@8XbwkrFnTwg?){y3X!cqrlZI9?9x(DzT26CN6t>rM3Gq}lM!zCQ6o>Zyb zS&Apnoeavr9nxr7&MMvzSm{xBf*A{lMzzkg7IRt@&yb^WEs8bgn6;ejh9*r>MoLA> z0Wd(SLZp_?`+RVR77shuc{5kTVLH7n;1#j=v}`#9SYe$JSL= z`C0ccDt4T?%Qtj{J}C|E=o&CJa3@on)p%bE6iIE!lsI8S6quJg^sv1;WN#Iwrq~dU zL@<~ofiv8Spg_*Bcc#!@g+ZOa`x88&&?O?B>Ae3pk>Pi3}lWKP_LrNaYE9eXnPz73pV>3xe>jTKt89Iftz9#Alr zYQ|i64L39z%R5pa*u;gJ?98y-NG@pOjT{7m<07gYT7mOBF;Oi{bqc4w5EIpcR7_MW z?IJ$!^sF8JuB!&tRBlU9%CKCl~9?V99(~j;c z(}9%O{aooo1Sqg0AQbxTF|>;+ZFa(IG5>=_0&N_Pz#EC?!%3fKQ3U<1x6Oof%RmYUiUWE`;h}1`<7Qh1p zCE7PDwZxeU5$KI7?U^O^LT7rWv&3Hab~{v_RNKn3B$+*>wXs{hYv>}Y4lh13{sdrv zP^3Ir$`;`Pq`%yrhi4w}FIHm8?Uj`!sdZ?Dphv#YfD~rtKzgZ69ShK2wZU+x>KCLs z%L_8w6C-DHCus7xo!#kOA{R@A@FBn)nSqr{)+5D>ZTCUa>+| zVdzv$3kVgxqz&faN};{nnT771NGOqCVzUzbunN=xVK6z-&uEX8nNFx2bU|a38YVZ8 zm{J1euD3zYc*Z#s-xTJYU61D>kEtR@$OkbV{(vtrI`xvK$8X`rnT%LSw(WVT5K1(? z3|G?Ot=;4&UEQ98PIB-K${WaAOF#ptt0WLm8Q`lOE2&zK7^0~@Y-D`WglEjf+c0kge4 zY%S&t%!U56X|A}KzC&g%c_QoMl4{@AZT87h$hNoFEEs>`={RfO(eodFOLYr$f@X7t z1vz>;%`X-H`Kyem%|aVkkDdq5T>N;}MN|4YqwBvs z;LVZplbx6RlSZ8*`vx$`zU!Jr#G6mAm_72MlW{TU558gX->kx)1bJC8AI5*z(4+D`t;2dVTD*&EHjdE8FN5 zo9U-q?njyx)o1u^sjqF>=l+|d7(GJGvd7Gv3K3mfzU9qlSKK=KV$j*=nj02A_S&ZJ zj(V!w?9m(NiHqtz^wtO0b(Xu9|Z>V${sp#+A@3GRg@ z>Gmu*m<%&2mWeui1&gL>11*gx7A3U-@)b%X7M7gF(qFZptGB;6S9Q1LgrC(kn#{=6ovj zR3RRhgGU4g!nPikWZ)AyS-8_#MNCcy_GID|=n}!mSZVLmsykyG>4~wGL`I-Nojq?q z7}~Yvt>;(XrWhJDg3KEiWl!@s2 zU7x@G{Hoi=T#DuB-h*Z=c=T_1-yYH2U!O5CW(fsP(i&U@W1Ls?MGTQ$N~KUSGMo^x z89rm{Xhu$Z9zL<@*obp7jxsqyYT>uX=9Qp{l7$}KWp8nz-37)Wu*EVW>yrBpjO_m6 z?HBHwI~I(Xdk?w}&njcfN$AYJ6$61-=o5XFMxb3oP=&B1kq)sldjS0iX(je@d?FHN z*Irn1l+SDmP*`as0>V#~1(%VB$n2k*$K%ts=T%_ZRQHaR2RNFK>$T z$NeVNArTXFgC@kKDk*!)2JTx453l3}zqrPknh8HgW+IcbLOp1zxSW&j#H7V(Pj`x( zLN+W(O-H2>;GD0H}z8asYFb)-Zc@ZfM|DaCn>F|Dh0Ms(^15prvdKJ1mKfFI< zAU$q(kN-=zHqMwP;RY(wJb3(~xPLtVH9l9RXK^PFz^5qUp~MZFgbE|=-EcS8LR;m?SHJI`&96QaAcd}B7HVhA>j7NDyFI9-W>;yK97yVA)E@lAT3 z9+l307#Ru((>xT!V{np9)fcIoA<5J&{O!# zlaoxOtmjC6_t4pf4q{m6qP+8PAke6iGQ&?N0&zKRsLQN^sN^)MaL>7p)Gch{AOQ!D z`(YXbKm;*zuF5 zIi_2tO_?~hc8q!aq^Y<*ZSq81o^qXIx_QdP@y;oahr&;4KQe#5?dSU4kvqQI`stQ!KQ`_*|5&)i`BBS9me0Qau^eCg_*MQ# z|M_VL+V9%_8QcH+$DMV%twkSw^x1c4z4OO^H+|&($nwc&+jpJbt?dlZ3_3w`CBY6$ z8g+FdiY@?u%WC9{%}_e#91C-9d=JOK!bhdO3Xc_DFznX4Rpyl`OIj8>7n&C>w%4zU zTDfBRlAZgGxg5gcaa8ZDE3@pVtZByF&|Q0I*S_jTKbFOsj#W6zTFNZDYnr@R32r>N zr|hu9jXV4&_U)`KGaqR3)d_1&S=sKoMq&0f9cU_Zmsxi1JK@J}W}hPaBupJ~7m*tD zM4_I=>RGC?h@LW?f!qN#xQ>hr636T#6157{j)74kwId2`NGxR2@T|rjm3lWP|tGRVJPF#Y>ilv+i})>>}&Go@xnaz4_z; z$@-oXExvHpPaW7@TW0#TrB>&>L6};8m5lE`a4L-PI49Og)AP7?2Zt)i1fPJH0$9{V zg)EFvc_sEN%+c_XT9BS9pusGJ^g8Te0ixwWZd_k2z}IQlmN9GWL zLKvzdQr$FX7&S_^c?R>A6-yT{a#Qn*m!*WUZ}od?_m$U!|Dz6fIREa(!_G2SnRRDH zz1JTufQG7lxTSnwwJRtBi>rEHxs%%8SJeCVGzx}%}Yy7%yDAG91Q0Kc#9;2tS}@Na@7>u5vF$(Q^aVv=^*K-N-_cU$h1Kk>b^C!F4(G*Eu?)gReczM~oU?LE@uJEfxn3TeKkBYVqTW&W~=9p(Fu)B`F*00r+@ol@-xoDFow@Mv}6! zHcT*npQEM{g4uhh)&qS9tOSDbxlbM3TC~u=P%MgAymVR0%225Q5#3G4f8D>Q+*cO4W7pn_qjgS1IwN+T#*-(_ zr;b$Y-L<0(Tl6D$?x{F_1rD;P#)?t*2f@ z``r!I2lwyUxx-%;Rla-QuhsP)NH=Ifkp;{j3*hX2EX|k-QEBMlEGWT>K341tc-?|? z#2QgxDX%Ih#4FSaG^A)&XF+*-s!Mb&M8iV#f$v}pXevcqV1`Zl3rvM2?gFk+LFxq> z3{MmmNzt5GC00f#*@%Uaixw|gwtU6PlRTr;dZ-WC@a|4w=&Nq6uN3gISWYJO% zH61*&n`+m8p_`}9y#Lt$#Qi5%nOE4CdX~7BSe7me!{XCOFzbIk&{%1%t|t&1nnAn< zM!PEAm6n6GE+CO1Efhk0juVF+mEwS@8h)r$QZFp7lZStGReI6>Xej;~A~?CqVo#nw z&zs~*vfOdk;_!H2@q2gvv*8`{7v(3zX=prJ=z7Qfj^$sap>Yv3xDS52x$zy#dtV$6 zU>#_v`|hKExZd%ieL;Ck5a&W@Saj?4)4Wq%Q!O)Yx-*;xgxXE>Z)==mell-gI1$y~ zzu=nVo?}_?Zbf65Aey(YTj87&b?cltx80Uj9*9REcev(wanHkf4QCQkx5~fL za`)7cL%l;>Ln20uzZHmgI%ueP@gIIey!M&s2F*J0kK36P1{C8E$Ru}fyve1xwTK>n z_@;)*grOWH48GcT7hI0}M*q9T3#d0{48m{qmMpj|+NF7M+weag^Mz!NhJ5N*MXp$S z&#lu&5BGqs$YCQU-8gT_@`f?F0g5_@i1HjQer3UcE>@Bk867w7zMMU^4FPX7 z=xbONxpKv_du|y&+%?1r`VwZ`wRpu!N02@zFwfKUW5%r)b}*gRqD-9!W}k4leHg&7 z>lUJ7i{qWCS9XXXozbSKxNCp+eUsaV(wGhiPHb~*Il1?~^J40?C~N28_q|`;;zt0M z-~&Efwcq@8QfI3Zw?{^GyJPdNW)GgW(7`c;R{WCn+!>>Wx`s3li5QxA>zxaihmcA_ zJheZ+wRB`>Yn>JuasD5^DywpaQ|hX%_~x-Ix>?OG&80<~V=tMt;pZv`*a@MuzH)o+ z>?lh;IElD)R{E9-w;xs@Np0p*=Jq#M4TvyFTFsG@p8KHmcw4kaq}+A$^a%;RA*O35 z`X_lOnJ11J<{M%iGwsH?i^7QR=xZupw|Lw|5tr< zkM>RVP3<_OZ%6#qdElaT#YZ8tARE?-k6&6o*r!=KTzPGxduqoC z7e`w(t?R&>Q$K8Q2l`C+_ST*q>Uqqi=Xj=$$Km%roDtxt@+ zAi@kzZ+y8Tj5W*Q%}cw1YjfXGE8eW|`F(zCVfvhY-N3-`m%oR726bls+&;vwMOr#t zIcLKTgy)D;FHaxTI|?i;{?!rWtfTYsKCzk>(eviL5;#GUE|}! zk-PI=y!YxhcpwH-w@A&iAM_hQ}rK8~K1!KCm!&}FzX59bJ6CONKDSXad>lTi_ zfWx1aw`(WgOzc{N(6 zOpl0kwUyuJzx7l?yBu13P58?XM;g6o>}sgm_3t+xyP4kAmIBY4_UPu_%|6r?eVrPr zE56&9KI`hpcG-+k<~jQMJ5s#lamC`~JMXw-_LR}>^Jt#^afM5Ct|{F7ulL_i?g1}p zPlJ}27n?oUMdEet{NVlf-+FOW8~jB}4Mtu*?`s!UFb{lOy?f^P1XsIY zLUrL~Pu|93`?7|1FuOI&S-Ik@@tEb8f+dkHXF^F(S$LwNcJIctk z(dVC?o5sU$EjEwo6VoO)s4F$B(!rkIv})CglqJ@?t{_?ixVnm+xK zXpq>RYGUX~!sluzUSpYU>tSkxn;rp2LXWPdx;MtfpBLMjp>9Dx62k5Hb^B_YIW7u$ zOMChW<7oMkd(5{@9NPRF{CKL0U%BfND~UWSKbY3m+o*7}XVBB-!X2G19rpe4PMogMC_AC)ARw}9f?Zwv*L=F=>Xvw&) zgq?OGvecBjrs&x@1EPDvi#uOD`S#1(fQPOj>N@ew8xM@LBAQ2DK6>)Ch~a19@|V|B zZ@E(QYq34XPaF2z@e8K7e8q~nlSX=mSjXRb>x^;j!(Zg=kN0_8mGgaCXOr1ty|?_y zOS_zv&!(2T(!UJUG@(VBESFBn`1txZ`0O0u)8{IGbq*vLY3@4nu|KVbP{P^lY}n@8 z)gEW=%**{+CuC~<|M=IGG002W!H00KRclrQcDug(`?r@~-5n`Rr--gsC%yZxhbMRVOZ z!n`*o7cUUmCpZ+=%cw+&|d zD79WT_luuWC)wg)=%&cYkG=ENC(rh4huI76`pecg?ik#O^Ndbi`_0Sz_CJ5T4%3XY zD|Xa%v*+C~a`=!TV0PHp8S|GcPd+QNGv4~kqf^d{0kc;w&MrCT{|#mz|LKYGmv*vB zW^Z`6_+a%}n2or2)(0O??<5#1i!b@)(WyUdB(E>*n6I7}4_Vtj6@{)(J_hIeO>|U+p=G z((Bn-HFfFJnbW53L!+0z^CODLXJgf5jXCeUNFw{y%$!{~N4Y$ZE?F)6j&jV`eW{vK-Thv#{Bs^)$uyyfW#t>eDS)bUzD+ z2&|Fa2i+dMw)~XG*A8!-^*ObUv3+iS`QKG|W~nU&TF8|PlgP+!mp%GTr^ zZ0PVYmMQb>D}1Y>&&p7QC2qj61p(=g-QGwfE@Xf3hEW<=L2t z>~z(2Z`5ebm@1vs4yAIy%cx1SEO%mx_nW+QnD*$K-_-slFIW8jAKOd^+-K*-rA0<| zow@$&1NFbb%>@%4%G=qjdCrL&{}9u#1pf$g;!Vk}vuehtMMrf#uXpdOAO5l$)2_29 z2exkN)XU%7GUKyaOq|cAAHNoDiSFLJ_hmz$I^k|xM|z02M0bhn-8=EY&;8h>aCR-} z@jYSe)SG6_ntRuh-{kA6+gCpMdK%%3k>BIq6ctz_duB)#5=w(@-6qOyU2SSMszNVx3zaQ6Tb{0AxN*Fh7_MOYH+9V4^ zi|5@q=`1CbXxm*+z4NmJRdI0HcyMd>+_M!?Vj^a~_>ZDP%?Jr76CM1|+iAnv<h_LjZ^VFt8Qj6cek}~Q1Huy8j zV7ylBZnNv9%8M5?}QBgJ=Bdu#06dZ{s(=pLA7^_NxsNC4EE0Q0w(e zC2Q6d_S?r`J)~X6%y`!2U6+VBu=(B&7L&idIUuT>mTos@?38?cvTR6%xedPb(xu64 zz2?R58o*ag>ZP46rq+CQQqdW+mWcT~n_xFl!hLenXiOLZU+v_V5zB9%o;U^>h;{4@ zH{NuU?J- zxF6|w-?gm4cer@uEm`!~D z8n6%%vOE;&Z9aAAFA2RQm9bYR7gRU6us<&--bm-EisA*GBCz6Oj=K7utnyRd&=nVd zeZ{Bg2~j9LV0Fk6J#)kMYQBrB)#?yd+ENzHn?5#Ss9b3qI(+oR+4tJRSK1D~|M2w7 z%~)yce9?&cpSfDCw0(&eJ9U#QZPvac?)pn**h*W=iM3Pu$6@&}qRY^`|GW)b4FfA} zu6>)9C-ja+X$C88){d8sd*Zw5GgsQUb17xn!rLZZE0-uE6UNL;UXrpRoIq!FdEtsE z5ID@fq4b0gOJo5#VwLjLuFcPnmjrgX=gn;gL4zSfETQ>azy9Z$8!rHXgI@jV*IMjf z3J~aPswvO8v2T$WW8z+zVj&qH(OqxD#McDQti>GPB=!RkD zrElyAU&%eRb+vbxdHAql?qQb6uk5T3Tg`QRo_=%VFzfJzKX7l2q6bU4d)C}M+BM9J z8}5FizSUB$B*eUQ{%xMwuGyA3N%w{?DO-G=Z(eM8#{6z^RX82B`~Ky6#{G=trLEO? zL8T!VENi=VeY&pk8OyV89|~R8uKD!U7hKPH(f-Zi=C(+%q%6L7fj8NeY+0~ySvU<= zzwhX`#f{s|;9DZ9wKbs9-9>5q~r+!zNq3O_Jyi>DfAJ-;@lQ+ogy&X5$cSej3La z1I>Kys|KInZ}uL22+Yh_^_j29v~TrxH1%O5>Y~Y3iGQ2%mjjm9 zr~{8JcHYMQF6XJEm3zLnv-A7%h10bE0jJG8b>U;~mn|=)jOg#NSw`Ob#EYJnBc6S9 z7EFRNp%~dK$Jt>s^|M)MYrOIu4kcBAmNd_L8`VXgLp9X{;}1Y#e)8nhpBsG*hjxBf z_(3u|@CC_efqd@yTcNwE)6v}9#ta%@>py7ZZLfb{>8a|tyXdj;2?P4uY=ef6Npw%P zP8u_OP=D%-`Xg1RY?K2vT7iSor;v}4BHPgrIrIb_L+3sD-shkHQ0wu#o9a(im)<8i z@dpWkJW}#@x|=&S9r!AJ;;{aMCp?rby8na)&wu3pJT~w7h2uyT z_~!WJydFoRjWoTFgP#onxAnn@DX*Z?#YpRrg!^)Tb>eBKqYt^^#vw{sxc&?Ojw{M` z?m6o6`@VW$=76b7H`h2lr;qO0fk&$x{>J@(zHRj2vB~ScVb!AHn|1e$yT${vP;RS4 zP;WCSRM>}+X+bnP%E@J;-oi~Va@4g$M%@2TNlleBKixuLEd6W~<}UU5R5BWbUJX-@Li_BsO=KZQZ=-&H1ft2PzwR-8|p2D^pg# z{MD~+S3~BYv~5*B=l*y9aP#EJ$$$K!(dF8|@s8`)e%s*pRebE<98++>?W_Cl<*5Vv z)4C}OLQac~{}Ll8L~4)c`)tP{Ie&=WNK^l7hL0XU?sq>n`hIw6(YUdr28X-U#H0uO z&kcL_x#ypI`ol)o>C9`=zOHhgC`_F(Y~a9gH^2JpX%ckDH*UYr^N-2n#*Lqq*9eRJ z_bu1-FP6qkQ!z**AqrNNf%_$f&^1GiiA34@4;VOL;F9kfeBVBkG;rX6{vc|)u0;i0 z!zbSV<|m%*gTKuCt{HN=CN=+%*Rk*Y=YMCnKl<|4+7^;E|2wbW@B4D~$`yCsmiqTS zF87zWUelipMLPce|Db~g7n<}?|Qf2zwg5j{*`&(jdMP%KK9|P zLH%h<%D0Y6+oF}xvQ?O@#MwR@X{GQSM6ICPorR=v!zZlXSk~pV>-4;?sARgVq)Bx=Ha@BG^2s{Qpqj($XMFdZPXz;gz1s+@9F}JKc>hL?N%eHOX{_UOyuK-mxTf(ZG z9jBXpEq$FpvSt!>&B!Gm{IK_!)8lKY+xzd#g%bz$r#`5iW42~Fv~;mwae)HkK`X0~ zuSo*%X!C5ZzDjh(&X`Hv6Qxjk-2P1$?*j2c7=sHzjj`254Ai%NcDfISt=$lfG9 zzz??szMT%Cwr$l~_dg(6=rL{8hiLsCi1gVkqf;_o_q}<+`d8om z>;P#THE-#%d++$e8(-`^QrF^b+VSe5QT>@)HR5Q292J(5N~bLn>NLl; z=-L1LxpZCPwc}EZO90ydwQ;eFb-m=^eRKt--m&1+u}o#;Ik$6 zvr&5P)BjvL*=8Fs|q5*w{bp_0VT+woy-SJG?*V{t4F%y5;dNy*}68_vhV-XNH@Py*k2wP0W-JTt4C7 zI_H}HMAkz%C?cN>-6V+WrlnEIRCs6_p`;WO^jBhx;SGkZ4IXpLUk{x2*H`}g-FM%6 zzX*>?QE&amyj*&+e)re^dhgv&zB%M`pZw^t={LW#ui4Z5%Rl_@#(c2f>v!yXW5z&9 zl`%G{Yk{pB21GL?wG3MaaU3VSQ7$zhQj;mXH{i7-(F?H!K_z;~*att`i=_;o&)d=M zbSbHge({Hse!t(_1zD)?_z%zDGHUW;A0BeziZ=?1Jn-S86Z>zMXhFl;jf2yG(>6s@ z+a|rH73>cje8ckhj^G({f9KPC4-@unwqbX_{EN$nE5h59|HRyp*9@QWVBQ`V+C+)w zJs+%|F%*%SUUgD3LYSo;)1MB~mTB1ykP*@MkWJuU8k)OJ;Gg?;;SX=GoPms(ciC){ z?ppU_v1#+Y2$sXf{eI(Do}W5@_4dYZzWq8CDd&XbH@25}e(LyL;hGyp+WPe$bp69` zedGQqV%u8}UpJ_~VIs<-DTH5eP*F_9yb5uTsr;r96e|yG2+@=7a--)iS}||paKy)< zW9F<}YPxd*8V?vW>9%`4D?2Z^`S#_@?wtkzxMtKX3zvIVc3igLx*-Dz2*W1cYIm=U zSbEFEp|<{1@(C#=p4EZ^Ar(VOahBrHjYv+rB#t@Q`b=uB88vRw=)nW&8ie}+gGMG! zFpVC9JZo^mSWjZ-al@{iIC1PS0^h(9V<&nN%@f89MH)9?(1?j{{E;w-R-w zO!7$BPIcN~hy_By|58{s7&WmVboM|AxouuVGJk*50Li4!=IO85T5#Tk6vx%y3`x*S z4$8FFh;CGe0m-zBYRPizaKTKA^GjthG%p^+06j&e6v&Q}t_qrm6zvcwzBm>pz-x!F zq4H0jZIue4HPWAXogKDF#r%jfCgC(=Wi)|NWel;gY4~jV+M$OflbkQXdU-d!ko{8O zPV`GRVUJa+$zGgtXkK!M!Mzx%VP2>>tG5}1s7#oAvLgZv+c4PrY}KkumJ~=DyQJiJ zej==EW!9w0-%pcW7o!cOKv!`|(9&Q|Lv2Ab*{;eBq;1l0Nrv6vIko3QQ@dc8G6!`hSe;LyF zUrGGmD~Z>IsVK#-X}NeYLrt1r>yV;li=sqLD^1h1p83XEenpC=CbEF&lU0i=ym!zh;WpENSwrW4xADksXhYMXr|kO33Z&MfVDfEz-1j z;Yieygvi&l8ob#L=QY@!n<0cclP9@CWM~=T_jk+C5(Ng#N7ou2XTSh>0SWFc6}j0x z96~?SPtaR#`2FTYEyE-5Zwg-0k)mbb-y$s@59!NK?6=DYX|k7A_r+_uxDQO>j(9B} z|K@5b@;-ceL{zqxLUG0aHH=*}#Sk4b(u5QT#0hROZnnG=pSY76ARpm(c1zLXi@<-b zNYRoU)C=##$ns8n;?5*3jbg|MztdC^kNq1EUa3!mbhL;hs<8$;mgFaX;|zMY;K{`N z(EDB&{%khtSdpDw1X<$#n(SO`R^x{YUs{ULN$4F<39J``gujGv{FK0E3S6rJ^);bi ztP?`h;vvD5M2C|vP07H%nhKHV(@cqY*wE~VPs1zfbF~U=Wz2=F5AfGmCDrH-CWi0v z>S=ucB1TiT_%~sSPs96?Qxcn@K9Ppkxuj8d;3F55IpQ-8h^Snx2Et8r>=ULW3?G>d zqro?_ubNzR$);U!RiA{cbQNfRlfSVxkyw?r)wI_g-;Pw)w|!0))?UbqxIt5nd{lki@N zT)!5Rn2T<6Gqj`%kLX*05fULSy+;}#dd`*IYDGS+2mZ#urD&Eya`gK;1}~&(DSSPt zfeYXbZ|+Ws&v(Sb5psbKX(=K*9zS5+OTvXX{7)7S)^ z_QqH^TYZ5C7CJ#__Vg=s24cC!ONl}oDBuNS=i;->f;{h{X z(OG`Nb`mqtK06-oPp1?rNN*Q958OgY07KztXB{9y3Pg363p3W+uvar$ijZQuglO@*dtmapZbmX3cR zQ7=dZ^^^g|17{h^FO?Fq;l>x%D0!nF#uN~q0koiy<;d_^_)#}>Alv0*U=qMPV?(a| zGerKT6sW8l1x6&I>!u|-9CXoM6dUzi3PEI37)kLp5Hmy`L%@hn10$tAc!4}Af>>*k zDgf26AxTj-+@*7_R^&(l9a0HNaO?{m@kt^dhe(O9fvRgT2AkxAPW0MKT9h;!v?)d3 zfjeV)r+y`rh4XR~aW|y~q<|r7`2-{2mWFqgLo$d0`2;C61Euj=N)p^N8sV#=6d?ti zc9WmH9Y{km5@9Ei4g^AsO)p8(k^nBbkS?f((fPy$5JW~AhC_cz*;;%l+9a|KxJj(& zQ-iM@vIBOFyFzY_30%qza)Gy67MZjP{LEE+E?(>o{=bEi46MSph){U#Y6W=9NW?GF znzIufp)H;k7NjZJr?CYTT%^?CW$a+o@l8l4nFv#wR@A~@CxL6>4Oa+kM?|f>GY!AU zgp20_R^bY*eCkBridR*&*HH zE3~CqqHR(d$N;mlF|Xk~*choBqDLAy(v97rCDG>@FVdoc@Bnm}s0T~5z|A6xA#7G7Jii1fOQW_(20BG?(t@Z=Q`GLT}u>gF?^0hRGSCZKw5a8sW zgl{4@IH8aT-$+8`fM)o1pQH?Qkqu*4VkT(n96(KaOpGP5I=?}lUdOLEB_&G!k@zX) z65x}PFty6Ylp@v$I0#pWP3=dM?ty5M2G>M(BQ)egipWa>u}%&Wh<+JhUD*fHN{)s} z1>X1Coe_-WCgD(ILzs+kIaz43LN%Qq@F-W zq_hr^m{h}HBUEBp5e$~G(v+kal7cL)7hPa$Nr>bC7zB_~k*y}YR>mTSNrP`)ZA2jg z9m3SvLQL;Kh=H9k!vjo#GMThqVnjmVVFuWNk)cE8;#3!7mef2(G-Jd|fPM0NnbNBe zifHIiH>>d3kv9bb+{Xb$Jtgq7f-u4_am9#a@)|55{Mt8iMxoX4*QbLmRY^i+>+1Ym zzRMO7YNh~a1E{A!_=pe|P9=Is04JnND2LraU*VJHNIgeK>PTRQJsMCfdMKa-aB@OG zgTPF!)!lk}jJx4yB0j^wJfU<*Y2e+f%(POHLMNtw=VT7{BEL5SEf8-Ea1l%l@Y)Gx zaS`#HXJm)pidq7+$FFfG^cG`yF=)p{=@4>W0tL6aQ_sb`$Z=?@X}N~qzzg6;gi&Nd znBX9iIYRGU58>(=5HdiBG#*G9NRxOMcm;+;z@pPqlKv8=SiA#1K0EvpehkKu0kcnX zw7za-GMDn_unx}MGU`MRcWp)K_AR;V|NQhr%kG*zW%$(>biL}mknWIN)pt9(r{s%G zIj=tV*!_!cyKc^>FQpbcn(ixmuD@JxJxY)s#siLv09 zHQD(vnc!HP#8qh;U>R8&;w9=Va1!Zz04`>4l6IV;N`|8`UWS6{z6_{4ls`s{TdoiR#KOdQBSYHgOTgqw*P8 zl|Dk0FLE>dT4#omA{a#)>ZDStnEXon$rbrH%LSFFeFCtx>>!mYsl-i)FIbctz zL`X|oBYX%VC<3vpYr*6~iDkS6T@cy@Nm@KI7;pt8Gt;Nt$y102W^AEd8-_(<^$9Z0 z(op(Nawz-SE@)XW3|UrHUH1t!LtS00j7q+v9lG7YY7t-HP*Tm&%G8jC21Oeo8GvTY z*`m}7_D}$&$3su0I0bl^;t486#1RX6LQ@N}HJCFCzHmcWs6$yO=;Sz{lT&J#eV7%4 zPgJ6j;!3qETEG?tjDh1ziJ{ajjSbohu~Cs72_-tRvq_r+HB?k41hO*|qh4%ocD6ua z7$Af4s?iYJLC_5I&wSjKC9M;$@0AAB1N!8|hh7*kU{HmL6#kX|$C?4FH-3~+&*S3-rYEsw@lgfSp-zc`OpF2|6{K}IG`O92ql z31bWdU|1K6){fvnmq{CfNkidnSPf0A2C<7DkUFr`kLnFft%(0{q+Cae(5%R&<5Ql~ znfaG28=y+Uf;R-M>ffm4Aq7NSXaKtT9_Zhwt#KG8r%*fFj$w>Vo;99tZp!bTpsK_?uV(p;_7oX9^u!#wn zG*!nb#2siIxe4FC0k>*;N$LCua z;vvUar2Y6?wnWKYeoB8rM1(F70j;!2F1ny%*-NF(fszOEF2-)k{GvcH1SgoLu*jYv zYwSh^1_Q%<1Tq2;ho1!plB31~$0|ZdUkA3f2FwV?f)~R|>*)+Vr{HHaaLLV|0hbnL zp$S#WtO=Uonu?WS45ev)e@K_;hkE6>6jd%+j7AAv6)*66J93uIxulW2=S!oeCr4xc zrrIHI)vFz8i7b5}gGTX{x61l#FQZxyuaTt^XdN(@mgp5%aRSI93TvL6eDcVEu)>Qs z^e4m`E*PXi7)dhPqyeUDUWGuuGVHlj%Wq;un|Ay=SR8)c5tk^BC@lL(TZW+koKaV0 z$r`f`DT<7sD5Pnk)XH!M$HJ@`lNbDCaat1cF#HAiLKaxSWRlOs9KWB&c{y5PSqc9F z&v2Ec5=_zc0y?@v5!fjBqphs1(Am%rCMf3z$}VzH6tCl6>VFDI=2RlS-^nevfWF+uOBrTW>oqeIEYaT^fwgt4INE8Ft&}&2Z;V=D+ z;8dCf^a8Y@QeH}7!Q%q!BT9C(N3Etb5z6ah6rXAk07~J@4$f;(M`XzhWlVjgg%g(U zsw{}?Om|yono1~Y4VwWt#K_V!!eNtzHP~Mat6r*Zjg&z@3x!RB9HfH6M*uc+0gkXU zuejJi;aoVIteqL_pR$-N%cgCBB+7q5*tDbpyc}F!ZzgM4ur-DAOIdwEFOAf3{|Bv zSSL^udoO_bR2&q5-sCb7tRfD^NwOe*u8`vjMnU%ke*DlYfgu3bG^QY2cZWwC(5Y9t z4YZaecBUZl2rJ=ut-}D83UaIaML}de^2+Li9 zu&fZuD-yy$o@^TnyLvepUP&3Z0%0&1az!z?P691G@5SA5cO5XrisT3CZe2`Pe~At)?mMHKF$*YgyBqc^X( zI@lFtM9z)%U$sI5Md~Al!7dzvKpdffSn>FpuwZer0>7h}n}j)BE>;SGmHGHl3Kor# znlaOF0BABh+|;1Ex=QF7mIcb^eEEfKX{uw4Ffy^l;o{T0Pxr!Tn>m~V414F zBi#)8rd8Az?;RT zdKF$@g$1ja%|J?OGXu3O7gObBET(drg87KPrAIID<2^>kHK2w}2#nwkZ@`2Sa}rFO zI3r>ITyjOkpxOY|Sf8Iz9=pb1{9mQtB|sm($EUwhvH9aXiq zJ(-pe5+ERmVgu|~O$P)L2pyz|bScsT456s#SW&$3dc7h6+g0;n4>r^YScu(76C#RX z=!Bk7laMxwar}|61R_U@~XU+2!r;yWe;38K2fs-hxRH%MyL( z5q*fP34=JW*mRf-Lt)JI2^Fmq%Zv;zjHbdk7=>mzoMIpaL%N>=rM zfYCAoBMJZvie7$&lR}gu{faaQF;XX4IGew<9)x@To8}~ffvNha6W#mqka>DA{GzQ<#3-2goks|#Us!I z(^=Q78ZRrp;4V#oHXbW>y`gl%vc@b23&r!9JopgQxUHt@RyBz)U(I5!6Q;U}{LLm@;aCf`)jM zizmI6u>@nxlwqnBVuol_Y==Myzg{PcNw|3^cRNPth^!e~8TCn>Sd(QeE~prDB88MNUR6)P&)*79}CrkLQ>g985k62STE#(Tc5C{ zNNjzA6bLZ}33ZpK@2o=SkQhFOE|RH*kI_(02(7rjkG4aUL-dwh(i??veKe^R8@2YN zC-y=D8X+;1Hec$6>vK}-~ zFhnp*r%n+%WKa>V__UkllzOs6Uql$zNy--kC$Y@H=Beti40$@tI8IVwA0ZlxU7Mm)Aj+qulJPF{4I*VFO(x7Er{qeMNgA=3Xd@pbR5jXfuUT zr~U+zB;&1c0*vNG1RjkD+{l|i>%>A8)*)a#xdVqgnZ))`dT}xXFKPZ^jNk;ZRVH-z zj_zC7Vmxw^s5LVcA{iP)OWzJCx0-CyuEHV=0Z3qf%Hr!0*rF6gqs954xq)b$o*L;1 z2HVjzV@C3!%48+oQ4+*H92spJ`3PeVXao5Ox>p48*kMEaL&Jw$oD_>|^)!aQN-&I> zh!iMA@;+$>Q4_uovl}QHHI^&I>V;_|eV-@13O92KgRl}jqT-50J?s&3#xlaDg~0gw zn%*W?`>-5(h`kYsBC*V;W5zCgn*NRf&F8WJgN+q$X zMCFNwV~`jgO*n{|aR|or@#=;eBTI+23*onIFKf5yaKe*SKpy0x^v41uqA&5M>94W5TbTpvTeEG(%M9ZK0$>xG%n_^ufCT_>QcB10v-pLtTkc4I3P0#&n3kZKCdO9_!qEj2ZN7v6 z=_Cco{opR-kx%FwU{VdIAOir#&(f}=h9a;h-m&a^9lGxT-EV7Ne0Wky zCqNg`>XsqtPrd!kF8siB0Kh=lNW&{v2Q=G)o^o5iT!6BIVdRV%)WEqC4PocOXv4zS zjXB8?1xZ}7c7^3PHsQmit=EH5gm+c>I=I;UaO$@;FFiadwQ~U6x4zj`bs`9^VL^ph zCW{2C$aj#2+`=!R(zCm|5fv8GNQl6EV+|+lHr8q~K#S0WLR#KvxEz8!gMGHr$6=PH@hki=ukeT9T6+993898S|v#Tx54R4-u%W@Ss2<1 zJMn|9{HBPOe;YhgwAvbIbxiKYe=jf?c26v;{5kO4C=+iM;mA*o-am%W%x7u`3%VZm z3Wx1@$d1P#p%zuxfDx8)Dj%KYmPskw#*oLkMW@e7Ix@y=reztZ?uxUI&9SYC#Nx?F zq>mcw-ijUyCE-($2S^O6)mY#fM;{RcGgdck{H4+U*ParGC;>YvB63R))Au|Ci4E&` zhh&;QZmj=No`VAb+9~XO8owS95w>tai;$;*1RMkf8tVz#llhF`fi-JsIQ@v8a4G1C zM+c3b-)i>zZyNdVTU$!EhcL>t>L+B)utyuVJ4>5Ysa+)d!K^jBY4O_{Kf4;qBIFQAY9lHGS=1A_;t?P#yqyF zpkn`D#=^cCvH1p@0KyTBkOe3XV;3LJC~l;DQ53$_tl9Su?!>QPzM}8km%cfo8kJ*1 zI8MOV`ryz=%9Se-gu0VEC5 zQ`+a6{n&S}%X(MevhQZqY{uATknql0Q$&>%_Nuj5@UfV-r z&&p!(4oNsuXsaR0LePEa0!5OG`o6e{faq#F2lf*!PU1)uK}gTA5J%eTJ!=%~Nh@tx1DZ=e3J z&-a?V{}5_x5c61Ii^oQsfN9`d=6WWoeiy^Nil1oR|Hbn&Q`!PX+YKWhdUJE>()yzb zAAxuoqtP(9^Pb1MeMcqYx*f12s!tL!ZnM0EPPO%ToBSj4W7a| zE{OJ=7UA9f*|XES#b6H$l;hUXkG;3G;qm0xWn37? zG;}0~NJ8)m98UKeS|&F6{$zc9(U49SNJxi1ju-O|t8djo6_#B@Ac2^P;lqD+1{AIp z>VQq!C<=!Lkuubg+t;yh;gQZuxI!aA5#$)hbi|$jBefxd;)YJ?=y>Ki9K|SC(b{rpj!W+NfiD8f;eVM&u9x!wKM?i-us~=kGpxr1Yt8Pw`~#Xf+mTC*vGe`- z_pi(!aJ8_NR}Wb5@9&SVu7|NaUrG=KnE%=NQY#6@GX+33kbp2Uz?5(}dTjRyM5Hu> zEH@fatEycSNPaLT5VSBtTs;9nM1R)InT`UYh_B4A-u}Up#yT-q5R3owbEr0<7zkB-%y;SuQ;{M8DfLqg+{k2vw9AD1#WIt+EY>nWHY6c( zP(o(J$s8SWL1fQpH|97TS(=vbbU2H7>DF9X4o7~r!;$UQit*;sG?&BS*0TK$Q{E~N%k8?5cX_^x!qW)qBXK*_5vGv&L$kntw z-VV=nUBb(vhLHOYVUp}9nD*W*EBOZEV)47fHCWVfNp1=)5xLkDx!HYb$ zg4v<$`s^50)vkgC*R(Q+qsaK1Ph!X$P6xiG4*HSL*^zxL-TcNwciv#DFom^Ek%5E} zP85jn_Ae)UPve&z;I%Ub*IJAE$r^ael*yBRE2S^YQ+e{AT@6b-dc!=ASUQ45C$=`kig9r46OqJ z!`WXo`{|#v7v0g>qSTve6EjU>ruC>HbCWT)f?_}9n_?b`K?G(i&@_Qw>rAq;2+Ae6 z7&1HOK`pu#OQHJM7&WskLP|J=mhpz1AlH$pYHgsKWn>O!!QU*mE0frSXF*aSu9TH* zM>Z$O*G#J#7+*wb;}>ImT&Wt8VUR{Sg9-8jO_f zYfYyo$ZJG!&FF@WvXX5)HrMj2IofhR5BA>$YFg~K-qc)V()AP^$_+*t3&De5yBulV zj6U^3G(Fq)J6@sLy!{jn&^%CwxQB(9f1=Hl@l9InDn-OzAL#A0El#e{jkW+{VdZ4Bt+ zx(4to3`Ctp)^g~|>2~$B8`sM+sFJ(0Bu;=^-&}<-TBNf!t_)OqWKSSt0no_Sg)PIH zHn_=(Ip=1}xY!L1n!=5cijc#=z*6NSv~(|2pboW~tqh*Q;l!G($dP{t%*ce=SaT6G zY7j3pd9D$Cky?ngJ}8f^t8`Gzdl(rzuH3~pbcCLi26j{ph#IgHp-l$9uLX=GH}qID zoE{&J7-h21y;WG6Vna9r!C;gG%+M81ftX?MOunNSle+JF9-4q(HnY1kVZWR?0=0re zT39x$kd~w1NOYJpr!lld4ewgL&Y~A{AokcX4>iH!P(fZcw>16NbZYibV7T zsU)kBK9r%)w*o1^54L2T1?<@j;EI7#R!$A@av)(t9C_E(Fh);dA&0QxzcA8S&E!@b zt@GTDoGiF6ca{Ug6=lLwV)t{A0uPYqfUV6}9nB~g#fTjh3qw)r3*kJYwG%iM zA#BZOsF00N!kMpSWh3S+W)Pc$8<+w>6l=xKEO(hB2joPcRqQA#a{`@K@$i$ zI_9ChY=h~L)z5RfU3poJk&&ypGZcAr=WzOvh{c>BJ_wj2A}|-|2Tg%8KpKSjK$Ha7 zj5P42IeY_s9a*^`T2>B#BQU~%NbV33zKk|`5EW}CqU!v28ljy8O+!c%sUt?ZA=6jj zC;(toOhShib*Dr?s^-Hj5E$zc#@yfG#}d{jwvQahzBtrK0ue~oh}uk$EQ%^ zEP5;i+m2i(h!R09!<|fMYm9iOsylKpNDiJLy@9y305AZ$A{qiR19+9`tpGbX38i;5 z!pWmrxW8!q%l8hsZsCWBN@@_oL*B5x6LiCNWua^h$B?JAaOLnf|Gt0N4R)LwA1Hh8 z(9F<|6fq5{VDam7MX1l7#_(dx|-F!m%rNJ?o3i%=1dDkrw=S^1o z4R_rCx*QhP37q{{vmi##r1&|ZpNEA9dyKn(#V4Cj_zM~w8FVlCY30MC zZ;L#S-)y{Y@Pe1uAMoc0`ia2{KB7?Ph_PW9#Mosun(ehmr=(ri?5wGo^~&yJ?_a)p z({aD6feEmA_S7$LS{@x67lrYyod;&T_|-n2JfypvtjT9e4}2=tBF_A=?%$73NxMOe zdPVoK_by+(@wmUJfl;xUJ^?4>s!ZXQj{P0Wzu4pbw}2QUg3V&Ytek^d#MvF|UVD5> z-y0$Ur=>&p(f2O@XyY+oNrNN$O+Hh&`Rcy2m#x|5SuTb8=EV%LVS01(}X)D41|F(wAvvcm#>2Xv10>UMyU=J9KYXcR*t%-IXjxSzYd{5t-Bx1LZzIWM28;|3WLck6pkKj)7)dcT2+YX*t>G=`N;C&V=pB!X>PWjh?Z{ zaaq0LjCq76Mi$XB!Wxu0at{EZ!Y^Kb;-3Bzq076CTDa`P4M)A61`$I1ytG;tRFGw$ zl>}%WtphDJU$jAd2@6sHlZOw8KeM=&gD6k|eE5Dok3%E~jmBJiLI zayi=98_t-AzA=(kkR}jBqEk*mR$fWfUW~BNy-3bZq!J;YS%9A+%5(k+}tEB59#} zcQIPK(BT5}(6B|)BkPpg3Pg5(mHp(j0XG8?v-$EaIICQ5WnT}0fG~=L?#if zJm*hZ#QB|Ht$cF&z?)lCn^Z*Q7l1m%V*+l#1iw@)XiwTeeT$&sMZBSEv2JG;^c<0i z2+s0#rz!n%PNo}+7PlkQt>xsiVSzIf{+5m#o!jG2$Z*Cy!Y4;kcqFB=z9#(ZS1y?` z@Nckg7Xg2$Pwn8&K^6uI#gN0zoL&}uWfmO1^qln22!wCMyA#48T`zAUq~Qnh#E}W@ z#~X}V7Jjk;H_RS z7f?=g!TUvZ*^am$$)kciR8Qp9(u>l&Efu-pQl)`=rRQnf71#U(N$asW|G3TEcQKjk_9yx1AIJQ0=-gTiij zv@3*D-~tYJg!TzMi4GR0Se#@bWW6Y11t&sR8@drgos0C&#S4x`rj+S^qG^a-=unnb z3{r_@QvTkHohhcy!a*1u9QVUA29^g0Ke0L&YX;7N!BMB6d!zeB><{g~*oihkXGm<2 zWYfigwgJYPYMPa^@!~pcV%;Pg@s1;J!^QRZ3fT;3OfkMwgC_R0W`Xf_aWmat^V)U1 z>sOk!4C`JPWDBZgdFTjzE30BUEDIq3Q{^VCa+x79J2m_@IT3bWZN8~|kTx)^Uuta+ zcMo&Vls@Hy!UqoMo7yuqZ9vr^%Yc5pdzSVvr>6DC{Q-S@<95G+RfEj^dZ)U3)b_BX z;A8n9d%s>OJ$m03F-Jg{G{>K@)677Rb|{2crutGsC7$ zuANjfDQxnzvYGZ7(ftuUvJud zevfHa0A|1mn2TuaP|_$X)556&(6?;-T8~H_bB%>HH=aW=Q1~cv6ysRoHHo9j7MSN} z%&MK?o?)Ju?%6*XPD4898%=Sb~>Se z7WPnpy_T&xfjk5c$Y(kbG=~*rqL6)c;;7OEVLIyRv*y-C-S0lNo2VZ?S6dhLnzM%l z>U+=BDs@pmcW6&(Vc6kX;|JO+P_;TN5Z`m?Tph&Qxlt$0%w_Ek3YC`yJYin)AW>K4 zGciKu6*#i7M#GykFVm?Z`JWA!UWPp^uxPoU8|$lic$|x`@e-Y}@Nt3~ZoP|&$iaq0 z7_uUQ-4tgCHBz>@2J)79v(smK$@%m-8FkRNs{Ydbu5#diqRLwre{bb6ccG`yy6a%M zU#&}kisJp~;@V&036j9#DcSFGll%LND?*5H8h(q*8NT2%A*pyFi+2UY7ojWicL>e$ ziZ!Pb*}P2PhQOMUY0G??M<*yp1D`{OLAi%{&xA(-rSu*uHtE_Ke&jlkP=(r3H9%7Y z?wR>P0yt(%0?eK}FN6R%EnazK@A*RO&fTZI;BtuQTNQ7KYo~_@?c8?^8+HxhuhcB= z(nCAXLn)4x;z#SPrwR-AlpzxHl^)yUF7%=Op;9*vW9s66Mr#AOi8PEo^TzlCzI%ZH zenNnBDS}nRL&ebyjs)V%wn)q|ws%u>Aj?43r$q~0FGGL6&^{~+EN3MWyAq%Y<{T;v z^q$vcj-mke^XECzy)!&BtTWT+%$r{ae~bIv;hhzQ)_up$E8ub{0aT^z$X-DJ*U?gN zI!FMk-(9kAS0%`H;GA0tlEA9C&mGuVTj+<>>??7@VuTQZ!1Lvj%8o^>$So5UkOYpD z9t0`7Y}jDmVl!OB?GG9pW!7fX3w2p7Bqtun$=fxYTvHvLaS@{u`+0PxTo~!ZhUj2 zibw8qM|Qh>;I4J|firG@kQzw8DdorayLQ%~-@fD3$~j#kkVsRikMDDN3e`f}PS^h9 zo_laX!EQ!WLe1Gp`Ez%XjAOi%-17-dZCA7FliMR8CK7T4{}bmO}aU?0ydu)-V6 z24Q?cNHXS^)*+0lRGlgUVfGy@^?~03DFI;=@3|v;ePFq5=bwqQkDRUcp%ev!Q+TY(dmcGhUwO&l{d-($VZ_c|dk-8b zsqm_2b?GVBB2;fh$&mwlckNUQ!(Ds!A1*2Pfx1Bnvga{=%!9J4D9wcBBh%2_omYU0 zJ}UNkyl=rZe2tc8aTVv~<15tiObF4e?mSnf)1$S@N5g!KfoBi~G!-PyGeaiTys-QN zZysw@pn9GOf~Vzg6r?!=EwV}4Xfy0H(`U_@J8%BkptzK2Hq}#g`p90;W%t1o=O7ay zbRk~;s>^og`;MNi#*YREs8Xi2Qru<5hxUSMyY?M9S>aXiRGQc_EmBpy6(^7E zL*JdYy@!g+Y89*mbvwHX1s2DQT@9i|R9)^#6xR{7CB&s7_=b0ILy95rNszrUxyW$^Gxbzy+3{e0q>%F*T} zx%=w^QL^nh&uH&x%e40oR@Naz&8Ao9xkrbO8a;Z^9~dotCZfV*?fvv72898}RB4DL_k23s zWAd78Z64loiot}zoJy!n>HE_OYC!iSAKfZ=xP8jA+q_Ce9nf~X_Q1&N z1Zd5=&HU%uk|1c+u;S&PKQQd(mN*h{#l)qbyRZt7&{b*Sz7v~YnRZJ{E5Wlzv`bl- zv$wP&pp61P_=<`J_WASX+;dlIk|*8`_>u=tPMza%0{}Ex~?YiE#t=g*~HKrQ`H?}#}p53>wZL@Nesahm0 zTwPMj$V3<);NdCV@^V@Ws~a4!hsWH#c6W^rr!92j7y|3OS@(<`e0zc?z9!z5&}Y=7 z8FNEGB_O`iKi-|)t%bD=ry4GQ_{YLxcU?$5r3be>er=4^>@j&zLx{X)#M^%qR{@<6 zNXv^heLOPUQf`U}vvnMi`OQJE3Mmkv)}WMmY|~o{Zn1?4Sk3mdXFuC!PM4$x6bwd>XNl&fqe97DMkdXy4(xfw?eqXs|u z?&i`u;76U`yY?SLTA-!nlIy!G{gwVv@g1V@sl}}`U)_8HGz+3(J^01)xpDY)v*y=z z?c?nq)$8gAi^vJBL z<=dA>*npX()y-2^9;u62@wX4(+{%KMktvJTDlWwp_3zQx2OMUJY&T@(j@mky{qo3w zOCy0<=leh0>UBl^GPQj(lgS#{`tk>lSBGF$yDa|d7B*lucuj%dWp(Y?@WL&?ETZ*| z{a4q+OlU%jId^nPjE_%9?$&dpW8VDv%6$90xfAH@HqesBIB03Mw8n>BB!2g<&sMK~cj@g7;1?k{Xzx7X7mpTEe&`pp z%N*CCK5osVa9%kz2PgSW-snS{zFfU}*|=N6FB&n&-NX9z?w!&t>4J!DTR5~&TH3YY zFl-k>th(fl0cpKclG?uQ2lRb?Z6S50C3jLKQ_h%-WpJ7WMJ1Dgad~sv8QKDn7cI7@byq(2!VQh}( zTK+L5-f|&qHZH!q`{hkzQ+e#&baRi(nl+A%ZV;(W3l_}Fm}Q+jq&r0I@OFG@~YIil<`p-z_6=ZWGo3Hf;imgb_W}WpAZi-!`&7LNP%-(ll?? z;Z677Y;G5hxTP`v)WK-(tb5F3dMDIe03ToR=2s?PVPi_3?=vyK#ffl#8y6?Eo4VZ^kA?!M{<*h|2R(NxJ=k9&G z!iP73<)8oMyz4sbGl*=HIv}xO|0T>ska2V8%^RE6%@=P?9W`ojO5^6wKJttGK2Om^ z#nd9qY_U#vE$P^@Nj$4-%XYkUE59e*9%kv-Z`l_^8o;wf08ho^dTlf)Xg9YS`uOwr zgD7>;Y+=aednG>i$3r`-rf5WJe|!4nj2?(f8nGV%G{>h;9XsguWHmlIA-Tt(iQ|X% zN{EkdB)$Ts8-H6%chn-H-Su7mb>{i&W17UYwBX}s@9rQljk$jC!cR7jYzou-l6C)> zln|j}YuZ)4oNv7QK6H-u|wDA|4Rn5m=t z^+-(6;#(vn_Z&E8#^e#bn?QEN=byd1sQ(o}wsqp@2fpyW!uc8%--u_A<;)*)Q?x+# zhH;O-v$b$+1IS(`+1hFBcfUK+Zf*xb53~1ueASO%{`00rkiBB^OFzAJcU&~r8PTn7 znvnJD&rc7;GUKm|4Mq0$fg>l}(Jd)H9>^y496WK>+^J0>JNVs~9_!b(8IZj$ePzK( z^#aH~@%xjh9iy!R**o6fe59laWNlZE`0R^8mxz^zE#~pv$ByPVitOd1|Gw(s8(LZs zJBLT#Jn_Q=rQ846FtS2fo69JyORoWU^iELYTP57yd&tak3fIfxGA0l12*O)h z$4`CZHzd59M%Fg^Uqi2iCfQp@T-!Z!PpMkfAhMByvzAMe7CitJjcj#o*E>Jgw2Cc% z#kILq*qCl(<_>I*FDNx%*&}-9D|=aM{#4A!7Eb?MNawg=(0!S=+XDTK4o8zC9d3byi?; zR9=HLvRE8hB3rhJ#xmM$8})khdRO@cP_+=%+W4@9tTkN{7J12a zOh=CSj<-sD-9@FWu zEzw2go{K>Uu~|Y=4@b9(}{Ww@#UAuvBVN4h3_7%k60+ER(RryC5#j2R!!9meLF2a_xg3ZU{T% zZ5kJk$!>2o^o?H*m0tjxD|$VYyQ{|JyC`hb_^`xewTrpW@Ts0AIfEY>2yfN4eft|9 z`Jn{Mt|piRSr3c8RBdk={Bmm3R@l*2-4&6VmC>mN+HV04z8GGOGSIjA;? z1X22gVQEdIP$F)g{M4#Hs*n{2mX$|-S~<3e(4`-4JX!;nfHcvOpWj=Y*eI6f zmbc7(bHkx>j|wbnetq+iVSmY?=vcP6ZOoE2$0`5=QbnrgaPH!vH#D9@(PcETYf9fS zbLYu4*xV^YdNUerY#D29pFH{@Yzd4ywe>};6q?92*erh={nY121sAuyl96_K1Na$f zu=YLYf408{X|VFQr}n!csy+|(6ko*Uaf6>f=3yGlU%BPMv>Vzqo^23TQi<0RtV3oC z)U5Ly<9eVT(kNnPYlrUddoi#IwE}pZa&~NC39FA+wDitcwb&-^s)pQzYu>Y;cgKPe=BttT(l&S8pguhifmnOq zF>Ls7Ww>S79et5lw|46_V8paKS=lK6`7MtQytyr?)cmsHo<}WnN8f6}YAqsh%Cldc zs*{$DI``Yk=}D1jY46-8U3pY_G-_;ITLvyy_J8#2B5!D3)>`<+q9GlD^(ARj7kM9z zTG*92_~uu4yDR%_Z7?ru^RAvXk6cP#{W3957+poOvN&x=|9TF8OY8|JF7@8PVzay~PzMM1&;3 z?f#l`M_)?5R6rSdJ<0;dgO`R);`LRN69TP8ifPIYCs~5|X<29y#4nx6*cG^&^8i^Xtf3T-9ab z*PeQnwjUM_zCK1&+N>SAOn#}TPNl8(%!~d0)(+)ETg!wgFKob8!$76Yv;XtC$?YSM znn9(_8r3o7$*m>zDs2M3@c9{YW{m0GRg@_0$vuWnos}`KE`aV5SN=SH|45?a?Hy+n zl*j^fM3wT~?zR6)6#%xp=ba5l0E1CFKnYFp9RB&4VOIda+g|(qa4GgL1prj4Pq}i2 zbqE&#w!C@nxBJU${|X?=$kMCd{j|y~yILe!F``qIvdPJL^_*kN$MO zKhd0&nCMNk^nGPld7Wx*)wh{KRQf#tNgE}T$I*l zPaNYL=^1GmJ$`!KlCnkdZCP6JjQRb|#dYB*-T#T_8SgWeR(gpRxS& zy`!OJ?NeX9_MGP#Kia>uxuziyEE(z3r}?LPrdp=Wm{S)9tE!y%b#vt=v+D$k*8v8h zzV9yGhl_5JFDzyIpl-*U@}<;z$2<(n6GYL-VXd*-P}7XSU(EIiPkt9Vem z+_HSd@)f-FE;r+ft(E2WXO}$o@RENm<7j+VgIBG1Vp>tP+?x6D!;e10&!x-F%U7&8 z!=734EP~tzV~$i>yJJkPt7Ej*rkFBZsd)MEiSIuBvm)-vX9}KKVp_+bff;}KF)T*3 zmX9rgzGwY>g?^LcJ_2Kbyho>@ktd|rp{HJG+b+)6+G4Wq?6Lw z-^q#=op8s5S6C-JwBrWuboQZ}A1|eog?DPjCC94~V`!b_*y5pLw3D;3s~4^KE?~ge zelaUQ+c;xqj7xA#q7nP^+AoI2kOYLcBGF10;0RE|K1gx*oi z!v!=tGICZQfC<4~;6?x=4YV)|xdXKUM3Ty+xx7QcBU0pmJJ!x7xT?id(2t+|;t?B3 zz4HSKA>V#^10VU2jAC7*sLV`MCosuDAa!8mpn(H=bxYus0vZy_ zAd(be6$GN0t;M@;x(Ok5O_5?l;S3dq_G`v^0P0_ zyzukgo|>q`KmVhD*SO@qPp)yDtMt`Goj<+#&6(X2V&nRzKmUdIJL{U~XQjn^W23}m z0v-%S%&3pTpyH+qu%vsS=1D(7kq=rP5E9es0Saw3<16|NJ&wX7K|;DH@fhkxvM|6Q z6Xcw_P||}*b0F=qc+UCsn2E9!q=_9g>3;v}!)~pmQv8@81!jkN(cB;gX`{s55*s)B zt?zg5!oR&IJgV}O^Uk=z8S75h`py^c-L>oR>1ws|z{?X-lhe|(e?^U;dBv~U)6)_K zVFfUZf20SYVCxYEb)PCD@l~Z$HH3-*8=0-40sNle5H6+Rry(<9GJq!?tU*Jm$x@L> z7wN+YK}$hcKxJSlO%m^VrI!^pD}**sr5=k`AHit=r3ADwEU)Ia9C(PLrN;g(uHS^Y z4>_F=J({`tjHaF`T#~pbcb``||L3Qf&WB#kJE-|9w!S{5SNiL_&MRK6h5!7Yug^&# z#{?JzPxre3P+CJHhL9pbP8u)i^C<*ER3zpBBrt&CeFEVP$t^WWFkfEQ3W`Y~kuoZA zQ39-xAptv6l06_i--Cp?q*rQkm%E>Md)>M%XK|uzXa2gi?@bXCL11+oLnAEQZfso2 z&?)oOjP45`eDSBlUQfk}q$L|m6!*c89vwAs;LK-!sPuXdd^TnHD_bj6<=|KA)_w8K zVXsoQ?WMuG!3H5D;B;`opqbZF5)6eC(TJdyR0;_;MM)k?mUe#bpX(|;=Ru$iCEha|9vRv#J|S&%Hp;Rf(3D@js^VKcNbM6j z`twSk>iuDCqI9)X5CJX8L~l=-5dSb=YhK9z`pwulsVj^r^+1op5Qt9vBHT6zW5hyW z<`w#&oDBa0!^vx()FJrDxL6MeW71uzVc_Fx*dRzD8-yq}HeO9==_sgBw*G5kLOfg$ zVTF?v21wFKfri}Pf6;qiZ}D$V`f<%RHzX+Wk#COrs}Fp-^nnHQ7r*#(SuF@O`JMv5 zswzJ^?_D@`!ozRx^>}|AmncA!UV+4s@Q z7pTJL8TFLpcq*Y9TVjbvI+E+1o0VU!R?z z2VVq4(x)XIIoS}GFlfg6C#yBT8e4Vrl+RP~LgIpt_IQ=rk{#>UtjXVV7CUl5pou@? zRI7Sm?dPAZSaj#OwIwIljZX9jC0PrJ(WG@SB1jpbQbdH_7#sz_dcXoSfV@W#Nv^&C zl{8!k!gaAB+CHg5cow8BdMaEV5EC*+hTZxapDM%H&<}D8Z;0!l47EapEc@v+LOW@6 zhAn~z>yJ>7W5#vs_uywcYe0~Sipr|0iW(IpiW@xZyT|~qOLta z#GjUkA}H4!)HqVjpt=-A;nn2;()tMXmQ#x`fbNe?gLW=R9}BIJ%FtZU=bz*8fsWNW zoaCW?k=Px2jeYGzm0ERj=f+K2w(hI+Yf!PcxbFA8@2ad(YOiotSDd4UO-V|ble>NY zDIA@zE!+R&3$yz}zlehoHN$lUm{?24hELLX>nmn8j!h&_$aNh#GPo|@B4*YHlQE*` zL{gC!5E)@^NH|G65pIde36P8?@JOhn^q`6JW9Ikz^vw^fdVAk!aKVQ-;X(kc5D6 z@3j(dxwe&r3Q50#IFd9n?$+X>l?xE3E_~rlC8y(C*&nVyMCznWo;xr7p2yz#e$R=r zT7UJf?AfVkh5y7-mtssvum~Cc1xHSB{yuvC$M^FqU zMun14iS?*Qq&h;}zF}V|C5AG>XJ8y%XCbaq#R*-AE5kxPS)p%`S~fw(Q#6ypk69>3 zYTPBUL+)Gatv&r*ceQAR5E_w>BGaXr7C`Fy#&x+6G*Uw1F0H(zuD;@shDJIq zY3T^Mz>znlW5iT?_6;-97E&(JMyN2k$Cor|RD3=R$`Ti)k{ddOL<7Bylx3Wz&Fl3j`%A)%&FRl@y`mqT%G8_d(U!h8cf zH8yU@!Zp}?{&Ul@gYPfuo0K?q$&Y@;v;UJxQ-4#nnp4@` z)x>6l)_4?6{TUGw#exzblSjgoL(mLICIB-+6+a#bk&_&j21US4B1t+6O7V$T+|unA zH9`sq^-q{*-V$Oe;v;fMBu9WIC7FDQ6#^$%K>9HhprHuT2zk_G(J#VqZ)m0~xF8WU zj}+=1*K6#*51m)b5B>1L2OoX5317@1EO_r13(uDC-SF9mAAG&_xZ*wgN+0@q(+;iTL!;meVj`)Af-^Q%y|bCP>7!Yj6$9*3oD~Bqx9wAP#y|T8SRaMpB5{XFV^!De+rVe^?-7z=r`0-UC z?!)Vz=tsz8SjT(?EjL*%ga_~#&PUpM$$3En0lwZ<@|lD&h#;3HM#^3vhbuiMA?1I* zLo(^tv_Nu5e}r+x&}0_)BIQ)(7B~aD2IZ+eTpq^?giE{>|Afnf&glXb5f`64e8ES@ z@kMZIi;Dfn5pu7Hi|sn?r9zK_JDT5}_tb=*iQR@e*X;G6O*5@#-{%hur$P(B<)CtG z0^UMQD#0ND(!%O~5va+9hQL>{mV_k<@kUMua_z)WT01_(GhJa}rDXz`e2|tK7gDbk znHeE860TTDDMdyI`hAWZy1}TH}Eq+>+yKU=+M-e&ooAJ)(-+X^WZTsb!;XN@(!m!0Tzk2_$ZCv&E(8PF7BrP<+ zmZ6R=BjPs6BBTS5v6&2s{E~>cN2mz2Uk@dMpOug#s%%FP@ti@p&@-k4M9GDzT#<>< z+ey2KhmdJL17uzjk`o05NK0)CgT#NS6K5}+)UO-oW+M{4ORov{&JCN^PmODbn}`4s z`;VV>@4ffkckg|(MopYQZ`Kf~Z(_>WIScN+PrbLreHrO@Br^pP+qM6=dAMUo!?|Po zbv2@GC_Nq$UcDj}%q1DVT(F(by}_uGzzAn9Oe}TOClQg7B^8whg$)fk1AUAjowsD& zQ7;V$WB`Zm4mq95QUdOiw!{DzBGw2}%7%~$_Yq$vrt}%mD+!2F5rn%)N*T~MtXCH< zios*!61(?T2518<1NwGPpu|WT ziL{;+V}c@}0U!YdAyf<+L8hQJm6FHL)GMhi=*gI!_C=FnH_@W7$N{)|m6+m!`7+@p z4JnqEo^*!FvS2O)HR%bxG6V@y#?mX5akp;&aHYzCM9u)Q5pg;-+l-7o%|LuS0HIjg z5GBUP>%0FV1 zPD*8wEr2B0#2$o`(~^2@A#-hF5=hwq>6TX7Ny zL>6%^u7LrOCbcNly0(dHonmND0`QXvRz#g$a8q{Ta$XF81|&A;gJ5xsp$)dF$BFdT}q z%9of-_SR(>>z-hLv@~o2)k^jyF{A;Ic+}E#DyY5jwj!clVdCf^1Os_jDv&B7U^$=o z8`!%dWJNEb2^>f?Nf5~`;AG?(_CPozZZCak3(s7_N}8|yn^@(C`-(6fESm7Y^-A0?Ok@&O)>E<9jJIm?Hqbuv`? zDAJ~RsB2t9$*u&R@pyZr!Xy+;$YNl!uD!XID4_3A1!R+T3l-Q z=*LJZ-mPK+4#7s@qPZB^CORia8h7wfNfI}CK`?yDVaDVN#!{0t0w4g9Goy=|6hi=T z#W(q10IU*&QgEIVS4*8G2@gDs5|34YD_{ + for(var c = document.getElementsByTagName("a"), a = 0;a < c.length;a++) { + var b = c[a]; + ((b.getAttribute("href") && b.hostname !== location.hostname) || (b.getAttribute("data-newtab")==true)) && (b.target = "_blank") + } + for(var c=document.getElementsByTagName("ol"), a=0; a{ + if(!child.getAttribute("data-before")) + child.setAttribute("data-before", pad(i.toString(2), Math.log2(b.children.length))); + }); + } + } +}); +function pad(num, size) { + var s = "000000000" + num; + return s.substr(s.length-size); +} + diff --git a/build/multiplexer/index.html b/build/multiplexer/index.html new file mode 100755 index 0000000..e9c0e76 --- /dev/null +++ b/build/multiplexer/index.html @@ -0,0 +1,28 @@ + + + + Build a multiplexer + + + + +

Build a multiplexer!

+

+ The multiplexer chip used in this CPU is a 16:8 mux - this means it can select between two 8-bit inputs.

+ Don't worry, this is an extremely simple chip to construct. To start with, you must build from logic gates a 2:1 mux which can switch between two individual bits. Then you can use 8 of these 2:1 muxes to build this chip. +

+ +

Start building

+
    +
  1. construct 2:1 mux
  2. +
  3. assemble 16:8 mux
  4. + +
+

+ Once you are finished, you can return to the CPU. +

+ + diff --git a/build/registers/index.html b/build/registers/index.html new file mode 100755 index 0000000..080f3a5 --- /dev/null +++ b/build/registers/index.html @@ -0,0 +1,23 @@ + + + + Build a multiplexer + + + +

Build a multiplexer!

+

+ The multiplexer chip used in this CPU is a 16:8 mux - this means it can select between two 8-bit inputs. +
+ Don't worry, this is an extremely simple chip to construct. To start with, you must build from logic gates a 2:1 mux which can switch between two individual bits. Then you can use 8 of these 2:1 muxes to build this chip. +

+

Start building

+
    +
  1. construct 2:1 mux
  2. +
  3. assemble 16:8 mux
  4. +
+

+ Once you are finished, you can return to the CPU. +

+ + diff --git a/cheat/index.html b/cheat/index.html new file mode 100755 index 0000000..04d0974 --- /dev/null +++ b/cheat/index.html @@ -0,0 +1,3 @@ + diff --git a/css/generator_config.txt b/css/generator_config.txt new file mode 100755 index 0000000..81e64f6 --- /dev/null +++ b/css/generator_config.txt @@ -0,0 +1,5 @@ +# Font Squirrel Font-face Generator Configuration File +# Upload this file to the generator to recreate the settings +# you used to create these fonts. + +{"mode":"optimal","formats":["woff","woff2"],"tt_instructor":"default","fix_gasp":"xy","fix_vertical_metrics":"Y","metrics_ascent":"","metrics_descent":"","metrics_linegap":"","add_spaces":"Y","add_hyphens":"Y","fallback":"none","fallback_custom":"100","options_subset":"basic","subset_custom":"","subset_custom_range":"","subset_ot_features_list":"","css_stylesheet":"stylesheet.css","filename_suffix":"-webfont","emsquare":"2048","spacing_adjustment":"0"} \ No newline at end of file diff --git a/css/specimen_files/grid_12-825-55-15.css b/css/specimen_files/grid_12-825-55-15.css new file mode 100755 index 0000000..3d6aef7 --- /dev/null +++ b/css/specimen_files/grid_12-825-55-15.css @@ -0,0 +1,129 @@ +/*Notes about grid: +Columns: 12 +Grid Width: 825px +Column Width: 55px +Gutter Width: 15px +-------------------------------*/ + + + +.section {margin-bottom: 18px; +} +.section:after {content: ".";display: block;height: 0;clear: both;visibility: hidden;} +.section {*zoom: 1;} + +.section .firstcolumn, +.section .firstcol {margin-left: 0;} + + +/* Border on left hand side of a column. */ +.border { + padding-left: 7px; + margin-left: 7px; + border-left: 1px solid #eee; +} + +/* Border with more whitespace, spans one column. */ +.colborder { + padding-left: 42px; + margin-left: 42px; + border-left: 1px solid #eee; +} + + + +/* The Grid Classes */ +.grid1, .grid1_2cols, .grid1_3cols, .grid1_4cols, .grid2, .grid2_3cols, .grid2_4cols, .grid3, .grid3_2cols, .grid3_4cols, .grid4, .grid4_3cols, .grid5, .grid5_2cols, .grid5_3cols, .grid5_4cols, .grid6, .grid6_4cols, .grid7, .grid7_2cols, .grid7_3cols, .grid7_4cols, .grid8, .grid8_3cols, .grid9, .grid9_2cols, .grid9_4cols, .grid10, .grid10_3cols, .grid10_4cols, .grid11, .grid11_2cols, .grid11_3cols, .grid11_4cols, .grid12 +{margin-left: 15px;float: left;display: inline; overflow: hidden;} + + +.width1, .grid1, .span-1 {width: 55px;} +.width1_2cols,.grid1_2cols {width: 20px;} +.width1_3cols,.grid1_3cols {width: 8px;} +.width1_4cols,.grid1_4cols {width: 2px;} +.input_width1 {width: 49px;} + +.width2, .grid2, .span-2 {width: 125px;} +.width2_3cols,.grid2_3cols {width: 31px;} +.width2_4cols,.grid2_4cols {width: 20px;} +.input_width2 {width: 119px;} + +.width3, .grid3, .span-3 {width: 195px;} +.width3_2cols,.grid3_2cols {width: 90px;} +.width3_4cols,.grid3_4cols {width: 37px;} +.input_width3 {width: 189px;} + +.width4, .grid4, .span-4 {width: 265px;} +.width4_3cols,.grid4_3cols {width: 78px;} +.input_width4 {width: 259px;} + +.width5, .grid5, .span-5 {width: 335px;} +.width5_2cols,.grid5_2cols {width: 160px;} +.width5_3cols,.grid5_3cols {width: 101px;} +.width5_4cols,.grid5_4cols {width: 72px;} +.input_width5 {width: 329px;} + +.width6, .grid6, .span-6 {width: 405px;} +.width6_4cols,.grid6_4cols {width: 90px;} +.input_width6 {width: 399px;} + +.width7, .grid7, .span-7 {width: 475px;} +.width7_2cols,.grid7_2cols {width: 230px;} +.width7_3cols,.grid7_3cols {width: 148px;} +.width7_4cols,.grid7_4cols {width: 107px;} +.input_width7 {width: 469px;} + +.width8, .grid8, .span-8 {width: 545px;} +.width8_3cols,.grid8_3cols {width: 171px;} +.input_width8 {width: 539px;} + +.width9, .grid9, .span-9 {width: 615px;} +.width9_2cols,.grid9_2cols {width: 300px;} +.width9_4cols,.grid9_4cols {width: 142px;} +.input_width9 {width: 609px;} + +.width10, .grid10, .span-10 {width: 685px;} +.width10_3cols,.grid10_3cols {width: 218px;} +.width10_4cols,.grid10_4cols {width: 160px;} +.input_width10 {width: 679px;} + +.width11, .grid11, .span-11 {width: 755px;} +.width11_2cols,.grid11_2cols {width: 370px;} +.width11_3cols,.grid11_3cols {width: 241px;} +.width11_4cols,.grid11_4cols {width: 177px;} +.input_width11 {width: 749px;} + +.width12, .grid12, .span-12 {width: 825px;} +.input_width12 {width: 819px;} + +/* Subdivided grid spaces */ +.emptycols_left1, .prepend-1 {padding-left: 70px;} +.emptycols_right1, .append-1 {padding-right: 70px;} +.emptycols_left2, .prepend-2 {padding-left: 140px;} +.emptycols_right2, .append-2 {padding-right: 140px;} +.emptycols_left3, .prepend-3 {padding-left: 210px;} +.emptycols_right3, .append-3 {padding-right: 210px;} +.emptycols_left4, .prepend-4 {padding-left: 280px;} +.emptycols_right4, .append-4 {padding-right: 280px;} +.emptycols_left5, .prepend-5 {padding-left: 350px;} +.emptycols_right5, .append-5 {padding-right: 350px;} +.emptycols_left6, .prepend-6 {padding-left: 420px;} +.emptycols_right6, .append-6 {padding-right: 420px;} +.emptycols_left7, .prepend-7 {padding-left: 490px;} +.emptycols_right7, .append-7 {padding-right: 490px;} +.emptycols_left8, .prepend-8 {padding-left: 560px;} +.emptycols_right8, .append-8 {padding-right: 560px;} +.emptycols_left9, .prepend-9 {padding-left: 630px;} +.emptycols_right9, .append-9 {padding-right: 630px;} +.emptycols_left10, .prepend-10 {padding-left: 700px;} +.emptycols_right10, .append-10 {padding-right: 700px;} +.emptycols_left11, .prepend-11 {padding-left: 770px;} +.emptycols_right11, .append-11 {padding-right: 770px;} +.pull-1 {margin-left: -70px;} +.push-1 {margin-right: -70px;margin-left: 18px;float: right;} +.pull-2 {margin-left: -140px;} +.push-2 {margin-right: -140px;margin-left: 18px;float: right;} +.pull-3 {margin-left: -210px;} +.push-3 {margin-right: -210px;margin-left: 18px;float: right;} +.pull-4 {margin-left: -280px;} +.push-4 {margin-right: -280px;margin-left: 18px;float: right;} \ No newline at end of file diff --git a/css/specimen_files/specimen_stylesheet.css b/css/specimen_files/specimen_stylesheet.css new file mode 100755 index 0000000..aecc43c --- /dev/null +++ b/css/specimen_files/specimen_stylesheet.css @@ -0,0 +1,396 @@ +@import url('grid_12-825-55-15.css'); + +/* + CSS Reset by Eric Meyer - Released under Public Domain + http://meyerweb.com/eric/tools/css/reset/ +*/ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, table, +caption, tbody, tfoot, thead, tr, th, td + {margin: 0;padding: 0;border: 0;outline: 0; + font-size: 100%;vertical-align: baseline; + background: transparent;} +body {line-height: 1;} +ol, ul {list-style: none;} +blockquote, q {quotes: none;} +blockquote:before, blockquote:after, +q:before, q:after {content: ''; content: none;} +:focus {outline: 0;} +ins {text-decoration: none;} +del {text-decoration: line-through;} +table {border-collapse: collapse;border-spacing: 0;} + + + + +body { + color: #000; + background-color: #dcdcdc; +} + +a { + text-decoration: none; + color: #1883ba; +} + +h1{ + font-size: 32px; + font-weight: normal; + font-style: normal; + margin-bottom: 18px; +} + +h2{ + font-size: 18px; +} + +#container { + width: 865px; + margin: 0px auto; +} + + +#header { + padding: 20px; + font-size: 36px; + background-color: #000; + color: #fff; +} + +#header span { + color: #666; +} +#main_content { + background-color: #fff; + padding: 60px 20px 20px; +} + + +#footer p { + margin: 0; + padding-top: 10px; + padding-bottom: 50px; + color: #333; + font: 10px Arial, sans-serif; +} + +.tabs { + width: 100%; + height: 31px; + background-color: #444; +} +.tabs li { + float: left; + margin: 0; + overflow: hidden; + background-color: #444; +} +.tabs li a { + display: block; + color: #fff; + text-decoration: none; + font: bold 11px/11px 'Arial'; + text-transform: uppercase; + padding: 10px 15px; + border-right: 1px solid #fff; +} + +.tabs li a:hover { + background-color: #00b3ff; + +} + +.tabs li.active a { + color: #000; + background-color: #fff; +} + + + +div.huge { + + font-size: 300px; + line-height: 1em; + padding: 0; + letter-spacing: -.02em; + overflow: hidden; +} +div.glyph_range { + font-size: 72px; + line-height: 1.1em; +} + +.size10{ font-size: 10px; } +.size11{ font-size: 11px; } +.size12{ font-size: 12px; } +.size13{ font-size: 13px; } +.size14{ font-size: 14px; } +.size16{ font-size: 16px; } +.size18{ font-size: 18px; } +.size20{ font-size: 20px; } +.size24{ font-size: 24px; } +.size30{ font-size: 30px; } +.size36{ font-size: 36px; } +.size48{ font-size: 48px; } +.size60{ font-size: 60px; } +.size72{ font-size: 72px; } +.size90{ font-size: 90px; } + + +.psample_row1 { height: 120px;} +.psample_row1 { height: 120px;} +.psample_row2 { height: 160px;} +.psample_row3 { height: 160px;} +.psample_row4 { height: 160px;} + +.psample { + overflow: hidden; + position: relative; +} +.psample p { + line-height: 1.3em; + display: block; + overflow: hidden; + margin: 0; +} + +.psample span { + margin-right: .5em; +} + +.white_blend { + width: 100%; + height: 61px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVkAAAA9CAYAAAAH4BojAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAO1JREFUeNrs3TsKgFAMRUE/eer+NxztxMYuEWQG3ECKwwUF58ycAKixOAGAyAKILAAiCyCyACILgMgCiCyAyAIgsgAiCyCyAIgsgMgCiCwAIgsgsgAiC4DIAogsACIL0CWuZ3UGgLrIhjMA1EV2OAOAJQtgyQLwjOzmDAAiCyCyAIgsQFtkd2cAEFkAkQVAZAHaIns4A4AlC2DJAiCyACILILIAiCzAV5H1dQGAJQsgsgCILIDIAvwisl58AViyAJYsACILILIAIgvAe2T9EhxAZAFEFgCRBeiL7HAGgLrIhjMAWLIAliwAt1OAAQDwygTBulLIlQAAAABJRU5ErkJggg==); + position: absolute; + bottom: 0; +} +.black_blend { + width: 100%; + height: 61px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVkAAAA9CAYAAAAH4BojAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNrs3TEKhTAQRVGjibr/9QoxhY2N3Ywo50A28IrLwP9g6b1PAMSYTQAgsgAiC4DIAogsgMgCILIAIgsgsgCILIDIAogsACILILIAIguAyAKILIDIAiCyACILgMgCZCnjLWYAiFGvB0BQZJsZAFyyAC5ZAO6RXc0AILIAIguAyAKkRXYzA4DIAogsACILkBbZ3QwALlkAlywAIgsgsgAiC4DIArwVWf8uAHDJAogsACILILIAv4isH74AXLIALlkARBZAZAFEFoDnyPokOIDIAogsACILkBfZZgaAuMhWMwC4ZAE+p4x3mAEgxinAAJ+XBbPWGkwAAAAAAElFTkSuQmCC); + position: absolute; + bottom: 0; +} +.fullreverse { + background: #000 !important; + color: #fff !important; + margin-left: -20px; + padding-left: 20px; + margin-right: -20px; + padding-right: 20px; + padding: 20px; + margin-bottom:0; +} + + +.sample_table td { + padding-top: 3px; + padding-bottom:5px; + padding-left: 5px; + vertical-align: middle; + line-height: 1.2em; +} + +.sample_table td:first-child { + background-color: #eee; + text-align: right; + padding-right: 5px; + padding-left: 0; + padding: 5px; + font: 11px/12px "Courier New", Courier, mono; +} + +code { + white-space: pre; + background-color: #eee; + display: block; + padding: 10px; + margin-bottom: 18px; + overflow: auto; +} + + +.bottom,.last {margin-bottom:0 !important; padding-bottom:0 !important;} + +.box { + padding: 18px; + margin-bottom: 18px; + background: #eee; +} + +.reverse,.reversed { background: #000 !important;color: #fff !important; border: none !important;} + +#bodycomparison { + position: relative; + overflow: hidden; + font-size: 72px; + height: 90px; + white-space: nowrap; +} + +#bodycomparison div{ + font-size: 72px; + line-height: 90px; + display: inline; + margin: 0 15px 0 0; + padding: 0; +} + +#bodycomparison div span{ + font: 10px Arial; + position: absolute; + left: 0; +} +#xheight { + float: none; + position: absolute; + color: #d9f3ff; + font-size: 72px; + line-height: 90px; +} + +.fontbody { + position: relative; +} +.arialbody{ + font-family: Arial; + position: relative; +} +.verdanabody{ + font-family: Verdana; + position: relative; +} +.georgiabody{ + font-family: Georgia; + position: relative; +} + +/* @group Layout page + */ + +#layout h1 { + font-size: 36px; + line-height: 42px; + font-weight: normal; + font-style: normal; +} + +#layout h2 { + font-size: 24px; + line-height: 23px; + font-weight: normal; + font-style: normal; +} + +#layout h3 { + font-size: 22px; + line-height: 1.4em; + margin-top: 1em; + font-weight: normal; + font-style: normal; +} + + +#layout p.byline { + font-size: 12px; + margin-top: 18px; + line-height: 12px; + margin-bottom: 0; +} +#layout p { + font-size: 14px; + line-height: 21px; + margin-bottom: .5em; +} + +#layout p.large{ + font-size: 18px; + line-height: 26px; +} + +#layout .sidebar p{ + font-size: 12px; + line-height: 1.4em; +} + +#layout p.caption { + font-size: 10px; + margin-top: -16px; + margin-bottom: 18px; +} + +/* @end */ + +/* @group Glyphs */ + +#glyph_chart div{ + background-color: #d9f3ff; + color: black; + float: left; + font-size: 36px; + height: 1.2em; + line-height: 1.2em; + margin-bottom: 1px; + margin-right: 1px; + text-align: center; + width: 1.2em; + position: relative; + padding: .6em .2em .2em; +} + +#glyph_chart div p { + position: absolute; + left: 0; + top: 0; + display: block; + text-align: center; + font: bold 9px Arial, sans-serif; + background-color: #3a768f; + width: 100%; + color: #fff; + padding: 2px 0; +} + + +#glyphs h1 { + font-family: Arial, sans-serif; +} +/* @end */ + +/* @group Installing */ + +#installing { + font: 13px Arial, sans-serif; +} + +#installing p, +#glyphs p{ + line-height: 1.2em; + margin-bottom: 18px; + font: 13px Arial, sans-serif; +} + + + +#installing h3{ + font-size: 15px; + margin-top: 18px; +} + +/* @end */ + +#rendering h1 { + font-family: Arial, sans-serif; +} +.render_table td { + font: 11px "Courier New", Courier, mono; + vertical-align: middle; +} + + diff --git a/css/style.css b/css/style.css new file mode 100755 index 0000000..a81b3b9 --- /dev/null +++ b/css/style.css @@ -0,0 +1,87 @@ +* { + margin:0; +} +body,html{ + color:#5be55b; + background-color:#191a1d; + width:100vw; + height:100vh; + display: flex; + flex-direction:column; + flex-wrap:wrap; + align-content:flex-start; + font-family:vcr_osd_monoregular; +} +canvas { + width:75vw; + height:100vh; + background-color:#36393E; +} +.center_holder{ + margin-left:-10px; + margin-right:-10px; + width:100%; + display:flex; + justify-content:center; +} +.right_holder{ + width:100%; + display: flex; + justify-content:right; +} +#compile{ + margin-top:5px; + margin-right:25px; +} +#program{ + width:90%; + height:20vh; +} +#sidebar{ + padding-left:10px; + padding-top:10px; + padding-right:10px; + padding-bottom:10px; + width:25vw; + height:100vh; +} +#memory{ + margin-top:5px; + /*font-size:13px; + line-height:15px; + */ + font-size: 0.65vw; + line-height:0.7vw; + color:#AAA; +} +#memory .written { + color: #FFF; +} +#memory tr td { + border-left: 1px solid #AAA; + border-bottom: 1px solid #AAA; +} +.label { + color: #5be55b; + border-left: none !important; +} +textarea::before{ + background-color:grey; + display:block; + content:''; + position:absolute; + height:20vh; + width:90%; +} +textarea { + color: white; + background-color: grey; + background: url(http://i.imgur.com/2cOaJ.png); + background-attachment: local; + background-repeat: no-repeat; + padding-left: 35px; + padding-top: 10px; + font-size:13px; + line-height:16px; + border-color:#ccc; +} diff --git a/css/stylesheet.css b/css/stylesheet.css new file mode 100755 index 0000000..0bc97b1 --- /dev/null +++ b/css/stylesheet.css @@ -0,0 +1,12 @@ +/*! Generated by Font Squirrel (https://www.fontsquirrel.com) on February 20, 2022 */ + + + +@font-face { + font-family: 'vcr_osd_monoregular'; + src: url('vcr_osd_mono_1.001-webfont.woff2') format('woff2'), + url('vcr_osd_mono_1.001-webfont.woff') format('woff'); + font-weight: normal; + font-style: normal; + +} diff --git a/css/vcr_osd_mono_1.001-demo.html b/css/vcr_osd_mono_1.001-demo.html new file mode 100755 index 0000000..e3ee752 --- /dev/null +++ b/css/vcr_osd_mono_1.001-demo.html @@ -0,0 +1,602 @@ + + + + + + + + + + + + + VCR OSD Mono Regular Specimen + + + + + + +
+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyVCR OSD Mono Regular +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of VCR OSD Mono Regular in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, English, Faroese, Finnish, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Alsatian, Aragonese, Arapaho, Arrernte, Asturian, Aymara, Bislama, Cebuano, Corsican, Fijian, French_creole, Genoese, Gilbertese, Greenlandic, Haitian_creole, Hiligaynon, Hmong, Hopi, Ibanag, Iloko_ilokano, Indonesian, Interglossa_glosa, Interlingua, Irish_gaelic, Jerriais, Lojban, Lombard, Luxembourgeois, Manx, Mohawk, Norfolk_pitcairnese, Occitan, Oromo, Pangasinan, Papiamento, Piedmontese, Potawatomi, Rhaeto-romance, Romansh, Rotokas, Sami_lule, Sardinian, Scots_gaelic, Seychelles_creole, Shona, Sicilian, Somali, Southern_ndebele, Swahili, Swati_swazi, Tagalog_filipino_pilipino, Tetum, Tok_pisin, Uyghur_latinized, Volapuk, Walloon, Warlpiri, Xhosa, Yapese, Zulu, Latinbasic, Ubasic, Demo

+

Glyph Chart

+

The subset of VCR OSD Mono Regular in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +

&#29;


+

&#13;

+

&#29;


+

&#32;

+

&#33;

!
+

&#34;

"
+

&#35;

#
+

&#36;

$
+

&#37;

%
+

&#38;

&
+

&#39;

'
+

&#40;

(
+

&#41;

)
+

&#42;

*
+

&#43;

+
+

&#44;

,
+

&#45;

-
+

&#46;

.
+

&#47;

/
+

&#48;

0
+

&#49;

1
+

&#50;

2
+

&#51;

3
+

&#52;

4
+

&#53;

5
+

&#54;

6
+

&#55;

7
+

&#56;

8
+

&#57;

9
+

&#58;

:
+

&#59;

;
+

&#60;

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#165;

¥
+

&#166;

¦
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#173;

­
+

&#174;

®
+

&#176;

°
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8220;

+

&#8221;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + \ No newline at end of file diff --git a/css/vcr_osd_mono_1.001-webfont.woff b/css/vcr_osd_mono_1.001-webfont.woff new file mode 100755 index 0000000000000000000000000000000000000000..5b551c357d5f9e12e43fd8709e4021a1358d18e6 GIT binary patch literal 19632 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 BUmgGe literal 0 HcmV?d00001 diff --git a/css/vcr_osd_mono_1.001-webfont.woff2 b/css/vcr_osd_mono_1.001-webfont.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..9e8d3ac320b30e4bb391afc6302616881b4ce6da GIT binary patch literal 15040 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 WII&6Vl6mZ%K*>`{^?q*aC@=t|Bm`Ul literal 0 HcmV?d00001 diff --git a/css/webfontkit-20220220-160412.zip b/css/webfontkit-20220220-160412.zip new file mode 100755 index 0000000000000000000000000000000000000000..806fcd0712ad5d455e56221d850da655d262b1bb GIT binary patch literal 47572 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 literal 0 HcmV?d00001 diff --git a/img/pencil.png b/img/pencil.png new file mode 100755 index 0000000000000000000000000000000000000000..5de29cef5346591cb9a00e7fb51d27574a530179 GIT binary patch literal 5563 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 + + + + + CPU sim + + + + + + + + + + + + + + + diff --git a/js/assembler copy.js b/js/assembler copy.js new file mode 100755 index 0000000..d0facf3 --- /dev/null +++ b/js/assembler copy.js @@ -0,0 +1,294 @@ +Array.prototype.findIndexes=function(where) { + return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []); +} +class assembler { + labels = []; + labelAddresses = []; + address = 0; + curLine = 0; + + offset = 0; // account for any instructions the assembler needs to add + upper8(address){ + return address>>8; + } + lower8(address){ + return address&0x00FF; + } + intByte(n){ + n=n.replace("#",""); + var invert = false; + if(n[0]=="~") { invert=true; n=n.slice(1)}; + var b = 0; + if(n.match(/^0b/)){ + b = parseInt(n.slice(2),2); + } else { + b = parseInt(n); + } + if(isNaN(b)) { + throw 'Invalid number'; + } else if(b>255 || b <-128){ + throw 'Number will not fit in a byte!'; + } + if(b<0){ + // apply 2's complement to negative value + var r= ~Math.abs(b)+1; + } else { + var r= b; + }; + return invert ? ((~r>>>0)&0xFF) : r; + } + encodeInstruction(line){ + var bytes = [0,0]; + var instruction = instructions.opcodes.find(oc=>oc.mnemonic==line[0].toLowerCase()); + if(instruction.mnemonic=="bflag"||instruction.mnemonic=="bnoflag") { + var flag = instructions.flags.indexOf(line[1]); + if(flag>=0){ + // evil stupid dumb + line[1] = line[1].replace(instructions.flags[flag],instructions.registers[flag]); + + } else throw 'Invalid flag.'; + } + if(!instruction) throw 'Unknown opcode'; + var patterns = instructions.arg_patterns[instruction.patterns]; + var mode = -1; + if(patterns[0].pattern.length!=line.length-1){ + throw 'Wrong number of operands'; + } else if(patterns.length==1){ + mode = patterns[0].mode; + } else { + patterns.forEach(pattern=>{ + var fit=0; + for(var i=0;i{ + var l; + var mnemonic = instruction[0].toLowerCase(); + this.curLine = i; + var offset=0; + // dealing with pseudo instructions + if(mnemonic==".data"){ + return; + /* + } else if(mnemonic=="hlt"){ // halt: jump to same instruction + if(this.upper8(instAddr)!=instPage){ + instPage=this.upper8(instAddr); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + offset=2; + } + bytecode = bytecode.concat(this.encodeInstruction(["jmp","#"+this.lower8(instAddr+offset)])); + } else if(mnemonic=="nop"){ // nop: jump to next instruction + if(this.upper8(instAddr+2)!=instPage){ + offset=2; + instPage=this.upper8(instAddr); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + } + bytecode = bytecode.concat(this.encodeInstruction(["jmp","#"+this.lower8(instAddr+2+offset)])); + */ + // now process labels + } else if(mnemonic=="jsr"||mnemonic=="jmp"){ + instruction[1] = instruction[1].replace("SKIP",'#'+(instAddr+4+offset)); + l = this.labelAddresses.find(la=>instruction[1].includes(la.label)); + + if(l){ // we must replace + instruction[1] = instruction[1].replace(l.label, "#"+this.lower8(l.address)); + if(this.upper8(l.address)!=instPage){ + instPage=this.upper8(l.address); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ip","#"+instPage])); + offset=2; + } + } + console.log(instruction); + bytecode=bytecode.concat(this.encodeInstruction(instruction)); + } else if(mnemonic=="stb"||mnemonic=="ldb"||mnemonic=="mov"||mnemonic=="bflag"||mnemonic=="bnoflag"){ + // QUICK AND DIRTY: WILL BREAK UNDER CERTAIN CONDITIONS + instruction[2] = instruction[2].replace("SKIP",'#'+(instAddr+4+offset)); + l = this.labelAddresses.find(la=>instruction[2].includes(la.label)); + if(l){ // we must replace + instruction[2] = instruction[2].replace(l.label, "#"+this.lower8(l.address)); + if(this.upper8(l.address)!=dataPage){ + dataPage=this.upper8(l.address); + bytecode=bytecode.concat(this.encodeInstruction(["mov","dp","#"+dataPage])); + offset=2; + } + } + bytecode=bytecode.concat(this.encodeInstruction(instruction)); + } else bytecode=bytecode.concat(this.encodeInstruction(instruction)); + console.log({i:i, l:this.labels}); + l = this.labels.findIndex(la=>la.line==i); + if(l>-1){ + this.labelAddresses.push({label: this.labels[l].label, address: instAddr}); + } + instAddr += 2 + offset; + }); + return bytecode; + } + assemble(code) { + // try + var tokens = this.tokenize(code).filter(line=>line.length>0 &&line[0]!=''); + console.log(tokens); + var withPseudo = this.processAndOr(tokens); + var delabeled = this.processLabels(withPseudo); + var data = this.processData(delabeled); + var bytecode = this.processInstructions(delabeled); + var pad = data.bytes.length>0?Array(data.start - bytecode.length).fill(0):[]; + console.log({tokens,withPseudo,delabeled,data,bytecode}) + + return bytecode.concat(pad).concat(data.bytes); + // catch + } + processAndOr(tokenLines) { + var processed=[]; + tokenLines.forEach(line=>{ + if(line.length<2){ + processed.push(line) + } + else if(line[0].toLowerCase()=="and") { + line[0] = "nand"; + processed.push(line); // NAND a, b + processed.push(['nand',line[1],line[1]]); // NAND a, a + } else if(line[1].toLowerCase()=="and") { + line[1] = "nand"; + processed.push(line); // ibid + processed.push(['nand',line[2],line[2]]); + } else if(line[0].toLowerCase()=="or") { + processed.push(['nand',line[1],line[1]]); // NAND a, a + if(line[2].toLowerCase().match(instructions.match.reg)){ + processed.push(['nand',line[2],line[2]]); // NAND b, b + processed.push(['nand',line[1],line[2]]); // NAND a, b + processed.push(['nand',line[2],line[2]]); // NAND b, b + } else if(line[2].toLowerCase().match(instructions.match.imm8)) { + //int imm8 = intByte(this.intByte(line[2]); // NAND b, b + processed.push(['nand',line[1],"~"+line[2]]);//line[2]]); // NAND a, b + } else if(line[2].toLowerCase().match(instructions.match.label)) { + processed.push(['nand',line[1],"~"+line[2]]);// NAND a, ~b + } else throw("error converting and"); + } else if(line[1].toLowerCase()=="or"){ + processed.push(['nand',line[2],line[2]]); // NAND a, a + if(line[3].toLowerCase().match(/(ip|dp|sp|r[0-3])/)){ + processed.push(['nand',line[3],line[3]]); // NAND b, b + processed.push(['nand',line[2],line[3]]); // NAND a, b + processed.push(['nand',line[3],line[3]]); // NAND b, b + } else if(line[3].toLowerCase().match(instructions.match.imm8)) { + imm8 = ~this.intByte(line[3]); // NAND b, b + processed.push(['nand',line[2],line[3]]); // NAND a, b + } else if(line[3].toLowerCase().match(instructions.match.label)) { + processed.push(['nand',line[2],"~"+line[3]]);// NAND a, ~b + } else throw("error converting and"); + + } else { + processed.push(line); + } + }); + return processed; + } + processLabels(tokenLines) { + var processed = []; + // first pass: extract labels + for(var i=0;i 1 && curLine[1]!=''){ + // first token was label; next token will be opcode or data + processed.push(curLine.slice(1)); + } + this.labels.push({ label: curLine[0].split(/:.*/)[0], line: lineNum }); + //processed.push(curLine.slice(1)); + } else processed.push(curLine); + } + return processed; + } + processData(tokenLines) { + // we want to find out where the end of the instructions will be + // however, we don't know how many the assembler will insert to deal with pages + // i can't be bothered doing this properly so let's just add an extra two bytes + // for every instruction that accesses memory + // get number of instructions that deal with memory + var dataInstructions = tokenLines.findIndexes(line=>line[0].toLowerCase().match('^.data$')); + var numMem = tokenLines.filter(line => line[0].toLowerCase().match(/(ldb|stb|jsr|jmp|bflag|bnoflag)/)).length; + var start = ( (tokenLines.length - dataInstructions.length) + numMem )* 2; + var curAddr = 0; + var bytes = []; + dataInstructions.forEach(i=>{ + this.curLine = i; + var thisLabel = this.labels.find(l => l.line== i); + if(thisLabel){ + this.labelAddresses.push({ label: thisLabel.label, address: curAddr+start }); + } + tokenLines[i].slice(1).forEach(token=>{ + // if string + if(token.match(/^".*"$/)) { + token.slice(1).slice(0,-1).replace(/[^\x00-\x7F]/g, "").split('').forEach(character=>{ + bytes.push(character.charCodeAt(0)); + curAddr += 1; + }); + } else { + bytes.push(this.intByte(token)); + curAddr += 1; + } + }); + + }) + + return { start, bytes }; + + } + tokenize(code) { + var tokenLines = []; + // split code into lines - strings enclosed in quotes can span multiple lines + // nb this breaks for escaped quotes but who cares + var lines = code.split(/(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*)\r?\n(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/); + lines.forEach(line=>{ + // split on wgutespace or comma, unless quoted + var tokens = line.split(/(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*)[ ,]+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/); + // remove comments preceded by ; + var hitSemicolon=false + var tokenLine=[]; + tokens.forEach(token=>{ + //console.log(token); + if(token[0]==";"||hitSemicolon){ + hitSemicolon=true; + } else { + tokenLine.push(token); + //console.log(tokenLine); + } + }) + tokenLines.push(tokenLine); + }) + return tokenLines; + } +} diff --git a/js/assembler.js b/js/assembler.js new file mode 100755 index 0000000..d0facf3 --- /dev/null +++ b/js/assembler.js @@ -0,0 +1,294 @@ +Array.prototype.findIndexes=function(where) { + return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []); +} +class assembler { + labels = []; + labelAddresses = []; + address = 0; + curLine = 0; + + offset = 0; // account for any instructions the assembler needs to add + upper8(address){ + return address>>8; + } + lower8(address){ + return address&0x00FF; + } + intByte(n){ + n=n.replace("#",""); + var invert = false; + if(n[0]=="~") { invert=true; n=n.slice(1)}; + var b = 0; + if(n.match(/^0b/)){ + b = parseInt(n.slice(2),2); + } else { + b = parseInt(n); + } + if(isNaN(b)) { + throw 'Invalid number'; + } else if(b>255 || b <-128){ + throw 'Number will not fit in a byte!'; + } + if(b<0){ + // apply 2's complement to negative value + var r= ~Math.abs(b)+1; + } else { + var r= b; + }; + return invert ? ((~r>>>0)&0xFF) : r; + } + encodeInstruction(line){ + var bytes = [0,0]; + var instruction = instructions.opcodes.find(oc=>oc.mnemonic==line[0].toLowerCase()); + if(instruction.mnemonic=="bflag"||instruction.mnemonic=="bnoflag") { + var flag = instructions.flags.indexOf(line[1]); + if(flag>=0){ + // evil stupid dumb + line[1] = line[1].replace(instructions.flags[flag],instructions.registers[flag]); + + } else throw 'Invalid flag.'; + } + if(!instruction) throw 'Unknown opcode'; + var patterns = instructions.arg_patterns[instruction.patterns]; + var mode = -1; + if(patterns[0].pattern.length!=line.length-1){ + throw 'Wrong number of operands'; + } else if(patterns.length==1){ + mode = patterns[0].mode; + } else { + patterns.forEach(pattern=>{ + var fit=0; + for(var i=0;i{ + var l; + var mnemonic = instruction[0].toLowerCase(); + this.curLine = i; + var offset=0; + // dealing with pseudo instructions + if(mnemonic==".data"){ + return; + /* + } else if(mnemonic=="hlt"){ // halt: jump to same instruction + if(this.upper8(instAddr)!=instPage){ + instPage=this.upper8(instAddr); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + offset=2; + } + bytecode = bytecode.concat(this.encodeInstruction(["jmp","#"+this.lower8(instAddr+offset)])); + } else if(mnemonic=="nop"){ // nop: jump to next instruction + if(this.upper8(instAddr+2)!=instPage){ + offset=2; + instPage=this.upper8(instAddr); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + } + bytecode = bytecode.concat(this.encodeInstruction(["jmp","#"+this.lower8(instAddr+2+offset)])); + */ + // now process labels + } else if(mnemonic=="jsr"||mnemonic=="jmp"){ + instruction[1] = instruction[1].replace("SKIP",'#'+(instAddr+4+offset)); + l = this.labelAddresses.find(la=>instruction[1].includes(la.label)); + + if(l){ // we must replace + instruction[1] = instruction[1].replace(l.label, "#"+this.lower8(l.address)); + if(this.upper8(l.address)!=instPage){ + instPage=this.upper8(l.address); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ip","#"+instPage])); + offset=2; + } + } + console.log(instruction); + bytecode=bytecode.concat(this.encodeInstruction(instruction)); + } else if(mnemonic=="stb"||mnemonic=="ldb"||mnemonic=="mov"||mnemonic=="bflag"||mnemonic=="bnoflag"){ + // QUICK AND DIRTY: WILL BREAK UNDER CERTAIN CONDITIONS + instruction[2] = instruction[2].replace("SKIP",'#'+(instAddr+4+offset)); + l = this.labelAddresses.find(la=>instruction[2].includes(la.label)); + if(l){ // we must replace + instruction[2] = instruction[2].replace(l.label, "#"+this.lower8(l.address)); + if(this.upper8(l.address)!=dataPage){ + dataPage=this.upper8(l.address); + bytecode=bytecode.concat(this.encodeInstruction(["mov","dp","#"+dataPage])); + offset=2; + } + } + bytecode=bytecode.concat(this.encodeInstruction(instruction)); + } else bytecode=bytecode.concat(this.encodeInstruction(instruction)); + console.log({i:i, l:this.labels}); + l = this.labels.findIndex(la=>la.line==i); + if(l>-1){ + this.labelAddresses.push({label: this.labels[l].label, address: instAddr}); + } + instAddr += 2 + offset; + }); + return bytecode; + } + assemble(code) { + // try + var tokens = this.tokenize(code).filter(line=>line.length>0 &&line[0]!=''); + console.log(tokens); + var withPseudo = this.processAndOr(tokens); + var delabeled = this.processLabels(withPseudo); + var data = this.processData(delabeled); + var bytecode = this.processInstructions(delabeled); + var pad = data.bytes.length>0?Array(data.start - bytecode.length).fill(0):[]; + console.log({tokens,withPseudo,delabeled,data,bytecode}) + + return bytecode.concat(pad).concat(data.bytes); + // catch + } + processAndOr(tokenLines) { + var processed=[]; + tokenLines.forEach(line=>{ + if(line.length<2){ + processed.push(line) + } + else if(line[0].toLowerCase()=="and") { + line[0] = "nand"; + processed.push(line); // NAND a, b + processed.push(['nand',line[1],line[1]]); // NAND a, a + } else if(line[1].toLowerCase()=="and") { + line[1] = "nand"; + processed.push(line); // ibid + processed.push(['nand',line[2],line[2]]); + } else if(line[0].toLowerCase()=="or") { + processed.push(['nand',line[1],line[1]]); // NAND a, a + if(line[2].toLowerCase().match(instructions.match.reg)){ + processed.push(['nand',line[2],line[2]]); // NAND b, b + processed.push(['nand',line[1],line[2]]); // NAND a, b + processed.push(['nand',line[2],line[2]]); // NAND b, b + } else if(line[2].toLowerCase().match(instructions.match.imm8)) { + //int imm8 = intByte(this.intByte(line[2]); // NAND b, b + processed.push(['nand',line[1],"~"+line[2]]);//line[2]]); // NAND a, b + } else if(line[2].toLowerCase().match(instructions.match.label)) { + processed.push(['nand',line[1],"~"+line[2]]);// NAND a, ~b + } else throw("error converting and"); + } else if(line[1].toLowerCase()=="or"){ + processed.push(['nand',line[2],line[2]]); // NAND a, a + if(line[3].toLowerCase().match(/(ip|dp|sp|r[0-3])/)){ + processed.push(['nand',line[3],line[3]]); // NAND b, b + processed.push(['nand',line[2],line[3]]); // NAND a, b + processed.push(['nand',line[3],line[3]]); // NAND b, b + } else if(line[3].toLowerCase().match(instructions.match.imm8)) { + imm8 = ~this.intByte(line[3]); // NAND b, b + processed.push(['nand',line[2],line[3]]); // NAND a, b + } else if(line[3].toLowerCase().match(instructions.match.label)) { + processed.push(['nand',line[2],"~"+line[3]]);// NAND a, ~b + } else throw("error converting and"); + + } else { + processed.push(line); + } + }); + return processed; + } + processLabels(tokenLines) { + var processed = []; + // first pass: extract labels + for(var i=0;i 1 && curLine[1]!=''){ + // first token was label; next token will be opcode or data + processed.push(curLine.slice(1)); + } + this.labels.push({ label: curLine[0].split(/:.*/)[0], line: lineNum }); + //processed.push(curLine.slice(1)); + } else processed.push(curLine); + } + return processed; + } + processData(tokenLines) { + // we want to find out where the end of the instructions will be + // however, we don't know how many the assembler will insert to deal with pages + // i can't be bothered doing this properly so let's just add an extra two bytes + // for every instruction that accesses memory + // get number of instructions that deal with memory + var dataInstructions = tokenLines.findIndexes(line=>line[0].toLowerCase().match('^.data$')); + var numMem = tokenLines.filter(line => line[0].toLowerCase().match(/(ldb|stb|jsr|jmp|bflag|bnoflag)/)).length; + var start = ( (tokenLines.length - dataInstructions.length) + numMem )* 2; + var curAddr = 0; + var bytes = []; + dataInstructions.forEach(i=>{ + this.curLine = i; + var thisLabel = this.labels.find(l => l.line== i); + if(thisLabel){ + this.labelAddresses.push({ label: thisLabel.label, address: curAddr+start }); + } + tokenLines[i].slice(1).forEach(token=>{ + // if string + if(token.match(/^".*"$/)) { + token.slice(1).slice(0,-1).replace(/[^\x00-\x7F]/g, "").split('').forEach(character=>{ + bytes.push(character.charCodeAt(0)); + curAddr += 1; + }); + } else { + bytes.push(this.intByte(token)); + curAddr += 1; + } + }); + + }) + + return { start, bytes }; + + } + tokenize(code) { + var tokenLines = []; + // split code into lines - strings enclosed in quotes can span multiple lines + // nb this breaks for escaped quotes but who cares + var lines = code.split(/(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*)\r?\n(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/); + lines.forEach(line=>{ + // split on wgutespace or comma, unless quoted + var tokens = line.split(/(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*)[ ,]+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/); + // remove comments preceded by ; + var hitSemicolon=false + var tokenLine=[]; + tokens.forEach(token=>{ + //console.log(token); + if(token[0]==";"||hitSemicolon){ + hitSemicolon=true; + } else { + tokenLine.push(token); + //console.log(tokenLine); + } + }) + tokenLines.push(tokenLine); + }) + return tokenLines; + } +} diff --git a/js/index.js b/js/index.js new file mode 100755 index 0000000..9295aa5 --- /dev/null +++ b/js/index.js @@ -0,0 +1,1129 @@ +var registers=[]; +var blocks=[]; +var wires=[]; +var tooltips=[]; +var embedded = {}; +var images={}; +const BORDER_THICKNESS=5.5; +var canvas, ctx; +var outputBuf = [] +var clockTimer; +var opcodes = ['add','sub','adc','subb','nand','xor','sll','srl','mov','ldb','stb', 'nop','bflag','bnoflag', 'jmp', 'hlt']; +var rs = ['io','stackptr','datapg','instpg','gp0','gp1','gp2','gp3']; +var flags = ['zero','carry','negative','overflow','input']; +var memory=new Array(65536).fill(0); +var memPage = 0; +var dataPage = 0; +function getNumber(pins,reverse=true){ + var val = 0; + for(var i=0;i>12; + var addressMode = (machineCode & 0b0000100000000000) >>11; + var r1 = (machineCode & 0b0000011100000000)>>8; + var r2 = (machineCode & 0b0000000011100000)>>5; + var imm8 = machineCode & 0b0000000011111111; + if(opcode==15){ + return(opcodes[opcode]); + } else if(opcode<11) { + return(`${opcodes[opcode]} ${specific?rs[r1]:'reg'}, ${specific?((addressMode?imm8:rs[r2])):addressMode?'imm8':'reg'}`); + } else if (opcode==11){ + return(`${opcodes[opcode]}`); + } else if(opcode==12) { + return(`${opcodes[opcode]} ${specific?flags[r1 & 0b00000111]:'flag'}, ${specific?((addressMode?imm8:rs[r2])):addressMode?'imm8':'reg'}`); + } else { + return(`${opcodes[opcode]} ${specific?((addressMode?imm8:rs[r2])):(addressMode?'imm8':'reg')}`); + } + +} +document.addEventListener("DOMContentLoaded", function(event){ + event; + canvas = document.getElementById("sim"); + ctx = canvas.getContext('2d'); + setup(); + setTimeout(function(){ + embedded['alu'] = document.getElementById('ALUframe').contentWindow.chip; + embedded['mux1'] = document.getElementById('MUX1frame').contentWindow.chip; + embedded['mux2'] = document.getElementById('MUX2frame').contentWindow.chip; + },2000); +}); +function w(width){ + return ((width*canvas.width)/1440); +} +function h(height){ + return ((height*canvas.height)/976); +} +function drawBorder(thing,thickness,color="black"){ + ctx.fillStyle=color; + ctx.fillRect(thing.x-thickness,thing.y-thickness,thing.width+thickness*2,thing.height+thickness*2); +} + +class Block { + constructor(name, x, y, width, height,points=[],editable=true){ + this.name=name; + this.url=""; + this.x=w(x); + this.y=h(y); + this.width=w(width); + this.height=h(height); + this.editable=editable; + this.points=points; + if(this.editable) + this.done=false; + else + this.done=true; + } + update(){ + } + reset(){ + } + makePointArray(){ + this.points=[] + for(const[key,value] of Object.entries(this.pins)){ + key; + //this.points=this.points.concat(value); + value.forEach((pin,i)=>{ pin.number=i; this.points.push(pin) }); + } + + } + drawOverlay(){ + if(!(this.done||this.attempted)){ + ctx.fillStyle="rgba(255,255,255,0.6)"; + ctx.fillRect(this.x,this.y+BORDER_THICKNESS+35,this.width,this.height-BORDER_THICKNESS-35); + ctx.fillStyle="#FFA500" + if(this.wrong) + ctx.fillStyle="#dd3333"; + ctx.fillRect(this.x+this.width/2-35,this.y+this.height/2-35+17,70,70); + ctx.drawImage(images[this.editable?'pencil':'question'],this.x+this.width/2-30,this.y+this.height/2-30+17,60,60); + } else + if(this.editable) + ctx.drawImage(images[this.editable?'pencil':'question'],this.x+this.width-w(37),this.y+this.height-h(30)-h(3),w(30),h(30)); + } + draw(color='white',textcolor='white'){ + ctx.fillStyle=color; + ctx.fillRect(this.x, this.y, this.width, this.height); + ctx.fillStyle="#444"; + ctx.fillRect(this.x,this.y,this.width,BORDER_THICKNESS); + ctx.fillRect(this.x-BORDER_THICKNESS,this.y,BORDER_THICKNESS,this.height+BORDER_THICKNESS); + ctx.fillRect(this.x+this.width,this.y,BORDER_THICKNESS,this.height+BORDER_THICKNESS); + ctx.fillRect(this.x,this.y+this.height,this.width,BORDER_THICKNESS); + if(this.done) + ctx.fillStyle="#43c143"; + else if(!this.attempted) + ctx.fillStyle="#ffa500"; + else + ctx.fillStyle="#dd3333"; + if(this.wrong){ + ctx.fillStyle="#dd3333"; + } + ctx.fillRect(this.x,this.y+BORDER_THICKNESS,this.width,35); + ctx.fillStyle=textcolor; + ctx.font=170*0.15+"px vcr_osd_monoregular"; + ctx.textBaseline = "top"; + ctx.textAlign='left'; + ctx.fillText(this.name,this.x+w(7), this.y+h(13)); + + + this.points.forEach(p=>p.draw()); + } + checkMouse(pos){ + // check if mouse is over icon + if(!this.attempted&&this.editable){ + return pos.x>=this.x+this.width/2-35 && pos.y>=this.y+this.height/2-35 && pos.x<=this.x+this.width/2-35+70 && pos.y<=this.y+this.height/2-35+70; + } else + return pos.x>=this.x+this.width-w(37) && pos.x<=this.x+this.width-w(7) && pos.y>=this.y+this.height-h(33) && pos.y<=this.y+this.height-h(3) && JSON.stringify(Array.from(ctx.getImageData(pos.x,pos.y,1,1).data.slice(0,3)))!="[255,255,255]"; + } +} +class Decoder extends Block { + update(){ + this.setInstruction(humanInstruction(registers[0].value,false),(registers[0].value>>12)); + for(var i=0;i<16;i++){ + if(i<4){ + this.pins.toALU[i].write(this.pins.instruction[i].read()); + } + } + // read from first register only if it's an ALU operation + // write to the first register unless we're in a store or branch instruction + this.pins.registerReadEnable[0].write(this.opcode<8); + this.pins.registerWriteEnable[0].write(this.opcode<10); + // imm8 + this.pins.toMux[0].write(this.pins.instruction[4].read() && this.opcode!=11 &&this.opcode!=15);//(this.mode==1 && this.opcode!=11 && this.opcode!=15)); + + // mem load + this.pins.toMux[1].write(this.opcode==9); + this.pins.memDataReadEnable[0].write(this.opcode==9); + this.pins.memDataWriteEnable[0].write(this.opcode==10); + // + this.pins.memAddrWriteEnable[0].write(this.opcode==9||this.opcode==10); + // jumps + if(this.opcode==14) + this.pins.pcWriteEnable[0].write(1); + else if(this.opcode!=12&&this.opcode!=13) + this.pins.pcWriteEnable[0].write(0); + else + this.pins.pcWriteEnable[0].write(branchyes?1:0); + } + setInstruction(instruction,opcode,mode){ + this.instruction = instruction; + this.opcode=opcode; + this.mode=mode; + } + constructor(x,y,width,height,points=[],editable=true){ + super("decoder",x,y,width,height,points,editable); + this.mode=0; + this.pins = { + instruction: [ + ], + toALU: [ + + ], + toMux: [ + new Pin(this.x+this.width,this.y+this.height-50,6,false,"right"), + new Pin(this.x+this.width,this.y+this.height-50+17,6,false,"right") + ], + registerWriteEnable: [ + new Pin(this.x+this.width,this.y+this.height-140,6,false,"right") + ], + registerReadEnable: [ + new Pin(this.x+this.width,this.y+this.height-157,6,false,"right") + ], + memAddrWriteEnable: [ + new Pin(this.x+190,this.y+this.height), + ], + memAddrReadEnable: [ + new Pin(this.x+207,this.y+this.height) + ], + pcWriteEnable: [ + new Pin(this.x+227+17,this.y+this.height) + ], + pcReadEnable: [ + new Pin(this.x+227+34,this.y+this.height) + ], + memDataWriteEnable:[ + new Pin(this.x+282+17,this.y+this.height) + ], + memDataReadEnable:[ + new Pin(this.x+282+34,this.y+this.height) + ], + + + + + } + for(var i=0;i<5;i++){ + this.pins.instruction.push(new Pin(this.x+17+17*i, this.y)); + if(i<4) + this.pins.toALU.push(new Pin((this.x+17+17*i+(i<4?0:34)), this.y+this.height)); + } + this.makePointArray(); + this.instruction="add reg,reg"; + this.opcode=0; + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.font=250*0.07+"px vcr_osd_monoregular"; + ctx.textBaseline = "top"; + ctx.textAlign='center'; + ctx.fillText("opcode: "+Register.getBits(this.opcode,4)+" / "+Register.getHex(this.opcode,1)+"",this.x+this.width/2-w(4), this.y+h(55)); + var am=this.pins["instruction"][4].read(); + this.mode=am; + ctx.fillText("mode: "+(am?1:0)+" / "+(this.opcode==15?'special':(((am==0||this.opcode==11)?"register":"immediate"))),this.x+this.width/2-w(4), this.y+h(75)); + + ctx.font=240*0.15+"px vcr_osd_monoregular"; + ctx.fillText(this.instruction,this.x+this.width/2-w(4), this.y+h(100)); + } + + +} +class Mux extends Block { + setChannel(c){ + this.channel=c; + } + update(){ + if(this.second){ + if(!embedded.mux2 || !embedded.mux2.pins) return; + embedded.mux2.pins[16] = this.pins.selector[0].read(); + for(var i=0;i<8;i++){ + embedded.mux2.pins[i] = this.pins.channel0[i].read(); + embedded.mux2.pins[8+i] = this.pins.channel1[7-i].read(); + this.pins.output[7-i].write(embedded.mux2.pins[24-i]); + + }}else{ + if(!embedded.mux1 || !embedded.mux1.pins) return; + embedded.mux1.pins[16] = this.pins.selector[0].read(false); + for(var i=0;i<8;i++){ + embedded.mux1.pins[i] = this.pins.channel0[7-i].read(); + embedded.mux1.pins[8+i] = this.pins.channel1[i].read(); + this.pins.output[7-i].write(embedded.mux1.pins[24-i]); + + }} + + + + this.setChannel(this.pins.selector[0].read()==true?1:0); + } + constructor(x,y,width,height,second=false,de=false,points=[],editable=true){ + super((de?"de":"")+"multiplexer",x,y,width,height,points,editable); + this.de=de; + this.second=second; + this.channel=0; + if(second) + var theselector=new Pin(this.x+this.width-17, this.y); + else + var theselector=new Pin(this.x-BORDER_THICKNESS,blocks[0].pins.toMux[0].y,6,"","right") + if(!this.de){ + this.pins={ + selector: [ + theselector + ], + channel0:[ + ], + channel1: [ + ], + output:[ + ] + } + for(var i=0;i<8;i++){ + if(second){ + this.pins.channel1.push(new Pin(this.x+62+17*i,this.y+BORDER_THICKNESS+this.height,6,"","up")); + this.pins.output.push(new Pin(this.x+this.width,this.y+17+17*i,6,"","right")); + this.pins.channel0.push(new Pin(this.x-BORDER_THICKNESS,this.y+17+17*i,6,"","right")); + } else { + this.pins.channel1.push(new Pin(this.x+17+17*i,this.y)); + this.pins.channel0.push(new Pin(this.x+BORDER_THICKNESS+this.width,this.y+17+17*i,6,"","left")); + this.pins.output.push(new Pin(this.x+17+17*i,this.y+this.height)); + } + } + } else { + this.pins={ + selector: [ + new Pin(this.x-BORDER_THICKNESS,this.y+15,6,"","right"), + new Pin(this.x-BORDER_THICKNESS,this.y+30,6,"","right") + ], + input:[ + ], + channel0:[ + ], + channel1:[ + ], + channel2:[ + ] + } + for(var i=0;i<8;i++){ + this.pins.input.push(new Pin(this.x-BORDER_THICKNESS,this.y+67+17*i,6,"","right")); + this.pins.channel0.push(new Pin(this.x+this.width,this.y+17+17*i,6,"","right")); + this.pins.channel1.push(new Pin(this.x+17+17*i,this.y+this.height)); + this.pins.channel2.push(new Pin(this.x+220+17*i,this.y+this.height)); + } + } + this.makePointArray(); + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.font="25px vcr_osd_monoregular"; + ctx.baseline="middle"; + ctx.textAlign="center"; + ctx.fillText(" channel: "+this.channel,this.x+this.width/2,this.y+this.height/2); + } +} +class ALU extends Block { + update(){ + if(!embedded.alu) return; + for(var i=0;i<8;i++){ + if(i<4){ + embedded.alu.pins[19-i] = this.pins.opcode[i].read(); + this.pins.flags[i].write(embedded.alu.pins[29+i]); + } + embedded.alu.pins[i] = this.pins.operand1[i].read(); + embedded.alu.pins[i+8] = this.pins.operand2[i].read(); + this.pins.result[i].write(embedded.alu.pins[21+i]); + } + this.values[3].set(getNumber(this.pins.flags)); + this.values[1].set(getNumber(this.pins.operand1,false)); + this.values[0].set(getNumber(this.pins.operand2,false)); + this.values[2].set(getNumber(this.pins.result,false)); + var opcode=getNumber(this.pins.opcode); + if(opcode==6){ + this.correctAnswer = this.values[1].value << this.values[0].value; + } else { + this.correctAnswer = -1; + } + if(opcode>=8){ + this.operation = "move"; + } else { + this.operation = opcodes[opcode]; + } + + } + constructor(x,y,width,height,points=[],editable=true){ + points; + super("ALU",x,y,width,height,wires,editable); + this.wrong=false; + this.operation="add"; + this.values=[new Register("operand 1",8,0,this.x+w(20),this.y+h(80),50,"above",true,"black"), + new Register("operand 0",8,0,this.x+w(20),this.y+h(175),50,"above",true,"black"), + new Register("result",8,0,this.x+w(20),this.y+h(340),50,"above",true,"black"), + new Register("O N C Z flags",4,1,this.x+w(20),this.y+h(410),32,"above",false,"black")]; + //new Register("O . N . C . Z",4,0,this.x+w(125),this.y+h(360),30,"above",false,"black")]; + this.pins={ opcode: []/*,setFlags:[]*/, operand1:[], operand2:[],flags:[],result:[] } + for(var i=0;i<4;i++){ + this.pins.opcode.push(new Pin(this.x+17+17*i,this.y)); + this.pins.flags.push(new Pin(this.x+17+17*i,this.y+this.height)); + } + this.pins.flags[3].write(1); + for(var i=0;i<8;i++){ + this.pins.operand2.push(new Pin(this.x+this.width+BORDER_THICKNESS, this.y+17+17*i,6,"","left")); + this.pins.operand1.push(new Pin(this.x+this.width+BORDER_THICKNESS, this.y+167+17*i,6,"","left")); + this.pins.result.push(new Pin(this.x+this.width, this.y+317+17*i,6,"","right")); + } + + //this.pins.setFlags.push(new Pin(this.x+17*5+34,this.y)); + //this.pins.setFlags[0].write(1); + + this.makePointArray(); + + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.font="25px vcr_osd_monoregular"; + ctx.fillText("operation: "+this.operation,this.x+this.width/2, this.y+260); + ctx.font="15px vcr_osd_monoregular"; + //ctx.fillText("set flags: "+(this.pins.setFlags[0].read()==1?"yes":"no"),this.x+this.width/2, this.y+280); + ctx.fillRect(this.x+20,this.y+300,this.width-40,2); + this.values.forEach(v=>v.draw(0)); + } +} +class RegisterFile extends Block { + fileRegisters = []; + selected(){ + return{r1:this.fileRegisters[7-getNumber(this.pins.address1,false)], r2:this.fileRegisters[7-getNumber(this.pins.address2,false)]}; + } + update(){ + for(var i=0;i<8;i++){ + if(this.pins.read1Enable[0].read()) + this.pins.data1[7-i].write(this.selected().r1.binary[i]); + this.pins.data2[7-i].write(this.selected().r2.binary[i]); + } + } + realUpdate(){ + if(!!this.pins.write1Enable[0].read()) { + this.selected().r1.set(getNumber(this.pins.writeback,false),true); + } + } + constructor(x,y,fileRegisters=[],pins=[],editable=true){ + pins,editable; + super("registers",x,y,0,fileRegisters.length*h(85)+h(45),wires,false); + fileRegisters.forEach((r,i)=>{ + if(!r.bits){ + r.bits=8 + } + this.fileRegisters.push(new Register(r.name,r.bits,0,x+w(20),y+i*h(85)+h(65),40,"above",true,"black")); + }); + this.width=this.fileRegisters[0].width+w(80); + this.pins={ + clock:[ new Pin(this.x-BORDER_THICKNESS,this.y+17,6,"","right") ], + read1Enable: [ new Pin(this.x-BORDER_THICKNESS,this.y+17+35,6,"","right") ], + write1Enable: [new Pin(this.x-BORDER_THICKNESS,this.y+34+35,6,"","right") ], + address1: [ ], + address2: [ ], + data2:[ ], + data1:[ ], + writeback:[] + }; + for(var i=0;i<3;i++){ + this.pins.address2.push(new Pin(this.x-BORDER_THICKNESS,this.y+55+35+17+17*i,6,"","right")); + this.pins.address1.push(new Pin(this.x-BORDER_THICKNESS,this.y+125+35+17+17*i,6,"","right")); + } + for(var i=0;i<8;i++){ + this.pins.data2.push(new Pin(this.x,this.y+205+35+17+17*i,6,"","left")); + this.pins.data1.push(new Pin(this.x,this.y+365+35+17+17*i,6,"","left")); + this.pins.writeback.push(new Pin(this.x-BORDER_THICKNESS,this.y+530+35+17+17*i,6,"","right")); + } + super.makePointArray(); + } + draw(){ + super.draw(); + this.fileRegisters.forEach(r=>r.draw(1)); + } +} +class Clock extends Block { + reset(){ + this.state=0; + this.cycles=0; + } + update(){ + this.pins.clk[0].write(this.state); + } + constructor(x,y,width,height){ + super("clock",x,y,width,height,[],false); + this.pins={clk:[new Pin(this.x+this.width,this.y+17,6,"","right")]}; + super.makePointArray(); + this.cycles=0; + this.state=0; + } + pulse(t,w=false){ + this.state = 1; + if(!w) + this.cycles+=1; + setTimeout(function(){this.state=0}.bind(this),t/10); + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.fillText(this.cycles,this.x+this.width/2,this.y+this.height/2+20); + } +} + +class Register { + pins=[]; + update(fuck=false){ + /*if(this.name=="memory address register" && fuck) return; + if(this.name=="m. data reg." && fuck) return;*/ + if(this.name=="flags"){ + this.set(getNumber(this.pins)); + if(document.getElementById("input").value.length>0) + this.value=this.value|0b10000; + else { + this.value=this.value & 0b01111; + } + this.set(this.value); + } + else if('writeEnable' in this) { + if(!!this.writeEnable.read()){ + this.set(getNumber(this.pins)); + } + } + if(this.name=="m. data reg."){ + var mAddr = registers[2].value; + if(this.writeEnable.read()){ + memory[mAddr] = this.value; + } + if(this.readEnable.read()||initialRun){ + initialRun=false; + this.set(memory[mAddr]); + } + } + } + static getBits(n,digits=8){ + if(n<0||n>=Math.pow(2,digits)||n%1!==0) { + //console.error(n+" is fucked, yo"); + } + return ("0000000000000000"+n.toString(2)).substr(-digits); + } + static getHex(n, digits=2){ + return "0x"+("0000"+n.toString(16).toUpperCase()).substr(-digits); + } + constructor(name, bits, value,x,y,scale,position="above",showValue=true,textColor="white",pins=false,numPins=8){ + this.name=name; + this.bits=bits; + this.x=w(x); + this.y=h(y); + this.width=w(scale * this.bits)*0.75; + this.height=h(scale); + this.above=position=="above"; + this.showValue=showValue; + this.textColor=textColor; + if(pins) + for(var i=bits-Math.min(bits,numPins);i{ pin.write(this.binary[i]) }); + + } + draw(border=0){ + if(this.name=="flags"){ + this.value=actualflags; + if(document.getElementById("input").value.length>0) + this.value=this.value|0b10000; + else { + this.value=this.value & 0b01111; + } + this.set(this.value); + } + + drawBorder(this,border); + ctx.fillStyle='white'; + ctx.fillRect(this.x,this.y,this.width,this.height); + var section_width = this.width/this.bits; + // draw text and separators + // labels + ctx.fillStyle = this.textColor; + ctx.font=this.height*0.4+"px vcr_osd_monoregular"; + var textY; + if(this.above){ + ctx.textBaseline = "bottom"; + textY = this.y-this.height*0.05; + } else { + ctx.textBaseline = "top"; + textY = this.y + this.height + this.height * 0.05; + ctx.fillStyle="rgba(24,27,32,0.5)"; + ctx.fillRect(this.x,this.y+this.height,this.width,21); + ctx.fillStyle="white"; + } + ctx.textAlign = "left"; + ctx.fillText(this.name,this.x,textY) + ctx.textAlign = "right"; + if(this.name=="instruction register"){ + ctx.fillText(humanInstruction(this.value),this.x+this.width,textY); + } else + this.showValue ? ctx.fillText(this.value+" | "+Register.getHex(this.value,(this.bits/4)),this.x+this.width,textY) : null; + + for(var i=0;i0) { + ctx.fillRect(this.x+section_width*i,this.y,2,this.height); + } + } + this.pins.forEach(pin=>pin.draw()); + if(this.readEnable){ + ctx.fillStyle="black"; + ctx.fillRect(this.x-6,this.y,6,this.height); + this.readEnable.draw(); + this.writeEnable.draw(); + } + } +} +var actualflags=0; +function pointInCircle(x, y, cx, cy, radius) { + var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy); + return distancesquared <= radius * radius; +} +class Pin { + constructor(x,y,radius=6,label=false,direction="down"){ + this.x=x; + this.y=y; + this.radius=radius; + this.state=0; + this.label=label; + this.direction=direction; + } + read(){ + return this.state; + } + write(state){ + this.state=state==true?1:0; + } + checkMouse(pos){ + return pointInCircle(pos.x,pos.y,this.x,this.y,this.radius); + } + draw(){ + ctx.fillStyle=this.read()==1?"red":"lightgray"; + ctx.beginPath(); + if(this.direction=="down"){ + ctx.arc(this.x,this.y,this.radius, 0*Math.PI,1*Math.PI,false); + } else if(this.direction=="right"){ + ctx.arc(this.x,this.y,this.radius,1.5*Math.PI,0.5*Math.PI,false); + } else if(this.direction=="left") { + ctx.arc(this.x,this.y,this.radius,0.5*Math.PI,1.5*Math.PI,false); + } else if (this.direction=="up") { + ctx.arc(this.x,this.y,this.radius, -1*Math.PI,0*Math.PI,false); + + } + ctx.fill(); + } +} + +class Wire { + update(){ + var state=!!this.input.read(); + if(this.killme>-1){ + if(registers[4].readEnable.read()){ + state = parseInt(registers[4].binary[7-this.killme]); + this.input.write(state); + } + } + this.state=state; + var hovered = this.input.hovered =1 || this.output.hovered == 1; + if(!this.behind) + this.color=state?"#F00":"#AAA"; + else if(this.behind==1) + this.color=state?"#A00":"#777"; + else + this.color=state?"#800":"#555"; + this.output.write(state); + } + draw(){ + ctx.beginPath(); + ctx.moveTo(this.input.x,this.input.y); + var n = this.output.number; + n = n - this.reindex; + var fuckyou = (this.output.number==0 && this.input.direction=="down")?2:0; + if (this.fuckoffanddie){ + ctx.lineTo(435,this.input.y); + ctx.lineTo(435,650); + ctx.lineTo(760,650); + ctx.lineTo(760,570); + ctx.lineTo(this.output.x,570); + } else { + if(!this.horizontal){ + if(!this.reverse){ + ctx.lineTo(this.input.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.45+n*7,0)); + ctx.lineTo(this.output.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.45+n*7,0.0)); + } else { + /* + ctx.lineTo(this.input.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + ctx.lineTo(this.output.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + */ + ctx.lineTo(this.input.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.56-n*6,0)); + ctx.lineTo(this.output.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.56-n*6,0.0)); + } + } else { + if(!this.reverse){ + //ctx.lineTo(this.input.x+fuckyou+Math.max((this.output.x-this.input.x)*0.45+n*7,0),this.input.y); + //ctx.lineTo(this.input.x+fuckyou+Math.max((this.output.x-this.input.x)*0.45+n*7,0.0),this.output.y); + if(!this.zigzag){ + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45+n*7),this.input.y); + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45+n*7),this.output.y); + } else{ + if(this.kms) + ctx.lineTo(this.input.x,this.output.y) + else + ctx.lineTo(this.output.x,this.input.y) + } + } else { + if(!this.zigzag){ + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45-n*7),this.input.y); + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45-n*7),this.output.y); + } else{ + ctx.lineTo(this.input.x,this.output.y) + } + /* + ctx.lineTo(this.input.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + ctx.lineTo(this.output.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + */ + + } + + }} + ctx.lineTo(this.output.x, this.output.y); + var redcolor,graycolor; + if(this.behind==0){ + redcolor="#F0F" + graycolor="#99F" + } else if(this.behind==1) { + redcolor="#A0A" + graycolor="#55F" + } else { + redcolor = "#808" + graycolor="#22F" + } + ctx.strokeStyle=this.hovered?(this.state?redcolor:graycolor):this.color + // cursed ctx.strokeStyle=this.color.substr(0,3)+(this.hovered?"F"/*(Math.min(parseInt(this.color[1],16)+3,15)).toString(16)*/:this.color[3]); + ctx.lineWidth=this.hovered?6:4; + ctx.stroke(); + } + constructor(input, output, label,behind=false, reverse=false,reindex=0,horizontal=false,flip=false,zigzag=false,kms=false,fuckoffanddie=false,killme=-1 ){ + this.input=input; + this.fuckoffanddie=fuckoffanddie; + this.output=output; + this.label=label; + this.reverse=reverse; + this.reindex=reindex; + this.behind=behind; + this.horizontal=horizontal; + this.flip=flip?-1:1; + this.zigzag=zigzag; + this.kms=kms; + this.killme=killme; + } +} +class Tooltip { + constructor(x,y,message,persist=false){ + this.x=x; + this.y=y; + this.message=message; + this.persist=persist; + } + draw(offset){ + ctx.fillStyle="rgba(0,0,0,0.65)"; + ctx.font="20px vcr_osd_monoregular"; + ctx.textBaseline="bottom"; + ctx.textAlign="left"; + var width=ctx.measureText(this.message).width+6; + ctx.fillRect(this.x<720?this.x:this.x-width,this.y-25-(26*offset),width,25); + ctx.fillStyle="white"; + ctx.fillText(this.message,this.x<720?(this.x+3):(this.x-width+3),this.y-(26*offset)); + } +} +function wireUp(){ + // clock + wires.push(new Wire(blocks[4].pins.clk[0],blocks[3].pins.clock[0],"clock")); + // instruction to decoder + //decoder to ALU + for(var i=0;i<5;i++){ + wires.push(new Wire(registers[0].pins[i],blocks[0].pins["instruction"][i],i<4?("opcode bit "+(3-i)):"addressing mode",false,false,2)); + if(i<4) + wires.push(new Wire(blocks[0].pins.toALU[i],blocks[2].points[i],i<4?"ALU opcode bit ":"set flags?")); + } + for(var i=0;i<8;i++){ + ///m data reg to mux + wires.push(new Wire(blocks[5].pins.channel1[7-i],registers[4].pins[7-i],"MDR (mux ch. 1), bit "+i,false,true,3,false,false,false,false,false,i)); + //wires.push(new Wire(blocks[5].pins.channel1[7-i],registers[4].pins[7-i],"memory data register, bit "+(7-i),false,true,5,false,false,false)); + + } + // ALU to flags + var flagtext=["overflow flag","negative flag","carry flag","zero flag"] + for(var i=0;i<4;i++){ + wires.push(new Wire(blocks[2].pins.flags[i],registers[1].pins[i+1],flagtext[i],false,true,2)); + } + //// INPUT OUTPUT STOPS BEHIND REVERSE REINDEX HORIZONTAL FLIP + // decoder to mux control + wires.push(new Wire(blocks[0].pins.toMux[0],blocks[1].pins.selector[0],"mux 0 selector")); + // instruction to multiplexer + for(var i=0;i<8;i++){ + // reg to mux and alu + wires.push(new Wire(blocks[3].pins.data1[i],blocks[2].pins.operand1[i],"first register data (operand 0), bit "+i,false,true,30,true)); + wires.push(new Wire(blocks[3].pins.data2[i],blocks[1].pins.channel0[i],"second register data (mux ch. 0), bit "+i,false,false,0,true)); + //mux to alu + wires.push(new Wire(blocks[1].pins.output[i],blocks[2].pins.operand2[7-i],/*"mux output, bit "+i*/"mux output (operand 1), bit "+[7-i],false,true,0,true,true,true)); + //alu to writeback + //wires.push(new Wire(blocks[2].pins.result[i],blocks[3].pins.writeback[i],"ALU result, bit "+i,false,false,-29,true,true)); + + wires.push(new Wire(blocks[5].pins.output[i],blocks[3].pins.writeback[i],"mux output (reg writeback), bit "+i,false,false,-29,true,true)); + wires.push(new Wire(blocks[2].pins.result[i],blocks[5].pins.channel0[i],"mux ch. 0 (ALU result), bit "+i,false,false,-29,true,true)); + + //alu to mar + wires.unshift(new Wire(blocks[2].pins.result[i],registers[2].pins[7-i],"MAR (ALU result), bit "+i,true,false,0,true,true,true)); + wires.unshift(new Wire(blocks[2].pins.result[i],registers[4].pins[7-i],"MDR (ALU result), bit "+i,true,false,0,true,true,true)); + + wires.unshift(new Wire(blocks[2].pins.result[i],registers[3].pins[7-i],"PC (ALU result), bit "+i,3,false,0,true,true,true)); + //inst to mux + wires.push(new Wire(registers[0].pins[15-i],blocks[1].pins.channel1[7-i],"immediate data (mux ch. 1), bit "+i,false,(7-i)<3,(7-i)<3?-2:8)); + } + // decoder to mux2 + wires.unshift(new Wire(blocks[0].pins.toMux[1],blocks[5].pins.selector[0],"mux 1 selector",true,false,0,false,false,true,true,true)); + + // decoder to reg rwenable + wires.unshift(new Wire(blocks[0].pins.registerReadEnable[0],blocks[3].pins.read1Enable[0],"first register read enable",true,false,-34,true,true)); + wires.unshift(new Wire(blocks[0].pins.registerWriteEnable[0],blocks[3].pins.write1Enable[0],"first register write enable",true,false,-35,true,true)); + // decoder to mar rwenable + wires.unshift(new Wire(blocks[0].pins.memAddrReadEnable[0],registers[2].readEnable,"MAR read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.memAddrWriteEnable[0],registers[2].writeEnable,"MAR write enable",3, false,0,true,true,true,true)); + //pc rwenable + wires.unshift(new Wire(blocks[0].pins.pcReadEnable[0],registers[3].readEnable,"PC read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.pcWriteEnable[0],registers[3].writeEnable,"PC write enable",3, false,0,true,true,true,true)); + // m d r rwenable + wires.unshift(new Wire(blocks[0].pins.memDataReadEnable[0],registers[4].readEnable,"MDR read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.memDataWriteEnable[0],registers[4].writeEnable,"MDR write enable",3, false,0,true,true,true,true)); + // instruction to register address + for(var i=0;i<3;i++){ + wires.unshift(new Wire(registers[0].pins[7-i],blocks[3].pins.address1[i],"first register address, bit "+i,3,false,3,true,true,true,true)); + wires.unshift(new Wire(registers[0].pins[10-i],blocks[3].pins.address2[i],"second register address, bit "+i,3,false,3,true,true,true,true)); + } + +} +url=""; +function setup(){ + images["pencil"]=new Image(); + images["pencil"].src='img/pencil.png'; + images["question"]=new Image(); + images["question"].src='img/question.png'; + + ctx.canvas.width = 1440//window.innerWidth*0.75; + ctx.canvas.height = 976 //window.innerHeight; + registers.push(new Register("instruction register",16, 0, w(13), h(36), 60,"above",true,"white","below",16)); + registers.push(new Register("flags",5,0,w(13),h(885),45,"below",false,"white","above")); + registers.push(new Register("memory address register", 16, 0, w(250), h(885), 45, "below",true,"white","above")) + registers.push(new Register("program counter", 16, 0, w(880), h(885), 45, "below",true,"white","above")) + registers.push(new Register("m. data reg.",8,0,880+(registers[registers.length-1].width/2),803,45,"below",true,"white","above")); + + //goddammit + for(var i=2;i{ + var rect = canvas.getBoundingClientRect(); + tooltips = tooltips.filter(t=>t.persist==true); + scaleX=canvas.width/rect.width; + scaleY=canvas.height/rect.height; + isOverOne=false; + this.wires.forEach(wire=>{ + wire.hovered=false; + var pos = {x:(e.clientX-rect.left)*scaleX, y:(e.clientY-rect.top)*scaleY}; + if(wire.input.checkMouse(pos)||wire.output.checkMouse(pos)){ + wire.hovered=true; + tooltips.push(new Tooltip(pos.x,pos.y,wire.label)); + isOverOne=2; + } + }); + blocks.forEach(block=>{ if(block.checkMouse({x:(e.clientX-rect.left)*scaleX, y:(e.clientY-rect.top)*scaleY})){isOverOne=true;url=block.url;} }); + if(isOverOne==1){ + canvas.style.cursor="pointer"; + } else if(isOverOne==2){ + canvas.style.cursor="help"; + } else { + canvas.style.cursor="default"; + url=""; + } + }); + document.addEventListener('click',e=>{ + if(url){ + window.location.href=url; + console.log("no"); + } else { + console.log("no"); + } + }); + requestAnimationFrame(drawCanvas); +} +var wait=false; +function clockTick(t=1000,oneTime=false){ + blocks[4].pulse(1000,wait); + if(wait){ + registers[2].update(); + registers[4].update(); + wait=false; + } else { + if(blocks[2].correctAnswer>-1){ + if(blocks[2].correctAnswer!=blocks[2].values[2].value){ + tick=false; + blocks[2].done = false; + blocks[2].editable = true; + blocks[2].wrong = true; + return; + } + } + if(!tick && !oneTime) return; + registers.forEach(r=>r.update(true)); + actualflags=getNumber(blocks[2].pins.flags); + if(blocks[4].cycles>1) + blocks[3].realUpdate(); + drawMemory(); + nextInstruction(); + } + if(tick){ + setTimeout(clockTick,t,t); + } +} +var tick=false; +const zeroPad = (num, places) => String(num).padStart(places, '0') +var memPage=0; +function nextMemPage(){ + memPage++; + if(memPage>255) memPage=0; + document.getElementById('label_mempage').innerHTML=zeroPad(memPage,3); + drawMemory(); +} +function prevMemPage(){ + memPage--; + if(memPage<0) memPage=255; + document.getElementById('label_mempage').innerHTML=zeroPad(memPage,3); + drawMemory(); +} +function drawMemory(){ + var memTable = document.getElementById('memory').children[0]; + for(var i=1;i<=16;i++){ + var row = memTable.children[i]; + for(var j=1;j<=16;j++){ + var cell = row.children[j]; + var address = ((memPage)<<8)+(i-1)*16+(j-1); + var val = memory[address]; + cell.innerHTML = zeroPad(val,3); + if(val>0) cell.classList.add('nonzero'); else cell.classList.remove('nonzero'); + } + } +} +initialRun=false; +function compile(){ + resetAll(); + try { + ass = new assembler(); + var bytecode = ass.assemble(document.getElementById('program').value); + console.log(ass.labelAddresses); + for(var i=0;ir.update()); +} +var branchyes = false; +var prevInstruction=-1; +function nextInstruction(){ + var pc = registers[3]; + if(!nosetpc){ + if(prevInstruction!=-1) { + pc.set(pc.value+2,false); + } + } else nosetpc=false; + var flag_reg = registers[1]; + var ir = registers[0]; + var mar = registers[2]; + var mdr = registers[4]; + ir.set((memory[pc.value]<<8)+memory[pc.value+1]); + var instruction = ir.value; + var opcode = instruction >> 12; + if(opcode==15){ + tick=false; + runLabel.innerHTML='Run (finished)'; + } + if(opcode==0b1011) return; + prevInstruction=instruction; + // glue code + wait=opcode==0b1001; + var mode = (instruction>>11)&0b00001; + var f = (registers[0].value >> 8)&0b00000111; + //input + var r2 = (instruction & 0x00FF)>>5; + if((opcode!=11 && opcode<=12)&&r2==0&&mode==0){ + var inp = document.getElementById('input'); + if(inp.value.length>0){ + var setTo; + if(document.getElementById('ascii').checked){ + setTo = inp.value[0]; + setTo = setTo.charCodeAt(0); + inp.value = inp.value.substr(1); + } else { + setTo = parseInt(inp.value.split(" ")[0]); + if(inp.value.indexOf(" ")==-1) inp.value=""; else + inp.value = inp.value.substring(inp.value.indexOf(" ")+1); + } + blocks[3].fileRegisters[7].set(setTo,false); + flag_reg.set(flag_reg.value+(1<<4)); + } else { + blocks[3].fileRegisters[7].set(0,false); + } + } + // memory stores + if(opcode==10){ + registers[4].set(blocks[3].fileRegisters[7-f].value); + } + // conditional branching + if(opcode==12||opcode==13){ + if((actualflags+(registers[1].binary[0]=='1'?16:0)) & (1 << f)){ + branchyes=(opcode==12); + nosetpc=(opcode==12); + } else { + branchyes=(opcode==13); + nosetpc=(opcode==13); + } + } + var mode = (ir.value & 0b0000100000000000)>>11; + if(opcode==0b1110) { //jmp: don't increment pc + nosetpc=true; + } + /* + if(opcode==1111 && mode==0){ // setipg + ir.set((171<<8)+((pc.value+4)>>8)); + } + */ + +} +var nosetpc=false; +function resetAll(){ + initialRun=true; + prevInstruction=-1; + branchyes=false; + nosetpc=false; + document.getElementById("output").value=""; + outputBuf = []; + memory = new Array(65536).fill(0); + blocks.forEach(b=>b.reset()); + registers.forEach(r=>r.set(0,false)); + blocks[3].fileRegisters.forEach(r=>r.set(0,false)); +} +function drawCanvas(){ + ctx.clearRect(0, 0, canvas.width, canvas.height); + if(window.debugall) {;} else { + wires.forEach(w=>w.update()); + blocks.forEach(b=>b.update()); + for(var i=0;i<8;i++){ + registers[4].pins[i].write(registers[4].binary[i]); + } + } + wires.forEach(w=>w.draw()); + blocks.forEach(b=>b.draw()); + registers.forEach(r=>r.draw(1)); + blocks.forEach(b=>b.drawOverlay()); + const flags = new Set(); + tooltips.filter(tt=>{if(flags.has(tt.message)){return false};flags.add(tt.message);return true;}).forEach((t,i)=>t.draw(i)); + requestAnimationFrame(drawCanvas); + +}; +function displayOutput(){ + outputBox = document.getElementById("output"); + outputBox.value = "" + outputBuf.forEach(value=>{ + if(document.getElementById('ascii').checked) + outputBox.value += String.fromCharCode(value); + else + document.getElementById("output").value += value + " "; + }) + +} \ No newline at end of file diff --git a/js/index_mod.js b/js/index_mod.js new file mode 100644 index 0000000..890083f --- /dev/null +++ b/js/index_mod.js @@ -0,0 +1,1129 @@ +var registers=[]; +var blocks=[]; +var wires=[]; +var tooltips=[]; +var embedded = {}; +var images={}; +const BORDER_THICKNESS=5.5; +var canvas, ctx; +var outputBuf = [] +var clockTimer; +var opcodes = ['add','sub','adc','subb','nand','xor','sll','srl','mov','ldb','stb', 'nop','bflag','bnoflag', 'jmp', 'hlt']; +var rs = ['io','stackptr','datapg','instpg','gp0','gp1','gp2','gp3']; +var flags = ['zero','carry','negative','overflow','input']; +var memory=new Array(65536).fill(0); +var memPage = 0; +var dataPage = 0; +function getNumber(pins,reverse=true){ + var val = 0; + for(var i=0;i>12; + var addressMode = (machineCode & 0b0000100000000000) >>11; + var r1 = (machineCode & 0b0000011100000000)>>8; + var r2 = (machineCode & 0b0000000011100000)>>5; + var imm8 = machineCode & 0b0000000011111111; + if(opcode==15){ + return(opcodes[opcode]); + } else if(opcode<11) { + return(`${opcodes[opcode]} ${specific?rs[r1]:'reg'}, ${specific?((addressMode?imm8:rs[r2])):addressMode?'imm8':'reg'}`); + } else if (opcode==11){ + return(`${opcodes[opcode]}`); + } else if(opcode==12) { + return(`${opcodes[opcode]} ${specific?flags[r1 & 0b00000111]:'flag'}, ${specific?((addressMode?imm8:rs[r2])):addressMode?'imm8':'reg'}`); + } else { + return(`${opcodes[opcode]} ${specific?((addressMode?imm8:rs[r2])):(addressMode?'imm8':'reg')}`); + } + +} +document.addEventListener("DOMContentLoaded", function(event){ + event; + canvas = document.getElementById("sim"); + ctx = canvas.getContext('2d'); + setup(); + setTimeout(function(){ + embedded['alu'] = document.getElementById('ALUframe').contentWindow.chip; + embedded['mux1'] = document.getElementById('MUX1frame').contentWindow.chip; + embedded['mux2'] = document.getElementById('MUX2frame').contentWindow.chip; + },2000); +}); +function w(width){ + return ((width*canvas.width)/1440); +} +function h(height){ + return ((height*canvas.height)/976); +} +function drawBorder(thing,thickness,color="black"){ + ctx.fillStyle=color; + ctx.fillRect(thing.x-thickness,thing.y-thickness,thing.width+thickness*2,thing.height+thickness*2); +} + +class Block { + constructor(name, x, y, width, height,points=[],editable=true){ + this.name=name; + this.url=""; + this.x=w(x); + this.y=h(y); + this.width=w(width); + this.height=h(height); + this.editable=editable; + this.points=points; + if(this.editable) + this.done=false; + else + this.done=true; + } + update(){ + } + reset(){ + } + makePointArray(){ + this.points=[] + for(const[key,value] of Object.entries(this.pins)){ + key; + //this.points=this.points.concat(value); + value.forEach((pin,i)=>{ pin.number=i; this.points.push(pin) }); + } + + } + drawOverlay(){ + if(!(this.done||this.attempted)){ + ctx.fillStyle="rgba(255,255,255,0.6)"; + ctx.fillRect(this.x,this.y+BORDER_THICKNESS+35,this.width,this.height-BORDER_THICKNESS-35); + ctx.fillStyle="#FFA500" + if(this.wrong) + ctx.fillStyle="#dd3333"; + ctx.fillRect(this.x+this.width/2-35,this.y+this.height/2-35+17,70,70); + ctx.drawImage(images[this.editable?'pencil':'question'],this.x+this.width/2-30,this.y+this.height/2-30+17,60,60); + } else + if(this.editable) + ctx.drawImage(images[this.editable?'pencil':'question'],this.x+this.width-w(37),this.y+this.height-h(30)-h(3),w(30),h(30)); + } + draw(color='white',textcolor='white'){ + ctx.fillStyle=color; + ctx.fillRect(this.x, this.y, this.width, this.height); + ctx.fillStyle="#444"; + ctx.fillRect(this.x,this.y,this.width,BORDER_THICKNESS); + ctx.fillRect(this.x-BORDER_THICKNESS,this.y,BORDER_THICKNESS,this.height+BORDER_THICKNESS); + ctx.fillRect(this.x+this.width,this.y,BORDER_THICKNESS,this.height+BORDER_THICKNESS); + ctx.fillRect(this.x,this.y+this.height,this.width,BORDER_THICKNESS); + if(this.done) + ctx.fillStyle="#43c143"; + else if(!this.attempted) + ctx.fillStyle="#ffa500"; + else + ctx.fillStyle="#dd3333"; + if(this.wrong){ + ctx.fillStyle="#dd3333"; + } + ctx.fillRect(this.x,this.y+BORDER_THICKNESS,this.width,35); + ctx.fillStyle=textcolor; + ctx.font=170*0.15+"px vcr_osd_monoregular"; + ctx.textBaseline = "top"; + ctx.textAlign='left'; + ctx.fillText(this.name,this.x+w(7), this.y+h(13)); + + + this.points.forEach(p=>p.draw()); + } + checkMouse(pos){ + // check if mouse is over icon + if(!this.attempted&&this.editable){ + return pos.x>=this.x+this.width/2-35 && pos.y>=this.y+this.height/2-35 && pos.x<=this.x+this.width/2-35+70 && pos.y<=this.y+this.height/2-35+70; + } else + return pos.x>=this.x+this.width-w(37) && pos.x<=this.x+this.width-w(7) && pos.y>=this.y+this.height-h(33) && pos.y<=this.y+this.height-h(3) && JSON.stringify(Array.from(ctx.getImageData(pos.x,pos.y,1,1).data.slice(0,3)))!="[255,255,255]"; + } +} +class Decoder extends Block { + update(){ + this.setInstruction(humanInstruction(registers[0].value,false),(registers[0].value>>12)); + for(var i=0;i<16;i++){ + if(i<4){ + this.pins.toALU[i].write(this.pins.instruction[i].read()); + } + } + // read from first register only if it's an ALU operation + // write to the first register unless we're in a store or branch instruction + this.pins.registerReadEnable[0].write(this.opcode<8); + this.pins.registerWriteEnable[0].write(this.opcode<10); + // imm8 + this.pins.toMux[0].write(this.pins.instruction[4].read() && this.opcode!=11 &&this.opcode!=15);//(this.mode==1 && this.opcode!=11 && this.opcode!=15)); + + // mem load + this.pins.toMux[1].write(this.opcode==9); + this.pins.memDataReadEnable[0].write(this.opcode==9); + this.pins.memDataWriteEnable[0].write(this.opcode==10); + // + this.pins.memAddrWriteEnable[0].write(this.opcode==9||this.opcode==10); + // jumps + if(this.opcode==14) + this.pins.pcWriteEnable[0].write(1); + else if(this.opcode!=12&&this.opcode!=13) + this.pins.pcWriteEnable[0].write(0); + else + this.pins.pcWriteEnable[0].write(branchyes?1:0); + } + setInstruction(instruction,opcode,mode){ + this.instruction = instruction; + this.opcode=opcode; + this.mode=mode; + } + constructor(x,y,width,height,points=[],editable=true){ + super("decoder",x,y,width,height,points,editable); + this.mode=0; + this.pins = { + instruction: [ + ], + toALU: [ + + ], + toMux: [ + new Pin(this.x+this.width,this.y+this.height-50,6,false,"right"), + new Pin(this.x+this.width,this.y+this.height-50+17,6,false,"right") + ], + registerWriteEnable: [ + new Pin(this.x+this.width,this.y+this.height-140,6,false,"right") + ], + registerReadEnable: [ + new Pin(this.x+this.width,this.y+this.height-157,6,false,"right") + ], + memAddrWriteEnable: [ + new Pin(this.x+190,this.y+this.height), + ], + memAddrReadEnable: [ + new Pin(this.x+207,this.y+this.height) + ], + pcWriteEnable: [ + new Pin(this.x+227+17,this.y+this.height) + ], + pcReadEnable: [ + new Pin(this.x+227+34,this.y+this.height) + ], + memDataWriteEnable:[ + new Pin(this.x+282+17,this.y+this.height) + ], + memDataReadEnable:[ + new Pin(this.x+282+34,this.y+this.height) + ], + + + + + } + for(var i=0;i<5;i++){ + this.pins.instruction.push(new Pin(this.x+17+17*i, this.y)); + if(i<4) + this.pins.toALU.push(new Pin((this.x+17+17*i+(i<4?0:34)), this.y+this.height)); + } + this.makePointArray(); + this.instruction="add reg,reg"; + this.opcode=0; + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.font=250*0.07+"px vcr_osd_monoregular"; + ctx.textBaseline = "top"; + ctx.textAlign='center'; + ctx.fillText("opcode: "+Register.getBits(this.opcode,4)+" / "+Register.getHex(this.opcode,1)+"",this.x+this.width/2-w(4), this.y+h(55)); + var am=this.pins["instruction"][4].read(); + this.mode=am; + ctx.fillText("mode: "+(am?1:0)+" / "+(this.opcode==15?'special':(((am==0||this.opcode==11)?"register":"immediate"))),this.x+this.width/2-w(4), this.y+h(75)); + + ctx.font=240*0.15+"px vcr_osd_monoregular"; + ctx.fillText(this.instruction,this.x+this.width/2-w(4), this.y+h(100)); + } + + +} +class Mux extends Block { + setChannel(c){ + this.channel=c; + } + update(){ + if(this.second){ + if(!embedded.mux2 || !embedded.mux2.pins) return; + embedded.mux2.pins[16] = this.pins.selector[0].read(); + for(var i=0;i<8;i++){ + embedded.mux2.pins[i] = this.pins.channel0[i].read(); + embedded.mux2.pins[8+i] = this.pins.channel1[7-i].read(); + this.pins.output[7-i].write(embedded.mux2.pins[24-i]); + + }}else{ + if(!embedded.mux1 || !embedded.mux1.pins) return; + embedded.mux1.pins[16] = this.pins.selector[0].read(false); + for(var i=0;i<8;i++){ + embedded.mux1.pins[i] = this.pins.channel0[7-i].read(); + embedded.mux1.pins[8+i] = this.pins.channel1[i].read(); + this.pins.output[7-i].write(embedded.mux1.pins[24-i]); + + }} + + + + this.setChannel(this.pins.selector[0].read()==true?1:0); + } + constructor(x,y,width,height,second=false,de=false,points=[],editable=true){ + super((de?"de":"")+"multiplexer",x,y,width,height,points,editable); + this.de=de; + this.second=second; + this.channel=0; + if(second) + var theselector=new Pin(this.x+this.width-17, this.y); + else + var theselector=new Pin(this.x-BORDER_THICKNESS,blocks[0].pins.toMux[0].y,6,"","right") + if(!this.de){ + this.pins={ + selector: [ + theselector + ], + channel0:[ + ], + channel1: [ + ], + output:[ + ] + } + for(var i=0;i<8;i++){ + if(second){ + this.pins.channel1.push(new Pin(this.x+62+17*i,this.y+BORDER_THICKNESS+this.height,6,"","up")); + this.pins.output.push(new Pin(this.x+this.width,this.y+17+17*i,6,"","right")); + this.pins.channel0.push(new Pin(this.x-BORDER_THICKNESS,this.y+17+17*i,6,"","right")); + } else { + this.pins.channel1.push(new Pin(this.x+17+17*i,this.y)); + this.pins.channel0.push(new Pin(this.x+BORDER_THICKNESS+this.width,this.y+17+17*i,6,"","left")); + this.pins.output.push(new Pin(this.x+17+17*i,this.y+this.height)); + } + } + } else { + this.pins={ + selector: [ + new Pin(this.x-BORDER_THICKNESS,this.y+15,6,"","right"), + new Pin(this.x-BORDER_THICKNESS,this.y+30,6,"","right") + ], + input:[ + ], + channel0:[ + ], + channel1:[ + ], + channel2:[ + ] + } + for(var i=0;i<8;i++){ + this.pins.input.push(new Pin(this.x-BORDER_THICKNESS,this.y+67+17*i,6,"","right")); + this.pins.channel0.push(new Pin(this.x+this.width,this.y+17+17*i,6,"","right")); + this.pins.channel1.push(new Pin(this.x+17+17*i,this.y+this.height)); + this.pins.channel2.push(new Pin(this.x+220+17*i,this.y+this.height)); + } + } + this.makePointArray(); + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.font="25px vcr_osd_monoregular"; + ctx.baseline="middle"; + ctx.textAlign="center"; + ctx.fillText(" channel: "+this.channel,this.x+this.width/2,this.y+this.height/2); + } +} +class ALU extends Block { + update(){ + if(!embedded.alu) return; + for(var i=0;i<8;i++){ + if(i<4){ + embedded.alu.pins[19-i] = this.pins.opcode[i].read(); + this.pins.flags[i].write(embedded.alu.pins[29+i]); + } + embedded.alu.pins[i] = this.pins.operand1[i].read(); + embedded.alu.pins[i+8] = this.pins.operand2[i].read(); + this.pins.result[i].write(embedded.alu.pins[21+i]); + } + this.values[3].set(getNumber(this.pins.flags)); + this.values[1].set(getNumber(this.pins.operand1,false)); + this.values[0].set(getNumber(this.pins.operand2,false)); + this.values[2].set(getNumber(this.pins.result,false)); + var opcode=getNumber(this.pins.opcode); + if(opcode==6){ + this.correctAnswer = this.values[1].value << this.values[0].value; + } else { + this.correctAnswer = -1; + } + if(opcode>=8){ + this.operation = "move"; + } else { + this.operation = opcodes[opcode]; + } + + } + constructor(x,y,width,height,points=[],editable=true){ + points; + super("ALU",x,y,width,height,wires,editable); + this.wrong=false; + this.operation="add"; + this.values=[new Register("operand 1",8,0,this.x+w(20),this.y+h(80),50,"above",true,"black"), + new Register("operand 0",8,0,this.x+w(20),this.y+h(175),50,"above",true,"black"), + new Register("result",8,0,this.x+w(20),this.y+h(340),50,"above",true,"black"), + new Register("O N C Z flags",4,1,this.x+w(20),this.y+h(410),32,"above",false,"black")]; + //new Register("O . N . C . Z",4,0,this.x+w(125),this.y+h(360),30,"above",false,"black")]; + this.pins={ opcode: []/*,setFlags:[]*/, operand1:[], operand2:[],flags:[],result:[] } + for(var i=0;i<4;i++){ + this.pins.opcode.push(new Pin(this.x+17+17*i,this.y)); + this.pins.flags.push(new Pin(this.x+17+17*i,this.y+this.height)); + } + this.pins.flags[3].write(1); + for(var i=0;i<8;i++){ + this.pins.operand2.push(new Pin(this.x+this.width+BORDER_THICKNESS, this.y+17+17*i,6,"","left")); + this.pins.operand1.push(new Pin(this.x+this.width+BORDER_THICKNESS, this.y+167+17*i,6,"","left")); + this.pins.result.push(new Pin(this.x+this.width, this.y+317+17*i,6,"","right")); + } + + //this.pins.setFlags.push(new Pin(this.x+17*5+34,this.y)); + //this.pins.setFlags[0].write(1); + + this.makePointArray(); + + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.font="25px vcr_osd_monoregular"; + ctx.fillText("operation: "+this.operation,this.x+this.width/2, this.y+260); + ctx.font="15px vcr_osd_monoregular"; + //ctx.fillText("set flags: "+(this.pins.setFlags[0].read()==1?"yes":"no"),this.x+this.width/2, this.y+280); + ctx.fillRect(this.x+20,this.y+300,this.width-40,2); + this.values.forEach(v=>v.draw(0)); + } +} +class RegisterFile extends Block { + fileRegisters = []; + selected(){ + return{r1:this.fileRegisters[7-getNumber(this.pins.address1,false)], r2:this.fileRegisters[7-getNumber(this.pins.address2,false)]}; + } + update(){ + for(var i=0;i<8;i++){ + if(this.pins.read1Enable[0].read()) + this.pins.data1[7-i].write(this.selected().r1.binary[i]); + this.pins.data2[7-i].write(this.selected().r2.binary[i]); + } + } + realUpdate(){ + if(!!this.pins.write1Enable[0].read()) { + this.selected().r1.set(getNumber(this.pins.writeback,false),true); + } + } + constructor(x,y,fileRegisters=[],pins=[],editable=true){ + pins,editable; + super("registers",x,y,0,fileRegisters.length*h(85)+h(45),wires,false); + fileRegisters.forEach((r,i)=>{ + if(!r.bits){ + r.bits=8 + } + this.fileRegisters.push(new Register(r.name,r.bits,0,x+w(20),y+i*h(85)+h(65),40,"above",true,"black")); + }); + this.width=this.fileRegisters[0].width+w(80); + this.pins={ + clock:[ new Pin(this.x-BORDER_THICKNESS,this.y+17,6,"","right") ], + read1Enable: [ new Pin(this.x-BORDER_THICKNESS,this.y+17+35,6,"","right") ], + write1Enable: [new Pin(this.x-BORDER_THICKNESS,this.y+34+35,6,"","right") ], + address1: [ ], + address2: [ ], + data2:[ ], + data1:[ ], + writeback:[] + }; + for(var i=0;i<3;i++){ + this.pins.address2.push(new Pin(this.x-BORDER_THICKNESS,this.y+55+35+17+17*i,6,"","right")); + this.pins.address1.push(new Pin(this.x-BORDER_THICKNESS,this.y+125+35+17+17*i,6,"","right")); + } + for(var i=0;i<8;i++){ + this.pins.data2.push(new Pin(this.x,this.y+205+35+17+17*i,6,"","left")); + this.pins.data1.push(new Pin(this.x,this.y+365+35+17+17*i,6,"","left")); + this.pins.writeback.push(new Pin(this.x-BORDER_THICKNESS,this.y+530+35+17+17*i,6,"","right")); + } + super.makePointArray(); + } + draw(){ + super.draw(); + this.fileRegisters.forEach(r=>r.draw(1)); + } +} +class Clock extends Block { + reset(){ + this.state=0; + this.cycles=0; + } + update(){ + this.pins.clk[0].write(this.state); + } + constructor(x,y,width,height){ + super("clock",x,y,width,height,[],false); + this.pins={clk:[new Pin(this.x+this.width,this.y+17,6,"","right")]}; + super.makePointArray(); + this.cycles=0; + this.state=0; + } + pulse(t,w=false){ + this.state = 1; + if(!w) + this.cycles+=1; + setTimeout(function(){this.state=0}.bind(this),t/10); + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.fillText(this.cycles,this.x+this.width/2,this.y+this.height/2+20); + } +} + +class Register { + pins=[]; + update(fuck=false){ + /*if(this.name=="memory address register" && fuck) return; + if(this.name=="m. data reg." && fuck) return;*/ + if(this.name=="flags"){ + this.set(getNumber(this.pins)); + if(document.getElementById("input").value.length>0) + this.value=this.value|0b10000; + else { + this.value=this.value & 0b01111; + } + this.set(this.value); + } + else if('writeEnable' in this) { + if(!!this.writeEnable.read()){ + this.set(getNumber(this.pins)); + } + } + if(this.name=="m. data reg."){ + var mAddr = registers[2].value; + if(this.writeEnable.read()){ + memory[mAddr] = this.value; + } + if(this.readEnable.read()||initialRun){ + initialRun=false; + this.set(memory[mAddr]); + } + } + } + static getBits(n,digits=8){ + if(n<0||n>=Math.pow(2,digits)||n%1!==0) { + //console.error(n+" is fucked, yo"); + } + return ("0000000000000000"+n.toString(2)).substr(-digits); + } + static getHex(n, digits=2){ + return "0x"+("0000"+n.toString(16).toUpperCase()).substr(-digits); + } + constructor(name, bits, value,x,y,scale,position="above",showValue=true,textColor="white",pins=false,numPins=8){ + this.name=name; + this.bits=bits; + this.x=w(x); + this.y=h(y); + this.width=w(scale * this.bits)*0.75; + this.height=h(scale); + this.above=position=="above"; + this.showValue=showValue; + this.textColor=textColor; + if(pins) + for(var i=bits-Math.min(bits,numPins);i{ pin.write(this.binary[i]) }); + + } + draw(border=0){ + if(this.name=="flags"){ + this.value=actualflags; + if(document.getElementById("input").value.length>0) + this.value=this.value|0b10000; + else { + this.value=this.value & 0b01111; + } + this.set(this.value); + } + + drawBorder(this,border); + ctx.fillStyle='white'; + ctx.fillRect(this.x,this.y,this.width,this.height); + var section_width = this.width/this.bits; + // draw text and separators + // labels + ctx.fillStyle = this.textColor; + ctx.font=this.height*0.4+"px vcr_osd_monoregular"; + var textY; + if(this.above){ + ctx.textBaseline = "bottom"; + textY = this.y-this.height*0.05; + } else { + ctx.textBaseline = "top"; + textY = this.y + this.height + this.height * 0.05; + ctx.fillStyle="rgba(24,27,32,0.5)"; + ctx.fillRect(this.x,this.y+this.height,this.width,21); + ctx.fillStyle="white"; + } + ctx.textAlign = "left"; + ctx.fillText(this.name,this.x,textY) + ctx.textAlign = "right"; + if(this.name=="instruction register"){ + ctx.fillText(humanInstruction(this.value),this.x+this.width,textY); + } else + this.showValue ? ctx.fillText(this.value+" | "+Register.getHex(this.value,(this.bits/4)),this.x+this.width,textY) : null; + + for(var i=0;i0) { + ctx.fillRect(this.x+section_width*i,this.y,2,this.height); + } + } + this.pins.forEach(pin=>pin.draw()); + if(this.readEnable){ + ctx.fillStyle="black"; + ctx.fillRect(this.x-6,this.y,6,this.height); + this.readEnable.draw(); + this.writeEnable.draw(); + } + } +} +var actualflags=0; +function pointInCircle(x, y, cx, cy, radius) { + var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy); + return distancesquared <= radius * radius; +} +class Pin { + constructor(x,y,radius=6,label=false,direction="down"){ + this.x=x; + this.y=y; + this.radius=radius; + this.state=0; + this.label=label; + this.direction=direction; + } + read(){ + return this.state; + } + write(state){ + this.state=state==true?1:0; + } + checkMouse(pos){ + return pointInCircle(pos.x,pos.y,this.x,this.y,this.radius); + } + draw(){ + ctx.fillStyle=this.read()==1?"red":"lightgray"; + ctx.beginPath(); + if(this.direction=="down"){ + ctx.arc(this.x,this.y,this.radius, 0*Math.PI,1*Math.PI,false); + } else if(this.direction=="right"){ + ctx.arc(this.x,this.y,this.radius,1.5*Math.PI,0.5*Math.PI,false); + } else if(this.direction=="left") { + ctx.arc(this.x,this.y,this.radius,0.5*Math.PI,1.5*Math.PI,false); + } else if (this.direction=="up") { + ctx.arc(this.x,this.y,this.radius, -1*Math.PI,0*Math.PI,false); + + } + ctx.fill(); + } +} + +class Wire { + update(){ + var state=!!this.input.read(); + if(this.killme>-1){ + if(registers[4].readEnable.read()){ + state = parseInt(registers[4].binary[7-this.killme]); + this.input.write(state); + } + } + this.state=state; + var hovered = this.input.hovered =1 || this.output.hovered == 1; + if(!this.behind) + this.color=state?"#F00":"#AAA"; + else if(this.behind==1) + this.color=state?"#A00":"#777"; + else + this.color=state?"#800":"#555"; + this.output.write(state); + } + draw(){ + ctx.beginPath(); + ctx.moveTo(this.input.x,this.input.y); + var n = this.output.number; + n = n - this.reindex; + var fuckyou = (this.output.number==0 && this.input.direction=="down")?2:0; + if (this.fuckoffanddie){ + ctx.lineTo(435,this.input.y); + ctx.lineTo(435,650); + ctx.lineTo(760,650); + ctx.lineTo(760,570); + ctx.lineTo(this.output.x,570); + } else { + if(!this.horizontal){ + if(!this.reverse){ + ctx.lineTo(this.input.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.45+n*7,0)); + ctx.lineTo(this.output.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.45+n*7,0.0)); + } else { + /* + ctx.lineTo(this.input.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + ctx.lineTo(this.output.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + */ + ctx.lineTo(this.input.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.56-n*6,0)); + ctx.lineTo(this.output.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.56-n*6,0.0)); + } + } else { + if(!this.reverse){ + //ctx.lineTo(this.input.x+fuckyou+Math.max((this.output.x-this.input.x)*0.45+n*7,0),this.input.y); + //ctx.lineTo(this.input.x+fuckyou+Math.max((this.output.x-this.input.x)*0.45+n*7,0.0),this.output.y); + if(!this.zigzag){ + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45+n*7),this.input.y); + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45+n*7),this.output.y); + } else{ + if(this.kms) + ctx.lineTo(this.input.x,this.output.y) + else + ctx.lineTo(this.output.x,this.input.y) + } + } else { + if(!this.zigzag){ + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45-n*7),this.input.y); + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45-n*7),this.output.y); + } else{ + ctx.lineTo(this.input.x,this.output.y) + } + /* + ctx.lineTo(this.input.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + ctx.lineTo(this.output.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + */ + + } + + }} + ctx.lineTo(this.output.x, this.output.y); + var redcolor,graycolor; + if(this.behind==0){ + redcolor="#F0F" + graycolor="#99F" + } else if(this.behind==1) { + redcolor="#A0A" + graycolor="#55F" + } else { + redcolor = "#808" + graycolor="#22F" + } + ctx.strokeStyle=this.hovered?(this.state?redcolor:graycolor):this.color + // cursed ctx.strokeStyle=this.color.substr(0,3)+(this.hovered?"F"/*(Math.min(parseInt(this.color[1],16)+3,15)).toString(16)*/:this.color[3]); + ctx.lineWidth=this.hovered?6:4; + ctx.stroke(); + } + constructor(input, output, label,behind=false, reverse=false,reindex=0,horizontal=false,flip=false,zigzag=false,kms=false,fuckoffanddie=false,killme=-1 ){ + this.input=input; + this.fuckoffanddie=fuckoffanddie; + this.output=output; + this.label=label; + this.reverse=reverse; + this.reindex=reindex; + this.behind=behind; + this.horizontal=horizontal; + this.flip=flip?-1:1; + this.zigzag=zigzag; + this.kms=kms; + this.killme=killme; + } +} +class Tooltip { + constructor(x,y,message,persist=false){ + this.x=x; + this.y=y; + this.message=message; + this.persist=persist; + } + draw(offset){ + ctx.fillStyle="rgba(0,0,0,0.65)"; + ctx.font="20px vcr_osd_monoregular"; + ctx.textBaseline="bottom"; + ctx.textAlign="left"; + var width=ctx.measureText(this.message).width+6; + ctx.fillRect(this.x<720?this.x:this.x-width,this.y-25-(26*offset),width,25); + ctx.fillStyle="white"; + ctx.fillText(this.message,this.x<720?(this.x+3):(this.x-width+3),this.y-(26*offset)); + } +} +function wireUp(){ + // clock + wires.push(new Wire(blocks[4].pins.clk[0],blocks[3].pins.clock[0],"clock")); + // instruction to decoder + //decoder to ALU + for(var i=0;i<5;i++){ + wires.push(new Wire(registers[0].pins[i],blocks[0].pins["instruction"][i],i<4?("opcode bit "+(3-i)):"addressing mode",false,false,2)); + if(i<4) + wires.push(new Wire(blocks[0].pins.toALU[i],blocks[2].points[i],i<4?"ALU opcode bit ":"set flags?")); + } + for(var i=0;i<8;i++){ + ///m data reg to mux + wires.push(new Wire(blocks[5].pins.channel1[7-i],registers[4].pins[7-i],"MDR (mux ch. 1), bit "+i,false,true,3,false,false,false,false,false,i)); + //wires.push(new Wire(blocks[5].pins.channel1[7-i],registers[4].pins[7-i],"memory data register, bit "+(7-i),false,true,5,false,false,false)); + + } + // ALU to flags + var flagtext=["overflow flag","negative flag","carry flag","zero flag"] + for(var i=0;i<4;i++){ + wires.push(new Wire(blocks[2].pins.flags[i],registers[1].pins[i+1],flagtext[i],false,true,2)); + } + //// INPUT OUTPUT STOPS BEHIND REVERSE REINDEX HORIZONTAL FLIP + // decoder to mux control + wires.push(new Wire(blocks[0].pins.toMux[0],blocks[1].pins.selector[0],"mux 0 selector")); + // instruction to multiplexer + for(var i=0;i<8;i++){ + // reg to mux and alu + wires.push(new Wire(blocks[3].pins.data1[i],blocks[2].pins.operand1[i],"first register data (operand 0), bit "+i,false,true,30,true)); + wires.push(new Wire(blocks[3].pins.data2[i],blocks[1].pins.channel0[i],"second register data (mux ch. 0), bit "+i,false,false,0,true)); + //mux to alu + wires.push(new Wire(blocks[1].pins.output[i],blocks[2].pins.operand2[7-i],/*"mux output, bit "+i*/"mux output (operand 1), bit "+[7-i],false,true,0,true,true,true)); + //alu to writeback + //wires.push(new Wire(blocks[2].pins.result[i],blocks[3].pins.writeback[i],"ALU result, bit "+i,false,false,-29,true,true)); + + wires.push(new Wire(blocks[5].pins.output[i],blocks[3].pins.writeback[i],"mux output (reg writeback), bit "+i,false,false,-29,true,true)); + wires.push(new Wire(blocks[2].pins.result[i],blocks[5].pins.channel0[i],"mux ch. 0 (ALU result), bit "+i,false,false,-29,true,true)); + + //alu to mar + wires.unshift(new Wire(blocks[2].pins.result[i],registers[2].pins[7-i],"MAR (ALU result), bit "+i,true,false,0,true,true,true)); + wires.unshift(new Wire(blocks[2].pins.result[i],registers[4].pins[7-i],"MDR (ALU result), bit "+i,true,false,0,true,true,true)); + + wires.unshift(new Wire(blocks[2].pins.result[i],registers[3].pins[7-i],"PC (ALU result), bit "+i,3,false,0,true,true,true)); + //inst to mux + wires.push(new Wire(registers[0].pins[15-i],blocks[1].pins.channel1[7-i],"immediate data (mux ch. 1), bit "+i,false,(7-i)<3,(7-i)<3?-2:8)); + } + // decoder to mux2 + wires.unshift(new Wire(blocks[0].pins.toMux[1],blocks[5].pins.selector[0],"mux 1 selector",true,false,0,false,false,true,true,true)); + + // decoder to reg rwenable + wires.unshift(new Wire(blocks[0].pins.registerReadEnable[0],blocks[3].pins.read1Enable[0],"first register read enable",true,false,-34,true,true)); + wires.unshift(new Wire(blocks[0].pins.registerWriteEnable[0],blocks[3].pins.write1Enable[0],"first register write enable",true,false,-35,true,true)); + // decoder to mar rwenable + wires.unshift(new Wire(blocks[0].pins.memAddrReadEnable[0],registers[2].readEnable,"MAR read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.memAddrWriteEnable[0],registers[2].writeEnable,"MAR write enable",3, false,0,true,true,true,true)); + //pc rwenable + wires.unshift(new Wire(blocks[0].pins.pcReadEnable[0],registers[3].readEnable,"PC read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.pcWriteEnable[0],registers[3].writeEnable,"PC write enable",3, false,0,true,true,true,true)); + // m d r rwenable + wires.unshift(new Wire(blocks[0].pins.memDataReadEnable[0],registers[4].readEnable,"MDR read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.memDataWriteEnable[0],registers[4].writeEnable,"MDR write enable",3, false,0,true,true,true,true)); + // instruction to register address + for(var i=0;i<3;i++){ + wires.unshift(new Wire(registers[0].pins[7-i],blocks[3].pins.address1[i],"first register address, bit "+i,3,false,3,true,true,true,true)); + wires.unshift(new Wire(registers[0].pins[10-i],blocks[3].pins.address2[i],"second register address, bit "+i,3,false,3,true,true,true,true)); + } + +} +url=""; +function setup(){ + images["pencil"]=new Image(); + images["pencil"].src='img/pencil.png'; + images["question"]=new Image(); + images["question"].src='img/question.png'; + + ctx.canvas.width = 1440//window.innerWidth*0.75; + ctx.canvas.height = 976 //window.innerHeight; + registers.push(new Register("instruction register",16, 0, w(13), h(36), 60,"above",true,"white","below",16)); + registers.push(new Register("flags",5,0,w(13),h(885),45,"below",false,"white","above")); + registers.push(new Register("memory address register", 16, 0, w(250), h(885), 45, "below",true,"white","above")) + registers.push(new Register("program counter", 16, 0, w(880), h(885), 45, "below",true,"white","above")) + registers.push(new Register("m. data reg.",8,0,880+(registers[registers.length-1].width/2),803,45,"below",true,"white","above")); + + //goddammit + for(var i=2;i{ + var rect = canvas.getBoundingClientRect(); + tooltips = tooltips.filter(t=>t.persist==true); + scaleX=canvas.width/rect.width; + scaleY=canvas.height/rect.height; + isOverOne=false; + this.wires.forEach(wire=>{ + wire.hovered=false; + var pos = {x:(e.clientX-rect.left)*scaleX, y:(e.clientY-rect.top)*scaleY}; + if(wire.input.checkMouse(pos)||wire.output.checkMouse(pos)){ + wire.hovered=true; + tooltips.push(new Tooltip(pos.x,pos.y,wire.label)); + isOverOne=2; + } + }); + blocks.forEach(block=>{ if(block.checkMouse({x:(e.clientX-rect.left)*scaleX, y:(e.clientY-rect.top)*scaleY})){isOverOne=true;url=block.url;} }); + if(isOverOne==1){ + canvas.style.cursor="pointer"; + } else if(isOverOne==2){ + canvas.style.cursor="help"; + } else { + canvas.style.cursor="default"; + url=""; + } + }); + document.addEventListener('click',e=>{ + if(url){ + window.location.href=url; + console.log("no"); + } else { + console.log("no"); + } + }); + requestAnimationFrame(drawCanvas); +} +var wait=false; +function clockTick(t=1000,oneTime=false){ + blocks[4].pulse(1000,wait); + if(wait){ + registers[2].update(); + registers[4].update(); + wait=false; + } else { + if(blocks[2].correctAnswer>-1){ + if(blocks[2].correctAnswer!=blocks[2].values[2].value){ + tick=false; + blocks[2].done = false; + blocks[2].editable = true; + blocks[2].wrong = true; + return; + } + } + if(!tick && !oneTime) return; + registers.forEach(r=>r.update(true)); + actualflags=getNumber(blocks[2].pins.flags); + if(blocks[4].cycles>1) + blocks[3].realUpdate(); + drawMemory(); + nextInstruction(); + } + if(tick){ + setTimeout(clockTick,t,t); + } +} +var tick=false; +const zeroPad = (num, places) => String(num).padStart(places, '0') +var memPage=0; +function nextMemPage(){ + memPage++; + if(memPage>255) memPage=0; + document.getElementById('label_mempage').innerHTML=zeroPad(memPage,3); + drawMemory(); +} +function prevMemPage(){ + memPage--; + if(memPage<0) memPage=255; + document.getElementById('label_mempage').innerHTML=zeroPad(memPage,3); + drawMemory(); +} +function drawMemory(){ + var memTable = document.getElementById('memory').children[0]; + for(var i=1;i<=16;i++){ + var row = memTable.children[i]; + for(var j=1;j<=16;j++){ + var cell = row.children[j]; + var address = ((memPage)<<8)+(i-1)*16+(j-1); + var val = memory[address]; + cell.innerHTML = zeroPad(val,3); + if(val>0) cell.classList.add('nonzero'); else cell.classList.remove('nonzero'); + } + } +} +initialRun=false; +function compile(){ + resetAll(); + try { + ass = new assembler(); + var bytecode = ass.assemble(document.getElementById('program').value); + console.log(ass.labelAddresses); + for(var i=0;ir.update()); +} +var branchyes = false; +var prevInstruction=-1; +function nextInstruction(){ + var pc = registers[3]; + if(!nosetpc){ + if(prevInstruction!=-1) { + pc.set(pc.value+2,false); + } + } else nosetpc=false; + var flag_reg = registers[1]; + var ir = registers[0]; + var mar = registers[2]; + var mdr = registers[4]; + ir.set((memory[pc.value]<<8)+memory[pc.value+1]); + var instruction = ir.value; + var opcode = instruction >> 12; + if(opcode==15){ + tick=false; + runLabel.innerHTML='Run (finished)'; + } + if(opcode==0b1011) return; + prevInstruction=instruction; + // glue code + wait=opcode==0b1001; + var mode = (instruction>>11)&0b00001; + var f = (registers[0].value >> 8)&0b00000111; + //input + var r2 = (instruction & 0x00FF)>>5; + if((opcode!=11 && opcode<=12)&&r2==0&&mode==0){ + var inp = document.getElementById('input'); + if(inp.value.length>0){ + var setTo; + if(document.getElementById('ascii').checked){ + setTo = inp.value[0]; + setTo = setTo.charCodeAt(0); + inp.value = inp.value.substr(1); + } else { + setTo = parseInt(inp.value.split(" ")[0]); + if(inp.value.indexOf(" ")==-1) inp.value=""; else + inp.value = inp.value.substring(inp.value.indexOf(" ")+1); + } + blocks[3].fileRegisters[7].set(setTo,false); + flag_reg.set(flag_reg.value+(1<<4)); + } else { + blocks[3].fileRegisters[7].set(0,false); + } + } + // memory stores + if(opcode==10){ + registers[4].set(blocks[3].fileRegisters[7-f].value); + } + // conditional branching + if(opcode==12||opcode==13){ + if((actualflags+(registers[1].binary[0]=='1'?16:0)) & (1 << f)){ + branchyes=(opcode==12); + nosetpc=(opcode==12); + } else { + branchyes=(opcode==13); + nosetpc=(opcode==13); + } + } + var mode = (ir.value & 0b0000100000000000)>>11; + if(opcode==0b1110) { //jmp: don't increment pc + nosetpc=true; + } + /* + if(opcode==1111 && mode==0){ // setipg + ir.set((171<<8)+((pc.value+4)>>8)); + } + */ + +} +var nosetpc=false; +function resetAll(){ + initialRun=true; + prevInstruction=-1; + branchyes=false; + nosetpc=false; + document.getElementById("output").value=""; + outputBuf = []; + memory = new Array(65536).fill(0); + blocks.forEach(b=>b.reset()); + registers.forEach(r=>r.set(0,false)); + blocks[3].fileRegisters.forEach(r=>r.set(0,false)); +} +function drawCanvas(){ + ctx.clearRect(0, 0, canvas.width, canvas.height); + if(window.debugall) {;} else { + wires.forEach(w=>w.update()); + blocks.forEach(b=>b.update()); + for(var i=0;i<8;i++){ + registers[4].pins[i].write(registers[4].binary[i]); + } + } + wires.forEach(w=>w.draw()); + blocks.forEach(b=>b.draw()); + registers.forEach(r=>r.draw(1)); + blocks.forEach(b=>b.drawOverlay()); + const flags = new Set(); + tooltips.filter(tt=>{if(flags.has(tt.message)){return false};flags.add(tt.message);return true;}).forEach((t,i)=>t.draw(i)); + requestAnimationFrame(drawCanvas); + +}; +function displayOutput(){ + outputBox = document.getElementById("output"); + outputBox.value = "" + outputBuf.forEach(value=>{ + if(!document.getElementById('ascii').checked) + outputBox.value += String.fromCharCode(b); + else + document.getElementById("output").value += value + " "; + }) + +} \ No newline at end of file diff --git a/js/index_old.js b/js/index_old.js new file mode 100644 index 0000000..efc8287 --- /dev/null +++ b/js/index_old.js @@ -0,0 +1,1112 @@ +var registers=[]; +var blocks=[]; +var wires=[]; +var tooltips=[]; +var embedded = {}; +var images={}; +const BORDER_THICKNESS=5.5; +var canvas, ctx; +var clockTimer; +var opcodes = ['add','sub','adc','subb','nand','xor','sll','srl','mov','ldb','stb', 'nop','bflag','bnoflag', 'jmp', 'hlt']; +var rs = ['io','stackptr','datapg','instpg','gp0','gp1','gp2','gp3']; +var flags = ['zero','carry','negative','overflow','input']; +var memory=new Array(65536).fill(0); +var memPage = 0; +var dataPage = 0; +function getNumber(pins,reverse=true){ + var val = 0; + for(var i=0;i>12; + var addressMode = (machineCode & 0b0000100000000000) >>11; + var r1 = (machineCode & 0b0000011100000000)>>8; + var r2 = (machineCode & 0b0000000011100000)>>5; + var imm8 = machineCode & 0b0000000011111111; + if(opcode==15){ + return(opcodes[opcode]); + } else if(opcode<11) { + return(`${opcodes[opcode]} ${specific?rs[r1]:'reg'}, ${specific?((addressMode?imm8:rs[r2])):addressMode?'imm8':'reg'}`); + } else if (opcode==11){ + return(`${opcodes[opcode]}`); + } else if(opcode==12) { + return(`${opcodes[opcode]} ${specific?flags[r1 & 0b00000111]:'flag'}, ${specific?((addressMode?imm8:rs[r2])):addressMode?'imm8':'reg'}`); + } else { + return(`${opcodes[opcode]} ${specific?((addressMode?imm8:rs[r2])):(addressMode?'imm8':'reg')}`); + } + +} +document.addEventListener("DOMContentLoaded", function(event){ + event; + canvas = document.getElementById("sim"); + ctx = canvas.getContext('2d'); + setup(); + setTimeout(function(){ + embedded['alu'] = document.getElementById('ALUframe').contentWindow.chip; + embedded['mux1'] = document.getElementById('MUX1frame').contentWindow.chip; + embedded['mux2'] = document.getElementById('MUX2frame').contentWindow.chip; + },2000); +}); +function w(width){ + return ((width*canvas.width)/1440); +} +function h(height){ + return ((height*canvas.height)/976); +} +function drawBorder(thing,thickness,color="black"){ + ctx.fillStyle=color; + ctx.fillRect(thing.x-thickness,thing.y-thickness,thing.width+thickness*2,thing.height+thickness*2); +} + +class Block { + constructor(name, x, y, width, height,points=[],editable=true){ + this.name=name; + this.url=""; + this.x=w(x); + this.y=h(y); + this.width=w(width); + this.height=h(height); + this.editable=editable; + this.points=points; + if(this.editable) + this.done=false; + else + this.done=true; + } + update(){ + } + reset(){ + } + makePointArray(){ + this.points=[] + for(const[key,value] of Object.entries(this.pins)){ + key; + //this.points=this.points.concat(value); + value.forEach((pin,i)=>{ pin.number=i; this.points.push(pin) }); + } + + } + drawOverlay(){ + if(!(this.done||this.attempted)){ + ctx.fillStyle="rgba(255,255,255,0.6)"; + ctx.fillRect(this.x,this.y+BORDER_THICKNESS+35,this.width,this.height-BORDER_THICKNESS-35); + ctx.fillStyle="#FFA500" + if(this.wrong) + ctx.fillStyle="#dd3333"; + ctx.fillRect(this.x+this.width/2-35,this.y+this.height/2-35+17,70,70); + ctx.drawImage(images[this.editable?'pencil':'question'],this.x+this.width/2-30,this.y+this.height/2-30+17,60,60); + } else + if(this.editable) + ctx.drawImage(images[this.editable?'pencil':'question'],this.x+this.width-w(37),this.y+this.height-h(30)-h(3),w(30),h(30)); + } + draw(color='white',textcolor='white'){ + ctx.fillStyle=color; + ctx.fillRect(this.x, this.y, this.width, this.height); + ctx.fillStyle="#444"; + ctx.fillRect(this.x,this.y,this.width,BORDER_THICKNESS); + ctx.fillRect(this.x-BORDER_THICKNESS,this.y,BORDER_THICKNESS,this.height+BORDER_THICKNESS); + ctx.fillRect(this.x+this.width,this.y,BORDER_THICKNESS,this.height+BORDER_THICKNESS); + ctx.fillRect(this.x,this.y+this.height,this.width,BORDER_THICKNESS); + if(this.done) + ctx.fillStyle="#43c143"; + else if(!this.attempted) + ctx.fillStyle="#ffa500"; + else + ctx.fillStyle="#dd3333"; + if(this.wrong){ + ctx.fillStyle="#dd3333"; + } + ctx.fillRect(this.x,this.y+BORDER_THICKNESS,this.width,35); + ctx.fillStyle=textcolor; + ctx.font=170*0.15+"px vcr_osd_monoregular"; + ctx.textBaseline = "top"; + ctx.textAlign='left'; + ctx.fillText(this.name,this.x+w(7), this.y+h(13)); + + + this.points.forEach(p=>p.draw()); + } + checkMouse(pos){ + // check if mouse is over icon + if(!this.attempted&&this.editable){ + return pos.x>=this.x+this.width/2-35 && pos.y>=this.y+this.height/2-35 && pos.x<=this.x+this.width/2-35+70 && pos.y<=this.y+this.height/2-35+70; + } else + return pos.x>=this.x+this.width-w(37) && pos.x<=this.x+this.width-w(7) && pos.y>=this.y+this.height-h(33) && pos.y<=this.y+this.height-h(3) && JSON.stringify(Array.from(ctx.getImageData(pos.x,pos.y,1,1).data.slice(0,3)))!="[255,255,255]"; + } +} +class Decoder extends Block { + update(){ + this.setInstruction(humanInstruction(registers[0].value,false),(registers[0].value>>12)); + for(var i=0;i<16;i++){ + if(i<4){ + this.pins.toALU[i].write(this.pins.instruction[i].read()); + } + } + // read from first register only if it's an ALU operation + // write to the first register unless we're in a store or branch instruction + this.pins.registerReadEnable[0].write(this.opcode<8); + this.pins.registerWriteEnable[0].write(this.opcode<10); + // imm8 + this.pins.toMux[0].write(this.pins.instruction[4].read() && this.opcode!=11 &&this.opcode!=15);//(this.mode==1 && this.opcode!=11 && this.opcode!=15)); + + // mem load + this.pins.toMux[1].write(this.opcode==9); + this.pins.memDataReadEnable[0].write(this.opcode==9); + this.pins.memDataWriteEnable[0].write(this.opcode==10); + // + this.pins.memAddrWriteEnable[0].write(this.opcode==9||this.opcode==10); + // jumps + if(this.opcode==14) + this.pins.pcWriteEnable[0].write(1); + else if(this.opcode!=12&&this.opcode!=13) + this.pins.pcWriteEnable[0].write(0); + else + this.pins.pcWriteEnable[0].write(branchyes?1:0); + } + setInstruction(instruction,opcode,mode){ + this.instruction = instruction; + this.opcode=opcode; + this.mode=mode; + } + constructor(x,y,width,height,points=[],editable=true){ + super("decoder",x,y,width,height,points,editable); + this.mode=0; + this.pins = { + instruction: [ + ], + toALU: [ + + ], + toMux: [ + new Pin(this.x+this.width,this.y+this.height-50,6,false,"right"), + new Pin(this.x+this.width,this.y+this.height-50+17,6,false,"right") + ], + registerWriteEnable: [ + new Pin(this.x+this.width,this.y+this.height-140,6,false,"right") + ], + registerReadEnable: [ + new Pin(this.x+this.width,this.y+this.height-157,6,false,"right") + ], + memAddrWriteEnable: [ + new Pin(this.x+190,this.y+this.height), + ], + memAddrReadEnable: [ + new Pin(this.x+207,this.y+this.height) + ], + pcWriteEnable: [ + new Pin(this.x+227+17,this.y+this.height) + ], + pcReadEnable: [ + new Pin(this.x+227+34,this.y+this.height) + ], + memDataWriteEnable:[ + new Pin(this.x+282+17,this.y+this.height) + ], + memDataReadEnable:[ + new Pin(this.x+282+34,this.y+this.height) + ], + + + + + } + for(var i=0;i<5;i++){ + this.pins.instruction.push(new Pin(this.x+17+17*i, this.y)); + if(i<4) + this.pins.toALU.push(new Pin((this.x+17+17*i+(i<4?0:34)), this.y+this.height)); + } + this.makePointArray(); + this.instruction="add reg,reg"; + this.opcode=0; + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.font=250*0.07+"px vcr_osd_monoregular"; + ctx.textBaseline = "top"; + ctx.textAlign='center'; + ctx.fillText("opcode: "+Register.getBits(this.opcode,4)+" / "+Register.getHex(this.opcode,1)+"",this.x+this.width/2-w(4), this.y+h(55)); + var am=this.pins["instruction"][4].read(); + this.mode=am; + ctx.fillText("mode: "+(am?1:0)+" / "+(this.opcode==15?'special':(((am==0||this.opcode==11)?"register":"immediate"))),this.x+this.width/2-w(4), this.y+h(75)); + + ctx.font=240*0.15+"px vcr_osd_monoregular"; + ctx.fillText(this.instruction,this.x+this.width/2-w(4), this.y+h(100)); + } + + +} +class Mux extends Block { + setChannel(c){ + this.channel=c; + } + update(){ + if(this.second){ + if(!embedded.mux2 || !embedded.mux2.pins) return; + embedded.mux2.pins[16] = this.pins.selector[0].read(); + for(var i=0;i<8;i++){ + embedded.mux2.pins[i] = this.pins.channel0[i].read(); + embedded.mux2.pins[8+i] = this.pins.channel1[7-i].read(); + this.pins.output[7-i].write(embedded.mux2.pins[24-i]); + + }}else{ + if(!embedded.mux1 || !embedded.mux1.pins) return; + embedded.mux1.pins[16] = this.pins.selector[0].read(false); + for(var i=0;i<8;i++){ + embedded.mux1.pins[i] = this.pins.channel0[7-i].read(); + embedded.mux1.pins[8+i] = this.pins.channel1[i].read(); + this.pins.output[7-i].write(embedded.mux1.pins[24-i]); + + }} + + + + this.setChannel(this.pins.selector[0].read()==true?1:0); + } + constructor(x,y,width,height,second=false,de=false,points=[],editable=true){ + super((de?"de":"")+"multiplexer",x,y,width,height,points,editable); + this.de=de; + this.second=second; + this.channel=0; + if(second) + var theselector=new Pin(this.x+this.width-17, this.y); + else + var theselector=new Pin(this.x-BORDER_THICKNESS,blocks[0].pins.toMux[0].y,6,"","right") + if(!this.de){ + this.pins={ + selector: [ + theselector + ], + channel0:[ + ], + channel1: [ + ], + output:[ + ] + } + for(var i=0;i<8;i++){ + if(second){ + this.pins.channel1.push(new Pin(this.x+62+17*i,this.y+BORDER_THICKNESS+this.height,6,"","up")); + this.pins.output.push(new Pin(this.x+this.width,this.y+17+17*i,6,"","right")); + this.pins.channel0.push(new Pin(this.x-BORDER_THICKNESS,this.y+17+17*i,6,"","right")); + } else { + this.pins.channel1.push(new Pin(this.x+17+17*i,this.y)); + this.pins.channel0.push(new Pin(this.x+BORDER_THICKNESS+this.width,this.y+17+17*i,6,"","left")); + this.pins.output.push(new Pin(this.x+17+17*i,this.y+this.height)); + } + } + } else { + this.pins={ + selector: [ + new Pin(this.x-BORDER_THICKNESS,this.y+15,6,"","right"), + new Pin(this.x-BORDER_THICKNESS,this.y+30,6,"","right") + ], + input:[ + ], + channel0:[ + ], + channel1:[ + ], + channel2:[ + ] + } + for(var i=0;i<8;i++){ + this.pins.input.push(new Pin(this.x-BORDER_THICKNESS,this.y+67+17*i,6,"","right")); + this.pins.channel0.push(new Pin(this.x+this.width,this.y+17+17*i,6,"","right")); + this.pins.channel1.push(new Pin(this.x+17+17*i,this.y+this.height)); + this.pins.channel2.push(new Pin(this.x+220+17*i,this.y+this.height)); + } + } + this.makePointArray(); + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.font="25px vcr_osd_monoregular"; + ctx.baseline="middle"; + ctx.textAlign="center"; + ctx.fillText(" channel: "+this.channel,this.x+this.width/2,this.y+this.height/2); + } +} +class ALU extends Block { + update(){ + if(!embedded.alu) return; + for(var i=0;i<8;i++){ + if(i<4){ + embedded.alu.pins[19-i] = this.pins.opcode[i].read(); + this.pins.flags[i].write(embedded.alu.pins[29+i]); + } + embedded.alu.pins[i] = this.pins.operand1[i].read(); + embedded.alu.pins[i+8] = this.pins.operand2[i].read(); + this.pins.result[i].write(embedded.alu.pins[21+i]); + } + this.values[3].set(getNumber(this.pins.flags)); + this.values[1].set(getNumber(this.pins.operand1,false)); + this.values[0].set(getNumber(this.pins.operand2,false)); + this.values[2].set(getNumber(this.pins.result,false)); + var opcode=getNumber(this.pins.opcode); + if(opcode==6){ + this.correctAnswer = this.values[1].value << this.values[0].value; + } else { + this.correctAnswer = -1; + } + if(opcode>=8){ + this.operation = "move"; + } else { + this.operation = opcodes[opcode]; + } + + } + constructor(x,y,width,height,points=[],editable=true){ + points; + super("ALU",x,y,width,height,wires,editable); + this.wrong=false; + this.operation="add"; + this.values=[new Register("operand 1",8,0,this.x+w(20),this.y+h(80),50,"above",true,"black"), + new Register("operand 0",8,0,this.x+w(20),this.y+h(175),50,"above",true,"black"), + new Register("result",8,0,this.x+w(20),this.y+h(340),50,"above",true,"black"), + new Register("O N C Z flags",4,1,this.x+w(20),this.y+h(410),32,"above",false,"black")]; + //new Register("O . N . C . Z",4,0,this.x+w(125),this.y+h(360),30,"above",false,"black")]; + this.pins={ opcode: []/*,setFlags:[]*/, operand1:[], operand2:[],flags:[],result:[] } + for(var i=0;i<4;i++){ + this.pins.opcode.push(new Pin(this.x+17+17*i,this.y)); + this.pins.flags.push(new Pin(this.x+17+17*i,this.y+this.height)); + } + this.pins.flags[3].write(1); + for(var i=0;i<8;i++){ + this.pins.operand2.push(new Pin(this.x+this.width+BORDER_THICKNESS, this.y+17+17*i,6,"","left")); + this.pins.operand1.push(new Pin(this.x+this.width+BORDER_THICKNESS, this.y+167+17*i,6,"","left")); + this.pins.result.push(new Pin(this.x+this.width, this.y+317+17*i,6,"","right")); + } + + //this.pins.setFlags.push(new Pin(this.x+17*5+34,this.y)); + //this.pins.setFlags[0].write(1); + + this.makePointArray(); + + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.font="25px vcr_osd_monoregular"; + ctx.fillText("operation: "+this.operation,this.x+this.width/2, this.y+260); + ctx.font="15px vcr_osd_monoregular"; + //ctx.fillText("set flags: "+(this.pins.setFlags[0].read()==1?"yes":"no"),this.x+this.width/2, this.y+280); + ctx.fillRect(this.x+20,this.y+300,this.width-40,2); + this.values.forEach(v=>v.draw(0)); + } +} +class RegisterFile extends Block { + fileRegisters = []; + selected(){ + return{r1:this.fileRegisters[7-getNumber(this.pins.address1,false)], r2:this.fileRegisters[7-getNumber(this.pins.address2,false)]}; + } + update(){ + for(var i=0;i<8;i++){ + if(this.pins.read1Enable[0].read()) + this.pins.data1[7-i].write(this.selected().r1.binary[i]); + this.pins.data2[7-i].write(this.selected().r2.binary[i]); + } + } + realUpdate(){ + if(!!this.pins.write1Enable[0].read()) { + this.selected().r1.set(getNumber(this.pins.writeback,false),true); + } + } + constructor(x,y,fileRegisters=[],pins=[],editable=true){ + pins,editable; + super("registers",x,y,0,fileRegisters.length*h(85)+h(45),wires,false); + fileRegisters.forEach((r,i)=>{ + if(!r.bits){ + r.bits=8 + } + this.fileRegisters.push(new Register(r.name,r.bits,0,x+w(20),y+i*h(85)+h(65),40,"above",true,"black")); + }); + this.width=this.fileRegisters[0].width+w(80); + this.pins={ + clock:[ new Pin(this.x-BORDER_THICKNESS,this.y+17,6,"","right") ], + read1Enable: [ new Pin(this.x-BORDER_THICKNESS,this.y+17+35,6,"","right") ], + write1Enable: [new Pin(this.x-BORDER_THICKNESS,this.y+34+35,6,"","right") ], + address1: [ ], + address2: [ ], + data2:[ ], + data1:[ ], + writeback:[] + }; + for(var i=0;i<3;i++){ + this.pins.address2.push(new Pin(this.x-BORDER_THICKNESS,this.y+55+35+17+17*i,6,"","right")); + this.pins.address1.push(new Pin(this.x-BORDER_THICKNESS,this.y+125+35+17+17*i,6,"","right")); + } + for(var i=0;i<8;i++){ + this.pins.data2.push(new Pin(this.x,this.y+205+35+17+17*i,6,"","left")); + this.pins.data1.push(new Pin(this.x,this.y+365+35+17+17*i,6,"","left")); + this.pins.writeback.push(new Pin(this.x-BORDER_THICKNESS,this.y+530+35+17+17*i,6,"","right")); + } + super.makePointArray(); + } + draw(){ + super.draw(); + this.fileRegisters.forEach(r=>r.draw(1)); + } +} +class Clock extends Block { + reset(){ + this.state=0; + this.cycles=0; + } + update(){ + this.pins.clk[0].write(this.state); + } + constructor(x,y,width,height){ + super("clock",x,y,width,height,[],false); + this.pins={clk:[new Pin(this.x+this.width,this.y+17,6,"","right")]}; + super.makePointArray(); + this.cycles=0; + this.state=0; + } + pulse(t,w=false){ + this.state = 1; + if(!w) + this.cycles+=1; + setTimeout(function(){this.state=0}.bind(this),t/10); + } + draw(){ + super.draw(); + ctx.fillStyle="black"; + ctx.textAlign="center"; + ctx.textBaseline="middle"; + ctx.fillText(this.cycles,this.x+this.width/2,this.y+this.height/2+20); + } +} + +class Register { + pins=[]; + update(fuck=false){ + /*if(this.name=="memory address register" && fuck) return; + if(this.name=="m. data reg." && fuck) return;*/ + if(this.name=="flags"){ + this.set(getNumber(this.pins)); + if(document.getElementById("input").value.length>0) + this.value=this.value|0b10000; + else { + this.value=this.value & 0b01111; + } + this.set(this.value); + } + else if('writeEnable' in this) { + if(!!this.writeEnable.read()){ + this.set(getNumber(this.pins)); + } + } + if(this.name=="m. data reg."){ + var mAddr = registers[2].value; + if(this.writeEnable.read()){ + memory[mAddr] = this.value; + } + if(this.readEnable.read()||initialRun){ + initialRun=false; + this.set(memory[mAddr]); + } + } + } + static getBits(n,digits=8){ + if(n<0||n>=Math.pow(2,digits)||n%1!==0) { + //console.error(n+" is fucked, yo"); + } + return ("0000000000000000"+n.toString(2)).substr(-digits); + } + static getHex(n, digits=2){ + return "0x"+("0000"+n.toString(16).toUpperCase()).substr(-digits); + } + constructor(name, bits, value,x,y,scale,position="above",showValue=true,textColor="white",pins=false,numPins=8){ + this.name=name; + this.bits=bits; + this.x=w(x); + this.y=h(y); + this.width=w(scale * this.bits)*0.75; + this.height=h(scale); + this.above=position=="above"; + this.showValue=showValue; + this.textColor=textColor; + if(pins) + for(var i=bits-Math.min(bits,numPins);i{ pin.write(this.binary[i]) }); + + } + draw(border=0){ + if(this.name=="flags"){ + this.value=actualflags; + if(document.getElementById("input").value.length>0) + this.value=this.value|0b10000; + else { + this.value=this.value & 0b01111; + } + this.set(this.value); + } + + drawBorder(this,border); + ctx.fillStyle='white'; + ctx.fillRect(this.x,this.y,this.width,this.height); + var section_width = this.width/this.bits; + // draw text and separators + // labels + ctx.fillStyle = this.textColor; + ctx.font=this.height*0.4+"px vcr_osd_monoregular"; + var textY; + if(this.above){ + ctx.textBaseline = "bottom"; + textY = this.y-this.height*0.05; + } else { + ctx.textBaseline = "top"; + textY = this.y + this.height + this.height * 0.05; + ctx.fillStyle="rgba(24,27,32,0.5)"; + ctx.fillRect(this.x,this.y+this.height,this.width,21); + ctx.fillStyle="white"; + } + ctx.textAlign = "left"; + ctx.fillText(this.name,this.x,textY) + ctx.textAlign = "right"; + if(this.name=="instruction register"){ + ctx.fillText(humanInstruction(this.value),this.x+this.width,textY); + } else + this.showValue ? ctx.fillText(this.value+" | "+Register.getHex(this.value,(this.bits/4)),this.x+this.width,textY) : null; + + for(var i=0;i0) { + ctx.fillRect(this.x+section_width*i,this.y,2,this.height); + } + } + this.pins.forEach(pin=>pin.draw()); + if(this.readEnable){ + ctx.fillStyle="black"; + ctx.fillRect(this.x-6,this.y,6,this.height); + this.readEnable.draw(); + this.writeEnable.draw(); + } + } +} +var actualflags=0; +function pointInCircle(x, y, cx, cy, radius) { + var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy); + return distancesquared <= radius * radius; +} +class Pin { + constructor(x,y,radius=6,label=false,direction="down"){ + this.x=x; + this.y=y; + this.radius=radius; + this.state=0; + this.label=label; + this.direction=direction; + } + read(){ + return this.state; + } + write(state){ + this.state=state==true?1:0; + } + checkMouse(pos){ + return pointInCircle(pos.x,pos.y,this.x,this.y,this.radius); + } + draw(){ + ctx.fillStyle=this.read()==1?"red":"lightgray"; + ctx.beginPath(); + if(this.direction=="down"){ + ctx.arc(this.x,this.y,this.radius, 0*Math.PI,1*Math.PI,false); + } else if(this.direction=="right"){ + ctx.arc(this.x,this.y,this.radius,1.5*Math.PI,0.5*Math.PI,false); + } else if(this.direction=="left") { + ctx.arc(this.x,this.y,this.radius,0.5*Math.PI,1.5*Math.PI,false); + } else if (this.direction=="up") { + ctx.arc(this.x,this.y,this.radius, -1*Math.PI,0*Math.PI,false); + + } + ctx.fill(); + } +} + +class Wire { + update(){ + var state=!!this.input.read(); + if(this.killme>-1){ + if(registers[4].readEnable.read()){ + state = parseInt(registers[4].binary[7-this.killme]); + this.input.write(state); + } + } + this.state=state; + var hovered = this.input.hovered =1 || this.output.hovered == 1; + if(!this.behind) + this.color=state?"#F00":"#AAA"; + else if(this.behind==1) + this.color=state?"#A00":"#777"; + else + this.color=state?"#800":"#555"; + this.output.write(state); + } + draw(){ + ctx.beginPath(); + ctx.moveTo(this.input.x,this.input.y); + var n = this.output.number; + n = n - this.reindex; + var fuckyou = (this.output.number==0 && this.input.direction=="down")?2:0; + if (this.fuckoffanddie){ + ctx.lineTo(435,this.input.y); + ctx.lineTo(435,650); + ctx.lineTo(760,650); + ctx.lineTo(760,570); + ctx.lineTo(this.output.x,570); + } else { + if(!this.horizontal){ + if(!this.reverse){ + ctx.lineTo(this.input.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.45+n*7,0)); + ctx.lineTo(this.output.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.45+n*7,0.0)); + } else { + /* + ctx.lineTo(this.input.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + ctx.lineTo(this.output.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + */ + ctx.lineTo(this.input.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.56-n*6,0)); + ctx.lineTo(this.output.x,this.input.y+fuckyou+Math.max((this.output.y-this.input.y)*0.56-n*6,0.0)); + } + } else { + if(!this.reverse){ + //ctx.lineTo(this.input.x+fuckyou+Math.max((this.output.x-this.input.x)*0.45+n*7,0),this.input.y); + //ctx.lineTo(this.input.x+fuckyou+Math.max((this.output.x-this.input.x)*0.45+n*7,0.0),this.output.y); + if(!this.zigzag){ + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45+n*7),this.input.y); + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45+n*7),this.output.y); + } else{ + if(this.kms) + ctx.lineTo(this.input.x,this.output.y) + else + ctx.lineTo(this.output.x,this.input.y) + } + } else { + if(!this.zigzag){ + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45-n*7),this.input.y); + ctx.lineTo(this.input.x-this.flip*(Math.abs(this.output.x-this.input.x)*0.45-n*7),this.output.y); + } else{ + ctx.lineTo(this.input.x,this.output.y) + } + /* + ctx.lineTo(this.input.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + ctx.lineTo(this.output.x,this.input.y-15+((this.output.y-this.input.y)*(1-(0.15*n)))); + */ + + } + + }} + ctx.lineTo(this.output.x, this.output.y); + var redcolor,graycolor; + if(this.behind==0){ + redcolor="#F0F" + graycolor="#99F" + } else if(this.behind==1) { + redcolor="#A0A" + graycolor="#55F" + } else { + redcolor = "#808" + graycolor="#22F" + } + ctx.strokeStyle=this.hovered?(this.state?redcolor:graycolor):this.color + // cursed ctx.strokeStyle=this.color.substr(0,3)+(this.hovered?"F"/*(Math.min(parseInt(this.color[1],16)+3,15)).toString(16)*/:this.color[3]); + ctx.lineWidth=this.hovered?6:4; + ctx.stroke(); + } + constructor(input, output, label,behind=false, reverse=false,reindex=0,horizontal=false,flip=false,zigzag=false,kms=false,fuckoffanddie=false,killme=-1 ){ + this.input=input; + this.fuckoffanddie=fuckoffanddie; + this.output=output; + this.label=label; + this.reverse=reverse; + this.reindex=reindex; + this.behind=behind; + this.horizontal=horizontal; + this.flip=flip?-1:1; + this.zigzag=zigzag; + this.kms=kms; + this.killme=killme; + } +} +class Tooltip { + constructor(x,y,message,persist=false){ + this.x=x; + this.y=y; + this.message=message; + this.persist=persist; + } + draw(offset){ + ctx.fillStyle="rgba(0,0,0,0.65)"; + ctx.font="20px vcr_osd_monoregular"; + ctx.textBaseline="bottom"; + ctx.textAlign="left"; + var width=ctx.measureText(this.message).width+6; + ctx.fillRect(this.x<720?this.x:this.x-width,this.y-25-(26*offset),width,25); + ctx.fillStyle="white"; + ctx.fillText(this.message,this.x<720?(this.x+3):(this.x-width+3),this.y-(26*offset)); + } +} +function wireUp(){ + // clock + wires.push(new Wire(blocks[4].pins.clk[0],blocks[3].pins.clock[0],"clock")); + // instruction to decoder + //decoder to ALU + for(var i=0;i<5;i++){ + wires.push(new Wire(registers[0].pins[i],blocks[0].pins["instruction"][i],i<4?("opcode bit "+(3-i)):"addressing mode",false,false,2)); + if(i<4) + wires.push(new Wire(blocks[0].pins.toALU[i],blocks[2].points[i],i<4?"ALU opcode bit ":"set flags?")); + } + for(var i=0;i<8;i++){ + ///m data reg to mux + wires.push(new Wire(blocks[5].pins.channel1[7-i],registers[4].pins[7-i],"MDR (mux ch. 1), bit "+i,false,true,3,false,false,false,false,false,i)); + //wires.push(new Wire(blocks[5].pins.channel1[7-i],registers[4].pins[7-i],"memory data register, bit "+(7-i),false,true,5,false,false,false)); + + } + // ALU to flags + var flagtext=["overflow flag","negative flag","carry flag","zero flag"] + for(var i=0;i<4;i++){ + wires.push(new Wire(blocks[2].pins.flags[i],registers[1].pins[i+1],flagtext[i],false,true,2)); + } + //// INPUT OUTPUT STOPS BEHIND REVERSE REINDEX HORIZONTAL FLIP + // decoder to mux control + wires.push(new Wire(blocks[0].pins.toMux[0],blocks[1].pins.selector[0],"mux 0 selector")); + // instruction to multiplexer + for(var i=0;i<8;i++){ + // reg to mux and alu + wires.push(new Wire(blocks[3].pins.data1[i],blocks[2].pins.operand1[i],"first register data (operand 0), bit "+i,false,true,30,true)); + wires.push(new Wire(blocks[3].pins.data2[i],blocks[1].pins.channel0[i],"second register data (mux ch. 0), bit "+i,false,false,0,true)); + //mux to alu + wires.push(new Wire(blocks[1].pins.output[i],blocks[2].pins.operand2[7-i],/*"mux output, bit "+i*/"mux output (operand 1), bit "+[7-i],false,true,0,true,true,true)); + //alu to writeback + //wires.push(new Wire(blocks[2].pins.result[i],blocks[3].pins.writeback[i],"ALU result, bit "+i,false,false,-29,true,true)); + + wires.push(new Wire(blocks[5].pins.output[i],blocks[3].pins.writeback[i],"mux output (reg writeback), bit "+i,false,false,-29,true,true)); + wires.push(new Wire(blocks[2].pins.result[i],blocks[5].pins.channel0[i],"mux ch. 0 (ALU result), bit "+i,false,false,-29,true,true)); + + //alu to mar + wires.unshift(new Wire(blocks[2].pins.result[i],registers[2].pins[7-i],"MAR (ALU result), bit "+i,true,false,0,true,true,true)); + wires.unshift(new Wire(blocks[2].pins.result[i],registers[4].pins[7-i],"MDR (ALU result), bit "+i,true,false,0,true,true,true)); + + wires.unshift(new Wire(blocks[2].pins.result[i],registers[3].pins[7-i],"PC (ALU result), bit "+i,3,false,0,true,true,true)); + //inst to mux + wires.push(new Wire(registers[0].pins[15-i],blocks[1].pins.channel1[7-i],"immediate data (mux ch. 1), bit "+i,false,(7-i)<3,(7-i)<3?-2:8)); + } + // decoder to mux2 + wires.unshift(new Wire(blocks[0].pins.toMux[1],blocks[5].pins.selector[0],"mux 1 selector",true,false,0,false,false,true,true,true)); + + // decoder to reg rwenable + wires.unshift(new Wire(blocks[0].pins.registerReadEnable[0],blocks[3].pins.read1Enable[0],"first register read enable",true,false,-34,true,true)); + wires.unshift(new Wire(blocks[0].pins.registerWriteEnable[0],blocks[3].pins.write1Enable[0],"first register write enable",true,false,-35,true,true)); + // decoder to mar rwenable + wires.unshift(new Wire(blocks[0].pins.memAddrReadEnable[0],registers[2].readEnable,"MAR read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.memAddrWriteEnable[0],registers[2].writeEnable,"MAR write enable",3, false,0,true,true,true,true)); + //pc rwenable + wires.unshift(new Wire(blocks[0].pins.pcReadEnable[0],registers[3].readEnable,"PC read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.pcWriteEnable[0],registers[3].writeEnable,"PC write enable",3, false,0,true,true,true,true)); + // m d r rwenable + wires.unshift(new Wire(blocks[0].pins.memDataReadEnable[0],registers[4].readEnable,"MDR read enable",3, false,0,true,true,true,true)); + wires.unshift(new Wire(blocks[0].pins.memDataWriteEnable[0],registers[4].writeEnable,"MDR write enable",3, false,0,true,true,true,true)); + // instruction to register address + for(var i=0;i<3;i++){ + wires.unshift(new Wire(registers[0].pins[7-i],blocks[3].pins.address1[i],"first register address, bit "+i,3,false,3,true,true,true,true)); + wires.unshift(new Wire(registers[0].pins[10-i],blocks[3].pins.address2[i],"second register address, bit "+i,3,false,3,true,true,true,true)); + } + +} +url=""; +function setup(){ + images["pencil"]=new Image(); + images["pencil"].src='img/pencil.png'; + images["question"]=new Image(); + images["question"].src='img/question.png'; + + ctx.canvas.width = 1440//window.innerWidth*0.75; + ctx.canvas.height = 976 //window.innerHeight; + registers.push(new Register("instruction register",16, 0, w(13), h(36), 60,"above",true,"white","below",16)); + registers.push(new Register("flags",5,0,w(13),h(885),45,"below",false,"white","above")); + registers.push(new Register("memory address register", 16, 0, w(250), h(885), 45, "below",true,"white","above")) + registers.push(new Register("program counter", 16, 0, w(880), h(885), 45, "below",true,"white","above")) + registers.push(new Register("m. data reg.",8,0,880+(registers[registers.length-1].width/2),803,45,"below",true,"white","above")); + + //goddammit + for(var i=2;i{ + var rect = canvas.getBoundingClientRect(); + tooltips = tooltips.filter(t=>t.persist==true); + scaleX=canvas.width/rect.width; + scaleY=canvas.height/rect.height; + isOverOne=false; + this.wires.forEach(wire=>{ + wire.hovered=false; + var pos = {x:(e.clientX-rect.left)*scaleX, y:(e.clientY-rect.top)*scaleY}; + if(wire.input.checkMouse(pos)||wire.output.checkMouse(pos)){ + wire.hovered=true; + tooltips.push(new Tooltip(pos.x,pos.y,wire.label)); + isOverOne=2; + } + }); + blocks.forEach(block=>{ if(block.checkMouse({x:(e.clientX-rect.left)*scaleX, y:(e.clientY-rect.top)*scaleY})){isOverOne=true;url=block.url;} }); + if(isOverOne==1){ + canvas.style.cursor="pointer"; + } else if(isOverOne==2){ + canvas.style.cursor="help"; + } else { + canvas.style.cursor="default"; + url=""; + } + }); + document.addEventListener('click',e=>{ + if(url){ + window.location.href=url; + console.log("no"); + } else { + console.log("no"); + } + }); + requestAnimationFrame(drawCanvas); +} +var wait=false; +function clockTick(t=1000,oneTime=false){ + blocks[4].pulse(1000,wait); + if(wait){ + registers[2].update(); + registers[4].update(); + wait=false; + } else { + if(blocks[2].correctAnswer>-1){ + if(blocks[2].correctAnswer!=blocks[2].values[2].value){ + tick=false; + blocks[2].done = false; + blocks[2].editable = true; + blocks[2].wrong = true; + return; + } + } + if(!tick && !oneTime) return; + registers.forEach(r=>r.update(true)); + actualflags=getNumber(blocks[2].pins.flags); + if(blocks[4].cycles>1) + blocks[3].realUpdate(); + drawMemory(); + nextInstruction(); + } + if(tick){ + setTimeout(clockTick,t,t); + } +} +var tick=false; +const zeroPad = (num, places) => String(num).padStart(places, '0') +var memPage=0; +function nextMemPage(){ + memPage++; + if(memPage>255) memPage=0; + document.getElementById('label_mempage').innerHTML=zeroPad(memPage,3); + drawMemory(); +} +function prevMemPage(){ + memPage--; + if(memPage<0) memPage=255; + document.getElementById('label_mempage').innerHTML=zeroPad(memPage,3); + drawMemory(); +} +function drawMemory(){ + var memTable = document.getElementById('memory').children[0]; + for(var i=1;i<=16;i++){ + var row = memTable.children[i]; + for(var j=1;j<=16;j++){ + var cell = row.children[j]; + var address = ((memPage)<<8)+(i-1)*16+(j-1); + var val = memory[address]; + cell.innerHTML = zeroPad(val,3); + if(val>0) cell.classList.add('nonzero'); else cell.classList.remove('nonzero'); + } + } +} +initialRun=false; +function compile(){ + resetAll(); + try { + ass = new assembler(); + var bytecode = ass.assemble(document.getElementById('program').value); + console.log(ass.labelAddresses); + for(var i=0;ir.update()); +} +var branchyes = false; +var prevInstruction=-1; +function nextInstruction(){ + var pc = registers[3]; + if(!nosetpc){ + if(prevInstruction!=-1) { + pc.set(pc.value+2,false); + } + } else nosetpc=false; + var flag_reg = registers[1]; + var ir = registers[0]; + var mar = registers[2]; + var mdr = registers[4]; + ir.set((memory[pc.value]<<8)+memory[pc.value+1]); + var instruction = ir.value; + var opcode = instruction >> 12; + if(opcode==15){ + tick=false; + runLabel.innerHTML='Run (finished)'; + } + if(opcode==0b1011) return; + prevInstruction=instruction; + // glue code + wait=opcode==0b1001; + var mode = (instruction>>11)&0b00001; + var f = (registers[0].value >> 8)&0b00000111; + //input + var r2 = (instruction & 0x00FF)>>5; + if((opcode!=11 && opcode<=12)&&r2==0&&mode==0){ + var inp = document.getElementById('input'); + if(inp.value.length>0){ + var setTo; + if(document.getElementById('ascii').checked){ + setTo = inp.value[0]; + setTo = setTo.charCodeAt(0); + inp.value = inp.value.substr(1); + } else { + setTo = parseInt(inp.value.split(" ")[0]); + if(inp.value.indexOf(" ")==-1) inp.value=""; else + inp.value = inp.value.substring(inp.value.indexOf(" ")+1); + } + blocks[3].fileRegisters[7].set(setTo,false); + flag_reg.set(flag_reg.value+(1<<4)); + } else { + blocks[3].fileRegisters[7].set(0,false); + } + } + // memory stores + if(opcode==10){ + registers[4].set(blocks[3].fileRegisters[7-f].value); + } + // conditional branching + if(opcode==12||opcode==13){ + if((actualflags+(registers[1].binary[0]=='1'?16:0)) & (1 << f)){ + branchyes=(opcode==12); + nosetpc=(opcode==12); + } else { + branchyes=(opcode==13); + nosetpc=(opcode==13); + } + } + var mode = (ir.value & 0b0000100000000000)>>11; + if(opcode==0b1110) { //jmp: don't increment pc + nosetpc=true; + } + /* + if(opcode==1111 && mode==0){ // setipg + ir.set((171<<8)+((pc.value+4)>>8)); + } + */ + +} +var nosetpc=false; +function resetAll(){ + initialRun=true; + prevInstruction=-1; + branchyes=false; + nosetpc=false; + document.getElementById("output").value=""; + memory = new Array(65536).fill(0); + blocks.forEach(b=>b.reset()); + registers.forEach(r=>r.set(0,false)); + blocks[3].fileRegisters.forEach(r=>r.set(0,false)); +} +function drawCanvas(){ + ctx.clearRect(0, 0, canvas.width, canvas.height); + if(window.debugall) {;} else { + wires.forEach(w=>w.update()); + blocks.forEach(b=>b.update()); + for(var i=0;i<8;i++){ + registers[4].pins[i].write(registers[4].binary[i]); + } + } + wires.forEach(w=>w.draw()); + blocks.forEach(b=>b.draw()); + registers.forEach(r=>r.draw(1)); + blocks.forEach(b=>b.drawOverlay()); + const flags = new Set(); + tooltips.filter(tt=>{if(flags.has(tt.message)){return false};flags.add(tt.message);return true;}).forEach((t,i)=>t.draw(i)); + requestAnimationFrame(drawCanvas); + +}; diff --git a/js/opcodes.js b/js/opcodes.js new file mode 100755 index 0000000..a5ad046 --- /dev/null +++ b/js/opcodes.js @@ -0,0 +1,152 @@ +match= { + reg: "(io|sp|ipage|dpage|stackptr|gp[0-3])", + imm8: "~?#(0b[0-1]{1,8}|(0x)?[0-9]{1,3})", + label: "[A-z][A-z0-9]*", + flags: "(INPUT|OVERFLOW|NEGATIVE|CARRY|ZERO)" + } +instructions = { + match: match, + registers:[ + "io", + "stackptr", + "dpage", + "ipage", + "gp0", + "gp1", + "gp2", + "gp3" + ], + flags:[ + "INPUT", + "OVERFLOW", + "NEGATIVE", + "CARRY", + "ZERO" + ].reverse(), + arg_patterns:[ + [ + { pattern: [ match.reg, match.reg ], mode: 0 }, + { pattern: [ match.reg, match.imm8 ], mode: 1 }, + ], + [ + { pattern: [ match.reg ], mode: 0 } + ], + [ + { pattern: [ match.reg ], mode: 1 } + + ], + [ + { pattern: [ match.flags, match.reg ], mode: 0 }, + { pattern: [ match.flags, match.imm8 ], mode: 1 }, + ], + [ + { pattern: [ match.reg ], mode: 0 }, + { pattern: [ match.imm8 ], mode: 1 }, + ], + [ + { pattern: [ ], mode: 0 } + ], + [ + { pattern: [ ], mode: 1 } + ] + ], + opcodes:[ + { + opcode: 0b0000, + mnemonic:"add", + patterns: 0, + description: "Adds the immediate data, or the contents of the register given as the second operand to the register given as first operand." + }, + { + opcode: 0b0001, + mnemonic:"sub", + patterns: 0, + description: "Subtracts the immediate data, or the contents of the register given as the third operand to the register given as the first operand." + }, + { + opcode:0b0010, + mnemonic: "adc", + patterns: 0, + description: "Adds the two operands plus the carry flag, stores in the first operand register." + }, + { + opcode:0b0011, + mnemonic:"subb", + patterns:0, + description: "Subtracts the second operand plus the carry flag from the first operand." + }, + { + opcode:0b0100, + mnemonic:"nand", + patterns:0, + description:"Performs logical NAND on the two operands; stores in first operand register." + }, + { + opcode:0b0101, + mnemonic: "xor", + patterns:0, + description:"Performs logical XOR on the two operands; stores in first operand register." + }, + { + opcode:0b0110, + mnemonic:"sll", + patterns:0, + description:"Shifts bits in the first operand register left by the amount specified in the second operand." + }, + { + opcode:0b0111, + mnemonic:"srl", + patterns:0, + description:"Shifts bits in the first operand register right by the amount specified in the second operand." + }, + { + opcode:0b1000, + mnemonic:"mov", + patterns:0, + description: "Copies the register or data in the second operand into the first operand register." + }, + { + opcode:0b1001, + mnemonic:"ldb", + patterns:0, + description:"Loads the byte into the first operand register at the address specified in the second operand." + }, + { + opcode:0b1010, + mnemonic:"stb", + patterns:0, + description:"Stores the contents of the first operand register into the address specified in the second operand." + }, + { + opcode:0b1011, + mnemonic:"nop", + patterns:5, + description:"performs no operation." + }, + { + opcode:0b1100, + mnemonic:"bflag", + patterns:0, + description: "Branches to the specified memory address if the specified flag bit is set." + }, + { + opcode:0b1101, + mnemonic:"bnoflag", + patterns:0, + description: "Branches to the specified memory address if the specified flag bit is NOT set." + }, + + { + opcode:0b1110, + mnemonic:"jmp", + patterns:4, + description:"Branches unconditionally to the specified memory address." + }, + { + opcode:0b1111, + mnemonic:"hlt", + patterns:5, + description:"Terminates execution." + } + ] +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/simulator/asm.html b/simulator/asm.html new file mode 100755 index 0000000..127b167 --- /dev/null +++ b/simulator/asm.html @@ -0,0 +1,5 @@ + + + diff --git a/simulator/assembler.js b/simulator/assembler.js new file mode 100755 index 0000000..5f5c97e --- /dev/null +++ b/simulator/assembler.js @@ -0,0 +1,283 @@ +Array.prototype.findIndexes=function(where) { + return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []); +} +class assembler { + labels = []; + labelAddresses = []; + address = 0; + curLine = 0; + + offset = 0; // account for any instructions the assembler needs to add + upper8(address){ + return address>>8; + } + lower8(address){ + return address&0x00FF; + } + intByte(n){ + n=n.replace("#",""); + var invert = false; + if(n[0]=="~") { invert=true; n=n.slice(1)}; + var b = 0; + if(n.match(/^0b/)){ + b = parseInt(n.slice(2),2); + } else { + b = parseInt(n); + } + if(isNaN(b)) { + throw 'Invalid number'; + } else if(b>255 || b <-128){ + throw 'Number will not fit in a byte!'; + } + if(b<0){ + // apply 2's complement to negative value + var r= ~Math.abs(b)+1; + } else { + var r= b; + }; + return invert ? ((~r>>>0)&0xFF) : r; + } + encodeInstruction(line){ + var bytes = [0,0]; + var instruction = instructions.opcodes.find(oc=>oc.mnemonic==line[0].toLowerCase()); + if(instruction.mnemonic=="bflag") { + flag = instruction.flags.indexOf(line[1]); + if(flag>=0){ + // evil stupid dumb + line[1] = line[1].replace(instruction.flags[flag],instruction.registers[flag]); + + } else throw 'Invalid flag.'; + } + if(!instruction) throw 'Unknown opcode'; + var patterns = instructions.arg_patterns[instruction.patterns]; + var mode = -1; + if(patterns[0].pattern.length!=line.length-1){ + throw 'Wrong number of operands'; + } else if(patterns.length==1){ + mode = patterns[0].mode; + } else { + patterns.forEach(pattern=>{ + var fit=0; + for(var i=0;i{ + var l; + var mnemonic = instruction[0].toLowerCase(); + this.curLine = i; + var offset=0; + // dealing with pseudo instructions + if(mnemonic==".data"){ + return; + } else if(mnemonic=="hlt"){ // halt: jump to same instruction + if(this.upper8(instAddr)!=instPage){ + instPage=this.upper8(instAddr); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + offset=2; + } + bytecode = bytecode.concat(this.encodeInstruction(["jmp","#"+this.lower8(instAddr+offset)])); + } else if(mnemonic=="nop"){ // nop: jump to next instruction + if(this.upper8(instAddr+2)!=instPage){ + offset=2; + instPage=this.upper8(instAddr); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + } + bytecode = bytecode.concat(this.encodeInstruction(["jmp","#"+this.lower8(instAddr+2+offset)])); + // now process labels + } else if(mnemonic=="jsr"||mnemonic=="jmp"){ + l = this.labelAddresses.find(la=>instruction[1].includes(la.label)); + + if(l){ // we must replace + instruction[1] = instruction[1].replace(l.label, "#"+this.lower8(l.address)); + if(this.upper8(l.address)!=instPage){ + instPage=this.upper8(l.address); + bytecode=bytecode.concat(this.encodeInstruction(["mov","ibank","#"+instPage])); + offset=2; + } + } + bytecode=bytecode.concat(this.encodeInstruction(instruction)); + } else if(mnemonic=="stb"||mnemonic=="ldb"){ + l = this.labelAddresses.find(la=>instruction[2].includes(la.label)); + if(l){ // we must replace + instruction[2] = instruction[2].replace(l.label, "#"+this.lower8(l.address)); + if(this.upper8(l.address)!=dataPage){ + dataPage=this.upper8(l.address); + bytecode=bytecode.concat(this.encodeInstruction(["mov","dbank","#"+dataPage])); + offset=2; + } + } + bytecode=bytecode.concat(this.encodeInstruction(instruction)); + } else bytecode=bytecode.concat(this.encodeInstruction(instruction)); + l = this.labels.findIndex(la=>la.line==i); + if(l>-1){ + this.labelAddresses.push({label: this.labels[i].label, address: instAddr}); + } + instAddr += 2 + offset; + }); + return bytecode; + } + assemble(code) { + // try + var tokens = this.tokenize(code); + var withPseudo = this.processAndOr(tokens); + var delabeled = this.processLabels(withPseudo); + var data = this.processData(delabeled); + var bytecode = this.processInstructions(delabeled); + var pad = data.bytes.length>0?Array(data.start - bytecode.length).fill(0):[]; + console.log({tokens,withPseudo,delabeled,data,bytecode}) + + return bytecode.concat(pad).concat(data.bytes); + // catch + } + processAndOr(tokenLines) { + var processed=[]; + tokenLines.forEach(line=>{ + if(line.length<2){ + processed.push(line) + } + else if(line[0].toLowerCase()=="and") { + line[0] = "nand"; + processed.push(line); // NAND a, b + processed.push(['nand',line[1],line[1]]); // NAND a, a + } else if(line[1].toLowerCase()=="and") { + line[1] = "nand"; + processed.push(line); // ibid + processed.push(['nand',line[2],line[2]]); + } else if(line[0].toLowerCase()=="or") { + processed.push(['nand',line[1],line[1]]); // NAND a, a + if(line[2].toLowerCase().match(instructions.match.reg)){ + processed.push(['nand',line[2],line[2]]); // NAND b, b + processed.push(['nand',line[1],line[2]]); // NAND a, b + processed.push(['nand',line[2],line[2]]); // NAND b, b + } else if(line[2].toLowerCase().match(instructions.match.imm8)) { + //int imm8 = intByte(this.intByte(line[2]); // NAND b, b + processed.push(['nand',line[1],"~"+line[2]]);//line[2]]); // NAND a, b + } else if(line[2].toLowerCase().match(instructions.match.label)) { + processed.push(['nand',line[1],"~"+line[2]]);// NAND a, ~b + } else throw("error converting and"); + } else if(line[1].toLowerCase()=="or"){ + processed.push(['nand',line[2],line[2]]); // NAND a, a + if(line[3].toLowerCase().match(/(ip|dp|sp|r[0-3])/)){ + processed.push(['nand',line[3],line[3]]); // NAND b, b + processed.push(['nand',line[2],line[3]]); // NAND a, b + processed.push(['nand',line[3],line[3]]); // NAND b, b + } else if(line[3].toLowerCase().match(instructions.match.imm8)) { + imm8 = ~this.intByte(line[3]); // NAND b, b + processed.push(['nand',line[2],line[3]]); // NAND a, b + } else if(line[3].toLowerCase().match(instructions.match.label)) { + processed.push(['nand',line[2],"~"+line[3]]);// NAND a, ~b + } else throw("error converting and"); + + } else { + processed.push(line); + } + }); + return processed; + } + processLabels(tokenLines) { + var processed = []; + // first pass: extract labels + for(var i=0;i 1 && curLine[1]!=''){ + // first token was label; next token will be opcode or data + processed.push(curLine.slice(1)); + } + this.labels.push({ label: curLine[0].split(/:.*/)[0], line: lineNum }); + //processed.push(curLine.slice(1)); + } else processed.push(curLine); + } + return processed; + } + processData(tokenLines) { + // we want to find out where the end of the instructions will be + // however, we don't know how many the assembler will insert to deal with pages + // i can't be bothered doing this properly so let's just add an extra two bytes + // for every instruction that accesses memory + // get number of instructions that deal with memory + var dataInstructions = tokenLines.findIndexes(line=>line[0].toLowerCase().match('^.data$')); + var numMem = tokenLines.filter(line => line[0].toLowerCase().match(/(ldb|stb|jsr|jmp|bflag)/)).length; + var start = ( (tokenLines.length - dataInstructions.length) + numMem )* 2; + var curAddr = 0; + var bytes = []; + dataInstructions.forEach(i=>{ + this.curLine = i; + var thisLabel = this.labels.find(l => l.line== i); + if(thisLabel){ + this.labelAddresses.push({ label: thisLabel.label, address: curAddr+start }); + } + tokenLines[i].slice(1).forEach(token=>{ + // if string + if(token.match(/^".*"$/)) { + token.slice(1).slice(0,-1).replace(/[^\x00-\x7F]/g, "").split('').forEach(character=>{ + bytes.push(character.charCodeAt(0)); + curAddr += 1; + }); + } else { + bytes.push(this.intByte(token)); + curAddr += 1; + } + }); + + }) + + return { start, bytes }; + + } + tokenize(code) { + var tokenLines = []; + // split code into lines - strings enclosed in quotes can span multiple lines + // nb this breaks for escaped quotes but who cares + var lines = code.split(/(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*)\r?\n(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/); + lines.forEach(line=>{ + // split on wgutespace or comma, unless quoted + var tokens = line.split(/(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*)[ ,]+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/); + // remove comments preceded by ; + var hitSemicolon=false + var tokenLine=[]; + tokens.forEach(token=>{ + //console.log(token); + if(token[0]==";"||hitSemicolon){ + hitSemicolon=true; + } else { + tokenLine.push(token); + //console.log(tokenLine); + } + }) + tokenLines.push(tokenLine); + }) + return tokenLines; + } +} diff --git a/simulator/opcodes.js b/simulator/opcodes.js new file mode 100755 index 0000000..13b76e4 --- /dev/null +++ b/simulator/opcodes.js @@ -0,0 +1,163 @@ +match= { + reg: "(ibank|dbank|sp|r[0-3])", + imm8: "~?#(0b[0-1]{1,8}|(0x)?[0-9]{1,3})", + label: "[A-z][A-z0-9]*", + flags: "(INPUT|OVERFLOW|NEGATIVE|CARRY|ZERO)" + } +instructions = { + match: match, + + registers:[ + "ibank", + "dbank", + "sp", + "r0", + "r1", + "r2", + "r3" + ], + flags:[ + "INPUT", + "OVERFLOW", + "NEGATIVE", + "CARRY", + "ZERO" + ], + arg_patterns:[ + [ + { pattern: [ match.reg, match.reg ], mode: 0 }, + { pattern: [ match.reg, match.imm8 ], mode: 1 }, + ], + [ + { pattern: [ match.reg ], mode: 0 } + ], + [ + { pattern: [ match.reg ], mode: 1 } + + ], + [ + { pattern: [ match.flags, match.reg ], mode: 0 }, + { pattern: [ match.flags, match.imm8 ], mode: 1 }, + ], + [ + { pattern: [ match.reg ], mode: 0 }, + { pattern: [ match.imm8 ], mode: 1 }, + ], + [ + { pattern: [ ], mode: 0 } + ], + [ + { pattern: [ ], mode: 1 } + ] + ], + opcodes:[ + { + opcode: 0b0000, + mnemonic:"add", + patterns: 0, + description: "Adds the immediate data, or the contents of the register given as the second operand to the register given as first operand." + }, + { + opcode: 0b0001, + mnemonic:"sub", + patterns: 0, + description: "Subtracts the immediate data, or the contents of the register given as the third operand to the register given as the first operand." + }, + { + opcode:0b0010, + mnemonic: "adc", + patterns: 0, + description: "Adds the two operands plus the carry flag, stores in the first operand register." + }, + { + opcode:0b0011, + mnemonic:"subb", + patterns:0, + description: "Subtracts the second operand plus the carry flag from the first operand." + }, + { + opcode:0b0100, + mnemonic:"nand", + patterns:0, + description:"Performs logical NAND on the two operands; stores in first operand register." + }, + { + opcode:0b0101, + mnemonic: "xor", + patterns:0, + description:"Performs logical XOR on the two operands; stores in first operand register." + }, + { + opcode:0b0110, + mnemonic:"sll", + patterns:0, + description:"Shifts bits in the first operand register left by the amount specified in the second operand." + }, + { + opcode:0b0111, + mnemonic:"srl", + patterns:0, + description:"Shifts bits in the first operand register right by the amount specified in the second operand." + }, + { + opcode:0b1000, + mnemonic:"mov", + patterns:0, + description: "Copies the register or data in the second operand into the first operand register." + }, + { + opcode:0b1001, + mnemonic:"ldb", + patterns:0, + description:"Loads the byte into the first operand register at the address specified in the second operand." + }, + { + opcode:0b1010, + mnemonic:"stb", + patterns:0, + description:"Stores the contents of the first operand register into the address specified in the second operand." + }, + { + opcode:0b1011, + mnemonic:"push", + patterns:1, + description:"Pushes the contents of the specified register onto the stack." + }, + { + opcode:0b1011, + mnemonic:"pop", + patterns:2, + description:"Pops the first item of the stack into the specified register" + }, + { + opcode:0b1100, + mnemonic:"bflag", + patterns:3, + description: "Branches to the specified memory address if the specified flag bit is set." + }, + { + opcode:0b1101, + mnemonic:"jmp", + patterns:4, + description:"Branches unconditionally to the specified memory address." + }, + { + opcode:0b1110, + "menmonic":"jsr", + patterns:4, + description:"Branches unconditionally to the specified memory address and push the lower 8 bits of (program counter + 2) onto the stack." + }, + { + opcode:0b1111, + mnemonic:"setipg", + patterns:5, + description:"Sets the instruction page register to the upper 8 bits of (program counter + 4)." + }, + { + opcode:0b1111, + mnemonic:"ret", + patterns:6, + description:"Pulls the lower 8 bits of the return address from the stack and jumps to it." + } + ] +} diff --git a/simulator/opcodes.json b/simulator/opcodes.json new file mode 100755 index 0000000..97c7224 --- /dev/null +++ b/simulator/opcodes.json @@ -0,0 +1,134 @@ +{ + "arg_patterns":[ + [ + "(ip|dp|sp|r[0-3]),? (ip|dp|sp|r[0-3])", + "(ip|dp|sp|r[0-3]),? #(0b[0-1]{1,8}|(0x)?[0-9]{1,3})", + "(ip|dp|sp|r[0-3]),? [A-z][A-z0-9]*" + ], + [ + "(ip|dp|sp|r[0-3])" + ], + [ + "#(0b[0-1]{1,3}|(0x)?[0-9]{1,3})", + "(INPUT|OVERFLOW|NEGATIVE|CARRY|ZERO)" + ] + [ + "(ip|dp|sp|r[0-3])", + "#(0b[0-1]{1,8}|(0x)?[0-9]{1,3})", + "[A-z][A-z0-9]*" + ], + [ + "" + ] + ], + "opcodes":[ + { + "opcode": 0b0000, + "mnemonic":"add", + "patterns": 0, + "description": "Adds the immediate data, or the contents of the register given as the second operand to the register given as first operand." + }, + { + "opcode": 0b0001, + "mnemonic":"sub", + "patterns": 0, + "description": "Subtracts the immediate data, or the contents of the register given as the third operand to the register given as the first operand." + }, + { + "opcode":0b0010, + "mnemonic": "adc", + "patterns": 0, + "description": "Adds the two operands plus the carry flag, stores in the first operand register." + }, + { + "opcode":0b0011, + "mnemonic":"subb", + "patterns":0, + "description": "Subtracts the second operand plus the carry flag from the first operand." + }, + { + "opcode":0b0100, + "mnemonic":"nand", + "patterns":0, + "description":"Performs logical NAND on the two operands; stores in first operand register." + }, + { + "opcode":0b0101, + "mnemonic": "xor", + "patterns":0, + "description":"Performs logical XOR on the two operands; stores in first operand register." + }, + { + "opcode":0b0110, + "mnemonic":"sll", + "patterns":0, + "description":"Shifts bits in the first operand register left by the amount specified in the second operand." + }, + { + "opcode":0b0111, + "mnemonic":"srl", + "patterns":0, + "description":"Shifts bits in the first operand register right by the amount specified in the second operand." + }, + { + "opcode":0b1000, + "mnemonic":"mov", + "patterns":0, + "description": "Copies the register or data in the second operand into the first operand register." + }, + { + "opcode":0b1001, + "mnemonic":"ldb", + "patterns":0, + "description":"Loads the byte into the first operand register at the address specified in the second operand." + }, + { + "opcode":0b1010, + "mnemonic":"stb", + "patterns":0, + "description":"Stores the contents of the first operand register into the address specified in the second operand." + }, + { + "opcode":0b1011, + "mnemonic":"push", + "patterns":1, + "description":"Pushes the contents of the specified register onto the stack." + }, + { + "opcode":0b1011, + "mnemonic":"pop", + "patterns":1, + "description":"Pops the first item of the stack into the specified register" + }, + { + "opcode":0b1100, + "mnemonic":"bflag", + "patterns":2, + "description": "Branches to the specified memory address if the specified flag bit is set." + }, + { + "opcode":0b1101, + "mnemonic":"jmp", + "patterns":3, + "description":"Branches unconditionally to the specified memory address." + }, + { + "opcode":0b1110, + "menmonic":"jsr", + "patterns":3, + "description":"Branches unconditionally to the specified memory address and push the lower 8 bits of (program counter + 2) onto the stack." + }, + { + "opcode":0b1111, + "mnemonic":"setipg", + "patterns":4, + "description":"Sets the instruction page register to the upper 8 bits of (program counter + 4)." + }, + { + "opcode":0b1111, + "mnemonic":"ret", + "patterns":4, + "description":"Pulls the lower 8 bits of the return address from the stack and jumps to it." + + +} diff --git a/simulator/sim.js b/simulator/sim.js new file mode 100755 index 0000000..d7d3ce8 --- /dev/null +++ b/simulator/sim.js @@ -0,0 +1,188 @@ +class eduProc { + reset() { + // initialise instruction and data memory + this.memory = new Array(65536).fill(0); + + this.state = 0; // 0=fetch, 1=decode, 2=execute; + // store the registers as private members + this.programCounter = 0x0000; // 16 bits + this.instructionRegister = 0x0000; // 16 bits + this.memoryAddressRegister = 0x0000; // 16 bits + //memoryDataRegister = 0x00; // 8 bits + this.flags = 0x0; // 4 bits + this.flagNames = { input: 4, overflow: 3, negative: 2, carry: 1, zero: 0 } + this.registers = [0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00]; //8 bits + // human friendly names for the four special purpose registers + this.regNames = { instruction_page: 0, data_page: 1, stack_pointer: 2, serial_io: 3 }; + this.stack_page = 0xFF; + } + + freeze() { + // todo + } + + constructor() { + reset(); + } + // handle flags + setFlag(flagName, onoff) { + // get bit position of flag + const bitPosition = this.flagNames[flagName]; + + // ensure we have a boolean + onoff = onoff ? 1 : 0; + // clear the bit in the bitmask, so we can replace it with the provided value + const clearMask = ~(1<=0 ? result % 255 : 255+result+1; // overflow if positive, underflow if negative + // write result and flags + if(operand!=6) { // don't write result of cmp + this.registers[dest] = result; + } + if(opcode==7) { // move instruction: don't affect flags + return; + } + this.setFlag("zero",result==0); + this.setFlag("negative",getBit(result,7)); + if(opcode==2||opcode==3) { // logic instruction: only zero and negative flag are touched + return; + } + this.setFlag("carry", result>255||result<0); + op1_sign = this.getBit(operand_1,7); + op2_sign = this.getBit(operand_2,7); + result_sign = this.getBit(result,7); + this.setFlag("overflow",~(op1_sign^op2_sign) && (op1_sign^result_sign)); // sets flag if two inputs have same sign but output has different + } + + // load a new program into memory and reset the processor + loadProgram(bytecode) { + reset(); + this.memory.splice(0,bytecode.length, ...bytecode); + freeze(); + } + // FETCH STAGE: load instruction from memory and increment PC + fetch(stage=0) { + if (stage=0) + this.instructionRegister = this.memory[this.programCounter]<<8; + else + this.instructionRegister += this.memory[this.programCounter]; + this.programCounter = (this.programCounter+1)%65535; + } + execute() { + instruction = this.instructionRegister; + opcode = instruction>>12; + addressingMode = this.getBit(instruction, 4); // 0 = from reg, 1 = immediate + operand_1 = (instruction>>8)&0x7 // extract operand 1 + operand_2 = instruction&0xFF // extract second byte + if(!addressingMode) { // not immediate data - load from register instead + operand_2 = this.registers[operand_2>>5]; + } + if(opcode<8) { // this means ALU INSTRUCTION + this.ALU(opcode,operand_1,operand_2); + } else { + data_address = this.regNames["data_page"]<<8+operand_2; + branch_address = this.regNames["instruction_page"]<<8+operand_2; + stack_pointer = this.stack_page+this.regNames["stack_pointer"]; + + switch(opcode){ + case 8: // load + this.registers[operand_1] = this.memory[data_address]; + break; + case 9: //store + this.memory[data_address] = this.registers[operand_1]; + break; + case 10: // stack + if(!addressingMode){ // push + this.memory[stack_pointer] = this.registers[operand_1]; + this.regNames["stack_pointer"] -= 1; + if(this.regNames["stack_pointer"]<0) + this.regNames["stack_pointer"]=255; + } else { // pop + this.registers[operand_1]=this.memory[stack_pointer]; + this.regNames["stack_pointer"]=(this.regNames["stack_pointer"]+1)%256 + } + break; + case 11: // beqz + if(this.getFlag("zero")) + this.programCounter = branch_address; + break; + case 12: // bneg + if(this.getFlag("negative")) + this.programCounter = branch_address; + break; + case 13: // binput + if(this.getFlag("input")) + this.programCounter = branch_address; + break; + case 14: + if(this.getFlag("overflow")) + this.programCounter = branch_address; + break; + case 15: + this.programCounter = branch_address; + break; + + + } + } + + } + + cycle(instructionStep=false) { + if(this.state==0||instructionStep) + this.fetch(0); + if(this.state==1||instructionStep) + this.fetch(1); + if(this.state==2||instructionStep) + this.execute(); + this.state = instructionStep ? 0 :(this.state+1)%3; + } + +} diff --git a/uncheat/index.html b/uncheat/index.html new file mode 100755 index 0000000..2ac25d0 --- /dev/null +++ b/uncheat/index.html @@ -0,0 +1 @@ +