12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562 |
- <!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: 10px 10px 10px 0px;
- }
- .dark .button-container {
- filter: invert(1);
- }
- .button-container button {
- background-size: 32px 32px;
- background-position: 5px 5px;
- background-repeat: no-repeat;
- }
- @media print {
- .hideonprint {
- display: none;
- }
- }
- canvas {
- cursor: crosshair;
- }
- canvas:active {
- cursor: grabbing;
- }
- .fileinfo {
- width: 100%;
- max-width: 1000px;
- border: none;
- padding: 5px;
- }
- .fileinfo .title {
- font-size: 20pt;
- font-weight: bold;
- }
- .fileinfo td {
- overflow: hidden;
- white-space: nowrap;
- max-width: 1px;
- width: 50%;
- text-overflow: ellipsis;
- }
- .bom {
- border-collapse: collapse;
- font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
- font-size: 10pt;
- table-layout: fixed;
- width: 100%;
- margin-top: 1px;
- 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: 10px 10px 10px 0px;
- }
- .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 {
- width: 100%;
- height: 100%;
- background-color: white;
- transition: background-color 0.3s;
- }
- #top {
- height: 78px;
- border-bottom: 2px solid black;
- }
- .dark #top {
- border-bottom: 2px solid #ccc;
- }
- #dbg {
- display: block;
- }
- ::-webkit-scrollbar {
- width: 8px;
- }
- ::-webkit-scrollbar-track {
- background: #aaa;
- }
- ::-webkit-scrollbar-thumb {
- background: #666;
- border-radius: 3px;
- }
- ::-webkit-scrollbar-thumb:hover {
- background: #555;
- }
- .slider {
- -webkit-appearance: none;
- width: 100%;
- margin: 3px 0;
- padding: 0;
- outline: none;
- opacity: 0.7;
- -webkit-transition: .2s;
- transition: opacity .2s;
- border-radius: 3px;
- }
- .slider:hover {
- opacity: 1;
- }
- .slider:focus {
- outline: none;
- }
- .slider::-webkit-slider-runnable-track {
- -webkit-appearance: none;
- width: 100%;
- height: 8px;
- background: #d3d3d3;
- border-radius: 3px;
- border: none;
- }
- .slider::-webkit-slider-thumb {
- -webkit-appearance: none;
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #0a0;
- cursor: pointer;
- margin-top: -4px;
- }
- .dark .slider::-webkit-slider-thumb {
- background: #3d3;
- }
- .slider::-moz-range-thumb {
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #0a0;
- cursor: pointer;
- }
- .slider::-moz-range-track {
- height: 8px;
- background: #d3d3d3;
- border-radius: 3px;
- }
- .dark .slider::-moz-range-thumb {
- background: #3d3;
- }
- .slider::-ms-track {
- width: 100%;
- height: 8px;
- border-width: 3px 0;
- background: transparent;
- border-color: transparent;
- color: transparent;
- transition: opacity .2s;
- }
- .slider::-ms-fill-lower {
- background: #d3d3d3;
- border: none;
- border-radius: 3px;
- }
- .slider::-ms-fill-upper {
- background: #d3d3d3;
- border: none;
- border-radius: 3px;
- }
- .slider::-ms-thumb {
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #0a0;
- cursor: pointer;
- margin: 0;
- }
- .shameless-plug {
- font-size: 0.8em;
- text-align: center;
- display: block;
- }
- a {
- color: #0278a4;
- }
- .dark a {
- color: #00b9fd;
- }
- #frontcanvas,
- #backcanvas {
- touch-action: none;
- }
- .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;
- }
- </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", "Hersteller-Nr.", "Mouser-Nr."]}
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- var pcbdata = JSON.parse(LZString.decompressFromBase64("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R1+zXntZa1l7Vptch1UFL0gGh1JgAYda+1NLXiBmiwdbX4dVewv7WLtQB1tFTjxh4AlHWhtZEk4bXbtSC1EHVRtQx1B7VQtcx1nbULtWe1CHXsdUh117XcdWUAvHX8dVh1b7UytRQ1eHWTyB21cHXEdZJ1ZHVAdTBAcnUMaAp1MEC0dfR1kLWGtRp1cHXadRa1yLV6dbWAKHU8dS01bTVOtV01JnU0tUw1FnVnyOJ1NnXLtd6E5HVQdcwAjnWogOB1dHWQdZR1MHWedfEA8HU+dam1WwDnNRm1gXV3NSF1LrVutTK100GeOuPI37UEdZp1f7VBgrZ1Y8bxdbJ11HUpdW51BrXlBLB1WXXedSIAiHVXtf51BnWgAEZ1z7UCde+1AoCKYpF1P7UsdRJ1sXXSdWu1qnVUdfJ1YHWKdbq1aXVzdRl1azWTdV11iXW6db116LWFdcF1o7WhdaV1/QC8ZON11XXWdf+103WNdXN1SXXOdVmArnUrde517XWZdXC1m3WItdt1nHX6dah1QXViteh1Q3VhdSN1yjWndWJ1k3UxdaR1DXX2dVmAN3WLdS51SnWpdSp1j3XLdet1NXXZdd1173V5dem1AXWGdd91xXXjtUd1hU6DhkD1VnVZdaD1vzXg9f81TXULdTR1sPWtdTG1h7VI9V51KrU6db51O3UFdVj1RXUHdSV1k7UrgLVwhPUeACD1F3Vg9VKiEPUgdZT1LXUPdW11iPU7NRt1jPU5dRx16PVcdV917PVPtYd1XPWZ1Tt8vPVrAPz1dXWXdcL1CwBQ9VT1kvUwtel1THX09Z11MvWo9cz1H3V9dYr1+3XK9Zz12HVClJGQX7WztcD1yPUk9aHVUnVXdQ51zXVLdZG14LWrdSb1UvXI9a91PXVW9bt1bPW29b91KvUO9SuAJxwa9UM1bvUC9aT1QvXk9dd1PvUw9Yb1CXW/1ep1pvUvdeb1W3WW9fL1n3V7dT91fHV/dXj1K4CpJPH10XVJ9R71dnWp9d71ovW+9cp1/vUI9X71x7XB9fn1b3WF9Z4FGPX9dU012PUc9bj1qvWM6LW1lXUu9UT1cLXu9YB1DfWQ9en1d3XU9eL1tPU59UH1DPVBgkz1uXW99Qr1JfU49Zh1FfWmQESozvWidZP1SrXT9Z71uvWJdfP1dgD3dfD1EvXt9eJ1IfVo9Vv1xfUR9a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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";
- for (var track of pcbdata.tracks[layer]) {
- if (highlight && highlightedNet != track.net) continue;
- 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();
- }
- }
- 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.renderTracks) {
- var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
- drawTracks(canvas, layer, trackColor, highlight);
- }
- if (settings.renderZones) {
- var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
- drawZones(canvas, layer, zoneColor, highlight);
- }
- if (highlight && settings.renderPads) {
- var padColor = style.getPropertyValue('--pad-color-highlight');
- var 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("bot").style.height = "";
- break;
- case 'top-bottom':
- document.getElementById("tb-btn").classList.add("depressed");
- document.getElementById("frontcanvas").style.display = "";
- document.getElementById("backcanvas").style.display = "";
- document.getElementById("bot").style.height = "calc(100% - 80px)";
- document.getElementById("bomdiv").classList.remove("split-horizontal");
- document.getElementById("canvasdiv").classList.remove("split-horizontal");
- document.getElementById("frontcanvas").classList.add("split-horizontal");
- document.getElementById("backcanvas").classList.add("split-horizontal");
- if (bomsplit) {
- bomsplit.destroy();
- bomsplit = null;
- canvassplit.destroy();
- canvassplit = null;
- }
- bomsplit = Split(['#bomdiv', '#canvasdiv'], {
- sizes: [50, 50],
- onDragEnd: resizeAll,
- direction: "vertical",
- gutterSize: 5
- });
- canvassplit = Split(['#frontcanvas', '#backcanvas'], {
- sizes: [50, 50],
- gutterSize: 5,
- onDragEnd: resizeAll
- });
- break;
- case 'left-right':
- document.getElementById("lr-btn").classList.add("depressed");
- document.getElementById("frontcanvas").style.display = "";
- document.getElementById("backcanvas").style.display = "";
- document.getElementById("bot").style.height = "calc(100% - 80px)";
- document.getElementById("bomdiv").classList.add("split-horizontal");
- document.getElementById("canvasdiv").classList.add("split-horizontal");
- document.getElementById("frontcanvas").classList.remove("split-horizontal");
- document.getElementById("backcanvas").classList.remove("split-horizontal");
- if (bomsplit) {
- bomsplit.destroy();
- bomsplit = null;
- canvassplit.destroy();
- canvassplit = null;
- }
- bomsplit = Split(['#bomdiv', '#canvasdiv'], {
- sizes: [50, 50],
- onDragEnd: resizeAll,
- gutterSize: 5
- });
- canvassplit = Split(['#frontcanvas', '#backcanvas'], {
- sizes: [50, 50],
- gutterSize: 5,
- direction: "vertical",
- onDragEnd: resizeAll
- });
- }
- settings.bomlayout = layout;
- writeStorage("bomlayout", layout);
- changeCanvasLayout(settings.canvaslayout);
- }
- function changeBomMode(mode) {
- document.getElementById("bom-grouped-btn").classList.remove("depressed");
- document.getElementById("bom-ungrouped-btn").classList.remove("depressed");
- document.getElementById("bom-netlist-btn").classList.remove("depressed");
- 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";
- }
- 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);
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- </script>
- </head>
- <body>
- <div id="topmostdiv" class="topmostdiv">
- <div id="top">
- <div style="float: right; height: 100%;">
- <div class="hideonprint menu" style="float: right; top: 8px;">
- <button class="menubtn"></button>
- <div class="menu-content">
- <label class="menu-label menu-label-top" style="width: calc(50% - 18px)">
- <input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)">
- Dark mode
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label menu-label-top" style="width: calc(50% - 17px); border-left: 0;">
- <input id="fullscreenCheckbox" type="checkbox" onchange="setFullscreen(this.checked)">
- Full Screen
- </label>
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
- Fab layer
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
- Silkscreen
- </label>
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
- References
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
- Values
- </label>
- <div id="tracksAndZonesCheckboxes">
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
- Tracks
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
- Zones
- </label>
- </div>
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
- Pads
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
- DNP outlined
- </label>
- <label class="menu-label">
- <input id="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"
- style="float: right; position: relative; top: 8px">
- <button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')"
- title="Front only">F
- </button>
- <button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')"
- title="Front and Back">FB
- </button>
- <button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')"
- title="Back only">B
- </button>
- </div>
- <div class="button-container hideonprint"
- style="float: right; position: relative; top: 8px">
- <button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')"
- title="BOM only"></button>
- <button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')"
- title="BOM left, drawings right"></button>
- <button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
- title="BOM top, drawings bot"></button>
- </div>
- <div class="button-container hideonprint"
- style="float: right; position: relative; top: 8px">
- <button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')"
- title="Grouped BOM"></button>
- <button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')"
- title="Ungrouped BOM"></button>
- <button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')"
- title="Netlist"></button>
- </div>
- <div class="hideonprint menu" style="float: right; top: 8px;">
- <button class="statsbtn"></button>
- <div class="menu-content">
- <table class="stats">
- <tbody>
- <tr>
- <td width="40%">Board stats</td>
- <td>Front</td>
- <td>Back</td>
- <td>Total</td>
- </tr>
- <tr>
- <td>Components</td>
- <td id="stats-components-front">~</td>
- <td id="stats-components-back">~</td>
- <td id="stats-components-total">~</td>
- </tr>
- <tr>
- <td>Groups</td>
- <td id="stats-groups-front">~</td>
- <td id="stats-groups-back">~</td>
- <td id="stats-groups-total">~</td>
- </tr>
- <tr>
- <td>SMD pads</td>
- <td id="stats-smd-pads-front">~</td>
- <td id="stats-smd-pads-back">~</td>
- <td id="stats-smd-pads-total">~</td>
- </tr>
- <tr>
- <td>TH pads</td>
- <td colspan=3 id="stats-th-pads">~</td>
- </tr>
- </tbody>
- </table>
- <table class="stats">
- <col width="40%"/><col />
- <tbody id="checkbox-stats">
- <tr>
- <td colspan=2 style="border-top: 0">Checkboxes</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="hideonprint menu" style="float: right; top: 8px;">
- <button class="iobtn"></button>
- <div class="menu-content">
- <div class="menu-label menu-label-top">
- <div style="margin-left: 5px;">Save board image</div>
- <div class="flexbox">
- <input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width"
- style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
- <span>X</span>
- <input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height"
- style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
- </div>
- <label>
- <input id="render-save-transparent" type="checkbox">
- Transparent background
- </label>
- <div class="flexbox">
- <button class="savebtn" onclick="saveImage('F')">Front</button>
- <button class="savebtn" onclick="saveImage('B')">Back</button>
- </div>
- </div>
- <div class="menu-label">
- <span style="margin-left: 5px;">Config and checkbox state</span>
- <div class="flexbox">
- <button class="savebtn" onclick="saveSettings()">Export</button>
- <button class="savebtn" onclick="loadSettings()">Import</button>
- <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 id="fileinfodiv" style="overflow: auto;">
- <table class="fileinfo">
- <tbody>
- <tr>
- <td id="title" class="title" style="width: 70%">
- Title
- </td>
- <td id="revision" class="title" style="width: 30%">
- Revision
- </td>
- </tr>
- <tr>
- <td id="company">
- Company
- </td>
- <td id="filedate">
- Date
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div id="bot" class="split" style="height: calc(100% - 80px)">
- <div id="bomdiv" class="split split-horizontal">
- <div style="width: 100%">
- <input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup"
- oninput="updateRefLookup(this.value)">
- <input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter"
- oninput="updateFilter(this.value)">
- <div class="button-container hideonprint" style="float: left; margin: 0;">
- <button id="copy" title="Copy bom table to clipboard"
- onclick="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>
|