mirror of
https://github.com/GemsErasmusPlus/GEMS_Electronics.git
synced 2026-04-12 14:45:49 +00:00
4670 lines
316 KiB
HTML
4670 lines
316 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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QPtUaHCaAEz7GQAs+8QWvPtG+5z7V8Hc+477xwDa+y/sBSD2UCsAIvti+2AAEvs6nLt7DvvCAJlAUAAZICsAcvto++YAVUBSgJd7AABSe1OsAHd74gCgAHj7dWraMO/wtkDve3j75wD3oCwA5wCNIVr7wPug+9147q4R5Pr7A6TZgHD76wCI+1H7CvseAEr7uPt4/AnAx/B5C8X7pPsv7ChAQ4hU+157jgDO++YAJvtm++lAYACW+xtYLbZ0/bb7Lnh4AOEAmgB+++L73CzpAlGAxgDS+2+G9fsY+1VAzftPe4EoEphK+J772pzd+3r7rAAxQB2AkwAD+8MAQ/vm+6P7VvsT+2N9U/uMQDP7QIDz+wH7i/vdgMEAUoDr+4r7m/uq+7JAO4uZexPgHfv8+2HkPfuV+2cAp/sWAOf7VYCm+1f7Y/uvwW412jB6FI/7c/ui+wv7ubxL++qcoACf+4373/sLwe+lx378Hnv7JfsUzIf7Szgn+76A7PvG+9AHI/uwB/ROgfJ3+6wAriRIB6wAz/uB+3m8H/so+2j7G/sgAFv771h/++0ugAfEB+kCpAfOQOAHFAfMgJf71Ac3+5gWk/sMB9P7s/vMBygHL/toB2/7GAdI+xwHDfuzAE37P/uIQHwHipMCB137Qge9+6IHkAerAFQHFvtSB12kMgeIB/IHwvuKB6wH6AfsB/L7XAc8B3gHP+g+JPv7+PwkB0YH5AcmBxIH5gfj+9IH9AfWB0/7dgev+9CAjgecB1/73AfaB637fBiEB537B/uGB6AHboA+Bxz7g/tmB9f7AQeWB0EHjAc2BywHYQfxABEHGge6AFoHuAe/+7eL43n6B4kH3YDCBwlAxgdpBxf7GQc0B5kxKYAIB7kHIQf++/YHKgdFB84HMQc7+6hAqgBVB54HSQfH+yIHqQeUB8P7/gdwB60HsgDtB8gHnQcFB+/7GIBYB5oHOAePe7wHt4uPjEMHJggjByMAYwfTgL4HTQcWB3QHsQtzBwoHCwfKB+EHywfqB70HZQc6B7eLqYzbB8AHR/t7B3UH4wfiB0cHWQcnB20HcgcdB6gH2pxsB9cHTgdRBy4H5Qe+yIbIFgBEBwYHNQfeBwcHDQdQB5MHmQfTB7+APwcP+3kHoQeXB4UHQIeRB9gH0Qd3B7EHAUhPB14HyQeLgHCHEwcwB8cH8AezB78H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BScCJ4D7Gif1x0L7ySdfx3yHJceuJ2eA7ieZJxgnw4f1JzqHLId8J/EnRmhRgMUn9ifaJ44niCffx1xHvSeVJ2gngCcFR8WH3se5J6MnT3vNJ62giScNxw4nv4BdJ84nCyfhJ/0nwof5R4DHDIfrJw0nSidxJ4QnaPG7Jx0nbuRlJ2knFSdncFUnNCcrJxcnayfMJyMngsc05uMnDvQPJ6UnKSd6J0qHbifvJ38AtCerJ4GHwye3B/DHM2RQok8HoKCNSMCnhyfFxxQniyfgJMsnJidNx2AnjSfwp29UAehIp+kCW7idJ04n6KdhJ7f75jCRJ+cn0Sd4pzcn+IcIp7Co7kdbR8inAxCop+SnoSfHJ1SnoKA0p1knQydXJ78nvidJSTYYxKfdgKSnTycgp+UnmKfUpwMndCeXJz8ncKfp+9dBRKetJ0AHbKcSpwlAISepJz0ngoe8p3Kn0KdXB7Cno4cCx8KnU4iqp+onoPul+CwApfgcp3MnKscGNJHHSsdMx+tH30e1x1anMQAQgJzHuKcWJwyn+Scip5KoLKd1xxqndqdkJxSn3KeBB7KnZyf8pwqnPidWJ/l0oqdqpxTMIadzh9qnoKcvR2/7+qfRp4MnsaexJ00nCad0jGKnKKepp88nuqc8p9inNSfXx3UngqdKp3wnBacm1kWn7Kclp1KnLycyp1mnwUeVp9knNacSh4ynzdafpUCnzadop1yn+ieBBxkn2afyp98ncae9p6oAPaADp/snb/tDpzqnGKcnJxCnkwBQp18nMKfdp9gn8Kd9pxMnc6czJwcnnKdLp5Sno6enJx2nUSc+p8an26fp+yonLSeWp2T7JSeDp0en6afpJ2en1ScXp14n9Kd5Jzenu6fZgPunZKf2p0cnI6fZB2On56e0p5enW6f4pz+nM6eu8Pgn0YePp/OnaafSpyunFacfp7UnMScbJ38nbaa/p16nSacEJwhnB6cLp8+nyGcGJ2+nHyc4p5+nvqffpy37t6cDB3BnngDtJ6GnhwetpyhnRifkZ52n9CfrhzJHesdtx2DHHcesJ13H7Cc9QAAAkipH3CdaR8+HN8EMqWPHufvhaAX74Wizx7XJRDhKUIvHgQCex7MAkGejRyTH8McixMV14icvx0sg+8dpR0hnLGcGJwD870eVxzhHrqcsx86nuYcpp2hnVae4++YnV6cxR9pnz4d00QMSOcdtJyhARmfzp5/HR6eYRxXHjMdhp3o0bqdxxy/s9mfgZ5+nLcclRz8nnccmx8pHKkcwx4PHFscTRwqEjsSChCjHrUfGRwX7pkdDBxZH3aSsvIRnamfyJ4TH1yfUZ097WERKotqI1Ycvx55HEsfMNqWny6e3+7lH46eGpzfHkUdHR5hndEfeWAuQGWfJR/Vn80ezJyFnx6cRp9kHrWdgZzGnDgcxZ0wnZUdGx5DH7CcAAIpJ+yAA5sdp+3FHLfQf3mgmSviGR6jHjWkiJ9sq9GdJEN2QIIyqZ3InCIxDR6vHU6c6ZwQEGzyuTclH8KB8yPAnJmdlp6On55x8pzmn6AcRR6nHX6ebJwA49BR3Z7Mi96cEJ49niKDPZ01nJ6cgZ+9nBqcbp0anmmcVZ/1UN97EnouI9GcJCOkCv4iEZ/5ngGfhp8BndAeGEKunFgDrp3SnM2e8ZwbH/GfzZ2wn5gAqRwAAggAAcuJndUdPe/8+uLLjgFlnE8fS0L97MEBDBw20KoDT1MCn6mf6AIqnJqdnR+n7Lxo+Z9RzyUewJ0r4AGcjZ4FnzIAfR9HHS0dhZ7z7L8dS596nlGcuZ1pntEeZx9oU2YOo5222PvBMZ0gnpmeBB1PATqdVx9ZnNcfhZ9qcrKAgBw5nwCcpx1FHmGduZ5bHtkSRC8xHL8egoO44RucJh0mHFmfBZyYHeEfupxTMtucvB1Nnm6dC58TH2uf4hyvE4ufkuslHXudNp4hnYcdLh0CA5udWZw6nwWdbR6HnB4efZxHn6ccu50znbuekxR8MNYeJ55qnjWcpJ6nn9McK5y6nmeerRx772ee7B+HncOeR565n0efwx7HnuLKTqABHpft+5K22Fec6J1Xnfufp559HlucGNGrHL+w55+rn6Ge/ZxnHMefF58gaCecU+4Pnw2fOhyPnCscB59XHE+fB51Pnzed5563nBecd56Lnuudrw4xwvedk++XnPueNhxvnQWcN57Lnsccq53XH0+ccZ7mnzufH567no/gRJGq5y+cD59fn5gDV52xnrYeWZ2Pn9edRx43nz+f75xOn3Qck57MA7ccsJxTngmfmAFd7L4ZrZ/DHAQGNR2gO/xLjxx4AbUe/ew7HXUfYx87HwEeux1D7c4dLxxdnK8caZ23nWuemp30HCQEBxzGkN0cvx1TH5Bfap3LndocgF4rnoWc2Z5Pn2pwEZy3nHWc/Z1Rn/Mci5/VHDBdXR0xHQcdzR9TH2OfDp2Cncsc151wXdecxx8rnEBfsx0Enr+fTZwwnIMek53FnAmcJZ+wnKkdmxyln62eVZ9oUGmJwBAZHbOe4FzlnFwB5Z3hnswAFZ1ZHc4c2R7bkpWdXZ3mnOmcWF3qBCHAtiBfnBCeDZ+DnLaevZ+NnBOcXx58n0SffZ07n5Wd/ZzQ4Phe1VElHjhcMZ0EXxmcQ52NndAcTZ++nUWez57AXugDwFy4A8WcXe8pHHCfVRxpHPCepZ5flfcH45IIn2WeQArln2ThDB2N7lkdHZL37H+wC5/DnohdYZ94EE2g2q8lH/Yd3WET8i6ccF8AXW+fj51nnbScDFzPnjmdz54Xnxfpttpa2/RcU+4MXLDwpJyMXq4djF2AXtmcvx1MXWhf55z7HcxcHkj7wfRfJFyUIyxdtFzT7gefLR5vn9+dXF2oXNYe7F/bnAqc0FydHYhdPe1J6svATaEsXrbYrFwb7wxfXF3fn4BcP5/cXOxfnF3sXh+cHFx/nWycumaOAXxenF+T73aRDXDD7L2fNZ6bn1CejF7cX2+cTF33nkIC6gIIXZiedZ7zH7+d0F00nx4hVCHCXwOezAAmAx4BDFwFnAJfy58oXwJe8F7vn0Ye4l1GA+JcYZ7EX8+fwp1gYsJdqJwEXVJcxhxkCw1zsF/SXnBebF6oXzJfW5wxnbJfTF12nLxddF8on15B8l/Rn1JfCl8iXYcfrFwzHmJfjF/fnL8eyl+CXUkc6FzxncBd8ZwgXSvuU58MAfccrZ2gX6fvy66PHCVQ4F197U8cXADPHpxdzxwvHrhcUF7hMl2fUF9dndpdNcTj0EIfFJ7AnxCcJQFjnI2cvp68nF/AfZ9AX3MeEl3fH3WcxB/bG1IjPx20ne8dwJ2kXIReol+Nn6Jdrp5EXTcfRF11nXJd0R3V6UCfBly/HGZdhlwOkEZfMZ6EXmRd5l4TnBZca550X3Re6epn7yVj651WXwReLp1GXmKcxlzDnxOfGl63Hppdk5+aXxsfFF+wnV3txcTVHFRdmF4SAaTFIx6znTpe6AHgX6Mf/e47HRBdQNCQXLgWgRx7HHhd+l5CXJJed54uXB8GOFOLHQ2ekh2sXYpcYl0CXdxdSl0/nGhdaJxyXRZdEl1yXhxd74JKUosfSF3dHhGf1B/MnuOc8R0oXEpdK5w+X6hfxx5oXTxeFR8OXsWdzZxaXSBfDADTntOc2l6YX6Bd55CYKtRfs55zhBftc58kXPOeDpPMg/OcHl4LnR+fHl6yH0/aBM/rnaudPp3IX4cc2Z6Pn3Bd0V1bnj5dk+9RXUFeTp0eXbxfvWGyleueS5xT70ueSp72XJGem58BXOpdbF3wX+Pwv5+xX4UcHRwmXsxdQl+9YRuju57/n3uc0VyNngBf+52JXkpfMV+BXe+cwh4aX1acKl9yXrIc8Vx/rQad951fnalfr582HQBcbF1pXoFc6V7mHUlc5FzMXIhfGV/VHSlcl58T7nucr5//nwwAaVwxXKhcOVzvn0pcmFPpX0lcQl8SXXFfcQKZX0fkqV0nnxWcp57fnDJcgVzwXjldN5+FXLlfyl6RX0VeyQJ5XS+fwl5ZXyefD5zZXmld3l1iXepeQF5lXHJfyV2RX9UexV8zaXmcWV75XVleLh8lX4pf2V2lXIVcsV3pXdudZV88XOVdtlxRs3+cPcPFXq+eHp7RXAVc3F+VXupdAlxlXfVc1V3kXBRdFFwhmnCcoV3OXOmflILqJdxWYV7gXShrrl95Xu4dZHIIAmOREV5QXCicllzEHUeRsSCkYAYmUl5JXLVfFV0JXJucgZwwUtldNlxRn6Gevl4mXl1f4h4oJN1dZsGvQyReNSCSnfleoRNsABgAoAHgAjuRrwUIsR2T4F4+Da5JXIO9wAYb2xzKIR2CRQOuXT/CY1/YX3NRB6MjXQaKF3BcAn6aKjATXixzDsOcAfiWVsPUgMQCU1xogNNc8LNjXP8QqqwtypSCHSBFE6QJVoCGYBNewJw0caew41wtQGNfHyyqrmxFs134XlkeI1zzwxxIS1xAQdNcGYMdQpSB0167gEtfReDzwStdh0/CgotdXIHTXggCC14rXONdWEnRt+teE12pwJNfc1197qOpnxekCJejU19rXqa79BIrXqa5K10dgdNcTICqrOtdIWK7X/87+oDrX3tfG1yZHeNdp7DrXWNcu1yjX7tda1xbX4tdo16rXE2By1wjXEBDS12jX0GCx5IOXEGdGV05HEKTBiW6JwNcIl6pXT1fEZy9XeOdvV7GX7WeGV/6XcUeZ185iXok517r741dEZ7RXfZcnJ8IE71cRF59Xrlea5wjndE3ELWmCd1cClw9Xf+etVwBXChc23s3XJdew50aXXGeMJ3oXcFcTl6tXAABKZRerZ6hXrIffun38R0m7Z9lnenq5Z5X4R2eEJ0+4Z1c+l1QXJFdeF5JnQvmTmDSw8Jc+Z37IYNejZ4BXOUfhF0TnhZeyV8IXHddxF8u4nDBr1x7n3mcr5wJXWqfpF3fX6EYP182XuRcwV7NnhsfwV4YXFNiiZ+tXEmct+0Y0qqvIxyuXk8f7cPJn+3CKZxZ5BeT4x8RXrZcflxn8YxpGBDWHhmeZl/On/5fdJzmXeOfmZ4FXTJfpV8GnoNcGV05nclduV7g3Iwx6ZwNnb8eyF9Q3jqfTV7Zn95c0N+qndDcRVxPXbvvcZyOX+Rdml4UXBheTl1TnDOe8J097SbRq4DMwBWkb1xPHdheXADpF+WcNYBLXRWcxQG4XHRcvF7lXzqMKNyCCi3wDZ4Tgv5cfx6QndZfkN4FHqGf9V3m831dfpwY37alGN+gN+LIeR2Y3DWdnALWXxuf1lzY3LdeP19FnoDfT1+A3VjSWl6wAKkfcwECAtpct+7ALVxNUJO+HNhdfe6o3Dhf3V84XqMAXFyVn51dlZzqHTjcT+FDttLITIF/XfeepF/OnH+zPV74399e2Ny+Xz9cxFzk3bZdag8JM9MtCGe43sCeXlxIAlxc+N9Y3lTf+N8A3MxdLV+I35gChNwhX4Tczl+UXsDfvF2ZLSXZZYrtXSTcQotvXlALJF2k32jerF3o3UEdON5OZE8iuR2uZLTf5x7SXDdfCV2EXVTcH50IXtTcY++s3PDS8aICaped1Zx43bTdlNwXXFTeAN0c3cZdCN+lAIjewVyE3C2fIFzA3jOf9VDWsWehve0g3LpmVcGo3KOx9152olXC6xAfX8PsXV3U3Tkdk+QDC5pbJF8dYuzeCVw83XTdPNz03bdcO585n8OdON0xSZ2Ao4IdXoPsotzIXg9dkN5DnmRdAN9i3nGfCN1PXo5f6FzBHYTcgAHPXL12zl+M3QsdTmH8MDugJN0g3F6IB19fwfdeCFBLXJ7CEZ7o32Df6N22XO+jsuXRaRTdk+1fXPiQWNyiXlLd+N2PXURc1N8WXcLcxB9K3PLnFIHK3gRc/1z2X6Lcqt903are4p/03Y5cSN0y3wzcstwAAohVAAABUDrdRN8vXlsfbEEhQMzerl4LEDSDwoOcAxhhcMEMHpIQWYKyg2Q6OFET8AucWt4y3AsfMt3PX3gAutxtX6fvRURg3XdrWF3y3W9e414K3TscyEPvXc4ftFxK3azdSt4+cybewUmw3A+e/15kCyrcZF6q3qddeJw43VGdONwhrTOvfsVF591fm8Ia3ubcdN0PXGaeXfma3gTeT17oXDLdwV0M3kDeIVzvA8bcctweSBo4YBVKwnrd/e1e8ajcLN6k3mjeFZ+W3Q+erN8dH6zeHGOYwqis91Ds3ZLf51/s3hdfVt21n49cEly/XeLdtl8LyeigINzO3l9e3NzfXjdctZ9S39DfB+/23JpdiN5a3gzdfN6O3MjeVF5O3cxD3hX74O5LKN7YXczcZt2mXoPtLN6u3KYDrt7kn6zcvjKuYx/r0xXu35jdot4e3jzdYFs+3gjdnt6c3ivvrN5O9OOMQrE8MKHeeN2vnnTcmt5i3vbcgN2+3ojfLV8MAw7dSN8MAsbejN0vXCbdxRxseEqinhqm3tsceNBm3fnhZt7rX+ODQt76Xx9dwd22XBSVUIr+VuWytt2HkSM4Ptwc3VLfPN6XXDDfnt5K3TkfTuZx3V4bEd3Vn7bcHt5GXCnfHt5NnxzfHh0E3g7efNzG3LHfRN+YXFV5XopaBIHezN7x3C7f8d0QX2bdCd16XmTeH17C3Zzfid6S4USVdrNp339dlt0a36HcYt5h3Snentyp3uHeN+/i3vnfHQvJIpbdyd1mX5Tehdz23NbfUd3S3A7cft1G3DHfz16gXrrfb+1G4fncHIrO3/LfzN853gEd71253xVewd+VnTjfVICBhf2J/pR5HuneJV9mXFHdhd1i39Dd1tx3XdXcxxEV3TXc6d0F35LdAZ8PX/JDhd0OXNHcfN+Tn0bc2t6y36kesdxO3tIQFlU/lybR3WPZ3q5eld3x3u9eud6K3ySc1d1q3TSdidDfl+dUJd9fXw3c456N3WRfsZ9h3kXeat953vic7U8d3O+XNd0N3endWN+13qXcntxN3GXfvt3R31rcjt6wAsbcmF2x37xftWCsVQsu8tzx32jBOd9t3gne7d85A4rdZN54XYnell2D3pxXcGTJ3CrfQd/GAljfkd1W3prdpd45n3XcXt6j32nufFWwZmPctd0q3/9eXd1h3djfaF5N3YDfTdzl3l3ust4vXVneX5ct3ohKFfCV36bcw900XlXfw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"))
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* 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>
|