diff options
author | jaseg <git@jaseg.de> | 2020-12-24 16:46:46 +0100 |
---|---|---|
committer | jaseg <git@jaseg.de> | 2020-12-24 16:46:46 +0100 |
commit | 8366601963623a694b602d28ca727be5020d6d15 (patch) | |
tree | 87e3581ca3ac46bd1f0ab0dfc4e84909e42ca444 | |
parent | 410a24c0e893bdd17851c63b698ea723b92ccf62 (diff) | |
download | minikbd-8366601963623a694b602d28ca727be5020d6d15.tar.gz minikbd-8366601963623a694b602d28ca727be5020d6d15.tar.bz2 minikbd-8366601963623a694b602d28ca727be5020d6d15.zip |
Export iBOM and schematic
-rw-r--r-- | .gitignore | 7 | ||||
m--------- | KiCAD-libs | 0 | ||||
-rw-r--r-- | pcb/OtterPill.kicad_prl | 10 | ||||
-rw-r--r-- | pcb/OtterPill.kicad_pro | 7 | ||||
-rw-r--r-- | pcb/OtterPill.pdf | bin | 66098 -> 79301 bytes | |||
-rw-r--r-- | pcb/bom/ibom.html | 3617 |
6 files changed, 3628 insertions, 13 deletions
@@ -16,15 +16,10 @@ fp-info-cache *.dsn *.ses -# Exported BOM files -*.xml -*.csv - ### KiCad Patch ### -escue-backup/ +rescue-backup/ *.tsv -bom/ # Gerber export output out/ diff --git a/KiCAD-libs b/KiCAD-libs -Subproject f0fc4b1219243143b722bb6ae9a1cd757c805d5 +Subproject 63265020429ce78dfc09df887e27c70b6b048ed diff --git a/pcb/OtterPill.kicad_prl b/pcb/OtterPill.kicad_prl index 8c439c7..9547250 100644 --- a/pcb/OtterPill.kicad_prl +++ b/pcb/OtterPill.kicad_prl @@ -1,15 +1,15 @@ { "board": { - "active_layer": 36, + "active_layer": 0, "active_layer_preset": "", "hidden_nets": [], - "high_contrast_mode": 1, + "high_contrast_mode": 0, "net_color_mode": 1, "opacity": { "pads": 1.0, "tracks": 1.0, "vias": 1.0, - "zones": 0.6 + "zones": 1.0 }, "ratsnest_display_mode": 0, "selection_filter": { @@ -17,7 +17,7 @@ "footprints": true, "graphics": true, "keepouts": true, - "lockedItems": true, + "lockedItems": false, "otherItems": true, "pads": true, "text": true, @@ -60,7 +60,7 @@ 36, 37 ], - "visible_layers": "000ffff_80000001" + "visible_layers": "fffffff_ffffffff" }, "meta": { "filename": "OtterPill.kicad_prl", diff --git a/pcb/OtterPill.kicad_pro b/pcb/OtterPill.kicad_pro index 9e837dd..59df4be 100644 --- a/pcb/OtterPill.kicad_pro +++ b/pcb/OtterPill.kicad_pro @@ -74,7 +74,6 @@ "invalid_outline": "error", "item_on_disabled_layer": "error", "items_not_allowed": "error", - "keepout": "error", "length_out_of_range": "error", "malformed_courtyard": "error", "microvia_drill_too_small": "error", @@ -95,7 +94,6 @@ "unconnected_items": "error", "unresolved_variable": "error", "via_dangling": "warning", - "via_hole_larger_than_pad": "error", "zone_has_empty_net": "error", "zones_intersect": "error" }, @@ -107,6 +105,7 @@ "max_error": 0.005, "min_clearance": 0.0, "min_copper_edge_clearance": 0.01, + "min_hole_clearance": 0.0, "min_hole_to_hole": 0.25, "min_microvia_diameter": 0.19999999999999998, "min_microvia_drill": 0.09999999999999999, @@ -152,6 +151,7 @@ "equivalence_files": [] }, "erc": { + "erc_exclusions": [], "meta": { "version": 0 }, @@ -311,6 +311,7 @@ "global_label_dangling": "error", "hier_label_mismatch": "error", "label_dangling": "error", + "lib_symbol_issues": "warning", "multiple_net_names": "error", "net_not_bus_member": "error", "no_connect_connected": "error", @@ -318,6 +319,7 @@ "pin_not_connected": "error", "pin_not_driven": "error", "pin_to_pin": "warning", + "power_pin_not_driven": "error", "similar_labels": "error", "unresolved_variable": "error", "wire_dangling": "error" @@ -397,6 +399,7 @@ "intersheets_ref_short": false, "intersheets_ref_show": false, "intersheets_ref_suffix": "", + "junction_size_choice": 3, "pin_symbol_size": 25.0, "text_offset_ratio": 0.3 }, diff --git a/pcb/OtterPill.pdf b/pcb/OtterPill.pdf Binary files differindex 0442ffa..3b68c65 100644 --- a/pcb/OtterPill.pdf +++ b/pcb/OtterPill.pdf diff --git a/pcb/bom/ibom.html b/pcb/bom/ibom.html new file mode 100644 index 0000000..e002d68 --- /dev/null +++ b/pcb/bom/ibom.html @@ -0,0 +1,3617 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Interactive BOM for KiCAD</title> + <style type="text/css"> +:root { + --pcb-edge-color: black; + --pad-color: #878787; + --pad-color-highlight: #D04040; + --pin1-outline-color: #ffb629; + --pin1-outline-color-highlight: #b4ff03; + --silkscreen-edge-color: #aa4; + --silkscreen-polygon-color: #4aa; + --silkscreen-text-color: #4aa; + --fabrication-edge-color: #907651; + --fabrication-polygon-color: #907651; + --fabrication-text-color: #a27c24; + --track-color: #def5f1; + --track-color-highlight: #D04040; + --zone-color: #def5f1; + --zone-color-highlight: #d0404080; +} + +html, body { + margin: 0px; + height: 100%; + font-family: Verdana, sans-serif; +} + +.dark.topmostdiv { + --pcb-edge-color: #eee; + --pad-color: #808080; + --pin1-outline-color: #ffa800; + --pin1-outline-color-highlight: #ccff00; + --track-color: #42524f; + --zone-color: #42524f; + background-color: #252c30; + color: #eee; +} + +button { + background-color: #eee; + border: 1px solid #888; + color: black; + height: 44px; + width: 44px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 14px; + font-weight: bolder; +} + +.dark button { + /* This will be inverted */ + background-color: #c3b7b5; +} + +button.depressed { + background-color: #0a0; + color: white; +} + +.dark button.depressed { + /* This will be inverted */ + background-color: #b3b; +} + +button:focus { + outline: 0; +} + +button#tb-btn { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.32 290.12h5.82M1.32 291.45h5.82' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 292.5v4.23M.26 292.63H8.2' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='1.35' y='295.73'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A"); +} + +button#lr-btn { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.06 290.12H3.7m-2.64 1.33H3.7m-2.64 1.32H3.7m-2.64 1.3H3.7m-2.64 1.33H3.7' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 288.8v7.94m0-4.11h3.96' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='5.11' y='291.96'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A"); +} + +button#bom-btn { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)' fill='none' stroke='%23000' stroke-width='.4'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' stroke-linejoin='round'/%3E%3Cpath d='M1.59 290.12h5.29M1.59 291.45h5.33M1.59 292.75h5.33M1.59 294.09h5.33M1.59 295.41h5.33'/%3E%3C/g%3E%3C/svg%3E"); +} + +button#bom-grouped-btn { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m4 0h5m4 0h3M6.1 22h3m3.9 0h5m4 0h4m-16-8h4m4 0h4'/%3E%3Cpath stroke-linecap='null' d='M5 17.5h22M5 26.6h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E"); +} + +button#bom-ungrouped-btn { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m-4 8h3m-3 8h4'/%3E%3Cpath stroke-linecap='null' d='M5 13.5h22m-22 8h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E"); +} + +button#bom-netlist-btn { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg fill='none' stroke='%23000' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-width='2' d='M6 26l6-6v-8m13.8-6.3l-6 6v8'/%3E%3Ccircle cx='11.8' cy='9.5' r='2.8' stroke-width='2'/%3E%3Ccircle cx='19.8' cy='22.8' r='2.8' stroke-width='2'/%3E%3C/g%3E%3C/svg%3E"); +} + +button#copy { + background-image: url("data:image/svg+xml,%3Csvg height='48' viewBox='0 0 48 48' width='48' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h48v48h-48z' fill='none'/%3E%3Cpath d='M32 2h-24c-2.21 0-4 1.79-4 4v28h4v-28h24v-4zm6 8h-22c-2.21 0-4 1.79-4 4v28c0 2.21 1.79 4 4 4h22c2.21 0 4-1.79 4-4v-28c0-2.21-1.79-4-4-4zm0 32h-22v-28h22v28z'/%3E%3C/svg%3E"); + background-position: 6px 6px; + background-repeat: no-repeat; + background-size: 26px 26px; + border-radius: 6px; + height: 40px; + width: 40px; + margin: 10px 5px; +} + +button#copy:active { + box-shadow: inset 0px 0px 5px #6c6c6c; +} + +textarea.clipboard-temp { + position: fixed; + top: 0; + left: 0; + width: 2em; + height: 2em; + padding: 0; + border: None; + outline: None; + box-shadow: None; + background: transparent; +} + +.left-most-button { + border-right: 0; + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.middle-button { + border-right: 0; +} + +.right-most-button { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.button-container { + font-size: 0; + margin: 10px 10px 10px 0px; +} + +.dark .button-container { + filter: invert(1); +} + +.button-container button { + background-size: 32px 32px; + background-position: 5px 5px; + background-repeat: no-repeat; +} + +@media print { + .hideonprint { + display: none; + } +} + +canvas { + cursor: crosshair; +} + +canvas:active { + cursor: grabbing; +} + +.fileinfo { + width: 100%; + max-width: 1000px; + border: none; + padding: 5px; +} + +.fileinfo .title { + font-size: 20pt; + font-weight: bold; +} + +.fileinfo td { + overflow: hidden; + white-space: nowrap; + max-width: 1px; + width: 50%; + text-overflow: ellipsis; +} + +.bom { + border-collapse: collapse; + font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace; + font-size: 10pt; + table-layout: fixed; + width: 100%; + margin-top: 1px; +} + +.bom th, .bom td { + border: 1px solid black; + padding: 5px; + word-wrap: break-word; + text-align: center; + position: relative; +} + +.dark .bom th, .dark .bom td { + border: 1px solid #777; +} + +.bom th { + background-color: #CCCCCC; + background-clip: padding-box; +} + +.dark .bom th { + background-color: #3b4749; +} + +.bom tr.highlighted:nth-child(n) { + background-color: #cfc; +} + +.dark .bom tr.highlighted:nth-child(n) { + background-color: #226022; +} + +.bom tr:nth-child(even) { + background-color: #f2f2f2; +} + +.dark .bom tr:nth-child(even) { + background-color: #313b40; +} + +.bom tr.checked { + color: #aaa; +} + +.dark .bom tr.checked { + color: #666; +} + +.bom tr { + transition: background-color 0.2s; +} + +.bom .numCol { + width: 25px; +} + +.bom .Description { + width: 10%; +} + +.bom .Part { + width: 10%; +} + +.bom .Value { + width: 15%; +} + +.bom .Quantity { + width: 65px; +} + +.bom th .sortmark { + position: absolute; + right: 1px; + top: 1px; + margin-top: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent #221 transparent; + transform-origin: 50% 85%; + transition: opacity 0.2s, transform 0.4s; +} + +.dark .bom th .sortmark { + filter: invert(1); +} + +.bom th .sortmark.none { + opacity: 0; +} + +.bom th .sortmark.desc { + transform: rotate(180deg); +} + +.bom th:hover .sortmark.none { + opacity: 0.5; +} + +.bom .bom-checkbox { + width: 30px; + position: relative; + user-select: none; + -moz-user-select: none; +} + +.bom .bom-checkbox:before { + content: ""; + position: absolute; + border-width: 15px; + border-style: solid; + border-color: #51829f transparent transparent transparent; + visibility: hidden; + top: -15px; +} + +.bom .bom-checkbox:after { + content: "Double click to set/unset all"; + position: absolute; + color: white; + top: -35px; + left: -26px; + background: #51829f; + padding: 5px 15px; + border-radius: 8px; + white-space: nowrap; + visibility: hidden; +} + +.bom .bom-checkbox:hover:before, .bom .bom-checkbox:hover:after { + visibility: visible; + transition: visibility 0.2s linear 1s; +} + +.split { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + overflow-y: auto; + overflow-x: hidden; + background-color: inherit; +} + +.split.split-horizontal, .gutter.gutter-horizontal { + height: 100%; + float: left; +} + +.gutter { + background-color: #ddd; + background-repeat: no-repeat; + background-position: 50%; + transition: background-color 0.3s; +} + +.dark .gutter { + background-color: #777; +} + +.gutter.gutter-horizontal { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); + cursor: ew-resize; + width: 5px; +} + +.gutter.gutter-vertical { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII='); + cursor: ns-resize; + height: 5px; +} + +.searchbox { + float: left; + height: 40px; + margin: 10px 5px; + padding: 12px 32px; + font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace; + font-size: 18px; + box-sizing: border-box; + border: 1px solid #888; + border-radius: 6px; + outline: none; + background-color: #eee; + transition: background-color 0.2s, border 0.2s; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABNklEQVQ4T8XSMUvDQBQH8P/LElFa/AIZHcTBQSz0I/gFstTBRR2KUC4ldDxw7h0Bl3RRUATxi4iiODgoiLNrbQYp5J6cpJJqomkX33Z37/14d/dIa33MzDuYI4johOI4XhyNRteO46zNYjDzAxE1yBZprVeZ+QbAUhXEGJMA2Ox2u4+fQIa0mPmsCgCgJYQ4t7lfgF0opQYAdv9ABkKI/UnOFCClXKjX61cA1osQY8x9kiRNKeV7IWA3oyhaSdP0FkAtjxhj3hzH2RBCPOf3pzqYHCilfAAX+URm9oMguPzeWSGQvUcMYC8rOBJCHBRdqxTo9/vbRHRqi8bj8XKv1xvODbiuW2u32/bvf0SlDv4XYOY7z/Mavu+nM1+BmQ+NMc0wDF/LprP0DbTWW0T00ul0nn4b7Q87+X4Qmfiq2wAAAABJRU5ErkJggg=='); + background-position: 10px 10px; + background-repeat: no-repeat; +} + +.dark .searchbox { + background-color: #111; + color: #eee; +} + +.searchbox::placeholder { + color: #ccc; +} + +.dark .searchbox::placeholder { + color: #666; +} + +.filter { + width: calc(60% - 64px); +} + +.reflookup { + width: calc(40% - 10px); +} + +input[type=text]:focus { + background-color: white; + border: 1px solid #333; +} + +.dark input[type=text]:focus { + background-color: #333; + border: 1px solid #ccc; +} + +mark.highlight { + background-color: #5050ff; + color: #fff; + padding: 2px; + border-radius: 6px; +} + +.dark mark.highlight { + background-color: #76a6da; + color: #111; +} + +.menubtn { + background-color: white; + border: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 20 20'%3E%3Cpath fill='none' d='M0 0h20v20H0V0z'/%3E%3Cpath d='M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z'/%3E%3C/svg%3E%0A"); + background-position: center; + background-repeat: no-repeat; +} + +.statsbtn { + background-color: white; + border: none; + background-image: url("data:image/svg+xml,%3Csvg width='36' height='36' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 6h28v24H4V6zm0 8h28v8H4m9-16v24h10V5.8' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E"); + background-position: center; + background-repeat: no-repeat; +} + +.iobtn { + background-color: white; + border: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='M3 33v-7l6.8-7h16.5l6.7 7v7H3zM3.2 26H33M21 9l5-5.9 5 6h-2.5V15h-5V9H21zm-4.9 0l-5 6-5-6h2.5V3h5v6h2.5z'/%3E%3Cpath fill='none' stroke='%23000' d='M6.1 29.5H10'/%3E%3C/svg%3E"); + background-position: center; + background-repeat: no-repeat; +} + +.dark .statsbtn, .dark .savebtn, .dark .menubtn, .dark .iobtn { + filter: invert(1); +} + +.flexbox { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; +} + +.savebtn { + background-color: #d6d6d6; + width: auto; + height: 30px; + flex-grow: 1; + margin: 5px; + border-radius: 4px; +} + +.savebtn:active { + background-color: #0a0; + color: white; +} + +.dark .savebtn:active { + /* This will be inverted */ + background-color: #b3b; +} + +.stats { + border-collapse: collapse; + font-size: 12pt; + table-layout: fixed; + width: 100%; + min-width: 450px; +} + +.dark .stats td { + border: 1px solid #bbb; +} + +.stats td { + border: 1px solid black; + padding: 5px; + word-wrap: break-word; + text-align: center; + position: relative; +} + +#checkbox-stats div { + position: absolute; + left: 0; + top: 0; + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +#checkbox-stats .bar { + background-color: rgba(28, 251, 0, 0.6); +} + +.menu { + position: relative; + display: inline-block; + margin: 10px 10px 10px 0px; +} + +.menu-content { + display: none; + position: absolute; + background-color: white; + right: 0; + min-width: 300px; + box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); + z-index: 100; + padding: 8px; +} + +.dark .menu-content { + background-color: #111; +} + +.menu:hover .menu-content { + display: block; +} + +.menu:hover .menubtn, .menu:hover .iobtn, .menu:hover .statsbtn { + background-color: #eee; +} + +.menu-label { + display: inline-block; + padding: 8px; + border: 1px solid #ccc; + border-top: 0; + width: calc(100% - 18px); +} + +.menu-label-top { + border-top: 1px solid #ccc; +} + +.menu-textbox { + float: left; + height: 24px; + margin: 10px 5px; + padding: 5px 5px; + font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace; + font-size: 14px; + box-sizing: border-box; + border: 1px solid #888; + border-radius: 4px; + outline: none; + background-color: #eee; + transition: background-color 0.2s, border 0.2s; + width: calc(100% - 10px); +} + +.menu-textbox.invalid, .dark .menu-textbox.invalid { + color: red; +} + +.dark .menu-textbox { + background-color: #222; + color: #eee; +} + +.radio-container { + margin: 4px; +} + +.topmostdiv { + width: 100%; + height: 100%; + background-color: white; + transition: background-color 0.3s; +} + +#top { + height: 78px; + border-bottom: 2px solid black; +} + +.dark #top { + border-bottom: 2px solid #ccc; +} + +#dbg { + display: block; +} + +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: #aaa; +} + +::-webkit-scrollbar-thumb { + background: #666; + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: #555; +} + +.slider { + -webkit-appearance: none; + width: 100%; + margin: 3px 0; + padding: 0; + outline: none; + opacity: 0.7; + -webkit-transition: .2s; + transition: opacity .2s; + border-radius: 3px; +} + +.slider:hover { + opacity: 1; +} + +.slider:focus { + outline: none; +} + +.slider::-webkit-slider-runnable-track { + -webkit-appearance: none; + width: 100%; + height: 8px; + background: #d3d3d3; + border-radius: 3px; + border: none; +} + +.slider::-webkit-slider-thumb { + -webkit-appearance: none; + width: 15px; + height: 15px; + border-radius: 50%; + background: #0a0; + cursor: pointer; + margin-top: -4px; +} + +.dark .slider::-webkit-slider-thumb { + background: #3d3; +} + +.slider::-moz-range-thumb { + width: 15px; + height: 15px; + border-radius: 50%; + background: #0a0; + cursor: pointer; +} + +.slider::-moz-range-track { + height: 8px; + background: #d3d3d3; + border-radius: 3px; +} + +.dark .slider::-moz-range-thumb { + background: #3d3; +} + +.slider::-ms-track { + width: 100%; + height: 8px; + border-width: 3px 0; + background: transparent; + border-color: transparent; + color: transparent; + transition: opacity .2s; +} + +.slider::-ms-fill-lower { + background: #d3d3d3; + border: none; + border-radius: 3px; +} + +.slider::-ms-fill-upper { + background: #d3d3d3; + border: none; + border-radius: 3px; +} + +.slider::-ms-thumb { + width: 15px; + height: 15px; + border-radius: 50%; + background: #0a0; + cursor: pointer; + margin: 0; +} + +.shameless-plug { + font-size: 0.8em; + text-align: center; + display: block; +} + +a { + color: #0278a4; +} + +.dark a { + color: #00b9fd; +} + +#frontcanvas, #backcanvas { + touch-action: none; +} + + + </style> + <script type="text/javascript" > +/////////////////////////////////////////////// +/* + Split.js - v1.3.5 + MIT License + https://github.com/nathancahill/Split.js +*/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Split=t()}(this,function(){"use strict";var e=window,t=e.document,n="addEventListener",i="removeEventListener",r="getBoundingClientRect",s=function(){return!1},o=e.attachEvent&&!e[n],a=["","-webkit-","-moz-","-o-"].filter(function(e){var n=t.createElement("div");return n.style.cssText="width:"+e+"calc(9px)",!!n.style.length}).shift()+"calc",l=function(e){return"string"==typeof e||e instanceof String?t.querySelector(e):e};return function(u,c){function z(e,t,n){var i=A(y,t,n);Object.keys(i).forEach(function(t){return e.style[t]=i[t]})}function h(e,t){var n=B(y,t);Object.keys(n).forEach(function(t){return e.style[t]=n[t]})}function f(e){var t=E[this.a],n=E[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,z(t.element,t.size,this.aGutterSize),z(n.element,n.size,this.bGutterSize)}function m(e){var t;this.dragging&&((t="touches"in e?e.touches[0][b]-this.start:e[b]-this.start)<=E[this.a].minSize+M+this.aGutterSize?t=E[this.a].minSize+this.aGutterSize:t>=this.size-(E[this.b].minSize+M+this.bGutterSize)&&(t=this.size-(E[this.b].minSize+this.bGutterSize)),f.call(this,t),c.onDrag&&c.onDrag())}function g(){var e=E[this.a].element,t=E[this.b].element;this.size=e[r]()[y]+t[r]()[y]+this.aGutterSize+this.bGutterSize,this.start=e[r]()[G]}function d(){var t=this,n=E[t.a].element,r=E[t.b].element;t.dragging&&c.onDragEnd&&c.onDragEnd(),t.dragging=!1,e[i]("mouseup",t.stop),e[i]("touchend",t.stop),e[i]("touchcancel",t.stop),t.parent[i]("mousemove",t.move),t.parent[i]("touchmove",t.move),delete t.stop,delete t.move,n[i]("selectstart",s),n[i]("dragstart",s),r[i]("selectstart",s),r[i]("dragstart",s),n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",t.gutter.style.cursor="",t.parent.style.cursor=""}function S(t){var i=this,r=E[i.a].element,o=E[i.b].element;!i.dragging&&c.onDragStart&&c.onDragStart(),t.preventDefault(),i.dragging=!0,i.move=m.bind(i),i.stop=d.bind(i),e[n]("mouseup",i.stop),e[n]("touchend",i.stop),e[n]("touchcancel",i.stop),i.parent[n]("mousemove",i.move),i.parent[n]("touchmove",i.move),r[n]("selectstart",s),r[n]("dragstart",s),o[n]("selectstart",s),o[n]("dragstart",s),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",i.gutter.style.cursor=j,i.parent.style.cursor=j,g.call(i)}function v(e){e.forEach(function(t,n){if(n>0){var i=F[n-1],r=E[i.a],s=E[i.b];r.size=e[n-1],s.size=t,z(r.element,r.size,i.aGutterSize),z(s.element,s.size,i.bGutterSize)}})}function p(){F.forEach(function(e){e.parent.removeChild(e.gutter),E[e.a].element.style[y]="",E[e.b].element.style[y]=""})}void 0===c&&(c={});var y,b,G,E,w=l(u[0]).parentNode,D=e.getComputedStyle(w).flexDirection,U=c.sizes||u.map(function(){return 100/u.length}),k=void 0!==c.minSize?c.minSize:100,x=Array.isArray(k)?k:u.map(function(){return k}),L=void 0!==c.gutterSize?c.gutterSize:10,M=void 0!==c.snapOffset?c.snapOffset:30,O=c.direction||"horizontal",j=c.cursor||("horizontal"===O?"ew-resize":"ns-resize"),C=c.gutter||function(e,n){var i=t.createElement("div");return i.className="gutter gutter-"+n,i},A=c.elementStyle||function(e,t,n){var i={};return"string"==typeof t||t instanceof String?i[e]=t:i[e]=o?t+"%":a+"("+t+"% - "+n+"px)",i},B=c.gutterStyle||function(e,t){return n={},n[e]=t+"px",n;var n};"horizontal"===O?(y="width","clientWidth",b="clientX",G="left","paddingLeft"):"vertical"===O&&(y="height","clientHeight",b="clientY",G="top","paddingTop");var F=[];return E=u.map(function(e,t){var i,s={element:l(e),size:U[t],minSize:x[t]};if(t>0&&(i={a:t-1,b:t,dragging:!1,isFirst:1===t,isLast:t===u.length-1,direction:O,parent:w},i.aGutterSize=L,i.bGutterSize=L,i.isFirst&&(i.aGutterSize=L/2),i.isLast&&(i.bGutterSize=L/2),"row-reverse"===D||"column-reverse"===D)){var a=i.a;i.a=i.b,i.b=a}if(!o&&t>0){var c=C(t,O);h(c,L),c[n]("mousedown",S.bind(i)),c[n]("touchstart",S.bind(i)),w.insertBefore(c,s.element),i.gutter=c}0===t||t===u.length-1?z(s.element,s.size,L/2):z(s.element,s.size,L);var f=s.element[r]()[y];return f<s.minSize&&(s.minSize=f),t>0&&F.push(i),s}),o?{setSizes:v,destroy:p}:{setSizes:v,getSizes:function(){return E.map(function(e){return e.size})},collapse:function(e){if(e===F.length){var t=F[e-1];g.call(t),o||f.call(t,t.size-t.bGutterSize)}else{var n=F[e];g.call(n),o||f.call(n,n.aGutterSize)}},destroy:p}}}); + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net> +// This work is free. You can redistribute it and/or modify it +// under the terms of the WTFPL, Version 2 +// For more information see LICENSE.txt or http://www.wtfpl.net/ +// +// For more information, the home page: +// http://pieroxy.net/blog/pages/lz-string/testing.html +// +// LZ-based compression algorithm, version 1.4.4 +var LZString=function(){var o=String.fromCharCode,i={};var n={decompressFromBase64:function(o){return null==o?"":""==o?null:n._decompress(o.length,32,function(n){return function(o,n){if(!i[o]){i[o]={};for(var t=0;t<o.length;t++)i[o][o.charAt(t)]=t}return i[o][n]}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",o.charAt(n))})},_decompress:function(i,n,t){var r,e,a,s,p,u,l,f=[],c=4,d=4,h=3,v="",g=[],m={val:t(0),position:n,index:1};for(r=0;r<3;r+=1)f[r]=r;for(a=0,p=Math.pow(2,2),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 2:return""}for(f[3]=l,e=l,g.push(l);;){if(m.index>i)return"";for(a=0,p=Math.pow(2,h),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(l=a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 2:return g.join("")}if(0==c&&(c=Math.pow(2,h),h++),f[l])v=f[l];else{if(l!==d)return null;v=e+e.charAt(0)}g.push(v),f[d++]=e+v.charAt(0),e=v,0==--c&&(c=Math.pow(2,h),h++)}}};return n}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString}); +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +/*! + * PEP v0.4.3 | https://github.com/jquery/PEP + * Copyright jQuery Foundation and other contributors | http://jquery.org/license + */ +!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.PointerEventsPolyfill=b()}(this,function(){"use strict";function a(a,b){b=b||Object.create(null);var c=document.createEvent("Event");c.initEvent(a,b.bubbles||!1,b.cancelable||!1); +for(var d,e=2;e<m.length;e++)d=m[e],c[d]=b[d]||n[e];c.buttons=b.buttons||0; +var f=0;return f=b.pressure&&c.buttons?b.pressure:c.buttons?.5:0,c.x=c.clientX,c.y=c.clientY,c.pointerId=b.pointerId||0,c.width=b.width||0,c.height=b.height||0,c.pressure=f,c.tiltX=b.tiltX||0,c.tiltY=b.tiltY||0,c.twist=b.twist||0,c.tangentialPressure=b.tangentialPressure||0,c.pointerType=b.pointerType||"",c.hwTimestamp=b.hwTimestamp||0,c.isPrimary=b.isPrimary||!1,c}function b(){this.array=[],this.size=0}function c(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),A&&(this.observer=new A(this.mutationWatcher.bind(this)))}function d(a){return"body /shadow-deep/ "+e(a)}function e(a){return'[touch-action="'+a+'"]'}function f(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; }"}function g(){if(F){D.forEach(function(a){String(a)===a?(E+=e(a)+f(a)+"\n",G&&(E+=d(a)+f(a)+"\n")):(E+=a.selectors.map(e)+f(a.rule)+"\n",G&&(E+=a.selectors.map(d)+f(a.rule)+"\n"))});var a=document.createElement("style");a.textContent=E,document.head.appendChild(a)}}function h(){if(!window.PointerEvent){if(window.PointerEvent=a,window.navigator.msPointerEnabled){var b=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:b,enumerable:!0}),u.registerSource("ms",_)}else Object.defineProperty(window.navigator,"maxTouchPoints",{value:0,enumerable:!0}),u.registerSource("mouse",N),void 0!==window.ontouchstart&&u.registerSource("touch",V);u.register(document)}}function i(a){if(!u.pointermap.has(a)){var b=new Error("InvalidPointerId");throw b.name="InvalidPointerId",b}}function j(a){for(var b=a.parentNode;b&&b!==a.ownerDocument;)b=b.parentNode;if(!b){var c=new Error("InvalidStateError");throw c.name="InvalidStateError",c}}function k(a){var b=u.pointermap.get(a);return 0!==b.buttons}function l(){window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:W},releasePointerCapture:{value:X},hasPointerCapture:{value:Y}})} +var m=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],n=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],o=window.Map&&window.Map.prototype.forEach,p=o?Map:b;b.prototype={set:function(a,b){return void 0===b?this["delete"](a):(this.has(a)||this.size++,void(this.array[a]=b))},has:function(a){return void 0!==this.array[a]},"delete":function(a){this.has(a)&&(delete this.array[a],this.size--)},get:function(a){return this.array[a]},clear:function(){this.array.length=0,this.size=0},forEach:function(a,b){return this.array.forEach(function(c,d){a.call(b,c,d,this)},this)}};var q=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp"],r=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],s={pointerover:1,pointerout:1,pointerenter:1,pointerleave:1},t="undefined"!=typeof SVGElementInstance,u={pointermap:new p,eventMap:Object.create(null),captureInfo:Object.create(null),eventSources:Object.create(null),eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++) +b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++) +b.unregister.call(b,a)},contains:function(a,b){try{return a.contains(b)}catch(c){return!1}},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.propagate(a,this.leave,!1)},enterOver:function(a){this.over(a),this.propagate(a,this.enter,!0)},eventHandler:function(a){if(!a._handledByPE){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),a._handledByPE=!0}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(b,c){this.captureInfo[c.pointerId]&&(c.relatedTarget=null);var d=new a(b,c);return c.preventDefault&&(d.preventDefault=c.preventDefault),d._target=d._target||c.target,d},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,c=Object.create(null),d=0;d<q.length;d++)b=q[d],c[b]=a[b]||r[d],!t||"target"!==b&&"relatedTarget"!==b||c[b]instanceof SVGElementInstance&&(c[b]=c[b].correspondingUseElement);return a.preventDefault&&(c.preventDefault=function(){a.preventDefault()}),c},getTarget:function(a){var b=this.captureInfo[a.pointerId];return b?a._target!==b&&a.type in s?void 0:b:a._target},propagate:function(a,b,c){for(var d=a.target,e=[];d!==document&&!d.contains(a.relatedTarget);) if(e.push(d),d=d.parentNode,!d)return;c&&e.reverse(),e.forEach(function(c){a.target=c,b.call(this,a)},this)},setCapture:function(b,c,d){this.captureInfo[b]&&this.releaseCapture(b,d),this.captureInfo[b]=c,this.implicitRelease=this.releaseCapture.bind(this,b,d),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease);var e=new a("gotpointercapture");e.pointerId=b,e._target=c,d||this.asyncDispatchEvent(e)},releaseCapture:function(b,c){var d=this.captureInfo[b];if(d){this.captureInfo[b]=void 0,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease);var e=new a("lostpointercapture");e.pointerId=b,e._target=d,c||this.asyncDispatchEvent(e)}},dispatchEvent:/*scope.external.dispatchEvent || */function(a){var b=this.getTarget(a);if(b)return b.dispatchEvent(a)},asyncDispatchEvent:function(a){requestAnimationFrame(this.dispatchEvent.bind(this,a))}};u.boundHandler=u.eventHandler.bind(u);var v={shadow:function(a){if(a)return a.shadowRoot||a.webkitShadowRoot},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);if(this.canTarget(b))return b},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d} e=this.olderShadow(e)} return f}},owner:function(a){ +for(var b=a;b.parentNode;)b=b.parentNode; +return b.nodeType!==Node.DOCUMENT_NODE&&b.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target); +return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}},w=Array.prototype.forEach.call.bind(Array.prototype.forEach),x=Array.prototype.map.call.bind(Array.prototype.map),y=Array.prototype.slice.call.bind(Array.prototype.slice),z=Array.prototype.filter.call.bind(Array.prototype.filter),A=window.MutationObserver||window.WebKitMutationObserver,B="[touch-action]",C={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};c.prototype={watchSubtree:function(a){ +// +this.observer&&v.canTarget(a)&&this.observer.observe(a,C)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){w(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(B):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(y(b))}, +installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){ +var b=x(a,this.findElements,this); +return b.push(z(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}};var D=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],E="",F=window.PointerEvent||window.MSPointerEvent,G=!window.ShadowDOMPolyfill&&document.head.createShadowRoot,H=u.pointermap,I=25,J=[1,4,2,8,16],K=!1;try{K=1===new MouseEvent("test",{buttons:1}).buttons}catch(L){} +var M,N={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},lastTouches:[], +isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,d=a.clientX,e=a.clientY,f=0,g=c.length;f<g&&(b=c[f]);f++){ +var h=Math.abs(d-b.x),i=Math.abs(e-b.y);if(h<=I&&i<=I)return!0}},prepareEvent:function(a){var b=u.cloneEvent(a),c=b.preventDefault;return b.preventDefault=function(){a.preventDefault(),c()},b.pointerId=this.POINTER_ID,b.isPrimary=!0,b.pointerType=this.POINTER_TYPE,b},prepareButtonsForMove:function(a,b){var c=H.get(this.POINTER_ID); +0!==b.which&&c?a.buttons=c.buttons:a.buttons=0,b.buttons=a.buttons},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);K||(c.buttons=J[c.button],b&&(c.buttons|=b.buttons),a.buttons=c.buttons),H.set(this.POINTER_ID,a),b&&0!==b.buttons?u.move(c):u.down(c)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.move(b)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);if(!K){var d=J[c.button]; +c.buttons=b?b.buttons&~d:0,a.buttons=c.buttons}H.set(this.POINTER_ID,a), +c.buttons&=~J[c.button],0===c.buttons?u.up(c):u.move(c)}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.enterOver(b)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,u.leaveOut(b)}},cancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.deactivateMouse()},deactivateMouse:function(){H["delete"](this.POINTER_ID)}},O=u.captureInfo,P=v.findTarget.bind(v),Q=v.allShadows.bind(v),R=u.pointermap,S=2500,T=200,U="touch-action",V={events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){M.enableOnSubtree(a)},unregister:function(){},elementAdded:function(a){var b=a.getAttribute(U),c=this.touchActionToScrollType(b);c&&(a._scrollType=c,u.listen(a,this.events), +Q(a).forEach(function(a){a._scrollType=c,u.listen(a,this.events)},this))},elementRemoved:function(a){a._scrollType=void 0,u.unlisten(a,this.events), +Q(a).forEach(function(a){a._scrollType=void 0,u.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(U),d=this.touchActionToScrollType(c),e=this.touchActionToScrollType(b); +d&&e?(a._scrollType=d,Q(a).forEach(function(a){a._scrollType=d},this)):e?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){ +(0===R.size||1===R.size&&R.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,T)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return"touchstart"!==a&&"touchmove"!==a||(b=1),b},touchToPointer:function(a){var b=this.currentTouchEvent,c=u.cloneEvent(a),d=c.pointerId=a.identifier+2;c.target=O[d]||P(c),c.bubbles=!0,c.cancelable=!0,c.detail=this.clickCount,c.button=0,c.buttons=this.typeToButtons(b.type),c.width=2*(a.radiusX||a.webkitRadiusX||0),c.height=2*(a.radiusY||a.webkitRadiusY||0),c.pressure=a.force||a.webkitForce||.5,c.isPrimary=this.isPrimaryTouch(a),c.pointerType=this.POINTER_TYPE, +c.altKey=b.altKey,c.ctrlKey=b.ctrlKey,c.metaKey=b.metaKey,c.shiftKey=b.shiftKey; +var e=this;return c.preventDefault=function(){e.scrolling=!1,e.firstXY=null,b.preventDefault()},c},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a;for(var d,e=0;e<c.length;e++)d=c[e],b.call(this,this.touchToPointer(d))}, +shouldScroll:function(a){if(this.firstXY){var b,c=a.currentTarget._scrollType;if("none"===c) +b=!1;else if("XY"===c) +b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]); +b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;d<e&&(c=a[d]);d++)if(c.identifier===b)return!0}, +vacuumTouches:function(a){var b=a.touches; +if(R.size>=b.length){var c=[];R.forEach(function(a,d){ +if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(e)}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){R.set(a.pointerId,{target:a.target,out:a,outTarget:a.target}),u.enterOver(a),u.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,c=R.get(b.pointerId); +if(c){var d=c.out,e=c.outTarget;u.move(b),d&&e!==b.target&&(d.relatedTarget=b.target,b.relatedTarget=e, +d.target=e,b.target?(u.leaveOut(d),u.enterOver(b)):( +b.target=e,b.relatedTarget=null,this.cancelOut(b))),c.out=b,c.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(u.up(a),u.leaveOut(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){u.cancel(a),u.leaveOut(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){R["delete"](a.pointerId),this.removePrimaryPointer(a)}, +dedupSynthMouse:function(a){var b=N.lastTouches,c=a.changedTouches[0]; +if(this.isPrimaryTouch(c)){ +var d={x:c.clientX,y:c.clientY};b.push(d);var e=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,b,d);setTimeout(e,S)}}};M=new c(V.elementAdded,V.elementRemoved,V.elementChanged,V);var W,X,Y,Z=u.pointermap,$=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,_={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var b=a;return $&&(b=u.cloneEvent(a),b.pointerType=this.POINTER_TYPES[a.pointerType]),b},cleanup:function(a){Z["delete"](a)},MSPointerDown:function(a){Z.set(a.pointerId,a);var b=this.prepareEvent(a);u.down(b)},MSPointerMove:function(a){var b=this.prepareEvent(a);u.move(b)},MSPointerUp:function(a){var b=this.prepareEvent(a);u.up(b),this.cleanup(a.pointerId)},MSPointerOut:function(a){var b=this.prepareEvent(a);u.leaveOut(b)},MSPointerOver:function(a){var b=this.prepareEvent(a);u.enterOver(b)},MSPointerCancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var b=u.makeEvent("lostpointercapture",a);u.dispatchEvent(b)},MSGotPointerCapture:function(a){var b=u.makeEvent("gotpointercapture",a);u.dispatchEvent(b)}},aa=window.navigator;aa.msPointerEnabled?(W=function(a){i(a),j(this),k(a)&&(u.setCapture(a,this,!0),this.msSetPointerCapture(a))},X=function(a){i(a),u.releaseCapture(a,!0),this.msReleasePointerCapture(a)}):(W=function(a){i(a),j(this),k(a)&&u.setCapture(a,this)},X=function(a){i(a),u.releaseCapture(a)}),Y=function(a){return!!u.captureInfo[a]},g(),h(),l();var ba={dispatcher:u,Installer:c,PointerEvent:a,PointerMap:p,targetFinding:v};return ba}); + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +var config = {"dark_mode": false, "show_pads": true, "show_fabrication": false, "show_silkscreen": true, "highlight_pin1": false, "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "extra_fields": []} +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +var pcbdata = JSON.parse(LZString.decompressFromBase64("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gGAs0CzeAHAszyzILLeMkABYLJJ8eCzUzKCso8z/4AKYEEzczIwsrCyorOwAGKzGLLisxUThmGIs+1YsTPKAcizmzIUsnKylLKQs4KzjzJ8XAJhYrIvM9QAdLOeAFKz2TOZAW0ypzMdM4yyXzKas90yWrJXM0Sz1rIkszqypLKQsnqz5LL6s6iyBrLys/UyYpJusl6zwbPNM4czyrLrMmGy7zPhsp8y+LKWslGyVrLRsn0yxLI2slQMyjkcsnaznLL2slsysrIgs+MzjrNgszG0ArIusnAB0zKBst9dszNOIcKybAAes4sy4TLJssIBCLJSWD6zJrNSs76z0rIos1o4+bM1M/qzDzO//WGBTzLBsrSyIbLKs3SzobKqstwAarNGAeayGrP+AV8zlrPFMyyy1rJ/MnoA/zMpM3GzzuT+s6wBcrMBsuiz3Ul7MpWzmLO0s82yobIqsp6yrbLhsriyEbIWspGzGbNBnZ2zf8BEs1myMbLssrGytrMAs7myIzNcssCz+bMOswWyyUBAAAABlAAB1BWDzrN+M8Wz/bLa9JlZJFnQslSzIQEb6aKzG+mDsigRzEHRM8W0fQBiyZHMA/B+szKy9bIJs6QAlFANs34gfwBrafhYOgE0soahrQExQdWzIQAbyfSzZrJ9M2l4hLMpQC4BtrNbAVYBo7NcAdI5MjhcATezVgG3s6eySrPSALFQ/gHaszGzNrM9s2SzdzPxsxSzXgBHswayx7KEnSRZ8LJRSWezxAHnsxezYbJts6yzV7Iss9ezigEPs7ey/7L3sloAsjizsrez37OYss+zpH2sstmyr7I5s4GAfbPJM4ezCbJrsl+ysp0nstwAT7MSOOeyqbNHMn+zabKeAFAAAHLgEDeyoHKPsnezhQHAcyByQACdM6ByT7O7aRKzsOkvs9Ozr7JQc++z/rMfsjByMLJJA3gFG0DbszFAeAAIci2yI7IXs3DoZrMpQOhyD7MAcp4BKHIYcmo5qHLAcjI4IHLkcpRymHLGsk0Bz7PRst2zrAA9srhzB7Ifs9BzR7KxIbppHyBwcmBzwgB//MRzw7Ops4hzpHKeAWRzXgEiYRRzGHJUc5eyQABcckBzrHJYc3RzU7P0cwxzLEFQcwcBTHOfsrEgYJHI/e1ZrHPxIEQASwGRzRxzrbK8cshzmrjXshRzgHKoc0ByUnMQAVYAGjigAV4APHOPs4qz8HOBDPRzbLPds+yyrjPqAUJzeHLMc3oAqQVTmbAhYnIgOP4T7HKIcqRzknMpQVJyNTnSc1wB3HOUc7JzunNyc/JzCnMGc6xzSnKsGdhzKnIzszmztrLDMnmzc7P2s/OzeAC8s+oAfLJLs0uzpKkrsxCz+HPhSONYaQLCs+6znLHhDaKz0yjbs2590TJBQdWy+7K1s36zuHN9ssJzeACfsomzfiFlAB5o27Kv/Z/D2nKhAAPwSHN3stRz6HLcczJzNHM8cmRzAXI0copzrHK+c7GzpnIMcqpyjHJJM/qzwnNec8sAkElZraiALnOEWcLJCHN+cjiyvHJ8c+Rz+nJBcqFzVHP3ssZytHIZM7FyKDjhc4JyanIectBznnL4c4Kz0XO/2TbIp7O0cvmAcXPEc6my/nKccgFzyXL6c4UABnOgcslz1HIpc6hzmHOpcmLJaXIRckJyGXKeckAAXnMwcstosYHI/TRCJnIbwvkA+YEO8DMAe7OhsvlyunOcciFzXHOwoEVywXONcwVysnL8ciA5DMAvsxByOHI5s7czb7N6s4xyeHJRclVzELi/ADIA71WEcrVysQB1c/1ybgH1ciRzDXJoc3gBCXIocklzxnLFc+hyoXKlc9QA7XPKc9mygzK5shZyc7LCANyzNTIFs7yzjrLLskWyQAECs6uyMLNSoUFSjnMbs5uynrNbsoqyGTJlCTuya7y1AENy6zNuc6SyMrJ1s2pyPXJLcvbRsHL9c7YA7HN7s/FzunPIc4FyJXKGcy1zxXN8cqVy4HLYch1yZnOvs51y5LO9shVy6nIicm6h94EpUzVy+3K/s3Fy2TLDcv+yenNNcoBzR3PDc7xyTXMnc7Rzp3PtctOy53OQc+Vy3XMecldzUXLXcoSchHJrc1IBP7MKWAdyl7KHctJyiXOFc6NzRXIJcs9zrXKnc6syZ3Ovc+FzZnMRc7KyH3M7c4KzbVQyyKxy8HNsc7dyeXNHMvdygPKtcqNzj3NjcyFzxnNA81hyr3KCcuVz6XPvcxlylXOZcwEyEPM1yP1zLMn7cg1zB3PHcoFyzXIA8i1yBXInckDyL3LA8ojyKnMg8zhy73KRcoeymXPqck5ImnLbsuJy2nK/c3+yUnOHcljycPJycvJyVgGPc5Dyt3Kmc2dy+PNvc0jzBPJMc4TzV3NE875oYnJPsiTyEnIY879zSHNk8o9zfHP3ckZylPPPc5EzJnJ48lNyz/wAspRz03JcszNy87Ozcguzc3KLssuzZO1Fsquz6gBLcyrIGgl6mctyIrLKwelJIQHOct9ypqB0c65yd3KesltykLLbcnoACTOXcuDznjN6sXCiMahInG1yuXIoORJzOnJPcyNyR3Ks8zDyOPNBc4pyqXIK8mVz1PLpc9LyyPMVc5VzgvNlAN/pPnOtAb5yivMY89jzmPMs861zcPOU84qyYXJwc2VyoPIE8mDzyPJa8lSzsvLonCbJ8vOrMptyOnJ682hzgPOw88rzwXKw8+NzOXMW8xzykHKDMibzkXN08p9zfzFC8q4A/XNPQtgBA3Mu8l6Tv7OK8wbyhXOXM1jyx3N68vDzKXNNMxNySwDG8+dzurJdcvGymvMfcz1z2NA9dKMJD4Oac5DybvJxmJQAg3KqAJbyoQCSckry1vLK8gbyKvLjc/DztHM+86sBvvOQctNzdrKWc3WyPLNWco6zfPNLsjNFC3LFsoLzJbI7shbDNEIbsiLyzsCi8mLyOXIZM4YgjgAS8tDzhAGS83Ez7nIB8zLzoSCZUx5pcHJ28xKy4fN3clbyI3KR8uTyNvKY8t7zJXOF87lyEHIg8hryCfMm85rzKPP58siiBtQYnBbyRfPnsjDzNvMq85HyqvMR8rbz0fJq83bzk3P285zzDvKE8ijz6nObyW/C37JPskby9fPF809ysPKN80lzUfNl86rybABd8y3zHXIO8rTzVfMB8vZyEkimwjVyIfIbAa7zo/Nd8szzXvMPcjJz5PIN8tHz3vIHMzHy9vMD87GyZLMXc6DyjvLt81dyZ0Fw4i6JtfKj8vVzRHJh84wBRfKS8t3zSvKl8lHyU/J98m1yM/ID8m9zU3PmcvHyPPOWcrzyifMLs1wAy7N1gFMzAvIlsqjzklFTmCoBwvLlsk5zGfJo/WLz3qHi8+BypPP7s9tyMvOO8z1y4/Aawy7yTbOYs2ry7vNr8yXz+vON8h7zOPPN83XzW/I08oPzGvO0891y1/P4crLT7GCd84bzOvOxs7rz4/NW8j3z6/KP873yhvORM/3zAnN485XyO3Nv8+DyBfPm8qVzd/MS8yRz9/I/8w/yvfMb8n/zTTIgC//ynPP/Mm3ydPIL8p9zenDO8ify5/JscyHyY/L1cvfy3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pu3ADKabJuym9iLs0GiG/Kb0TMKm4qbtJsRGnsbtvTCAaQbeAAsGxQaihuNGnEbTRoBmwwabZtMGsIbzBoJgSwaSgCmG/ZLXpphmj6b8Rq+mwkbrRoeG/kb9BsiGkyatxsdG02aEht+G+uaUhsKm94z0ho0mtobzZuyG08aChuem6Ya05rZG3Ea4ZoRmpGa/ptJGpSabss+Gr4aics+G/ybbZuWisYaJhqLm2wbZhvmGv4J3puWGnobHRqBG7hLHRtnmhQLyIrOmgKbKYoKGo4bpAFlGs4b05thm8ub4Zsrm5GbJ5q1GuPqqfAxmiEagRonynubXsChGnYbY5sXmwmb7JvRGqGbr5uHm00bzRpVGn6a1Rurmu0b/ht+Gqkb2IpKKvubeAAZGpkaS5pvmsuaLRsRm36abRqfmgUbfhtxmkUa1ptPmiUapRplGtBbQFtvmzBbx5pwWmuaTrJ1GgmaJRtkG4BbsRooWjBaIFqwWqBaNRrQmsNLHRpwm0+bXRo9Gr0bfRv9GwMbdxrDGiMa0JujG8iLCpvjG8iKTJqSK34bTZrTGxhZUxqzGhhbgxvzGwsbixtLG8sbeAErG6sbaxvrGxsbmxtbGvAA0Js7G2vl1Ft4AfsbBxo/RYcaxFrHGv8AJxqnGxAAZxrnGjsaaotQKdabNps3G7caeEr3GpxbDxo7G48a+ppzm/UaKpvwmwibiJtIm8ia3QCyGk6zqJpaAWibVgHomxibmJq4GmzZ2JsFm+QL2IoXSdaaHJqcmvCbSJrcm0MaPJq8mrIbwhoH8vyarFs2ckabeABqmuqbHhsamioAWpu6oNqa4Js6m3pzWhp6m8iLQlpGGiUahprqWkAAxpoCASabppsuGuaaFpvKAJabulpFs7GAals2m7abXgEWWg6bs0COm5abjxpPm/qbqnIqOBCb4AEwGmQA+wHKOAgBUAB8GucAkXPqORo5hQDnAcKBgIo4ASEAoAEUACABXsAAAHUaOEwAgAAAA")) +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +/* Utility functions */ + +var storagePrefix = 'KiCad_HTML_BOM__' + pcbdata.metadata.title + '__' + + pcbdata.metadata.revision + '__#'; +var storage; + +function initStorage(key) { + try { + window.localStorage.getItem("blank"); + storage = window.localStorage; + } catch (e) { + // localStorage not available + } + if (!storage) { + try { + window.sessionStorage.getItem("blank"); + storage = window.sessionStorage; + } catch (e) { + // sessionStorage also not available + } + } +} + +function readStorage(key) { + if (storage) { + return storage.getItem(storagePrefix + key); + } else { + return null; + } +} + +function writeStorage(key, value) { + if (storage) { + storage.setItem(storagePrefix + key, value); + } +} + +function fancyDblClickHandler(el, onsingle, ondouble) { + return function() { + if (el.getAttribute("data-dblclick") == null) { + el.setAttribute("data-dblclick", 1); + setTimeout(function() { + if (el.getAttribute("data-dblclick") == 1) { + onsingle(); + } + el.removeAttribute("data-dblclick"); + }, 200); + } else { + el.removeAttribute("data-dblclick"); + ondouble(); + } + } +} + +function smoothScrollToRow(rowid) { + document.getElementById(rowid).scrollIntoView({ + behavior: "smooth", + block: "center", + inline: "nearest" + }); +} + +function focusInputField(input) { + input.scrollIntoView(false); + input.focus(); + input.select(); +} + +function copyToClipboard() { + var text = ''; + for (var node of bomhead.childNodes[0].childNodes) { + if (node.firstChild) { + text = text + node.firstChild.nodeValue; + } + if (node != bomhead.childNodes[0].lastChild) { + text += '\t'; + } + } + text += '\n'; + for (var row of bombody.childNodes) { + for (var cell of row.childNodes) { + for (var node of cell.childNodes) { + if (node.nodeName == "INPUT") { + if (node.checked) { + text = text + '✓'; + } + } else if (node.nodeName == "MARK") { + text = text + node.firstChild.nodeValue; + } else { + text = text + node.nodeValue; + } + } + if (cell != row.lastChild) { + text += '\t'; + } + } + text += '\n'; + } + var textArea = document.createElement("textarea"); + textArea.classList.add('clipboard-temp'); + textArea.value = text; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + if (document.execCommand('copy')) { + console.log('Bom copied to clipboard.'); + } + } catch (err) { + console.log('Can not copy to clipboard.'); + } + + document.body.removeChild(textArea); +} + +function removeGutterNode(node) { + for (var i = 0; i < node.childNodes.length; i++) { + if (node.childNodes[i].classList && + node.childNodes[i].classList.contains("gutter")) { + node.removeChild(node.childNodes[i]); + break; + } + } +} + +function cleanGutters() { + removeGutterNode(document.getElementById("bot")); + removeGutterNode(document.getElementById("canvasdiv")); +} + +var units = { + prefixes: { + giga: ["G", "g", "giga", "Giga", "GIGA"], + mega: ["M", "mega", "Mega", "MEGA"], + kilo: ["K", "k", "kilo", "Kilo", "KILO"], + milli: ["m", "milli", "Milli", "MILLI"], + micro: ["U", "u", "micro", "Micro", "MICRO", "μ", "µ"], // different utf8 μ + nano: ["N", "n", "nano", "Nano", "NANO"], + pico: ["P", "p", "pico", "Pico", "PICO"], + }, + unitsShort: ["R", "r", "Ω", "F", "f", "H", "h"], + unitsLong: [ + "OHM", "Ohm", "ohm", "ohms", + "FARAD", "Farad", "farad", + "HENRY", "Henry", "henry" + ], + getMultiplier: function(s) { + if (this.prefixes.giga.includes(s)) return 1e9; + if (this.prefixes.mega.includes(s)) return 1e6; + if (this.prefixes.kilo.includes(s)) return 1e3; + if (this.prefixes.milli.includes(s)) return 1e-3; + if (this.prefixes.micro.includes(s)) return 1e-6; + if (this.prefixes.nano.includes(s)) return 1e-9; + if (this.prefixes.pico.includes(s)) return 1e-12; + return 1; + }, + valueRegex: null, +} + +function initUtils() { + var allPrefixes = units.prefixes.giga + .concat(units.prefixes.mega) + .concat(units.prefixes.kilo) + .concat(units.prefixes.milli) + .concat(units.prefixes.micro) + .concat(units.prefixes.nano) + .concat(units.prefixes.pico); + var allUnits = units.unitsShort.concat(units.unitsLong); + units.valueRegex = new RegExp("^([0-9\.]+)" + + "\\s*(" + allPrefixes.join("|") + ")?" + + "(" + allUnits.join("|") + ")?" + + "(\\b.*)?$", ""); + units.valueAltRegex = new RegExp("^([0-9]*)" + + "(" + units.unitsShort.join("|") + ")?" + + "([GgMmKkUuNnPp])?" + + "([0-9]*)" + + "(\\b.*)?$", ""); + for (var bom_type of ["both", "F", "B"]) { + for (var row of pcbdata.bom[bom_type]) { + row.push(parseValue(row[1], row[3][0][0])); + } + } +} + +function parseValue(val, ref) { + var inferUnit = (unit, ref) => { + if (unit) { + unit = unit.toLowerCase(); + if (unit == 'Ω' || unit == "ohm" || unit == "ohms") { + unit = 'r'; + } + unit = unit[0]; + } else { + ref = /^([a-z]+)\d+$/i.exec(ref); + if (ref) { + ref = ref[1].toLowerCase(); + if (ref == "c") unit = 'f'; + else if (ref == "l") unit = 'h'; + else if (ref == "r" || ref == "rv") unit = 'r'; + else unit = null; + } + } + return unit; + }; + val = val.replace(/,/g, ""); + var match = units.valueRegex.exec(val); + var unit; + if (match) { + val = parseFloat(match[1]); + if (match[2]) { + val = val * units.getMultiplier(match[2]); + } + unit = inferUnit(match[3], ref); + if (!unit) return null; + else return { + val: val, + unit: unit, + extra: match[4], + } + } + match = units.valueAltRegex.exec(val); + if (match && (match[1] || match[4])) { + val = parseFloat(match[1] + "." + match[4]); + if (match[3]) { + val = val * units.getMultiplier(match[3]); + } + unit = inferUnit(match[2], ref); + if (!unit) return null; + else return { + val: val, + unit: unit, + extra: match[5], + } + } + return null; +} + +function valueCompare(a, b, stra, strb) { + if (a === null && b === null) { + // Failed to parse both values, compare them as strings. + if (stra != strb) return stra > strb ? 1 : -1; + else return 0; + } else if (a === null) { + return 1; + } else if (b === null) { + return -1; + } else { + if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1; + else if (a.val != b.val) return a.val > b.val ? 1 : -1; + else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1; + else return 0; + } +} + +function validateSaveImgDimension(element) { + var valid = false; + var intValue = 0; + if (/^[1-9]\d*$/.test(element.value)) { + intValue = parseInt(element.value); + if (intValue <= 16000) { + valid = true; + } + } + if (valid) { + element.classList.remove("invalid"); + } else { + element.classList.add("invalid"); + } + return intValue; +} + +function saveImage(layer) { + var width = validateSaveImgDimension(document.getElementById("render-save-width")); + var height = validateSaveImgDimension(document.getElementById("render-save-height")); + var bgcolor = null; + if (!document.getElementById("render-save-transparent").checked) { + var style = getComputedStyle(topmostdiv); + bgcolor = style.getPropertyValue("background-color"); + } + if (!width || !height) return; + + // Prepare image + var canvas = document.createElement("canvas"); + var layerdict = { + transform: { + x: 0, + y: 0, + s: 1, + panx: 0, + pany: 0, + zoom: 1, + }, + bg: canvas, + fab: canvas, + silk: canvas, + highlight: canvas, + layer: layer, + } + // Do the rendering + recalcLayerScale(layerdict, width, height); + prepareLayer(layerdict); + clearCanvas(canvas, bgcolor); + drawBackground(layerdict, false); + drawHighlightsOnLayer(layerdict, false); + + // Save image + var imgdata = canvas.toDataURL("image/png"); + + var filename = pcbdata.metadata.title; + if (pcbdata.metadata.revision) { + filename += `.${pcbdata.metadata.revision}`; + } + filename += `.${layer}.png`; + saveFile(filename, dataURLtoBlob(imgdata)); +} + +function saveSettings() { + var data = { + type: "InteractiveHtmlBom settings", + version: 1, + pcbmetadata: pcbdata.metadata, + settings: settings, + } + var blob = new Blob([JSON.stringify(data, null, 4)], {type: "application/json"}); + saveFile(`${pcbdata.metadata.title}.settings.json`, blob); +} + +function loadSettings() { + var input = document.createElement("input"); + input.type = "file"; + input.accept = ".settings.json"; + input.onchange = function(e) { + var file = e.target.files[0]; + var reader = new FileReader(); + reader.onload = readerEvent => { + var content = readerEvent.target.result; + var newSettings; + try { + newSettings = JSON.parse(content); + } catch(e) { + alert("Selected file is not InteractiveHtmlBom settings file."); + return; + } + if (newSettings.type != "InteractiveHtmlBom settings") { + alert("Selected file is not InteractiveHtmlBom settings file."); + return; + } + var metadataMatches = newSettings.hasOwnProperty("pcbmetadata"); + if (metadataMatches) { + for (var k in pcbdata.metadata) { + if (!newSettings.pcbmetadata.hasOwnProperty(k) || newSettings.pcbmetadata[k] != pcbdata.metadata[k]) { + metadataMatches = false; + } + } + } + if (!metadataMatches) { + var currentMetadata = JSON.stringify(pcbdata.metadata, null, 4); + var fileMetadata = JSON.stringify(newSettings.pcbmetadata, null, 4); + if (!confirm( + `Settins file metadata does not match current metadata.\n\n` + + `Page metadata:\n${currentMetadata}\n\n` + + `Settings file metadata:\n${fileMetadata}\n\n` + + `Press OK if you would like to import settings anyway.`)) { + return; + } + } + overwriteSettings(newSettings.settings); + } + reader.readAsText(file, 'UTF-8'); + } + input.click(); +} + +function overwriteSettings(newSettings) { + initDone = false; + Object.assign(settings, newSettings); + writeStorage("bomlayout", settings.bomlayout); + writeStorage("bommode", settings.bommode); + writeStorage("canvaslayout", settings.canvaslayout); + writeStorage("bomCheckboxes", settings.checkboxes.join(",")); + document.getElementById("bomCheckboxes").value = settings.checkboxes.join(","); + for (var checkbox of settings.checkboxes) { + writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]); + } + writeStorage("darkenWhenChecked", settings.darkenWhenChecked); + padsVisible(settings.renderPads); + document.getElementById("padsCheckbox").checked = settings.renderPads; + fabricationVisible(settings.renderFabrication); + document.getElementById("fabricationCheckbox").checked = settings.renderFabrication; + silkscreenVisible(settings.renderSilkscreen); + document.getElementById("silkscreenCheckbox").checked = settings.renderSilkscreen; + referencesVisible(settings.renderReferences); + document.getElementById("referencesCheckbox").checked = settings.renderReferences; + valuesVisible(settings.renderValues); + document.getElementById("valuesCheckbox").checked = settings.renderValues; + tracksVisible(settings.renderTracks); + document.getElementById("tracksCheckbox").checked = settings.renderTracks; + zonesVisible(settings.renderZones); + document.getElementById("zonesCheckbox").checked = settings.renderZones; + dnpOutline(settings.renderDnpOutline); + document.getElementById("dnpOutlineCheckbox").checked = settings.renderDnpOutline; + setRedrawOnDrag(settings.redrawOnDrag); + document.getElementById("dragCheckbox").checked = settings.redrawOnDrag; + setDarkMode(settings.darkMode); + document.getElementById("darkmodeCheckbox").checked = settings.darkMode; + setHighlightPin1(settings.highlightpin1); + document.getElementById("highlightpin1Checkbox").checked = settings.highlightpin1; + writeStorage("boardRotation", settings.boardRotation); + document.getElementById("boardRotation").value = settings.boardRotation / 5; + document.getElementById("rotationDegree").textContent = settings.boardRotation; + initDone = true; + prepCheckboxes(); + changeBomLayout(settings.bomlayout); +} + +function saveFile(filename, blob) { + var link = document.createElement("a"); + var objurl = URL.createObjectURL(blob); + link.download = filename; + link.href = objurl; + link.click(); +} + +function dataURLtoBlob(dataurl) { + var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); + while(n--){ + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], {type:mime}); +} + +var settings = { + canvaslayout: "default", + bomlayout: "default", + bommode: "grouped", + checkboxes: [], + checkboxStoredRefs: {}, + darkMode: false, + highlightpin1: false, + redrawOnDrag: true, + boardRotation: 0, + renderPads: true, + renderReferences: true, + renderValues: true, + renderSilkscreen: true, + renderFabrication: true, + renderDnpOutline: false, + renderTracks: true, + renderZones: true, +} + +function initDefaults() { + settings.bomlayout = readStorage("bomlayout"); + if (settings.bomlayout === null) { + settings.bomlayout = config.bom_view; + } + if (!['bom-only', 'left-right', 'top-bottom'].includes(settings.bomlayout)) { + settings.bomlayout = config.bom_view; + } + settings.bommode = readStorage("bommode"); + if (settings.bommode === null) { + settings.bommode = "grouped"; + } + if (!["grouped", "ungrouped", "netlist"].includes(settings.bommode)) { + settings.bommode = "grouped"; + } + settings.canvaslayout = readStorage("canvaslayout"); + if (settings.canvaslayout === null) { + settings.canvaslayout = config.layer_view; + } + var bomCheckboxes = readStorage("bomCheckboxes"); + if (bomCheckboxes === null) { + bomCheckboxes = config.checkboxes; + } + settings.checkboxes = bomCheckboxes.split(",").filter((e) => e); + document.getElementById("bomCheckboxes").value = bomCheckboxes; + + settings.darkenWhenChecked = readStorage("darkenWhenChecked") || ""; + populateDarkenWhenCheckedOptions(); + + function initBooleanSetting(storageString, def, elementId, func) { + var b = readStorage(storageString); + if (b === null) { + b = def; + } else { + b = (b == "true"); + } + document.getElementById(elementId).checked = b; + func(b); + } + + initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible); + initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible); + initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible); + initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible); + initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible); + if ("tracks" in pcbdata) { + initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible); + initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible); + } else { + document.getElementById("tracksAndZonesCheckboxes").style.display = "none"; + tracksVisible(false); + zonesVisible(false); + } + initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline); + initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag); + initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode); + initBooleanSetting("highlightpin1", config.highlight_pin1, "highlightpin1Checkbox", setHighlightPin1); + settings.boardRotation = readStorage("boardRotation"); + if (settings.boardRotation === null) { + settings.boardRotation = config.board_rotation * 5; + } else { + settings.boardRotation = parseInt(settings.boardRotation); + } + document.getElementById("boardRotation").value = settings.boardRotation / 5; + document.getElementById("rotationDegree").textContent = settings.boardRotation; +} + +// Helper classes for user js callbacks. + +const IBOM_EVENT_TYPES = { + ALL: "all", + HIGHLIGHT_EVENT: "highlightEvent", + CHECKBOX_CHANGE_EVENT: "checkboxChangeEvent", + BOM_BODY_CHANGE_EVENT: "bomBodyChangeEvent", +} + +const EventHandler = { + callbacks: {}, + init: function() { + for (eventType of Object.values(IBOM_EVENT_TYPES)) + this.callbacks[eventType] = []; + }, + registerCallback: function(eventType, callback) { + this.callbacks[eventType].push(callback); + }, + emitEvent: function(eventType, eventArgs) { + event = { + eventType: eventType, + args: eventArgs, + } + var callback; + for(callback of this.callbacks[eventType]) + callback(event); + for(callback of this.callbacks[IBOM_EVENT_TYPES.ALL]) + callback(event); + } +} +EventHandler.init(); + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +/* PCB rendering code */ + +var emptyContext2d = document.createElement("canvas").getContext("2d"); + +function deg2rad(deg) { + return deg * Math.PI / 180; +} + +function calcFontPoint(linepoint, text, offsetx, offsety, tilt) { + var point = [ + linepoint[0] * text.width + offsetx, + linepoint[1] * text.height + offsety + ]; + // This approximates pcbnew behavior with how text tilts depending on horizontal justification + point[0] -= (linepoint[1] + 0.5 * (1 + text.justify[0])) * text.height * tilt; + return point; +} + +function drawText(ctx, text, color) { + if ("ref" in text && !settings.renderReferences) return; + if ("val" in text && !settings.renderValues) return; + ctx.save(); + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineCap = "round"; + ctx.lineJoin = "round"; + ctx.lineWidth = text.thickness; + if ("svgpath" in text) { + ctx.stroke(new Path2D(text.svgpath)); + ctx.restore(); + return; + } + ctx.translate(...text.pos); + ctx.translate(text.thickness * 0.5, 0); + var angle = -text.angle; + if (text.attr.includes("mirrored")) { + ctx.scale(-1, 1); + angle = -angle; + } + var tilt = 0; + if (text.attr.includes("italic")) { + tilt = 0.125; + } + var interline = text.height * 1.5 + text.thickness; + var txt = text.text.split("\n"); + // KiCad ignores last empty line. + if (txt[txt.length - 1] == '') txt.pop(); + ctx.rotate(deg2rad(angle)); + var offsety = (1 - text.justify[1]) / 2 * text.height; // One line offset + offsety -= (txt.length - 1) * (text.justify[1] + 1) / 2 * interline; // Multiline offset + for (var i in txt) { + var lineWidth = text.thickness + interline / 2 * tilt; + for (var j = 0; j < txt[i].length; j++) { + if (txt[i][j] == '\t') { + var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width; + lineWidth += fourSpaces - lineWidth % fourSpaces; + } else { + if (txt[i][j] == '~') { + j++; + if (j == txt[i].length) + break; + } + lineWidth += pcbdata.font_data[txt[i][j]].w * text.width; + } + } + var offsetx = -lineWidth * (text.justify[0] + 1) / 2; + var inOverbar = false; + for (var j = 0; j < txt[i].length; j++) { + if (txt[i][j] == '\t') { + var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width; + offsetx += fourSpaces - offsetx % fourSpaces; + continue; + } else if (txt[i][j] == '~') { + j++; + if (j == txt[i].length) + break; + if (txt[i][j] != '~') { + inOverbar = !inOverbar; + } + } + var glyph = pcbdata.font_data[txt[i][j]]; + if (inOverbar) { + var overbarStart = [offsetx, -text.height * 1.4 + offsety]; + var overbarEnd = [offsetx + text.width * glyph.w, overbarStart[1]]; + + if (!lastHadOverbar) { + overbarStart[0] += text.height * 1.4 * tilt; + lastHadOverbar = true; + } + ctx.beginPath(); + ctx.moveTo(...overbarStart); + ctx.lineTo(...overbarEnd); + ctx.stroke(); + } else { + lastHadOverbar = false; + } + for (var line of glyph.l) { + ctx.beginPath(); + ctx.moveTo(...calcFontPoint(line[0], text, offsetx, offsety, tilt)); + for (var k = 1; k < line.length; k++) { + ctx.lineTo(...calcFontPoint(line[k], text, offsetx, offsety, tilt)); + } + ctx.stroke(); + } + offsetx += glyph.w * text.width; + } + offsety += interline; + } + ctx.restore(); +} + +function drawedge(ctx, scalefactor, edge, color) { + ctx.strokeStyle = color; + ctx.lineWidth = Math.max(1 / scalefactor, edge.width); + ctx.lineCap = "round"; + if ("svgpath" in edge) { + ctx.stroke(new Path2D(edge.svgpath)); + } else { + ctx.beginPath(); + if (edge.type == "segment") { + ctx.moveTo(...edge.start); + ctx.lineTo(...edge.end); + } + if (edge.type == "rect") { + ctx.moveTo(...edge.start); + ctx.lineTo(edge.start[0], edge.end[1]); + ctx.lineTo(...edge.end); + ctx.lineTo(edge.end[0], edge.start[1]); + ctx.lineTo(...edge.start); + } + if (edge.type == "arc") { + ctx.arc( + ...edge.start, + edge.radius, + deg2rad(edge.startangle), + deg2rad(edge.endangle)); + } + if (edge.type == "circle") { + ctx.arc( + ...edge.start, + edge.radius, + 0, 2 * Math.PI); + ctx.closePath(); + } + if (edge.type == "curve") { + ctx.moveTo(...edge.start); + ctx.bezierCurveTo(...edge.cpa, ...edge.cpb, ...edge.end); + } + ctx.stroke(); + } +} + +function getChamferedRectPath(size, radius, chamfpos, chamfratio) { + // chamfpos is a bitmask, left = 1, right = 2, bottom left = 4, bottom right = 8 + var path = new Path2D(); + var width = size[0]; + var height = size[1]; + var x = width * -0.5; + var y = height * -0.5; + var chamfOffset = Math.min(width, height) * chamfratio; + path.moveTo(x, 0); + if (chamfpos & 4) { + path.lineTo(x, y + height - chamfOffset); + path.lineTo(x + chamfOffset, y + height); + path.lineTo(0, y + height); + } else { + path.arcTo(x, y + height, x + width, y + height, radius); + } + if (chamfpos & 8) { + path.lineTo(x + width - chamfOffset, y + height); + path.lineTo(x + width, y + height - chamfOffset); + path.lineTo(x + width, 0); + } else { + path.arcTo(x + width, y + height, x + width, y, radius); + } + if (chamfpos & 2) { + path.lineTo(x + width, y + chamfOffset); + path.lineTo(x + width - chamfOffset, y); + path.lineTo(0, y); + } else { + path.arcTo(x + width, y, x, y, radius); + } + if (chamfpos & 1) { + path.lineTo(x + chamfOffset, y); + path.lineTo(x, y + chamfOffset); + path.lineTo(x, 0); + } else { + path.arcTo(x, y, x, y + height, radius); + } + path.closePath(); + return path; +} + +function getOblongPath(size) { + return getChamferedRectPath(size, Math.min(size[0], size[1]) / 2, 0, 0); +} + +function getPolygonsPath(shape) { + if (shape.path2d) { + return shape.path2d; + } + if ("svgpath" in shape) { + shape.path2d = new Path2D(shape.svgpath); + } else { + var path = new Path2D(); + for (var polygon of shape.polygons) { + path.moveTo(...polygon[0]); + for (var i = 1; i < polygon.length; i++) { + path.lineTo(...polygon[i]); + } + path.closePath(); + } + shape.path2d = path; + } + return shape.path2d; +} + +function drawPolygonShape(ctx, shape, color) { + ctx.save(); + ctx.fillStyle = color; + if (!("svgpath" in shape)) { + ctx.translate(...shape.pos); + ctx.rotate(deg2rad(-shape.angle)); + } + ctx.fill(getPolygonsPath(shape)); + ctx.restore(); +} + +function drawDrawing(ctx, scalefactor, drawing, color) { + if (["segment", "arc", "circle", "curve"].includes(drawing.type)) { + drawedge(ctx, scalefactor, drawing, color); + } else if (drawing.type == "polygon") { + drawPolygonShape(ctx, drawing, color); + } else { + drawText(ctx, drawing, color); + } +} + +function getCirclePath(radius) { + var path = new Path2D(); + path.arc(0, 0, radius, 0, 2 * Math.PI); + path.closePath(); + return path; +} + +function getCachedPadPath(pad) { + if (!pad.path2d) { + // if path2d is not set, build one and cache it on pad object + if (pad.shape == "rect") { + pad.path2d = new Path2D(); + pad.path2d.rect(...pad.size.map(c => -c * 0.5), ...pad.size); + } else if (pad.shape == "oval") { + pad.path2d = getOblongPath(pad.size); + } else if (pad.shape == "circle") { + pad.path2d = getCirclePath(pad.size[0] / 2); + } else if (pad.shape == "roundrect") { + pad.path2d = getChamferedRectPath(pad.size, pad.radius, 0, 0); + } else if (pad.shape == "chamfrect") { + pad.path2d = getChamferedRectPath(pad.size, pad.radius, pad.chamfpos, pad.chamfratio) + } else if (pad.shape == "custom") { + pad.path2d = getPolygonsPath(pad); + } + } + return pad.path2d; +} + +function drawPad(ctx, pad, color, outline, hole) { + ctx.save(); + ctx.translate(...pad.pos); + ctx.rotate(deg2rad(pad.angle)); + if (pad.offset) { + ctx.translate(...pad.offset); + } + ctx.fillStyle = color; + ctx.strokeStyle = color; + var path = getCachedPadPath(pad); + if (outline) { + ctx.stroke(path); + } else { + ctx.fill(path); + } + if (pad.type == "th" && hole) { + if (pad.offset) { + ctx.translate(-pad.offset[0], -pad.offset[1]); + } + ctx.fillStyle = "#CCCCCC"; + if (pad.drillshape == "oblong") { + ctx.fill(getOblongPath(pad.drillsize)); + } else { + ctx.fill(getCirclePath(pad.drillsize[0] / 2)); + } + } + ctx.restore(); +} + +function drawFootprint(ctx, layer, scalefactor, footprint, padcolor, outlinecolor, highlight, outline) { + if (highlight) { + // draw bounding box + if (footprint.layer == layer) { + ctx.save(); + ctx.globalAlpha = 0.2; + ctx.translate(...footprint.bbox.pos); + ctx.rotate(deg2rad(-footprint.bbox.angle)); + ctx.translate(...footprint.bbox.relpos); + ctx.fillStyle = padcolor; + ctx.fillRect(0, 0, ...footprint.bbox.size); + ctx.globalAlpha = 1; + ctx.strokeStyle = padcolor; + ctx.strokeRect(0, 0, ...footprint.bbox.size); + ctx.restore(); + } + } + // draw drawings + for (var drawing of footprint.drawings) { + if (drawing.layer == layer) { + drawDrawing(ctx, scalefactor, drawing.drawing, padcolor); + } + } + // draw pads + if (settings.renderPads) { + for (var pad of footprint.pads) { + if (pad.layers.includes(layer)) { + drawPad(ctx, pad, padcolor, outline, true); + if (pad.pin1 && settings.highlightpin1) { + drawPad(ctx, pad, outlinecolor, true, false); + } + } + } + } +} + +function drawEdgeCuts(canvas, scalefactor) { + var ctx = canvas.getContext("2d"); + var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color'); + for (var edge of pcbdata.edges) { + drawedge(ctx, scalefactor, edge, edgecolor); + } +} + +function drawFootprints(canvas, layer, scalefactor, highlight) { + var ctx = canvas.getContext("2d"); + ctx.lineWidth = 3 / scalefactor; + var style = getComputedStyle(topmostdiv); + var padcolor = style.getPropertyValue('--pad-color'); + var outlinecolor = style.getPropertyValue('--pin1-outline-color'); + if (highlight) { + padcolor = style.getPropertyValue('--pad-color-highlight'); + outlinecolor = style.getPropertyValue('--pin1-outline-color-highlight'); + } + for (var i = 0; i < pcbdata.footprints.length; i++) { + var mod = pcbdata.footprints[i]; + var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i); + if (!highlight || highlightedFootprints.includes(i)) { + drawFootprint(ctx, layer, scalefactor, mod, padcolor, outlinecolor, highlight, outline); + } + } +} + +function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) { + var ctx = canvas.getContext("2d"); + for (var d of pcbdata[layername][layer]) { + if (["segment", "arc", "circle", "curve", "rect"].includes(d.type)) { + drawedge(ctx, scalefactor, d, edgeColor); + } else if (d.type == "polygon") { + drawPolygonShape(ctx, d, polygonColor); + } else { + drawText(ctx, d, textColor); + } + } +} + +function drawTracks(canvas, layer, color, highlight) { + ctx = canvas.getContext("2d"); + ctx.strokeStyle = color; + ctx.lineCap = "round"; + for(var track of pcbdata.tracks[layer]) { + if (highlight && highlightedNet != track.net) continue; + ctx.lineWidth = track.width; + ctx.beginPath(); + ctx.moveTo(...track.start); + ctx.lineTo(...track.end); + ctx.stroke(); + } +} + +function drawZones(canvas, layer, color, highlight) { + ctx = canvas.getContext("2d"); + ctx.strokeStyle = color; + ctx.fillStyle = color; + ctx.lineJoin = "round"; + for(var zone of pcbdata.zones[layer]) { + if (!zone.path2d) { + zone.path2d = getPolygonsPath(zone); + } + if (highlight && highlightedNet != zone.net) continue; + ctx.fill(zone.path2d); + if (zone.width > 0) { + ctx.lineWidth = zone.width; + ctx.stroke(zone.path2d); + } + } +} + +function clearCanvas(canvas, color = null) { + var ctx = canvas.getContext("2d"); + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + if (color) { + ctx.fillStyle = color; + ctx.fillRect(0, 0, canvas.width, canvas.height); + } else { + ctx.clearRect(0, 0, canvas.width, canvas.height); + } + ctx.restore(); +} + +function drawNets(canvas, layer, highlight) { + var style = getComputedStyle(topmostdiv); + if (settings.renderTracks) { + var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color'); + drawTracks(canvas, layer, trackColor, highlight); + } + if (settings.renderZones) { + var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color'); + drawZones(canvas, layer, zoneColor, highlight); + } + if (highlight && settings.renderPads) { + var padColor = style.getPropertyValue('--pad-color-highlight'); + var ctx = canvas.getContext("2d"); + for (var footprint of pcbdata.footprints) { + // draw pads + for (var pad of footprint.pads) { + if (highlightedNet != pad.net) continue; + if (pad.layers.includes(layer)) { + drawPad(ctx, pad, padColor, false, true); + } + } + } + } +} + +function drawHighlightsOnLayer(canvasdict, clear = true) { + if (clear) { + clearCanvas(canvasdict.highlight); + } + if (highlightedFootprints.length > 0) { + drawFootprints(canvasdict.highlight, canvasdict.layer, + canvasdict.transform.s * canvasdict.transform.zoom, true); + } + if (highlightedNet !== null) { + drawNets(canvasdict.highlight, canvasdict.layer, true); + } +} + +function drawHighlights() { + drawHighlightsOnLayer(allcanvas.front); + drawHighlightsOnLayer(allcanvas.back); +} + +function drawBackground(canvasdict, clear = true) { + if (clear) { + clearCanvas(canvasdict.bg); + clearCanvas(canvasdict.fab); + clearCanvas(canvasdict.silk); + } + + drawNets(canvasdict.bg, canvasdict.layer, false); + drawFootprints(canvasdict.bg, canvasdict.layer, + canvasdict.transform.s * canvasdict.transform.zoom, false); + + drawEdgeCuts(canvasdict.bg, canvasdict.transform.s); + + var style = getComputedStyle(topmostdiv); + var edgeColor = style.getPropertyValue('--silkscreen-edge-color'); + var polygonColor = style.getPropertyValue('--silkscreen-polygon-color'); + var textColor = style.getPropertyValue('--silkscreen-text-color'); + if (settings.renderSilkscreen) { + drawBgLayer( + "silkscreen", canvasdict.silk, canvasdict.layer, + canvasdict.transform.s * canvasdict.transform.zoom, + edgeColor, polygonColor, textColor); + } + edgeColor = style.getPropertyValue('--fabrication-edge-color'); + polygonColor = style.getPropertyValue('--fabrication-polygon-color'); + textColor = style.getPropertyValue('--fabrication-text-color'); + if (settings.renderFabrication) { + drawBgLayer( + "fabrication", canvasdict.fab, canvasdict.layer, + canvasdict.transform.s * canvasdict.transform.zoom, + edgeColor, polygonColor, textColor); + } +} + +function prepareCanvas(canvas, flip, transform) { + var ctx = canvas.getContext("2d"); + ctx.setTransform(1, 0, 0, 1, 0, 0); + var fontsize = 1.55; + ctx.scale(transform.zoom, transform.zoom); + ctx.translate(transform.panx, transform.pany); + if (flip) { + ctx.scale(-1, 1); + } + ctx.translate(transform.x, transform.y); + ctx.rotate(deg2rad(settings.boardRotation)); + ctx.scale(transform.s, transform.s); +} + +function prepareLayer(canvasdict) { + var flip = (canvasdict.layer == "B"); + for (var c of ["bg", "fab", "silk", "highlight"]) { + prepareCanvas(canvasdict[c], flip, canvasdict.transform); + } +} + +function rotateVector(v, angle) { + angle = deg2rad(angle); + return [ + v[0] * Math.cos(angle) - v[1] * Math.sin(angle), + v[0] * Math.sin(angle) + v[1] * Math.cos(angle) + ]; +} + +function applyRotation(bbox) { + var corners = [ + [bbox.minx, bbox.miny], + [bbox.minx, bbox.maxy], + [bbox.maxx, bbox.miny], + [bbox.maxx, bbox.maxy], + ]; + corners = corners.map((v) => rotateVector(v, settings.boardRotation)); + return { + minx: corners.reduce((a, v) => Math.min(a, v[0]), Infinity), + miny: corners.reduce((a, v) => Math.min(a, v[1]), Infinity), + maxx: corners.reduce((a, v) => Math.max(a, v[0]), -Infinity), + maxy: corners.reduce((a, v) => Math.max(a, v[1]), -Infinity), + } +} + +function recalcLayerScale(layerdict, width, height) { + var bbox = applyRotation(pcbdata.edges_bbox); + var scalefactor = 0.98 * Math.min( + width / (bbox.maxx - bbox.minx), + height / (bbox.maxy - bbox.miny) + ); + if (scalefactor < 0.1) { + scalefactor = 1; + } + layerdict.transform.s = scalefactor; + var flip = (layerdict.layer == "B"); + if (flip) { + layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor + width) * 0.5; + } else { + layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor - width) * 0.5; + } + layerdict.transform.y = -((bbox.maxy + bbox.miny) * scalefactor - height) * 0.5; + for (var c of ["bg", "fab", "silk", "highlight"]) { + canvas = layerdict[c]; + canvas.width = width; + canvas.height = height; + canvas.style.width = (width / devicePixelRatio) + "px"; + canvas.style.height = (height / devicePixelRatio) + "px"; + } +} + +function redrawCanvas(layerdict) { + prepareLayer(layerdict); + drawBackground(layerdict); + drawHighlightsOnLayer(layerdict); +} + +function resizeCanvas(layerdict) { + var canvasdivid = { + "F": "frontcanvas", + "B": "backcanvas" + } [layerdict.layer]; + var width = document.getElementById(canvasdivid).clientWidth * devicePixelRatio; + var height = document.getElementById(canvasdivid).clientHeight * devicePixelRatio; + recalcLayerScale(layerdict, width, height); + redrawCanvas(layerdict); +} + +function resizeAll() { + resizeCanvas(allcanvas.front); + resizeCanvas(allcanvas.back); +} + +function pointWithinDistanceToSegment(x, y, x1, y1, x2, y2, d) { + var A = x - x1; + var B = y - y1; + var C = x2 - x1; + var D = y2 - y1; + + var dot = A * C + B * D; + var len_sq = C * C + D * D; + var dx, dy; + if (len_sq == 0) { + // start and end of the segment coincide + dx = x - x1; + dy = y - y1; + } else { + var param = dot / len_sq; + var xx, yy; + if (param < 0) { + xx = x1; + yy = y1; + } else if (param > 1) { + xx = x2; + yy = y2; + } else { + xx = x1 + param * C; + yy = y1 + param * D; + } + dx = x - xx; + dy = y - yy; + } + return dx * dx + dy * dy <= d * d; +} + +function pointWithinPad(x, y, pad) { + var v = [x - pad.pos[0], y - pad.pos[1]]; + v = rotateVector(v, -pad.angle); + if (pad.offset) { + v[0] -= pad.offset[0]; + v[1] -= pad.offset[1]; + } + return emptyContext2d.isPointInPath(getCachedPadPath(pad), ...v); +} + +function netHitScan(layer, x, y) { + // Check track segments + if (settings.renderTracks && pcbdata.tracks) { + for(var track of pcbdata.tracks[layer]) { + if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) { + return track.net; + } + } + } + // Check pads + if (settings.renderPads) { + for (var footprint of pcbdata.footprints) { + for(var pad of footprint.pads) { + if (pad.layers.includes(layer) && pointWithinPad(x, y, pad)) { + return pad.net; + } + } + } + } + return null; +} + +function pointWithinFootprintBbox(x, y, bbox) { + var v = [x - bbox.pos[0], y - bbox.pos[1]]; + v = rotateVector(v, bbox.angle); + return bbox.relpos[0] <= v[0] && v[0] <= bbox.relpos[0] + bbox.size[0] && + bbox.relpos[1] <= v[1] && v[1] <= bbox.relpos[1] + bbox.size[1]; +} + +function bboxHitScan(layer, x, y) { + var result = []; + for (var i = 0; i < pcbdata.footprints.length; i++) { + var footprint = pcbdata.footprints[i]; + if (footprint.layer == layer) { + if (pointWithinFootprintBbox(x, y, footprint.bbox)) { + result.push(i); + } + } + } + return result; +} + +function handlePointerDown(e, layerdict) { + if (e.button != 0 && e.button != 1) { + return; + } + e.preventDefault(); + e.stopPropagation(); + + if (!e.hasOwnProperty("offsetX")) { + // The polyfill doesn't set this properly + e.offsetX = e.pageX - e.currentTarget.offsetLeft; + e.offsetY = e.pageY - e.currentTarget.offsetTop; + } + + layerdict.pointerStates[e.pointerId] = { + distanceTravelled: 0, + lastX: e.offsetX, + lastY: e.offsetY, + downTime: Date.now(), + }; +} + +function handleMouseClick(e, layerdict) { + if (!e.hasOwnProperty("offsetX")) { + // The polyfill doesn't set this properly + e.offsetX = e.pageX - e.currentTarget.offsetLeft; + e.offsetY = e.pageY - e.currentTarget.offsetTop; + } + + var x = e.offsetX; + var y = e.offsetY; + var t = layerdict.transform; + if (layerdict.layer == "B") { + x = (devicePixelRatio * x / t.zoom - t.panx + t.x) / -t.s; + } else { + x = (devicePixelRatio * x / t.zoom - t.panx - t.x) / t.s; + } + y = (devicePixelRatio * y / t.zoom - t.y - t.pany) / t.s; + var v = rotateVector([x, y], -settings.boardRotation); + if ("nets" in pcbdata) { + var net = netHitScan(layerdict.layer, ...v); + if (net !== highlightedNet) { + netClicked(net); + } + } + if (highlightedNet === null) { + var footprints = bboxHitScan(layerdict.layer, ...v); + if (footprints.length > 0) { + footprintsClicked(footprints); + } + } +} + +function handlePointerLeave(e, layerdict) { + e.preventDefault(); + e.stopPropagation(); + + if (!settings.redrawOnDrag) { + redrawCanvas(layerdict); + } + + delete layerdict.pointerStates[e.pointerId]; +} + +function resetTransform(layerdict) { + layerdict.transform.panx = 0; + layerdict.transform.pany = 0; + layerdict.transform.zoom = 1; + redrawCanvas(layerdict); +} + +function handlePointerUp(e, layerdict) { + if (!e.hasOwnProperty("offsetX")) { + // The polyfill doesn't set this properly + e.offsetX = e.pageX - e.currentTarget.offsetLeft; + e.offsetY = e.pageY - e.currentTarget.offsetTop; + } + + e.preventDefault(); + e.stopPropagation(); + + if (e.button == 2) { + // Reset pan and zoom on right click. + resetTransform(layerdict); + layerdict.anotherPointerTapped = false; + return; + } + + // We haven't necessarily had a pointermove event since the interaction started, so make sure we update this now + var ptr = layerdict.pointerStates[e.pointerId]; + ptr.distanceTravelled += Math.abs(e.offsetX - ptr.lastX) + Math.abs(e.offsetY - ptr.lastY); + + if (e.button == 0 && ptr.distanceTravelled < 10 && Date.now() - ptr.downTime <= 500) { + if (Object.keys(layerdict.pointerStates).length == 1) { + if (layerdict.anotherPointerTapped) { + // This is the second pointer coming off of a two-finger tap + resetTransform(layerdict); + } else { + // This is just a regular tap + handleMouseClick(e, layerdict); + } + layerdict.anotherPointerTapped = false; + } else { + // This is the first finger coming off of what could become a two-finger tap + layerdict.anotherPointerTapped = true; + } + } else { + if (!settings.redrawOnDrag) { + redrawCanvas(layerdict); + } + layerdict.anotherPointerTapped = false; + } + + delete layerdict.pointerStates[e.pointerId]; +} + +function handlePointerMove(e, layerdict) { + if (!layerdict.pointerStates.hasOwnProperty(e.pointerId)) { + return; + } + e.preventDefault(); + e.stopPropagation(); + + if (!e.hasOwnProperty("offsetX")) { + // The polyfill doesn't set this properly + e.offsetX = e.pageX - e.currentTarget.offsetLeft; + e.offsetY = e.pageY - e.currentTarget.offsetTop; + } + + var thisPtr = layerdict.pointerStates[e.pointerId]; + + var dx = e.offsetX - thisPtr.lastX; + var dy = e.offsetY - thisPtr.lastY; + + // If this number is low on pointer up, we count the action as a click + thisPtr.distanceTravelled += Math.abs(dx) + Math.abs(dy); + + if (Object.keys(layerdict.pointerStates).length == 1) { + // This is a simple drag + layerdict.transform.panx += devicePixelRatio * dx / layerdict.transform.zoom; + layerdict.transform.pany += devicePixelRatio * dy / layerdict.transform.zoom; + } else if (Object.keys(layerdict.pointerStates).length == 2) { + var otherPtr = Object.values(layerdict.pointerStates).filter((ptr) => ptr != thisPtr)[0]; + + var oldDist = Math.sqrt(Math.pow(thisPtr.lastX - otherPtr.lastX, 2) + Math.pow(thisPtr.lastY - otherPtr.lastY, 2)); + var newDist = Math.sqrt(Math.pow(e.offsetX - otherPtr.lastX, 2) + Math.pow(e.offsetY - otherPtr.lastY, 2)); + + var scaleFactor = newDist/oldDist; + + if (scaleFactor != NaN) { + layerdict.transform.zoom *= scaleFactor; + + var zoomd = (1 - scaleFactor) / layerdict.transform.zoom; + layerdict.transform.panx += devicePixelRatio * otherPtr.lastX * zoomd; + layerdict.transform.pany += devicePixelRatio * otherPtr.lastY * zoomd; + } + } + + thisPtr.lastX = e.offsetX; + thisPtr.lastY = e.offsetY; + + if (settings.redrawOnDrag) { + redrawCanvas(layerdict); + } +} + +function handleMouseWheel(e, layerdict) { + e.preventDefault(); + e.stopPropagation(); + var t = layerdict.transform; + var wheeldelta = e.deltaY; + if (e.deltaMode == 1) { + // FF only, scroll by lines + wheeldelta *= 30; + } else if (e.deltaMode == 2) { + wheeldelta *= 300; + } + var m = Math.pow(1.1, -wheeldelta / 40); + // Limit amount of zoom per tick. + if (m > 2) { + m = 2; + } else if (m < 0.5) { + m = 0.5; + } + t.zoom *= m; + var zoomd = (1 - m) / t.zoom; + t.panx += devicePixelRatio * e.offsetX * zoomd; + t.pany += devicePixelRatio * e.offsetY * zoomd; + redrawCanvas(layerdict); +} + +function addMouseHandlers(div, layerdict) { + div.addEventListener("pointerdown", function(e) { + handlePointerDown(e, layerdict); + }); + div.addEventListener("pointermove", function(e) { + handlePointerMove(e, layerdict); + }); + div.addEventListener("pointerup", function(e) { + handlePointerUp(e, layerdict); + }); + var pointerleave = function(e) { + handlePointerLeave(e, layerdict); + } + div.addEventListener("pointercancel", pointerleave); + div.addEventListener("pointerleave", pointerleave); + div.addEventListener("pointerout", pointerleave); + + div.onwheel = function(e) { + handleMouseWheel(e, layerdict); + } + for (var element of [div, layerdict.bg, layerdict.fab, layerdict.silk, layerdict.highlight]) { + element.addEventListener("contextmenu", function(e) { + e.preventDefault(); + }, false); + } +} + +function setRedrawOnDrag(value) { + settings.redrawOnDrag = value; + writeStorage("redrawOnDrag", value); +} + +function setBoardRotation(value) { + settings.boardRotation = value * 5; + writeStorage("boardRotation", settings.boardRotation); + document.getElementById("rotationDegree").textContent = settings.boardRotation; + resizeAll(); +} + +function initRender() { + allcanvas = { + front: { + transform: { + x: 0, + y: 0, + s: 1, + panx: 0, + pany: 0, + zoom: 1, + }, + pointerStates: {}, + anotherPointerTapped: false, + bg: document.getElementById("F_bg"), + fab: document.getElementById("F_fab"), + silk: document.getElementById("F_slk"), + highlight: document.getElementById("F_hl"), + layer: "F", + }, + back: { + transform: { + x: 0, + y: 0, + s: 1, + panx: 0, + pany: 0, + zoom: 1, + }, + pointerStates: {}, + anotherPointerTapped: false, + bg: document.getElementById("B_bg"), + fab: document.getElementById("B_fab"), + silk: document.getElementById("B_slk"), + highlight: document.getElementById("B_hl"), + layer: "B", + } + }; + addMouseHandlers(document.getElementById("frontcanvas"), allcanvas.front); + addMouseHandlers(document.getElementById("backcanvas"), allcanvas.back); +} + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +/* DOM manipulation and misc code */ + +var bomsplit; +var canvassplit; +var initDone = false; +var bomSortFunction = null; +var currentSortColumn = null; +var currentSortOrder = null; +var currentHighlightedRowId; +var highlightHandlers = []; +var footprintIndexToHandler = {}; +var netsToHandler = {}; +var highlightedFootprints = []; +var highlightedNet = null; +var lastClicked; + +function dbg(html) { + dbgdiv.innerHTML = html; +} + +function redrawIfInitDone() { + if (initDone) { + redrawCanvas(allcanvas.front); + redrawCanvas(allcanvas.back); + } +} + +function padsVisible(value) { + writeStorage("padsVisible", value); + settings.renderPads = value; + redrawIfInitDone(); +} + +function referencesVisible(value) { + writeStorage("referencesVisible", value); + settings.renderReferences = value; + redrawIfInitDone(); +} + +function valuesVisible(value) { + writeStorage("valuesVisible", value); + settings.renderValues = value; + redrawIfInitDone(); +} + +function tracksVisible(value) { + writeStorage("tracksVisible", value); + settings.renderTracks = value; + redrawIfInitDone(); +} + +function zonesVisible(value) { + writeStorage("zonesVisible", value); + settings.renderZones = value; + redrawIfInitDone(); +} + +function dnpOutline(value) { + writeStorage("dnpOutline", value); + settings.renderDnpOutline = value; + redrawIfInitDone(); +} + +function setDarkMode(value) { + if (value) { + topmostdiv.classList.add("dark"); + } else { + topmostdiv.classList.remove("dark"); + } + writeStorage("darkmode", value); + settings.darkMode = value; + redrawIfInitDone(); +} + +function setFullscreen(value) { + if (value) { + document.documentElement.requestFullscreen(); + } else { + document.exitFullscreen(); + } +} + +function fabricationVisible(value) { + writeStorage("fabricationVisible", value); + settings.renderFabrication = value; + redrawIfInitDone(); +} + +function silkscreenVisible(value) { + writeStorage("silkscreenVisible", value); + settings.renderSilkscreen = value; + redrawIfInitDone(); +} + +function setHighlightPin1(value) { + writeStorage("highlightpin1", value); + settings.highlightpin1 = value; + redrawIfInitDone(); +} + +function getStoredCheckboxRefs(checkbox) { + function convert(ref) { + var intref = parseInt(ref); + if (isNaN(intref)) { + for (var i = 0; i < pcbdata.footprints.length; i++) { + if (pcbdata.footprints[i].ref == ref) { + return i; + } + } + return -1; + } else { + return intref; + } + } + if (!(checkbox in settings.checkboxStoredRefs)) { + var val = readStorage("checkbox_" + checkbox); + settings.checkboxStoredRefs[checkbox] = val ? val : ""; + } + if (!settings.checkboxStoredRefs[checkbox]) { + return new Set(); + } else { + return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0)); + } +} + +function getCheckboxState(checkbox, references) { + var storedRefsSet = getStoredCheckboxRefs(checkbox); + var currentRefsSet = new Set(references.map(r => r[1])); + // Get difference of current - stored + var difference = new Set(currentRefsSet); + for (ref of storedRefsSet) { + difference.delete(ref); + } + if (difference.size == 0) { + // All the current refs are stored + return "checked"; + } else if (difference.size == currentRefsSet.size) { + // None of the current refs are stored + return "unchecked"; + } else { + // Some of the refs are stored + return "indeterminate"; + } +} + +function setBomCheckboxState(checkbox, element, references) { + var state = getCheckboxState(checkbox, references); + element.checked = (state == "checked"); + element.indeterminate = (state == "indeterminate"); +} + +function createCheckboxChangeHandler(checkbox, references, row) { + return function() { + refsSet = getStoredCheckboxRefs(checkbox); + var darkenWhenChecked = settings.darkenWhenChecked == checkbox; + eventArgs = { + checkbox: checkbox, + refs: references, + } + if (this.checked) { + // checkbox ticked + for (var ref of references) { + refsSet.add(ref[1]); + } + if (darkenWhenChecked) { + row.classList.add("checked"); + } + eventArgs.state = 'checked'; + } else { + // checkbox unticked + for (var ref of references) { + refsSet.delete(ref[1]); + } + if (darkenWhenChecked) { + row.classList.remove("checked"); + } + eventArgs.state = 'unchecked'; + } + settings.checkboxStoredRefs[checkbox] = [...refsSet].join(","); + writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]); + updateCheckboxStats(checkbox); + EventHandler.emitEvent(IBOM_EVENT_TYPES.CHECKBOX_CHANGE_EVENT, eventArgs); + } +} + +function clearHighlightedFootprints() { + if (currentHighlightedRowId) { + document.getElementById(currentHighlightedRowId).classList.remove("highlighted"); + currentHighlightedRowId = null; + highlightedFootprints = []; + highlightedNet = null; + } +} + +function createRowHighlightHandler(rowid, refs, net) { + return function() { + if (currentHighlightedRowId) { + if (currentHighlightedRowId == rowid) { + return; + } + document.getElementById(currentHighlightedRowId).classList.remove("highlighted"); + } + document.getElementById(rowid).classList.add("highlighted"); + currentHighlightedRowId = rowid; + highlightedFootprints = refs ? refs.map(r => r[1]) : []; + highlightedNet = net; + drawHighlights(); + EventHandler.emitEvent( + IBOM_EVENT_TYPES.HIGHLIGHT_EVENT, + { + rowid: rowid, + refs: refs, + net: net + }); + } +} + +function entryMatches(entry) { + if (settings.bommode == "netlist") { + // entry is just a net name + return entry.toLowerCase().indexOf(filter) >= 0; + } + // check refs + for (var ref of entry[3]) { + if (ref[0].toLowerCase().indexOf(filter) >= 0) { + return true; + } + } + // check extra fields + for (var i in config.extra_fields) { + if (entry[4][i].toLowerCase().indexOf(filter) >= 0) { + return true; + } + } + // check value + if (entry[1].toLowerCase().indexOf(filter) >= 0) { + return true; + } + // check footprint + if (entry[2].toLowerCase().indexOf(filter) >= 0) { + return true; + } + return false; +} + +function findRefInEntry(entry) { + return entry[3].filter(r => r[0].toLowerCase() == reflookup); +} + +function highlightFilter(s) { + if (!filter) { + return s; + } + var parts = s.toLowerCase().split(filter); + if (parts.length == 1) { + return s; + } + var r = ""; + var pos = 0; + for (var i in parts) { + if (i > 0) { + r += '<mark class="highlight">' + + s.substring(pos, pos + filter.length) + + '</mark>'; + pos += filter.length; + } + r += s.substring(pos, pos + parts[i].length); + pos += parts[i].length; + } + return r; +} + +function checkboxSetUnsetAllHandler(checkboxname) { + return function() { + var checkboxnum = 0; + while (checkboxnum < settings.checkboxes.length && + settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) { + checkboxnum++; + } + if (checkboxnum >= settings.checkboxes.length) { + return; + } + var allset = true; + var checkbox; + var row; + for (row of bombody.childNodes) { + checkbox = row.childNodes[checkboxnum + 1].childNodes[0]; + if (!checkbox.checked || checkbox.indeterminate) { + allset = false; + break; + } + } + for (row of bombody.childNodes) { + checkbox = row.childNodes[checkboxnum + 1].childNodes[0]; + checkbox.checked = !allset; + checkbox.indeterminate = false; + checkbox.onchange(); + } + } +} + +function createColumnHeader(name, cls, comparator) { + var th = document.createElement("TH"); + th.innerHTML = name; + th.classList.add(cls); + th.style.cursor = "pointer"; + var span = document.createElement("SPAN"); + span.classList.add("sortmark"); + span.classList.add("none"); + th.appendChild(span); + th.onclick = function() { + if (currentSortColumn && this !== currentSortColumn) { + // Currently sorted by another column + currentSortColumn.childNodes[1].classList.remove(currentSortOrder); + currentSortColumn.childNodes[1].classList.add("none"); + currentSortColumn = null; + currentSortOrder = null; + } + if (currentSortColumn && this === currentSortColumn) { + // Already sorted by this column + if (currentSortOrder == "asc") { + // Sort by this column, descending order + bomSortFunction = function(a, b) { + return -comparator(a, b); + } + currentSortColumn.childNodes[1].classList.remove("asc"); + currentSortColumn.childNodes[1].classList.add("desc"); + currentSortOrder = "desc"; + } else { + // Unsort + bomSortFunction = null; + currentSortColumn.childNodes[1].classList.remove("desc"); + currentSortColumn.childNodes[1].classList.add("none"); + currentSortColumn = null; + currentSortOrder = null; + } + } else { + // Sort by this column, ascending order + bomSortFunction = comparator; + currentSortColumn = this; + currentSortColumn.childNodes[1].classList.remove("none"); + currentSortColumn.childNodes[1].classList.add("asc"); + currentSortOrder = "asc"; + } + populateBomBody(); + } + return th; +} + +function populateBomHeader() { + while (bomhead.firstChild) { + bomhead.removeChild(bomhead.firstChild); + } + var tr = document.createElement("TR"); + var th = document.createElement("TH"); + th.classList.add("numCol"); + tr.appendChild(th); + var checkboxCompareClosure = function(checkbox) { + return (a, b) => { + var stateA = getCheckboxState(checkbox, a[3]); + var stateB = getCheckboxState(checkbox, b[3]); + if (stateA > stateB) return -1; + if (stateA < stateB) return 1; + return 0; + } + } + if (settings.bommode == "netlist") { + th = createColumnHeader("Net name", "bom-netname", (a, b) => { + if (a > b) return -1; + if (a < b) return 1; + return 0; + }); + tr.appendChild(th); + } else { + for (var checkbox of settings.checkboxes) { + th = createColumnHeader( + checkbox, "bom-checkbox", checkboxCompareClosure(checkbox)); + th.onclick = fancyDblClickHandler( + th, th.onclick.bind(th), checkboxSetUnsetAllHandler(checkbox)); + tr.appendChild(th); + } + tr.appendChild(createColumnHeader("References", "References", (a, b) => { + var i = 0; + while (i < a[3].length && i < b[3].length) { + if (a[3][i] != b[3][i]) return a[3][i] > b[3][i] ? 1 : -1; + i++; + } + return a[3].length - b[3].length; + })); + // Extra fields + if (config.extra_fields.length > 0) { + var extraFieldCompareClosure = function(fieldIndex) { + return (a, b) => { + var fa = a[4][fieldIndex]; + var fb = b[4][fieldIndex]; + if (fa != fb) return fa > fb ? 1 : -1; + else return 0; + } + } + for (var i in config.extra_fields) { + tr.appendChild(createColumnHeader( + config.extra_fields[i], "extra", extraFieldCompareClosure(i))); + } + } + tr.appendChild(createColumnHeader("Value", "Value", (a, b) => { + return valueCompare(a[5], b[5], a[1], b[1]); + })); + tr.appendChild(createColumnHeader("Footprint", "Footprint", (a, b) => { + if (a[2] != b[2]) return a[2] > b[2] ? 1 : -1; + else return 0; + })); + if (settings.bommode == "grouped") { + tr.appendChild(createColumnHeader("Quantity", "Quantity", (a, b) => { + return a[3].length - b[3].length; + })); + } + } + bomhead.appendChild(tr); +} + +function populateBomBody() { + while (bom.firstChild) { + bom.removeChild(bom.firstChild); + } + highlightHandlers = []; + footprintIndexToHandler = {}; + netsToHandler = {}; + currentHighlightedRowId = null; + var first = true; + if (settings.bommode == "netlist") { + bomtable = pcbdata.nets.slice(); + } else { + switch (settings.canvaslayout) { + case 'F': + bomtable = pcbdata.bom.F.slice(); + break; + case 'FB': + bomtable = pcbdata.bom.both.slice(); + break; + case 'B': + bomtable = pcbdata.bom.B.slice(); + break; + } + if (settings.bommode == "ungrouped") { + // expand bom table + expandedTable = [] + for (var bomentry of bomtable) { + for (var ref of bomentry[3]) { + expandedTable.push([1, bomentry[1], bomentry[2], [ref], bomentry[4], bomentry[5]]); + } + } + bomtable = expandedTable; + } + } + if (bomSortFunction) { + bomtable = bomtable.sort(bomSortFunction); + } + for (var i in bomtable) { + var bomentry = bomtable[i]; + if (filter && !entryMatches(bomentry)) { + continue; + } + var references = null; + var netname = null; + var tr = document.createElement("TR"); + var td = document.createElement("TD"); + var rownum = +i + 1; + tr.id = "bomrow" + rownum; + td.textContent = rownum; + tr.appendChild(td); + if (settings.bommode == "netlist") { + netname = bomentry; + td = document.createElement("TD"); + td.innerHTML = highlightFilter(netname ? netname : "<no net>"); + tr.appendChild(td); + } else { + if (reflookup) { + references = findRefInEntry(bomentry); + if (references.length == 0) { + continue; + } + } else { + references = bomentry[3]; + } + // Checkboxes + for (var checkbox of settings.checkboxes) { + if (checkbox) { + td = document.createElement("TD"); + var input = document.createElement("input"); + input.type = "checkbox"; + input.onchange = createCheckboxChangeHandler(checkbox, references, tr); + setBomCheckboxState(checkbox, input, references); + if (input.checked && settings.darkenWhenChecked == checkbox) { + tr.classList.add("checked"); + } + td.appendChild(input); + tr.appendChild(td); + } + } + // References + td = document.createElement("TD"); + td.innerHTML = highlightFilter(references.map(r => r[0]).join(", ")); + tr.appendChild(td); + // Extra fields + for (var i in config.extra_fields) { + td = document.createElement("TD"); + td.innerHTML = highlightFilter(bomentry[4][i]); + tr.appendChild(td); + } + // Value + td = document.createElement("TD"); + td.innerHTML = highlightFilter(bomentry[1]); + tr.appendChild(td); + // Footprint + td = document.createElement("TD"); + td.innerHTML = highlightFilter(bomentry[2]); + tr.appendChild(td); + if (settings.bommode == "grouped") { + // Quantity + td = document.createElement("TD"); + td.textContent = bomentry[3].length; + tr.appendChild(td); + } + } + bom.appendChild(tr); + var handler = createRowHighlightHandler(tr.id, references, netname); + tr.onmousemove = handler; + highlightHandlers.push({ + id: tr.id, + handler: handler, + }); + if (references !== null) { + for (var refIndex of references.map(r => r[1])) { + footprintIndexToHandler[refIndex] = handler; + } + } + if (netname !== null) { + netsToHandler[netname] = handler; + } + if ((filter || reflookup) && first) { + handler(); + first = false; + } + } + EventHandler.emitEvent( + IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT, + { + filter: filter, + reflookup: reflookup, + checkboxes: settings.checkboxes, + bommode: settings.bommode, + }); +} + +function highlightPreviousRow() { + if (!currentHighlightedRowId) { + highlightHandlers[highlightHandlers.length - 1].handler(); + } else { + if (highlightHandlers.length > 1 && + highlightHandlers[0].id == currentHighlightedRowId) { + highlightHandlers[highlightHandlers.length - 1].handler(); + } else { + for (var i = 0; i < highlightHandlers.length - 1; i++) { + if (highlightHandlers[i + 1].id == currentHighlightedRowId) { + highlightHandlers[i].handler(); + break; + } + } + } + } + smoothScrollToRow(currentHighlightedRowId); +} + +function highlightNextRow() { + if (!currentHighlightedRowId) { + highlightHandlers[0].handler(); + } else { + if (highlightHandlers.length > 1 && + highlightHandlers[highlightHandlers.length - 1].id == currentHighlightedRowId) { + highlightHandlers[0].handler(); + } else { + for (var i = 1; i < highlightHandlers.length; i++) { + if (highlightHandlers[i - 1].id == currentHighlightedRowId) { + highlightHandlers[i].handler(); + break; + } + } + } + } + smoothScrollToRow(currentHighlightedRowId); +} + +function populateBomTable() { + populateBomHeader(); + populateBomBody(); +} + +function footprintsClicked(footprintIndexes) { + var lastClickedIndex = footprintIndexes.indexOf(lastClicked); + for (var i = 1; i <= footprintIndexes.length; i++) { + var refIndex = footprintIndexes[(lastClickedIndex + i) % footprintIndexes.length]; + if (refIndex in footprintIndexToHandler) { + lastClicked = refIndex; + footprintIndexToHandler[refIndex](); + smoothScrollToRow(currentHighlightedRowId); + break; + } + } +} + +function netClicked(net) { + if (net in netsToHandler) { + netsToHandler[net](); + smoothScrollToRow(currentHighlightedRowId); + } else { + clearHighlightedFootprints(); + highlightedNet = net; + drawHighlights(); + } +} + +function updateFilter(input) { + filter = input.toLowerCase(); + populateBomTable(); +} + +function updateRefLookup(input) { + reflookup = input.toLowerCase(); + populateBomTable(); +} + +function changeCanvasLayout(layout) { + document.getElementById("fl-btn").classList.remove("depressed"); + document.getElementById("fb-btn").classList.remove("depressed"); + document.getElementById("bl-btn").classList.remove("depressed"); + switch (layout) { + case 'F': + document.getElementById("fl-btn").classList.add("depressed"); + if (settings.bomlayout != "bom-only") { + canvassplit.collapse(1); + } + break; + case 'B': + document.getElementById("bl-btn").classList.add("depressed"); + if (settings.bomlayout != "bom-only") { + canvassplit.collapse(0); + } + break; + default: + document.getElementById("fb-btn").classList.add("depressed"); + if (settings.bomlayout != "bom-only") { + canvassplit.setSizes([50, 50]); + } + } + settings.canvaslayout = layout; + writeStorage("canvaslayout", layout); + resizeAll(); + changeBomMode(settings.bommode); +} + +function populateMetadata() { + document.getElementById("title").innerHTML = pcbdata.metadata.title; + document.getElementById("revision").innerHTML = "Rev: " + pcbdata.metadata.revision; + document.getElementById("company").innerHTML = pcbdata.metadata.company; + document.getElementById("filedate").innerHTML = pcbdata.metadata.date; + if (pcbdata.metadata.title != "") { + document.title = pcbdata.metadata.title + " BOM"; + } + // Calculate board stats + var fp_f = 0, fp_b = 0, pads_f = 0, pads_b = 0, pads_th = 0; + for (var i = 0; i < pcbdata.footprints.length; i++) { + if (pcbdata.bom.skipped.includes(i)) continue; + var mod = pcbdata.footprints[i]; + if (mod.layer == "F") { + fp_f++; + } else { + fp_b++; + } + for (var pad of mod.pads) { + if (pad.type == "th") { + pads_th++; + } else { + if (pad.layers.includes("F")) { + pads_f++; + } + if (pad.layers.includes("B")) { + pads_b++; + } + } + } + } + document.getElementById("stats-components-front").innerHTML = fp_f; + document.getElementById("stats-components-back").innerHTML = fp_b; + document.getElementById("stats-components-total").innerHTML = fp_f + fp_b; + document.getElementById("stats-groups-front").innerHTML = pcbdata.bom.F.length; + document.getElementById("stats-groups-back").innerHTML = pcbdata.bom.B.length; + document.getElementById("stats-groups-total").innerHTML = pcbdata.bom.both.length; + document.getElementById("stats-smd-pads-front").innerHTML = pads_f; + document.getElementById("stats-smd-pads-back").innerHTML = pads_b; + document.getElementById("stats-smd-pads-total").innerHTML = pads_f + pads_b; + document.getElementById("stats-th-pads").innerHTML = pads_th; + // Update version string + document.getElementById("github-link").innerHTML = "InteractiveHtmlBom " + + /^v\d+\.\d+/.exec(pcbdata.ibom_version)[0]; +} + +function changeBomLayout(layout) { + document.getElementById("bom-btn").classList.remove("depressed"); + document.getElementById("lr-btn").classList.remove("depressed"); + document.getElementById("tb-btn").classList.remove("depressed"); + switch (layout) { + case 'bom-only': + document.getElementById("bom-btn").classList.add("depressed"); + if (bomsplit) { + bomsplit.destroy(); + bomsplit = null; + canvassplit.destroy(); + canvassplit = null; + } + document.getElementById("frontcanvas").style.display = "none"; + document.getElementById("backcanvas").style.display = "none"; + document.getElementById("bot").style.height = ""; + break; + case 'top-bottom': + document.getElementById("tb-btn").classList.add("depressed"); + document.getElementById("frontcanvas").style.display = ""; + document.getElementById("backcanvas").style.display = ""; + document.getElementById("bot").style.height = "calc(100% - 80px)"; + document.getElementById("bomdiv").classList.remove("split-horizontal"); + document.getElementById("canvasdiv").classList.remove("split-horizontal"); + document.getElementById("frontcanvas").classList.add("split-horizontal"); + document.getElementById("backcanvas").classList.add("split-horizontal"); + if (bomsplit) { + bomsplit.destroy(); + bomsplit = null; + canvassplit.destroy(); + canvassplit = null; + } + bomsplit = Split(['#bomdiv', '#canvasdiv'], { + sizes: [50, 50], + onDragEnd: resizeAll, + direction: "vertical", + gutterSize: 5 + }); + canvassplit = Split(['#frontcanvas', '#backcanvas'], { + sizes: [50, 50], + gutterSize: 5, + onDragEnd: resizeAll + }); + break; + case 'left-right': + document.getElementById("lr-btn").classList.add("depressed"); + document.getElementById("frontcanvas").style.display = ""; + document.getElementById("backcanvas").style.display = ""; + document.getElementById("bot").style.height = "calc(100% - 80px)"; + document.getElementById("bomdiv").classList.add("split-horizontal"); + document.getElementById("canvasdiv").classList.add("split-horizontal"); + document.getElementById("frontcanvas").classList.remove("split-horizontal"); + document.getElementById("backcanvas").classList.remove("split-horizontal"); + if (bomsplit) { + bomsplit.destroy(); + bomsplit = null; + canvassplit.destroy(); + canvassplit = null; + } + bomsplit = Split(['#bomdiv', '#canvasdiv'], { + sizes: [50, 50], + onDragEnd: resizeAll, + gutterSize: 5 + }); + canvassplit = Split(['#frontcanvas', '#backcanvas'], { + sizes: [50, 50], + gutterSize: 5, + direction: "vertical", + onDragEnd: resizeAll + }); + } + settings.bomlayout = layout; + writeStorage("bomlayout", layout); + changeCanvasLayout(settings.canvaslayout); +} + +function changeBomMode(mode) { + document.getElementById("bom-grouped-btn").classList.remove("depressed"); + document.getElementById("bom-ungrouped-btn").classList.remove("depressed"); + document.getElementById("bom-netlist-btn").classList.remove("depressed"); + switch (mode) { + case 'grouped': + document.getElementById("bom-grouped-btn").classList.add("depressed"); + break; + case 'ungrouped': + document.getElementById("bom-ungrouped-btn").classList.add("depressed"); + break; + case 'netlist': + document.getElementById("bom-netlist-btn").classList.add("depressed"); + } + writeStorage("bommode", mode); + if (mode != settings.bommode) { + settings.bommode = mode; + bomSortFunction = null; + currentSortColumn = null; + currentSortOrder = null; + clearHighlightedFootprints(); + } + populateBomTable(); +} + +function focusFilterField() { + focusInputField(document.getElementById("filter")); +} + +function focusRefLookupField() { + focusInputField(document.getElementById("reflookup")); +} + +function toggleBomCheckbox(bomrowid, checkboxnum) { + if (!bomrowid || checkboxnum > settings.checkboxes.length) { + return; + } + var bomrow = document.getElementById(bomrowid); + var checkbox = bomrow.childNodes[checkboxnum].childNodes[0]; + checkbox.checked = !checkbox.checked; + checkbox.indeterminate = false; + checkbox.onchange(); +} + +function checkBomCheckbox(bomrowid, checkboxname) { + var checkboxnum = 0; + while (checkboxnum < settings.checkboxes.length && + settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) { + checkboxnum++; + } + if (!bomrowid || checkboxnum >= settings.checkboxes.length) { + return; + } + var bomrow = document.getElementById(bomrowid); + var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0]; + checkbox.checked = true; + checkbox.indeterminate = false; + checkbox.onchange(); +} + +function setBomCheckboxes(value) { + writeStorage("bomCheckboxes", value); + settings.checkboxes = value.split(",").filter((e) => e); + prepCheckboxes(); + populateBomTable(); + populateDarkenWhenCheckedOptions(); +} + +function setDarkenWhenChecked(value) { + writeStorage("darkenWhenChecked", value); + settings.darkenWhenChecked = value; + populateBomTable(); +} + +function prepCheckboxes() { + var table = document.getElementById("checkbox-stats"); + while (table.childElementCount > 1) { + table.removeChild(table.lastChild); + } + if (settings.checkboxes.length) { + table.style.display = ""; + } else { + table.style.display = "none"; + } + for (var checkbox of settings.checkboxes) { + var tr = document.createElement("TR"); + var td = document.createElement("TD"); + td.innerHTML = checkbox; + tr.appendChild(td); + td = document.createElement("TD"); + td.id = "checkbox-stats-" + checkbox; + var progressbar = document.createElement("div"); + progressbar.classList.add("bar"); + td.appendChild(progressbar); + var text = document.createElement("div"); + text.classList.add("text"); + td.appendChild(text); + tr.appendChild(td); + table.appendChild(tr); + updateCheckboxStats(checkbox); + } +} + +function populateDarkenWhenCheckedOptions() { + var container = document.getElementById("darkenWhenCheckedContainer"); + + if (settings.checkboxes.length == 0) { + container.parentElement.style.display = "none"; + return; + } + + container.innerHTML = ''; + container.parentElement.style.display = "inline-block"; + + function createOption(name, displayName) { + var id = "darkenWhenChecked-" + name; + + var div = document.createElement("div"); + div.classList.add("radio-container"); + + var input = document.createElement("input"); + input.type = "radio"; + input.name = "darkenWhenChecked"; + input.value = name; + input.id = id; + input.onchange = () => setDarkenWhenChecked(name); + div.appendChild(input); + + // Preserve the selected element when the checkboxes change + if (name == settings.darkenWhenChecked) { + input.checked = true; + } + + var label = document.createElement("label"); + label.innerHTML = displayName; + label.htmlFor = id; + div.appendChild(label); + + container.appendChild(div); + } + createOption("", "None"); + for (var checkbox of settings.checkboxes) { + createOption(checkbox, checkbox); + } +} + +function updateCheckboxStats(checkbox) { + var checked = getStoredCheckboxRefs(checkbox).size; + var total = pcbdata.footprints.length - pcbdata.bom.skipped.length; + var percent = checked * 100.0 / total; + var td = document.getElementById("checkbox-stats-" + checkbox); + td.firstChild.style.width = percent + "%"; + td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)"; +} + +document.onkeydown = function(e) { + switch (e.key) { + case "n": + if (document.activeElement.type == "text") { + return; + } + if (currentHighlightedRowId !== null) { + checkBomCheckbox(currentHighlightedRowId, "placed"); + highlightNextRow(); + e.preventDefault(); + } + break; + case "ArrowUp": + highlightPreviousRow(); + e.preventDefault(); + break; + case "ArrowDown": + highlightNextRow(); + e.preventDefault(); + break; + default: + break; + } + if (e.altKey) { + switch (e.key) { + case "f": + focusFilterField(); + e.preventDefault(); + break; + case "r": + focusRefLookupField(); + e.preventDefault(); + break; + case "z": + changeBomLayout("bom-only"); + e.preventDefault(); + break; + case "x": + changeBomLayout("left-right"); + e.preventDefault(); + break; + case "c": + changeBomLayout("top-bottom"); + e.preventDefault(); + break; + case "v": + changeCanvasLayout("F"); + e.preventDefault(); + break; + case "b": + changeCanvasLayout("FB"); + e.preventDefault(); + break; + case "n": + changeCanvasLayout("B"); + e.preventDefault(); + break; + default: + break; + } + if (e.key >= '1' && e.key <= '9') { + toggleBomCheckbox(currentHighlightedRowId, parseInt(e.key)); + } + } +} + +function hideNetlistButton() { + document.getElementById("bom-ungrouped-btn").classList.remove("middle-button"); + document.getElementById("bom-ungrouped-btn").classList.add("right-most-button"); + document.getElementById("bom-netlist-btn").style.display = "none"; +} + +window.onload = function(e) { + initUtils(); + initRender(); + initStorage(); + initDefaults(); + cleanGutters(); + populateMetadata(); + dbgdiv = document.getElementById("dbg"); + bom = document.getElementById("bombody"); + bomhead = document.getElementById("bomhead"); + filter = ""; + reflookup = ""; + if (!("nets" in pcbdata)) { + hideNetlistButton(); + } + initDone = true; + prepCheckboxes(); + // Triggers render + changeBomLayout(settings.bomlayout); + + // Users may leave fullscreen without touching the checkbox. Uncheck. + document.addEventListener('fullscreenchange', () => { + if (!document.fullscreenElement) + document.getElementById('fullscreenCheckbox').checked = false; + }); +} + +window.onresize = resizeAll; +window.matchMedia("print").addListener(resizeAll); + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// + </script> +</head> + +<body> + +<div id="topmostdiv" class="topmostdiv"> + <div id="top"> + <div style="float: right; height: 100%;"> + <div class="hideonprint menu" style="float: right; top: 8px;"> + <button class="menubtn"></button> + <div class="menu-content"> + <label class="menu-label menu-label-top" style="width: calc(50% - 18px)"> + <input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)"> + Dark mode + </label><!-- This comment eats space! All of it! + --><label class="menu-label menu-label-top" style="width: calc(50% - 17px); border-left: 0;"> + <input id="fullscreenCheckbox" type="checkbox" onchange="setFullscreen(this.checked)"> + Full Screen + </label> + <label class="menu-label" style="width: calc(50% - 18px)"> + <input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)"> + Fab layer + </label><!-- This comment eats space! All of it! + --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;"> + <input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)"> + Silkscreen + </label> + <label class="menu-label" style="width: calc(50% - 18px)"> + <input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)"> + References + </label><!-- This comment eats space! All of it! + --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;"> + <input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)"> + Values + </label> + <div id="tracksAndZonesCheckboxes"> + <label class="menu-label" style="width: calc(50% - 18px)"> + <input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)"> + Tracks + </label><!-- This comment eats space! All of it! + --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;"> + <input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)"> + Zones + </label> + </div> + <label class="menu-label" style="width: calc(50% - 18px)"> + <input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)"> + Pads + </label><!-- This comment eats space! All of it! + --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;"> + <input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)"> + DNP outlined + </label> + <label class="menu-label"> + <input id="highlightpin1Checkbox" type="checkbox" onchange="setHighlightPin1(this.checked)"> + Highlight first pin + </label> + <label class="menu-label"> + <input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)"> + Continuous redraw on drag + </label> + <label class="menu-label"> + <span>Board rotation</span> + <span style="float: right"><span id="rotationDegree">0</span>°</span> + <input id="boardRotation" type="range" min="-36" max="36" value="0" class="slider" oninput="setBoardRotation(this.value)"> + </label> + <label class="menu-label"> + <div style="margin-left: 5px">Bom checkboxes</div> + <input id="bomCheckboxes" class="menu-textbox" type=text + oninput="setBomCheckboxes(this.value)"> + </label> + <label class="menu-label"> + <div style="margin-left: 5px">Darken when checked</div> + <div id="darkenWhenCheckedContainer"></div> + </label> + <label class="menu-label"> + <span class="shameless-plug"> + <span>Created using</span> + <a id="github-link" target="blank" href="https://github.com/openscopeproject/InteractiveHtmlBom">InteractiveHtmlBom</a> + </span> + </label> + </div> + </div> + <div class="button-container hideonprint" + style="float: right; position: relative; top: 8px"> + <button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')" + title="Front only">F + </button> + <button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')" + title="Front and Back">FB + </button> + <button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')" + title="Back only">B + </button> + </div> + <div class="button-container hideonprint" + style="float: right; position: relative; top: 8px"> + <button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')" + title="BOM only"></button> + <button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')" + title="BOM left, drawings right"></button> + <button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')" + title="BOM top, drawings bot"></button> + </div> + <div class="button-container hideonprint" + style="float: right; position: relative; top: 8px"> + <button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')" + title="Grouped BOM"></button> + <button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')" + title="Ungrouped BOM"></button> + <button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')" + title="Netlist"></button> + </div> + <div class="hideonprint menu" style="float: right; top: 8px;"> + <button class="statsbtn"></button> + <div class="menu-content"> + <table class="stats"> + <tbody> + <tr> + <td width="40%">Board stats</td> + <td>Front</td> + <td>Back</td> + <td>Total</td> + </tr> + <tr> + <td>Components</td> + <td id="stats-components-front">~</td> + <td id="stats-components-back">~</td> + <td id="stats-components-total">~</td> + </tr> + <tr> + <td>Groups</td> + <td id="stats-groups-front">~</td> + <td id="stats-groups-back">~</td> + <td id="stats-groups-total">~</td> + </tr> + <tr> + <td>SMD pads</td> + <td id="stats-smd-pads-front">~</td> + <td id="stats-smd-pads-back">~</td> + <td id="stats-smd-pads-total">~</td> + </tr> + <tr> + <td>TH pads</td> + <td colspan=3 id="stats-th-pads">~</td> + </tr> + </tbody> + </table> + <table class="stats"> + <col width="40%"/><col /> + <tbody id="checkbox-stats"> + <tr> + <td colspan=2 style="border-top: 0">Checkboxes</td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="hideonprint menu" style="float: right; top: 8px;"> + <button class="iobtn"></button> + <div class="menu-content"> + <div class="menu-label menu-label-top"> + <div style="margin-left: 5px;">Save board image</div> + <div class="flexbox"> + <input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width" + style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)"> + <span>X</span> + <input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height" + style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)"> + </div> + <label> + <input id="render-save-transparent" type="checkbox"> + Transparent background + </label> + <div class="flexbox"> + <button class="savebtn" onclick="saveImage('F')">Front</button> + <button class="savebtn" onclick="saveImage('B')">Back</button> + </div> + </div> + <div class="menu-label"> + <span style="margin-left: 5px;">Config and checkbox state</span> + <div class="flexbox"> + <button class="savebtn" onclick="saveSettings()">Export</button> + <button class="savebtn" onclick="loadSettings()">Import</button> + </div> + </div> + </div> + </div> + </div> + <div id="fileinfodiv" style="overflow: auto;"> + <table class="fileinfo"> + <tbody> + <tr> + <td id="title" class="title" style="width: 70%"> + Title + </td> + <td id="revision" class="title" style="width: 30%"> + Revision + </td> + </tr> + <tr> + <td id="company"> + Company + </td> + <td id="filedate"> + Date + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div id="bot" class="split" style="height: calc(100% - 80px)"> + <div id="bomdiv" class="split split-horizontal"> + <div style="width: 100%"> + <input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup" + oninput="updateRefLookup(this.value)"> + <input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter" + oninput="updateFilter(this.value)"> + <div class="button-container hideonprint" style="float: left; margin: 0;"> + <button id="copy" title="Copy bom table to clipboard" + onclick="copyToClipboard()"></button> + </div> + </div> + <div id="dbg"></div> + <table class="bom"> + <thead id="bomhead"> + </thead> + <tbody id="bombody"> + </tbody> + </table> + </div> + <div id="canvasdiv" class="split split-horizontal"> + <div id="frontcanvas" class="split" touch-action="none" style="overflow: hidden"> + <div style="position: relative; width: 100%; height: 100%;"> + <canvas id="F_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas> + <canvas id="F_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas> + <canvas id="F_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas> + <canvas id="F_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas> + </div> + </div> + <div id="backcanvas" class="split" touch-action="none" style="overflow: hidden"> + <div style="position: relative; width: 100%; height: 100%;"> + <canvas id="B_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas> + <canvas id="B_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas> + <canvas id="B_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas> + <canvas id="B_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas> + </div> + </div> + </div> + </div> +</div> + +</body> + +</html> |