£Á°èZ¨Ä…–K§‚«“ô4“ÒÙ´dîfUÙÃÅ WKbyʦ•ꎅȮFÒ¿ÊÎóCozá¬S@6{Í:›œêZÌ:Š•_%:¢¾¾~;‘Ã~芩ÊǍí`ÔÑ©ú뙵'5I¿fš×WO%ø9¾«¾DK|€ùÍD”Ýs]nHÕ¶êםӼ㞪éUWŸÈË%DÒÕ¬ï‘]/Åcx ‰ï2ß]ä6G[]S£Ôϯrs{úëóµmÒï#UQxo·õÞCe]"±/aÙ&Eã4ú9Jé_ÞåëdãöKë)AÞ ¯¹ægƒÛowЍø^d™ý½ßB7áyMä9ÜÖUã !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // All Coupler and Screw Images const couplerImages = { dcl: "./images/main/app/dcl.png", dcr: "./images/main/app/dcr.png", dtc: "./images/main/app/dtc.png", ecl: "./images/main/app/ecl.png", ecr: "./images/main/app/ecr.png", fl: "./images/main/app/fl.png", flh: "./images/main/app/flh.png", hdl: "./images/main/app/hdl.png", hdr: "./images/main/app/hdr.png", hrl: "./images/main/app/hrl.png", hrr: "./images/main/app/hrr.png", lrl: "./images/main/app/lrl.png", lrr: "./images/main/app/lrr.png", sr: "./images/main/app/sr.png", tc: "./images/main/app/tc.png", }; const screw = "./images/ic_screw.png"; const recSvg = "./images/recommended.svg"; const meaSvg = "./images/measure.svg"; // definded all the initial values let root = document.getElementById("root"); let spineCreator = document.getElementById("creator"); let spineAssembler = document.getElementById("assembler"); // mesurment variables let shortName = {}; let lMeasurement = []; let rMeasurement = []; let lMeasured = []; let rMeasured = []; let leftSet = []; let rightSet = []; let options = []; let recommended = []; let measured = []; let iWidth = {}; let screwPos = {}; let allRange = {}; let mainSets; let iHeight = 0; let canvasWidth = 750; // handler variables let chkLR; let close; let position = 0; let width, height; let side = "L"; let isFirstTime = true, dataSaved = false; let screwW, screwH; let mContext; let leftAdapter, rightAdapter; let commonData; let imageUrl = ""; let currentPage = 1; let loading = false; let state = { LEFT: [], RIGHT: [], isLeft: false, toggle: false, }; // handling evnets on load window.onload = () => { toastr.options = { closeButton: true, debug: false, newestOnTop: true, progressBar: false, positionClass: "toast-top-center", preventDuplicates: true, onclick: null, showDuration: "300", hideDuration: "1000", timeOut: "5000", extendedTimeOut: "1000", showEasing: "swing", hideEasing: "linear", showMethod: "fadeIn", hideMethod: "fadeOut", }; $(".main_input").keypress(function (eve) { if ( ((eve.which != 46 || $(this).val().indexOf(".") != -1) && (eve.which < 48 || eve.which > 57)) || (eve.which == 46 && $(this)?.caret && $(this)?.caret().start == 0) ) { eve.preventDefault(); } else if ($(this).val().length > 3) { eve.preventDefault(); } // this part is when left part of number is deleted and leaves a . in the leftmost position. For example, 33.25, then 33 is deleted $(".main_input").keyup(function (eve) { if ($(this).val().indexOf(".") == 0) { $(this).val($(this).val().substring(1)); } }); }); }; // loading the UI contentLoader(); // Layout Makers function Header() { const htmlString = `

Assemble

`; return htmlString; } function loadUI() { return `
`; } function noData() { return `

No Options Available

`; } function Assembler() { return `

${hasValues() && hasSets() ? loadUI() : noData()} ${ hasSets() && ` ` }
`; } function togglePlay(key) { let ele = document.getElementById(key + "_PLAY"); let values = Object.values(state[key]).reduce( (acc, cur) => (cur ? [...acc, cur] : acc), [] ); if (values.length > 0) { ele.style.display = "block"; } else { ele.style.display = "none"; } } function Creator() { return `

Construct Builder

`; } function Layout(Content) { const html = `
${state.toggle ? Header() : ""} ${Content()}
`; return html; } // Construct Builder function onCreate() { setDefaultVal(); getAssembleOptions(); if (hasSets()) { refreshUI(); genrateImage(); } else { refreshUI(); } } function getAssembleOptions() { const { LEFT, RIGHT } = state; let leftData = removeEmpty(LEFT, "LEFT"); let rightData = removeEmpty(RIGHT, "RIGHT"); if (!(leftData.length === 0)) { leftSet = getOptions(mainSets[leftData.length - 1], leftData, true); leftSet = sortEndCoupler(leftSet); console.log(leftSet, "LeftSet"); } if (!(rightData.length === 0)) { rightSet = getOptions(mainSets[rightData.length - 1], rightData, false); rightSet = sortEndCoupler(rightSet); console.log(rightSet, "RightSet"); } } function sortEndCoupler(data) { return (data || []).reduce((acc, cur) => { if (cur[0] === "ecl") { return [cur, ...acc] } else { return [...acc, cur] } }, []) } function getOptions(sets, measure, isLeft) { var temp = []; if (measure.length > 0) { for (var i = 0; i < sets.length; i++) { var set = sets[i]; var l = 0; for (var j = 0; j < set.length; j++) { var res = inRang(set[j], measure[l], isLeft); if (res >= 0) { if (res !== 2000 && l < measure.length) { l++; } } else { if (isLeft && lMeasurement.length !== lMeasured.length) { lMeasurement = []; } else if (!isLeft && rMeasurement.length !== rMeasured.length) { rMeasurement = []; } break; } if (j === set.length - 1 && l === measure.length) { temp.push(set); } else if (j === set.length - 1 || l === measure.length) { if ( l === measure.length && j + 1 === set.length - 1 && (set[j + 1].toLowerCase() === "tc" || set[j + 1].toLowerCase() === "ecl" || set[j + 1].toLowerCase() === "ecr") ) { temp.push(set); } else { if (isLeft && lMeasurement.length !== lMeasured.length) { lMeasurement = []; } else if (!isLeft && rMeasurement.length !== rMeasured.length) { rMeasurement = []; } } break; } } } } return temp; } function inRang(handle, measure, isLeft) { let temp = []; let returnVal = -2; if ( handle.toLowerCase() === "tc" || handle.toLowerCase() === "ecl" || handle.toLowerCase() === "ecr" ) { return 2000; } else if (handle.toLowerCase() === "fl") { temp = allRange.get("fl"); } else if (handle.toLowerCase() === "dcl" || handle.toLowerCase() === "dcr") { temp = allRange.get("dc"); } else if (handle.toLowerCase() === "lrl" || handle.toLowerCase() === "lrr") { temp = allRange.get("lr"); } else if (handle.toLowerCase() === "dtc") { temp = allRange.get("dtc"); } else if (handle.toLowerCase() === "hrl" || handle.toLowerCase() === "hrr") { temp = allRange.get("hr"); } else if (handle.toLowerCase() === "sr") { temp = allRange.get("sr"); } else if (handle.toLowerCase() === "flh") { temp = allRange.get("flh"); } else if (handle.toLowerCase() === "hdr" || handle.toLowerCase() === "hdl") { temp = allRange.get("hd"); } if (temp.length > 0) { for (let f of temp) { if (measure >= f[1] && measure < f[2]) { returnVal = 5; if (isLeft && lMeasurement.length !== lMeasured.length) { lMeasurement.push(f[0]); } else if (!isLeft && rMeasurement.length !== rMeasured.length) { rMeasurement.push(f[0]); } break; } } } return returnVal; } function genrateImage() { let ele = document.getElementById("image-Loader"); let images = []; let screws = []; let imagesLoaded = 0; let screwLoaded = 0; let screwAxis = []; let xAxis = 0; const canvas = document.getElementById("myCanvas"); const context = canvas.getContext("2d"); const measureValues = removeEmpty( state.isLeft ? state.LEFT : state.RIGHT , state.isLeft ? "LEFT" : "RIGHT"); const width = { 1: 250, 2: 250, 3: 350, 4: 450, 5: 550, 6: 650, 7: 750, 8: 850, 9: 950, 10: 950, 11: 950, 12: 950, 13: 950, 14: 950, 15: 950, }; let mainSet = state.isLeft ? [leftSet[currentPage - 1]] : [rightSet[currentPage - 1]]; canvas.width = width[mainSet[0].length]; ele.classList.add("is-active"); mainSet.forEach((item, temp) => { if (temp > 0) { return; } // Function to handle image loading function imageLoaded() { imagesLoaded++; // Check if all images have been loaded if (imagesLoaded === item.length) { images.forEach(({ image, coupler }, index) => { const scaledWidth = image.width * 0.2; const scaledHeight = image.height * iWidth.get(coupler)[0]; context.drawImage( image, xAxis, iWidth.get(coupler)[1], scaledWidth, scaledHeight ); let addWidth = printAt({ context, text: shortName.get(coupler)[1], x: xAxis, y: 40, lineHeight: 20, color: "white", }); for (let i = 0; i < screwPos?.get(coupler)?.length; i++) { screws.push( loadScrew( context, xAxis, coupler, i + 1, screwPos?.get(coupler)?.length, loadScrews ) ); } xAxis = updateXaxis( xAxis + (addWidth > 0 ? addWidth : 0), images?.[index + 1]?.coupler === "sr" || coupler === "sr", images?.[index + 1]?.coupler === "hrr" ); canvasWidth = xAxis; }); } } item.forEach((coupler) => { const image = new Image(); image.src = couplerImages[coupler]; image.addEventListener("load", imageLoaded); images.push({ image, coupler }); }); }); function updateXaxis(x, change, hrr) { if (change) { return x + 95; } else if (hrr) { return x + 110; } else { return x + 100; } } function loadScrews() { screwLoaded++; // Check if all images have been loaded if (screwLoaded === screws.length) { ele.classList.remove("is-active"); screws.forEach((image, index) => { context.drawImage(image, getDimension(image), 135, 35, 40); screwAxis.push({ x: getDimension(image), vertical: image.totalScrews === 2 && image.screwNo === 1, }); }); let sortedAxis = screwAxis.sort((a, b) => a.x - b.x); // let tempAxis = // i !== 0 // ? i === sortedAxis.length - 2 // ? screwAxis[sortedAxis.length - 1].x - 80 // : sc.x + 40 // : sc.x - 20; sortedAxis.forEach((sc, i) => { if (i + 1 !== sortedAxis.length && i + 1 !== 6) { printAt({ context, text: renderNum(measureValues[i]), x: sc.x, y: 20, lineHeight: 15, nextAxis: sortedAxis[i + 1].x, color: "yellow", }); if (sc.vertical) { // printVertical({ // context, // text: `${Number(measureValues[i]).toFixed()}mm`, // x: sc.x, // y: -135, // lineHeight: 15, // color: "#c718b6", // }); printAt({ context, text: `${Number(measureValues[i]).toFixed()}mm`, x: sc.x, y: 195, lineHeight: 15, nextAxis: sortedAxis[i + 1].x, color: "#c718b6", }); } else { printAt({ context, text: `${Number(measureValues[i]).toFixed()}mm`, x: sc.x, y: 195, lineHeight: 15, nextAxis: sortedAxis[i + 1].x, color: "#c718b6", }); } } }); } } } function loadScrew(context, xAxis, coupler, screwNo, totalScrews, loadScrews) { const image = new Image(); image.src = screw; image.xAxis = xAxis; image.coupler = coupler; image.screwNo = screwNo; image.totalScrews = totalScrews; image.addEventListener("load", loadScrews); return image; } // handlers function onPageChange(e) { const { id } = e; switch (id) { case "prevBtn": { currentPage = currentPage - 1; break; } default: { currentPage = currentPage + 1; break; } } contentLoader(); } function handleSwitch(selected) { state.isLeft = selected === "LEFT"; currentPage = 1; contentLoader(); } function makeOrdered(obj) { if (typeof obj !== "object" || obj === null) { throw new Error("Input must be a non-null object."); } let arr = []; Object.entries(obj).map((item) => { arr[item[0].replace("RIGHT", "").replace("LEFT", "")] = item[1]; }); return arr; } function hasNoBlankValuesInMiddle(obj, selected) { let order = makeOrdered(obj); let isBlank = false; order.forEach((cur, index) => { if ( cur && (order[index + 2] || order[index + 3] || order[index + 4]) && !order[index + 1] ) { isBlank = true; return; } }); let values = Object.values(obj).reduce( (acc, cur) => (cur && (+cur < 12 || +cur > 79) ? [...acc, cur] : acc), [] ); return { values, isBlank }; } function handlePlay(selected) { let nonSelected = selected === "LEFT" ? "RIGHT" : "LEFT"; let { values, isBlank } = hasNoBlankValuesInMiddle(state[selected], selected); if (values.length > 0) { toastr.info("Measurements must be greater than 11 and less than 80"); return; } else if (isBlank) { toastr.info("Blanks are not allowed between entries."); return; } let { values: v, isBlank: b } = hasNoBlankValuesInMiddle( state[nonSelected], nonSelected ); if (v.length > 0 && Object.values(state[nonSelected]).length) { toastr.info("Measurements must be greater than 11 and less than 80"); return; } else if (b && Object.values(state[nonSelected]).length) { toastr.info("Blanks are not allowed between entries."); return; } handleSwitch(selected); UIToggle(); onCreate(); contentLoader(); } function refreshUI() { let UI = Layout(state.toggle ? Assembler : Creator); root.innerHTML = UI; } function contentLoader() { refreshUI(); if (!state.toggle) { inputLoader("LEFT"); inputLoader("RIGHT"); togglePlay("LEFT"); togglePlay("RIGHT"); } else { Object.values(state[state.isLeft ? "LEFT" : "RIGHT"]).length && onCreate(); } } function UIToggle() { state.toggle = !state.toggle; !state.toggle && updateToDefault(); contentLoader(); } function inputLoader(key) { let i = 1; while (i < 6) { let input = document.getElementById(key + i); input.addEventListener("input", (e) => { handleChange(e, key); }); i++; } } function handleChange(e, key) { const { name, value } = e.target; state = { ...state, [name.slice(0, -1)]: { ...state[key], [name]: value }, }; togglePlay(key); } // util functions function getDimension(image) { const { coupler, xAxis, screwNo } = image; switch (screwNo) { case 2: { return xAxis + screwPos?.get(coupler)[1]; } default: { return xAxis + screwPos?.get(coupler)[0]; } } } function setDefaultVal() { allRange = new Map(); allRange.set("fl", [ [12, 11, 13], [14, 13, 15], [16, 15, 17], [18, 17, 19], [20, 19, 21], [22, 21, 23], [24, 23, 25], [26, 25, 27], [28, 27, 29], [30, 29, 31], [32, 31, 33], [34, 33, 35], [36, 35, 37.5], ]); allRange.set("dc", [ [12, 11, 13], [14, 13, 15], [16, 15, 17], ]); allRange.set("lr", [ [18, 17, 19], [20, 19, 20.5], [22, 20.5, 22.5], [24, 22.5, 24.5], [26, 24.5, 26.5], [28, 26.5, 28.5], [30, 28.5, 30.5], [32, 30.5, 32.5], [34, 32.5, 34.5], [36, 34.5, 36.5], ]); allRange.set("dtc", [ [12, 11, 13], [14, 13, 15], [16, 15, 17], ]); allRange.set("hr", [ [18, 17, 19], [20, 19, 20.5], [22, 20.5, 22.5], [24, 22.5, 24.5], ]); allRange.set("sr", [ [24, 24, 24.8], [26, 24.8, 27], [28, 27, 29], [30, 29, 31], [32, 31, 33], [34, 33, 35], [36, 35, 37], [38, 37, 39], [40, 39, 41], [42, 41, 43], [44, 43, 45], [46, 45, 47], [48, 47, 49], [50, 49, 51], [52, 51, 53], [54, 53, 55], [56, 55, 57], [58, 57, 59], [60, 59, 61], [62.5, 61, 63.5], [65, 63.5, 66], [67.5, 66, 68.5], [70, 68.5, 71], [72.5, 71, 73.5], [75, 73.5, 76], [77.5, 76, 78.5], [80, 78.5, 81], ]); allRange.set("flh", [ [12, 11, 13], [14, 13, 15], [16, 15, 17], ]); allRange.set("hd", [ [12, 11, 13], [14, 13, 15], [16, 15, 17], ]); mainSets = [ [ // two screw ["fl"], ["ecl", "sr", "ecr"], ], [ // three screw ["dcl", "lrr"], ["dcl", "sr", "ecr"], ["lrl", "dcr"], ["lrl", "tc", "lrr"], ["lrl", "tc", "sr", "ecr"], ["ecl", "sr", "dcr"], ["ecl", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "ecr"], ], [ // four screw ["dcl", "hrr", "lrr"], ["dcl", "hrr", "sr", "ecr"], ["dcl", "sr", "dcr"], ["dcl", "sr", "tc", "lrr"], ["dcl", "sr", "tc", "sr", "ecr"], ["lrl", "dtc", "lrr"], ["lrl", "dtc", "sr", "ecr"], ["lrl", "hrl", "dcr"], ["lrl", "hrl", "tc", "lrr"], ["lrl", "hrl", "tc", "sr", "ecr"], ["lrl", "tc", "hrr", "lrr"], ["lrl", "tc", "hrr", "sr", "ecr"], ["lrl", "tc", "sr", "dcr"], ["lrl", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "dtc", "lrr"], ["ecl", "sr", "dtc", "sr", "ecr"], ["ecl", "sr", "hrl", "dcr"], ["ecl", "sr", "hrl", "tc", "lrr"], ["ecl", "sr", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "lrr"], ["ecl", "sr", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "dcr"], ["ecl", "sr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "ecr"], ], [ // five screw ["dcl", "hrr", "hrr", "lrr"], ["dcl", "hrr", "hrr", "sr", "ecr"], ["dcl", "hrr", "sr", "dcr"], ["dcl", "hrr", "tc", "sr", "tc", "lrr"], ["dcl", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["dcl", "sr", "dtc", "lrr"], ["dcl", "sr", "dtc", "sr", "ecr"], ["dcl", "sr", "hrl", "dcr"], ["dcl", "sr", "hrl", "tc", "lrr"], ["dcl", "sr", "hrl", "tc", "sr", "ecr"], ["dcl", "sr", "tc", "hrr", "lrr"], ["dcl", "sr", "tc", "hrr", "sr", "ecr"], ["dcl", "sr", "tc", "sr", "dcr"], ["dcl", "sr", "tc", "sr", "tc", "lrr"], ["dcl", "sr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "dtc", "hrr", "lrr"], ["lrl", "dtc", "hrr", "sr", "ecr"], ["lrl", "dtc", "sr", "dcr"], ["lrl", "dtc", "tc", "sr", "tc", "lrr"], ["lrl", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "hrl", "dtc", "lrr"], ["lrl", "hrl", "dtc", "sr", "ecr"], ["lrl", "hrl", "hrl", "dcr"], ["lrl", "hrl", "hrl", "tc", "lrr"], ["lrl", "hrl", "hrl", "tc", "sr", "ecr"], ["lrl", "hrl", "tc", "hrr", "lrr"], ["lrl", "hrl", "tc", "hrr", "sr", "ecr"], ["lrl", "hrl", "tc", "sr", "dcr"], ["lrl", "hrl", "tc", "sr", "tc", "lrr"], ["lrl", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "hrr", "hrr", "lrr"], ["lrl", "tc", "hrr", "hrr", "sr", "ecr"], ["lrl", "tc", "hrr", "sr", "dcr"], ["lrl", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "dtc", "lrr"], ["lrl", "tc", "sr", "dtc", "sr", "ecr"], ["lrl", "tc", "sr", "hrl", "dcr"], ["lrl", "tc", "sr", "hrl", "tc", "lrr"], ["lrl", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "hrr", "lrr"], ["lrl", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "sr", "dcr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "dtc", "hrr", "lrr"], ["ecl", "sr", "dtc", "hrr", "sr", "ecr"], ["ecl", "sr", "dtc", "sr", "dcr"], ["ecl", "sr", "dtc", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "dtc", "lrr"], ["ecl", "sr", "hrl", "dtc", "sr", "ecr"], ["ecl", "sr", "hrl", "hrl", "dcr"], ["ecl", "sr", "hrl", "hrl", "tc", "lrr"], ["ecl", "sr", "hrl", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "hrr", "lrr"], ["ecl", "sr", "hrl", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "sr", "dcr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "hrr", "lrr"], ["ecl", "sr", "tc", "hrr", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "sr", "dcr"], ["ecl", "sr", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "dtc", "lrr"], ["ecl", "sr", "tc", "sr", "dtc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "hrl", "dcr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "dcr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ], [ // six screw ["dcl", "hrr", "hrr", "hrr", "lrr"], ["dcl", "hrr", "hrr", "hrr", "sr", "ecr"], ["dcl", "hrr", "hrr", "sr", "dcr"], ["dcl", "hrr", "hrr", "tc", "sr", "tc", "lrr"], ["dcl", "hrr", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["dcl", "hrr", "sr", "dtc", "lrr"], ["dcl", "hrr", "sr", "dtc", "sr", "ecr"], ["dcl", "hrr", "sr", "hrl", "dcr"], ["dcl", "hrr", "sr", "hrl", "tc", "lrr"], ["dcl", "hrr", "sr", "hrl", "tc", "sr", "ecr"], ["dcl", "hrr", "sr", "tc", "hrr", "lrr"], ["dcl", "hrr", "sr", "tc", "hrr", "sr", "ecr"], ["dcl", "hrr", "sr", "tc", "sr", "dcr"], ["dcl", "hrr", "sr", "tc", "sr", "tc", "lrr"], ["dcl", "hrr", "sr", "tc", "sr", "tc", "sr", "ecr"], ["dcl", "sr", "dtc", "hrr", "lrr"], ["dcl", "sr", "dtc", "hrr", "sr", "ecr"], ["dcl", "sr", "dtc", "sr", "dcr"], ["dcl", "sr", "dtc", "tc", "sr", "tc", "lrr"], ["dcl", "sr", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["dcl", "sr", "hrl", "dtc", "lrr"], ["dcl", "sr", "hrl", "dtc", "sr", "ecr"], ["dcl", "sr", "hrl", "hrl", "dcr"], ["dcl", "sr", "hrl", "hrl", "tc", "lrr"], ["dcl", "sr", "hrl", "hrl", "tc", "sr", "ecr"], ["dcl", "sr", "hrl", "tc", "hrr", "lrr"], ["dcl", "sr", "hrl", "tc", "hrr", "sr", "ecr"], ["dcl", "sr", "hrl", "tc", "sr", "dcr"], ["dcl", "sr", "hrl", "tc", "sr", "tc", "lrr"], ["dcl", "sr", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["dcl", "sr", "tc", "hrr", "hrr", "lrr"], ["dcl", "sr", "tc", "hrr", "hrr", "sr", "ecr"], ["dcl", "sr", "tc", "hrr", "sr", "dcr"], ["dcl", "sr", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["dcl", "sr", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["dcl", "sr", "tc", "sr", "dtc", "lrr"], ["dcl", "sr", "tc", "sr", "dtc", "sr", "ecr"], ["dcl", "sr", "tc", "sr", "hrl", "dcr"], ["dcl", "sr", "tc", "sr", "hrl", "tc", "lrr"], ["dcl", "sr", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["dcl", "sr", "tc", "sr", "tc", "hrr", "lrr"], ["dcl", "sr", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["dcl", "sr", "tc", "sr", "tc", "sr", "dcr"], ["dcl", "sr", "tc", "sr", "tc", "sr", "tc", "lrr"], ["dcl", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "dtc", "hrr", "hrr", "lrr"], ["lrl", "dtc", "hrr", "hrr", "sr", "ecr"], ["lrl", "dtc", "hrr", "sr", "dcr"], ["lrl", "dtc", "hrr", "tc", "sr", "tc", "lrr"], ["lrl", "dtc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "dtc", "sr", "dtc", "lrr"], ["lrl", "dtc", "sr", "dtc", "sr", "ecr"], ["lrl", "dtc", "sr", "hrl", "dcr"], ["lrl", "dtc", "sr", "hrl", "tc", "lrr"], ["lrl", "dtc", "sr", "hrl", "tc", "sr", "ecr"], ["lrl", "dtc", "sr", "tc", "hrr", "lrr"], ["lrl", "dtc", "sr", "tc", "hrr", "sr", "ecr"], ["lrl", "dtc", "sr", "tc", "sr", "dcr"], ["lrl", "dtc", "sr", "tc", "sr", "tc", "lrr"], ["lrl", "dtc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "hrl", "dtc", "hrr", "lrr"], ["lrl", "hrl", "dtc", "hrr", "sr", "ecr"], ["lrl", "hrl", "dtc", "sr", "dcr"], ["lrl", "hrl", "dtc", "tc", "sr", "tc", "lrr"], ["lrl", "hrl", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "hrl", "hrl", "dtc", "lrr"], ["lrl", "hrl", "hrl", "dtc", "sr", "ecr"], ["lrl", "hrl", "hrl", "hrl", "dcr"], ["lrl", "hrl", "hrl", "hrl", "tc", "lrr"], ["lrl", "hrl", "hrl", "hrl", "tc", "sr", "ecr"], ["lrl", "hrl", "hrl", "tc", "hrr", "lrr"], ["lrl", "hrl", "hrl", "tc", "hrr", "sr", "ecr"], ["lrl", "hrl", "hrl", "tc", "sr", "dcr"], ["lrl", "hrl", "hrl", "tc", "sr", "tc", "lrr"], ["lrl", "hrl", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "hrl", "tc", "hrr", "hrr", "lrr"], ["lrl", "hrl", "tc", "hrr", "hrr", "sr", "ecr"], ["lrl", "hrl", "tc", "hrr", "sr", "dcr"], ["lrl", "hrl", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["lrl", "hrl", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "hrl", "tc", "sr", "dtc", "lrr"], ["lrl", "hrl", "tc", "sr", "dtc", "sr", "ecr"], ["lrl", "hrl", "tc", "sr", "hrl", "dcr"], ["lrl", "hrl", "tc", "sr", "hrl", "tc", "lrr"], ["lrl", "hrl", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["lrl", "hrl", "tc", "sr", "tc", "hrr", "lrr"], ["lrl", "hrl", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["lrl", "hrl", "tc", "sr", "tc", "sr", "dcr"], ["lrl", "hrl", "tc", "sr", "tc", "sr", "tc", "lrr"], ["lrl", "hrl", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "hrr", "hrr", "hrr", "lrr"], ["lrl", "tc", "hrr", "hrr", "hrr", "sr", "ecr"], ["lrl", "tc", "hrr", "hrr", "sr", "dcr"], ["lrl", "tc", "hrr", "hrr", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "hrr", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "hrr", "sr", "dtc", "lrr"], ["lrl", "tc", "hrr", "sr", "dtc", "sr", "ecr"], ["lrl", "tc", "hrr", "sr", "hrl", "dcr"], ["lrl", "tc", "hrr", "sr", "hrl", "tc", "lrr"], ["lrl", "tc", "hrr", "sr", "hrl", "tc", "sr", "ecr"], ["lrl", "tc", "hrr", "sr", "tc", "hrr", "lrr"], ["lrl", "tc", "hrr", "sr", "tc", "hrr", "sr", "ecr"], ["lrl", "tc", "hrr", "sr", "tc", "sr", "dcr"], ["lrl", "tc", "hrr", "sr", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "hrr", "sr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "dtc", "hrr", "lrr"], ["lrl", "tc", "sr", "dtc", "hrr", "sr", "ecr"], ["lrl", "tc", "sr", "dtc", "sr", "dcr"], ["lrl", "tc", "sr", "dtc", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "sr", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "hrl", "dtc", "lrr"], ["lrl", "tc", "sr", "hrl", "dtc", "sr", "ecr"], ["lrl", "tc", "sr", "hrl", "hrl", "dcr"], ["lrl", "tc", "sr", "hrl", "hrl", "tc", "lrr"], ["lrl", "tc", "sr", "hrl", "hrl", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "hrl", "tc", "hrr", "lrr"], ["lrl", "tc", "sr", "hrl", "tc", "hrr", "sr", "ecr"], ["lrl", "tc", "sr", "hrl", "tc", "sr", "dcr"], ["lrl", "tc", "sr", "hrl", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "sr", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "hrr", "hrr", "lrr"], ["lrl", "tc", "sr", "tc", "hrr", "hrr", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "hrr", "sr", "dcr"], ["lrl", "tc", "sr", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "sr", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "sr", "dtc", "lrr"], ["lrl", "tc", "sr", "tc", "sr", "dtc", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "sr", "hrl", "dcr"], ["lrl", "tc", "sr", "tc", "sr", "hrl", "tc", "lrr"], ["lrl", "tc", "sr", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "hrr", "lrr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "sr", "dcr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "sr", "tc", "lrr"], ["lrl", "tc", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "dtc", "hrr", "hrr", "lrr"], ["ecl", "sr", "dtc", "hrr", "hrr", "sr", "ecr"], ["ecl", "sr", "dtc", "hrr", "sr", "dcr"], ["ecl", "sr", "dtc", "hrr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "dtc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "dtc", "sr", "dtc", "lrr"], ["ecl", "sr", "dtc", "sr", "dtc", "sr", "ecr"], ["ecl", "sr", "dtc", "sr", "hrl", "dcr"], ["ecl", "sr", "dtc", "sr", "hrl", "tc", "lrr"], ["ecl", "sr", "dtc", "sr", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "dtc", "sr", "tc", "hrr", "lrr"], ["ecl", "sr", "dtc", "sr", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "dtc", "sr", "tc", "sr", "dcr"], ["ecl", "sr", "dtc", "sr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "dtc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "dtc", "hrr", "lrr"], ["ecl", "sr", "hrl", "dtc", "hrr", "sr", "ecr"], ["ecl", "sr", "hrl", "dtc", "sr", "dcr"], ["ecl", "sr", "hrl", "dtc", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "hrl", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "hrl", "dtc", "lrr"], ["ecl", "sr", "hrl", "hrl", "dtc", "sr", "ecr"], ["ecl", "sr", "hrl", "hrl", "hrl", "dcr"], ["ecl", "sr", "hrl", "hrl", "hrl", "tc", "lrr"], ["ecl", "sr", "hrl", "hrl", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "hrl", "tc", "hrr", "lrr"], ["ecl", "sr", "hrl", "hrl", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "hrl", "hrl", "tc", "sr", "dcr"], ["ecl", "sr", "hrl", "hrl", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "hrl", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "hrr", "hrr", "lrr"], ["ecl", "sr", "hrl", "tc", "hrr", "hrr", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "hrr", "sr", "dcr"], ["ecl", "sr", "hrl", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "hrl", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "sr", "dtc", "lrr"], ["ecl", "sr", "hrl", "tc", "sr", "dtc", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "sr", "hrl", "dcr"], ["ecl", "sr", "hrl", "tc", "sr", "hrl", "tc", "lrr"], ["ecl", "sr", "hrl", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "hrr", "lrr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "sr", "dcr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "hrl", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "hrr", "hrr", "lrr"], ["ecl", "sr", "tc", "hrr", "hrr", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "hrr", "sr", "dcr"], ["ecl", "sr", "tc", "hrr", "hrr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "hrr", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "sr", "dtc", "lrr"], ["ecl", "sr", "tc", "hrr", "sr", "dtc", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "sr", "hrl", "dcr"], ["ecl", "sr", "tc", "hrr", "sr", "hrl", "tc", "lrr"], ["ecl", "sr", "tc", "hrr", "sr", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "sr", "tc", "hrr", "lrr"], ["ecl", "sr", "tc", "hrr", "sr", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "hrr", "sr", "tc", "sr", "dcr"], ["ecl", "sr", "tc", "hrr", "sr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "hrr", "sr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "dtc", "hrr", "lrr"], ["ecl", "sr", "tc", "sr", "dtc", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "dtc", "sr", "dcr"], ["ecl", "sr", "tc", "sr", "dtc", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "dtc", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "hrl", "dtc", "lrr"], ["ecl", "sr", "tc", "sr", "hrl", "dtc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "hrl", "hrl", "dcr"], ["ecl", "sr", "tc", "sr", "hrl", "hrl", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "hrl", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "hrr", "lrr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "sr", "dcr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "hrl", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "hrr", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "sr", "dcr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "hrr", "tc", "sr", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "dtc", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "dtc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "hrl", "dcr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "hrl", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "hrl", "tc", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "hrr", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "hrr", "sr", "ecr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "dcr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "tc", "lrr"], ["ecl", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "tc", "sr", "ecr"], ], ]; iWidth = new Map(); iWidth.set("fl", [0.2, 85]); iWidth.set("tc", [0.2, 85]); iWidth.set("ecl", [0.2, 85]); iWidth.set("ecr", [0.2, 85]); iWidth.set("dcl", [0.2, 85]); iWidth.set("dcr", [0.2, 85]); iWidth.set("lrl", [0.2, 85]); iWidth.set("lrr", [0.2, 85]); iWidth.set("dtc", [0.2, 85]); iWidth.set("hrl", [0.2, 85]); iWidth.set("hrr", [0.2, 85]); iWidth.set("sr", [0.3, 75]); iWidth.set("flh", [0.2, 85]); iWidth.set("hdr", [0.2, 85]); iWidth.set("hdl", [0.2, 85]); screwPos = new Map(); screwPos.set("fl", [10, 90]); screwPos.set("tc", [50]); screwPos.set("ecr", [60]); screwPos.set("ecl", [40]); screwPos.set("dcr", [40, 85]); screwPos.set("dcl", [20, 60]); screwPos.set("lrl", [40]); screwPos.set("lrr", [60]); screwPos.set("dtc", [30, 70]); screwPos.set("hrr", [50]); screwPos.set("hrl", [50]); screwPos.set("flh", [15, 85]); screwPos.set("hdl", [15, 60]); screwPos.set("hdr", [40, 85]); shortName = new Map(); shortName.set("fl", ["fixed_length", "Fixed\n Length\n Coupler"]); shortName.set("tc", ["t_coupler", "T-Coupler"]); shortName.set("ecr", ["end_coupler", "End-\nCoupler"]); shortName.set("ecl", ["end_coupler_flipped", "End-\nCoupler"]); shortName.set("dcr", ["double_coupler", "Double\n Coupler"]); shortName.set("dcl", ["double_coupler_flipped", "Double\n Coupler"]); shortName.set("lrl", ["l_coupler", "L-Coupler"]); shortName.set("lrr", ["l_coupler_flipped", "L-Coupler"]); shortName.set("dtc", ["double_t_coupler", "Double\n T-Coupler"]); shortName.set("hrr", ["hybrid_rod", "Hybrid\n Coupler"]); shortName.set("hrl", ["hybrid_rod_flipped", "Hybrid\n Coupler"]); shortName.set("sr", ["telescoping_rod", "Rod"]); shortName.set("flh", [ "fixed_length_hyperlordotic", "Fixed\n Length\n (Hyperlordotic)", ]); shortName.set("hdl", [ "double_coupler_hyperlordotic_flipped", "Double\n Coupler\n (Hyperlordotic)", ]); shortName.set("hdr", [ "double_coupler_hyperlordotic", "Double\n Coupler\n (Hyperlordotic)", ]); } function updateToDefault() { shortName = {}; lMeasurement = []; rMeasurement = []; lMeasured = []; rMeasured = []; leftSet = []; rightSet = []; options = []; recommended = []; measured = []; iWidth = {}; screwPos = {}; allRange = {}; mainSets; iHeight = 0; chkLR; close; position = 0; width, height; side = "L"; (isFirstTime = true), (dataSaved = false); screwW, screwH; mContext; leftAdapter, rightAdapter; commonData; imageUrl = ""; currentPage = 1; state = { LEFT: state.LEFT, RIGHT: state.RIGHT, isLeft: false, toggle: false, }; } function hasValues() { return removeEmpty(state[state.isLeft ? "LEFT" : "RIGHT"], state.isLeft ? "LEFT" : "RIGHT").length; } function hasSets() { return state.isLeft ? leftSet.length : rightSet.length; } function printAt({ context, text, x, y, lineHeight, nextAxis, color }) { context.font = "bold 16px arial"; context.textAlign = "center"; context.fillStyle = color; let midPoint = (x + nextAxis) / 2; var lines = text.split("\n"); for (var i = 0; i < lines.length; i++) { if (midPoint) { context.fillText(lines[i], midPoint + 10, y + i * lineHeight); } else { context.fillText(lines[i], x + 60, y + i * lineHeight); } } return getTextEndAxis(context, lines); } function getTextEndAxis(context, lines) { return ( lines.reduce((acc, cur, i) => { let a = context.measureText(cur); return a.width > 100 && a.width > acc ? a.width : acc; }, 0) - 100 ); } function printVertical({ context, text, x, y, lineHeight, color }) { context.font = "bold 16px arial"; context.textAlign = "center"; context.fillStyle = color; var lines = text.split("\n"); context.save(); // Save the current canvas state context.translate(50, 50); // Translate to the desired position context.rotate(-Math.PI / 2); // Rotate the canvas 90 degrees counter-clockwise for (var i = 0; i < lines.length; i++) { context.fillText(lines[i], y, x + i * lineHeight - 15); } context.restore(); // Restore the canvas state } function renderNum(num) { let updatedNum = Math.floor(+num); if (updatedNum % 2 === 0) { return `${updatedNum.toFixed()}mm`; } else { return `${(updatedNum + 1).toFixed()}mm`; } } // function removeEmpty(arr) { // return arr.reduce((acc, cur) => (cur ? [...acc, cur] : [...acc]), []); // } function removeEmpty(obj, key) { if (typeof obj !== "object" || obj === null) { throw new Error("Input must be a non-null object."); } let arr = []; arr[0] = obj?.[`${key}1`]; arr[1] = obj?.[`${key}2`]; arr[2] = obj?.[`${key}3`]; arr[3] = obj?.[`${key}4`]; arr[4] = obj?.[`${key}5`]; const values = arr.filter( (value) => value !== null && value !== undefined && value !== "" ); return values; } function validateNumber(number) { const numberRegex = /^(?:[1-7]?[0-9]|80)$/; return numberRegex.test(number); }