mirror of
https://github.com/Alex-2-Graf/ZX-Spectrum-BDI-TR-DOS-interface.git
synced 2026-06-15 04:11:34 +03:00
4670 lines
311 KiB
HTML
4670 lines
311 KiB
HTML
<!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-hole-color: #CCCCCC;
|
|
--pad-color-highlight: #D04040;
|
|
--pad-color-highlight-both: #D0D040;
|
|
--pad-color-highlight-marked: #44a344;
|
|
--pin1-outline-color: #ffb629;
|
|
--pin1-outline-color-highlight: #ffb629;
|
|
--pin1-outline-color-highlight-both: #fcbb39;
|
|
--pin1-outline-color-highlight-marked: #fdbe41;
|
|
--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: 0.4rem 0.4rem 0.4rem 0;
|
|
}
|
|
|
|
.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: 3px;
|
|
}
|
|
|
|
.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;
|
|
position: relative;
|
|
}
|
|
|
|
.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: #1cb53d;
|
|
}
|
|
|
|
.dark .bom tr.checked {
|
|
color: #2cce54;
|
|
}
|
|
|
|
.bom tr {
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.bom .numCol {
|
|
width: 30px;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
.visbtn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' stroke='%23333' d='M2.5 4.5h5v15h-5zM9.5 4.5h5v15h-5zM16.5 4.5h5v15h-5z'/%3E%3C/svg%3E");
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
padding: 15px;
|
|
}
|
|
|
|
#vismenu-content {
|
|
left: 0px;
|
|
font-family: Verdana, sans-serif;
|
|
}
|
|
|
|
.dark .statsbtn,
|
|
.dark .savebtn,
|
|
.dark .menubtn,
|
|
.dark .iobtn,
|
|
.dark .visbtn {
|
|
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: 0.4rem 0.4rem 0.4rem 0;
|
|
}
|
|
|
|
.menu-content {
|
|
font-size: 12pt !important;
|
|
text-align: left !important;
|
|
font-weight: normal !important;
|
|
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 {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
background-color: white;
|
|
transition: background-color 0.3s;
|
|
}
|
|
|
|
#top {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
}
|
|
|
|
#topdivider {
|
|
border-bottom: 2px solid black;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.dark #topdivider {
|
|
border-bottom: 2px solid #ccc;
|
|
}
|
|
|
|
#topdivider>div {
|
|
position: relative;
|
|
}
|
|
|
|
#toptoggle {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
position: absolute;
|
|
padding: 0.1rem 0.3rem;
|
|
top: -0.4rem;
|
|
left: -1rem;
|
|
font-size: 1.4rem;
|
|
line-height: 60%;
|
|
border: 1px solid black;
|
|
border-radius: 1rem;
|
|
background-color: #fff;
|
|
z-index: 100;
|
|
}
|
|
|
|
.flipped {
|
|
transform: rotate(0.5turn);
|
|
}
|
|
|
|
.dark #toptoggle {
|
|
border: 1px solid #fff;
|
|
background-color: #222;
|
|
}
|
|
|
|
#fileinfodiv {
|
|
flex: 20rem 1 0;
|
|
overflow: auto;
|
|
}
|
|
|
|
#bomcontrols {
|
|
display: flex;
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
#bomcontrols>* {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
#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;
|
|
}
|
|
|
|
.placeholder {
|
|
border: 1px dashed #9f9fda !important;
|
|
background-color: #edf2f7 !important;
|
|
}
|
|
|
|
.dragging {
|
|
z-index: 999;
|
|
}
|
|
|
|
.dark .dragging>table>tbody>tr {
|
|
background-color: #252c30;
|
|
}
|
|
|
|
.dark .placeholder {
|
|
filter: invert(1);
|
|
}
|
|
|
|
.column-spacer {
|
|
top: 0;
|
|
left: 0;
|
|
width: calc(100% - 4px);
|
|
position: absolute;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
height: 100%;
|
|
}
|
|
|
|
.column-width-handle {
|
|
top: 0;
|
|
right: 0;
|
|
width: 4px;
|
|
position: absolute;
|
|
cursor: col-resize;
|
|
user-select: none;
|
|
height: 100%;
|
|
}
|
|
|
|
.column-width-handle:hover {
|
|
background-color: #4f99bd;
|
|
}
|
|
|
|
.help-link {
|
|
border: 1px solid #0278a4;
|
|
padding-inline: 0.3rem;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dark .help-link {
|
|
border: 1px solid #00b9fd;
|
|
}
|
|
|
|
.bom-color {
|
|
width: 20%;
|
|
}
|
|
|
|
.color-column input {
|
|
width: 1.6rem;
|
|
height: 1rem;
|
|
border: 1px solid black;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
}
|
|
|
|
/* removes default styling from input color element */
|
|
::-webkit-color-swatch {
|
|
border: none;
|
|
}
|
|
|
|
::-webkit-color-swatch-wrapper {
|
|
padding: 0;
|
|
}
|
|
|
|
::-moz-color-swatch,
|
|
::-moz-focus-inner {
|
|
border: none;
|
|
}
|
|
|
|
::-moz-focus-inner {
|
|
padding: 0;
|
|
}
|
|
/* #bomhead {
|
|
position: sticky;
|
|
top: 0px;
|
|
z-index: 1;
|
|
} */
|
|
</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": "none", "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "offset_back_rotation": false, "kicad_text_formatting": true, "fields": ["Value", "Footprint"]}
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
var pcbdata = JSON.parse(LZString.decompressFromBase64("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AAVgCkiBriNzCcfPoA2KdfMJimNyb6AHYABKb7MOUAGgDlAarIB00nEP1kRgBEAcKxjgAOAWSxFAV+AYQBVgFmAJwBYAEsp8KxA0r4MxgAnKbmAfSnBKdoLCpA+gBQAKYApgDbMF8x66jkiLwBiAHngqpUFKaUplSmzADUp4QANKdrqE8wQ4mXJleFfKcMphfwTKcbqc8NzKehdNyncLBQAQ9VhAHspsYBHKaq4nynCqfsADymNzG8plyn+Kb8ppSIAqeEAIKmQqbAAMKnKsjkiRcxYqeUp1SmrgCSpkABNKfKyBSwzflS6VzjdKd4pgymFLCMpqQAcqcYABF18qbeAaqnjQGKpyd5SqaksBymvKcqplymVqcYAWqmKqecpzKmZqeiAFqnGADap0KmKsmiAKrIeqcUpvqmEqYGpxgBkqabcKSI4jJT8VIAVyb1ARqmsqeMps95FqcWzZamrKaKpkqnGADKpuqmdqdcpoGmaqeGRXgzwaaOp76mTqeMp7txzqeCpy6nfAHCpoIBbqbip/qn1KaGplKnRqdvMianPqdS0BGnCgFmponBTKbypgGm9QD2pkAA1qZecDanwrC2pkAB6qchp9ymYaaDS1mnSaZqAZqmIqZRp9qnOqeup7qngLF6p+KnfAESpp6m8aZepvswhBO0jZimvqempsmnsqb+pk8MlqZppqGnVqZBpkEFmadZp2mmDqe2p+GnFaZ5p06m+abpp1GmOqaup2SJMaZFpu6mxaaSACWmQAGep0SIpIk3IgYIPqYyp7mmicF+pymnEzDVp1LRaafppjcwwacOpqqmNaf2pjmnPKZZpiGnPad5p5GmzaYFpy2mu3DK41UBRaZxpwanhqZdpzfh0qZLMY6mlae9p3Knfaepp/2mw6bpprWng6YNp0On2aZjpSOmuaaNp/ynTaYupi2n0aa6p62mU6dtptOnJaYzp/ixuWuzpvSmY6eVpn2n2AD9ptmngafWp0GnNqfKpiundqZLp/Wmo6cNppqmTabjpxunBaatpyuplgDWADYAoACkiPoBRafsAK4BFzEIpkABSKYopqinhABopiQB6KZGp/v1E53ZEegFjgFYpq+nTAG4pwwJn6bABXOmhKcKsBoAaIEHpnAAJKbBMaSmU6Tkp1OmHqdxprunGKZvpiqwc6f7p/OmFqdVpoumR6fsAGym7KYnpu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gBG+5nHmbMAQdMbXl1AfPmlOlm5imB5ucsRYjmcua8AQBmVufB513n52cz5oSwaRq953wAdYAYAHWAVeaR56rmg0qD5i3m0WfO5vdmzAFb57AB2+bt5n9mHeYcAJ3na7Fa5nZn2ubj5zrmE+e65/b4j6ZT50+nGACG54XnQWfK7HNmnXo4rXPnfAFfp6bmeKeb5pIBhKaXTB2Efmb/pmgA1eaSAMHnNeae54zmt+cdesZnoGeqZn5nh6dppk3nyObN5yjne+ZAADBmB+cu5rHncWft5/FnJ+YM59NnIeZkZ6J1PtruZ0nnX+fvZ9/m+2eO57/nTua75unn2mZWZiPmQBZTZx7m52ZkZsanfT1gF0rmvafgF7Lme0ycZp9nTedBpn/m0mbQF4TnMeYbpnlmQeYk52/msObwF0FmrGe355/nFGbJ5qZmjecp5/jnqedR5ugXHOYZ5zAWmecj5vHnDOYJ5gmnvzK4F0DmZqY+5hJn/efOpqnmUBZp5kQWAebEFoHnR+eYFnAWXefv58LnZaatcIgXj+Z5ppQW+Baq5thnVObLZlFmEOfoF7QWgBaYFxjnJOfx56Tn+LBGZ+QW4BYpphAWKBeR5nvnaBYD5/vmP2bJpxnngBbH5lgWNebYF9bnH6b/6wgXc2bMFkgWfBbIFpdM/BYEFmwWBObsF6jnRBcAFxgWbudx51wXpBfcFvMwe6dlenfn4edIFivnyBc756wXkBeoF1AWghfR5jAWdBawFiIX3Oej5mfnY+aiF7nmAuZ65oimMgBC5oXnVQBkZ826X2pi5yXnsXkL5x9R3mbrp1iE2+ccQNdnr+fMAKIWpOZw50YWb2t1xFdmfecq56znGhcjpgIXeOf/5kIXpIlt51oW9Baa5whmiWYMF9gXXqZp1T7algq2FqhAdhatZ9IW6hbg0BoW++aaF2jnw+YkF7AWWeajptnnZ+e6FrrmeeaX5oLnV+cG50LmN+deppcIr3A92rtMHmcm5+8jnmeFKG9nBKbA9ESmKufvZ/+mq+f+Z9XncBZiFmEWyOELMUnt9ecs5607+BeNAT/mUeayFkPmLufWZ04XfhbaFi4X7ufAFiHmjOfC5mJlpZTmjA/5HhZhZ7EWVBb45jIWhBdpF2nmHBc/ZnTnwhfOFtkW6+ZGF7xlpZTR4JUq+Rd95ntmrBdUFwQX1BeEFvYXxRYZFyUXnBYKF1gXVhZKZrkXlaV2SskXthYFFykX1ReFFzUXRRc0F0PmJRZ+FqUWXBcNFtwW1hflF9cnUxHNFp4XLRbVFoUW3hfN5wIXPhfQF74WXOaZF6UWpBYgFjkW5RaVXVwVT/mVF54XvubUF+oWNBe1FnIXdRadF/UW+WcjF9kWZBd8iD0X9zEkUXkWY6YN5ikW/RZ+5tTm/ubFF9MWThb1F/IXsxcKFqMW8xYuiAsX4Re9F/kWUhZqF60WAxZoFw4WrefpF2sXMxfrFqdnXRaKFwrniRcHMIsX2xZVFkjmXhdqFqgX3hdTF4MWdRcHFsMXnRYNFlYW3RZKZ2EXCzGi4YsXb2YtFzsXBRYrF2wX1OftFgcWD2drZ3QWXRc3FscXtxYnFommboQTF30Xdhe7FhcXAxb7FzTmABYzFtcWsxZHF28WmxeKF7hpxqY2StqI0Re95n0WjxatF/0X3xd7F+wWaxcvF8dm9OYbF0cXAJfHFpKAFRZl06cXExZU5nsWPhb/5/sXvxdXFq8WzhZvFgkXIBdBZncXlaR5F7CWXxbnFt8Wv+ZTFrUXlxYQl5zmSJfDFsiXrhcJFvTkHxb/TeMWSxfJF1UXXxZglxiXFxeYlgiWvxeOFxCXgec4l2vnDBZjFuwo+Jf3FwjnDxaqFh9n6JZElmkWzxbTFrQXHRd/F4cWG2en5rzmOeY65rnmQRd6FsEWV+cGF9PnQWaw+ckb5OYl5p5mC+a4pgvmS+bPSbUlFhdxFvLm5JZuFi95w7Tk5jtnuaaH5kfmUhYO5+CXRJY/F8KWHRZP5hQB5ha/hdcWembu515wjJfZ5pIBOeeUpnoWk+b6FqyW0+eG5zfnTBzd1IlU9+fYpqbmh0y9DBTnT+dEpi/nJKaWF1CXcxaAl7Sm5yT11WeEKheSFtSXEBfhZxFnYJfwlo4WkOYYF67nkJdXppKWYqa4liiXWObSp4zsFBbzpyoXmGePF5MWxJbtFnSXopeNp8QWEpf/F8iXoxY4F765Jpe8FxhnZpeglk8XMhe0lliXdJdCF1aW/xYw5uqXZRY4Ft2KePozLcCXFBd4Fqmmuxc0lg4WopYHF/RmZJY3FjaXmxa4Wu6Wwy1alvaXlBYOl+aXIpeyF06WVpZaFjiXvpdGlzaXXqeMFnaXiBd25t/m0hfnFiKW4JfBl5aXPpevFmGWfJe4l4Zm0Hv+llqWX+bal/aXyxdBljGW6RaIl7GXSJdxlu/nfJbzMLOnEZcSF5GXfBZelw6WRReOliSXghb6lxwW8hcGly6WAJfqlwDmG+eZlh6XppdJl4GXyZY1FpiXFpZOlrGXfGZxlvlmUpaBF+Pm1KdBF+wBwReslvKXWOYKFcOEPAXGFp5nSpdfpiqXP6bP5imBqpZxFmIBq+fxF2GXfpcf5/WWppfMFp6XC6Zel6kW3pcxlj6XFZdplxKXHecuFkaW8ZbGlqhmYoqS43aW9uddluaWZZYWlrmXepfp53IWBpZx5lCWhZeul+GXtpdDlpGWLBeelyOWbRdllmOXCJeOFmmXoZaTln6WGpbeptRFl2ZJloGXLBeEljmXbRbzlySXeZfjlr6Xi5btl0uXImdrhCuWeBZmlqWWa5YplnqX85cbls6WoZbWlwWWS5Zw5hGX05ZZlzOWI5ZBlqOWwZaplguXvZaLl9aXW5ZFlzwWO5adlpIWq5azl2eWc5ejlqsXzxeplpeWR5dB55OX5JdiFpmXJ5fFl52Xu5erljSXa5dzlg+Wlpa9lsIWLpdPlseXwmdFlq+XAZfDllRn2Zb7lpcXuZa+F5Znh5bfl7qmVZa6FtWXE+YIp7KWT6e1l6EWYLDnJPTy76cRFiYXOKbKlmbnSucql8/n72cv5qSmvJZr5+mX8Zevp8CNXKuvlreXf5eqFwUX3ZcrF4PnqxYhlwuWT5dAF/2XnecDluGXg5YGCZBXN5dZllIWOpf8F2hXf+djl5oWnBYMl9+XV5ZKZggXiebl6MOWUZf/lueXKZfoVhWXX5dEVyIWP5eM5zgWuFZkVtmXs5bwlwBWhFayZ86WVFf0FthXfpciZzRWM5Zdlv+WdFe6lvRWB5bjloeWRFYFlsRWTFbblpjkpFe4F2Jnb5Z3l6WW95fnlxRWX5cMVpxXVFfEV31nXafcV7hXp5asV3eXdFfEl/RWQFccVxOWV5ZcVkWXL5fMVqeXLFaoV6JWbFdiVuxXhFf5lxJXR5ZCV+vnShY8q6RWLFa8VmeWfFZiVuWWgFZDF+JX8leZ5qPnWeZj5kyW5+bMlhfmNZeNAXnnFm1ylhBXBXG5JGg9DZbz5yYXpuZdBUrnpuHmFsEo1JaW5ghXbZeSV7XmBlayelmXSxf25r7mopY9lheXB5eIlpCWClfH5glmWFYe5opWoBfhJW/HnxdCltZXMZY2V/xWiJeklpWX8mYgV1pXgRY6ViyXNZZyltfmoReGF/KW5yVMOxyXhlfQVk2WsFbNl1pRLZav52ZWb+bPlhmWSFcVZKI7yFZ4V9qXUZaJVLqX0Zf7lhuX7FchlhJXmeeGl1hWiFaDlzywJpb0h8I70lYqVqJWqleyVmpW4lf6l5uWklZxV9hXRqbTln5WiVcllu+WkxfkVlFWeZbRVxhWwFeMVmlXTFdulhlXYVciVzJXSVeRV2xXUVbyVhOXGlZzFlOWZacJp/lWf5dkV6xWRVZyVsVWDFdAVoxXembUVowW3FbCOwKWu5aZV7xXe5dZV0VX2VfFVqlXClfmV0JXPBblVyuXKFdSFuRXfFYUVw+XF5eUVoJX2heaVzoXHlagVxfnXlbgV3pXPlZdpkpX+VaGV/fnnJaHTVyXSue1JMvmxKZ1O2qWIVeIVsIVA1ZhV9+ngpYW5+9mwpcuVgRWgxdqVlcWU1filrlWWReSljoXjJbSl0yWMpfMlrKXLJd9V95Whhcvp3WXE5wJBhdNUFaNl/5XypcBVlnwqpdwVmqWwVeWFzVWoBYKFBtXylf1VypXhJZoV08Wn5fllgJW1VddVgtWA5Z5V0uXoBerJEUHGVe3l4dX75YAV5VWTVdVVjFXJBcbF4WWJFbTl8UGIlYyVu1XFVa0l8dXs1ZrFzlX1VZlF8+X4Zdulw9WtFd4VhFXXpczVz8XN1fqViVWd1aul29WZVbkFh9XB1ZXVklXDVYdVtlXgFcpVu5XzVbnV8eXtVeFBtbEANdtVvhXXhbJV+uX31fA1n2XqVeiF3FXxzHXlgdXl1YQ159WH5f3luhWnVa2Vq9Xp1ZvVyFWwhUvl/9W8NYVVrJWlVfJV3JWt1YaVr9W41aw1hNXJDRo1gVXj1cQ1tGWz1eI15+Wj5ZdV3ZXwFaLV1KXTAHSllYBMpZgVytXU+erVmyW61aLZCwzpkWDVkqWW1cwVswXsFYtlztWrZYcAG2XwVd7Vr5WlNb15+DW6Nb9F0dWjpfPVilW+Zc/Vv4WsVcOVi1XwuYXVsXndVc8VodWgNbXVo1WN1bA1mzWzVecVqDX91YwllzWj1eJVoVXgNeqVlDWfNabliDX/Ncw12lXLGfvV5TWQtfc1sLXPNZA141WotYcVljW/hYo1+NW/pZbC1zWqmZS1k9X6Nf41wRWmNY/VvzXglcc1/AWYNYK15LXANdS1llX0te81upW0NeXlyDW4tebFsJXgtcfV+FX7VYi1qzWKtfa1phXuVa61hqW4hY958XnaNe0V0rWrlZI1jlXj5fzV3LX2Na/l+rW+tbJl8LXkNaG1lVXKtZi10TX3VeLViTXS1ak18tWZNfsAAAARAbn1+f9VvswX8ez5xtXipafpkZWMFc12a+X8XBEpwGgfma7V62W8RYM1o5XQWfu1pvnYVZWVxMxJKfM1hFnkGbHVgTWJ1ZuVtiWdlcxVv2XWRalVn9X38fUi9OTuFdB19gBwda21hjXItba1sPn9JfI1h5WS1baVstXnlYrVn1W5NchFmtWnNYKFB7Xflf3542XW1c01oFXv6Z010FXfte8lgLWH+fp14HX5Vdm1iHWkVbK1rNXrNei19DX8GaR1q4Watc35/FWHjMK1x6XQtZK14VWRdbfVzLX0Vey15kWVtfi1iJmD1YZ1mbWn1YG17bWYdYvVhhWltevVlHXKNbLlgKWGtfw1o3W8dZ211DXfNf21sbWjRfUVwmn5ddt1szXcddV196WhNcCVkTXXda3F9RW6tf117jWldd41hiXfdc9l/3Wp1cD1jVWAdZdp9eWw9YF1w3XT1fm1wTXnVYD1xpWSdeO1snXTtYp187XjQC1lv1Xa1cQV8CMNcdU157X1NaP56+WtNfL58Smftb01v7We1cT18vWs/Q1x1PX+teoVyHXBtZN1sXWstds15kX7Ne11+2X8VcVeKlm3Nca15XWfdYz12HWs9bj1yVXd1elVulWgte+y/J0NtZ7ltLW+9fK13bWRteW1y3W8tY0VzvWbVe917fXjdd31p3XxdY612LW3daMFwmmJ9a91wXXZ9dfVv3WF9e3VnLXD9fY10pmO9Y310zXn9fP1h3X+9eG153WJddv14PX6+c8Fx/XN9eZV3CWL9dF1kA3r9dG1hPWZdczp8Tl19YoiGA2DVcAN6PXNlcW14TWl9e/VyjWv5egN//W09bm11/WY9ff1zXXpRdz1yTXpNcyPY0BeuYF5+TWdZcJ5/7QKI1bBxnX2KdBcQvn/CJmFwSnMUGHoZWla6BBV/BWudcIV8bWcOZe54HEn5rIN7vXoJYs1zmXHdfV1sjX49ZH1r/WddYr0zg3iXC71zbWNJdnpufXTdaUV7PXWNcM116mZDZhWrA3V1bV1/YXKDbwN01WXdZQNnnWoec25ucGpwz0NrfXbDZ31hA299dANm/XqtZcNkbmiebJWzYXT9YAN7w34DciNs3WCDbMNtvX2PjcNglbw9eK1yPXjDaMNgfWNdaH1iMXl9dR1w94QjbuUnBFPDdgNjNXodcv11Q3zdfI1zQ3fpeh5xvKn9fINv0XDDfsN65XqDayN2SWgjdsl/I2J9rqNhQ2Gjat59I3EDdCF6Dx7CCq1oPW7xeM5mo3AVMILIo3sDeiN3A3mjdI1io349dH10uWZDa9+6Y2bDfWVpo2FtccNsA3AjakN57m3DbWN8I36jeElxo3Sjd8Nq/XB9ZGN5w39jfGN/I2I/uSN6fXUjbONyzXgDb8NpA2D9ZyNq3WJjYeN9Y2PNdmN/o33jauNpw3ljekN+43mzoN1no3Tjb6NrY3M9YWN2I3P9a+NvLWfjYhNx427dcFFl43lDbeNy43MjeuN0E3nufyNx6HrDf+NzY3zjdmNydWP9a11qo2VjbcNok35Df0NgE3YTfn1+E3TDcRNog3kTcJNtIHiTaa10k3XjbKNgnWPjYt1pE3v9YmNyGHujYZN3k2sTf5NlcW1DcINtjWtDZkN3yhdDeONqE2DDZhNsk239ZZNxfW4jdQNi95aTaKB+k2vDclNuuWVDYFN4E3djdGNtCWCTY4NsMK5ST+Nnk2Sjb5Ni43yjYRNqk3hTYVN/U2Awu5NmfW1TcD5pk3jDYpNmg22jduNqHnCTeEuyE2JTcdNqU3nTbNN3E2QTepN6Q3aTfDNtE2z9cZNjU2qDa1Nyk3sjfZNkU2wzcEuw03ijZD5wE2cTdlNnU32jYsNpM38zYjNo02ozZNN7E2XTdZNt02czYVNsM3Z0ZTNiI3jTcfl+s3YzdLNtk35TeqNpM22zftNn020zadN8k3Y9azN4M279eCNm03sOnFNms2izf9NjI3ezabN/s2aTYmRta7vTeeN9U2xzc1N/A3GzezNtc2wTdnNg66tzefVzE26zelNy9XFjblN8w29TY3N0675zcLNxRXizYbN7U2ctboNk7WGDZOZ+eDS9c5F5Tsg1abVv5WXmYwVn9JEhc+ZxF1vmctF2NW7zbNugC2k1YEl1SXlOZLppQ3LzZjNlcXblYtNmdXsVZDNmRm7hfCV2iWoJZV1183YzcwtgI3LTb3V4zn8LZVxv/XllcEl2cXmtZ8N8c2pJfh1vE2EzZKZ6i2jstA0Qi21Jft1uY3tjdDF9iXkDfxNqi2zLOHKn60eLeQtygWgDavNiGWyLeEt9i3RLbgunVXMdfotonEX9fTNhw3BLYR1ss3cLdBZyTsADSvKs5XeLfT1pc2Bje2Vti33Td+lgy2YDWJlg8XIJZMtig3NLfmNtFX5Lc+N5s3rLeU7Ug26LaQtqzmcDZItjC3WLfjNqy3S5ZstojzPKqRlrHXLWcYtqI29zffpty2hTY8t0K2vLe6UBXWuOd8tssWNLd3NjM3XLaCtrC2RLf/NsztgcWSRyK21LeituA2ZLfQt1iXGRYUtkK2cOc4t1JHSrYytoSX/LbMtoE2LLeCtpK36rbEtnorJLb8tmK3KreYtrZWEreJ1sTXVZfn59WWXleL1t5WadYU19vXDvIRa3fmkReaiDBXa9eTVs2WO1ZSFvBWYLfiNqFWFrcn1orWnjefV1C2uzdktkw33zeH1qXXZ1b0t8aXqGZW8g63FdZSNgjX11cY19q2VzcPN2C3LGYPV5kkzzb4tgK3rzddNj63drYiZ+9WfrYLNmY2Krf4tuE39zYutoG3dTdkFrtowberN582kNcGtuK3mNdaNumWbrZlpurWkbfbNk43WrectgS29tfytxS3IDcJli5rfrdMtom3obZ2N8i2bjenNi+X0Dcpt8G2NjaQF2K2crbpt2q2urc/lkpWWbeRtiG32bbRtzm2MbbxNz8389e/NnrmLtd/N1g2+lf4GX/XMDe4N6vWJGle11EX36Y+1pdMvtfvZpvWZKe517G3KOS+y7y2QdbKt6rs3Zd71jm2tLZE5onX1DautnC3GbZhFr7LrVfstjsW1JZx1wm3srcttm3m6xdGtw7XxNfoNs7XGDcYAXrmeldlt27W13jEtyf0c+eWtl+mWdbr1oFXs0A75znXm9b1t+22DBQjtsIinzdWVs23hdf+tmI2Dzdu5222HNfLNtO3lLcLF8F5vTfTV6S2obeZNmG3Jzaxt1O3w7dLt36M0rZvl4rXK7f4Vmm2a7a5t9y2jzY4tsS3SFo8Vw63bVfbt1G3q7YDNic2gzfrtiA28Lf7tnTt8bemVi5Wq7dzt86267eVlsa3IFYmt6BXA7eX5qtXZrbYN8BmWXUDZx7Xo7amFjTW47fbVnBWtrZ1t/TXW9fhtva2A2ZCYKm3FDfNt4W3Pbf8N5A2NDbqti9m5dZqFTO22baXttq2SzZvN3S2G7a+ttfX22b/tkk2hbbHt5c3gHb7Nz62Qbdk0zqkj7dZtqB2AHc7t8e2Wjcstnm33db/V3+2n7eItwB23zdXtjDXQHYiZurX8HdQdh030HY9tly3u7cSt3u3LVYptyh2Bbf/tju3aHeJt/fWGHYQdybWH7Y5OVh20HfYd6M2hrdrtye2W5bvtjjXCjD4dlu2KFdTNyG3l7cDNzG217d9t8a32lcmtynXi9Zg0P82oBdsG1K2o7bQVlW3nmbZqchW5heH5hYXoLe7VnB2nNd0dgYqmrYctqS2XzaId0i28rfptz+2rHbJZ7oq9Hb6tzK33beEd9G2rbaEt5bXxbaeV9R2i9aDtrR3Q7bL1wVxRedJsnBEq9YP51a3jHfWtlnwh8DENna2JHbExU8I3ofntyM3Opah1jh3abdFtpw23HcYd8Ln9ISWCbJ3hzdSNwjW/Fc4d9+2gnfXtz1XN7e9V4vWWDb3tuW2gOYtnK8r4nZe1ox2BDZPMOQRJlejVikX0neLt65munYktux2XbYcd+0WFHbh1mq381ZKdhB2XXELDIy3ELfsd/q35HacdwK2FnevV4J2vVc6V4imQ7fadsO3W2ZuZtJWlrYMd2zw+nfM50x2uOk8liQ25lbGds52bsQud4y2ZnaWluZ2WLd2d6dWlneBtlZ2CLamdmcX1Ld8dtC2RHfitlx3hLf2d5p3DnZAAXnnrtY+VqJ2d/l11C1KlbY4pwx3phYU5iZWzHamV+gtRnf1t5F31dVRdny2NnZ8d0c2/HZFtgJ2dLbs1wu2CrbJZn3V1sfedzZ3azdOtqq25Lchdhp2VHY3ttR2t7cPpi7W2nZu1pF3eqVzqo22enfEE6bm3tfVtluJPtemhV23dNd1tyQ2yHfvqzhWT9edt4F2cADdtw7mX7Zgd8y2RrZttifmDlbpdwHXc6qdtlSXSXfPDTV2tnYwdjI29XZz1xp3SdZCd3l3YFep1wV26dcTndvgV4TFdla2AVdZ1i+3tNavt+V2b7fcdozX5dn1WKh2RzY/57V2vnczNsR2hpdpdsm2oBbl1j13IHeodoR2wXf8drh3Kja/t9RWD1eTdgh2srYpdt+3BTazd4N271aQdhvgHrYllo62/re2dgG387antsY379b/VvN3w3eqdl638dZlNuB3VzeWdieWK3ZTdiN3oHejd0R2lHdId6e3YhfXllt2BHdTd0e2h3fodkt3SnYz56jXJ3Zydhc203dZd8F2indJt7N3ilc415d2qneetrzXXraAdwG2T2ehdnl2WneIp2sB4FdOd1lx8QZuatF3encxd4gW7nfMdqCX8XaVd7FH+beNt5q2GLc7NojWzrYvFjl31Vb+djJ2hQa/dpl2yXatdgp2u7e0tsW37Xbz1x12L3ZAAY5nwwGvdoV2arna8ZI19HebVkC2peaSdj5mdVBr+AJELHced/7WMnbauTD25BFUtn92QXa1dnO3a3fZdn539Xf2V5HXt3Z0d2ZBU5kHt/NmaPfKtwd2GPeWl212QHbHd1jmPrsXcWvVqPfNd392+Petd3V2gPfnd5Z2KPcXVuDWSXemd5l2aHcLduh3YPc6thd2RWZUy1bFO5bNd1T3IPek96D3MHeGtuT2ljYTd3T3HEUnccT3vHZatga2dXfatwT34Hf+d9aNOPYk9oz2HPag9jT26nb0lwJ3uHbc9vT3j3DDdlT31XfUlxz3Z3a09/K2z3fJ10J3t7ZL1yJ23XZZdPl1j7bQV713Y7eSd3UBNrbUl7a3LHZ09xTWKWdS91t3jrajd/j3FHeuNkD3nndfMH+3ivandgd31PfTdyl3M3cs9tj2tpfAdpdn+3bbdw92O3brd2G2pzeE9mWn71c69/N3QXfXdjN36ncC9jJ325ZG9kr2a3Zk9t62u3bht6r2f9eNZgz2h7bkdkz3fPcKdkm36baNdpPXmHbq9ld2Ubb41qL3dve5tgr3+LGo12b36ve69lrWj3eId2N3OtbIdtbWbveO9wW3GvfG95r3JvZ9tgEWWlYddg52preIpma3XXb7Vg11xLYnwNL3m1Yy9s+2sva+Ztf5G9cDdlvXS3fL1/3IWinW9x63q3Z71+j2FvePd+t3fZYNd1j2Ufc8sNp70fa69g937vd69vO3+vYbdq02c3auQfsrJndu9in2mLYm94t3WveJ9hLXg+oh9jH2q3fRNpy3TPdgdk93afcotpt3XLh598n35vcF98y33rYG9xt3atfUSxn3Ifbm96m3pfcW94X3xHeq9+1jlIbWdvVWsfYF97b2YPfO9zl2/vY9VgH2YXaB9ne2XXcRd5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9Cnsafkp4mnoaeVR8YAa8AEqczH/IRtR92HjYfFB+Eno0fCx+LHhafGx9inmae/x75HgUf4p7mn58f0p5Mnssfxp8On2Uf+p6unmSe0p8qwykevh8GnmUegx+en2afXp9eH/gAup4On+6ejp9cnj6ffJ4oZrgAaJ7SATEfGAGxHi7XcR8YnmQBmJ+In1ifTYDJHkAAXQB+n96frp7env0eXp6BnvoBkXziH6gAap+Ip7CfNJ8anwifmp/hnkqeD0DIn8qfKJ5xn0aeG4EAHvinEh5WAFgBjLAgnwAflM7IAQdN7B+3HnGeJJ+mntGe/p5un/mfMZ8BnnmeYh72n4WeKx8FnjGepZ9DH4aeYh4un/aeBZ7lnoWfjp6xnsWfGACJgJaf/YAkHnXOcx7kHjaf8x/gHlQeHJ+Bn/yfaJ6xH+ie8R4u1gkf4B6JH8me2J+BnmKeQAEzH/RJVp72HgQBbJ/snosfHJ+EAFcBMp4Jno+miZ7ynqCezx50nsme9J4pnvgAqZ5Qnmme/Z6qni2eIZ6tnmGe4Z8jnx2e+gD8Qp6eRZ/Rn9ceBp9FnpSfGAFZAVGfs5+ln3Oe7p5Vns6efoGLn2WeQp9BHpKflZ9rn+WfC54lntWf856mn1uec54oZ7kBVJ7tH2qfg54ansOfCp6vHqYfSp6Qn6mfK5+cnjufS5+/HhufUp6bnkABy4Aepsyf4AD+ABx9+aGzHtaekYAUHpLwfJ5Nnn2eu5+dnqeeK57Ln36fj54oZkMBq59rH6ef655Lns+f8h6qn5aeyqCsn9afzR73nnaeXZ4jHvcfMJ77njSeQ560n88emp6Kn8mfWp/Hn14fQIB7noXuf5/qn/KfB58AX4eeSJ8pnsqfY57OnkqBL5+kns+eb55rnuef5p5dniWflp9QX5+f9h8NnuyfjZ+2n32fGABZANBfvJ9Onk+fZ58mntKf8wAwng8ff54Hn/Ceh55an0efDJ/an4QAvQAgXnKecJ5gXthe4F44XxBex5+QXsBfD57hAaMfpABnnmofgh/Vn+ce0Kca4nnvEe5ltlHv4XeF7yXwMe4zMLHvtc4zMXHu4Xfx7oIBpe/555Hu9+4p74Xu1+9p7tPuGe/OiJnvde8b7oim2e60X/oWTONd7iPu+e6N7wXvhe8T8UXv9F/r7/oXJe/cXhfuIA4v7uxfmc/0X4xeI+539hgA1e+qADnvNe9P7hfude5Ep3xeDe7b5o3urtZ0Xj3vg+/N7rWu9+/RDi/vL+9yXu3uIPAd7jMwne9yXl3uCl/d7gpeve8I8H3vde4KXgPuhPGl70PvxSXD7kJe3lbX7mPul+9X5t/4d+6T79PuvF8T78fvl+8cXt5Xs+8S93Pvpl7GX1fnC+/X7uZfhe8n7qtXy+7L7kZfVl98XxL2mQgb7vpeL+5WXuTXW+8774fu3la77zvuAl7eV/vuR+42XuTXLlh370fuR+6WX4T49l+L9F5fvaTeX+VJN+8T7t5eV++mXnpeq1Y37iPuC+/MXt5Wcl4X74/uRKaSX5Xvz+9iXvfvg7d17+fvoV7v7iupBqfbqIFmSO4qX+/u0KYwpzsx4AEVOrMw6KbQpggBoe/gAd4A+qdq4s4AD1QXQGgBlQCAAAAA=="))
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* 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 saveBomTable(output) {
|
|
var text = '';
|
|
for (var node of bomhead.childNodes[0].childNodes) {
|
|
if (node.firstChild) {
|
|
text += (output == 'csv' ? `"${node.firstChild.nodeValue}"` : node.firstChild.nodeValue);
|
|
}
|
|
if (node != bomhead.childNodes[0].lastChild) {
|
|
text += (output == 'csv' ? ',' : '\t');
|
|
}
|
|
}
|
|
text += '\n';
|
|
for (var row of bombody.childNodes) {
|
|
for (var cell of row.childNodes) {
|
|
let val = '';
|
|
for (var node of cell.childNodes) {
|
|
if (node.nodeName == "INPUT") {
|
|
if (node.checked) {
|
|
val += '✓';
|
|
}
|
|
} else if ((node.nodeName == "MARK") || (node.nodeName == "A")) {
|
|
val += node.firstChild.nodeValue;
|
|
} else {
|
|
val += node.nodeValue;
|
|
}
|
|
}
|
|
if (output == 'csv') {
|
|
val = val.replace(/\"/g, '\"\"'); // pair of double-quote characters
|
|
if (isNumeric(val)) {
|
|
val = +val; // use number
|
|
} else {
|
|
val = `"${val}"`; // enclosed within double-quote
|
|
}
|
|
}
|
|
text += val;
|
|
if (cell != row.lastChild) {
|
|
text += (output == 'csv' ? ',' : '\t');
|
|
}
|
|
}
|
|
text += '\n';
|
|
}
|
|
|
|
if (output != 'clipboard') {
|
|
// To file: csv or txt
|
|
var blob = new Blob([text], {
|
|
type: `text/${output}`
|
|
});
|
|
saveFile(`${pcbdata.metadata.title}.${output}`, blob);
|
|
} else {
|
|
// To clipboard
|
|
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 isNumeric(str) {
|
|
/* https://stackoverflow.com/a/175787 */
|
|
return (typeof str != "string" ? false : !isNaN(str) && !isNaN(parseFloat(str)));
|
|
}
|
|
|
|
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.*)?$", "");
|
|
if (config.fields.includes("Value")) {
|
|
var index = config.fields.indexOf("Value");
|
|
pcbdata.bom["parsedValues"] = {};
|
|
for (var id in pcbdata.bom.fields) {
|
|
pcbdata.bom.parsedValues[id] = parseValue(pcbdata.bom.fields[id][index])
|
|
}
|
|
}
|
|
}
|
|
|
|
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 resetSettings() {
|
|
if (!confirm(
|
|
`This will reset all checkbox states and other settings.\n\n` +
|
|
`Press OK if you want to continue.`)) {
|
|
return;
|
|
}
|
|
if (storage) {
|
|
var keys = [];
|
|
for (var i = 0; i < storage.length; i++) {
|
|
var key = storage.key(i);
|
|
if (key.startsWith(storagePrefix)) keys.push(key);
|
|
}
|
|
for (var key of keys) storage.removeItem(key);
|
|
}
|
|
location.reload();
|
|
}
|
|
|
|
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("markWhenChecked", settings.markWhenChecked);
|
|
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.forms.highlightpin1.highlightpin1.value = settings.highlightpin1;
|
|
writeStorage("boardRotation", settings.boardRotation);
|
|
document.getElementById("boardRotation").value = settings.boardRotation / 5;
|
|
document.getElementById("rotationDegree").textContent = settings.boardRotation;
|
|
setOffsetBackRotation(settings.offsetBackRotation);
|
|
document.getElementById("offsetBackRotationCheckbox").checked = settings.offsetBackRotation;
|
|
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: "FB",
|
|
bomlayout: "left-right",
|
|
bommode: "grouped",
|
|
checkboxes: [],
|
|
checkboxStoredRefs: {},
|
|
darkMode: false,
|
|
highlightpin1: "none",
|
|
redrawOnDrag: true,
|
|
boardRotation: 0,
|
|
offsetBackRotation: false,
|
|
renderPads: true,
|
|
renderReferences: true,
|
|
renderValues: true,
|
|
renderSilkscreen: true,
|
|
renderFabrication: true,
|
|
renderDnpOutline: false,
|
|
renderTracks: true,
|
|
renderZones: true,
|
|
columnOrder: [],
|
|
hiddenColumns: [],
|
|
netColors: {},
|
|
}
|
|
|
|
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 (settings.bommode == "netlist" && !pcbdata.nets) {
|
|
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;
|
|
|
|
var highlightpin1 = readStorage("highlightpin1") || config.highlight_pin1;
|
|
if (highlightpin1 === "false") highlightpin1 = "none";
|
|
if (highlightpin1 === "true") highlightpin1 = "all";
|
|
setHighlightPin1(highlightpin1);
|
|
document.forms.highlightpin1.highlightpin1.value = highlightpin1;
|
|
|
|
settings.markWhenChecked = readStorage("markWhenChecked") || "";
|
|
populateMarkWhenCheckedOptions();
|
|
|
|
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);
|
|
|
|
var fields = ["checkboxes", "References"].concat(config.fields).concat(["Quantity"]);
|
|
var hcols = JSON.parse(readStorage("hiddenColumns"));
|
|
if (hcols === null) {
|
|
hcols = [];
|
|
}
|
|
settings.hiddenColumns = hcols.filter(e => fields.includes(e));
|
|
|
|
var cord = JSON.parse(readStorage("columnOrder"));
|
|
if (cord === null) {
|
|
cord = fields;
|
|
} else {
|
|
cord = cord.filter(e => fields.includes(e));
|
|
if (cord.length != fields.length)
|
|
cord = fields;
|
|
}
|
|
settings.columnOrder = cord;
|
|
|
|
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;
|
|
initBooleanSetting("offsetBackRotation", config.offset_back_rotation, "offsetBackRotationCheckbox", setOffsetBackRotation);
|
|
|
|
settings.netColors = JSON.parse(readStorage("netColors")) || {};
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
if ("polygons" in text) {
|
|
ctx.fill(getPolygonsPath(text));
|
|
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 (config.kicad_text_formatting) {
|
|
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.fillStyle = color;
|
|
ctx.lineWidth = Math.max(1 / scalefactor, edge.width);
|
|
ctx.lineCap = "round";
|
|
ctx.lineJoin = "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);
|
|
}
|
|
if("filled" in edge && edge.filled)
|
|
ctx.fill();
|
|
else
|
|
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, scalefactor, shape, color) {
|
|
ctx.save();
|
|
if (!("svgpath" in shape)) {
|
|
ctx.translate(...shape.pos);
|
|
ctx.rotate(deg2rad(-shape.angle));
|
|
}
|
|
if("filled" in shape && !shape.filled) {
|
|
ctx.strokeStyle = color;
|
|
ctx.lineWidth = Math.max(1 / scalefactor, shape.width);
|
|
ctx.lineCap = "round";
|
|
ctx.lineJoin = "round";
|
|
ctx.stroke(getPolygonsPath(shape));
|
|
} else {
|
|
ctx.fillStyle = color;
|
|
ctx.fill(getPolygonsPath(shape));
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawDrawing(ctx, scalefactor, drawing, color) {
|
|
if (["segment", "arc", "circle", "curve", "rect"].includes(drawing.type)) {
|
|
drawedge(ctx, scalefactor, drawing, color);
|
|
} else if (drawing.type == "polygon") {
|
|
drawPolygonShape(ctx, scalefactor, 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) {
|
|
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);
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawPadHole(ctx, pad, padHoleColor) {
|
|
if (pad.type != "th") return;
|
|
ctx.save();
|
|
ctx.translate(...pad.pos);
|
|
ctx.rotate(-deg2rad(pad.angle));
|
|
ctx.fillStyle = padHoleColor;
|
|
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, colors, 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 = colors.pad;
|
|
ctx.fillRect(0, 0, ...footprint.bbox.size);
|
|
ctx.globalAlpha = 1;
|
|
ctx.strokeStyle = colors.pad;
|
|
ctx.lineWidth = 3 / scalefactor;
|
|
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, colors.pad);
|
|
}
|
|
}
|
|
ctx.lineWidth = 3 / scalefactor;
|
|
// draw pads
|
|
if (settings.renderPads) {
|
|
for (var pad of footprint.pads) {
|
|
if (pad.layers.includes(layer)) {
|
|
drawPad(ctx, pad, colors.pad, outline);
|
|
if (pad.pin1 &&
|
|
(settings.highlightpin1 == "all" ||
|
|
settings.highlightpin1 == "selected" && highlight)) {
|
|
drawPad(ctx, pad, colors.outline, true);
|
|
}
|
|
}
|
|
}
|
|
for (var pad of footprint.pads) {
|
|
drawPadHole(ctx, pad, colors.padHole);
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawEdgeCuts(canvas, scalefactor) {
|
|
var ctx = canvas.getContext("2d");
|
|
var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color');
|
|
for (var edge of pcbdata.edges) {
|
|
drawDrawing(ctx, scalefactor, edge, edgecolor);
|
|
}
|
|
}
|
|
|
|
function drawFootprints(canvas, layer, scalefactor, highlight) {
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.lineWidth = 3 / scalefactor;
|
|
var style = getComputedStyle(topmostdiv);
|
|
|
|
var colors = {
|
|
pad: style.getPropertyValue('--pad-color'),
|
|
padHole: style.getPropertyValue('--pad-hole-color'),
|
|
outline: style.getPropertyValue('--pin1-outline-color'),
|
|
}
|
|
|
|
for (var i = 0; i < pcbdata.footprints.length; i++) {
|
|
var mod = pcbdata.footprints[i];
|
|
var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
|
|
var h = highlightedFootprints.includes(i);
|
|
var d = markedFootprints.has(i);
|
|
if (highlight) {
|
|
if(h && d) {
|
|
colors.pad = style.getPropertyValue('--pad-color-highlight-both');
|
|
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-both');
|
|
} else if (h) {
|
|
colors.pad = style.getPropertyValue('--pad-color-highlight');
|
|
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight');
|
|
} else if (d) {
|
|
colors.pad = style.getPropertyValue('--pad-color-highlight-marked');
|
|
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-marked');
|
|
}
|
|
}
|
|
if( h || d || !highlight) {
|
|
drawFootprint(ctx, layer, scalefactor, mod, colors, highlight, outline);
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) {
|
|
var ctx = canvas.getContext("2d");
|
|
for (var d of pcbdata.drawings[layername][layer]) {
|
|
if (["segment", "arc", "circle", "curve", "rect"].includes(d.type)) {
|
|
drawedge(ctx, scalefactor, d, edgeColor);
|
|
} else if (d.type == "polygon") {
|
|
drawPolygonShape(ctx, scalefactor, d, polygonColor);
|
|
} else {
|
|
drawText(ctx, d, textColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawTracks(canvas, layer, defaultColor, highlight) {
|
|
ctx = canvas.getContext("2d");
|
|
ctx.lineCap = "round";
|
|
|
|
var hasHole = (track) => (
|
|
'drillsize' in track &&
|
|
track.start[0] == track.end[0] &&
|
|
track.start[1] == track.end[1]);
|
|
|
|
// First draw tracks and tented vias
|
|
for (var track of pcbdata.tracks[layer]) {
|
|
if (highlight && highlightedNet != track.net) continue;
|
|
if (!hasHole(track)) {
|
|
ctx.strokeStyle = highlight ? defaultColor : settings.netColors[track.net] || defaultColor;
|
|
ctx.lineWidth = track.width;
|
|
ctx.beginPath();
|
|
if ('radius' in track) {
|
|
ctx.arc(
|
|
...track.center,
|
|
track.radius,
|
|
deg2rad(track.startangle),
|
|
deg2rad(track.endangle));
|
|
} else {
|
|
ctx.moveTo(...track.start);
|
|
ctx.lineTo(...track.end);
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
// Second pass to draw untented vias
|
|
var style = getComputedStyle(topmostdiv);
|
|
var holeColor = style.getPropertyValue('--pad-hole-color')
|
|
|
|
for (var track of pcbdata.tracks[layer]) {
|
|
if (highlight && highlightedNet != track.net) continue;
|
|
if (hasHole(track)) {
|
|
ctx.strokeStyle = highlight ? defaultColor : settings.netColors[track.net] || defaultColor;
|
|
ctx.lineWidth = track.width;
|
|
ctx.beginPath();
|
|
ctx.moveTo(...track.start);
|
|
ctx.lineTo(...track.end);
|
|
ctx.stroke();
|
|
ctx.strokeStyle = holeColor;
|
|
ctx.lineWidth = track.drillsize;
|
|
ctx.lineTo(...track.end);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawZones(canvas, layer, defaultColor, highlight) {
|
|
ctx = canvas.getContext("2d");
|
|
ctx.lineJoin = "round";
|
|
for (var zone of pcbdata.zones[layer]) {
|
|
if (highlight && highlightedNet != zone.net) continue;
|
|
ctx.strokeStyle = highlight ? defaultColor : settings.netColors[zone.net] || defaultColor;
|
|
ctx.fillStyle = highlight ? defaultColor : settings.netColors[zone.net] || defaultColor;
|
|
if (!zone.path2d) {
|
|
zone.path2d = getPolygonsPath(zone);
|
|
}
|
|
ctx.fill(zone.path2d, zone.fillrule || "nonzero");
|
|
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 {
|
|
if (!window.matchMedia("print").matches)
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawNets(canvas, layer, highlight) {
|
|
var style = getComputedStyle(topmostdiv);
|
|
if (settings.renderZones) {
|
|
var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
|
|
drawZones(canvas, layer, zoneColor, highlight);
|
|
}
|
|
if (settings.renderTracks) {
|
|
var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
|
|
drawTracks(canvas, layer, trackColor, highlight);
|
|
}
|
|
if (highlight && settings.renderPads) {
|
|
var padColor = style.getPropertyValue('--pad-color-highlight');
|
|
var padHoleColor = style.getPropertyValue('--pad-hole-color');
|
|
var ctx = canvas.getContext("2d");
|
|
for (var footprint of pcbdata.footprints) {
|
|
// draw pads
|
|
var padDrawn = false;
|
|
for (var pad of footprint.pads) {
|
|
if (highlightedNet != pad.net) continue;
|
|
if (pad.layers.includes(layer)) {
|
|
drawPad(ctx, pad, padColor, false);
|
|
padDrawn = true;
|
|
}
|
|
}
|
|
if (padDrawn) {
|
|
// redraw all pad holes because some pads may overlap
|
|
for (var pad of footprint.pads) {
|
|
drawPadHole(ctx, pad, padHoleColor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawHighlightsOnLayer(canvasdict, clear = true) {
|
|
if (clear) {
|
|
clearCanvas(canvasdict.highlight);
|
|
}
|
|
if (markedFootprints.size > 0 || 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 * canvasdict.transform.zoom);
|
|
|
|
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);
|
|
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 + (flip && settings.offsetBackRotation ? - 180 : 0)));
|
|
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, flip) {
|
|
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 + (flip && settings.offsetBackRotation ? - 180 : 0)));
|
|
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 flip = (layerdict.layer === "B");
|
|
var bbox = applyRotation(pcbdata.edges_bbox, flip);
|
|
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;
|
|
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 modulo(n, mod) {
|
|
return ((n % mod) + mod) % mod;
|
|
}
|
|
|
|
function pointWithinDistanceToArc(x, y, xc, yc, radius, startangle, endangle, d) {
|
|
var dx = x - xc;
|
|
var dy = y - yc;
|
|
var r_sq = dx * dx + dy * dy;
|
|
var rmin = Math.max(0, radius - d);
|
|
var rmax = radius + d;
|
|
|
|
if (r_sq < rmin * rmin || r_sq > rmax * rmax)
|
|
return false;
|
|
|
|
var angle1 = modulo(deg2rad(startangle), 2 * Math.PI);
|
|
var dx1 = xc + radius * Math.cos(angle1) - x;
|
|
var dy1 = yc + radius * Math.sin(angle1) - y;
|
|
if (dx1 * dx1 + dy1 * dy1 <= d * d)
|
|
return true;
|
|
|
|
var angle2 = modulo(deg2rad(endangle), 2 * Math.PI);
|
|
var dx2 = xc + radius * Math.cos(angle2) - x;
|
|
var dy2 = yc + radius * Math.sin(angle2) - y;
|
|
if (dx2 * dx2 + dy2 * dy2 <= d * d)
|
|
return true;
|
|
|
|
var angle = modulo(Math.atan2(dy, dx), 2 * Math.PI);
|
|
if (angle1 > angle2)
|
|
return (angle >= angle2 || angle <= angle1);
|
|
else
|
|
return (angle >= angle1 && angle <= angle2);
|
|
}
|
|
|
|
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 ('radius' in track) {
|
|
if (pointWithinDistanceToArc(x, y, ...track.center, track.radius, track.startangle, track.endangle, track.width / 2)) {
|
|
return track.net;
|
|
}
|
|
} else {
|
|
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;
|
|
var flip = layerdict.layer === "B";
|
|
if (flip) {
|
|
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 + (flip && settings.offsetBackRotation ? - 180 : 0));
|
|
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 setOffsetBackRotation(value) {
|
|
settings.offsetBackRotation = value;
|
|
writeStorage("offsetBackRotation", value);
|
|
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);
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/*
|
|
* Table reordering via Drag'n'Drop
|
|
* Inspired by: https://htmldom.dev/drag-and-drop-table-column
|
|
*/
|
|
|
|
function setBomHandlers() {
|
|
|
|
const bom = document.getElementById('bomtable');
|
|
|
|
let dragName;
|
|
let placeHolderElements;
|
|
let draggingElement;
|
|
let forcePopulation;
|
|
let xOffset;
|
|
let yOffset;
|
|
let wasDragged;
|
|
|
|
const mouseUpHandler = function(e) {
|
|
// Delete dragging element
|
|
draggingElement.remove();
|
|
|
|
// Make BOM selectable again
|
|
bom.style.removeProperty("userSelect");
|
|
|
|
// Remove listeners
|
|
document.removeEventListener('mousemove', mouseMoveHandler);
|
|
document.removeEventListener('mouseup', mouseUpHandler);
|
|
|
|
if (wasDragged) {
|
|
// Redraw whole BOM
|
|
populateBomTable();
|
|
}
|
|
}
|
|
|
|
const mouseMoveHandler = function(e) {
|
|
// Notice the dragging
|
|
wasDragged = true;
|
|
|
|
// Make the dragged element visible
|
|
draggingElement.style.removeProperty("display");
|
|
|
|
// Set elements position to mouse position
|
|
draggingElement.style.left = `${e.screenX - xOffset}px`;
|
|
draggingElement.style.top = `${e.screenY - yOffset}px`;
|
|
|
|
// Forced redrawing of BOM table
|
|
if (forcePopulation) {
|
|
forcePopulation = false;
|
|
// Copy array
|
|
phe = Array.from(placeHolderElements);
|
|
// populate BOM table again
|
|
populateBomHeader(dragName, phe);
|
|
populateBomBody(dragName, phe);
|
|
}
|
|
|
|
// Set up array of hidden columns
|
|
var hiddenColumns = Array.from(settings.hiddenColumns);
|
|
// In the ungrouped mode, quantity don't exist
|
|
if (settings.bommode === "ungrouped")
|
|
hiddenColumns.push("Quantity");
|
|
// If no checkbox fields can be found, we consider them hidden
|
|
if (settings.checkboxes.length == 0)
|
|
hiddenColumns.push("checkboxes");
|
|
|
|
// Get table headers and group them into checkboxes, extrafields and normal headers
|
|
const bh = document.getElementById("bomhead");
|
|
headers = Array.from(bh.querySelectorAll("th"))
|
|
headers.shift() // numCol is not part of the columnOrder
|
|
headerGroups = []
|
|
lastCompoundClass = null;
|
|
for (i = 0; i < settings.columnOrder.length; i++) {
|
|
cElem = settings.columnOrder[i];
|
|
if (hiddenColumns.includes(cElem)) {
|
|
// Hidden columns appear as a dummy element
|
|
headerGroups.push([]);
|
|
continue;
|
|
}
|
|
elem = headers.filter(e => getColumnOrderName(e) === cElem)[0];
|
|
if (elem.classList.contains("bom-checkbox")) {
|
|
if (lastCompoundClass === "bom-checkbox") {
|
|
cbGroup = headerGroups.pop();
|
|
cbGroup.push(elem);
|
|
headerGroups.push(cbGroup);
|
|
} else {
|
|
lastCompoundClass = "bom-checkbox";
|
|
headerGroups.push([elem])
|
|
}
|
|
} else {
|
|
headerGroups.push([elem])
|
|
}
|
|
}
|
|
|
|
// Copy settings.columnOrder
|
|
var columns = Array.from(settings.columnOrder)
|
|
|
|
// Set up array with indices of hidden columns
|
|
var hiddenIndices = hiddenColumns.map(e => settings.columnOrder.indexOf(e));
|
|
var dragIndex = columns.indexOf(dragName);
|
|
var swapIndex = dragIndex;
|
|
var swapDone = false;
|
|
|
|
// Check if the current dragged element is swapable with the left or right element
|
|
if (dragIndex > 0) {
|
|
// Get left headers boundingbox
|
|
swapIndex = dragIndex - 1;
|
|
while (hiddenIndices.includes(swapIndex) && swapIndex > 0)
|
|
swapIndex--;
|
|
if (!hiddenIndices.includes(swapIndex)) {
|
|
box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
|
|
if (e.clientX < box.left + window.scrollX + (box.width / 2)) {
|
|
swapElement = columns[dragIndex];
|
|
columns.splice(dragIndex, 1);
|
|
columns.splice(swapIndex, 0, swapElement);
|
|
forcePopulation = true;
|
|
swapDone = true;
|
|
}
|
|
}
|
|
}
|
|
if ((!swapDone) && dragIndex < headerGroups.length - 1) {
|
|
// Get right headers boundingbox
|
|
swapIndex = dragIndex + 1;
|
|
while (hiddenIndices.includes(swapIndex))
|
|
swapIndex++;
|
|
if (swapIndex < headerGroups.length) {
|
|
box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
|
|
if (e.clientX > box.left + window.scrollX + (box.width / 2)) {
|
|
swapElement = columns[dragIndex];
|
|
columns.splice(dragIndex, 1);
|
|
columns.splice(swapIndex, 0, swapElement);
|
|
forcePopulation = true;
|
|
swapDone = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write back change to storage
|
|
if (swapDone) {
|
|
settings.columnOrder = columns
|
|
writeStorage("columnOrder", JSON.stringify(columns));
|
|
}
|
|
|
|
}
|
|
|
|
const mouseDownHandler = function(e) {
|
|
var target = e.target;
|
|
if (target.tagName.toLowerCase() != "td")
|
|
target = target.parentElement;
|
|
|
|
// Used to check if a dragging has ever happened
|
|
wasDragged = false;
|
|
|
|
// Create new element which will be displayed as the dragged column
|
|
draggingElement = document.createElement("div")
|
|
draggingElement.classList.add("dragging");
|
|
draggingElement.style.display = "none";
|
|
draggingElement.style.position = "absolute";
|
|
draggingElement.style.overflow = "hidden";
|
|
|
|
// Get bomhead and bombody elements
|
|
const bh = document.getElementById("bomhead");
|
|
const bb = document.getElementById("bombody");
|
|
|
|
// Get all compound headers for the current column
|
|
var compoundHeaders;
|
|
if (target.classList.contains("bom-checkbox")) {
|
|
compoundHeaders = Array.from(bh.querySelectorAll("th.bom-checkbox"));
|
|
} else {
|
|
compoundHeaders = [target];
|
|
}
|
|
|
|
// Create new table which will display the column
|
|
var newTable = document.createElement("table");
|
|
newTable.classList.add("bom");
|
|
newTable.style.background = "white";
|
|
draggingElement.append(newTable);
|
|
|
|
// Create new header element
|
|
var newHeader = document.createElement("thead");
|
|
newTable.append(newHeader);
|
|
|
|
// Set up array for storing all placeholder elements
|
|
placeHolderElements = [];
|
|
|
|
// Add all compound headers to the new thead element and placeholders
|
|
compoundHeaders.forEach(function(h) {
|
|
clone = cloneElementWithDimensions(h);
|
|
newHeader.append(clone);
|
|
placeHolderElements.push(clone);
|
|
});
|
|
|
|
// Create new body element
|
|
var newBody = document.createElement("tbody");
|
|
newTable.append(newBody);
|
|
|
|
// Get indices for compound headers
|
|
var idxs = compoundHeaders.map(e => getBomTableHeaderIndex(e));
|
|
|
|
// For each row in the BOM body...
|
|
var rows = bb.querySelectorAll("tr");
|
|
rows.forEach(function(row) {
|
|
// ..get the cells for the compound column
|
|
const tds = row.querySelectorAll("td");
|
|
var copytds = idxs.map(i => tds[i]);
|
|
// Add them to the new element and the placeholders
|
|
var newRow = document.createElement("tr");
|
|
copytds.forEach(function(td) {
|
|
clone = cloneElementWithDimensions(td);
|
|
newRow.append(clone);
|
|
placeHolderElements.push(clone);
|
|
});
|
|
newBody.append(newRow);
|
|
});
|
|
|
|
// Compute width for compound header
|
|
var width = compoundHeaders.reduce((acc, x) => acc + x.clientWidth, 0);
|
|
draggingElement.style.width = `${width}px`;
|
|
|
|
// Insert the new dragging element and disable selection on BOM
|
|
bom.insertBefore(draggingElement, null);
|
|
bom.style.userSelect = "none";
|
|
|
|
// Determine the mouse position offset
|
|
xOffset = e.screenX - compoundHeaders.reduce((acc, x) => Math.min(acc, x.offsetLeft), compoundHeaders[0].offsetLeft);
|
|
yOffset = e.screenY - compoundHeaders[0].offsetTop;
|
|
|
|
// Get name for the column in settings.columnOrder
|
|
dragName = getColumnOrderName(target);
|
|
|
|
// Change text and class for placeholder elements
|
|
placeHolderElements = placeHolderElements.map(function(e) {
|
|
newElem = cloneElementWithDimensions(e);
|
|
newElem.textContent = "";
|
|
newElem.classList.add("placeholder");
|
|
return newElem;
|
|
});
|
|
|
|
// On next mouse move, the whole BOM needs to be redrawn to show the placeholders
|
|
forcePopulation = true;
|
|
|
|
// Add listeners for move and up on mouse
|
|
document.addEventListener('mousemove', mouseMoveHandler);
|
|
document.addEventListener('mouseup', mouseUpHandler);
|
|
}
|
|
|
|
// In netlist mode, there is nothing to reorder
|
|
if (settings.bommode === "netlist")
|
|
return;
|
|
|
|
// Add mouseDownHandler to every column except the numCol
|
|
bom.querySelectorAll("th")
|
|
.forEach(function(head) {
|
|
if (!head.classList.contains("numCol")) {
|
|
head.onmousedown = mouseDownHandler;
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function getBoundingClientRectFromMultiple(elements) {
|
|
var elems = Array.from(elements);
|
|
|
|
if (elems.length == 0)
|
|
return null;
|
|
|
|
var box = elems.shift()
|
|
.getBoundingClientRect();
|
|
|
|
elems.forEach(function(elem) {
|
|
var elembox = elem.getBoundingClientRect();
|
|
box.left = Math.min(elembox.left, box.left);
|
|
box.top = Math.min(elembox.top, box.top);
|
|
box.width += elembox.width;
|
|
box.height = Math.max(elembox.height, box.height);
|
|
});
|
|
|
|
return box;
|
|
}
|
|
|
|
function cloneElementWithDimensions(elem) {
|
|
var newElem = elem.cloneNode(true);
|
|
newElem.style.height = window.getComputedStyle(elem).height;
|
|
newElem.style.width = window.getComputedStyle(elem).width;
|
|
return newElem;
|
|
}
|
|
|
|
function getBomTableHeaderIndex(elem) {
|
|
const bh = document.getElementById('bomhead');
|
|
const ths = Array.from(bh.querySelectorAll("th"));
|
|
return ths.indexOf(elem);
|
|
}
|
|
|
|
function getColumnOrderName(elem) {
|
|
var cname = elem.getAttribute("col_name");
|
|
if (cname === "bom-checkbox")
|
|
return "checkboxes";
|
|
else
|
|
return cname;
|
|
}
|
|
|
|
function resizableGrid(tablehead) {
|
|
var cols = tablehead.firstElementChild.children;
|
|
var rowWidth = tablehead.offsetWidth;
|
|
|
|
for (var i = 1; i < cols.length; i++) {
|
|
if (cols[i].classList.contains("bom-checkbox"))
|
|
continue;
|
|
cols[i].style.width = ((cols[i].clientWidth - paddingDiff(cols[i])) * 100 / rowWidth) + '%';
|
|
}
|
|
|
|
for (var i = 1; i < cols.length - 1; i++) {
|
|
var div = document.createElement('div');
|
|
div.className = "column-width-handle";
|
|
cols[i].appendChild(div);
|
|
setListeners(div);
|
|
}
|
|
|
|
function setListeners(div) {
|
|
var startX, curCol, nxtCol, curColWidth, nxtColWidth, rowWidth;
|
|
|
|
div.addEventListener('mousedown', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
curCol = e.target.parentElement;
|
|
nxtCol = curCol.nextElementSibling;
|
|
startX = e.pageX;
|
|
|
|
var padding = paddingDiff(curCol);
|
|
|
|
rowWidth = curCol.parentElement.offsetWidth;
|
|
curColWidth = curCol.clientWidth - padding;
|
|
nxtColWidth = nxtCol.clientWidth - padding;
|
|
});
|
|
|
|
document.addEventListener('mousemove', function(e) {
|
|
if (startX) {
|
|
var diffX = e.pageX - startX;
|
|
diffX = -Math.min(-diffX, curColWidth - 20);
|
|
diffX = Math.min(diffX, nxtColWidth - 20);
|
|
|
|
curCol.style.width = ((curColWidth + diffX) * 100 / rowWidth) + '%';
|
|
nxtCol.style.width = ((nxtColWidth - diffX) * 100 / rowWidth) + '%';
|
|
console.log(`${curColWidth + nxtColWidth} ${(curColWidth + diffX) * 100 / rowWidth + (nxtColWidth - diffX) * 100 / rowWidth}`);
|
|
}
|
|
});
|
|
|
|
document.addEventListener('mouseup', function(e) {
|
|
curCol = undefined;
|
|
nxtCol = undefined;
|
|
startX = undefined;
|
|
nxtColWidth = undefined;
|
|
curColWidth = undefined
|
|
});
|
|
}
|
|
|
|
function paddingDiff(col) {
|
|
|
|
if (getStyleVal(col, 'box-sizing') == 'border-box') {
|
|
return 0;
|
|
}
|
|
|
|
var padLeft = getStyleVal(col, 'padding-left');
|
|
var padRight = getStyleVal(col, 'padding-right');
|
|
return (parseInt(padLeft) + parseInt(padRight));
|
|
|
|
}
|
|
|
|
function getStyleVal(elm, css) {
|
|
return (window.getComputedStyle(elm, null).getPropertyValue(css))
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* 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 markedFootprints = new Set();
|
|
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();
|
|
if (initDone) {
|
|
populateBomTable();
|
|
}
|
|
}
|
|
|
|
function setShowBOMColumn(field, value) {
|
|
if (field === "references") {
|
|
var rl = document.getElementById("reflookup");
|
|
rl.disabled = !value;
|
|
if (!value) {
|
|
rl.value = "";
|
|
updateRefLookup("");
|
|
}
|
|
}
|
|
|
|
var n = settings.hiddenColumns.indexOf(field);
|
|
if (value) {
|
|
if (n != -1) {
|
|
settings.hiddenColumns.splice(n, 1);
|
|
}
|
|
} else {
|
|
if (n == -1) {
|
|
settings.hiddenColumns.push(field);
|
|
}
|
|
}
|
|
|
|
writeStorage("hiddenColumns", JSON.stringify(settings.hiddenColumns));
|
|
|
|
if (initDone) {
|
|
populateBomTable();
|
|
}
|
|
|
|
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 markWhenChecked = settings.markWhenChecked == checkbox;
|
|
eventArgs = {
|
|
checkbox: checkbox,
|
|
refs: references,
|
|
}
|
|
if (this.checked) {
|
|
// checkbox ticked
|
|
for (var ref of references) {
|
|
refsSet.add(ref[1]);
|
|
}
|
|
if (markWhenChecked) {
|
|
row.classList.add("checked");
|
|
for (var ref of references) {
|
|
markedFootprints.add(ref[1]);
|
|
}
|
|
drawHighlights();
|
|
}
|
|
eventArgs.state = 'checked';
|
|
} else {
|
|
// checkbox unticked
|
|
for (var ref of references) {
|
|
refsSet.delete(ref[1]);
|
|
}
|
|
if (markWhenChecked) {
|
|
row.classList.remove("checked");
|
|
for (var ref of references) {
|
|
markedFootprints.delete(ref[1]);
|
|
}
|
|
drawHighlights();
|
|
}
|
|
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 updateNetColors() {
|
|
writeStorage("netColors", JSON.stringify(settings.netColors));
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function netColorChangeHandler(net) {
|
|
return (event) => {
|
|
settings.netColors[net] = event.target.value;
|
|
updateNetColors();
|
|
}
|
|
}
|
|
|
|
function netColorRightClick(net) {
|
|
return (event) => {
|
|
if (event.button == 2) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
var style = getComputedStyle(topmostdiv);
|
|
var defaultNetColor = style.getPropertyValue('--track-color').trim();
|
|
event.target.value = defaultNetColor;
|
|
delete settings.netColors[net];
|
|
updateNetColors();
|
|
}
|
|
}
|
|
}
|
|
|
|
function entryMatches(entry) {
|
|
if (settings.bommode == "netlist") {
|
|
// entry is just a net name
|
|
return entry.toLowerCase().indexOf(filter) >= 0;
|
|
}
|
|
// check refs
|
|
if (!settings.hiddenColumns.includes("references")) {
|
|
for (var ref of entry) {
|
|
if (ref[0].toLowerCase().indexOf(filter) >= 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
// check fields
|
|
for (var i in config.fields) {
|
|
var f = config.fields[i];
|
|
if (!settings.hiddenColumns.includes(f)) {
|
|
for (var ref of entry) {
|
|
if (String(pcbdata.bom.fields[ref[1]][i]).toLowerCase().indexOf(filter) >= 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function findRefInEntry(entry) {
|
|
return entry.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, is_checkbox = false) {
|
|
var th = document.createElement("TH");
|
|
th.innerHTML = name;
|
|
th.classList.add(cls);
|
|
if (is_checkbox)
|
|
th.setAttribute("col_name", "bom-checkbox");
|
|
else
|
|
th.setAttribute("col_name", name);
|
|
var span = document.createElement("SPAN");
|
|
span.classList.add("sortmark");
|
|
span.classList.add("none");
|
|
th.appendChild(span);
|
|
var spacer = document.createElement("div");
|
|
spacer.className = "column-spacer";
|
|
th.appendChild(spacer);
|
|
spacer.onclick = function () {
|
|
if (currentSortColumn && th !== currentSortColumn) {
|
|
// Currently sorted by another column
|
|
currentSortColumn.childNodes[1].classList.remove(currentSortOrder);
|
|
currentSortColumn.childNodes[1].classList.add("none");
|
|
currentSortColumn = null;
|
|
currentSortOrder = null;
|
|
}
|
|
if (currentSortColumn && th === 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 = th;
|
|
currentSortColumn.childNodes[1].classList.remove("none");
|
|
currentSortColumn.childNodes[1].classList.add("asc");
|
|
currentSortOrder = "asc";
|
|
}
|
|
populateBomBody();
|
|
}
|
|
if (is_checkbox) {
|
|
spacer.onclick = fancyDblClickHandler(
|
|
spacer, spacer.onclick, checkboxSetUnsetAllHandler(name));
|
|
}
|
|
return th;
|
|
}
|
|
|
|
function populateBomHeader(placeHolderColumn = null, placeHolderElements = null) {
|
|
while (bomhead.firstChild) {
|
|
bomhead.removeChild(bomhead.firstChild);
|
|
}
|
|
var tr = document.createElement("TR");
|
|
var th = document.createElement("TH");
|
|
th.classList.add("numCol");
|
|
|
|
var vismenu = document.createElement("div");
|
|
vismenu.id = "vismenu";
|
|
vismenu.classList.add("menu");
|
|
|
|
var visbutton = document.createElement("div");
|
|
visbutton.classList.add("visbtn");
|
|
visbutton.classList.add("hideonprint");
|
|
|
|
var viscontent = document.createElement("div");
|
|
viscontent.classList.add("menu-content");
|
|
viscontent.id = "vismenu-content";
|
|
|
|
settings.columnOrder.forEach(column => {
|
|
if (typeof column !== "string")
|
|
return;
|
|
|
|
// Skip empty columns
|
|
if (column === "checkboxes" && settings.checkboxes.length == 0)
|
|
return;
|
|
else if (column === "Quantity" && settings.bommode == "ungrouped")
|
|
return;
|
|
|
|
var label = document.createElement("label");
|
|
label.classList.add("menu-label");
|
|
|
|
var input = document.createElement("input");
|
|
input.classList.add("visibility_checkbox");
|
|
input.type = "checkbox";
|
|
input.onchange = function (e) {
|
|
setShowBOMColumn(column, e.target.checked)
|
|
};
|
|
input.checked = !(settings.hiddenColumns.includes(column));
|
|
|
|
label.appendChild(input);
|
|
if (column.length > 0)
|
|
label.append(column[0].toUpperCase() + column.slice(1));
|
|
|
|
viscontent.appendChild(label);
|
|
});
|
|
|
|
viscontent.childNodes[0].classList.add("menu-label-top");
|
|
|
|
vismenu.appendChild(visbutton);
|
|
if (settings.bommode != "netlist") {
|
|
vismenu.appendChild(viscontent);
|
|
th.appendChild(vismenu);
|
|
}
|
|
tr.appendChild(th);
|
|
|
|
var checkboxCompareClosure = function (checkbox) {
|
|
return (a, b) => {
|
|
var stateA = getCheckboxState(checkbox, a);
|
|
var stateB = getCheckboxState(checkbox, b);
|
|
if (stateA > stateB) return -1;
|
|
if (stateA < stateB) return 1;
|
|
return 0;
|
|
}
|
|
}
|
|
var stringFieldCompareClosure = function (fieldIndex) {
|
|
return (a, b) => {
|
|
var fa = pcbdata.bom.fields[a[0][1]][fieldIndex];
|
|
var fb = pcbdata.bom.fields[b[0][1]][fieldIndex];
|
|
if (fa != fb) return fa > fb ? 1 : -1;
|
|
else return 0;
|
|
}
|
|
}
|
|
var referenceRegex = /(?<prefix>[^0-9]+)(?<number>[0-9]+)/;
|
|
var compareRefs = (a, b) => {
|
|
var ra = referenceRegex.exec(a);
|
|
var rb = referenceRegex.exec(b);
|
|
if (ra === null || rb === null) {
|
|
if (a != b) return a > b ? 1 : -1;
|
|
return 0;
|
|
} else {
|
|
if (ra.groups.prefix != rb.groups.prefix) {
|
|
return ra.groups.prefix > rb.groups.prefix ? 1 : -1;
|
|
}
|
|
if (ra.groups.number != rb.groups.number) {
|
|
return parseInt(ra.groups.number) > parseInt(rb.groups.number) ? 1 : -1;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
if (settings.bommode == "netlist") {
|
|
tr.appendChild(createColumnHeader("Net name", "bom-netname", (a, b) => {
|
|
if (a > b) return -1;
|
|
if (a < b) return 1;
|
|
return 0;
|
|
}));
|
|
tr.appendChild(createColumnHeader("Color", "bom-color", (a, b) => {
|
|
return 0;
|
|
}));
|
|
} else {
|
|
// Filter hidden columns
|
|
var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
|
|
var valueIndex = config.fields.indexOf("Value");
|
|
var footprintIndex = config.fields.indexOf("Footprint");
|
|
columns.forEach((column) => {
|
|
if (column === placeHolderColumn) {
|
|
var n = 1;
|
|
if (column === "checkboxes")
|
|
n = settings.checkboxes.length;
|
|
for (i = 0; i < n; i++) {
|
|
td = placeHolderElements.shift();
|
|
tr.appendChild(td);
|
|
}
|
|
return;
|
|
} else if (column === "checkboxes") {
|
|
for (var checkbox of settings.checkboxes) {
|
|
th = createColumnHeader(
|
|
checkbox, "bom-checkbox", checkboxCompareClosure(checkbox), true);
|
|
tr.appendChild(th);
|
|
}
|
|
} else if (column === "References") {
|
|
tr.appendChild(createColumnHeader("References", "references", (a, b) => {
|
|
var i = 0;
|
|
while (i < a.length && i < b.length) {
|
|
if (a[i] != b[i]) return compareRefs(a[i][0], b[i][0]);
|
|
i++;
|
|
}
|
|
return a.length - b.length;
|
|
}));
|
|
} else if (column === "Value") {
|
|
tr.appendChild(createColumnHeader("Value", "value", (a, b) => {
|
|
var ra = a[0][1], rb = b[0][1];
|
|
return valueCompare(
|
|
pcbdata.bom.parsedValues[ra], pcbdata.bom.parsedValues[rb],
|
|
pcbdata.bom.fields[ra][valueIndex], pcbdata.bom.fields[rb][valueIndex]);
|
|
}));
|
|
return;
|
|
} else if (column === "Footprint") {
|
|
tr.appendChild(createColumnHeader(
|
|
"Footprint", "footprint", stringFieldCompareClosure(footprintIndex)));
|
|
} else if (column === "Quantity" && settings.bommode == "grouped") {
|
|
tr.appendChild(createColumnHeader("Quantity", "quantity", (a, b) => {
|
|
return a.length - b.length;
|
|
}));
|
|
} else {
|
|
// Other fields
|
|
var i = config.fields.indexOf(column);
|
|
if (i < 0)
|
|
return;
|
|
tr.appendChild(createColumnHeader(
|
|
column, `field${i + 1}`, stringFieldCompareClosure(i)));
|
|
}
|
|
});
|
|
}
|
|
bomhead.appendChild(tr);
|
|
}
|
|
|
|
function populateBomBody(placeholderColumn = null, placeHolderElements = null) {
|
|
const urlRegex = /^(https?:\/\/[^\s\/$.?#][^\s]*|file:\/\/([a-zA-Z]:|\/)[^\x00]+)$/;
|
|
while (bom.firstChild) {
|
|
bom.removeChild(bom.firstChild);
|
|
}
|
|
highlightHandlers = [];
|
|
footprintIndexToHandler = {};
|
|
netsToHandler = {};
|
|
currentHighlightedRowId = null;
|
|
var first = true;
|
|
var style = getComputedStyle(topmostdiv);
|
|
var defaultNetColor = style.getPropertyValue('--track-color').trim();
|
|
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) {
|
|
expandedTable.push([ref]);
|
|
}
|
|
}
|
|
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);
|
|
var color = settings.netColors[netname] || defaultNetColor;
|
|
td = document.createElement("TD");
|
|
var colorBox = document.createElement("INPUT");
|
|
colorBox.type = "color";
|
|
colorBox.value = color;
|
|
colorBox.onchange = netColorChangeHandler(netname);
|
|
colorBox.onmouseup = netColorRightClick(netname);
|
|
colorBox.oncontextmenu = (e) => e.preventDefault();
|
|
td.appendChild(colorBox);
|
|
td.classList.add("color-column");
|
|
tr.appendChild(td);
|
|
} else {
|
|
if (reflookup) {
|
|
references = findRefInEntry(bomentry);
|
|
if (references.length == 0) {
|
|
continue;
|
|
}
|
|
} else {
|
|
references = bomentry;
|
|
}
|
|
// Filter hidden columns
|
|
var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
|
|
columns.forEach((column) => {
|
|
if (column === placeholderColumn) {
|
|
var n = 1;
|
|
if (column === "checkboxes")
|
|
n = settings.checkboxes.length;
|
|
for (i = 0; i < n; i++) {
|
|
td = placeHolderElements.shift();
|
|
tr.appendChild(td);
|
|
}
|
|
return;
|
|
} else if (column === "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.markWhenChecked == checkbox) {
|
|
tr.classList.add("checked");
|
|
}
|
|
td.appendChild(input);
|
|
tr.appendChild(td);
|
|
}
|
|
}
|
|
} else if (column === "References") {
|
|
td = document.createElement("TD");
|
|
td.innerHTML = highlightFilter(references.map(r => r[0]).join(", "));
|
|
tr.appendChild(td);
|
|
} else if (column === "Quantity" && settings.bommode == "grouped") {
|
|
// Quantity
|
|
td = document.createElement("TD");
|
|
td.textContent = references.length;
|
|
tr.appendChild(td);
|
|
} else {
|
|
// All the other fields
|
|
var field_index = config.fields.indexOf(column)
|
|
if (field_index < 0)
|
|
return;
|
|
var valueSet = new Set();
|
|
references.map(r => r[1]).forEach((id) => valueSet.add(pcbdata.bom.fields[id][field_index]));
|
|
td = document.createElement("TD");
|
|
var output = new Array();
|
|
for (let item of valueSet) {
|
|
const visible = highlightFilter(String(item));
|
|
if (typeof item === 'string' && item.match(urlRegex)) {
|
|
output.push(`<a href="${item}" target="_blank">${visible}</a>`);
|
|
} else {
|
|
output.push(visible);
|
|
}
|
|
}
|
|
td.innerHTML = output.join(", ");
|
|
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();
|
|
setBomHandlers();
|
|
resizableGrid(bomhead);
|
|
}
|
|
|
|
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("topmostdiv").style.height = "";
|
|
document.getElementById("topmostdiv").style.display = "block";
|
|
break;
|
|
case 'top-bottom':
|
|
document.getElementById("tb-btn").classList.add("depressed");
|
|
document.getElementById("frontcanvas").style.display = "";
|
|
document.getElementById("backcanvas").style.display = "";
|
|
document.getElementById("topmostdiv").style.height = "100%";
|
|
document.getElementById("topmostdiv").style.display = "flex";
|
|
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("topmostdiv").style.height = "100%";
|
|
document.getElementById("topmostdiv").style.display = "flex";
|
|
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");
|
|
var chkbxs = document.getElementsByClassName("visibility_checkbox");
|
|
|
|
switch (mode) {
|
|
case 'grouped':
|
|
document.getElementById("bom-grouped-btn").classList.add("depressed");
|
|
for (var i = 0; i < chkbxs.length; i++) {
|
|
chkbxs[i].disabled = false;
|
|
}
|
|
break;
|
|
case 'ungrouped':
|
|
document.getElementById("bom-ungrouped-btn").classList.add("depressed");
|
|
for (var i = 0; i < chkbxs.length; i++) {
|
|
chkbxs[i].disabled = false;
|
|
}
|
|
break;
|
|
case 'netlist':
|
|
document.getElementById("bom-netlist-btn").classList.add("depressed");
|
|
for (var i = 0; i < chkbxs.length; i++) {
|
|
chkbxs[i].disabled = true;
|
|
}
|
|
}
|
|
|
|
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(",").map((e) => e.trim()).filter((e) => e);
|
|
prepCheckboxes();
|
|
populateMarkWhenCheckedOptions();
|
|
setMarkWhenChecked(settings.markWhenChecked);
|
|
}
|
|
|
|
function setMarkWhenChecked(value) {
|
|
writeStorage("markWhenChecked", value);
|
|
settings.markWhenChecked = value;
|
|
markedFootprints.clear();
|
|
for (var ref of (value ? getStoredCheckboxRefs(value) : [])) {
|
|
markedFootprints.add(ref);
|
|
}
|
|
populateBomTable();
|
|
drawHighlights();
|
|
}
|
|
|
|
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 populateMarkWhenCheckedOptions() {
|
|
var container = document.getElementById("markWhenCheckedContainer");
|
|
|
|
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 = "markWhenChecked-" + name;
|
|
|
|
var div = document.createElement("div");
|
|
div.classList.add("radio-container");
|
|
|
|
var input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.name = "markWhenChecked";
|
|
input.value = name;
|
|
input.id = id;
|
|
input.onchange = () => setMarkWhenChecked(name);
|
|
div.appendChild(input);
|
|
|
|
// Preserve the selected element when the checkboxes change
|
|
if (name == settings.markWhenChecked) {
|
|
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) + "%)";
|
|
}
|
|
|
|
function constrain(number, min, max) {
|
|
return Math.min(Math.max(parseInt(number), min), max);
|
|
}
|
|
|
|
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;
|
|
case "ArrowLeft":
|
|
case "ArrowRight":
|
|
if (document.activeElement.type != "text") {
|
|
e.preventDefault();
|
|
let boardRotationElement = document.getElementById("boardRotation")
|
|
settings.boardRotation = parseInt(boardRotationElement.value); // degrees / 5
|
|
if (e.key == "ArrowLeft") {
|
|
settings.boardRotation += 3; // 15 degrees
|
|
}
|
|
else {
|
|
settings.boardRotation -= 3;
|
|
}
|
|
settings.boardRotation = constrain(settings.boardRotation, boardRotationElement.min, boardRotationElement.max);
|
|
boardRotationElement.value = settings.boardRotation
|
|
setBoardRotation(settings.boardRotation);
|
|
}
|
|
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));
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
|
|
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";
|
|
}
|
|
|
|
function topToggle() {
|
|
var top = document.getElementById("top");
|
|
var toptoggle = document.getElementById("toptoggle");
|
|
if (top.style.display === "none") {
|
|
top.style.display = "flex";
|
|
toptoggle.classList.remove("flipped");
|
|
} else {
|
|
top.style.display = "none";
|
|
toptoggle.classList.add("flipped");
|
|
}
|
|
}
|
|
|
|
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;
|
|
setBomCheckboxes(document.getElementById("bomCheckboxes").value);
|
|
// 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);
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
// EventHandler.registerCallback(IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT, () => {
|
|
// for(var tr of bom.childNodes) {
|
|
// tr.onclick = tr.onmousemove;
|
|
// tr.onmousemove = null;
|
|
// };
|
|
// });
|
|
|
|
///////////////////////////////////////////////
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="topmostdiv" class="topmostdiv">
|
|
<div id="top">
|
|
<div id="fileinfodiv">
|
|
<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 id="bomcontrols">
|
|
<div class="hideonprint menu">
|
|
<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="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
|
|
Continuous redraw on drag
|
|
</label>
|
|
<label class="menu-label">
|
|
Highlight first pin
|
|
<form id="highlightpin1">
|
|
<div class="flexbox">
|
|
<label>
|
|
<input type="radio" name="highlightpin1" value="none" onchange="setHighlightPin1('none')">
|
|
None
|
|
</label>
|
|
<label>
|
|
<input type="radio" name="highlightpin1" value="all" onchange="setHighlightPin1('all')">
|
|
All
|
|
</label>
|
|
<label>
|
|
<input type="radio" name="highlightpin1" value="selected" onchange="setHighlightPin1('selected')">
|
|
Selected
|
|
</label>
|
|
</div>
|
|
</form>
|
|
</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">
|
|
<input id="offsetBackRotationCheckbox" type="checkbox" onchange="setOffsetBackRotation(this.checked)">
|
|
Offset back rotation
|
|
</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">Mark when checked</div>
|
|
<div id="markWhenCheckedContainer"></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>
|
|
<a target="blank" title="Mouse and keyboard help" href="https://github.com/openscopeproject/InteractiveHtmlBom/wiki/Usage#bom-page-mouse-actions" style="text-decoration: none;"><label class="help-link">?</label></a>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="button-container hideonprint">
|
|
<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">
|
|
<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">
|
|
<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">
|
|
<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">
|
|
<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>
|
|
<button class="savebtn" onclick="resetSettings()">Reset</button>
|
|
</div>
|
|
</div>
|
|
<div class="menu-label">
|
|
<span style="margin-left: 5px;">Save bom table as</span>
|
|
<div class="flexbox">
|
|
<button class="savebtn" onclick="saveBomTable('csv')">csv</button>
|
|
<button class="savebtn" onclick="saveBomTable('txt')">txt</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="topdivider">
|
|
<div class="hideonprint">
|
|
<div id="toptoggle" onclick="topToggle()">︽</div>
|
|
</div>
|
|
</div>
|
|
<div id="bot" class="split" style="flex: 1 1">
|
|
<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="saveBomTable('clipboard')"></button>
|
|
</div>
|
|
</div>
|
|
<div id="dbg"></div>
|
|
<table class="bom" id="bomtable">
|
|
<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>
|