| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Interactive BOM for KiCAD</title>
- <style type="text/css">
- :root {
- --pcb-edge-color: black;
- --pad-color: #878787;
- --pad-hole-color: #CCCCCC;
- --pad-color-highlight: #D04040;
- --pad-color-highlight-both: #D0D040;
- --pad-color-highlight-marked: #44a344;
- --pin1-outline-color: #ffb629;
- --pin1-outline-color-highlight: #ffb629;
- --pin1-outline-color-highlight-both: #fcbb39;
- --pin1-outline-color-highlight-marked: #fdbe41;
- --silkscreen-edge-color: #aa4;
- --silkscreen-polygon-color: #4aa;
- --silkscreen-text-color: #4aa;
- --fabrication-edge-color: #907651;
- --fabrication-polygon-color: #907651;
- --fabrication-text-color: #a27c24;
- --track-color: #def5f1;
- --track-color-highlight: #D04040;
- --zone-color: #def5f1;
- --zone-color-highlight: #d0404080;
- }
- html,
- body {
- margin: 0px;
- height: 100%;
- font-family: Verdana, sans-serif;
- }
- .dark.topmostdiv {
- --pcb-edge-color: #eee;
- --pad-color: #808080;
- --pin1-outline-color: #ffa800;
- --pin1-outline-color-highlight: #ccff00;
- --track-color: #42524f;
- --zone-color: #42524f;
- background-color: #252c30;
- color: #eee;
- }
- button {
- background-color: #eee;
- border: 1px solid #888;
- color: black;
- height: 44px;
- width: 44px;
- text-align: center;
- text-decoration: none;
- display: inline-block;
- font-size: 14px;
- font-weight: bolder;
- }
- .dark button {
- /* This will be inverted */
- background-color: #c3b7b5;
- }
- button.depressed {
- background-color: #0a0;
- color: white;
- }
- .dark button.depressed {
- /* This will be inverted */
- background-color: #b3b;
- }
- button:focus {
- outline: 0;
- }
- button#tb-btn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.32 290.12h5.82M1.32 291.45h5.82' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 292.5v4.23M.26 292.63H8.2' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='1.35' y='295.73'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
- }
- button#lr-btn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.06 290.12H3.7m-2.64 1.33H3.7m-2.64 1.32H3.7m-2.64 1.3H3.7m-2.64 1.33H3.7' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 288.8v7.94m0-4.11h3.96' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='5.11' y='291.96'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
- }
- button#bom-btn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)' fill='none' stroke='%23000' stroke-width='.4'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' stroke-linejoin='round'/%3E%3Cpath d='M1.59 290.12h5.29M1.59 291.45h5.33M1.59 292.75h5.33M1.59 294.09h5.33M1.59 295.41h5.33'/%3E%3C/g%3E%3C/svg%3E");
- }
- button#bom-grouped-btn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m4 0h5m4 0h3M6.1 22h3m3.9 0h5m4 0h4m-16-8h4m4 0h4'/%3E%3Cpath stroke-linecap='null' d='M5 17.5h22M5 26.6h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
- }
- button#bom-ungrouped-btn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m-4 8h3m-3 8h4'/%3E%3Cpath stroke-linecap='null' d='M5 13.5h22m-22 8h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
- }
- button#bom-netlist-btn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg fill='none' stroke='%23000' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-width='2' d='M6 26l6-6v-8m13.8-6.3l-6 6v8'/%3E%3Ccircle cx='11.8' cy='9.5' r='2.8' stroke-width='2'/%3E%3Ccircle cx='19.8' cy='22.8' r='2.8' stroke-width='2'/%3E%3C/g%3E%3C/svg%3E");
- }
- button#copy {
- background-image: url("data:image/svg+xml,%3Csvg height='48' viewBox='0 0 48 48' width='48' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h48v48h-48z' fill='none'/%3E%3Cpath d='M32 2h-24c-2.21 0-4 1.79-4 4v28h4v-28h24v-4zm6 8h-22c-2.21 0-4 1.79-4 4v28c0 2.21 1.79 4 4 4h22c2.21 0 4-1.79 4-4v-28c0-2.21-1.79-4-4-4zm0 32h-22v-28h22v28z'/%3E%3C/svg%3E");
- background-position: 6px 6px;
- background-repeat: no-repeat;
- background-size: 26px 26px;
- border-radius: 6px;
- height: 40px;
- width: 40px;
- margin: 10px 5px;
- }
- button#copy:active {
- box-shadow: inset 0px 0px 5px #6c6c6c;
- }
- textarea.clipboard-temp {
- position: fixed;
- top: 0;
- left: 0;
- width: 2em;
- height: 2em;
- padding: 0;
- border: None;
- outline: None;
- box-shadow: None;
- background: transparent;
- }
- .left-most-button {
- border-right: 0;
- border-top-left-radius: 6px;
- border-bottom-left-radius: 6px;
- }
- .middle-button {
- border-right: 0;
- }
- .right-most-button {
- border-top-right-radius: 6px;
- border-bottom-right-radius: 6px;
- }
- .button-container {
- font-size: 0;
- margin: 0.4rem 0.4rem 0.4rem 0;
- }
- .dark .button-container {
- filter: invert(1);
- }
- .button-container button {
- background-size: 32px 32px;
- background-position: 5px 5px;
- background-repeat: no-repeat;
- }
- @media print {
- .hideonprint {
- display: none;
- }
- }
- canvas {
- cursor: crosshair;
- }
- canvas:active {
- cursor: grabbing;
- }
- .fileinfo {
- width: 100%;
- max-width: 1000px;
- border: none;
- padding: 3px;
- }
- .fileinfo .title {
- font-size: 20pt;
- font-weight: bold;
- }
- .fileinfo td {
- overflow: hidden;
- white-space: nowrap;
- max-width: 1px;
- width: 50%;
- text-overflow: ellipsis;
- }
- .bom {
- border-collapse: collapse;
- font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
- font-size: 10pt;
- table-layout: fixed;
- width: 100%;
- margin-top: 1px;
- position: relative;
- }
- .bom th,
- .bom td {
- border: 1px solid black;
- padding: 5px;
- word-wrap: break-word;
- text-align: center;
- position: relative;
- }
- .dark .bom th,
- .dark .bom td {
- border: 1px solid #777;
- }
- .bom th {
- background-color: #CCCCCC;
- background-clip: padding-box;
- }
- .dark .bom th {
- background-color: #3b4749;
- }
- .bom tr.highlighted:nth-child(n) {
- background-color: #cfc;
- }
- .dark .bom tr.highlighted:nth-child(n) {
- background-color: #226022;
- }
- .bom tr:nth-child(even) {
- background-color: #f2f2f2;
- }
- .dark .bom tr:nth-child(even) {
- background-color: #313b40;
- }
- .bom tr.checked {
- color: #1cb53d;
- }
- .dark .bom tr.checked {
- color: #2cce54;
- }
- .bom tr {
- transition: background-color 0.2s;
- }
- .bom .numCol {
- width: 30px;
- }
- .bom .value {
- width: 15%;
- }
- .bom .quantity {
- width: 65px;
- }
- .bom th .sortmark {
- position: absolute;
- right: 1px;
- top: 1px;
- margin-top: -5px;
- border-width: 5px;
- border-style: solid;
- border-color: transparent transparent #221 transparent;
- transform-origin: 50% 85%;
- transition: opacity 0.2s, transform 0.4s;
- }
- .dark .bom th .sortmark {
- filter: invert(1);
- }
- .bom th .sortmark.none {
- opacity: 0;
- }
- .bom th .sortmark.desc {
- transform: rotate(180deg);
- }
- .bom th:hover .sortmark.none {
- opacity: 0.5;
- }
- .bom .bom-checkbox {
- width: 30px;
- position: relative;
- user-select: none;
- -moz-user-select: none;
- }
- .bom .bom-checkbox:before {
- content: "";
- position: absolute;
- border-width: 15px;
- border-style: solid;
- border-color: #51829f transparent transparent transparent;
- visibility: hidden;
- top: -15px;
- }
- .bom .bom-checkbox:after {
- content: "Double click to set/unset all";
- position: absolute;
- color: white;
- top: -35px;
- left: -26px;
- background: #51829f;
- padding: 5px 15px;
- border-radius: 8px;
- white-space: nowrap;
- visibility: hidden;
- }
- .bom .bom-checkbox:hover:before,
- .bom .bom-checkbox:hover:after {
- visibility: visible;
- transition: visibility 0.2s linear 1s;
- }
- .split {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- overflow-y: auto;
- overflow-x: hidden;
- background-color: inherit;
- }
- .split.split-horizontal,
- .gutter.gutter-horizontal {
- height: 100%;
- float: left;
- }
- .gutter {
- background-color: #ddd;
- background-repeat: no-repeat;
- background-position: 50%;
- transition: background-color 0.3s;
- }
- .dark .gutter {
- background-color: #777;
- }
- .gutter.gutter-horizontal {
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
- cursor: ew-resize;
- width: 5px;
- }
- .gutter.gutter-vertical {
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
- cursor: ns-resize;
- height: 5px;
- }
- .searchbox {
- float: left;
- height: 40px;
- margin: 10px 5px;
- padding: 12px 32px;
- font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
- font-size: 18px;
- box-sizing: border-box;
- border: 1px solid #888;
- border-radius: 6px;
- outline: none;
- background-color: #eee;
- transition: background-color 0.2s, border 0.2s;
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABNklEQVQ4T8XSMUvDQBQH8P/LElFa/AIZHcTBQSz0I/gFstTBRR2KUC4ldDxw7h0Bl3RRUATxi4iiODgoiLNrbQYp5J6cpJJqomkX33Z37/14d/dIa33MzDuYI4johOI4XhyNRteO46zNYjDzAxE1yBZprVeZ+QbAUhXEGJMA2Ox2u4+fQIa0mPmsCgCgJYQ4t7lfgF0opQYAdv9ABkKI/UnOFCClXKjX61cA1osQY8x9kiRNKeV7IWA3oyhaSdP0FkAtjxhj3hzH2RBCPOf3pzqYHCilfAAX+URm9oMguPzeWSGQvUcMYC8rOBJCHBRdqxTo9/vbRHRqi8bj8XKv1xvODbiuW2u32/bvf0SlDv4XYOY7z/Mavu+nM1+BmQ+NMc0wDF/LprP0DbTWW0T00ul0nn4b7Q87+X4Qmfiq2wAAAABJRU5ErkJggg==');
- background-position: 10px 10px;
- background-repeat: no-repeat;
- }
- .dark .searchbox {
- background-color: #111;
- color: #eee;
- }
- .searchbox::placeholder {
- color: #ccc;
- }
- .dark .searchbox::placeholder {
- color: #666;
- }
- .filter {
- width: calc(60% - 64px);
- }
- .reflookup {
- width: calc(40% - 10px);
- }
- input[type=text]:focus {
- background-color: white;
- border: 1px solid #333;
- }
- .dark input[type=text]:focus {
- background-color: #333;
- border: 1px solid #ccc;
- }
- mark.highlight {
- background-color: #5050ff;
- color: #fff;
- padding: 2px;
- border-radius: 6px;
- }
- .dark mark.highlight {
- background-color: #76a6da;
- color: #111;
- }
- .menubtn {
- background-color: white;
- border: none;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 20 20'%3E%3Cpath fill='none' d='M0 0h20v20H0V0z'/%3E%3Cpath d='M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z'/%3E%3C/svg%3E%0A");
- background-position: center;
- background-repeat: no-repeat;
- }
- .statsbtn {
- background-color: white;
- border: none;
- background-image: url("data:image/svg+xml,%3Csvg width='36' height='36' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 6h28v24H4V6zm0 8h28v8H4m9-16v24h10V5.8' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
- background-position: center;
- background-repeat: no-repeat;
- }
- .iobtn {
- background-color: white;
- border: none;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='M3 33v-7l6.8-7h16.5l6.7 7v7H3zM3.2 26H33M21 9l5-5.9 5 6h-2.5V15h-5V9H21zm-4.9 0l-5 6-5-6h2.5V3h5v6h2.5z'/%3E%3Cpath fill='none' stroke='%23000' d='M6.1 29.5H10'/%3E%3C/svg%3E");
- background-position: center;
- background-repeat: no-repeat;
- }
- .visbtn {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' stroke='%23333' d='M2.5 4.5h5v15h-5zM9.5 4.5h5v15h-5zM16.5 4.5h5v15h-5z'/%3E%3C/svg%3E");
- background-position: center;
- background-repeat: no-repeat;
- padding: 15px;
- }
- #vismenu-content {
- left: 0px;
- font-family: Verdana, sans-serif;
- }
- .dark .statsbtn,
- .dark .savebtn,
- .dark .menubtn,
- .dark .iobtn,
- .dark .visbtn {
- filter: invert(1);
- }
- .flexbox {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- }
- .savebtn {
- background-color: #d6d6d6;
- width: auto;
- height: 30px;
- flex-grow: 1;
- margin: 5px;
- border-radius: 4px;
- }
- .savebtn:active {
- background-color: #0a0;
- color: white;
- }
- .dark .savebtn:active {
- /* This will be inverted */
- background-color: #b3b;
- }
- .stats {
- border-collapse: collapse;
- font-size: 12pt;
- table-layout: fixed;
- width: 100%;
- min-width: 450px;
- }
- .dark .stats td {
- border: 1px solid #bbb;
- }
- .stats td {
- border: 1px solid black;
- padding: 5px;
- word-wrap: break-word;
- text-align: center;
- position: relative;
- }
- #checkbox-stats div {
- position: absolute;
- left: 0;
- top: 0;
- height: 100%;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- #checkbox-stats .bar {
- background-color: rgba(28, 251, 0, 0.6);
- }
- .menu {
- position: relative;
- display: inline-block;
- margin: 0.4rem 0.4rem 0.4rem 0;
- }
- .menu-content {
- font-size: 12pt !important;
- text-align: left !important;
- font-weight: normal !important;
- display: none;
- position: absolute;
- background-color: white;
- right: 0;
- min-width: 300px;
- box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
- z-index: 100;
- padding: 8px;
- }
- .dark .menu-content {
- background-color: #111;
- }
- .menu:hover .menu-content {
- display: block;
- }
- .menu:hover .menubtn,
- .menu:hover .iobtn,
- .menu:hover .statsbtn {
- background-color: #eee;
- }
- .menu-label {
- display: inline-block;
- padding: 8px;
- border: 1px solid #ccc;
- border-top: 0;
- width: calc(100% - 18px);
- }
- .menu-label-top {
- border-top: 1px solid #ccc;
- }
- .menu-textbox {
- float: left;
- height: 24px;
- margin: 10px 5px;
- padding: 5px 5px;
- font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
- font-size: 14px;
- box-sizing: border-box;
- border: 1px solid #888;
- border-radius: 4px;
- outline: none;
- background-color: #eee;
- transition: background-color 0.2s, border 0.2s;
- width: calc(100% - 10px);
- }
- .menu-textbox.invalid,
- .dark .menu-textbox.invalid {
- color: red;
- }
- .dark .menu-textbox {
- background-color: #222;
- color: #eee;
- }
- .radio-container {
- margin: 4px;
- }
- .topmostdiv {
- display: flex;
- flex-direction: column;
- width: 100%;
- background-color: white;
- transition: background-color 0.3s;
- }
- #top {
- display: flex;
- flex-wrap: wrap;
- justify-content: flex-end;
- align-items: center;
- }
- #topdivider {
- border-bottom: 2px solid black;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .dark #topdivider {
- border-bottom: 2px solid #ccc;
- }
- #topdivider>div {
- position: relative;
- }
- #toptoggle {
- cursor: pointer;
- user-select: none;
- position: absolute;
- padding: 0.1rem 0.3rem;
- top: -0.4rem;
- left: -1rem;
- font-size: 1.4rem;
- line-height: 60%;
- border: 1px solid black;
- border-radius: 1rem;
- background-color: #fff;
- z-index: 100;
- }
- .flipped {
- transform: rotate(0.5turn);
- }
- .dark #toptoggle {
- border: 1px solid #fff;
- background-color: #222;
- }
- #fileinfodiv {
- flex: 20rem 1 0;
- overflow: auto;
- }
- #bomcontrols {
- display: flex;
- flex-direction: row-reverse;
- }
- #bomcontrols>* {
- flex-shrink: 0;
- }
- #dbg {
- display: block;
- }
- ::-webkit-scrollbar {
- width: 8px;
- }
- ::-webkit-scrollbar-track {
- background: #aaa;
- }
- ::-webkit-scrollbar-thumb {
- background: #666;
- border-radius: 3px;
- }
- ::-webkit-scrollbar-thumb:hover {
- background: #555;
- }
- .slider {
- -webkit-appearance: none;
- width: 100%;
- margin: 3px 0;
- padding: 0;
- outline: none;
- opacity: 0.7;
- -webkit-transition: .2s;
- transition: opacity .2s;
- border-radius: 3px;
- }
- .slider:hover {
- opacity: 1;
- }
- .slider:focus {
- outline: none;
- }
- .slider::-webkit-slider-runnable-track {
- -webkit-appearance: none;
- width: 100%;
- height: 8px;
- background: #d3d3d3;
- border-radius: 3px;
- border: none;
- }
- .slider::-webkit-slider-thumb {
- -webkit-appearance: none;
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #0a0;
- cursor: pointer;
- margin-top: -4px;
- }
- .dark .slider::-webkit-slider-thumb {
- background: #3d3;
- }
- .slider::-moz-range-thumb {
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #0a0;
- cursor: pointer;
- }
- .slider::-moz-range-track {
- height: 8px;
- background: #d3d3d3;
- border-radius: 3px;
- }
- .dark .slider::-moz-range-thumb {
- background: #3d3;
- }
- .slider::-ms-track {
- width: 100%;
- height: 8px;
- border-width: 3px 0;
- background: transparent;
- border-color: transparent;
- color: transparent;
- transition: opacity .2s;
- }
- .slider::-ms-fill-lower {
- background: #d3d3d3;
- border: none;
- border-radius: 3px;
- }
- .slider::-ms-fill-upper {
- background: #d3d3d3;
- border: none;
- border-radius: 3px;
- }
- .slider::-ms-thumb {
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #0a0;
- cursor: pointer;
- margin: 0;
- }
- .shameless-plug {
- font-size: 0.8em;
- text-align: center;
- display: block;
- }
- a {
- color: #0278a4;
- }
- .dark a {
- color: #00b9fd;
- }
- #frontcanvas,
- #backcanvas {
- touch-action: none;
- }
- .placeholder {
- border: 1px dashed #9f9fda !important;
- background-color: #edf2f7 !important;
- }
- .dragging {
- z-index: 999;
- }
- .dark .dragging>table>tbody>tr {
- background-color: #252c30;
- }
- .dark .placeholder {
- filter: invert(1);
- }
- .column-spacer {
- top: 0;
- left: 0;
- width: calc(100% - 4px);
- position: absolute;
- cursor: pointer;
- user-select: none;
- height: 100%;
- }
- .column-width-handle {
- top: 0;
- right: 0;
- width: 4px;
- position: absolute;
- cursor: col-resize;
- user-select: none;
- height: 100%;
- }
- .column-width-handle:hover {
- background-color: #4f99bd;
- }
- .help-link {
- border: 1px solid #0278a4;
- padding-inline: 0.3rem;
- border-radius: 3px;
- cursor: pointer;
- }
- .dark .help-link {
- border: 1px solid #00b9fd;
- }
- .bom-color {
- width: 20%;
- }
- .color-column input {
- width: 1.6rem;
- height: 1rem;
- border: 1px solid black;
- cursor: pointer;
- padding: 0;
- }
- /* removes default styling from input color element */
- ::-webkit-color-swatch {
- border: none;
- }
- ::-webkit-color-swatch-wrapper {
- padding: 0;
- }
- ::-moz-color-swatch,
- ::-moz-focus-inner {
- border: none;
- }
- ::-moz-focus-inner {
- padding: 0;
- }
- /* #bomhead {
- position: sticky;
- top: 0px;
- z-index: 1;
- } */
- </style>
- <script type="text/javascript" >
- ///////////////////////////////////////////////
- /*
- Split.js - v1.3.5
- MIT License
- https://github.com/nathancahill/Split.js
- */
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Split=t()}(this,function(){"use strict";var e=window,t=e.document,n="addEventListener",i="removeEventListener",r="getBoundingClientRect",s=function(){return!1},o=e.attachEvent&&!e[n],a=["","-webkit-","-moz-","-o-"].filter(function(e){var n=t.createElement("div");return n.style.cssText="width:"+e+"calc(9px)",!!n.style.length}).shift()+"calc",l=function(e){return"string"==typeof e||e instanceof String?t.querySelector(e):e};return function(u,c){function z(e,t,n){var i=A(y,t,n);Object.keys(i).forEach(function(t){return e.style[t]=i[t]})}function h(e,t){var n=B(y,t);Object.keys(n).forEach(function(t){return e.style[t]=n[t]})}function f(e){var t=E[this.a],n=E[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,z(t.element,t.size,this.aGutterSize),z(n.element,n.size,this.bGutterSize)}function m(e){var t;this.dragging&&((t="touches"in e?e.touches[0][b]-this.start:e[b]-this.start)<=E[this.a].minSize+M+this.aGutterSize?t=E[this.a].minSize+this.aGutterSize:t>=this.size-(E[this.b].minSize+M+this.bGutterSize)&&(t=this.size-(E[this.b].minSize+this.bGutterSize)),f.call(this,t),c.onDrag&&c.onDrag())}function g(){var e=E[this.a].element,t=E[this.b].element;this.size=e[r]()[y]+t[r]()[y]+this.aGutterSize+this.bGutterSize,this.start=e[r]()[G]}function d(){var t=this,n=E[t.a].element,r=E[t.b].element;t.dragging&&c.onDragEnd&&c.onDragEnd(),t.dragging=!1,e[i]("mouseup",t.stop),e[i]("touchend",t.stop),e[i]("touchcancel",t.stop),t.parent[i]("mousemove",t.move),t.parent[i]("touchmove",t.move),delete t.stop,delete t.move,n[i]("selectstart",s),n[i]("dragstart",s),r[i]("selectstart",s),r[i]("dragstart",s),n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",t.gutter.style.cursor="",t.parent.style.cursor=""}function S(t){var i=this,r=E[i.a].element,o=E[i.b].element;!i.dragging&&c.onDragStart&&c.onDragStart(),t.preventDefault(),i.dragging=!0,i.move=m.bind(i),i.stop=d.bind(i),e[n]("mouseup",i.stop),e[n]("touchend",i.stop),e[n]("touchcancel",i.stop),i.parent[n]("mousemove",i.move),i.parent[n]("touchmove",i.move),r[n]("selectstart",s),r[n]("dragstart",s),o[n]("selectstart",s),o[n]("dragstart",s),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",i.gutter.style.cursor=j,i.parent.style.cursor=j,g.call(i)}function v(e){e.forEach(function(t,n){if(n>0){var i=F[n-1],r=E[i.a],s=E[i.b];r.size=e[n-1],s.size=t,z(r.element,r.size,i.aGutterSize),z(s.element,s.size,i.bGutterSize)}})}function p(){F.forEach(function(e){e.parent.removeChild(e.gutter),E[e.a].element.style[y]="",E[e.b].element.style[y]=""})}void 0===c&&(c={});var y,b,G,E,w=l(u[0]).parentNode,D=e.getComputedStyle(w).flexDirection,U=c.sizes||u.map(function(){return 100/u.length}),k=void 0!==c.minSize?c.minSize:100,x=Array.isArray(k)?k:u.map(function(){return k}),L=void 0!==c.gutterSize?c.gutterSize:10,M=void 0!==c.snapOffset?c.snapOffset:30,O=c.direction||"horizontal",j=c.cursor||("horizontal"===O?"ew-resize":"ns-resize"),C=c.gutter||function(e,n){var i=t.createElement("div");return i.className="gutter gutter-"+n,i},A=c.elementStyle||function(e,t,n){var i={};return"string"==typeof t||t instanceof String?i[e]=t:i[e]=o?t+"%":a+"("+t+"% - "+n+"px)",i},B=c.gutterStyle||function(e,t){return n={},n[e]=t+"px",n;var n};"horizontal"===O?(y="width","clientWidth",b="clientX",G="left","paddingLeft"):"vertical"===O&&(y="height","clientHeight",b="clientY",G="top","paddingTop");var F=[];return E=u.map(function(e,t){var i,s={element:l(e),size:U[t],minSize:x[t]};if(t>0&&(i={a:t-1,b:t,dragging:!1,isFirst:1===t,isLast:t===u.length-1,direction:O,parent:w},i.aGutterSize=L,i.bGutterSize=L,i.isFirst&&(i.aGutterSize=L/2),i.isLast&&(i.bGutterSize=L/2),"row-reverse"===D||"column-reverse"===D)){var a=i.a;i.a=i.b,i.b=a}if(!o&&t>0){var c=C(t,O);h(c,L),c[n]("mousedown",S.bind(i)),c[n]("touchstart",S.bind(i)),w.insertBefore(c,s.element),i.gutter=c}0===t||t===u.length-1?z(s.element,s.size,L/2):z(s.element,s.size,L);var f=s.element[r]()[y];return f<s.minSize&&(s.minSize=f),t>0&&F.push(i),s}),o?{setSizes:v,destroy:p}:{setSizes:v,getSizes:function(){return E.map(function(e){return e.size})},collapse:function(e){if(e===F.length){var t=F[e-1];g.call(t),o||f.call(t,t.size-t.bGutterSize)}else{var n=F[e];g.call(n),o||f.call(n,n.aGutterSize)}},destroy:p}}});
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- // Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
- // This work is free. You can redistribute it and/or modify it
- // under the terms of the WTFPL, Version 2
- // For more information see LICENSE.txt or http://www.wtfpl.net/
- //
- // For more information, the home page:
- // http://pieroxy.net/blog/pages/lz-string/testing.html
- //
- // LZ-based compression algorithm, version 1.4.4
- var LZString=function(){var o=String.fromCharCode,i={};var n={decompressFromBase64:function(o){return null==o?"":""==o?null:n._decompress(o.length,32,function(n){return function(o,n){if(!i[o]){i[o]={};for(var t=0;t<o.length;t++)i[o][o.charAt(t)]=t}return i[o][n]}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",o.charAt(n))})},_decompress:function(i,n,t){var r,e,a,s,p,u,l,f=[],c=4,d=4,h=3,v="",g=[],m={val:t(0),position:n,index:1};for(r=0;r<3;r+=1)f[r]=r;for(a=0,p=Math.pow(2,2),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 2:return""}for(f[3]=l,e=l,g.push(l);;){if(m.index>i)return"";for(a=0,p=Math.pow(2,h),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(l=a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 2:return g.join("")}if(0==c&&(c=Math.pow(2,h),h++),f[l])v=f[l];else{if(l!==d)return null;v=e+e.charAt(0)}g.push(v),f[d++]=e+v.charAt(0),e=v,0==--c&&(c=Math.pow(2,h),h++)}}};return n}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString});
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- /*!
- * PEP v0.4.3 | https://github.com/jquery/PEP
- * Copyright jQuery Foundation and other contributors | http://jquery.org/license
- */
- !function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.PointerEventsPolyfill=b()}(this,function(){"use strict";function a(a,b){b=b||Object.create(null);var c=document.createEvent("Event");c.initEvent(a,b.bubbles||!1,b.cancelable||!1);
- for(var d,e=2;e<m.length;e++)d=m[e],c[d]=b[d]||n[e];c.buttons=b.buttons||0;
- var f=0;return f=b.pressure&&c.buttons?b.pressure:c.buttons?.5:0,c.x=c.clientX,c.y=c.clientY,c.pointerId=b.pointerId||0,c.width=b.width||0,c.height=b.height||0,c.pressure=f,c.tiltX=b.tiltX||0,c.tiltY=b.tiltY||0,c.twist=b.twist||0,c.tangentialPressure=b.tangentialPressure||0,c.pointerType=b.pointerType||"",c.hwTimestamp=b.hwTimestamp||0,c.isPrimary=b.isPrimary||!1,c}function b(){this.array=[],this.size=0}function c(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),A&&(this.observer=new A(this.mutationWatcher.bind(this)))}function d(a){return"body /shadow-deep/ "+e(a)}function e(a){return'[touch-action="'+a+'"]'}function f(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; }"}function g(){if(F){D.forEach(function(a){String(a)===a?(E+=e(a)+f(a)+"\n",G&&(E+=d(a)+f(a)+"\n")):(E+=a.selectors.map(e)+f(a.rule)+"\n",G&&(E+=a.selectors.map(d)+f(a.rule)+"\n"))});var a=document.createElement("style");a.textContent=E,document.head.appendChild(a)}}function h(){if(!window.PointerEvent){if(window.PointerEvent=a,window.navigator.msPointerEnabled){var b=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:b,enumerable:!0}),u.registerSource("ms",_)}else Object.defineProperty(window.navigator,"maxTouchPoints",{value:0,enumerable:!0}),u.registerSource("mouse",N),void 0!==window.ontouchstart&&u.registerSource("touch",V);u.register(document)}}function i(a){if(!u.pointermap.has(a)){var b=new Error("InvalidPointerId");throw b.name="InvalidPointerId",b}}function j(a){for(var b=a.parentNode;b&&b!==a.ownerDocument;)b=b.parentNode;if(!b){var c=new Error("InvalidStateError");throw c.name="InvalidStateError",c}}function k(a){var b=u.pointermap.get(a);return 0!==b.buttons}function l(){window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:W},releasePointerCapture:{value:X},hasPointerCapture:{value:Y}})}
- var m=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],n=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],o=window.Map&&window.Map.prototype.forEach,p=o?Map:b;b.prototype={set:function(a,b){return void 0===b?this["delete"](a):(this.has(a)||this.size++,void(this.array[a]=b))},has:function(a){return void 0!==this.array[a]},"delete":function(a){this.has(a)&&(delete this.array[a],this.size--)},get:function(a){return this.array[a]},clear:function(){this.array.length=0,this.size=0},forEach:function(a,b){return this.array.forEach(function(c,d){a.call(b,c,d,this)},this)}};var q=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp"],r=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],s={pointerover:1,pointerout:1,pointerenter:1,pointerleave:1},t="undefined"!=typeof SVGElementInstance,u={pointermap:new p,eventMap:Object.create(null),captureInfo:Object.create(null),eventSources:Object.create(null),eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
- b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
- b.unregister.call(b,a)},contains:function(a,b){try{return a.contains(b)}catch(c){return!1}},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.propagate(a,this.leave,!1)},enterOver:function(a){this.over(a),this.propagate(a,this.enter,!0)},eventHandler:function(a){if(!a._handledByPE){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),a._handledByPE=!0}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(b,c){this.captureInfo[c.pointerId]&&(c.relatedTarget=null);var d=new a(b,c);return c.preventDefault&&(d.preventDefault=c.preventDefault),d._target=d._target||c.target,d},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,c=Object.create(null),d=0;d<q.length;d++)b=q[d],c[b]=a[b]||r[d],!t||"target"!==b&&"relatedTarget"!==b||c[b]instanceof SVGElementInstance&&(c[b]=c[b].correspondingUseElement);return a.preventDefault&&(c.preventDefault=function(){a.preventDefault()}),c},getTarget:function(a){var b=this.captureInfo[a.pointerId];return b?a._target!==b&&a.type in s?void 0:b:a._target},propagate:function(a,b,c){for(var d=a.target,e=[];d!==document&&!d.contains(a.relatedTarget);) if(e.push(d),d=d.parentNode,!d)return;c&&e.reverse(),e.forEach(function(c){a.target=c,b.call(this,a)},this)},setCapture:function(b,c,d){this.captureInfo[b]&&this.releaseCapture(b,d),this.captureInfo[b]=c,this.implicitRelease=this.releaseCapture.bind(this,b,d),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease);var e=new a("gotpointercapture");e.pointerId=b,e._target=c,d||this.asyncDispatchEvent(e)},releaseCapture:function(b,c){var d=this.captureInfo[b];if(d){this.captureInfo[b]=void 0,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease);var e=new a("lostpointercapture");e.pointerId=b,e._target=d,c||this.asyncDispatchEvent(e)}},dispatchEvent:/*scope.external.dispatchEvent || */function(a){var b=this.getTarget(a);if(b)return b.dispatchEvent(a)},asyncDispatchEvent:function(a){requestAnimationFrame(this.dispatchEvent.bind(this,a))}};u.boundHandler=u.eventHandler.bind(u);var v={shadow:function(a){if(a)return a.shadowRoot||a.webkitShadowRoot},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);if(this.canTarget(b))return b},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d} e=this.olderShadow(e)} return f}},owner:function(a){
- for(var b=a;b.parentNode;)b=b.parentNode;
- return b.nodeType!==Node.DOCUMENT_NODE&&b.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target);
- return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}},w=Array.prototype.forEach.call.bind(Array.prototype.forEach),x=Array.prototype.map.call.bind(Array.prototype.map),y=Array.prototype.slice.call.bind(Array.prototype.slice),z=Array.prototype.filter.call.bind(Array.prototype.filter),A=window.MutationObserver||window.WebKitMutationObserver,B="[touch-action]",C={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};c.prototype={watchSubtree:function(a){
- //
- this.observer&&v.canTarget(a)&&this.observer.observe(a,C)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){w(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(B):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(y(b))},
- installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){
- var b=x(a,this.findElements,this);
- return b.push(z(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}};var D=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],E="",F=window.PointerEvent||window.MSPointerEvent,G=!window.ShadowDOMPolyfill&&document.head.createShadowRoot,H=u.pointermap,I=25,J=[1,4,2,8,16],K=!1;try{K=1===new MouseEvent("test",{buttons:1}).buttons}catch(L){}
- var M,N={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},lastTouches:[],
- isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,d=a.clientX,e=a.clientY,f=0,g=c.length;f<g&&(b=c[f]);f++){
- var h=Math.abs(d-b.x),i=Math.abs(e-b.y);if(h<=I&&i<=I)return!0}},prepareEvent:function(a){var b=u.cloneEvent(a),c=b.preventDefault;return b.preventDefault=function(){a.preventDefault(),c()},b.pointerId=this.POINTER_ID,b.isPrimary=!0,b.pointerType=this.POINTER_TYPE,b},prepareButtonsForMove:function(a,b){var c=H.get(this.POINTER_ID);
- 0!==b.which&&c?a.buttons=c.buttons:a.buttons=0,b.buttons=a.buttons},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);K||(c.buttons=J[c.button],b&&(c.buttons|=b.buttons),a.buttons=c.buttons),H.set(this.POINTER_ID,a),b&&0!==b.buttons?u.move(c):u.down(c)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.move(b)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);if(!K){var d=J[c.button];
- c.buttons=b?b.buttons&~d:0,a.buttons=c.buttons}H.set(this.POINTER_ID,a),
- c.buttons&=~J[c.button],0===c.buttons?u.up(c):u.move(c)}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.enterOver(b)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,u.leaveOut(b)}},cancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.deactivateMouse()},deactivateMouse:function(){H["delete"](this.POINTER_ID)}},O=u.captureInfo,P=v.findTarget.bind(v),Q=v.allShadows.bind(v),R=u.pointermap,S=2500,T=200,U="touch-action",V={events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){M.enableOnSubtree(a)},unregister:function(){},elementAdded:function(a){var b=a.getAttribute(U),c=this.touchActionToScrollType(b);c&&(a._scrollType=c,u.listen(a,this.events),
- Q(a).forEach(function(a){a._scrollType=c,u.listen(a,this.events)},this))},elementRemoved:function(a){a._scrollType=void 0,u.unlisten(a,this.events),
- Q(a).forEach(function(a){a._scrollType=void 0,u.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(U),d=this.touchActionToScrollType(c),e=this.touchActionToScrollType(b);
- d&&e?(a._scrollType=d,Q(a).forEach(function(a){a._scrollType=d},this)):e?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){
- (0===R.size||1===R.size&&R.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,T)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return"touchstart"!==a&&"touchmove"!==a||(b=1),b},touchToPointer:function(a){var b=this.currentTouchEvent,c=u.cloneEvent(a),d=c.pointerId=a.identifier+2;c.target=O[d]||P(c),c.bubbles=!0,c.cancelable=!0,c.detail=this.clickCount,c.button=0,c.buttons=this.typeToButtons(b.type),c.width=2*(a.radiusX||a.webkitRadiusX||0),c.height=2*(a.radiusY||a.webkitRadiusY||0),c.pressure=a.force||a.webkitForce||.5,c.isPrimary=this.isPrimaryTouch(a),c.pointerType=this.POINTER_TYPE,
- c.altKey=b.altKey,c.ctrlKey=b.ctrlKey,c.metaKey=b.metaKey,c.shiftKey=b.shiftKey;
- var e=this;return c.preventDefault=function(){e.scrolling=!1,e.firstXY=null,b.preventDefault()},c},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a;for(var d,e=0;e<c.length;e++)d=c[e],b.call(this,this.touchToPointer(d))},
- shouldScroll:function(a){if(this.firstXY){var b,c=a.currentTarget._scrollType;if("none"===c)
- b=!1;else if("XY"===c)
- b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]);
- b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;d<e&&(c=a[d]);d++)if(c.identifier===b)return!0},
- vacuumTouches:function(a){var b=a.touches;
- if(R.size>=b.length){var c=[];R.forEach(function(a,d){
- if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(e)}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){R.set(a.pointerId,{target:a.target,out:a,outTarget:a.target}),u.enterOver(a),u.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,c=R.get(b.pointerId);
- if(c){var d=c.out,e=c.outTarget;u.move(b),d&&e!==b.target&&(d.relatedTarget=b.target,b.relatedTarget=e,
- d.target=e,b.target?(u.leaveOut(d),u.enterOver(b)):(
- b.target=e,b.relatedTarget=null,this.cancelOut(b))),c.out=b,c.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(u.up(a),u.leaveOut(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){u.cancel(a),u.leaveOut(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){R["delete"](a.pointerId),this.removePrimaryPointer(a)},
- dedupSynthMouse:function(a){var b=N.lastTouches,c=a.changedTouches[0];
- if(this.isPrimaryTouch(c)){
- var d={x:c.clientX,y:c.clientY};b.push(d);var e=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,b,d);setTimeout(e,S)}}};M=new c(V.elementAdded,V.elementRemoved,V.elementChanged,V);var W,X,Y,Z=u.pointermap,$=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,_={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var b=a;return $&&(b=u.cloneEvent(a),b.pointerType=this.POINTER_TYPES[a.pointerType]),b},cleanup:function(a){Z["delete"](a)},MSPointerDown:function(a){Z.set(a.pointerId,a);var b=this.prepareEvent(a);u.down(b)},MSPointerMove:function(a){var b=this.prepareEvent(a);u.move(b)},MSPointerUp:function(a){var b=this.prepareEvent(a);u.up(b),this.cleanup(a.pointerId)},MSPointerOut:function(a){var b=this.prepareEvent(a);u.leaveOut(b)},MSPointerOver:function(a){var b=this.prepareEvent(a);u.enterOver(b)},MSPointerCancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var b=u.makeEvent("lostpointercapture",a);u.dispatchEvent(b)},MSGotPointerCapture:function(a){var b=u.makeEvent("gotpointercapture",a);u.dispatchEvent(b)}},aa=window.navigator;aa.msPointerEnabled?(W=function(a){i(a),j(this),k(a)&&(u.setCapture(a,this,!0),this.msSetPointerCapture(a))},X=function(a){i(a),u.releaseCapture(a,!0),this.msReleasePointerCapture(a)}):(W=function(a){i(a),j(this),k(a)&&u.setCapture(a,this)},X=function(a){i(a),u.releaseCapture(a)}),Y=function(a){return!!u.captureInfo[a]},g(),h(),l();var ba={dispatcher:u,Installer:c,PointerEvent:a,PointerMap:p,targetFinding:v};return ba});
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- var config = {"dark_mode": false, "show_pads": true, "show_fabrication": false, "show_silkscreen": true, "highlight_pin1": "none", "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "offset_back_rotation": false, "kicad_text_formatting": true, "fields": ["Value", "Footprint", "Partkeepr"]}
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- var pcbdata = JSON.parse(LZString.decompressFromBase64("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aEoHzBHd7tIAC9bUntLh0iHbAAYh337URtqO2Tbb4dvR0grdqEXRzNHYRtDh1GHbCtYx0k7UwdW+3ZHcjtsR1GbfMd5B36oLHCauxDHSvtIx0ZbX1t2B2uHXgd7h3THQLtT+1ZrRYdxR3EgHYtpR3nbe+t0m3VHUfttR3W0GltwB3aHWcgjR3q7Ssdn20N7VAd6x38AK2tQzSt7brt3R0ErQsd3608Lblp1m2oHakdkJ0Ybevtwh2b7YHtd+2sHaXAzS3eHc7thx0R7YId1tDIgmcdoR3WrVid4x04naIdeJ05HdTtcR0kndYdscJoHJSdEa2ZbdftOB1ZHdEdex25HYFt+R3P7TIdue1yHWItH+2cAGdtlS5fHX0d/wDEHImcmh2PbVYAOh3Ane1A+h1tAhCdFx0rbXptyC1dHfit5G2Indk0KZpgVKidKR0hHRGtkaLOHVsdkR07HXydGe3YrUSd0+3wnQadRx2CiiGohbR87IvtaJ3mnWkdlp0ZHYwdNp24nbsd9p31bcydzp1iLRHtQuwKnRydvp2bHXDtdJ2THQyd/J0mLXkdd60v7c8dti0KHZLtP+3KHX/tBq1G1IAdzpjK7YCdqu2vbU0dXp3WAK0dAMS6bR0d+m1mHTYAzx04LYad7/TynTVUMZ0YnattNJ3Wnbyddx34ncRtcx3hnc2dWEitnWkQ7Z1anUxtVx2ZHVttnG3B7Q/toZ0HHYOdrp3tNGuy1B2LLWsd450bHV2d8Z3bHUGddp3j7ZntqZ0HbSKdr+1inW8dhe2S7TQAL81l7d8dVIA9QEMAP81aHXctQJ1q7WqdoJ1Vne0dJh11nXqdTZ1Lnccl5XxpnPYd6J0bndSd4R0BnT2dM50eHVTtsx0kHYudkZ16gInwIS2AXT6dHZ1cndcdEx1THX2dTp36nRGdXB2AbEAMpp1rnUBdox1bnTft050jbfudj+2HnQUdRR2ZnRKdIABnbbLqMp0eLYbsQwAtaMWdT52lnWAdFZ0tHeCdbR1pHdCdcB3mHTFtQ52P0iXAd/QAXbHt653EXaBd2J07nfSdwZ0UXQSdU+3sHdhdIl3SXGJduSB1nMzt3p3DHdJdVp3bnYGd8l17nXOdTJ0LnapdS524AqxdJC2SXURdlx1xnaRdqe29nYydkh1CnU8dOa2cAGed+a1lHXIAV51VHbKd1KiFnY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usxtQrl/AmKxhrWGs4a+2A+GtCrWmAFCtkAHgAbktaAJWrJiu2axZrEmvxq5wAoKCiLcWAwisboIGzqkseQ9qrqkuBsyRUFR1R4fYrFSuYa9hruGvNa98ArWvta51rnADda6MABCLJa0VrOmsRq0CqO2uZq2mATABTExUdcSsRACsrZkYIqxoAoi1La41reGvtgGtrbWsda+2r9iuZaw4tTDMUABQrAGv44O4rR4CaS5MrPrD2K82rjyvPKx5DKABTADAAEmswgLpAO2tdq+Dr8ACQ69DruW1Ga+cr0jD2K0OrSOso6zDruWslK5jrO2s0a3QA7mDwAO+tJOuNQGTr3yuRAN2th0CiLWoAEmucwJwYowDqQKItgbPeAF4AHytaAJ/tVADygMWARFQeQ0RUwivibbYr7UC06/urIADMK6QrXqtsK4zrvCss62JrKWv9a+lru4Aqa56r3qvK68zrWgCTsntrqWuHa7TrWmt9a/jrIWsq6wZrRuvFa/rrLOtDqzGrxusDayAABQBha0rrtuvpaydAjuv7a+jrduvowMNrTyvI61DreOsW6wTrGiujACCA3usQ637raOt9q3DrkSuZqzjr4euw64TrK6s3q7HrqOvx60HrK6uZa8nr/usHa4Hr8Osrq4br9muRaxOrK6tdqwzrxutM65ErQ6ul6wHr/avki8HrxOu0K+xrteuTKz+rKS1V69nrNeta6yUrz2ut6w3r8mtbzI0rKgD0673rDGtN613rmatt6+jr5evJKzJrF6t965cLySuZa3ZrQWtF613rzauHq2XrJ6vJK12r6+vV61eryStDqzvr7et7683rNGuH65Prm+uTKwYT56uM6xfrBOsVK2frwmt8q5frEusP633ru6uX65mrr+vqa0/rBOs3qzgMbiuf7eJtWGtCrXjgHWs5K6Abm2scK7G4jStTKz0dABtAG44rFR0QG+Ab9IBva4Yr0BvlK4brTuvV63br6hZhawXrc6sTqz5qioChACNLPksB4HFLgUtBy04tWUuUy9FLuUuQK9FLTZOjIEVLHXO9+BtLTUtFS61LK0uqy0ArZBsYkzvA9csxy6tLCUArSwKrUS1/yyNL0MMoyzfLsmMCy4wbLmNrS/DLmWNrS6HLsmOSy99LN3QTHNLL8ssXyyLDHXMkxMTLUMuyGyjLdBteQ1jLCht3y8Cz70sEy8XgBst7Swob4hvknWDLgMudy1IbqsuUABdLTZMwAzrLWUtCG1IbJe1mywbLFsvxy8bL0MMCy9XLI0vHLVtLDsuZy5Eb5G2py75L1uAZy1tLoRs1yznL/hsJG/nLFctey24bCRtly/EbPKMrQ09AFcsoy5kbPKONy8kbhcsty7PL5G3ty1EteRurK0R9gMu1G00bJe0VgDNLxH1+DvHgC0vzy0MAi8v7y6fLh8uny4/LM0sfy2nLM0sAK1ptM0sgK/PAYCubuSeAUUvQK2/iMxvwKzMb3RsoKxrdpBveS6FLW8uqc50AkUv5Sx1zsUv5SwlLehvJSwcb1BvpSzfLha0Cy9QbmVOsXTVLI8vlGx2zBxtpG2QbY0uNGw4tU0uwK9FLnUtfG0tLO8CtG4dLZ0sAgCdLtUvGIBdLHXOOJNdLoJuyGwhLDkhmG6oAI8tqG8TAI8sKGz9LSUgqy6TLpUtLQwVLh0AXSyDL8Jt0y0HLsmPQm+2AzMugm2YbGgt5RJzLoJvvG9LLbst6Gw4joJtby7DLwRAHS4jLshvoy7+DBsugm78bdsuBgA7LCxt6G67LHwMey17LuJu+y81oHssrQwdkLsuky6HLhy3hy1vLxy3HG78bw8sBCBqbRH3gy5XDvRvsyyvLa8uLy5vLi8s7y0fLZ0u4m2fLZ0t6G1fLxjMPyzdLCCvPy6GzBxt8Gy7LP8uZ8Jp0583pNLYA8ADyS+IAcoA+agQArkvwAPGAHB0hahk0xIDxgNHAygDpcEAAAA"))
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- /* Utility functions */
- var storagePrefix = 'KiCad_HTML_BOM__' + pcbdata.metadata.title + '__' +
- pcbdata.metadata.revision + '__#';
- var storage;
- function initStorage(key) {
- try {
- window.localStorage.getItem("blank");
- storage = window.localStorage;
- } catch (e) {
- // localStorage not available
- }
- if (!storage) {
- try {
- window.sessionStorage.getItem("blank");
- storage = window.sessionStorage;
- } catch (e) {
- // sessionStorage also not available
- }
- }
- }
- function readStorage(key) {
- if (storage) {
- return storage.getItem(storagePrefix + key);
- } else {
- return null;
- }
- }
- function writeStorage(key, value) {
- if (storage) {
- storage.setItem(storagePrefix + key, value);
- }
- }
- function fancyDblClickHandler(el, onsingle, ondouble) {
- return function () {
- if (el.getAttribute("data-dblclick") == null) {
- el.setAttribute("data-dblclick", 1);
- setTimeout(function () {
- if (el.getAttribute("data-dblclick") == 1) {
- onsingle();
- }
- el.removeAttribute("data-dblclick");
- }, 200);
- } else {
- el.removeAttribute("data-dblclick");
- ondouble();
- }
- }
- }
- function smoothScrollToRow(rowid) {
- document.getElementById(rowid).scrollIntoView({
- behavior: "smooth",
- block: "center",
- inline: "nearest"
- });
- }
- function focusInputField(input) {
- input.scrollIntoView(false);
- input.focus();
- input.select();
- }
- function saveBomTable(output) {
- var text = '';
- for (var node of bomhead.childNodes[0].childNodes) {
- if (node.firstChild) {
- text += (output == 'csv' ? `"${node.firstChild.nodeValue}"` : node.firstChild.nodeValue);
- }
- if (node != bomhead.childNodes[0].lastChild) {
- text += (output == 'csv' ? ',' : '\t');
- }
- }
- text += '\n';
- for (var row of bombody.childNodes) {
- for (var cell of row.childNodes) {
- let val = '';
- for (var node of cell.childNodes) {
- if (node.nodeName == "INPUT") {
- if (node.checked) {
- val += '✓';
- }
- } else if ((node.nodeName == "MARK") || (node.nodeName == "A")) {
- val += node.firstChild.nodeValue;
- } else {
- val += node.nodeValue;
- }
- }
- if (output == 'csv') {
- val = val.replace(/\"/g, '\"\"'); // pair of double-quote characters
- if (isNumeric(val)) {
- val = +val; // use number
- } else {
- val = `"${val}"`; // enclosed within double-quote
- }
- }
- text += val;
- if (cell != row.lastChild) {
- text += (output == 'csv' ? ',' : '\t');
- }
- }
- text += '\n';
- }
- if (output != 'clipboard') {
- // To file: csv or txt
- var blob = new Blob([text], {
- type: `text/${output}`
- });
- saveFile(`${pcbdata.metadata.title}.${output}`, blob);
- } else {
- // To clipboard
- var textArea = document.createElement("textarea");
- textArea.classList.add('clipboard-temp');
- textArea.value = text;
- document.body.appendChild(textArea);
- textArea.focus();
- textArea.select();
- try {
- if (document.execCommand('copy')) {
- console.log('Bom copied to clipboard.');
- }
- } catch (err) {
- console.log('Can not copy to clipboard.');
- }
- document.body.removeChild(textArea);
- }
- }
- function isNumeric(str) {
- /* https://stackoverflow.com/a/175787 */
- return (typeof str != "string" ? false : !isNaN(str) && !isNaN(parseFloat(str)));
- }
- function removeGutterNode(node) {
- for (var i = 0; i < node.childNodes.length; i++) {
- if (node.childNodes[i].classList &&
- node.childNodes[i].classList.contains("gutter")) {
- node.removeChild(node.childNodes[i]);
- break;
- }
- }
- }
- function cleanGutters() {
- removeGutterNode(document.getElementById("bot"));
- removeGutterNode(document.getElementById("canvasdiv"));
- }
- var units = {
- prefixes: {
- giga: ["G", "g", "giga", "Giga", "GIGA"],
- mega: ["M", "mega", "Mega", "MEGA"],
- kilo: ["K", "k", "kilo", "Kilo", "KILO"],
- milli: ["m", "milli", "Milli", "MILLI"],
- micro: ["U", "u", "micro", "Micro", "MICRO", "μ", "µ"], // different utf8 μ
- nano: ["N", "n", "nano", "Nano", "NANO"],
- pico: ["P", "p", "pico", "Pico", "PICO"],
- },
- unitsShort: ["R", "r", "Ω", "F", "f", "H", "h"],
- unitsLong: [
- "OHM", "Ohm", "ohm", "ohms",
- "FARAD", "Farad", "farad",
- "HENRY", "Henry", "henry"
- ],
- getMultiplier: function (s) {
- if (this.prefixes.giga.includes(s)) return 1e9;
- if (this.prefixes.mega.includes(s)) return 1e6;
- if (this.prefixes.kilo.includes(s)) return 1e3;
- if (this.prefixes.milli.includes(s)) return 1e-3;
- if (this.prefixes.micro.includes(s)) return 1e-6;
- if (this.prefixes.nano.includes(s)) return 1e-9;
- if (this.prefixes.pico.includes(s)) return 1e-12;
- return 1;
- },
- valueRegex: null,
- }
- function initUtils() {
- var allPrefixes = units.prefixes.giga
- .concat(units.prefixes.mega)
- .concat(units.prefixes.kilo)
- .concat(units.prefixes.milli)
- .concat(units.prefixes.micro)
- .concat(units.prefixes.nano)
- .concat(units.prefixes.pico);
- var allUnits = units.unitsShort.concat(units.unitsLong);
- units.valueRegex = new RegExp("^([0-9\.]+)" +
- "\\s*(" + allPrefixes.join("|") + ")?" +
- "(" + allUnits.join("|") + ")?" +
- "(\\b.*)?$", "");
- units.valueAltRegex = new RegExp("^([0-9]*)" +
- "(" + units.unitsShort.join("|") + ")?" +
- "([GgMmKkUuNnPp])?" +
- "([0-9]*)" +
- "(\\b.*)?$", "");
- if (config.fields.includes("Value")) {
- var index = config.fields.indexOf("Value");
- pcbdata.bom["parsedValues"] = {};
- for (var id in pcbdata.bom.fields) {
- pcbdata.bom.parsedValues[id] = parseValue(pcbdata.bom.fields[id][index])
- }
- }
- }
- function parseValue(val, ref) {
- var inferUnit = (unit, ref) => {
- if (unit) {
- unit = unit.toLowerCase();
- if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
- unit = 'r';
- }
- unit = unit[0];
- } else {
- ref = /^([a-z]+)\d+$/i.exec(ref);
- if (ref) {
- ref = ref[1].toLowerCase();
- if (ref == "c") unit = 'f';
- else if (ref == "l") unit = 'h';
- else if (ref == "r" || ref == "rv") unit = 'r';
- else unit = null;
- }
- }
- return unit;
- };
- val = val.replace(/,/g, "");
- var match = units.valueRegex.exec(val);
- var unit;
- if (match) {
- val = parseFloat(match[1]);
- if (match[2]) {
- val = val * units.getMultiplier(match[2]);
- }
- unit = inferUnit(match[3], ref);
- if (!unit) return null;
- else return {
- val: val,
- unit: unit,
- extra: match[4],
- }
- }
- match = units.valueAltRegex.exec(val);
- if (match && (match[1] || match[4])) {
- val = parseFloat(match[1] + "." + match[4]);
- if (match[3]) {
- val = val * units.getMultiplier(match[3]);
- }
- unit = inferUnit(match[2], ref);
- if (!unit) return null;
- else return {
- val: val,
- unit: unit,
- extra: match[5],
- }
- }
- return null;
- }
- function valueCompare(a, b, stra, strb) {
- if (a === null && b === null) {
- // Failed to parse both values, compare them as strings.
- if (stra != strb) return stra > strb ? 1 : -1;
- else return 0;
- } else if (a === null) {
- return 1;
- } else if (b === null) {
- return -1;
- } else {
- if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1;
- else if (a.val != b.val) return a.val > b.val ? 1 : -1;
- else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1;
- else return 0;
- }
- }
- function validateSaveImgDimension(element) {
- var valid = false;
- var intValue = 0;
- if (/^[1-9]\d*$/.test(element.value)) {
- intValue = parseInt(element.value);
- if (intValue <= 16000) {
- valid = true;
- }
- }
- if (valid) {
- element.classList.remove("invalid");
- } else {
- element.classList.add("invalid");
- }
- return intValue;
- }
- function saveImage(layer) {
- var width = validateSaveImgDimension(document.getElementById("render-save-width"));
- var height = validateSaveImgDimension(document.getElementById("render-save-height"));
- var bgcolor = null;
- if (!document.getElementById("render-save-transparent").checked) {
- var style = getComputedStyle(topmostdiv);
- bgcolor = style.getPropertyValue("background-color");
- }
- if (!width || !height) return;
- // Prepare image
- var canvas = document.createElement("canvas");
- var layerdict = {
- transform: {
- x: 0,
- y: 0,
- s: 1,
- panx: 0,
- pany: 0,
- zoom: 1,
- },
- bg: canvas,
- fab: canvas,
- silk: canvas,
- highlight: canvas,
- layer: layer,
- }
- // Do the rendering
- recalcLayerScale(layerdict, width, height);
- prepareLayer(layerdict);
- clearCanvas(canvas, bgcolor);
- drawBackground(layerdict, false);
- drawHighlightsOnLayer(layerdict, false);
- // Save image
- var imgdata = canvas.toDataURL("image/png");
- var filename = pcbdata.metadata.title;
- if (pcbdata.metadata.revision) {
- filename += `.${pcbdata.metadata.revision}`;
- }
- filename += `.${layer}.png`;
- saveFile(filename, dataURLtoBlob(imgdata));
- }
- function saveSettings() {
- var data = {
- type: "InteractiveHtmlBom settings",
- version: 1,
- pcbmetadata: pcbdata.metadata,
- settings: settings,
- }
- var blob = new Blob([JSON.stringify(data, null, 4)], {
- type: "application/json"
- });
- saveFile(`${pcbdata.metadata.title}.settings.json`, blob);
- }
- function loadSettings() {
- var input = document.createElement("input");
- input.type = "file";
- input.accept = ".settings.json";
- input.onchange = function (e) {
- var file = e.target.files[0];
- var reader = new FileReader();
- reader.onload = readerEvent => {
- var content = readerEvent.target.result;
- var newSettings;
- try {
- newSettings = JSON.parse(content);
- } catch (e) {
- alert("Selected file is not InteractiveHtmlBom settings file.");
- return;
- }
- if (newSettings.type != "InteractiveHtmlBom settings") {
- alert("Selected file is not InteractiveHtmlBom settings file.");
- return;
- }
- var metadataMatches = newSettings.hasOwnProperty("pcbmetadata");
- if (metadataMatches) {
- for (var k in pcbdata.metadata) {
- if (!newSettings.pcbmetadata.hasOwnProperty(k) || newSettings.pcbmetadata[k] != pcbdata.metadata[k]) {
- metadataMatches = false;
- }
- }
- }
- if (!metadataMatches) {
- var currentMetadata = JSON.stringify(pcbdata.metadata, null, 4);
- var fileMetadata = JSON.stringify(newSettings.pcbmetadata, null, 4);
- if (!confirm(
- `Settins file metadata does not match current metadata.\n\n` +
- `Page metadata:\n${currentMetadata}\n\n` +
- `Settings file metadata:\n${fileMetadata}\n\n` +
- `Press OK if you would like to import settings anyway.`)) {
- return;
- }
- }
- overwriteSettings(newSettings.settings);
- }
- reader.readAsText(file, 'UTF-8');
- }
- input.click();
- }
- function resetSettings() {
- if (!confirm(
- `This will reset all checkbox states and other settings.\n\n` +
- `Press OK if you want to continue.`)) {
- return;
- }
- if (storage) {
- var keys = [];
- for (var i = 0; i < storage.length; i++) {
- var key = storage.key(i);
- if (key.startsWith(storagePrefix)) keys.push(key);
- }
- for (var key of keys) storage.removeItem(key);
- }
- location.reload();
- }
- function overwriteSettings(newSettings) {
- initDone = false;
- Object.assign(settings, newSettings);
- writeStorage("bomlayout", settings.bomlayout);
- writeStorage("bommode", settings.bommode);
- writeStorage("canvaslayout", settings.canvaslayout);
- writeStorage("bomCheckboxes", settings.checkboxes.join(","));
- document.getElementById("bomCheckboxes").value = settings.checkboxes.join(",");
- for (var checkbox of settings.checkboxes) {
- writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
- }
- writeStorage("markWhenChecked", settings.markWhenChecked);
- padsVisible(settings.renderPads);
- document.getElementById("padsCheckbox").checked = settings.renderPads;
- fabricationVisible(settings.renderFabrication);
- document.getElementById("fabricationCheckbox").checked = settings.renderFabrication;
- silkscreenVisible(settings.renderSilkscreen);
- document.getElementById("silkscreenCheckbox").checked = settings.renderSilkscreen;
- referencesVisible(settings.renderReferences);
- document.getElementById("referencesCheckbox").checked = settings.renderReferences;
- valuesVisible(settings.renderValues);
- document.getElementById("valuesCheckbox").checked = settings.renderValues;
- tracksVisible(settings.renderTracks);
- document.getElementById("tracksCheckbox").checked = settings.renderTracks;
- zonesVisible(settings.renderZones);
- document.getElementById("zonesCheckbox").checked = settings.renderZones;
- dnpOutline(settings.renderDnpOutline);
- document.getElementById("dnpOutlineCheckbox").checked = settings.renderDnpOutline;
- setRedrawOnDrag(settings.redrawOnDrag);
- document.getElementById("dragCheckbox").checked = settings.redrawOnDrag;
- setDarkMode(settings.darkMode);
- document.getElementById("darkmodeCheckbox").checked = settings.darkMode;
- setHighlightPin1(settings.highlightpin1);
- document.forms.highlightpin1.highlightpin1.value = settings.highlightpin1;
- writeStorage("boardRotation", settings.boardRotation);
- document.getElementById("boardRotation").value = settings.boardRotation / 5;
- document.getElementById("rotationDegree").textContent = settings.boardRotation;
- setOffsetBackRotation(settings.offsetBackRotation);
- document.getElementById("offsetBackRotationCheckbox").checked = settings.offsetBackRotation;
- initDone = true;
- prepCheckboxes();
- changeBomLayout(settings.bomlayout);
- }
- function saveFile(filename, blob) {
- var link = document.createElement("a");
- var objurl = URL.createObjectURL(blob);
- link.download = filename;
- link.href = objurl;
- link.click();
- }
- function dataURLtoBlob(dataurl) {
- var arr = dataurl.split(','),
- mime = arr[0].match(/:(.*?);/)[1],
- bstr = atob(arr[1]),
- n = bstr.length,
- u8arr = new Uint8Array(n);
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new Blob([u8arr], {
- type: mime
- });
- }
- var settings = {
- canvaslayout: "FB",
- bomlayout: "left-right",
- bommode: "grouped",
- checkboxes: [],
- checkboxStoredRefs: {},
- darkMode: false,
- highlightpin1: "none",
- redrawOnDrag: true,
- boardRotation: 0,
- offsetBackRotation: false,
- renderPads: true,
- renderReferences: true,
- renderValues: true,
- renderSilkscreen: true,
- renderFabrication: true,
- renderDnpOutline: false,
- renderTracks: true,
- renderZones: true,
- columnOrder: [],
- hiddenColumns: [],
- netColors: {},
- }
- function initDefaults() {
- settings.bomlayout = readStorage("bomlayout");
- if (settings.bomlayout === null) {
- settings.bomlayout = config.bom_view;
- }
- if (!['bom-only', 'left-right', 'top-bottom'].includes(settings.bomlayout)) {
- settings.bomlayout = config.bom_view;
- }
- settings.bommode = readStorage("bommode");
- if (settings.bommode === null) {
- settings.bommode = "grouped";
- }
- if (settings.bommode == "netlist" && !pcbdata.nets) {
- settings.bommode = "grouped";
- }
- if (!["grouped", "ungrouped", "netlist"].includes(settings.bommode)) {
- settings.bommode = "grouped";
- }
- settings.canvaslayout = readStorage("canvaslayout");
- if (settings.canvaslayout === null) {
- settings.canvaslayout = config.layer_view;
- }
- var bomCheckboxes = readStorage("bomCheckboxes");
- if (bomCheckboxes === null) {
- bomCheckboxes = config.checkboxes;
- }
- settings.checkboxes = bomCheckboxes.split(",").filter((e) => e);
- document.getElementById("bomCheckboxes").value = bomCheckboxes;
- var highlightpin1 = readStorage("highlightpin1") || config.highlight_pin1;
- if (highlightpin1 === "false") highlightpin1 = "none";
- if (highlightpin1 === "true") highlightpin1 = "all";
- setHighlightPin1(highlightpin1);
- document.forms.highlightpin1.highlightpin1.value = highlightpin1;
- settings.markWhenChecked = readStorage("markWhenChecked") || "";
- populateMarkWhenCheckedOptions();
- function initBooleanSetting(storageString, def, elementId, func) {
- var b = readStorage(storageString);
- if (b === null) {
- b = def;
- } else {
- b = (b == "true");
- }
- document.getElementById(elementId).checked = b;
- func(b);
- }
- initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible);
- initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible);
- initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible);
- initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible);
- initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible);
- if ("tracks" in pcbdata) {
- initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible);
- initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible);
- } else {
- document.getElementById("tracksAndZonesCheckboxes").style.display = "none";
- tracksVisible(false);
- zonesVisible(false);
- }
- initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline);
- initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag);
- initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
- var fields = ["checkboxes", "References"].concat(config.fields).concat(["Quantity"]);
- var hcols = JSON.parse(readStorage("hiddenColumns"));
- if (hcols === null) {
- hcols = [];
- }
- settings.hiddenColumns = hcols.filter(e => fields.includes(e));
- var cord = JSON.parse(readStorage("columnOrder"));
- if (cord === null) {
- cord = fields;
- } else {
- cord = cord.filter(e => fields.includes(e));
- if (cord.length != fields.length)
- cord = fields;
- }
- settings.columnOrder = cord;
- settings.boardRotation = readStorage("boardRotation");
- if (settings.boardRotation === null) {
- settings.boardRotation = config.board_rotation * 5;
- } else {
- settings.boardRotation = parseInt(settings.boardRotation);
- }
- document.getElementById("boardRotation").value = settings.boardRotation / 5;
- document.getElementById("rotationDegree").textContent = settings.boardRotation;
- initBooleanSetting("offsetBackRotation", config.offset_back_rotation, "offsetBackRotationCheckbox", setOffsetBackRotation);
- settings.netColors = JSON.parse(readStorage("netColors")) || {};
- }
- // Helper classes for user js callbacks.
- const IBOM_EVENT_TYPES = {
- ALL: "all",
- HIGHLIGHT_EVENT: "highlightEvent",
- CHECKBOX_CHANGE_EVENT: "checkboxChangeEvent",
- BOM_BODY_CHANGE_EVENT: "bomBodyChangeEvent",
- }
- const EventHandler = {
- callbacks: {},
- init: function () {
- for (eventType of Object.values(IBOM_EVENT_TYPES))
- this.callbacks[eventType] = [];
- },
- registerCallback: function (eventType, callback) {
- this.callbacks[eventType].push(callback);
- },
- emitEvent: function (eventType, eventArgs) {
- event = {
- eventType: eventType,
- args: eventArgs,
- }
- var callback;
- for (callback of this.callbacks[eventType])
- callback(event);
- for (callback of this.callbacks[IBOM_EVENT_TYPES.ALL])
- callback(event);
- }
- }
- EventHandler.init();
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- /* PCB rendering code */
- var emptyContext2d = document.createElement("canvas").getContext("2d");
- function deg2rad(deg) {
- return deg * Math.PI / 180;
- }
- function calcFontPoint(linepoint, text, offsetx, offsety, tilt) {
- var point = [
- linepoint[0] * text.width + offsetx,
- linepoint[1] * text.height + offsety
- ];
- // This approximates pcbnew behavior with how text tilts depending on horizontal justification
- point[0] -= (linepoint[1] + 0.5 * (1 + text.justify[0])) * text.height * tilt;
- return point;
- }
- function drawText(ctx, text, color) {
- if ("ref" in text && !settings.renderReferences) return;
- if ("val" in text && !settings.renderValues) return;
- ctx.save();
- ctx.fillStyle = color;
- ctx.strokeStyle = color;
- ctx.lineCap = "round";
- ctx.lineJoin = "round";
- ctx.lineWidth = text.thickness;
- if ("svgpath" in text) {
- ctx.stroke(new Path2D(text.svgpath));
- ctx.restore();
- return;
- }
- if ("polygons" in text) {
- ctx.fill(getPolygonsPath(text));
- ctx.restore();
- return;
- }
- ctx.translate(...text.pos);
- ctx.translate(text.thickness * 0.5, 0);
- var angle = -text.angle;
- if (text.attr.includes("mirrored")) {
- ctx.scale(-1, 1);
- angle = -angle;
- }
- var tilt = 0;
- if (text.attr.includes("italic")) {
- tilt = 0.125;
- }
- var interline = text.height * 1.5 + text.thickness;
- var txt = text.text.split("\n");
- // KiCad ignores last empty line.
- if (txt[txt.length - 1] == '') txt.pop();
- ctx.rotate(deg2rad(angle));
- var offsety = (1 - text.justify[1]) / 2 * text.height; // One line offset
- offsety -= (txt.length - 1) * (text.justify[1] + 1) / 2 * interline; // Multiline offset
- for (var i in txt) {
- var lineWidth = text.thickness + interline / 2 * tilt;
- for (var j = 0; j < txt[i].length; j++) {
- if (txt[i][j] == '\t') {
- var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
- lineWidth += fourSpaces - lineWidth % fourSpaces;
- } else {
- if (txt[i][j] == '~') {
- j++;
- if (j == txt[i].length)
- break;
- }
- lineWidth += pcbdata.font_data[txt[i][j]].w * text.width;
- }
- }
- var offsetx = -lineWidth * (text.justify[0] + 1) / 2;
- var inOverbar = false;
- for (var j = 0; j < txt[i].length; j++) {
- if (config.kicad_text_formatting) {
- if (txt[i][j] == '\t') {
- var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
- offsetx += fourSpaces - offsetx % fourSpaces;
- continue;
- } else if (txt[i][j] == '~') {
- j++;
- if (j == txt[i].length)
- break;
- if (txt[i][j] != '~') {
- inOverbar = !inOverbar;
- }
- }
- }
- var glyph = pcbdata.font_data[txt[i][j]];
- if (inOverbar) {
- var overbarStart = [offsetx, -text.height * 1.4 + offsety];
- var overbarEnd = [offsetx + text.width * glyph.w, overbarStart[1]];
- if (!lastHadOverbar) {
- overbarStart[0] += text.height * 1.4 * tilt;
- lastHadOverbar = true;
- }
- ctx.beginPath();
- ctx.moveTo(...overbarStart);
- ctx.lineTo(...overbarEnd);
- ctx.stroke();
- } else {
- lastHadOverbar = false;
- }
- for (var line of glyph.l) {
- ctx.beginPath();
- ctx.moveTo(...calcFontPoint(line[0], text, offsetx, offsety, tilt));
- for (var k = 1; k < line.length; k++) {
- ctx.lineTo(...calcFontPoint(line[k], text, offsetx, offsety, tilt));
- }
- ctx.stroke();
- }
- offsetx += glyph.w * text.width;
- }
- offsety += interline;
- }
- ctx.restore();
- }
- function drawedge(ctx, scalefactor, edge, color) {
- ctx.strokeStyle = color;
- ctx.fillStyle = color;
- ctx.lineWidth = Math.max(1 / scalefactor, edge.width);
- ctx.lineCap = "round";
- ctx.lineJoin = "round";
- if ("svgpath" in edge) {
- ctx.stroke(new Path2D(edge.svgpath));
- } else {
- ctx.beginPath();
- if (edge.type == "segment") {
- ctx.moveTo(...edge.start);
- ctx.lineTo(...edge.end);
- }
- if (edge.type == "rect") {
- ctx.moveTo(...edge.start);
- ctx.lineTo(edge.start[0], edge.end[1]);
- ctx.lineTo(...edge.end);
- ctx.lineTo(edge.end[0], edge.start[1]);
- ctx.lineTo(...edge.start);
- }
- if (edge.type == "arc") {
- ctx.arc(
- ...edge.start,
- edge.radius,
- deg2rad(edge.startangle),
- deg2rad(edge.endangle));
- }
- if (edge.type == "circle") {
- ctx.arc(
- ...edge.start,
- edge.radius,
- 0, 2 * Math.PI);
- ctx.closePath();
- }
- if (edge.type == "curve") {
- ctx.moveTo(...edge.start);
- ctx.bezierCurveTo(...edge.cpa, ...edge.cpb, ...edge.end);
- }
- if("filled" in edge && edge.filled)
- ctx.fill();
- else
- ctx.stroke();
- }
- }
- function getChamferedRectPath(size, radius, chamfpos, chamfratio) {
- // chamfpos is a bitmask, left = 1, right = 2, bottom left = 4, bottom right = 8
- var path = new Path2D();
- var width = size[0];
- var height = size[1];
- var x = width * -0.5;
- var y = height * -0.5;
- var chamfOffset = Math.min(width, height) * chamfratio;
- path.moveTo(x, 0);
- if (chamfpos & 4) {
- path.lineTo(x, y + height - chamfOffset);
- path.lineTo(x + chamfOffset, y + height);
- path.lineTo(0, y + height);
- } else {
- path.arcTo(x, y + height, x + width, y + height, radius);
- }
- if (chamfpos & 8) {
- path.lineTo(x + width - chamfOffset, y + height);
- path.lineTo(x + width, y + height - chamfOffset);
- path.lineTo(x + width, 0);
- } else {
- path.arcTo(x + width, y + height, x + width, y, radius);
- }
- if (chamfpos & 2) {
- path.lineTo(x + width, y + chamfOffset);
- path.lineTo(x + width - chamfOffset, y);
- path.lineTo(0, y);
- } else {
- path.arcTo(x + width, y, x, y, radius);
- }
- if (chamfpos & 1) {
- path.lineTo(x + chamfOffset, y);
- path.lineTo(x, y + chamfOffset);
- path.lineTo(x, 0);
- } else {
- path.arcTo(x, y, x, y + height, radius);
- }
- path.closePath();
- return path;
- }
- function getOblongPath(size) {
- return getChamferedRectPath(size, Math.min(size[0], size[1]) / 2, 0, 0);
- }
- function getPolygonsPath(shape) {
- if (shape.path2d) {
- return shape.path2d;
- }
- if ("svgpath" in shape) {
- shape.path2d = new Path2D(shape.svgpath);
- } else {
- var path = new Path2D();
- for (var polygon of shape.polygons) {
- path.moveTo(...polygon[0]);
- for (var i = 1; i < polygon.length; i++) {
- path.lineTo(...polygon[i]);
- }
- path.closePath();
- }
- shape.path2d = path;
- }
- return shape.path2d;
- }
- function drawPolygonShape(ctx, scalefactor, shape, color) {
- ctx.save();
- if (!("svgpath" in shape)) {
- ctx.translate(...shape.pos);
- ctx.rotate(deg2rad(-shape.angle));
- }
- if("filled" in shape && !shape.filled) {
- ctx.strokeStyle = color;
- ctx.lineWidth = Math.max(1 / scalefactor, shape.width);
- ctx.lineCap = "round";
- ctx.lineJoin = "round";
- ctx.stroke(getPolygonsPath(shape));
- } else {
- ctx.fillStyle = color;
- ctx.fill(getPolygonsPath(shape));
- }
- ctx.restore();
- }
- function drawDrawing(ctx, scalefactor, drawing, color) {
- if (["segment", "arc", "circle", "curve", "rect"].includes(drawing.type)) {
- drawedge(ctx, scalefactor, drawing, color);
- } else if (drawing.type == "polygon") {
- drawPolygonShape(ctx, scalefactor, drawing, color);
- } else {
- drawText(ctx, drawing, color);
- }
- }
- function getCirclePath(radius) {
- var path = new Path2D();
- path.arc(0, 0, radius, 0, 2 * Math.PI);
- path.closePath();
- return path;
- }
- function getCachedPadPath(pad) {
- if (!pad.path2d) {
- // if path2d is not set, build one and cache it on pad object
- if (pad.shape == "rect") {
- pad.path2d = new Path2D();
- pad.path2d.rect(...pad.size.map(c => -c * 0.5), ...pad.size);
- } else if (pad.shape == "oval") {
- pad.path2d = getOblongPath(pad.size);
- } else if (pad.shape == "circle") {
- pad.path2d = getCirclePath(pad.size[0] / 2);
- } else if (pad.shape == "roundrect") {
- pad.path2d = getChamferedRectPath(pad.size, pad.radius, 0, 0);
- } else if (pad.shape == "chamfrect") {
- pad.path2d = getChamferedRectPath(pad.size, pad.radius, pad.chamfpos, pad.chamfratio)
- } else if (pad.shape == "custom") {
- pad.path2d = getPolygonsPath(pad);
- }
- }
- return pad.path2d;
- }
- function drawPad(ctx, pad, color, outline) {
- ctx.save();
- ctx.translate(...pad.pos);
- ctx.rotate(-deg2rad(pad.angle));
- if (pad.offset) {
- ctx.translate(...pad.offset);
- }
- ctx.fillStyle = color;
- ctx.strokeStyle = color;
- var path = getCachedPadPath(pad);
- if (outline) {
- ctx.stroke(path);
- } else {
- ctx.fill(path);
- }
- ctx.restore();
- }
- function drawPadHole(ctx, pad, padHoleColor) {
- if (pad.type != "th") return;
- ctx.save();
- ctx.translate(...pad.pos);
- ctx.rotate(-deg2rad(pad.angle));
- ctx.fillStyle = padHoleColor;
- if (pad.drillshape == "oblong") {
- ctx.fill(getOblongPath(pad.drillsize));
- } else {
- ctx.fill(getCirclePath(pad.drillsize[0] / 2));
- }
- ctx.restore();
- }
- function drawFootprint(ctx, layer, scalefactor, footprint, colors, highlight, outline) {
- if (highlight) {
- // draw bounding box
- if (footprint.layer == layer) {
- ctx.save();
- ctx.globalAlpha = 0.2;
- ctx.translate(...footprint.bbox.pos);
- ctx.rotate(deg2rad(-footprint.bbox.angle));
- ctx.translate(...footprint.bbox.relpos);
- ctx.fillStyle = colors.pad;
- ctx.fillRect(0, 0, ...footprint.bbox.size);
- ctx.globalAlpha = 1;
- ctx.strokeStyle = colors.pad;
- ctx.lineWidth = 3 / scalefactor;
- ctx.strokeRect(0, 0, ...footprint.bbox.size);
- ctx.restore();
- }
- }
- // draw drawings
- for (var drawing of footprint.drawings) {
- if (drawing.layer == layer) {
- drawDrawing(ctx, scalefactor, drawing.drawing, colors.pad);
- }
- }
- ctx.lineWidth = 3 / scalefactor;
- // draw pads
- if (settings.renderPads) {
- for (var pad of footprint.pads) {
- if (pad.layers.includes(layer)) {
- drawPad(ctx, pad, colors.pad, outline);
- if (pad.pin1 &&
- (settings.highlightpin1 == "all" ||
- settings.highlightpin1 == "selected" && highlight)) {
- drawPad(ctx, pad, colors.outline, true);
- }
- }
- }
- for (var pad of footprint.pads) {
- drawPadHole(ctx, pad, colors.padHole);
- }
- }
- }
- function drawEdgeCuts(canvas, scalefactor) {
- var ctx = canvas.getContext("2d");
- var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color');
- for (var edge of pcbdata.edges) {
- drawDrawing(ctx, scalefactor, edge, edgecolor);
- }
- }
- function drawFootprints(canvas, layer, scalefactor, highlight) {
- var ctx = canvas.getContext("2d");
- ctx.lineWidth = 3 / scalefactor;
- var style = getComputedStyle(topmostdiv);
- var colors = {
- pad: style.getPropertyValue('--pad-color'),
- padHole: style.getPropertyValue('--pad-hole-color'),
- outline: style.getPropertyValue('--pin1-outline-color'),
- }
- for (var i = 0; i < pcbdata.footprints.length; i++) {
- var mod = pcbdata.footprints[i];
- var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
- var h = highlightedFootprints.includes(i);
- var d = markedFootprints.has(i);
- if (highlight) {
- if(h && d) {
- colors.pad = style.getPropertyValue('--pad-color-highlight-both');
- colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-both');
- } else if (h) {
- colors.pad = style.getPropertyValue('--pad-color-highlight');
- colors.outline = style.getPropertyValue('--pin1-outline-color-highlight');
- } else if (d) {
- colors.pad = style.getPropertyValue('--pad-color-highlight-marked');
- colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-marked');
- }
- }
- if( h || d || !highlight) {
- drawFootprint(ctx, layer, scalefactor, mod, colors, highlight, outline);
- }
- }
- }
- function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) {
- var ctx = canvas.getContext("2d");
- for (var d of pcbdata.drawings[layername][layer]) {
- if (["segment", "arc", "circle", "curve", "rect"].includes(d.type)) {
- drawedge(ctx, scalefactor, d, edgeColor);
- } else if (d.type == "polygon") {
- drawPolygonShape(ctx, scalefactor, d, polygonColor);
- } else {
- drawText(ctx, d, textColor);
- }
- }
- }
- function drawTracks(canvas, layer, defaultColor, highlight) {
- ctx = canvas.getContext("2d");
- ctx.lineCap = "round";
- var hasHole = (track) => (
- 'drillsize' in track &&
- track.start[0] == track.end[0] &&
- track.start[1] == track.end[1]);
- // First draw tracks and tented vias
- for (var track of pcbdata.tracks[layer]) {
- if (highlight && highlightedNet != track.net) continue;
- if (!hasHole(track)) {
- ctx.strokeStyle = highlight ? defaultColor : settings.netColors[track.net] || defaultColor;
- ctx.lineWidth = track.width;
- ctx.beginPath();
- if ('radius' in track) {
- ctx.arc(
- ...track.center,
- track.radius,
- deg2rad(track.startangle),
- deg2rad(track.endangle));
- } else {
- ctx.moveTo(...track.start);
- ctx.lineTo(...track.end);
- }
- ctx.stroke();
- }
- }
- // Second pass to draw untented vias
- var style = getComputedStyle(topmostdiv);
- var holeColor = style.getPropertyValue('--pad-hole-color')
- for (var track of pcbdata.tracks[layer]) {
- if (highlight && highlightedNet != track.net) continue;
- if (hasHole(track)) {
- ctx.strokeStyle = highlight ? defaultColor : settings.netColors[track.net] || defaultColor;
- ctx.lineWidth = track.width;
- ctx.beginPath();
- ctx.moveTo(...track.start);
- ctx.lineTo(...track.end);
- ctx.stroke();
- ctx.strokeStyle = holeColor;
- ctx.lineWidth = track.drillsize;
- ctx.lineTo(...track.end);
- ctx.stroke();
- }
- }
- }
- function drawZones(canvas, layer, defaultColor, highlight) {
- ctx = canvas.getContext("2d");
- ctx.lineJoin = "round";
- for (var zone of pcbdata.zones[layer]) {
- if (highlight && highlightedNet != zone.net) continue;
- ctx.strokeStyle = highlight ? defaultColor : settings.netColors[zone.net] || defaultColor;
- ctx.fillStyle = highlight ? defaultColor : settings.netColors[zone.net] || defaultColor;
- if (!zone.path2d) {
- zone.path2d = getPolygonsPath(zone);
- }
- ctx.fill(zone.path2d, zone.fillrule || "nonzero");
- if (zone.width > 0) {
- ctx.lineWidth = zone.width;
- ctx.stroke(zone.path2d);
- }
- }
- }
- function clearCanvas(canvas, color = null) {
- var ctx = canvas.getContext("2d");
- ctx.save();
- ctx.setTransform(1, 0, 0, 1, 0, 0);
- if (color) {
- ctx.fillStyle = color;
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- } else {
- if (!window.matchMedia("print").matches)
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- }
- ctx.restore();
- }
- function drawNets(canvas, layer, highlight) {
- var style = getComputedStyle(topmostdiv);
- if (settings.renderZones) {
- var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
- drawZones(canvas, layer, zoneColor, highlight);
- }
- if (settings.renderTracks) {
- var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
- drawTracks(canvas, layer, trackColor, highlight);
- }
- if (highlight && settings.renderPads) {
- var padColor = style.getPropertyValue('--pad-color-highlight');
- var padHoleColor = style.getPropertyValue('--pad-hole-color');
- var ctx = canvas.getContext("2d");
- for (var footprint of pcbdata.footprints) {
- // draw pads
- var padDrawn = false;
- for (var pad of footprint.pads) {
- if (highlightedNet != pad.net) continue;
- if (pad.layers.includes(layer)) {
- drawPad(ctx, pad, padColor, false);
- padDrawn = true;
- }
- }
- if (padDrawn) {
- // redraw all pad holes because some pads may overlap
- for (var pad of footprint.pads) {
- drawPadHole(ctx, pad, padHoleColor);
- }
- }
- }
- }
- }
- function drawHighlightsOnLayer(canvasdict, clear = true) {
- if (clear) {
- clearCanvas(canvasdict.highlight);
- }
- if (markedFootprints.size > 0 || highlightedFootprints.length > 0) {
- drawFootprints(canvasdict.highlight, canvasdict.layer,
- canvasdict.transform.s * canvasdict.transform.zoom, true);
- }
- if (highlightedNet !== null) {
- drawNets(canvasdict.highlight, canvasdict.layer, true);
- }
- }
- function drawHighlights() {
- drawHighlightsOnLayer(allcanvas.front);
- drawHighlightsOnLayer(allcanvas.back);
- }
- function drawBackground(canvasdict, clear = true) {
- if (clear) {
- clearCanvas(canvasdict.bg);
- clearCanvas(canvasdict.fab);
- clearCanvas(canvasdict.silk);
- }
- drawNets(canvasdict.bg, canvasdict.layer, false);
- drawFootprints(canvasdict.bg, canvasdict.layer,
- canvasdict.transform.s * canvasdict.transform.zoom, false);
- drawEdgeCuts(canvasdict.bg, canvasdict.transform.s * canvasdict.transform.zoom);
- var style = getComputedStyle(topmostdiv);
- var edgeColor = style.getPropertyValue('--silkscreen-edge-color');
- var polygonColor = style.getPropertyValue('--silkscreen-polygon-color');
- var textColor = style.getPropertyValue('--silkscreen-text-color');
- if (settings.renderSilkscreen) {
- drawBgLayer(
- "silkscreen", canvasdict.silk, canvasdict.layer,
- canvasdict.transform.s * canvasdict.transform.zoom,
- edgeColor, polygonColor, textColor);
- }
- edgeColor = style.getPropertyValue('--fabrication-edge-color');
- polygonColor = style.getPropertyValue('--fabrication-polygon-color');
- textColor = style.getPropertyValue('--fabrication-text-color');
- if (settings.renderFabrication) {
- drawBgLayer(
- "fabrication", canvasdict.fab, canvasdict.layer,
- canvasdict.transform.s * canvasdict.transform.zoom,
- edgeColor, polygonColor, textColor);
- }
- }
- function prepareCanvas(canvas, flip, transform) {
- var ctx = canvas.getContext("2d");
- ctx.setTransform(1, 0, 0, 1, 0, 0);
- ctx.scale(transform.zoom, transform.zoom);
- ctx.translate(transform.panx, transform.pany);
- if (flip) {
- ctx.scale(-1, 1);
- }
- ctx.translate(transform.x, transform.y);
- ctx.rotate(deg2rad(settings.boardRotation + (flip && settings.offsetBackRotation ? - 180 : 0)));
- ctx.scale(transform.s, transform.s);
- }
- function prepareLayer(canvasdict) {
- var flip = (canvasdict.layer === "B");
- for (var c of ["bg", "fab", "silk", "highlight"]) {
- prepareCanvas(canvasdict[c], flip, canvasdict.transform);
- }
- }
- function rotateVector(v, angle) {
- angle = deg2rad(angle);
- return [
- v[0] * Math.cos(angle) - v[1] * Math.sin(angle),
- v[0] * Math.sin(angle) + v[1] * Math.cos(angle)
- ];
- }
- function applyRotation(bbox, flip) {
- var corners = [
- [bbox.minx, bbox.miny],
- [bbox.minx, bbox.maxy],
- [bbox.maxx, bbox.miny],
- [bbox.maxx, bbox.maxy],
- ];
- corners = corners.map((v) => rotateVector(v, settings.boardRotation + (flip && settings.offsetBackRotation ? - 180 : 0)));
- return {
- minx: corners.reduce((a, v) => Math.min(a, v[0]), Infinity),
- miny: corners.reduce((a, v) => Math.min(a, v[1]), Infinity),
- maxx: corners.reduce((a, v) => Math.max(a, v[0]), -Infinity),
- maxy: corners.reduce((a, v) => Math.max(a, v[1]), -Infinity),
- }
- }
- function recalcLayerScale(layerdict, width, height) {
- var flip = (layerdict.layer === "B");
- var bbox = applyRotation(pcbdata.edges_bbox, flip);
- var scalefactor = 0.98 * Math.min(
- width / (bbox.maxx - bbox.minx),
- height / (bbox.maxy - bbox.miny)
- );
- if (scalefactor < 0.1) {
- scalefactor = 1;
- }
- layerdict.transform.s = scalefactor;
- if (flip) {
- layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor + width) * 0.5;
- } else {
- layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor - width) * 0.5;
- }
- layerdict.transform.y = -((bbox.maxy + bbox.miny) * scalefactor - height) * 0.5;
- for (var c of ["bg", "fab", "silk", "highlight"]) {
- canvas = layerdict[c];
- canvas.width = width;
- canvas.height = height;
- canvas.style.width = (width / devicePixelRatio) + "px";
- canvas.style.height = (height / devicePixelRatio) + "px";
- }
- }
- function redrawCanvas(layerdict) {
- prepareLayer(layerdict);
- drawBackground(layerdict);
- drawHighlightsOnLayer(layerdict);
- }
- function resizeCanvas(layerdict) {
- var canvasdivid = {
- "F": "frontcanvas",
- "B": "backcanvas"
- } [layerdict.layer];
- var width = document.getElementById(canvasdivid).clientWidth * devicePixelRatio;
- var height = document.getElementById(canvasdivid).clientHeight * devicePixelRatio;
- recalcLayerScale(layerdict, width, height);
- redrawCanvas(layerdict);
- }
- function resizeAll() {
- resizeCanvas(allcanvas.front);
- resizeCanvas(allcanvas.back);
- }
- function pointWithinDistanceToSegment(x, y, x1, y1, x2, y2, d) {
- var A = x - x1;
- var B = y - y1;
- var C = x2 - x1;
- var D = y2 - y1;
- var dot = A * C + B * D;
- var len_sq = C * C + D * D;
- var dx, dy;
- if (len_sq == 0) {
- // start and end of the segment coincide
- dx = x - x1;
- dy = y - y1;
- } else {
- var param = dot / len_sq;
- var xx, yy;
- if (param < 0) {
- xx = x1;
- yy = y1;
- } else if (param > 1) {
- xx = x2;
- yy = y2;
- } else {
- xx = x1 + param * C;
- yy = y1 + param * D;
- }
- dx = x - xx;
- dy = y - yy;
- }
- return dx * dx + dy * dy <= d * d;
- }
- function modulo(n, mod) {
- return ((n % mod) + mod) % mod;
- }
- function pointWithinDistanceToArc(x, y, xc, yc, radius, startangle, endangle, d) {
- var dx = x - xc;
- var dy = y - yc;
- var r_sq = dx * dx + dy * dy;
- var rmin = Math.max(0, radius - d);
- var rmax = radius + d;
- if (r_sq < rmin * rmin || r_sq > rmax * rmax)
- return false;
- var angle1 = modulo(deg2rad(startangle), 2 * Math.PI);
- var dx1 = xc + radius * Math.cos(angle1) - x;
- var dy1 = yc + radius * Math.sin(angle1) - y;
- if (dx1 * dx1 + dy1 * dy1 <= d * d)
- return true;
- var angle2 = modulo(deg2rad(endangle), 2 * Math.PI);
- var dx2 = xc + radius * Math.cos(angle2) - x;
- var dy2 = yc + radius * Math.sin(angle2) - y;
- if (dx2 * dx2 + dy2 * dy2 <= d * d)
- return true;
- var angle = modulo(Math.atan2(dy, dx), 2 * Math.PI);
- if (angle1 > angle2)
- return (angle >= angle2 || angle <= angle1);
- else
- return (angle >= angle1 && angle <= angle2);
- }
- function pointWithinPad(x, y, pad) {
- var v = [x - pad.pos[0], y - pad.pos[1]];
- v = rotateVector(v, pad.angle);
- if (pad.offset) {
- v[0] -= pad.offset[0];
- v[1] -= pad.offset[1];
- }
- return emptyContext2d.isPointInPath(getCachedPadPath(pad), ...v);
- }
- function netHitScan(layer, x, y) {
- // Check track segments
- if (settings.renderTracks && pcbdata.tracks) {
- for (var track of pcbdata.tracks[layer]) {
- if ('radius' in track) {
- if (pointWithinDistanceToArc(x, y, ...track.center, track.radius, track.startangle, track.endangle, track.width / 2)) {
- return track.net;
- }
- } else {
- if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) {
- return track.net;
- }
- }
- }
- }
- // Check pads
- if (settings.renderPads) {
- for (var footprint of pcbdata.footprints) {
- for (var pad of footprint.pads) {
- if (pad.layers.includes(layer) && pointWithinPad(x, y, pad)) {
- return pad.net;
- }
- }
- }
- }
- return null;
- }
- function pointWithinFootprintBbox(x, y, bbox) {
- var v = [x - bbox.pos[0], y - bbox.pos[1]];
- v = rotateVector(v, bbox.angle);
- return bbox.relpos[0] <= v[0] && v[0] <= bbox.relpos[0] + bbox.size[0] &&
- bbox.relpos[1] <= v[1] && v[1] <= bbox.relpos[1] + bbox.size[1];
- }
- function bboxHitScan(layer, x, y) {
- var result = [];
- for (var i = 0; i < pcbdata.footprints.length; i++) {
- var footprint = pcbdata.footprints[i];
- if (footprint.layer == layer) {
- if (pointWithinFootprintBbox(x, y, footprint.bbox)) {
- result.push(i);
- }
- }
- }
- return result;
- }
- function handlePointerDown(e, layerdict) {
- if (e.button != 0 && e.button != 1) {
- return;
- }
- e.preventDefault();
- e.stopPropagation();
- if (!e.hasOwnProperty("offsetX")) {
- // The polyfill doesn't set this properly
- e.offsetX = e.pageX - e.currentTarget.offsetLeft;
- e.offsetY = e.pageY - e.currentTarget.offsetTop;
- }
- layerdict.pointerStates[e.pointerId] = {
- distanceTravelled: 0,
- lastX: e.offsetX,
- lastY: e.offsetY,
- downTime: Date.now(),
- };
- }
- function handleMouseClick(e, layerdict) {
- if (!e.hasOwnProperty("offsetX")) {
- // The polyfill doesn't set this properly
- e.offsetX = e.pageX - e.currentTarget.offsetLeft;
- e.offsetY = e.pageY - e.currentTarget.offsetTop;
- }
- var x = e.offsetX;
- var y = e.offsetY;
- var t = layerdict.transform;
- var flip = layerdict.layer === "B";
- if (flip) {
- x = (devicePixelRatio * x / t.zoom - t.panx + t.x) / -t.s;
- } else {
- x = (devicePixelRatio * x / t.zoom - t.panx - t.x) / t.s;
- }
- y = (devicePixelRatio * y / t.zoom - t.y - t.pany) / t.s;
- var v = rotateVector([x, y], -settings.boardRotation + (flip && settings.offsetBackRotation ? - 180 : 0));
- if ("nets" in pcbdata) {
- var net = netHitScan(layerdict.layer, ...v);
- if (net !== highlightedNet) {
- netClicked(net);
- }
- }
- if (highlightedNet === null) {
- var footprints = bboxHitScan(layerdict.layer, ...v);
- if (footprints.length > 0) {
- footprintsClicked(footprints);
- }
- }
- }
- function handlePointerLeave(e, layerdict) {
- e.preventDefault();
- e.stopPropagation();
- if (!settings.redrawOnDrag) {
- redrawCanvas(layerdict);
- }
- delete layerdict.pointerStates[e.pointerId];
- }
- function resetTransform(layerdict) {
- layerdict.transform.panx = 0;
- layerdict.transform.pany = 0;
- layerdict.transform.zoom = 1;
- redrawCanvas(layerdict);
- }
- function handlePointerUp(e, layerdict) {
- if (!e.hasOwnProperty("offsetX")) {
- // The polyfill doesn't set this properly
- e.offsetX = e.pageX - e.currentTarget.offsetLeft;
- e.offsetY = e.pageY - e.currentTarget.offsetTop;
- }
- e.preventDefault();
- e.stopPropagation();
- if (e.button == 2) {
- // Reset pan and zoom on right click.
- resetTransform(layerdict);
- layerdict.anotherPointerTapped = false;
- return;
- }
- // We haven't necessarily had a pointermove event since the interaction started, so make sure we update this now
- var ptr = layerdict.pointerStates[e.pointerId];
- ptr.distanceTravelled += Math.abs(e.offsetX - ptr.lastX) + Math.abs(e.offsetY - ptr.lastY);
- if (e.button == 0 && ptr.distanceTravelled < 10 && Date.now() - ptr.downTime <= 500) {
- if (Object.keys(layerdict.pointerStates).length == 1) {
- if (layerdict.anotherPointerTapped) {
- // This is the second pointer coming off of a two-finger tap
- resetTransform(layerdict);
- } else {
- // This is just a regular tap
- handleMouseClick(e, layerdict);
- }
- layerdict.anotherPointerTapped = false;
- } else {
- // This is the first finger coming off of what could become a two-finger tap
- layerdict.anotherPointerTapped = true;
- }
- } else {
- if (!settings.redrawOnDrag) {
- redrawCanvas(layerdict);
- }
- layerdict.anotherPointerTapped = false;
- }
- delete layerdict.pointerStates[e.pointerId];
- }
- function handlePointerMove(e, layerdict) {
- if (!layerdict.pointerStates.hasOwnProperty(e.pointerId)) {
- return;
- }
- e.preventDefault();
- e.stopPropagation();
- if (!e.hasOwnProperty("offsetX")) {
- // The polyfill doesn't set this properly
- e.offsetX = e.pageX - e.currentTarget.offsetLeft;
- e.offsetY = e.pageY - e.currentTarget.offsetTop;
- }
- var thisPtr = layerdict.pointerStates[e.pointerId];
- var dx = e.offsetX - thisPtr.lastX;
- var dy = e.offsetY - thisPtr.lastY;
- // If this number is low on pointer up, we count the action as a click
- thisPtr.distanceTravelled += Math.abs(dx) + Math.abs(dy);
- if (Object.keys(layerdict.pointerStates).length == 1) {
- // This is a simple drag
- layerdict.transform.panx += devicePixelRatio * dx / layerdict.transform.zoom;
- layerdict.transform.pany += devicePixelRatio * dy / layerdict.transform.zoom;
- } else if (Object.keys(layerdict.pointerStates).length == 2) {
- var otherPtr = Object.values(layerdict.pointerStates).filter((ptr) => ptr != thisPtr)[0];
- var oldDist = Math.sqrt(Math.pow(thisPtr.lastX - otherPtr.lastX, 2) + Math.pow(thisPtr.lastY - otherPtr.lastY, 2));
- var newDist = Math.sqrt(Math.pow(e.offsetX - otherPtr.lastX, 2) + Math.pow(e.offsetY - otherPtr.lastY, 2));
- var scaleFactor = newDist / oldDist;
- if (scaleFactor != NaN) {
- layerdict.transform.zoom *= scaleFactor;
- var zoomd = (1 - scaleFactor) / layerdict.transform.zoom;
- layerdict.transform.panx += devicePixelRatio * otherPtr.lastX * zoomd;
- layerdict.transform.pany += devicePixelRatio * otherPtr.lastY * zoomd;
- }
- }
- thisPtr.lastX = e.offsetX;
- thisPtr.lastY = e.offsetY;
- if (settings.redrawOnDrag) {
- redrawCanvas(layerdict);
- }
- }
- function handleMouseWheel(e, layerdict) {
- e.preventDefault();
- e.stopPropagation();
- var t = layerdict.transform;
- var wheeldelta = e.deltaY;
- if (e.deltaMode == 1) {
- // FF only, scroll by lines
- wheeldelta *= 30;
- } else if (e.deltaMode == 2) {
- wheeldelta *= 300;
- }
- var m = Math.pow(1.1, -wheeldelta / 40);
- // Limit amount of zoom per tick.
- if (m > 2) {
- m = 2;
- } else if (m < 0.5) {
- m = 0.5;
- }
- t.zoom *= m;
- var zoomd = (1 - m) / t.zoom;
- t.panx += devicePixelRatio * e.offsetX * zoomd;
- t.pany += devicePixelRatio * e.offsetY * zoomd;
- redrawCanvas(layerdict);
- }
- function addMouseHandlers(div, layerdict) {
- div.addEventListener("pointerdown", function(e) {
- handlePointerDown(e, layerdict);
- });
- div.addEventListener("pointermove", function(e) {
- handlePointerMove(e, layerdict);
- });
- div.addEventListener("pointerup", function(e) {
- handlePointerUp(e, layerdict);
- });
- var pointerleave = function(e) {
- handlePointerLeave(e, layerdict);
- }
- div.addEventListener("pointercancel", pointerleave);
- div.addEventListener("pointerleave", pointerleave);
- div.addEventListener("pointerout", pointerleave);
- div.onwheel = function(e) {
- handleMouseWheel(e, layerdict);
- }
- for (var element of [div, layerdict.bg, layerdict.fab, layerdict.silk, layerdict.highlight]) {
- element.addEventListener("contextmenu", function(e) {
- e.preventDefault();
- }, false);
- }
- }
- function setRedrawOnDrag(value) {
- settings.redrawOnDrag = value;
- writeStorage("redrawOnDrag", value);
- }
- function setBoardRotation(value) {
- settings.boardRotation = value * 5;
- writeStorage("boardRotation", settings.boardRotation);
- document.getElementById("rotationDegree").textContent = settings.boardRotation;
- resizeAll();
- }
- function setOffsetBackRotation(value) {
- settings.offsetBackRotation = value;
- writeStorage("offsetBackRotation", value);
- resizeAll();
- }
- function initRender() {
- allcanvas = {
- front: {
- transform: {
- x: 0,
- y: 0,
- s: 1,
- panx: 0,
- pany: 0,
- zoom: 1,
- },
- pointerStates: {},
- anotherPointerTapped: false,
- bg: document.getElementById("F_bg"),
- fab: document.getElementById("F_fab"),
- silk: document.getElementById("F_slk"),
- highlight: document.getElementById("F_hl"),
- layer: "F",
- },
- back: {
- transform: {
- x: 0,
- y: 0,
- s: 1,
- panx: 0,
- pany: 0,
- zoom: 1,
- },
- pointerStates: {},
- anotherPointerTapped: false,
- bg: document.getElementById("B_bg"),
- fab: document.getElementById("B_fab"),
- silk: document.getElementById("B_slk"),
- highlight: document.getElementById("B_hl"),
- layer: "B",
- }
- };
- addMouseHandlers(document.getElementById("frontcanvas"), allcanvas.front);
- addMouseHandlers(document.getElementById("backcanvas"), allcanvas.back);
- }
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- /*
- * Table reordering via Drag'n'Drop
- * Inspired by: https://htmldom.dev/drag-and-drop-table-column
- */
- function setBomHandlers() {
- const bom = document.getElementById('bomtable');
- let dragName;
- let placeHolderElements;
- let draggingElement;
- let forcePopulation;
- let xOffset;
- let yOffset;
- let wasDragged;
- const mouseUpHandler = function(e) {
- // Delete dragging element
- draggingElement.remove();
- // Make BOM selectable again
- bom.style.removeProperty("userSelect");
- // Remove listeners
- document.removeEventListener('mousemove', mouseMoveHandler);
- document.removeEventListener('mouseup', mouseUpHandler);
- if (wasDragged) {
- // Redraw whole BOM
- populateBomTable();
- }
- }
- const mouseMoveHandler = function(e) {
- // Notice the dragging
- wasDragged = true;
- // Make the dragged element visible
- draggingElement.style.removeProperty("display");
- // Set elements position to mouse position
- draggingElement.style.left = `${e.screenX - xOffset}px`;
- draggingElement.style.top = `${e.screenY - yOffset}px`;
- // Forced redrawing of BOM table
- if (forcePopulation) {
- forcePopulation = false;
- // Copy array
- phe = Array.from(placeHolderElements);
- // populate BOM table again
- populateBomHeader(dragName, phe);
- populateBomBody(dragName, phe);
- }
- // Set up array of hidden columns
- var hiddenColumns = Array.from(settings.hiddenColumns);
- // In the ungrouped mode, quantity don't exist
- if (settings.bommode === "ungrouped")
- hiddenColumns.push("Quantity");
- // If no checkbox fields can be found, we consider them hidden
- if (settings.checkboxes.length == 0)
- hiddenColumns.push("checkboxes");
- // Get table headers and group them into checkboxes, extrafields and normal headers
- const bh = document.getElementById("bomhead");
- headers = Array.from(bh.querySelectorAll("th"))
- headers.shift() // numCol is not part of the columnOrder
- headerGroups = []
- lastCompoundClass = null;
- for (i = 0; i < settings.columnOrder.length; i++) {
- cElem = settings.columnOrder[i];
- if (hiddenColumns.includes(cElem)) {
- // Hidden columns appear as a dummy element
- headerGroups.push([]);
- continue;
- }
- elem = headers.filter(e => getColumnOrderName(e) === cElem)[0];
- if (elem.classList.contains("bom-checkbox")) {
- if (lastCompoundClass === "bom-checkbox") {
- cbGroup = headerGroups.pop();
- cbGroup.push(elem);
- headerGroups.push(cbGroup);
- } else {
- lastCompoundClass = "bom-checkbox";
- headerGroups.push([elem])
- }
- } else {
- headerGroups.push([elem])
- }
- }
- // Copy settings.columnOrder
- var columns = Array.from(settings.columnOrder)
- // Set up array with indices of hidden columns
- var hiddenIndices = hiddenColumns.map(e => settings.columnOrder.indexOf(e));
- var dragIndex = columns.indexOf(dragName);
- var swapIndex = dragIndex;
- var swapDone = false;
- // Check if the current dragged element is swapable with the left or right element
- if (dragIndex > 0) {
- // Get left headers boundingbox
- swapIndex = dragIndex - 1;
- while (hiddenIndices.includes(swapIndex) && swapIndex > 0)
- swapIndex--;
- if (!hiddenIndices.includes(swapIndex)) {
- box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
- if (e.clientX < box.left + window.scrollX + (box.width / 2)) {
- swapElement = columns[dragIndex];
- columns.splice(dragIndex, 1);
- columns.splice(swapIndex, 0, swapElement);
- forcePopulation = true;
- swapDone = true;
- }
- }
- }
- if ((!swapDone) && dragIndex < headerGroups.length - 1) {
- // Get right headers boundingbox
- swapIndex = dragIndex + 1;
- while (hiddenIndices.includes(swapIndex))
- swapIndex++;
- if (swapIndex < headerGroups.length) {
- box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
- if (e.clientX > box.left + window.scrollX + (box.width / 2)) {
- swapElement = columns[dragIndex];
- columns.splice(dragIndex, 1);
- columns.splice(swapIndex, 0, swapElement);
- forcePopulation = true;
- swapDone = true;
- }
- }
- }
- // Write back change to storage
- if (swapDone) {
- settings.columnOrder = columns
- writeStorage("columnOrder", JSON.stringify(columns));
- }
- }
- const mouseDownHandler = function(e) {
- var target = e.target;
- if (target.tagName.toLowerCase() != "td")
- target = target.parentElement;
- // Used to check if a dragging has ever happened
- wasDragged = false;
- // Create new element which will be displayed as the dragged column
- draggingElement = document.createElement("div")
- draggingElement.classList.add("dragging");
- draggingElement.style.display = "none";
- draggingElement.style.position = "absolute";
- draggingElement.style.overflow = "hidden";
- // Get bomhead and bombody elements
- const bh = document.getElementById("bomhead");
- const bb = document.getElementById("bombody");
- // Get all compound headers for the current column
- var compoundHeaders;
- if (target.classList.contains("bom-checkbox")) {
- compoundHeaders = Array.from(bh.querySelectorAll("th.bom-checkbox"));
- } else {
- compoundHeaders = [target];
- }
- // Create new table which will display the column
- var newTable = document.createElement("table");
- newTable.classList.add("bom");
- newTable.style.background = "white";
- draggingElement.append(newTable);
- // Create new header element
- var newHeader = document.createElement("thead");
- newTable.append(newHeader);
- // Set up array for storing all placeholder elements
- placeHolderElements = [];
- // Add all compound headers to the new thead element and placeholders
- compoundHeaders.forEach(function(h) {
- clone = cloneElementWithDimensions(h);
- newHeader.append(clone);
- placeHolderElements.push(clone);
- });
- // Create new body element
- var newBody = document.createElement("tbody");
- newTable.append(newBody);
- // Get indices for compound headers
- var idxs = compoundHeaders.map(e => getBomTableHeaderIndex(e));
- // For each row in the BOM body...
- var rows = bb.querySelectorAll("tr");
- rows.forEach(function(row) {
- // ..get the cells for the compound column
- const tds = row.querySelectorAll("td");
- var copytds = idxs.map(i => tds[i]);
- // Add them to the new element and the placeholders
- var newRow = document.createElement("tr");
- copytds.forEach(function(td) {
- clone = cloneElementWithDimensions(td);
- newRow.append(clone);
- placeHolderElements.push(clone);
- });
- newBody.append(newRow);
- });
- // Compute width for compound header
- var width = compoundHeaders.reduce((acc, x) => acc + x.clientWidth, 0);
- draggingElement.style.width = `${width}px`;
- // Insert the new dragging element and disable selection on BOM
- bom.insertBefore(draggingElement, null);
- bom.style.userSelect = "none";
- // Determine the mouse position offset
- xOffset = e.screenX - compoundHeaders.reduce((acc, x) => Math.min(acc, x.offsetLeft), compoundHeaders[0].offsetLeft);
- yOffset = e.screenY - compoundHeaders[0].offsetTop;
- // Get name for the column in settings.columnOrder
- dragName = getColumnOrderName(target);
- // Change text and class for placeholder elements
- placeHolderElements = placeHolderElements.map(function(e) {
- newElem = cloneElementWithDimensions(e);
- newElem.textContent = "";
- newElem.classList.add("placeholder");
- return newElem;
- });
- // On next mouse move, the whole BOM needs to be redrawn to show the placeholders
- forcePopulation = true;
- // Add listeners for move and up on mouse
- document.addEventListener('mousemove', mouseMoveHandler);
- document.addEventListener('mouseup', mouseUpHandler);
- }
- // In netlist mode, there is nothing to reorder
- if (settings.bommode === "netlist")
- return;
- // Add mouseDownHandler to every column except the numCol
- bom.querySelectorAll("th")
- .forEach(function(head) {
- if (!head.classList.contains("numCol")) {
- head.onmousedown = mouseDownHandler;
- }
- });
- }
- function getBoundingClientRectFromMultiple(elements) {
- var elems = Array.from(elements);
- if (elems.length == 0)
- return null;
- var box = elems.shift()
- .getBoundingClientRect();
- elems.forEach(function(elem) {
- var elembox = elem.getBoundingClientRect();
- box.left = Math.min(elembox.left, box.left);
- box.top = Math.min(elembox.top, box.top);
- box.width += elembox.width;
- box.height = Math.max(elembox.height, box.height);
- });
- return box;
- }
- function cloneElementWithDimensions(elem) {
- var newElem = elem.cloneNode(true);
- newElem.style.height = window.getComputedStyle(elem).height;
- newElem.style.width = window.getComputedStyle(elem).width;
- return newElem;
- }
- function getBomTableHeaderIndex(elem) {
- const bh = document.getElementById('bomhead');
- const ths = Array.from(bh.querySelectorAll("th"));
- return ths.indexOf(elem);
- }
- function getColumnOrderName(elem) {
- var cname = elem.getAttribute("col_name");
- if (cname === "bom-checkbox")
- return "checkboxes";
- else
- return cname;
- }
- function resizableGrid(tablehead) {
- var cols = tablehead.firstElementChild.children;
- var rowWidth = tablehead.offsetWidth;
- for (var i = 1; i < cols.length; i++) {
- if (cols[i].classList.contains("bom-checkbox"))
- continue;
- cols[i].style.width = ((cols[i].clientWidth - paddingDiff(cols[i])) * 100 / rowWidth) + '%';
- }
- for (var i = 1; i < cols.length - 1; i++) {
- var div = document.createElement('div');
- div.className = "column-width-handle";
- cols[i].appendChild(div);
- setListeners(div);
- }
- function setListeners(div) {
- var startX, curCol, nxtCol, curColWidth, nxtColWidth, rowWidth;
- div.addEventListener('mousedown', function(e) {
- e.preventDefault();
- e.stopPropagation();
- curCol = e.target.parentElement;
- nxtCol = curCol.nextElementSibling;
- startX = e.pageX;
- var padding = paddingDiff(curCol);
- rowWidth = curCol.parentElement.offsetWidth;
- curColWidth = curCol.clientWidth - padding;
- nxtColWidth = nxtCol.clientWidth - padding;
- });
- document.addEventListener('mousemove', function(e) {
- if (startX) {
- var diffX = e.pageX - startX;
- diffX = -Math.min(-diffX, curColWidth - 20);
- diffX = Math.min(diffX, nxtColWidth - 20);
- curCol.style.width = ((curColWidth + diffX) * 100 / rowWidth) + '%';
- nxtCol.style.width = ((nxtColWidth - diffX) * 100 / rowWidth) + '%';
- console.log(`${curColWidth + nxtColWidth} ${(curColWidth + diffX) * 100 / rowWidth + (nxtColWidth - diffX) * 100 / rowWidth}`);
- }
- });
- document.addEventListener('mouseup', function(e) {
- curCol = undefined;
- nxtCol = undefined;
- startX = undefined;
- nxtColWidth = undefined;
- curColWidth = undefined
- });
- }
- function paddingDiff(col) {
- if (getStyleVal(col, 'box-sizing') == 'border-box') {
- return 0;
- }
- var padLeft = getStyleVal(col, 'padding-left');
- var padRight = getStyleVal(col, 'padding-right');
- return (parseInt(padLeft) + parseInt(padRight));
- }
- function getStyleVal(elm, css) {
- return (window.getComputedStyle(elm, null).getPropertyValue(css))
- }
- }
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- /* DOM manipulation and misc code */
- var bomsplit;
- var canvassplit;
- var initDone = false;
- var bomSortFunction = null;
- var currentSortColumn = null;
- var currentSortOrder = null;
- var currentHighlightedRowId;
- var highlightHandlers = [];
- var footprintIndexToHandler = {};
- var netsToHandler = {};
- var markedFootprints = new Set();
- var highlightedFootprints = [];
- var highlightedNet = null;
- var lastClicked;
- function dbg(html) {
- dbgdiv.innerHTML = html;
- }
- function redrawIfInitDone() {
- if (initDone) {
- redrawCanvas(allcanvas.front);
- redrawCanvas(allcanvas.back);
- }
- }
- function padsVisible(value) {
- writeStorage("padsVisible", value);
- settings.renderPads = value;
- redrawIfInitDone();
- }
- function referencesVisible(value) {
- writeStorage("referencesVisible", value);
- settings.renderReferences = value;
- redrawIfInitDone();
- }
- function valuesVisible(value) {
- writeStorage("valuesVisible", value);
- settings.renderValues = value;
- redrawIfInitDone();
- }
- function tracksVisible(value) {
- writeStorage("tracksVisible", value);
- settings.renderTracks = value;
- redrawIfInitDone();
- }
- function zonesVisible(value) {
- writeStorage("zonesVisible", value);
- settings.renderZones = value;
- redrawIfInitDone();
- }
- function dnpOutline(value) {
- writeStorage("dnpOutline", value);
- settings.renderDnpOutline = value;
- redrawIfInitDone();
- }
- function setDarkMode(value) {
- if (value) {
- topmostdiv.classList.add("dark");
- } else {
- topmostdiv.classList.remove("dark");
- }
- writeStorage("darkmode", value);
- settings.darkMode = value;
- redrawIfInitDone();
- if (initDone) {
- populateBomTable();
- }
- }
- function setShowBOMColumn(field, value) {
- if (field === "references") {
- var rl = document.getElementById("reflookup");
- rl.disabled = !value;
- if (!value) {
- rl.value = "";
- updateRefLookup("");
- }
- }
- var n = settings.hiddenColumns.indexOf(field);
- if (value) {
- if (n != -1) {
- settings.hiddenColumns.splice(n, 1);
- }
- } else {
- if (n == -1) {
- settings.hiddenColumns.push(field);
- }
- }
- writeStorage("hiddenColumns", JSON.stringify(settings.hiddenColumns));
- if (initDone) {
- populateBomTable();
- }
- redrawIfInitDone();
- }
- function setFullscreen(value) {
- if (value) {
- document.documentElement.requestFullscreen();
- } else {
- document.exitFullscreen();
- }
- }
- function fabricationVisible(value) {
- writeStorage("fabricationVisible", value);
- settings.renderFabrication = value;
- redrawIfInitDone();
- }
- function silkscreenVisible(value) {
- writeStorage("silkscreenVisible", value);
- settings.renderSilkscreen = value;
- redrawIfInitDone();
- }
- function setHighlightPin1(value) {
- writeStorage("highlightpin1", value);
- settings.highlightpin1 = value;
- redrawIfInitDone();
- }
- function getStoredCheckboxRefs(checkbox) {
- function convert(ref) {
- var intref = parseInt(ref);
- if (isNaN(intref)) {
- for (var i = 0; i < pcbdata.footprints.length; i++) {
- if (pcbdata.footprints[i].ref == ref) {
- return i;
- }
- }
- return -1;
- } else {
- return intref;
- }
- }
- if (!(checkbox in settings.checkboxStoredRefs)) {
- var val = readStorage("checkbox_" + checkbox);
- settings.checkboxStoredRefs[checkbox] = val ? val : "";
- }
- if (!settings.checkboxStoredRefs[checkbox]) {
- return new Set();
- } else {
- return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0));
- }
- }
- function getCheckboxState(checkbox, references) {
- var storedRefsSet = getStoredCheckboxRefs(checkbox);
- var currentRefsSet = new Set(references.map(r => r[1]));
- // Get difference of current - stored
- var difference = new Set(currentRefsSet);
- for (ref of storedRefsSet) {
- difference.delete(ref);
- }
- if (difference.size == 0) {
- // All the current refs are stored
- return "checked";
- } else if (difference.size == currentRefsSet.size) {
- // None of the current refs are stored
- return "unchecked";
- } else {
- // Some of the refs are stored
- return "indeterminate";
- }
- }
- function setBomCheckboxState(checkbox, element, references) {
- var state = getCheckboxState(checkbox, references);
- element.checked = (state == "checked");
- element.indeterminate = (state == "indeterminate");
- }
- function createCheckboxChangeHandler(checkbox, references, row) {
- return function () {
- refsSet = getStoredCheckboxRefs(checkbox);
- var markWhenChecked = settings.markWhenChecked == checkbox;
- eventArgs = {
- checkbox: checkbox,
- refs: references,
- }
- if (this.checked) {
- // checkbox ticked
- for (var ref of references) {
- refsSet.add(ref[1]);
- }
- if (markWhenChecked) {
- row.classList.add("checked");
- for (var ref of references) {
- markedFootprints.add(ref[1]);
- }
- drawHighlights();
- }
- eventArgs.state = 'checked';
- } else {
- // checkbox unticked
- for (var ref of references) {
- refsSet.delete(ref[1]);
- }
- if (markWhenChecked) {
- row.classList.remove("checked");
- for (var ref of references) {
- markedFootprints.delete(ref[1]);
- }
- drawHighlights();
- }
- eventArgs.state = 'unchecked';
- }
- settings.checkboxStoredRefs[checkbox] = [...refsSet].join(",");
- writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
- updateCheckboxStats(checkbox);
- EventHandler.emitEvent(IBOM_EVENT_TYPES.CHECKBOX_CHANGE_EVENT, eventArgs);
- }
- }
- function clearHighlightedFootprints() {
- if (currentHighlightedRowId) {
- document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
- currentHighlightedRowId = null;
- highlightedFootprints = [];
- highlightedNet = null;
- }
- }
- function createRowHighlightHandler(rowid, refs, net) {
- return function () {
- if (currentHighlightedRowId) {
- if (currentHighlightedRowId == rowid) {
- return;
- }
- document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
- }
- document.getElementById(rowid).classList.add("highlighted");
- currentHighlightedRowId = rowid;
- highlightedFootprints = refs ? refs.map(r => r[1]) : [];
- highlightedNet = net;
- drawHighlights();
- EventHandler.emitEvent(
- IBOM_EVENT_TYPES.HIGHLIGHT_EVENT, {
- rowid: rowid,
- refs: refs,
- net: net
- });
- }
- }
- function updateNetColors() {
- writeStorage("netColors", JSON.stringify(settings.netColors));
- redrawIfInitDone();
- }
- function netColorChangeHandler(net) {
- return (event) => {
- settings.netColors[net] = event.target.value;
- updateNetColors();
- }
- }
- function netColorRightClick(net) {
- return (event) => {
- if (event.button == 2) {
- event.preventDefault();
- event.stopPropagation();
- var style = getComputedStyle(topmostdiv);
- var defaultNetColor = style.getPropertyValue('--track-color').trim();
- event.target.value = defaultNetColor;
- delete settings.netColors[net];
- updateNetColors();
- }
- }
- }
- function entryMatches(entry) {
- if (settings.bommode == "netlist") {
- // entry is just a net name
- return entry.toLowerCase().indexOf(filter) >= 0;
- }
- // check refs
- if (!settings.hiddenColumns.includes("references")) {
- for (var ref of entry) {
- if (ref[0].toLowerCase().indexOf(filter) >= 0) {
- return true;
- }
- }
- }
- // check fields
- for (var i in config.fields) {
- var f = config.fields[i];
- if (!settings.hiddenColumns.includes(f)) {
- for (var ref of entry) {
- if (String(pcbdata.bom.fields[ref[1]][i]).toLowerCase().indexOf(filter) >= 0) {
- return true;
- }
- }
- }
- }
- return false;
- }
- function findRefInEntry(entry) {
- return entry.filter(r => r[0].toLowerCase() == reflookup);
- }
- function highlightFilter(s) {
- if (!filter) {
- return s;
- }
- var parts = s.toLowerCase().split(filter);
- if (parts.length == 1) {
- return s;
- }
- var r = "";
- var pos = 0;
- for (var i in parts) {
- if (i > 0) {
- r += '<mark class="highlight">' +
- s.substring(pos, pos + filter.length) +
- '</mark>';
- pos += filter.length;
- }
- r += s.substring(pos, pos + parts[i].length);
- pos += parts[i].length;
- }
- return r;
- }
- function checkboxSetUnsetAllHandler(checkboxname) {
- return function () {
- var checkboxnum = 0;
- while (checkboxnum < settings.checkboxes.length &&
- settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
- checkboxnum++;
- }
- if (checkboxnum >= settings.checkboxes.length) {
- return;
- }
- var allset = true;
- var checkbox;
- var row;
- for (row of bombody.childNodes) {
- checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
- if (!checkbox.checked || checkbox.indeterminate) {
- allset = false;
- break;
- }
- }
- for (row of bombody.childNodes) {
- checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
- checkbox.checked = !allset;
- checkbox.indeterminate = false;
- checkbox.onchange();
- }
- }
- }
- function createColumnHeader(name, cls, comparator, is_checkbox = false) {
- var th = document.createElement("TH");
- th.innerHTML = name;
- th.classList.add(cls);
- if (is_checkbox)
- th.setAttribute("col_name", "bom-checkbox");
- else
- th.setAttribute("col_name", name);
- var span = document.createElement("SPAN");
- span.classList.add("sortmark");
- span.classList.add("none");
- th.appendChild(span);
- var spacer = document.createElement("div");
- spacer.className = "column-spacer";
- th.appendChild(spacer);
- spacer.onclick = function () {
- if (currentSortColumn && th !== currentSortColumn) {
- // Currently sorted by another column
- currentSortColumn.childNodes[1].classList.remove(currentSortOrder);
- currentSortColumn.childNodes[1].classList.add("none");
- currentSortColumn = null;
- currentSortOrder = null;
- }
- if (currentSortColumn && th === currentSortColumn) {
- // Already sorted by this column
- if (currentSortOrder == "asc") {
- // Sort by this column, descending order
- bomSortFunction = function (a, b) {
- return -comparator(a, b);
- }
- currentSortColumn.childNodes[1].classList.remove("asc");
- currentSortColumn.childNodes[1].classList.add("desc");
- currentSortOrder = "desc";
- } else {
- // Unsort
- bomSortFunction = null;
- currentSortColumn.childNodes[1].classList.remove("desc");
- currentSortColumn.childNodes[1].classList.add("none");
- currentSortColumn = null;
- currentSortOrder = null;
- }
- } else {
- // Sort by this column, ascending order
- bomSortFunction = comparator;
- currentSortColumn = th;
- currentSortColumn.childNodes[1].classList.remove("none");
- currentSortColumn.childNodes[1].classList.add("asc");
- currentSortOrder = "asc";
- }
- populateBomBody();
- }
- if (is_checkbox) {
- spacer.onclick = fancyDblClickHandler(
- spacer, spacer.onclick, checkboxSetUnsetAllHandler(name));
- }
- return th;
- }
- function populateBomHeader(placeHolderColumn = null, placeHolderElements = null) {
- while (bomhead.firstChild) {
- bomhead.removeChild(bomhead.firstChild);
- }
- var tr = document.createElement("TR");
- var th = document.createElement("TH");
- th.classList.add("numCol");
- var vismenu = document.createElement("div");
- vismenu.id = "vismenu";
- vismenu.classList.add("menu");
- var visbutton = document.createElement("div");
- visbutton.classList.add("visbtn");
- visbutton.classList.add("hideonprint");
- var viscontent = document.createElement("div");
- viscontent.classList.add("menu-content");
- viscontent.id = "vismenu-content";
- settings.columnOrder.forEach(column => {
- if (typeof column !== "string")
- return;
- // Skip empty columns
- if (column === "checkboxes" && settings.checkboxes.length == 0)
- return;
- else if (column === "Quantity" && settings.bommode == "ungrouped")
- return;
- var label = document.createElement("label");
- label.classList.add("menu-label");
- var input = document.createElement("input");
- input.classList.add("visibility_checkbox");
- input.type = "checkbox";
- input.onchange = function (e) {
- setShowBOMColumn(column, e.target.checked)
- };
- input.checked = !(settings.hiddenColumns.includes(column));
- label.appendChild(input);
- if (column.length > 0)
- label.append(column[0].toUpperCase() + column.slice(1));
- viscontent.appendChild(label);
- });
- viscontent.childNodes[0].classList.add("menu-label-top");
- vismenu.appendChild(visbutton);
- if (settings.bommode != "netlist") {
- vismenu.appendChild(viscontent);
- th.appendChild(vismenu);
- }
- tr.appendChild(th);
- var checkboxCompareClosure = function (checkbox) {
- return (a, b) => {
- var stateA = getCheckboxState(checkbox, a);
- var stateB = getCheckboxState(checkbox, b);
- if (stateA > stateB) return -1;
- if (stateA < stateB) return 1;
- return 0;
- }
- }
- var stringFieldCompareClosure = function (fieldIndex) {
- return (a, b) => {
- var fa = pcbdata.bom.fields[a[0][1]][fieldIndex];
- var fb = pcbdata.bom.fields[b[0][1]][fieldIndex];
- if (fa != fb) return fa > fb ? 1 : -1;
- else return 0;
- }
- }
- var referenceRegex = /(?<prefix>[^0-9]+)(?<number>[0-9]+)/;
- var compareRefs = (a, b) => {
- var ra = referenceRegex.exec(a);
- var rb = referenceRegex.exec(b);
- if (ra === null || rb === null) {
- if (a != b) return a > b ? 1 : -1;
- return 0;
- } else {
- if (ra.groups.prefix != rb.groups.prefix) {
- return ra.groups.prefix > rb.groups.prefix ? 1 : -1;
- }
- if (ra.groups.number != rb.groups.number) {
- return parseInt(ra.groups.number) > parseInt(rb.groups.number) ? 1 : -1;
- }
- return 0;
- }
- }
- if (settings.bommode == "netlist") {
- tr.appendChild(createColumnHeader("Net name", "bom-netname", (a, b) => {
- if (a > b) return -1;
- if (a < b) return 1;
- return 0;
- }));
- tr.appendChild(createColumnHeader("Color", "bom-color", (a, b) => {
- return 0;
- }));
- } else {
- // Filter hidden columns
- var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
- var valueIndex = config.fields.indexOf("Value");
- var footprintIndex = config.fields.indexOf("Footprint");
- columns.forEach((column) => {
- if (column === placeHolderColumn) {
- var n = 1;
- if (column === "checkboxes")
- n = settings.checkboxes.length;
- for (i = 0; i < n; i++) {
- td = placeHolderElements.shift();
- tr.appendChild(td);
- }
- return;
- } else if (column === "checkboxes") {
- for (var checkbox of settings.checkboxes) {
- th = createColumnHeader(
- checkbox, "bom-checkbox", checkboxCompareClosure(checkbox), true);
- tr.appendChild(th);
- }
- } else if (column === "References") {
- tr.appendChild(createColumnHeader("References", "references", (a, b) => {
- var i = 0;
- while (i < a.length && i < b.length) {
- if (a[i] != b[i]) return compareRefs(a[i][0], b[i][0]);
- i++;
- }
- return a.length - b.length;
- }));
- } else if (column === "Value") {
- tr.appendChild(createColumnHeader("Value", "value", (a, b) => {
- var ra = a[0][1], rb = b[0][1];
- return valueCompare(
- pcbdata.bom.parsedValues[ra], pcbdata.bom.parsedValues[rb],
- pcbdata.bom.fields[ra][valueIndex], pcbdata.bom.fields[rb][valueIndex]);
- }));
- return;
- } else if (column === "Footprint") {
- tr.appendChild(createColumnHeader(
- "Footprint", "footprint", stringFieldCompareClosure(footprintIndex)));
- } else if (column === "Quantity" && settings.bommode == "grouped") {
- tr.appendChild(createColumnHeader("Quantity", "quantity", (a, b) => {
- return a.length - b.length;
- }));
- } else {
- // Other fields
- var i = config.fields.indexOf(column);
- if (i < 0)
- return;
- tr.appendChild(createColumnHeader(
- column, `field${i + 1}`, stringFieldCompareClosure(i)));
- }
- });
- }
- bomhead.appendChild(tr);
- }
- function populateBomBody(placeholderColumn = null, placeHolderElements = null) {
- const urlRegex = /^(https?:\/\/[^\s\/$.?#][^\s]*|file:\/\/([a-zA-Z]:|\/)[^\x00]+)$/;
- while (bom.firstChild) {
- bom.removeChild(bom.firstChild);
- }
- highlightHandlers = [];
- footprintIndexToHandler = {};
- netsToHandler = {};
- currentHighlightedRowId = null;
- var first = true;
- var style = getComputedStyle(topmostdiv);
- var defaultNetColor = style.getPropertyValue('--track-color').trim();
- if (settings.bommode == "netlist") {
- bomtable = pcbdata.nets.slice();
- } else {
- switch (settings.canvaslayout) {
- case 'F':
- bomtable = pcbdata.bom.F.slice();
- break;
- case 'FB':
- bomtable = pcbdata.bom.both.slice();
- break;
- case 'B':
- bomtable = pcbdata.bom.B.slice();
- break;
- }
- if (settings.bommode == "ungrouped") {
- // expand bom table
- expandedTable = []
- for (var bomentry of bomtable) {
- for (var ref of bomentry) {
- expandedTable.push([ref]);
- }
- }
- bomtable = expandedTable;
- }
- }
- if (bomSortFunction) {
- bomtable = bomtable.sort(bomSortFunction);
- }
- for (var i in bomtable) {
- var bomentry = bomtable[i];
- if (filter && !entryMatches(bomentry)) {
- continue;
- }
- var references = null;
- var netname = null;
- var tr = document.createElement("TR");
- var td = document.createElement("TD");
- var rownum = +i + 1;
- tr.id = "bomrow" + rownum;
- td.textContent = rownum;
- tr.appendChild(td);
- if (settings.bommode == "netlist") {
- netname = bomentry;
- td = document.createElement("TD");
- td.innerHTML = highlightFilter(netname ? netname : "<no net>");
- tr.appendChild(td);
- var color = settings.netColors[netname] || defaultNetColor;
- td = document.createElement("TD");
- var colorBox = document.createElement("INPUT");
- colorBox.type = "color";
- colorBox.value = color;
- colorBox.onchange = netColorChangeHandler(netname);
- colorBox.onmouseup = netColorRightClick(netname);
- colorBox.oncontextmenu = (e) => e.preventDefault();
- td.appendChild(colorBox);
- td.classList.add("color-column");
- tr.appendChild(td);
- } else {
- if (reflookup) {
- references = findRefInEntry(bomentry);
- if (references.length == 0) {
- continue;
- }
- } else {
- references = bomentry;
- }
- // Filter hidden columns
- var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
- columns.forEach((column) => {
- if (column === placeholderColumn) {
- var n = 1;
- if (column === "checkboxes")
- n = settings.checkboxes.length;
- for (i = 0; i < n; i++) {
- td = placeHolderElements.shift();
- tr.appendChild(td);
- }
- return;
- } else if (column === "checkboxes") {
- for (var checkbox of settings.checkboxes) {
- if (checkbox) {
- td = document.createElement("TD");
- var input = document.createElement("input");
- input.type = "checkbox";
- input.onchange = createCheckboxChangeHandler(checkbox, references, tr);
- setBomCheckboxState(checkbox, input, references);
- if (input.checked && settings.markWhenChecked == checkbox) {
- tr.classList.add("checked");
- }
- td.appendChild(input);
- tr.appendChild(td);
- }
- }
- } else if (column === "References") {
- td = document.createElement("TD");
- td.innerHTML = highlightFilter(references.map(r => r[0]).join(", "));
- tr.appendChild(td);
- } else if (column === "Quantity" && settings.bommode == "grouped") {
- // Quantity
- td = document.createElement("TD");
- td.textContent = references.length;
- tr.appendChild(td);
- } else {
- // All the other fields
- var field_index = config.fields.indexOf(column)
- if (field_index < 0)
- return;
- var valueSet = new Set();
- references.map(r => r[1]).forEach((id) => valueSet.add(pcbdata.bom.fields[id][field_index]));
- td = document.createElement("TD");
- var output = new Array();
- for (let item of valueSet) {
- const visible = highlightFilter(String(item));
- if (typeof item === 'string' && item.match(urlRegex)) {
- output.push(`<a href="${item}" target="_blank">${visible}</a>`);
- } else {
- output.push(visible);
- }
- }
- td.innerHTML = output.join(", ");
- tr.appendChild(td);
- }
- });
- }
- bom.appendChild(tr);
- var handler = createRowHighlightHandler(tr.id, references, netname);
- tr.onmousemove = handler;
- highlightHandlers.push({
- id: tr.id,
- handler: handler,
- });
- if (references !== null) {
- for (var refIndex of references.map(r => r[1])) {
- footprintIndexToHandler[refIndex] = handler;
- }
- }
- if (netname !== null) {
- netsToHandler[netname] = handler;
- }
- if ((filter || reflookup) && first) {
- handler();
- first = false;
- }
- }
- EventHandler.emitEvent(
- IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT, {
- filter: filter,
- reflookup: reflookup,
- checkboxes: settings.checkboxes,
- bommode: settings.bommode,
- });
- }
- function highlightPreviousRow() {
- if (!currentHighlightedRowId) {
- highlightHandlers[highlightHandlers.length - 1].handler();
- } else {
- if (highlightHandlers.length > 1 &&
- highlightHandlers[0].id == currentHighlightedRowId) {
- highlightHandlers[highlightHandlers.length - 1].handler();
- } else {
- for (var i = 0; i < highlightHandlers.length - 1; i++) {
- if (highlightHandlers[i + 1].id == currentHighlightedRowId) {
- highlightHandlers[i].handler();
- break;
- }
- }
- }
- }
- smoothScrollToRow(currentHighlightedRowId);
- }
- function highlightNextRow() {
- if (!currentHighlightedRowId) {
- highlightHandlers[0].handler();
- } else {
- if (highlightHandlers.length > 1 &&
- highlightHandlers[highlightHandlers.length - 1].id == currentHighlightedRowId) {
- highlightHandlers[0].handler();
- } else {
- for (var i = 1; i < highlightHandlers.length; i++) {
- if (highlightHandlers[i - 1].id == currentHighlightedRowId) {
- highlightHandlers[i].handler();
- break;
- }
- }
- }
- }
- smoothScrollToRow(currentHighlightedRowId);
- }
- function populateBomTable() {
- populateBomHeader();
- populateBomBody();
- setBomHandlers();
- resizableGrid(bomhead);
- }
- function footprintsClicked(footprintIndexes) {
- var lastClickedIndex = footprintIndexes.indexOf(lastClicked);
- for (var i = 1; i <= footprintIndexes.length; i++) {
- var refIndex = footprintIndexes[(lastClickedIndex + i) % footprintIndexes.length];
- if (refIndex in footprintIndexToHandler) {
- lastClicked = refIndex;
- footprintIndexToHandler[refIndex]();
- smoothScrollToRow(currentHighlightedRowId);
- break;
- }
- }
- }
- function netClicked(net) {
- if (net in netsToHandler) {
- netsToHandler[net]();
- smoothScrollToRow(currentHighlightedRowId);
- } else {
- clearHighlightedFootprints();
- highlightedNet = net;
- drawHighlights();
- }
- }
- function updateFilter(input) {
- filter = input.toLowerCase();
- populateBomTable();
- }
- function updateRefLookup(input) {
- reflookup = input.toLowerCase();
- populateBomTable();
- }
- function changeCanvasLayout(layout) {
- document.getElementById("fl-btn").classList.remove("depressed");
- document.getElementById("fb-btn").classList.remove("depressed");
- document.getElementById("bl-btn").classList.remove("depressed");
- switch (layout) {
- case 'F':
- document.getElementById("fl-btn").classList.add("depressed");
- if (settings.bomlayout != "bom-only") {
- canvassplit.collapse(1);
- }
- break;
- case 'B':
- document.getElementById("bl-btn").classList.add("depressed");
- if (settings.bomlayout != "bom-only") {
- canvassplit.collapse(0);
- }
- break;
- default:
- document.getElementById("fb-btn").classList.add("depressed");
- if (settings.bomlayout != "bom-only") {
- canvassplit.setSizes([50, 50]);
- }
- }
- settings.canvaslayout = layout;
- writeStorage("canvaslayout", layout);
- resizeAll();
- changeBomMode(settings.bommode);
- }
- function populateMetadata() {
- document.getElementById("title").innerHTML = pcbdata.metadata.title;
- document.getElementById("revision").innerHTML = "Rev: " + pcbdata.metadata.revision;
- document.getElementById("company").innerHTML = pcbdata.metadata.company;
- document.getElementById("filedate").innerHTML = pcbdata.metadata.date;
- if (pcbdata.metadata.title != "") {
- document.title = pcbdata.metadata.title + " BOM";
- }
- // Calculate board stats
- var fp_f = 0,
- fp_b = 0,
- pads_f = 0,
- pads_b = 0,
- pads_th = 0;
- for (var i = 0; i < pcbdata.footprints.length; i++) {
- if (pcbdata.bom.skipped.includes(i)) continue;
- var mod = pcbdata.footprints[i];
- if (mod.layer == "F") {
- fp_f++;
- } else {
- fp_b++;
- }
- for (var pad of mod.pads) {
- if (pad.type == "th") {
- pads_th++;
- } else {
- if (pad.layers.includes("F")) {
- pads_f++;
- }
- if (pad.layers.includes("B")) {
- pads_b++;
- }
- }
- }
- }
- document.getElementById("stats-components-front").innerHTML = fp_f;
- document.getElementById("stats-components-back").innerHTML = fp_b;
- document.getElementById("stats-components-total").innerHTML = fp_f + fp_b;
- document.getElementById("stats-groups-front").innerHTML = pcbdata.bom.F.length;
- document.getElementById("stats-groups-back").innerHTML = pcbdata.bom.B.length;
- document.getElementById("stats-groups-total").innerHTML = pcbdata.bom.both.length;
- document.getElementById("stats-smd-pads-front").innerHTML = pads_f;
- document.getElementById("stats-smd-pads-back").innerHTML = pads_b;
- document.getElementById("stats-smd-pads-total").innerHTML = pads_f + pads_b;
- document.getElementById("stats-th-pads").innerHTML = pads_th;
- // Update version string
- document.getElementById("github-link").innerHTML = "InteractiveHtmlBom " +
- /^v\d+\.\d+/.exec(pcbdata.ibom_version)[0];
- }
- function changeBomLayout(layout) {
- document.getElementById("bom-btn").classList.remove("depressed");
- document.getElementById("lr-btn").classList.remove("depressed");
- document.getElementById("tb-btn").classList.remove("depressed");
- switch (layout) {
- case 'bom-only':
- document.getElementById("bom-btn").classList.add("depressed");
- if (bomsplit) {
- bomsplit.destroy();
- bomsplit = null;
- canvassplit.destroy();
- canvassplit = null;
- }
- document.getElementById("frontcanvas").style.display = "none";
- document.getElementById("backcanvas").style.display = "none";
- document.getElementById("topmostdiv").style.height = "";
- document.getElementById("topmostdiv").style.display = "block";
- break;
- case 'top-bottom':
- document.getElementById("tb-btn").classList.add("depressed");
- document.getElementById("frontcanvas").style.display = "";
- document.getElementById("backcanvas").style.display = "";
- document.getElementById("topmostdiv").style.height = "100%";
- document.getElementById("topmostdiv").style.display = "flex";
- document.getElementById("bomdiv").classList.remove("split-horizontal");
- document.getElementById("canvasdiv").classList.remove("split-horizontal");
- document.getElementById("frontcanvas").classList.add("split-horizontal");
- document.getElementById("backcanvas").classList.add("split-horizontal");
- if (bomsplit) {
- bomsplit.destroy();
- bomsplit = null;
- canvassplit.destroy();
- canvassplit = null;
- }
- bomsplit = Split(['#bomdiv', '#canvasdiv'], {
- sizes: [50, 50],
- onDragEnd: resizeAll,
- direction: "vertical",
- gutterSize: 5
- });
- canvassplit = Split(['#frontcanvas', '#backcanvas'], {
- sizes: [50, 50],
- gutterSize: 5,
- onDragEnd: resizeAll
- });
- break;
- case 'left-right':
- document.getElementById("lr-btn").classList.add("depressed");
- document.getElementById("frontcanvas").style.display = "";
- document.getElementById("backcanvas").style.display = "";
- document.getElementById("topmostdiv").style.height = "100%";
- document.getElementById("topmostdiv").style.display = "flex";
- document.getElementById("bomdiv").classList.add("split-horizontal");
- document.getElementById("canvasdiv").classList.add("split-horizontal");
- document.getElementById("frontcanvas").classList.remove("split-horizontal");
- document.getElementById("backcanvas").classList.remove("split-horizontal");
- if (bomsplit) {
- bomsplit.destroy();
- bomsplit = null;
- canvassplit.destroy();
- canvassplit = null;
- }
- bomsplit = Split(['#bomdiv', '#canvasdiv'], {
- sizes: [50, 50],
- onDragEnd: resizeAll,
- gutterSize: 5
- });
- canvassplit = Split(['#frontcanvas', '#backcanvas'], {
- sizes: [50, 50],
- gutterSize: 5,
- direction: "vertical",
- onDragEnd: resizeAll
- });
- }
- settings.bomlayout = layout;
- writeStorage("bomlayout", layout);
- changeCanvasLayout(settings.canvaslayout);
- }
- function changeBomMode(mode) {
- document.getElementById("bom-grouped-btn").classList.remove("depressed");
- document.getElementById("bom-ungrouped-btn").classList.remove("depressed");
- document.getElementById("bom-netlist-btn").classList.remove("depressed");
- var chkbxs = document.getElementsByClassName("visibility_checkbox");
- switch (mode) {
- case 'grouped':
- document.getElementById("bom-grouped-btn").classList.add("depressed");
- for (var i = 0; i < chkbxs.length; i++) {
- chkbxs[i].disabled = false;
- }
- break;
- case 'ungrouped':
- document.getElementById("bom-ungrouped-btn").classList.add("depressed");
- for (var i = 0; i < chkbxs.length; i++) {
- chkbxs[i].disabled = false;
- }
- break;
- case 'netlist':
- document.getElementById("bom-netlist-btn").classList.add("depressed");
- for (var i = 0; i < chkbxs.length; i++) {
- chkbxs[i].disabled = true;
- }
- }
- writeStorage("bommode", mode);
- if (mode != settings.bommode) {
- settings.bommode = mode;
- bomSortFunction = null;
- currentSortColumn = null;
- currentSortOrder = null;
- clearHighlightedFootprints();
- }
- populateBomTable();
- }
- function focusFilterField() {
- focusInputField(document.getElementById("filter"));
- }
- function focusRefLookupField() {
- focusInputField(document.getElementById("reflookup"));
- }
- function toggleBomCheckbox(bomrowid, checkboxnum) {
- if (!bomrowid || checkboxnum > settings.checkboxes.length) {
- return;
- }
- var bomrow = document.getElementById(bomrowid);
- var checkbox = bomrow.childNodes[checkboxnum].childNodes[0];
- checkbox.checked = !checkbox.checked;
- checkbox.indeterminate = false;
- checkbox.onchange();
- }
- function checkBomCheckbox(bomrowid, checkboxname) {
- var checkboxnum = 0;
- while (checkboxnum < settings.checkboxes.length &&
- settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
- checkboxnum++;
- }
- if (!bomrowid || checkboxnum >= settings.checkboxes.length) {
- return;
- }
- var bomrow = document.getElementById(bomrowid);
- var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0];
- checkbox.checked = true;
- checkbox.indeterminate = false;
- checkbox.onchange();
- }
- function setBomCheckboxes(value) {
- writeStorage("bomCheckboxes", value);
- settings.checkboxes = value.split(",").map((e) => e.trim()).filter((e) => e);
- prepCheckboxes();
- populateMarkWhenCheckedOptions();
- setMarkWhenChecked(settings.markWhenChecked);
- }
- function setMarkWhenChecked(value) {
- writeStorage("markWhenChecked", value);
- settings.markWhenChecked = value;
- markedFootprints.clear();
- for (var ref of (value ? getStoredCheckboxRefs(value) : [])) {
- markedFootprints.add(ref);
- }
- populateBomTable();
- drawHighlights();
- }
- function prepCheckboxes() {
- var table = document.getElementById("checkbox-stats");
- while (table.childElementCount > 1) {
- table.removeChild(table.lastChild);
- }
- if (settings.checkboxes.length) {
- table.style.display = "";
- } else {
- table.style.display = "none";
- }
- for (var checkbox of settings.checkboxes) {
- var tr = document.createElement("TR");
- var td = document.createElement("TD");
- td.innerHTML = checkbox;
- tr.appendChild(td);
- td = document.createElement("TD");
- td.id = "checkbox-stats-" + checkbox;
- var progressbar = document.createElement("div");
- progressbar.classList.add("bar");
- td.appendChild(progressbar);
- var text = document.createElement("div");
- text.classList.add("text");
- td.appendChild(text);
- tr.appendChild(td);
- table.appendChild(tr);
- updateCheckboxStats(checkbox);
- }
- }
- function populateMarkWhenCheckedOptions() {
- var container = document.getElementById("markWhenCheckedContainer");
- if (settings.checkboxes.length == 0) {
- container.parentElement.style.display = "none";
- return;
- }
- container.innerHTML = '';
- container.parentElement.style.display = "inline-block";
- function createOption(name, displayName) {
- var id = "markWhenChecked-" + name;
- var div = document.createElement("div");
- div.classList.add("radio-container");
- var input = document.createElement("input");
- input.type = "radio";
- input.name = "markWhenChecked";
- input.value = name;
- input.id = id;
- input.onchange = () => setMarkWhenChecked(name);
- div.appendChild(input);
- // Preserve the selected element when the checkboxes change
- if (name == settings.markWhenChecked) {
- input.checked = true;
- }
- var label = document.createElement("label");
- label.innerHTML = displayName;
- label.htmlFor = id;
- div.appendChild(label);
- container.appendChild(div);
- }
- createOption("", "None");
- for (var checkbox of settings.checkboxes) {
- createOption(checkbox, checkbox);
- }
- }
- function updateCheckboxStats(checkbox) {
- var checked = getStoredCheckboxRefs(checkbox).size;
- var total = pcbdata.footprints.length - pcbdata.bom.skipped.length;
- var percent = checked * 100.0 / total;
- var td = document.getElementById("checkbox-stats-" + checkbox);
- td.firstChild.style.width = percent + "%";
- td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
- }
- function constrain(number, min, max) {
- return Math.min(Math.max(parseInt(number), min), max);
- }
- document.onkeydown = function (e) {
- switch (e.key) {
- case "n":
- if (document.activeElement.type == "text") {
- return;
- }
- if (currentHighlightedRowId !== null) {
- checkBomCheckbox(currentHighlightedRowId, "placed");
- highlightNextRow();
- e.preventDefault();
- }
- break;
- case "ArrowUp":
- highlightPreviousRow();
- e.preventDefault();
- break;
- case "ArrowDown":
- highlightNextRow();
- e.preventDefault();
- break;
- case "ArrowLeft":
- case "ArrowRight":
- if (document.activeElement.type != "text") {
- e.preventDefault();
- let boardRotationElement = document.getElementById("boardRotation")
- settings.boardRotation = parseInt(boardRotationElement.value); // degrees / 5
- if (e.key == "ArrowLeft") {
- settings.boardRotation += 3; // 15 degrees
- }
- else {
- settings.boardRotation -= 3;
- }
- settings.boardRotation = constrain(settings.boardRotation, boardRotationElement.min, boardRotationElement.max);
- boardRotationElement.value = settings.boardRotation
- setBoardRotation(settings.boardRotation);
- }
- break;
- default:
- break;
- }
- if (e.altKey) {
- switch (e.key) {
- case "f":
- focusFilterField();
- e.preventDefault();
- break;
- case "r":
- focusRefLookupField();
- e.preventDefault();
- break;
- case "z":
- changeBomLayout("bom-only");
- e.preventDefault();
- break;
- case "x":
- changeBomLayout("left-right");
- e.preventDefault();
- break;
- case "c":
- changeBomLayout("top-bottom");
- e.preventDefault();
- break;
- case "v":
- changeCanvasLayout("F");
- e.preventDefault();
- break;
- case "b":
- changeCanvasLayout("FB");
- e.preventDefault();
- break;
- case "n":
- changeCanvasLayout("B");
- e.preventDefault();
- break;
- default:
- break;
- }
- if (e.key >= '1' && e.key <= '9') {
- toggleBomCheckbox(currentHighlightedRowId, parseInt(e.key));
- e.preventDefault();
- }
- }
- }
- function hideNetlistButton() {
- document.getElementById("bom-ungrouped-btn").classList.remove("middle-button");
- document.getElementById("bom-ungrouped-btn").classList.add("right-most-button");
- document.getElementById("bom-netlist-btn").style.display = "none";
- }
- function topToggle() {
- var top = document.getElementById("top");
- var toptoggle = document.getElementById("toptoggle");
- if (top.style.display === "none") {
- top.style.display = "flex";
- toptoggle.classList.remove("flipped");
- } else {
- top.style.display = "none";
- toptoggle.classList.add("flipped");
- }
- }
- window.onload = function (e) {
- initUtils();
- initRender();
- initStorage();
- initDefaults();
- cleanGutters();
- populateMetadata();
- dbgdiv = document.getElementById("dbg");
- bom = document.getElementById("bombody");
- bomhead = document.getElementById("bomhead");
- filter = "";
- reflookup = "";
- if (!("nets" in pcbdata)) {
- hideNetlistButton();
- }
- initDone = true;
- setBomCheckboxes(document.getElementById("bomCheckboxes").value);
- // Triggers render
- changeBomLayout(settings.bomlayout);
- // Users may leave fullscreen without touching the checkbox. Uncheck.
- document.addEventListener('fullscreenchange', () => {
- if (!document.fullscreenElement)
- document.getElementById('fullscreenCheckbox').checked = false;
- });
- }
- window.onresize = resizeAll;
- window.matchMedia("print").addListener(resizeAll);
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- // EventHandler.registerCallback(IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT, () => {
- // for(var tr of bom.childNodes) {
- // tr.onclick = tr.onmousemove;
- // tr.onmousemove = null;
- // };
- // });
- ///////////////////////////////////////////////
- </script>
- </head>
- <body>
- <div id="topmostdiv" class="topmostdiv">
- <div id="top">
- <div id="fileinfodiv">
- <table class="fileinfo">
- <tbody>
- <tr>
- <td id="title" class="title" style="width: 70%">
- Title
- </td>
- <td id="revision" class="title" style="width: 30%">
- Revision
- </td>
- </tr>
- <tr>
- <td id="company">
- Company
- </td>
- <td id="filedate">
- Date
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="bomcontrols">
- <div class="hideonprint menu">
- <button class="menubtn"></button>
- <div class="menu-content">
- <label class="menu-label menu-label-top" style="width: calc(50% - 18px)">
- <input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)">
- Dark mode
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label menu-label-top" style="width: calc(50% - 17px); border-left: 0;">
- <input id="fullscreenCheckbox" type="checkbox" onchange="setFullscreen(this.checked)">
- Full Screen
- </label>
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
- Fab layer
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
- Silkscreen
- </label>
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
- References
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
- Values
- </label>
- <div id="tracksAndZonesCheckboxes">
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
- Tracks
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
- Zones
- </label>
- </div>
- <label class="menu-label" style="width: calc(50% - 18px)">
- <input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
- Pads
- </label><!-- This comment eats space! All of it!
- --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
- <input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
- DNP outlined
- </label>
- <label class="menu-label">
- <input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
- Continuous redraw on drag
- </label>
- <label class="menu-label">
- Highlight first pin
- <form id="highlightpin1">
- <div class="flexbox">
- <label>
- <input type="radio" name="highlightpin1" value="none" onchange="setHighlightPin1('none')">
- None
- </label>
- <label>
- <input type="radio" name="highlightpin1" value="all" onchange="setHighlightPin1('all')">
- All
- </label>
- <label>
- <input type="radio" name="highlightpin1" value="selected" onchange="setHighlightPin1('selected')">
- Selected
- </label>
- </div>
- </form>
- </label>
- <label class="menu-label">
- <span>Board rotation</span>
- <span style="float: right"><span id="rotationDegree">0</span>°</span>
- <input id="boardRotation" type="range" min="-36" max="36" value="0" class="slider" oninput="setBoardRotation(this.value)">
- </label>
- <label class="menu-label">
- <input id="offsetBackRotationCheckbox" type="checkbox" onchange="setOffsetBackRotation(this.checked)">
- Offset back rotation
- </label>
- <label class="menu-label">
- <div style="margin-left: 5px">Bom checkboxes</div>
- <input id="bomCheckboxes" class="menu-textbox" type=text
- oninput="setBomCheckboxes(this.value)">
- </label>
- <label class="menu-label">
- <div style="margin-left: 5px">Mark when checked</div>
- <div id="markWhenCheckedContainer"></div>
- </label>
- <label class="menu-label">
- <span class="shameless-plug">
- <span>Created using</span>
- <a id="github-link" target="blank" href="https://github.com/openscopeproject/InteractiveHtmlBom">InteractiveHtmlBom</a>
- <a target="blank" title="Mouse and keyboard help" href="https://github.com/openscopeproject/InteractiveHtmlBom/wiki/Usage#bom-page-mouse-actions" style="text-decoration: none;"><label class="help-link">?</label></a>
- </span>
- </label>
- </div>
- </div>
- <div class="button-container hideonprint">
- <button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')"
- title="Front only">F
- </button>
- <button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')"
- title="Front and Back">FB
- </button>
- <button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')"
- title="Back only">B
- </button>
- </div>
- <div class="button-container hideonprint">
- <button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')"
- title="BOM only"></button>
- <button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')"
- title="BOM left, drawings right"></button>
- <button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
- title="BOM top, drawings bot"></button>
- </div>
- <div class="button-container hideonprint">
- <button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')"
- title="Grouped BOM"></button>
- <button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')"
- title="Ungrouped BOM"></button>
- <button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')"
- title="Netlist"></button>
- </div>
- <div class="hideonprint menu">
- <button class="statsbtn"></button>
- <div class="menu-content">
- <table class="stats">
- <tbody>
- <tr>
- <td width="40%">Board stats</td>
- <td>Front</td>
- <td>Back</td>
- <td>Total</td>
- </tr>
- <tr>
- <td>Components</td>
- <td id="stats-components-front">~</td>
- <td id="stats-components-back">~</td>
- <td id="stats-components-total">~</td>
- </tr>
- <tr>
- <td>Groups</td>
- <td id="stats-groups-front">~</td>
- <td id="stats-groups-back">~</td>
- <td id="stats-groups-total">~</td>
- </tr>
- <tr>
- <td>SMD pads</td>
- <td id="stats-smd-pads-front">~</td>
- <td id="stats-smd-pads-back">~</td>
- <td id="stats-smd-pads-total">~</td>
- </tr>
- <tr>
- <td>TH pads</td>
- <td colspan=3 id="stats-th-pads">~</td>
- </tr>
- </tbody>
- </table>
- <table class="stats">
- <col width="40%"/><col />
- <tbody id="checkbox-stats">
- <tr>
- <td colspan=2 style="border-top: 0">Checkboxes</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="hideonprint menu">
- <button class="iobtn"></button>
- <div class="menu-content">
- <div class="menu-label menu-label-top">
- <div style="margin-left: 5px;">Save board image</div>
- <div class="flexbox">
- <input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width"
- style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
- <span>X</span>
- <input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height"
- style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
- </div>
- <label>
- <input id="render-save-transparent" type="checkbox">
- Transparent background
- </label>
- <div class="flexbox">
- <button class="savebtn" onclick="saveImage('F')">Front</button>
- <button class="savebtn" onclick="saveImage('B')">Back</button>
- </div>
- </div>
- <div class="menu-label">
- <span style="margin-left: 5px;">Config and checkbox state</span>
- <div class="flexbox">
- <button class="savebtn" onclick="saveSettings()">Export</button>
- <button class="savebtn" onclick="loadSettings()">Import</button>
- <button class="savebtn" onclick="resetSettings()">Reset</button>
- </div>
- </div>
- <div class="menu-label">
- <span style="margin-left: 5px;">Save bom table as</span>
- <div class="flexbox">
- <button class="savebtn" onclick="saveBomTable('csv')">csv</button>
- <button class="savebtn" onclick="saveBomTable('txt')">txt</button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div id="topdivider">
- <div class="hideonprint">
- <div id="toptoggle" onclick="topToggle()">︽</div>
- </div>
- </div>
- <div id="bot" class="split" style="flex: 1 1">
- <div id="bomdiv" class="split split-horizontal">
- <div style="width: 100%">
- <input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup"
- oninput="updateRefLookup(this.value)">
- <input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter"
- oninput="updateFilter(this.value)">
- <div class="button-container hideonprint" style="float: left; margin: 0;">
- <button id="copy" title="Copy bom table to clipboard"
- onclick="saveBomTable('clipboard')"></button>
- </div>
- </div>
- <div id="dbg"></div>
- <table class="bom" id="bomtable">
- <thead id="bomhead">
- </thead>
- <tbody id="bombody">
- </tbody>
- </table>
- </div>
- <div id="canvasdiv" class="split split-horizontal">
- <div id="frontcanvas" class="split" touch-action="none" style="overflow: hidden">
- <div style="position: relative; width: 100%; height: 100%;">
- <canvas id="F_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
- <canvas id="F_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
- <canvas id="F_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
- <canvas id="F_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
- </div>
- </div>
- <div id="backcanvas" class="split" touch-action="none" style="overflow: hidden">
- <div style="position: relative; width: 100%; height: 100%;">
- <canvas id="B_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
- <canvas id="B_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
- <canvas id="B_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
- <canvas id="B_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- </html>
|