| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570 | htmlElemAttr.forEach((prop) => {    $('#set-icube-' + prop).on("click", function () {        clickOn(prop, this);    });});/** * * @param { PropertyKey } prop */function finishToSet(prop) {    if ($('#set-icube-' + prop).hasClass("active-icube-setting")) {        if (selectedIcube)            selectedIcube.finishToSetProperty(prop);        if (prop === 'connection') {            updateConnectorsPrice();        }    }    g_sceneMode = sceneMode.normal;}/** * * @param { PropertyKey } prop * @param { htmlDomElement } htmlElem */function clickOn(prop, htmlElem) {    updateDrawButtonState();    if (['passthrough', 'charger'].includes(prop)) {        if (currentView !== ViewType.free)            switch_to_free_camera();        else            switchCamera(ViewType.free);        scene.activeCamera.alpha = g_rackingOrientation === OrientationRacking.horizontal ? Math.PI / 4 : 3 * Math.PI / 4;        scene.activeCamera.beta = 1;    } else {        if (currentView !== ViewType.top)            switch_to_top_camera();    }    if ($(htmlElem).hasClass("active-icube-setting")) {        finishToSet(prop);    } else {        if (prop === 'connection') {            // check if exist icube to connect            const validIcube = getValidIcubeToConect();            if (validIcube.length === 0) {                Utils.logg('无法连接SIMANC!', '错误');                return;            }        }        htmlElemAttr.forEach((localProp) => {            if (localProp !== prop)                finishToSet(localProp);        });        if (selectedIcube)            selectedIcube.previewProperty(prop);        tracking(65 + parseInt(htmlElemAttr.indexOf(prop)));    }    renderScene(1000);}//Control tab$('.a-tabs').on("click", function () {    updateDrawButtonState();    htmlElemAttr.forEach((prop) => {        finishToSet(prop);    });    clearSceneItemManual();    endSimulation();    unsetCurrentMesh();    const pane_id = $(this).attr("aria-controls");    tracking(56 + parseInt(menuTab.indexOf(pane_id.split('-')[3])));    if (pane_id === "#main-tabs-pane-Price") {        updateConnectorsPrice();        if (userRole === g_UserRole.Sales) {            if (g_priceChanged !== g_priceUpdated) {                $('#waiting').show();            }        }    }    if (pane_id === "#main-tabs-pane-Export") {        icubes.forEach((icube) => {            icube.software.update();        });    }    if (pane_id === "#main-tabs-pane-Simulation") {        if (selectedIcube) {            const samePos = selectedIcube.activedIOPorts.filter(e => e.portPosition === (selectedIcube.isHorizontal ? "bottom" : "left"));            if (samePos.length === selectedIcube.activedIOPorts.length)                $('select[name="simLiftA"]').val(1);            else                $('select[name="simLiftA"]').val(0);        }    }    if (pane_id === "#main-tabs-pane-Contact") {        $('#con_fullName').val(userName);        $('#con_email').val(userEmail);    }    $('.a-tabs').parent().removeClass("active");    $('.a-tabs').attr("aria-selected", false).attr("tabindex", -1);    if ($(pane_id).hasClass('show')) {        $('.tab-pane').removeClass("show");        $(pane_id).parent().addClass("hide");    } else {        $(this).parent().addClass("active");        $(this).attr("aria-selected", true).removeAttr("tabindex");        $('.tab-pane').removeClass("show");        $(pane_id).parent().removeClass("hide");        $(pane_id).addClass("show");    }    resizeRenderer();})//Control warehouse size$('.input-spinner').on("change", function (event) {    if (!menuEnabled) return;    let newVal = parseFloat(event.target.value);    const controller = $(this).parent().attr('controller');    switch (controller) {        case 'width':            if (!isNaN(parseFloat(newVal))) {                newVal = useP(newVal) / useP(rateUnit);                if (newVal < g_WarehouseMinWidth) {                    newVal = g_WarehouseMinWidth;                } else if (newVal > g_WarehouseMaxWidth) {                    newVal = g_WarehouseMaxWidth;                }            } else {                newVal = WHDimensions[0];            }            WHDimensions[0] = _round(newVal, 2);            warehouse.update(WHDimensions);            if (selectedIcube)                selectedIcube.addRowLabels();            tracking(55);            Behavior.add(Behavior.type.WHDimensions);            break;        case 'length':            if (!isNaN(parseFloat(newVal))) {                newVal = useP(newVal) / useP(rateUnit);                if (newVal < g_WarehouseMinLength) {                    newVal = g_WarehouseMinLength;                }                if (newVal > g_WarehouseMaxLength) {                    newVal = g_WarehouseMaxLength;                }            } else {                newVal = WHDimensions[1];            }            WHDimensions[1] = _round(newVal, 2);            warehouse.update(WHDimensions);            if (selectedIcube)                selectedIcube.addRowLabels();            tracking(54);            Behavior.add(Behavior.type.WHDimensions);            break;        case 'height':            if (!isNaN(parseFloat(newVal))) {                newVal = useP(newVal) / useP(rateUnit);                if (newVal < g_WarehouseMinHeight) {                    newVal = g_WarehouseMinHeight;                }                if (newVal > g_WarehouseMaxHeight) {                    newVal = g_WarehouseMaxHeight;                }            } else {                newVal = WHDimensions[2];            }            WHDimensions[2] = _round(newVal, 2);            warehouse.update(WHDimensions);            //Set ui            updateRackingHighLevel();            updateSelectedIcube();            tracking(53);            Behavior.add(Behavior.type.WHDimensions);            break;        case 'pallet-height':            if (!isNaN(parseFloat(newVal))) {                newVal = useP(newVal) / useP(rateUnit);                if (newVal < g_PalletMinHeight) {                    newVal = g_PalletMinHeight;                }                if (newVal > g_PalletMaxHeight) {                    newVal = g_PalletMaxHeight;                }            } else {                newVal = g_palletHeight;            }            g_palletHeight = useP(useP(newVal), false);            tracking(52);            //Set racking height            updateRackingHighLevel();            if (g_palletHeight > 0 && g_palletHeight <= 1.2) {                simulateEvent('palletOverhang', 'change', 0.05);            } else if (g_palletHeight > 1.2 && g_palletHeight <= 1.8) {                simulateEvent('palletOverhang', 'change', 0.075);            } else {                simulateEvent('palletOverhang', 'change', 0.100);            }            // Behavior.add(Behavior.type.palletHeight);            break;        case 'pallet-weight':            if (isNaN(parseFloat(newVal))) {                newVal = g_palletHeight;            }            g_palletWeight = useP(useP(newVal), false);            if (selectedIcube) selectedIcube.palletWeight = g_palletWeight;            tracking(51);            Behavior.add(Behavior.type.palletWeight);            break;        case 'layoutScale':            if (newVal > 0 && newVal < 200) {                layoutMap.scale = parseFloat((2 - parseFloat(newVal / 100)).toFixed(2));                warehouse.update(WHDimensions);            }            break;        default:            break;    }    setUnitForInput();})$('.spinner-up').on("click", function () {    if (!menuEnabled) return;    const controller = $(this).parent().parent().attr('controller');    switch (controller) {        case 'width':            if (WHDimensions[0] < g_WarehouseMaxWidth) {                WHDimensions[0] += g_WarehouseIncValue;                warehouse.update(WHDimensions);                if (selectedIcube)                    selectedIcube.addRowLabels();                tracking(55);                Behavior.add(Behavior.type.WHDimensions);            }            break;        case 'length':            if (WHDimensions[1] < g_WarehouseMaxLength) {                WHDimensions[1] += g_WarehouseIncValue;                warehouse.update(WHDimensions);                if (selectedIcube)                    selectedIcube.addRowLabels();                tracking(54);                Behavior.add(Behavior.type.WHDimensions);            }            break;        case 'height':            if (WHDimensions[2] < g_WarehouseMaxHeight) {                WHDimensions[2] += g_WarehouseIncValue;                warehouse.update(WHDimensions);                updateRackingHighLevel();                updateSelectedIcube();                tracking(53);                Behavior.add(Behavior.type.WHDimensions);            }            break;        case 'pallet-height':            if (g_palletHeight < g_PalletMaxHeight) {                g_palletHeight += g_PalletIncValue;                tracking(52);                updateRackingHighLevel();                if (g_palletHeight > 0 && g_palletHeight <= 1.2) {                    simulateEvent('palletOverhang', 'change', 0.05);                } else if (g_palletHeight > 1.2 && g_palletHeight <= 1.8) {                    simulateEvent('palletOverhang', 'change', 0.075);                } else {                    simulateEvent('palletOverhang', 'change', 0.100);                }                // Behavior.add(Behavior.type.palletHeight);            }            break;        case 'pallet-weight':            if (g_palletWeight < g_PalletMaxWeight) {                g_palletWeight = parseFloat($('#input-pallet-weight').val()) + 100;                $('#input-pallet-weight').val(g_palletWeight);                if (selectedIcube) selectedIcube.palletWeight = g_palletWeight;                tracking(51);                Behavior.add(Behavior.type.palletWeight);            }            break;        case 'layoutScale':            if (layoutMap && layoutMap.scale > 0) {                let newVal = parseFloat($('#layoutScale').val());                newVal += 0.1;                $('#layoutScale').val(parseFloat(newVal.toFixed(2)));                layoutMap.scale = 2 - parseFloat(newVal / 100);                warehouse.update(WHDimensions);            }            break;        default:            break;    }    setUnitForInput();});$('.spinner-down').on("click", function () {    if (!menuEnabled) return;    const controller = $(this).parent().parent().attr('controller');    switch (controller) {        case 'width':            if (WHDimensions[0] > g_WarehouseMinWidth) {                WHDimensions[0] -= g_WarehouseIncValue;                $('#input-wh-width').val(WHDimensions[0]);                warehouse.update(WHDimensions);                if (selectedIcube)                    selectedIcube.addRowLabels();                tracking(55);                Behavior.add(Behavior.type.WHDimensions);            }            break;        case 'length':            if (WHDimensions[1] > g_WarehouseMinLength) {                WHDimensions[1] -= g_WarehouseIncValue;                $('#input-wh-length').val(WHDimensions[1]);                warehouse.update(WHDimensions);                if (selectedIcube)                    selectedIcube.addRowLabels();                tracking(54);                Behavior.add(Behavior.type.WHDimensions);            }            break;        case 'height':            if (WHDimensions[2] > g_WarehouseMinHeight) {                WHDimensions[2] -= g_WarehouseIncValue;                $('#input-wh-height').val(WHDimensions[2]);                warehouse.update(WHDimensions);                updateRackingHighLevel();                updateSelectedIcube();                tracking(53);                Behavior.add(Behavior.type.WHDimensions);            }            break;        case 'pallet-height':            if (g_palletHeight > g_PalletMinHeight) {                g_palletHeight -= g_PalletIncValue;                tracking(52);                updateRackingHighLevel();                if (g_palletHeight > 0 && g_palletHeight <= 1.2) {                    simulateEvent('palletOverhang', 'change', 0.05);                } else if (g_palletHeight > 1.2 && g_palletHeight <= 1.8) {                    simulateEvent('palletOverhang', 'change', 0.075);                } else {                    simulateEvent('palletOverhang', 'change', 0.100);                }                // Behavior.add(Behavior.type.palletHeight);            }            break;        case 'pallet-weight':            if (g_palletWeight > g_PalletMinWeight) {                g_palletWeight = parseFloat($('#input-pallet-weight').val()) - 100;                $('#input-pallet-weight').val(g_palletWeight);                if (selectedIcube) selectedIcube.palletWeight = g_palletWeight;                tracking(51);                Behavior.add(Behavior.type.palletWeight);            }            break;        case 'layoutScale':            if (layoutMap && layoutMap.scale < 2) {                let newVal = parseFloat($('#layoutScale').val());                newVal -= 0.1;                $('#layoutScale').val(parseFloat(newVal.toFixed(2)));                layoutMap.scale = 2 - parseFloat(newVal / 100);                warehouse.update(WHDimensions);            }            break;        default:            break;    }    setUnitForInput();});$('#draw-baseline').on("click", function () {    g_drawMode = 0;    if ($(this).hasClass("active-icube-setting")) {        updateDrawButtonState();    } else {        $('#draw-baseline').addClass('active-icube-setting');        $('#draw-baseline').text('确认图纸');        if (currentView !== ViewType.top)            switch_to_top_camera();        tracking(30);        g_sceneMode = sceneMode.draw;    }});$('#draw-auto').on("click", function () {    g_drawMode = 1;    updateDrawButtonState();    const manualsItems = getManualItems();    if (icubes.length > 0 || manualsItems.length > 0) {        Utils.logg('在绘制货架之前清除场景!', '提示');        return;    }    tracking(31);    recreateAutoIcube();});$('#remove-all-icubes').on("click", function () {    updateDrawButtonState();    removeAllIcubes();    Behavior.add(Behavior.type.removeIcube);    renderScene();});$('#remove-all-items').on("click", function () {    if (confirm('这将从工作区中删除所有项目。你确定吗??')) {        updateDrawButtonState();        removeManualItems();        Behavior.add(Behavior.type.deleteItem);        renderScene();    }});$('#input-upRightDistance').on("change", function (event) {    tracking(50);    let newVal = parseFloat(event.target.value);    newVal = useP(newVal) / useP(rateUnit);    if (newVal < g_MinDistUpRights * 0.6) {        newVal = g_MinDistUpRights * 0.6;    }    if (newVal > g_MaxDistUpRights) {        newVal = g_MaxDistUpRights;    }    g_distUpRight = useP(useP(newVal), false);    //Set racking height    updateRackingHighLevel();    updateSelectedIcube();    Behavior.add(Behavior.type.upRightDistance);});$('#palletDistr_0, #palletDistr_1, #palletDistr_2').on("change", function (event) {    tracking(41);    const attr = $(this).attr('id').split('_');    updateDistrPallet(attr[1], parseInt(event.target.value));});function updateDistrPallet(id, val) {    const prevMax = g_palletInfo.max;    const prevVal = [...g_palletInfo.value];    g_palletInfo.value[id] = val;    g_palletInfo.type = optimizeDistrCalculation(id, g_palletInfo.value);    updatePalletDistributions(g_palletInfo.value);    g_xtrackFixedDim = (g_palletInfo.max !== 2 ? 1.350 : 1.550);    if (g_palletInfo.max !== prevMax || (prevVal[0] == 0 && g_palletInfo.value[0] != 0) || (prevVal[1] == 0 && g_palletInfo.value[1] != 0) ||        (prevVal[2] == 0 && g_palletInfo.value[2] != 0) || (prevVal[0] != 0 && g_palletInfo.value[0] == 0) || (prevVal[1] != 0 && g_palletInfo.value[1] == 0) || (prevVal[2] != 0 && g_palletInfo.value[2] == 0)) {        if (selectedIcube && g_palletInfo.max !== prevMax)            selectedIcube.activedPillers = [];        updateSelectedIcube();    } else {        palletsNoJS();    }    Behavior.add(Behavior.type.palletType);    renderScene();}$('#rackingHighLevel').on("change", function (event) {    g_rackingHighLevel = parseInt(event.target.value);    updateRackingHighLevel();    updateSelectedIcube();    tracking(49);    Behavior.add(Behavior.type.rackingLevel);});$('#palletOverhang').on("change", function (event) {    g_palletOverhang = parseFloat(event.target.value);    updateSelectedIcube();    tracking(48);    Behavior.add(Behavior.type.palletOverhang);});$('#loadPalletOverhang').on("change", function (event) {    g_loadPalletOverhang = parseFloat(event.target.value);    g_palletInfo.type = g_palletInfo.value;    updateSelectedIcube();    tracking(47);    Behavior.add(Behavior.type.palletOverhang);});$('#orientationRacking').on("change", function (event) {    g_rackingOrientation = parseInt(event.target.value);    if (selectedIcube !== null) {        if (g_drawMode === 1) {            recreateAutoIcube();        } else {            selectedIcube.resetIcubeData();            updateSelectedIcube();        }    }    tracking(46);    Behavior.add(Behavior.type.rackingOrient);});function recreateAutoIcube() {    if (currentView !== ViewType.free)        switch_to_free_camera();    else        switchCamera(ViewType.free);    removeAllIcubes();    autoDrawIcube();}$('#numberOfSKU').on("change", function (event) {    g_SKU = parseInt(event.target.value);    const prevXtracksLnegth = g_recomandedXtrackAmount;    if (selectedIcube !== null) {        calculateProps(selectedIcube.baseLines);        if (prevXtracksLnegth !== g_recomandedXtrackAmount) {            selectedIcube.resetIcubeData();            updateSelectedIcube();        }    }    tracking(45);    Behavior.add(Behavior.type.sku);});$('#numberOfPalletInOutPerHour').on("change", function (event) {    g_movesPerHour = parseInt(event.target.value);    if (selectedIcube !== null) {        selectedIcube.updateThroughput(g_movesPerHour);        selectedIcube.getEstimationPrice();    }    tracking(44);    Behavior.add(Behavior.type.throughput);    renderScene();});$('#extracarrierAmount').on("change", function (event) {    if (selectedIcube) {        g_extraCarrierAmount = parseInt(event.target.value) < 0 ? 0 : parseInt(event.target.value);        selectedIcube.updateCarrier(g_extraCarrierAmount);        selectedIcube.getEstimationPrice();        Behavior.add(Behavior.type.addCharger);        renderScene();    }});function updateCarrierAmount(amount, extra) {    if (selectedIcube !== null) {        g_recomandedCarrierAmount = parseInt(amount);        $('#carrierAmount').html(g_recomandedCarrierAmount);        $('#extracarrierAmount').val(parseInt(extra));    }}function updateLiftAmount(amount, extra) {    g_recomandedLiftAmount = parseInt(amount);    $('#liftAmount').html(g_recomandedLiftAmount);    $('#extraliftAmount').html(parseInt(extra));}function updateXtrackAmount(amount, extra) {    g_recomandedXtrackAmount = parseInt(amount);    $('#xtrackAmount').html(g_recomandedXtrackAmount);    $('#extraxtrackAmount').html(parseInt(extra));}$('#cameraView3D').on("click", function () {    if (g_simMultipleView) return;    switch_to_free_camera();});$('#cameraView2D').on("click", function () {    if (g_simMultipleView) return;    switch_to_top_camera();});$('#cameraFront').on("click", function () {    if (g_simMultipleView) return;    switch_to_front_camera();});$('#cameraSide').on("click", function () {    if (g_simMultipleView) return;    switch_to_side_camera();});$('#zoomIn').on("click", function () {    switch (currentView) {        case ViewType.top:            zoom2DCamera(-1, false);            break;        case ViewType.free:            scene.activeCamera.radius -= 1;            break;        case ViewType.front:        case ViewType.side:            zoom2DCamera(-1, true);            break;        default:            break;    }    renderScene();});$('#zoomOut').on("click", function () {    switch (currentView) {        case ViewType.top:            zoom2DCamera(1, false);            break;        case ViewType.free:            scene.activeCamera.radius += 1;            break;        case ViewType.front:        case ViewType.side:            zoom2DCamera(1, true);            break;        default:            break;    }    renderScene();});$('#resetCamera').on("click", function () {    switchCamera(currentView);});/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////New, Save and Load///////////////////////////////////////////////////////////////////////////////////////////////////////////////////$('.new-btn').on("click", function () {    currenntDataBaseAction = DataBaseAction.new;    $(".new-modal-close").show();    if (hasUpdates()) {        if (confirm("你想保存你的工作吗?")) {            saveProject(() => {                showModal('new-modal');            });        } else {            showModal('new-modal');        }    } else {        showModal('new-modal');    }});$('.save-btn').on("click", function () {    currenntDataBaseAction = DataBaseAction.save;    if (documentName === "") {        showModal('saveAs-modal');    } else {        if (hasUpdates()) {            tracking(3);            saveProject(() => {                if (userRole === g_UserRole.Demo) {                    window.location.replace('home/logout');                }            });        }    }});$('.saveAs-btn').on("click", function () {    currenntDataBaseAction = DataBaseAction.save;    showModal('saveAs-modal');});$('.adminLoadAutoSave-btn').on("click", function () {    currenntDataBaseAction = DataBaseAction.load;    loadProject(documentName, documentInfo, true);});$('.load-btn').on("click", function () {    currenntDataBaseAction = DataBaseAction.load;    $(".load-modal-close").show();    if (hasUpdates()) {        if (confirm("你想保存你的工作吗?")) {            saveProject(function () {                getProjectList(function (datas) {                    createProjectList(datas);                });            });        } else {            getProjectList(function (datas) {                createProjectList(datas);            });        }    } else {        getProjectList(function (datas) {            createProjectList(datas);        });    }});$('.load-modal-close').on("click", function () {    hideModal('load-modal');});$('.new-modal-close').on("click", function () {    hideModal('new-modal');});$('.saveAs-modal-close').on("click", function () {    hideModal('saveAs-modal');});$('.rating-modal-close').on("click", function () {    Utils.request(g_BasePath + 'home/rating', 'POST', {complete: 0}, () => {        hideModal('rating-modal');    });});$('.planAddInfo-modal-close').on("click", function () {    hideModal('planAddInfo-modal');});$('.saveAs-modal-confirm').on("click", function () {    if ($('#inputDocumentAs').val() == "") {        $('#inputDocumentAs').focus();    } else {        old_documentName = documentName;        documentName = $('#inputDocumentAs').val().trim();        documentNameOverlapCheck(function (datas) {            let isOverlap = false;            datas.map(data => {                if (data.document_name == documentName) {                    isOverlap = true;                }            });            if (isOverlap) {                documentName = old_documentName;                Utils.logg("项目名称已存在。选择其他名称。", '错误');                $('#inputDocumentAs').val("").focus();            } else {                createBehavior();                $('#project-name').html(documentName);                hideModal('saveAs-modal');                tracking(37);                currenntDataBaseAction = DataBaseAction.save;                saveProject();            }        });    }});$('.new-modal-confirm').on("click", function () {    if ($('#inputDocument').val() == "") {        $('#inputDocument').focus();    } else {        old_documentName = documentName;        documentName = $('#inputDocument').val().trim();        documentNameOverlapCheck((datas) => {            let isOverlap = false;            datas.map(data => {                if (data.document_name == documentName) {                    isOverlap = true;                }            });            if (isOverlap) {                documentName = "";                Utils.logg("项目名称已存在。选择其他名称。", '错误');                $('#inputDocument').val("").focus();            } else {                $('#project-name').html(documentName);                hideModal('new-modal');                saveProject();                currenntDataBaseAction = DataBaseAction.new;                if (currenntDataBaseAction === DataBaseAction.new || currenntDataBaseAction === DataBaseAction.load || isEditByAdmin) {                    currentTemplateType.document_name = documentName;                    setProject(currentTemplateType);                }            }        });    }});$(".undo-btn").on("click", function () {    Behavior.undo();});$(".redo-btn").on("click", function () {    Behavior.redo();});//Change templates$(".img-rounded").on("click", function () {    currentTemplateType = Template.values[Template.type[$(this).attr('key')]];    const templateItems = $(".template-item-box");    for (let i = 0; i < templateItems.length; i++) {        templateItems[i].classList.remove("select");    }    $(this).parent().addClass("select");});function initToolBar() {    SetUIUnits();    ChangeUnits();    setUnitForInput();    $('#numberOfSKU').val(parseInt(g_SKU));    $('#numberOfPalletInOutPerHour').val(parseInt(g_movesPerHour));    $('#carrierAmount').html(parseInt(g_recomandedCarrierAmount));    $('#liftAmount').html(parseInt(g_recomandedLiftAmount));    $('#extracarrierAmount').val(parseInt(g_extraCarrierAmount));    $('#extraliftAmount').html(parseInt(g_extraLiftAmount));    $('#xtrackAmount').html(parseInt(g_recomandedXtrackAmount));    $('#extraxtrackAmount').html(parseInt(g_extraXtrackAmount));    updateRackingHighLevel(true);    updatePalletDistributions(g_palletInfo.value);    $('#input-pallet-weight').val(g_palletWeight);    $('#palletOverhang').val(g_palletOverhang);    $('#loadPalletOverhang').val(g_loadPalletOverhang);    $('select[name="orientationRacking"]').val(g_rackingOrientation);    $('#spacing_b_rows').val(g_spacingBetweenRows);    if (g_palletAtLevel.length > 0) {        $('#customLastRow').trigger('click');    }    if (g_drawMode === 0) {        if ($('#custom-upRightDist').hasClass('active-icube-setting')) return;        $('#auto-upRightDist').removeClass('active-icube-setting');        $('#input-upRightDistance').attr('disabled', false);        $('#custom-upRightDist').addClass('active-icube-setting');    } else {        if ($('#auto-upRightDist').hasClass('active-icube-setting')) return;        $('#custom-upRightDist').removeClass('active-icube-setting');        $('#input-upRightDistance').attr('disabled', true);        $('#auto-upRightDist').addClass('active-icube-setting');    }    createPassThList();    if (isEditByAdmin || g_palletAtLevel.length > 0 || g_palletInfo.order.length > 1) {        if (!$('#settingsModeA1').hasClass('active-icube-setting')) {            $('#settingsModeA1').trigger('click');        }    }}function initToolBarForICube(rackingHighLevel, rackingOrientation, palletHeight, palletWeight, palletOverhang, loadPalletOverhang, sku, throughput, calculatedCarriersNo, calculatedLiftsNo, extra, upRightDistance, calculatedXtracksNo, palletAtLevel, spacingBetweenRows) {    g_rackingHighLevel = rackingHighLevel;    g_rackingOrientation = rackingOrientation;    g_palletHeight = palletHeight;    g_palletWeight = palletWeight;    g_palletOverhang = palletOverhang;    g_loadPalletOverhang = loadPalletOverhang;    g_SKU = sku;    g_movesPerHour = throughput;    g_recomandedCarrierAmount = calculatedCarriersNo;    g_recomandedLiftAmount = calculatedLiftsNo;    g_extraCarrierAmount = extra.carrier;    g_extraLiftAmount = extra.lift;    g_extraXtrackAmount = extra.xtrack;    g_distUpRight = upRightDistance;    g_palletAtLevel = palletAtLevel;    g_spacingBetweenRows = spacingBetweenRows;    currentUnits = unit_measurement;    initToolBar();}function saveProject(callback) {    const icubeData = getIcubeData();    const itemMData = getManualItems();    const measurements = getAllMeasurements();    WHDimensions = WHDimensions.map(e => parseFloat((e).toFixed(unit_measurement ? 3 : 2)));    const data = {        document_name: documentName,        warehouse_dimensions: WHDimensions,        icubeData: icubeData,        itemMData: itemMData,        unit_measurement: unit_measurement,        layoutMap: layoutMap,        extraInfo: extraInfo,        extraPrice: extraPrice,        measurements: measurements,        custom_values: custom_values    }    initData(data);    Utils.request(g_BasePath + 'home/save', 'POST', {        documentInfo: documentInfo,        document_name: documentName,        isEditByAdmin: parseInt(isEditByAdmin),        warehouse_dimensions: JSON.stringify(WHDimensions),        icubeData: JSON.stringify(icubeData),        itemMData: JSON.stringify(itemMData),        unit_measurement: JSON.stringify(unit_measurement),        layoutMap: JSON.stringify(layoutMap),        extraInfo: JSON.stringify(extraInfo),        extraPrice: JSON.stringify(extraPrice),        measurements: JSON.stringify(measurements),        custom_values: JSON.stringify(custom_values),        inventory: g_inventory    }, (data) => {        documentName = data['documentName'];        $('#project-name').html(documentName);        Utils.logg('布局已成功保存!', '成功');        Behavior.add(Behavior.type.saves);        let rev = {            document_name: documentName        }        if (documentInfo > 0) {            rev = Object.assign({}, rev, {slid: documentInfo});        }        getRevisions(rev);        if (callback) callback();    }, () => {        alert("保存失败!请稍后再试。");    });}function loadProject(document_name, slid = -1, useBackUp = false) {    let data = {        document_name: document_name    }    if (slid !== -1) {        data = Object.assign({}, data, {slid: slid});    }    if (useBackUp) {        data = Object.assign({}, data, {useBackUp: useBackUp});    }    Utils.request(g_BasePath + 'home/load', 'POST', data, (res) => {        setProject(res);    }, () => {        alert("加载失败!请稍后再试。");    });}function setProject(data, newProject = true, versionIdx = -1) {    if (currentView !== ViewType.top)        switch_to_top_camera();    extraInfo = data.extraInfo;    extraPrice = data.extraPrice ? data.extraPrice : [];    unit_measurement = data.unit_measurement || 0;    msments = data.measurements ? data.measurements : [];    custom_values = data.custom_values ? data.custom_values : [];    documentInfo = (isEditByAdmin) ? data.documentInfo : "";    documentName = data.document_name;    if (!Array.isArray(data.warehouse_dimensions) || data.warehouse_dimensions.length === 0) {        data.warehouse_dimensions = Template.values[Template.type.Default].warehouse_dimensions;    }    WHDimensions = [parseFloat(data.warehouse_dimensions[0]), parseFloat(data.warehouse_dimensions[1]), parseFloat(data.warehouse_dimensions[2])];    // update html inputs    initToolBar();    // remove curent icubes    removeAllIcubes();    // remove manual items    removeManualItems();    // remove all measurements    removeAllMeasurements();    warehouse.update(WHDimensions);    // need to set this to be able to set later the racking    g_palletHeight = (data.icubeData.length !== 0) ? data.icubeData[data.icubeData.length - 1].palletHeight : g_palletHeight;    resetConfigVariables();    loadIcubeData(data.icubeData, data.itemMData, data.layoutMap);    // load manual items inside loadIcube, after icube was draw    // loadItemMData(data.itemMData);    $('#customValue').html(custom_values.length > 0 ? `<b>⚠ This project contains custom values ⚠</b>` : ``);    // show measurements    for (let i = 0; i < msments.length; i++) {        const msm = new Measurement({            id: msments[i][2],            pi: new BABYLON.Vector3(msments[i][0][0], 0, msments[i][0][1]),            pf: new BABYLON.Vector3(msments[i][1][0], 0, msments[i][1][1])        }, scene);        msm.isCompleted();        g_measurementList.push(msm);    }    if (!$('.tab-content').is(':visible'))        $('#main-tabs-tab-Size').trigger('click');    if (newProject) {        initData(data);        let rev = {            document_name: documentName        }        if (documentInfo > 0) {            rev = Object.assign({}, rev, {slid: documentInfo});        }        getRevisions(rev, versionIdx);        Behavior.init();        createBehavior();        Behavior.add(Behavior.type.addIcube);        $('#project-name').html(documentName);        Utils.logg('布局已成功加载!', '成功');    }}function deleteProject(document_name, slid = -1) {    let data = {        document_name: document_name    }    if (slid !== -1) {        data = Object.assign({}, data, {slid: slid});    }    Utils.request(g_BasePath + 'home/delete', 'POST', data, () => {        Utils.logg('布局已成功删除!', '成功');    }, () => {        alert("删除失败!请稍后再试。");    });}function renameProject(document_name, slid) {    Utils.request(g_BasePath + 'home/rename', 'POST', {        document_name: document_name,        slid: slid    }, () => {        Utils.logg('布局已成功重命名!', '成功');    }, () => {        alert("重命名失败!请稍后再试。");    });}function sendProjectNotify(document_name, email) {    Utils.request(g_BasePath + 'home/sentNotificationSA', 'POST', {        docName: document_name,        email: email    }, () => {        Utils.logg('通知已成功发送!', '成功');    }, () => {        alert("通知已成功发送!");    });}function showModal(name) {    $('#' + name).removeClass('fade').show();    if (name === 'new-modal') {        $('#inputDocument').val("").focus();    }    if (name === 'saveAs-modal') {        $('#inputDocumentAs').val("").focus();    }    if (name === 'load-modal') {        $('#searchProject').val("").focus();    }}function hideModal(name) {    $('#' + name).addClass('fade').hide();    $('.modal-backdrop').hide();}function createProjectList(datas) {    let html = ``;    $('.list-group').html("");    for (let i = 0; i < datas.length; i++) {        html += `<div class="form-group projectList">      <div class="col-lg-11 loadP" style="cursor:pointer;">        <h5 style="font-weight:bold;">` + datas[i].document_name + `</h5>        <span>` + datas[i].saved_time + `</span>      </div>      <div class="col-lg-1">        <button type="button" class="loadP-btn deleteP" title="Delete project"><i class="fa fa-times" aria-hidden="true"></i></button>`            + (datas[i].backup ? `<button type="button" class="loadP-btn loadBP" title="Restore project from auto-saves"><i class="fa fa-hdd-o" aria-hidden="true"></i></button>` : ``) +            `</div>    </div>`;    }    $(".list-group").append(html);    showModal('load-modal');    $('.loadP').click(function () {        const document_name = $(this).find('h5').html();        loadProject(document_name);        hideModal('load-modal');    });    $('.deleteP').click(function (e) {        //if (confirm('Are you sure you want to permanently delete this project?')) {        const document_name = $(this).parent().prev()[0].firstElementChild.innerHTML;        deleteProject(document_name);        $(this).parent().parent().remove();        //}    });    $('.loadBP').click(function () {        const document_name = $(this).parent().prev()[0].firstElementChild.innerHTML;        loadProject(document_name, -1, true);        hideModal("load-modal");    });}function initData(data) {    for (let key in data) {        if (Array.isArray(data[key])) {            init_data[key] = [];            if (data[key].length > 0) {                if (isNaN(parseInt(data[key]))) {                    if (key === 'icubeData') {                        for (let i = 0; i < data[key].length; i++) {                            init_data[key][i] = {};                            for (let key2 in data[key][i]) {                                if (['name', 'uid', 'baseLines'].includes(key2)) continue;                                if (Array.isArray(data[key][i][key2])) {                                    if (isNaN(parseInt(data[key][i][key2]))) {                                        if (key2 === 'activedCarrierInfos') {                                            init_data[key][i][key2] = [...data[key][i][key2]];                                        } else {                                            init_data[key][i][key2] = data[key][i][key2].map(a => {                                                return {...a};                                            });                                        }                                    } else {                                        init_data[key][i][key2] = [...data[key][i][key2]];                                    }                                } else {                                    if (isNaN(parseInt(data[key][i][key2]))) {                                        init_data[key][i][key2] = JSON.parse(data[key][i][key2]);                                    } else {                                        init_data[key][i][key2] = data[key][i][key2];                                    }                                }                            }                        }                    } else {                        init_data[key] = data[key].map(a => {                            return {...a};                        });                    }                } else {                    init_data[key] = [...data[key]];                }            }        } else {            init_data[key] = data[key];        }    }}function hasUpdates() {    const icubeData = getIcubeData();    const itemMData = getManualItems();    const measurements = getAllMeasurements();    if (icubeData.length === 0 && itemMData.length === 0) return false;    if (JSON.stringify(init_data.layoutMap) == JSON.stringify(layoutMap) &&        JSON.stringify(init_data.extraInfo) == JSON.stringify(extraInfo) &&        JSON.stringify(init_data.extraPrice) == JSON.stringify(extraPrice) &&        JSON.stringify(init_data.measurements) == JSON.stringify(measurements) &&        JSON.stringify(init_data.custom_values) == JSON.stringify(custom_values) &&        JSON.stringify(init_data.warehouse_dimensions) == JSON.stringify(WHDimensions) &&        JSON.stringify(init_data.itemMData) == JSON.stringify(itemMData)    ) {        let hasChanges = true;        for (let i = 0; i < init_data.icubeData.length; i++) {            if (icubeData[i]) {                let changes = [];                for (let key in init_data.icubeData[i]) {                    if (Array.isArray(init_data.icubeData[i][key])) {                        changes.push(JSON.stringify(init_data.icubeData[i][key]) == JSON.stringify(icubeData[i][key]) ? false : true);                    } else {                        changes.push(init_data.icubeData[i][key] == icubeData[i][key] ? false : true);                    }                }                const change = changes.filter(e => e === true);                hasChanges = change.length > 0 ? true : false;                if (!hasChanges) break;            }        }        // console.log('if ', hasChanges)        return hasChanges;    } else {        // console.log('else truuuue')        return true;    }}function documentNameOverlapCheck(callback) {    Utils.request(g_BasePath + 'home/documentNameOverlapCheck', 'GET', {}, (data) => {        callback(data);    }, null);}function getProjectList(callback) {    Utils.request(g_BasePath + 'home/getProjectList', 'GET', {}, (data) => {        callback(data);    }, null);}function getUserInfo(callback = null) {    Utils.request(g_BasePath + 'home/getUserInfo', 'POST', {        documentInfo: documentInfo    }, (data) => {        userName = data.name;        userEmail = data.email;        userPhone = data.phone;        loginCount = data.login_count;        if (parseInt(data.projects) === 0)            loginCount = 1;        if (userRole !== g_UserRole.Demo)            $('#emailP').val(userEmail);        if (!isEditByAdmin && userRole === g_UserRole.Sales)            getUsersSA();        if (callback)            callback();    }, null);}$("#btn-full-screen").on("click", function () {    scene.getEngine().enterFullscreen(false);});$("#btn-save-pdf").on("click", function () {    $('#waiting').show('fast', () => {        Export_PDF.generateFile(false);        tracking(8);    });    if (!isEditByAdmin)        Utils.request(g_BasePath + 'home/downloadPDF', 'POST', {}, null, null);});$("#btn-save-dxf").on("click", function () {    $('#waiting').show('fast', () => {        tracking(12);        if ($('#cadAsPDF').is(':checked')) {            Export_CAD.generateFile(false, true);        } else {            const formData = new FormData();            formData.append('dxf', Export_CAD.generateFile(false, false));            formData.append('data', JSON.stringify({documentName: documentName, documentInfo: documentInfo}));            Utils.requestFormData(g_BasePath + 'home/uploadCAD', 'POST', formData, async (result) => {                const res = JSON.parse(result);                if (res.url.length === 0) {                    $('#waiting').hide();                    Utils.logg('首先保存项目', '错误');                    return;                }                const newURL = res.url.replace(/ /g, "%20");                const ccURL = "https://api.cloudconvert.com/v2";                const name = res.url.split("/").pop().split('.').shift();                const job = {                    "tasks": {                        "file1": {                            "operation": "import/url",                            "url": newURL                        },                        "converttodwg": {                            "operation": "convert",                            "input_format": "dxf",                            "output_format": "dwg",                            "engine": "cadconverter",                            "input": ["file1"],                            "engine_version": "8.9",                            "filename": name + ".dwg"                        },                        "converted": {                            "operation": "export/url",                            "input": ["converttodwg"],                            "inline": false,                            "archive_multiple_files": false                        }                    },                    "tag": "logiqs"                }                const options = {                    "method": "POST",                    "body": JSON.stringify(job),                    "headers": {                        "Authorization": "Bearer " + res.key,                        "Content-type": "application/json"                    }                }                const response = await fetch(ccURL + "/jobs", options);                response.json().then(async (resJob) => {                    const options2 = {                        "method": "GET",                        "headers": {                            "Authorization": "Bearer " + res.key                        }                    }                    const response2 = await fetch(ccURL + "/tasks/" + resJob.data.tasks[2].id + '/wait', options2);                    response2.json().then((resTask) => {                        $('#waiting').hide();                        if ((!resTask.data.result) || (resTask.data.result && resTask.data.result.files.length === 0)) return;                        const url = resTask.data.result.files[0].url;                        const filename = name + ".dwg";                        Utils.download(filename, url, false);                    });                });            });        }    });});$("#btn-save-3ds").on("click", function () {    $('#waiting').show('fast', async () => {        await Export_OBJ.generateFile();        $('#waiting').hide();        tracking(43);    });});$("#btn-save-view").on("click", function () {    if (hasUpdates()) {        saveProject(() => {            Export_PNG.generateFile();            tracking(40);        });    } else {        Export_PNG.generateFile();        tracking(40);    }});$("#btnSubmission").on("click", function () {    $('#waiting').show('fast', () => {        Export_PDF.generateFile(true);    });});$('#contact-form').on("submit", function (e) {    e.preventDefault();});$('#contact_submit').on("click", async function () {    if ($('#contact-form').valid()) {        $('#waiting').show();        const doc = new window.jspdf.jsPDF('l', 'pt', 'a4', true);        doc.setFont('arial-unicode-ms');        // page 1        doc.setFontSize(15);        doc.text(50, 50, '用户名 : ' + $('#con_fullName').val());        doc.setFontSize(15);        doc.text(50, 80, '邮箱 : ' + $('#con_email').val());        doc.setFontSize(15);        doc.text(50, 110, '公司 : ' + $('#con_company').val());        doc.setFontSize(15);        doc.text(50, 140, '位置 : ' + $('#con_location').val());        doc.setFontSize(15);        doc.text(50, 170, '产量 : ' + $('#con_crop').val());        doc.setFontSize(15);        doc.text(50, 200, $('#schedule_yes').is(":checked") ? "客户希望与销售人员预约" : "客户不想与销售人员预约");        doc.setFontSize(15);        doc.text(50, 230, '日期 : ' + $('#con_preferred_date').val());        doc.setFontSize(15);        doc.text(50, 260, '问题 : ');        const splitTitle = doc.splitTextToSize($('#con_question').val(), 650);        doc.text(100, 290, splitTitle);        if ($('#include_yes').is(":checked")) {            doc.addPage();            const lastView = currentView;            const freeImage = await getImage(ViewType.free, true);            doc.addImage(freeImage, 'JPEG', 20, 40, 800, 500, undefined, 'FAST');            getImage(lastView);        }        const formData = new FormData();        formData.append('pdf', doc.output('blob'));        Utils.requestFormData(g_BasePath + 'home/contact', 'POST', formData, () => {            $('#waiting').hide();            Utils.logg('您的问题已成功提交!', '成功');        });    }});function SetUIUnits() {    if (currentUnits === Units.metric) {        $('#metric').attr("checked", true);        $('#usStand').attr("checked", false);        $('select[name="metric"]').attr("disabled", false);        $('select[name="usStand"]').attr("disabled", true);        $('.unit-text2').text(' mm ');    } else if (currentUnits === Units.usStand) {        $('#metric').attr("checked", false);        $('#usStand').attr("checked", true);        $('select[name="metric"]').attr("disabled", true);        $('select[name="usStand"]').attr("disabled", false);        $('.unit-text2').text(' in ');    }    $('select[name="metric"]').val(currentMetric);    $('select[name="usStand"]').val(currentUSStand);    for (let i = 0; i < palletTypeNameM.length; i++) {        if (currentUnits === Units.metric) {            $('#palletDistr_' + i).prev().text(palletTypeNameM[i]);            $('#palletDistrC_' + i).prev().text(palletTypeNameM[i]);        } else {            $('#palletDistr_' + i).prev().text(palletTypeNameU[i]);            $('#palletDistrC_' + i).prev().text(palletTypeNameU[i]);        }    }    for (let i = 0; i < palletTypeNameM.length; i++) {        if (currentUnits === Units.metric) {            $(".palletSizeList li:nth-child(" + (i + 1) + ") > label").html(palletTypeNameM[i]);        } else {            $(".palletSizeList li:nth-child(" + (i + 1) + ") > label").html(palletTypeNameU[i]);        }    }}function ChangeUnits() {    rateUnit = 1;    unitChar = UnitChars.meters;    if (currentUnits === Units.metric) {        switch (currentMetric) {            case Metric.millimeters:                rateUnit = rateUnit * 1000;                unitChar = UnitChars.millimeters;                break;            case Metric.centimeters:                rateUnit = rateUnit * 100;                unitChar = UnitChars.centimeters;                break;            case Metric.meters:                rateUnit = rateUnit * 1;                unitChar = UnitChars.meters;                break;        }    } else if (currentUnits === Units.usStand) {        switch (currentUSStand) {            case USStand.feet:                rateUnit = rateUnit * 3.28084;                unitChar = UnitChars.feet;                break;            case USStand.inches:                rateUnit = rateUnit * 39.3701;                unitChar = UnitChars.inches;                break;        }    }    setUnitForInput();    //Change unit of unitChar    $('.unit-text').each(function (index) {        $(this).text(unitChar);    });    updateIcubesDimensions();}//Setting$('.units').on("change", function () {    if (currentUnits === Units.metric) {        currentUnits = Units.usStand;    } else {        currentUnits = Units.metric;    }    unit_measurement = currentUnits;    tracking(36);    SetUIUnits();    ChangeUnits();});$('select[name="metric"]').on("change", function (event) {    currentMetric = parseInt(event.target.value);    ChangeUnits();});$('select[name="usStand"]').on("change", function (event) {    currentUSStand = parseInt(event.target.value);    ChangeUnits();});$('#con_preferred_date').datepicker({    minDate: '+1d',    beforeShowDay: $.datepicker.noWeekends}).datepicker('setDate', '+1d');$('#addInfo_delivery_date, #addInfo_delivery_date2').datepicker({    minDate: '+1m',    beforeShowDay: $.datepicker.noWeekends}).datepicker('setDate', '+1m');function setUnitForInput() {    $('#input-wh-width').val((WHDimensions[0] * rateUnit).toFixed(unitChar === UnitChars.millimeters ? 0 : 2));    $('#input-wh-length').val((WHDimensions[1] * rateUnit).toFixed(unitChar === UnitChars.millimeters ? 0 : 2));    $('#input-wh-height').val((WHDimensions[2] * rateUnit).toFixed(unitChar === UnitChars.millimeters ? 0 : 2));    $('#input-pallet-height').val((g_palletHeight * rateUnit).toFixed(unitChar === UnitChars.millimeters ? 0 : 2));    $('#input-upRightDistance').val((g_distUpRight * rateUnit).toFixed(unitChar === UnitChars.millimeters ? 0 : 3));    $('#spacing_b_rows').find("option").each(function () {        $(this).text(($(this).val() * rateUnit).toFixed(unitChar === UnitChars.millimeters ? 0 : 2));    });    $('#palletOverhang, #loadPalletOverhang').find("option").each(function () {        if (currentUnits === Units.metric) {            $(this).text(($(this).val() * 1000));            $('.unit-text2').text('mm');        } else {            $(this).text(($(this).val() * 39.3701).toFixed(3));            $('.unit-text2').text('in');        }    });    if (currentUnits === Units.metric) {        $("#palletSize > label").html(palletTypeNameM[g_palletInfo.order[0]]);    } else {        $("#palletSize > label").html(palletTypeNameU[g_palletInfo.order[0]]);    }}function formatIntNumber(num) {    return Math.round(num).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.');}//Tooltip$(document).ready(function () {    $('[data-toggle="tooltip"]').tooltip();    document.addEventListener("contextmenu", e => e.preventDefault());});//Error handlingwindow.onerror = (message, url, lineNumber) => {    console.log(message, url, lineNumber);    const formData = new FormData();    formData.append("documentName", documentName);    formData.append("lineNumber", lineNumber);    formData.append("message", message);    formData.append("url", url);    BABYLON.Tools.CreateScreenshotAsync(scene.getEngine(), scene.activeCamera, {        width: 1600,        height: 1000    }).then((screenshot) => {        formData.append("screenshot", screenshot);        Utils.requestFormData(g_BasePath + "home/sendLog", "POST", formData);    });    return true;}function checkForUnknownTable() {    if (userRole !== g_UserRole.Sales) return;    const elem = document.getElementById('tablesHolder');    const kids = elem.childNodes.length;    for (let i = kids - 1; i >= 0; i -= 2) {        if (elem.childNodes[i].childNodes.length > 1) {            const body = elem.childNodes[i].childNodes[elem.childNodes[i].childNodes.length - 2];            if (body.id && icubes.filter(e => e.id === body.id).length === 0) {                elem.removeChild(elem.childNodes[i]);                elem.removeChild(elem.childNodes[i - 2]);            }        }    }}//Pricingfunction setPriceTable(data, icube) {    if (g_tutorialIsRunning) return;    if (userRole !== g_UserRole.Sales) return;    checkForUnknownTable();    // console.log(extraPrice)    const dataInfo = {        'racking': 'Racking costs',        'xtrack': 'X-Track elements',        'lift': 'Vertical Transporters',        'carrier': '3D-Carriers',        'wifi': 'System WiFi connectivity',        'data_control': 'Dat-A-Control WMS Software',        'software_implementation': 'Software implementation and deployment',        'central_panel': 'Central control panel',        // 'extra_lift': 'Extra Vertical Transporters',        'extra_carrier': 'Extra 3D-Carriers',        'total_excluding': 'Total price estimation \n (excluding transport and installation)'    }    const details = $('#priceDetails').is(':checked');    let html = "";    for (let item in data) {        if (!details && item != 'total_excluding') continue;        html += '<tr>';        html += '<td>' + dataInfo[item] + ((item == 'lift' && icube.extra.lift > 0) ? ' (' + icube.extra.lift + ' added by customer)' : '') + '</td>'; //name        html += '<td class="text-right">' + (data[item]['qty'] === -1 ? ' ' : formatIntNumber(data[item]['qty'])) + (item === 'racking' ? ' pallet positions' : '') + '</td>'; //qty        html += '<td class="text-right">' + '€' + formatIntNumber(data[item]['val']) + '</td>'; //price        html += '</tr>';    }    if (document.getElementById(icube.id)) {        document.getElementById(icube.id).innerHTML = html;    } else {        const table = `      <div class="itemTable" style="margin-top:50px; padding: 10px; font-weight: bold;">` + icube.name + `</div>      <table class="table itemTable table-responsive-lg table-bordered table-striped table-sm mb-0 mt-0">        <colgroup>          <col width="30%">          <col width="8%">          <col width="10%">        </colgroup>        <thead>          <tr>            <th>` + (details === false ? 'Item name' : 'Automatic item name') + `</th>            <th class="text-right">Quantity</th>            <th class="text-right">Price estimation</th>          </tr>        </thead>        <tbody id="` + icube.id + `">` + html + `</tbody>      </table>`;        document.getElementById("tablesHolder").innerHTML += table;    }    g_totalPrice = parseFloat(updateExtraPriceTable());    g_totalPrice += parseFloat(document.getElementById('connectorPrice').innerHTML) * 1000;    for (let i = 0; i < icubes.length; i++) {        g_totalPrice += icubes[i].estimatedPrice;    }    $('#totalPrice').text('€' + formatIntNumber(g_totalPrice));}function updateInventory() {    if (!selectedIcube) return;    let cap = 0;    icubes.forEach((icube) => {        const icubePalletNo = icube.getPalletNoJS();        cap += icubePalletNo[0];        cap += icubePalletNo[1];        cap += icubePalletNo[2];    });    let sstores = [];    let railLengths = [0, 0, 0, 0, 0];    for (let i = 0; i < selectedIcube.stores.length; i++) {        for (let j = 0; j < selectedIcube.stores[i].dimension.length; j++) {            const length = _round(selectedIcube.stores[i].dimension[j][1] - selectedIcube.stores[i].dimension[j][0], 3);            if (length < 5) {                railLengths[0]++;            } else {                if (length < 10 && length >= 5) {                    railLengths[1]++;                } else {                    if (length < 25 && length >= 10) {                        railLengths[2]++;                    } else {                        if (length < 50 && length >= 25) {                            railLengths[3]++;                        } else {                            railLengths[4]++;                        }                    }                }            }            if (sstores.length === 0) {                sstores.push({                    length: length,                    pallets: selectedIcube.stores[i].capacity[j][g_palletInfo.max],                    numbers: 1                });            } else {                const filter = sstores.filter(e => (e.length == length));                if (filter.length > 0) {                    filter[0].numbers += 1;                } else {                    sstores.push({                        length: length,                        pallets: selectedIcube.stores[i].capacity[j][g_palletInfo.max],                        numbers: 1                    });                }            }        }    }    // console.log(manualItemInfo[3].meshData)    g_inventory = {        'stores': JSON.stringify(sstores),        'dimension': JSON.stringify(WHDimensions),        'pallet_800': g_palletInfo.value[0],        'pallet_1000': g_palletInfo.value[1],        'pallet_1200': g_palletInfo.value[2],        'levelHeight': g_palletHeight,        'rackingLevels': g_rackingHighLevel,        'SKU': g_SKU,        'throughput': g_movesPerHour,        'g_lift': (selectedIcube.calculatedLiftsNo + selectedIcube.extra.lift),        'g_carrier': (selectedIcube.calculatedCarriersNo + selectedIcube.extra.carrier),        'g_port': selectedIcube.activedIOPorts.length,        'g_capacity': cap,        'g_rail_5': railLengths[0],        'g_rail_5_10': railLengths[1],        'g_rail_10_25': railLengths[2],        'g_rail_25_50': railLengths[3],        'g_rail_50': railLengths[4],        'm_xtrack': manualItemInfo[0].meshData.length,        'm_palletDropS': manualItemInfo[1].meshData.length,        'm_palletDropSCS': manualItemInfo[9].meshData.length,        'm_palletDropSCC': manualItemInfo[6].meshData.length,        'm_chainC400': manualItemInfo[4].meshData.length,        'm_chainC540': manualItemInfo[5].meshData.length,        'm_rollerCC': manualItemInfo[8].meshData.length,        'm_roller200': manualItemInfo[7].meshData.length,        'm_sfence100': manualItemInfo[10].meshData.length,        'm_sfence200': manualItemInfo[2].meshData.length,        'm_sfenceDoor': manualItemInfo[11].meshData.length,        'm_scanner': manualItemInfo[12].meshData.length,        'm_stairs': manualItemInfo[13].meshData.length,        'm_rail_5': 0,        'm_rail_5_10': 0,        'm_rail_10_25': 0,        'm_rail_25_50': 0,        'm_rail_50': 0,        'm_others': 0    }    //console.log(g_inventory);}$('.faq').on("click", function () {    $('.faq').removeClass('faq_active');    $('.faq').next().addClass('hide');    $(this).addClass('faq_active');    $(this).next().removeClass('hide');});function showLoadingPopUp(callback) {    $("#loadingScene").fadeIn(1, callback);}function hideLoadingPopUp() {    $("#loadingScene").fadeOut(100);}function checkPlacedXtracklift() {    let allSet = true;    let xtracks, lifts;    for (let i = 0; i < icubes.length; i++) {        xtracks = parseInt(icubes[i].calculatedXtracksNo) - parseInt(icubes[i].activedXtrackIds.length);        lifts = parseInt(icubes[i].calculatedLiftsNo) + parseInt(icubes[i].extra.lift) - parseInt(icubes[i].activedLiftInfos.length);        if (xtracks !== 0 || lifts !== 0) {            allSet = false;            break;        }    }    let mess = '';    if (!allSet) {        if (xtracks !== 0 && lifts !== 0) {            mess += 'You have not placed the required x-Track(s) and Vertical Transporters to the layout.<br>';            mess += 'Are you sure you want to submit for pricing or would you like to first add the missing x-Track(s) and Vertical Transporters';        } else {            if (xtracks !== 0) {                mess += 'You have not placed the required x-Track(s) to the layout.<br>';                mess += 'Are you sure you want to submit for pricing or would you like to first add the missing x-Track(s)';            } else {                mess += 'You have not placed the required Vertical Transporters to the layout.<br>';                mess += 'Are you sure you want to submit for pricing or would you like to first add the missing Vertical Transporters';            }        }    }    return [allSet, mess];}$("#btnSubmissionPlan").on("click", function () {    const data = checkPlacedXtracklift();    if (data[0]) {        showModal('planAddInfo-modal');    } else {        $('#submit-modal-mess').html(data[1]);        showModal('submit-modal');    }});$("#btnSubmissionPlanToManager").on("click", function () {    $('#waiting').show('fast', () => {        Export_PDF.generateFile(true);    });    hideModal('planAddInfo-modal');});$("#btnSubmissionPlanToManager2").on("click", function () {    const data = checkPlacedXtracklift();    extraInfo = {        email: $('#emailP').val(),        compName: (userRole === g_UserRole.Sales ? $('#addInfo_company').val() : $('#addInfo_company2').val()),        contactP: (userRole === g_UserRole.Sales ? $('#addInfo_contacter').val() : $('#addInfo_contacter2').val()),        location: (userRole === g_UserRole.Sales ? $('#addInfo_location').val() : $('#addInfo_location2').val()),        delDate: (userRole === g_UserRole.Sales ? $('#addInfo_delivery_date').val() : $('#addInfo_delivery_date2').val()),        temperature: (userRole === g_UserRole.Sales ? ($('#addInfo_temp').is(":checked") ? 'Yes' : 'No') : ($('#addInfo_temp2').is(":checked") ? 'Yes' : 'No')),        flammable: (userRole === g_UserRole.Sales ? ($('#addInfo_flammable').is(":checked") ? 'Yes' : 'No') : ($('#addInfo_flammable2').is(":checked") ? 'Yes' : 'No')),        food: (userRole === g_UserRole.Sales ? ($('#addInfo_food').is(":checked") ? 'Yes' : 'No') : ($('#addInfo_food2').is(":checked") ? 'Yes' : 'No')),        feedback: $('#help_feedback').val()    }    if (data[0]) {        if (userRole !== g_UserRole.Demo) {            $('#waiting').show('fast', () => {                Export_PDF.generateFile(true);            });        } else {            if (extraInfo.contactP.length === 0) return;            if (extraInfo.email.length === 0) return;            if (!Utils.validateEmail(extraInfo.email)) return;            Utils.request(g_BasePath + 'home/createDemoAccount', 'POST', {                name: extraInfo.contactP,                email: extraInfo.email            }, (data) => {                documentInfo = data.documentInfo;                userEmail = extraInfo.email;                userName = extraInfo.contactP;                $('#waiting').show('fast', () => {                    Export_PDF.generateFile(true);                });            }, () => {                Utils.logg('帐户创建失败!请稍后再试', '错误');            });        }    } else {        $('#submit-modal-mess').html(data[1]);        $('#submit-modal').removeClass('fade').show();    }});$('.submit-modal-close').on("click", function () {    $('#submit-modal').addClass('fade').hide();    document.getElementById('main-tabs-tab-Racking').dispatchEvent(new Event('click'));});$('.submit-modal-confirm').on("click", function () {    hideModal('submit-modal');    if (userRole === g_UserRole.Sales) {        showModal('planAddInfo-modal');    } else {        $('#waiting').show('fast', () => {            Export_PDF.generateFile(true);        });    }});function _generateLabels(objectTransforms, text = '', transparency = false, rotationX = Math.PI / 2, rotationY = 0, rotationZ = 0, alpha = 0) {    if (objectTransforms.length === 0)        return null;    const half = parseInt(Math.floor(Math.sqrt(objectTransforms.length)) + 1);    const cellWidth = 64;    const cellHeight = 32;    const dT = new BABYLON.DynamicTexture("DynamicTexture", {        width: cellWidth * half,        height: cellHeight * half    }, scene);    dT.hasAlpha = transparency;    const offsetX = [28, 26, 22, 2];    for (let r = 0; r < half; r++) {        for (let c = 0; c < half; c++) {            let textStr = text + (r * half + c + 1);            if (objectTransforms[r * half + c] && objectTransforms[r * half + c][3]) {                textStr = text + objectTransforms[r * half + c][3];            }            if (transparency === true) {                dT.drawText(textStr, offsetX[textStr.length] + c * cellWidth, 25 + (half - r - 1) * cellHeight, "normal 26px monospace", "#ffffff", null);            } else {                dT.drawText(textStr, offsetX[textStr.length] + c * cellWidth - 3, 27 + (half - r - 1) * cellHeight, "bold 40px monospace", "#adadad", null);                dT.drawText(textStr, offsetX[textStr.length] + c * cellWidth - 0.5, 25.5 + (half - r - 1) * cellHeight, "normal 38px monospace", "#ffffff", null);            }        }    }    const planeBase = new BABYLON.MeshBuilder.CreatePlane("TextPlane", {        width: 1,        height: 1,        sideOrientation: 2    }, scene);    planeBase.isPickable = false;    const mat = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);    mat.emissiveTexture = dT;    mat.emissiveTexture.hasAlpha = true;    mat.opacityTexture = dT;    mat.specularColor = BABYLON.Color3.Black();    mat.freeze();    // planeBase.material = mat;    const SPSLabels = new BABYLON.SolidParticleSystem('SPSLabels', scene);    SPSLabels.addShape(planeBase, objectTransforms.length);    const mesh = SPSLabels.buildMesh();    mesh.material = mat;    if (transparency) {        planeBase.position.y = 0.1;    } else {        planeBase.position.y = 0.05;    }    planeBase.dispose();    SPSLabels.initParticles = function () {        for (let p = 0; p < this.nbParticles; p++) {            this.recycleParticle(this.particles[p]);        }    };    SPSLabels.recycleParticle = function (particle) {        const col = particle.idx % half;        const row = Math.floor(particle.idx / half);        particle.position.x = objectTransforms[particle.idx][0];        particle.position.y = objectTransforms[particle.idx][1] - alpha;        particle.position.z = objectTransforms[particle.idx][2];        particle.rotation.x = rotationX;        particle.rotation.z = rotationY;        particle.rotation.y = rotationZ;        particle.uvs.x = (col * cellWidth) / (cellWidth * half);        particle.uvs.y = (row * cellHeight) / (cellHeight * half);        particle.uvs.z = ((col + 1) * cellWidth) / (cellWidth * half);        particle.uvs.w = ((row + 1) * cellHeight) / (cellHeight * half);    };    SPSLabels.initParticles();    SPSLabels.setParticles();    SPSLabels.refreshVisibleSize();    SPSLabels.computeParticleRotation = false;    SPSLabels.computeParticleTexture = false;    SPSLabels.computeParticleColor = false;    SPSLabels.computeParticleVertex = false;    SPSLabels.mesh.freezeWorldMatrix();    SPSLabels.mesh.freezeNormals();    return SPSLabels;}function clickManualItem(itemId) {    scene.unfreezeActiveMeshes();    tracking(35);    // clear previous added Item features    clearSceneItemManual();    //Add item in scene    selectedItemMesh = addNewItem(manualItemInfo[parseInt(itemId)], "Item-" + manualItemInfo[parseInt(itemId)].name);    const fixedDirection = [        [ITEMDIRECTION.right, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.top, ITEMDIRECTION.bottom, ITEMDIRECTION.left, ITEMDIRECTION.left, ITEMDIRECTION.left, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom],        [ITEMDIRECTION.bottom, ITEMDIRECTION.left, ITEMDIRECTION.bottom, ITEMDIRECTION.left, ITEMDIRECTION.right, ITEMDIRECTION.left, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.left, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom, ITEMDIRECTION.bottom]    ]    if (itemId < 800) {        if (fixedDirection[0][parseInt(itemId)] === undefined) {            console.error('Set fixed direction first');            //TODO: refact this fixed rotation            return;        }        selectedItemMesh.direction = fixedDirection[0][parseInt(itemId)];        if (selectedIcube && !selectedIcube.isHorizontal)            selectedItemMesh.direction = fixedDirection[1][parseInt(itemId)];        selectedItemMesh.rotation.y = parseInt(selectedItemMesh.direction) * Math.PI / 2;    }    currentMesh = selectedItemMesh;    currentMesh.position = new BABYLON.Vector3(-g_WarehouseMaxWidth, 0, -g_WarehouseMaxLength);    startingPoint = null;    if (!currentMesh.ruler) {        currentMesh.ruler = new RulerMItems(currentMesh, scene);        currentMesh.ruler.buttons[0].isClicked = true;        for (let i = 0; i < currentMesh.ruler.buttons.length; i++) {            currentMesh.ruler.buttons[i].isPointerBlocker = false;        }        if (!matManager.matHighLight.hasMesh(currentMesh)) {            Utils.addMatHighLight(currentMesh);        }        setTimeout(() => {            // after object is placed not allow click to go through UI            if (currentMesh && currentMesh.ruler) {                for (let i = 0; i < currentMesh.ruler.buttons.length; i++) {                    currentMesh.ruler.buttons[i].isPointerBlocker = true;                }            }        }, 150);    }}// Selected Item$('.equipment-item').on('click', function () {    clickManualItem($(this).attr("idx"));});/** * * @param {*} meshData * @param {*} name */function addNewItem(meshData, name) {    let item = meshData.originMesh.clone(name);    item.setEnabled(true);    if ([ITEMTYPE.Manual.ContourScanner, ITEMTYPE.Manual.ExteriorStairs].includes(meshData.type)) {        let heightOffset = g_palletHeight;        if (g_palletHeight >= 1)            heightOffset = g_palletHeight - (g_palletHeight - 1) * 0.26;        else            heightOffset = g_palletHeight + (1 - g_palletHeight) * 0.26;        item.scaling.y = heightOffset;        const material = item.material;        if (selectedIcube && g_rackingHighLevel > 2 && meshData.type === ITEMTYPE.Manual.ExteriorStairs) {            for (let i = 1; i < g_rackingHighLevel - 1; i++) {                const aux = meshData.originMesh.clone(meshData.originMesh);                aux.scaling.y = heightOffset;                aux.position.y = (g_palletHeight + g_railHeight) * i;                item = BABYLON.Mesh.MergeMeshes([item, aux], true, true, null, true, true);            }            item.material = material;        }    }    // machine placeholder can be placed at a specific distance    if (parseInt(meshData.type) >= 1000 && meshData.hasOwnProperty('atDist')) {        item.atDist = meshData.atDist;    }    // temporary    if (meshData.type === ITEMTYPE.Manual.RailOutside) {        meshData.atDist = 0;        item.atDist = meshData.atDist;    }    item.name = meshData.name;    item.type = meshData.type;    item.width = meshData.width;    item.height = meshData.height;    item.length = meshData.length;    item.multiply = meshData.multiply;    item.direction = meshData.direction;    item.isPickable = true;    item.actionManager = new BABYLON.ActionManager(scene);    item.actionManager.hoverCursor = "pointer";    item.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOverTrigger, () => {    }));    item.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnLeftPickTrigger, (evt) => {        startingPoint = null;        if (currentMesh) {            if (currentMesh.ruler) {                if (currentMesh.ruler.multiplyPanel && currentMesh.ruler.multiplyPanel.isVisible) {                    onOkNumMultiply(currentMesh.prevDirection);                } else {                    currentMesh.ruler.dispose();                    delete currentMesh.ruler;                }                if (isCtrlPressed) {                    itemsGroup.push(currentMesh);                }            }            if (currentMesh && matManager.matHighLight.hasMesh(currentMesh) && !isCtrlPressed) {                Utils.removeMatHighLight(currentMesh);                removeItemsGroup();            }        }        currentMesh = evt.meshUnderPointer;        if (!currentMesh.ruler) {            currentMesh.ruler = new RulerMItems(item, scene);        }        //Set Highlight Material        if (!matManager.matHighLight.hasMesh(currentMesh)) {            Utils.addMatHighLight(currentMesh);        }        setTimeout(() => {            // after object is placed not allow click to go through UI            if (currentMesh && currentMesh.ruler) {                for (let i = 0; i < currentMesh.ruler.buttons.length; i++) {                    currentMesh.ruler.buttons[i].isPointerBlocker = true;                }            }        }, 150);        if (selectedItemMesh) {            manualItemInfo[parseInt(selectedItemMesh.type)].meshData.push(selectedItemMesh);            Behavior.add(Behavior.type.addItem);            selectedItemMesh = undefined;        }    }));    return item;}function removeItemsGroup(dispose = false) {    if (itemsGroup.length > 0) {        itemsGroup.forEach(element => {            Utils.removeMatHighLight(element);            if (dispose) {                removeItemData(element);                element.dispose();            }        });    }    itemsGroup = [];}// unset current meshfunction unsetCurrentMesh(dispose = false) {    if (currentMesh) {        Utils.removeMatHighLight(currentMesh);        removeItemsGroup();        if (currentMesh.ruler) {            currentMesh.ruler.dispose();            delete currentMesh.ruler;        }        if (dispose) {            removeItemData(currentMesh);            currentMesh.dispose();        }        currentMesh = null;    }}// close gui, unset curentMesh, dispose selectedfunction clearSceneItemManual() {    // Remove selected item if you didn't paste it in the scene    if (selectedItemMesh) {        selectedItemMesh.dispose();        selectedItemMesh = null;    }    if (currentMesh) {        if (currentMesh && currentMesh.ruler && (currentMesh.ruler.multiplyPanel && currentMesh.ruler.multiplyPanel.isVisible)) {            onOkNumMultiply(currentMesh.prevDirection);        } else {            unsetCurrentMesh(false);        }    }}$('#show_tutorial_atFirst').on("click", function () {    switchCamera(currentView);    hideModal("hello-modal");    g_saveBehaviour = false;    if ($('.tab-content').is(':visible'))        $('#main-tabs-tab-Size').trigger('click');    tutorialTour.start(() => {        setProject(currentTemplateType, false);        initData(currentTemplateType);        onBegin();    });});$('#show_tutorial').on("click", function () {    switchCamera(currentView);    g_saveBehaviour = false;    const prevData = {        document_name: documentName,        warehouse_dimensions: [...WHDimensions],        icubeData: [...getIcubeData()],        itemMData: [...getManualItems()],        unit_measurement: unit_measurement,        extraInfo: extraInfo,        extraPrice: [...extraPrice],        measurements: [...getAllMeasurements()],        custom_values: [...custom_values],        layoutMap: {...layoutMap}    }    setProject(Template.values[Template.type.Default], false);    if ($('.tab-content').is(':visible'))        $('#main-tabs-tab-Size').trigger('click');    tutorialTour.start(() => {        setProject(prevData, false);        Behavior.init();    });});function saveTutorial(passed) {    Utils.request(g_BasePath + 'home/tutorial/' + passed, 'POST', {}, null, null);}$("#send_feedback").on("click", function () {    Utils.request(g_BasePath + 'home/sendFeedback', 'POST', {        fmessage: $('#help_feedback').val()    }, (data) => {        if (data)            Utils.logg('反馈已发送!', '成功');    }, null);});$('#gotoRacking').on("click", function () {    document.getElementById('main-tabs-tab-Racking').dispatchEvent(new Event('click'));    $('.tab-content').animate({scrollTop: 0}, 1);});$('#auto-upRightDist').on("click", function () {    if ($(this).hasClass('active-icube-setting')) return;    $('#custom-upRightDist').removeClass('active-icube-setting');    $('#input-upRightDistance').attr('disabled', true);    $(this).addClass('active-icube-setting');});$('#custom-upRightDist').on("click", function () {    if ($(this).hasClass('active-icube-setting')) return;    $('#auto-upRightDist').removeClass('active-icube-setting');    $('#input-upRightDistance').attr('disabled', false);    $(this).addClass('active-icube-setting');});$('#download_it').on("click", function () {    if (selectedIcube)        selectedIcube.software.download();});$('#download_it_wms').on("click", function () {    if (selectedIcube)        selectedIcube.software.download_wms();});$('#accountToCreate').on("click", function () {    const name = $('#nameToCreate').val();    const email = $('#emailToCreate').val();    if (name.length === 0) return;    if (email.length === 0) return;    if (!Utils.validateEmail(email)) return;    Utils.request(g_BasePath + 'home/createAccountSA', 'POST', {        name: name,        email: email    }, (data) => {        if (data === 'Error')            Utils.logg('此用户已存在', '错误');        else            createUsersSAhtml(data);    }, () => {        Utils.logg('帐户创建失败!请稍后再试', '错误');    });});function getUsersSA() {    Utils.request(g_BasePath + 'home/getUsersSA', 'GET', {}, (data) => {        createUsersSAhtml(data);    }, null);}function createUsersSAhtml(data) {    $('#createdAccounts').html('');    for (let i = 0; i < data.length; i++) {        // user data        const sec1 = document.createElement('div');        sec1.style.marginBottom = "5px";        sec1.classList.add("col-sm-12");        const row = document.createElement('div');        row.classList.add("col-sm-9", "padding-no");        row.style.fontWeight = "bold";        row.innerHTML = data[i].email;        sec1.appendChild(row);        const row2 = document.createElement('div');        row2.classList.add("col-sm-3", "padding-no");        row2.style.textAlign = "right";        sec1.appendChild(row2);        const but1 = createUsersSAbut("新建项目", "fa-plus", () => {            if (confirm('是否要将当前布局另存为用户的新项目 ' + data[i].name + '?')) {                documentInfo = data[i].id;                saveProject(() => {                    documentInfo = '';                    setProject(Template.values[Template.type.Default], false);                    setTimeout(() => {                        getUsersSA();                    }, 1000);                });            }        });        row2.appendChild(but1);        if (data[i].projects.length > 0) {            const but0 = createUsersSAbut("Projects list", "fa-bars", () => {                const doc = document.getElementById('slv_' + i);                if (doc.style.display === "none")                    doc.style.display = "block";                else                    doc.style.display = "none";            });            row2.appendChild(but0);        }        $('#createdAccounts').append(sec1);        // list of projects        const sec1a = document.createElement('div');        $(sec1a).attr('id', 'slv_' + i);        sec1a.style.display = "none";        for (let j = 0; j < data[i].projects.length; j++) {            const sec2 = document.createElement('div');            sec2.classList.add("col-lg-12");            sec1a.appendChild(sec2);            const row1 = document.createElement('div');            row1.classList.add("col-sm-6", "padding-no");            row1.innerHTML = (j + 1) + '. ' + data[i].projects[j].document_name;            $(row1).attr('title', data[i].projects[j].saved_time);            sec2.appendChild(row1);            const row2 = document.createElement('div');            row2.classList.add("col-sm-6", "padding-no");            row2.style.textAlign = "right";            sec2.appendChild(row2);            const but1a = createUsersSAbut("重命名", "fa-pencil", () => {                const sceneDocName = data[i].projects[j].document_name;                const projectName = prompt("请输入项目名称:", data[i].projects[j].document_name);                if (projectName == null || projectName == "") {                } else {                    if (documentName == sceneDocName)                        documentName = projectName;                    renameProject(projectName, data[i].projects[j].id);                    setTimeout(() => {                        getUsersSA();                    }, 1000);                }            });            row2.appendChild(but1a);            const but2 = createUsersSAbut("删除", "fa-times", () => {                if (confirm('是否要删除此布局?')) {                    deleteProject(data[i].projects[j].document_name, data[i].id);                    setProject(Template.values[Template.type.Default], false);                    setTimeout(() => {                        getUsersSA();                    }, 1000);                }            });            row2.appendChild(but2);            const but3 = createUsersSAbut("编辑", "fa-edit", () => {                if (confirm('是否要查看/编辑此布局?')) {                    loadProject(data[i].projects[j].document_name, data[i].id);                }            });            row2.appendChild(but3);            const but4 = createUsersSAbut("覆盖", "fa-exchange", () => {                if (confirm('是否用当前布局覆盖此布局?')) {                    documentInfo = data[i].id;                    const docName = documentName;                    documentName = data[i].projects[j].document_name                    saveProject(() => {                        documentInfo = '';                        documentName = docName;                        setProject(Template.values[Template.type.Default], false);                        setTimeout(() => {                            getUsersSA();                        }, 1000);                    });                }            });            row2.appendChild(but4);            const but5 = createUsersSAbut("通知", "fa-envelope", () => {                if (confirm('是否要发送电子邮件通知?')) {                    sendProjectNotify(data[i].projects[j].document_name, data[i].email);                }            });            row2.appendChild(but5);        }        $('#createdAccounts').append(sec1a);        const sec3 = document.createElement('div');        sec3.classList.add("col-lg-12");        const hr = document.createElement('hr');        hr.classList.add("short");        sec3.appendChild(hr);        $('#createdAccounts').append(sec3);    }}function createUsersSAbut(text, faClass, onclick) {    const but = document.createElement('div');    but.classList.add("fa", faClass, "fa_icon2");    $(but).attr('title', text);    but.addEventListener('click', onclick, false);    return but;}$("#uploadedLayout").on("change", function () {    const formData = new FormData($("#uploader").get(0));    Utils.requestFormData(g_BasePath + 'home/uploadCAD_layout', 'POST', formData, (data) => {        if (data.length === 0)            Utils.logg('上传失败!', '错误');        else            Utils.logg('上传完成!', '成功');        if (!layoutMap || (layoutMap && !layoutMap.hasOwnProperty('url')))            layoutMap = {url: '', scale: 1, uOffset: 0, vOffset: 0}        layoutMap.url = data;        layoutMap.scale = 1;        layoutMap.uOffset = 0;        layoutMap.vOffset = 0;        prepareTexture();    });});function prepareTexture() {    if (layoutMap && layoutMap.hasOwnProperty('url')) {        if (layoutMap.url !== '') {            const texture = new BABYLON.Texture(layoutMap.url, scene);            texture.uScale = layoutMap.scale;            texture.vScale = layoutMap.scale;            texture.uOffset = layoutMap.uOffset;            texture.vOffset = layoutMap.vOffset;            texture.wrapU = 0;            texture.wrapV = 0;            /* - to check            //offset the UVs            materialPlane1.diffuseTexture.uOffset = 0.2;            materialPlane1.diffuseTexture.vOffset = -0.2;            //clamp U, V => otherwise the texture will repeat itself while offsetting            materialPlane1.diffuseTexture.wrapV = 0;            materialPlane1.diffuseTexture.wrapU = 0;           */            warehouse.floor.material.albedoTexture = texture;            $('#layoutScale').val(parseFloat(((2 - layoutMap.scale) * 100).toFixed(2)));        } else {            if (warehouse.floor.material.albedoTexture) {                warehouse.floor.material.albedoTexture.dispose();                warehouse.floor.material.albedoTexture = null;            }        }    } else {        if (warehouse.floor.material.albedoTexture) {            warehouse.floor.material.albedoTexture.dispose();            warehouse.floor.material.albedoTexture = null;        }    }    renderScene();}$('#layoutDrawing').on("click", function () {    for (let i = layoutArrows.length - 1; i >= 0; i--) {        layoutArrows[i].dispose();    }    layoutArrows = [];    if ($(this).hasClass('active-icube-setting')) {        $(this).removeClass('active-icube-setting').text("负载建筑图纸(可选)");        $('#uploader').hide();        tracking(38);    } else {        $(this).addClass('active-icube-setting').text("确认放置");        $('#uploader').show();        for (let i = 0; i < 4; i++) {            const arrow = otherItemInfo[ITEMTYPE.Other.PortArrow].originMesh.createInstance('inst_' + i);            arrow.rotationQuaternion = null;            arrow.scaling.y = 0.001;            if (i % 2 === 0) {                arrow.position.x = (i === 0 ? -1 : 1) * warehouse.width / 1.8;                arrow.rotation.y = (i === 0 ? -Math.PI / 2 : Math.PI / 2);            } else {                arrow.position.z = (i === 1 ? -1 : 1) * warehouse.length / 1.8;                arrow.rotation.y = (i === 1 ? Math.PI : 0);            }            arrow.actionManager = new BABYLON.ActionManager(scene);            arrow.actionManager.hoverCursor = "pointer";            arrow.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOverTrigger, () => {            }));            arrow.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickDownTrigger, (evt) => {                if (!layoutMap) return;                switch (i) {                    case 0:                        layoutMap.uOffset += 0.1;                        break;                    case 1:                        layoutMap.vOffset += 0.1;                        break;                    case 2:                        layoutMap.uOffset -= 0.1;                        break;                    case 3:                        layoutMap.vOffset -= 0.1;                        break;                }                if (warehouse.floor.material.albedoTexture) {                    warehouse.floor.material.albedoTexture.uOffset = layoutMap.uOffset;                    warehouse.floor.material.albedoTexture.vOffset = layoutMap.vOffset;                }            }));            layoutArrows.push(arrow);        }        warehouse.update(WHDimensions);    }    renderScene(4000);});function createPassThList() {    $('#passthroughList').html('');    if (selectedIcube) {        for (let j = 0; j < selectedIcube.activedPassthrough.length; j++) {            const sec2 = document.createElement('div');            sec2.style.display = "inline-flex";            sec2.classList.add("col-lg-12");            $(sec2).attr('id', 'pass' + j);            const row1 = document.createElement('div');            row1.classList.add("col-lg-12");            row1.style.overflow = "hidden";            row1.innerHTML = 'Passthrough' + (j + 1);            sec2.appendChild(row1);            const but3 = createUsersSAbut("Edit", "fa-edit", () => {                $('#set-icube-passthrough').addClass('active-icube-setting').text("确认放置");                selectedIcube.property['passthrough'].selectors.forEach((item) => {                    item.dispose();                });                selectedIcube.property['passthrough'].selectors = [];                selectedIcube.showSelectors(0, j);                selectedIcube.showSelectors(1, j);                selectedIcube.showSelectors(2, j);            });            sec2.appendChild(but3);            const but2 = createUsersSAbut("Delete", "fa-times", () => {                selectedIcube.activedPassthrough.splice(j, 1);                selectedIcube.updateRacking();                Behavior.add(Behavior.type.addPassthrough);                createPassThList();                renderScene();            });            sec2.appendChild(but2);            const hr = document.createElement('hr');            hr.classList.add("short");            sec2.appendChild(hr);            $('#passthroughList').append(sec2);        }    }}function optimizeDistrCalculation(id, type) {    let sum = 0;    for (let i = 0; i < type.length; i++) {        sum += type[i];    }    const diff = (sum > 100 || sum < 100) ? sum - 100 : 0;    if (diff !== 0) {        switch (parseInt(id)) {            case 0:                if (type[1] !== 0 && type[2] !== 0) {                    if (diff < 0) {                        type[1] += Math.abs(diff);                    } else {                        if (type[1] >= diff) {                            type[1] -= diff;                        } else {                            const diff2 = diff - type[1];                            type[1] = 0;                            type[2] -= diff2;                        }                    }                } else if (type[1] !== 0) {                    type[1] = type[1] + (diff > 0 ? -1 : 1) * Math.abs(diff);                } else if (type[2] !== 0) {                    type[2] = type[2] + (diff > 0 ? -1 : 1) * Math.abs(diff);                } else {                    type[1] = Math.abs(diff);                }                break;            case 1:                if (type[0] !== 0 && type[2] !== 0) {                    if (diff < 0) {                        type[0] += Math.abs(diff);                    } else {                        if (type[0] >= diff) {                            type[0] -= diff;                        } else {                            const diff2 = diff - type[0];                            type[0] = 0;                            type[2] -= diff2;                        }                    }                } else if (type[0] !== 0) {                    type[0] = type[0] + (diff > 0 ? -1 : 1) * Math.abs(diff);                } else if (type[2] !== 0) {                    type[2] = type[2] + (diff > 0 ? -1 : 1) * Math.abs(diff);                } else {                    type[0] = Math.abs(diff);                }                break;            case 2:                if (type[0] !== 0 && type[1] !== 0) {                    if (diff < 0) {                        type[0] += Math.abs(diff);                    } else {                        if (type[0] >= diff) {                            type[0] -= diff;                        } else {                            const diff2 = diff - type[0];                            type[0] = 0;                            type[1] -= diff2;                        }                    }                } else if (type[0] !== 0) {                    type[0] = type[0] + (diff > 0 ? -1 : 1) * Math.abs(diff);                } else if (type[1] !== 0) {                    type[1] = type[1] + (diff > 0 ? -1 : 1) * Math.abs(diff);                } else {                    type[0] = Math.abs(diff);                }                break;        }    }    return type;}$('#customLastRow').on("click", function () {    if ($('#lastLSetting').is(':visible')) {        visibility = false    } else {        visibility = true    }    $('#lastLSetting').css('display', (visibility ? 'block' : 'none'));    $('#input-pallet-height').attr('disabled', visibility);    $('#input-pallet-height').next().children().attr('disabled', visibility);    $('#input-pallet-weight').attr('disabled', visibility);    $('#input-pallet-weight').next().children().attr('disabled', visibility);});function updateInputPallet(idx, palletIdx) {    const value1 = $('#palletL_' + idx + '_' + palletIdx).val();    const value2 = $('#palletL_' + (1 - idx) + '_' + palletIdx).val();    let atLevelIdx = -1;    for (let i = 0; i < g_palletAtLevel.length; i++) {        if (g_palletAtLevel[i].idx === palletIdx) {            atLevelIdx = i;            break;        }    }    if (idx === 0) {        const tempH = parseFloat(value1);        const max = parseFloat((WHDimensions[2] - g_bottomLength - g_railHeight - (g_rackingHighLevel - 1) * parseFloat(g_palletHeight + g_railHeight)).toFixed(2));        if (tempH > max) {            $('#palletL_' + idx + '_' + palletIdx).val(max);        }        if (atLevelIdx !== -1) {            if (value1 === g_palletHeight && value2 === g_palletWeight) {                g_palletAtLevel.splice(atLevelIdx, 1);            } else {                g_palletAtLevel[atLevelIdx].height = value1            }        } else {            g_palletAtLevel.push({                idx: palletIdx,                height: value1,                weight: value2            });        }        updateRackingAtLevel();        Behavior.add(Behavior.type.palletHeight);    } else {        if (atLevelIdx !== -1) {            if (value1 === g_palletWeight && value2 === g_palletHeight) {                g_palletAtLevel.splice(atLevelIdx, 1);            } else {                g_palletAtLevel[atLevelIdx].weight = value1            }        } else {            g_palletAtLevel.push({                idx: palletIdx,                height: value2,                weight: value1            });        }        updateRackingAtLevel(false);        Behavior.add(Behavior.type.palletWeight);    }}function updateRackingAtLevel(updateProps = true) {    if (updateProps) {        updateRackingHighLevel();        updateSelectedIcube();    } else {        if (selectedIcube) {            selectedIcube.palletAtLevel = g_palletAtLevel;        }    }}$('#spacing_b_rows').on("change", function (event) {    g_spacingBetweenRows = parseFloat(event.target.value);    if (selectedIcube) {        selectedIcube.updateDistanceBetweenRows();        selectedIcube.getEstimationPrice();    }});$('#start_sim').on("click", function () {    if (simulation) {        updateSimulation(simulation);        const carrierList = document.getElementById('carriersHolder');        carrierList.childNodes.forEach(function (carrier) {            carrier.removeChild(carrier.childNodes[0]);        });        simulation.remove();        simulation = null;        $(this).text('开始');        $('#pause_sim').hide();    } else {        document.getElementById("liftsHolder").innerHTML = '';        document.getElementById("carriersHolder").innerHTML = '';        simulation = new Simulation({            input: parseInt(document.querySelector('input[id="simIn"]').value),            output: parseInt(document.querySelector('input[id="simOut"]').value),            //mixed     : (document.querySelector('input[name="simMixed"]:checked') ? true : false),            process: parseInt(document.querySelector('select[name="simProces"]').value),            strategy: parseInt(document.querySelector('select[name="simStrat"]').value),            multiply: parseInt(document.querySelector('select[name="simSpeed"]').value),            liftAssign: parseInt(document.querySelector('select[name="simLiftA"]').value),            sharePath: (document.querySelector('input[name="simHandoff"]:checked') ? true : false),            isReply: false,            onEnd: () => {                // console.log('done');                tracking(15);                endSimulation();            }        });        if (simulation.error !== '') {            simulation.remove();            simulation = null;        } else {            tracking(14);            Behavior.add(Behavior.type.playAnimation);            saveSimulation(simulation);            $(this).text('停止');            $('#pause_sim').text('暂停').show();        }    }});$('select[name="simSpeed"]').on("change", function () {    if (simulation)        simulation.multiply = parseInt($(this)[0].value);});$('#pause_sim').on("click", function () {    if (simulation.isPlaying) {        simulation.pause();        $(this).text('重新');    } else {        simulation.resume();        $(this).text('暂停');    }});$('#simMultipleView').on("change", function () {    g_simMultipleView = $(this).is(":checked");    toggleMultipleView();});$('#addPriceRow').on("click", function () {    if (!$('#extraPriceTable')[0]) {        const tab = `<table id="extraPriceTable" class="table itemTable table-responsive-lg table-bordered table-striped table-sm mb-0" style="margin-top: 10px;">      <colgroup>        <col width="30%">        <col width="8%">        <col width="10%">        <col width="3%">      </colgroup>      <tbody></tbody>    </table>`;        document.getElementById("extraPriceHolder").innerHTML = tab;    }    const info = `<tr id="extraP_` + extraPrice.length + `">    <td><input class="epName" type="text" style="width:100%" /></td>    <td><input class="epQuantity" type="number" style="width:100%;text-align:right" value="0" /></td>    <td><input class="epValue" type="number" style="width:100%;text-align:right"  value="0" /></td>    <td><button style="width:100%;font-size:10px;padding:0" onclick="saveExtraPrice(` + extraPrice.length + `)">Save</button></td>  </tr>`;    $('#extraPriceTable tbody').append(info);});function updateExtraPriceTable() {    let price = 0;    $("#extraPriceHolder").html('');    if (Array.isArray(extraPrice) && extraPrice.length > 0) {        if (!$('#extraPriceTable')[0]) {            const tab = `<table id="extraPriceTable" class="table itemTable table-responsive-lg table-bordered table-striped table-sm mb-0" style="margin-top: 10px;">        <colgroup>          <col width="30%">          <col width="8%">          <col width="10%">          <col width="1%">        </colgroup>        <tbody></tbody>      </table>`;            document.getElementById("extraPriceHolder").innerHTML = tab;        }        extraPrice.forEach((extra, idx) => {            price += parseFloat(extra.quantity) * parseFloat(extra.value);            const info = `<tr id="extraP_` + idx + `">        <td class="epName">` + extra.name + `</td>        <td class="epQuantity" style="text-align:right">` + formatIntNumber(extra.quantity) + `</td>        <td class="epValue" style="text-align:right">€` + formatIntNumber(extra.value) + `</td>        <td style="text-align:right"><i class="fa fa-trash" title="Delete custom row" onclick="deleteExtraPrice(` + idx + `)"></i></td>      </tr>`;            $('#extraPriceTable tbody').append(info);        });    }    return price;}function saveExtraPrice(idx) {    const name = $("#extraP_" + idx + " > td > .epName")[0].value    const qty = $("#extraP_" + idx + " > td > .epQuantity")[0].value    const val = $("#extraP_" + idx + " > td > .epValue")[0].value    extraPrice.push({        name: name,        quantity: qty,        value: val    });    tracking(42);    saveProject(() => {        if (selectedIcube !== null) {            selectedIcube.getEstimationPrice();        }    });}function deleteExtraPrice(idx) {    extraPrice.splice(idx, 1);    tracking(43);    saveProject(() => {        if (selectedIcube !== null) {            selectedIcube.getEstimationPrice();        }    });}$("#viewer2d_it").on("click", function () {    const doc = document.getElementById('itHelper');    const canvas = $("#itHelper > canvas")[0];    if (doc.style.display === "none") {        doc.style.display = "block";        if (it3DEngine) {            it3DEngine.dispose();            it3DEngine = null;        }        it2DEngine = create2DViewerIt(canvas);    } else {        doc.style.display = "none";        if (it2DEngine) {            it2DEngine.dispose();            it2DEngine = null;        }    }});$("#viewer3d_it").on("click", function () {    const doc = document.getElementById('itHelper');    const canvas = $("#itHelper > canvas")[0];    if (doc.style.display === "none") {        doc.style.display = "block";        if (it2DEngine) {            it2DEngine.dispose();            it2DEngine = null;        }        it3DEngine = create3DViewerIt(canvas);    } else {        doc.style.display = "none";        if (it3DEngine) {            it3DEngine.dispose();            it3DEngine = null;        }    }});$('#submit-rating-btn').on("click", function () {    const stars = $('input[name=rating_star]:checked').val();    if (isNaN(parseFloat(stars))) {        $(this).parent().append('<p>Please choose a rating star</p>');        setTimeout(() => {            const list = document.getElementById("submit-rating-btn").parentNode;            list.removeChild(list.lastChild);        }, 2000);        return;    }    const comm = $('#rating_comment').val();    const agent = $('#rating_agent').is(":checked");    let data = {        stars: stars,        comm: comm,        agent: agent,        complete: 1    }    Utils.request(g_BasePath + 'home/rating', 'POST', data, () => {        Utils.logg('反馈已成功发送!', '成功');        hideModal('rating-modal');    }, () => {        alert("反馈失败!请稍后再试。");    });});$('#manualItem-placeholder').on("change", function () {    $('#placeholder_data').toggle();});$('#add-placeholder').on("click", function () {    let maxKey = manualItemInfo.indexOf(manualItemInfo[manualItemInfo.length - 1]);    if (maxKey < 1000)        maxKey = 1000;    else        maxKey = maxKey + 1;    createFakeManualItem({        type: maxKey,        name: $('#machine_name').val(),        width: parseFloat($('#machine_width').val()),        length: parseFloat($('#machine_length').val()),        height: parseFloat($('#machine_height').val()),        colors: $('#machine_color').val(),        atDist: parseFloat($('#machine_atDist').val())    });    clickManualItem(maxKey);});function createFakeManualItem(params) {    const itemInfo = {        display: params.name,        name: params.name,        type: params.type,        direction: ITEMDIRECTION.bottom,        multiply: (params.length + 0.2),        width: params.width,        length: params.length,        height: params.height,        meshData: [],        originMesh: null,        colors: params.colors,        atDist: params.atDist    }    let faceUV = new Array(6);    for (let i = 0; i < 6; i++) {        faceUV[i] = new BABYLON.Vector4(0, 0, 0, 0);    }    faceUV[4] = new BABYLON.Vector4(0, 0, 1, 1);    const placeholder = BABYLON.MeshBuilder.CreateBox(itemInfo.display, {        height: 1,        width: 1,        depth: 1,        faceUV: faceUV    }, scene);    placeholder.position.y = 1 / 2;    placeholder.bakeCurrentTransformIntoVertices();    placeholder.setEnabled(false);    placeholder.isPickable = false;    placeholder.scaling = new BABYLON.Vector3(itemInfo.width, itemInfo.height, itemInfo.length);    placeholder.freezeWorldMatrix();    const DTWidth = itemInfo.width * 120;    const DTHeight = itemInfo.length * 120;    const albedoText = new BABYLON.DynamicTexture("dynamic texture", {width: DTHeight, height: DTWidth}, scene, false);    const ctx = albedoText.getContext();    const size = 12;    ctx.font = size + "px Arial";    const textWidth = ctx.measureText(itemInfo.display).width;    const ratio = textWidth / size;    let font_size = Math.floor(Math.min(DTWidth, DTHeight) / ratio);    font_size = font_size < 100 ? font_size : font_size / 2;    const font = parseInt(font_size) + "px Arial";    albedoText.drawText(itemInfo.display, null, null, font, "white", itemInfo.colors);    const placeholderM = new BABYLON.PBRMaterial("placeholderM", scene);    placeholderM.albedoTexture = albedoText;    placeholderM.alpha = 0.5;    placeholderM.roughness = 1;    placeholderM.freeze();    placeholder.material = placeholderM;    itemInfo.originMesh = placeholder;    manualItemInfo[params.type] = itemInfo;}$('#add-people').on("click", function () {    clickManualItem(899);});$('.fa-question-circle').on("mouseenter", function () {    document.getElementById($(this)[0].dataset.info).style.display = 'block';}).on("mouseout", function () {    document.getElementById($(this)[0].dataset.info).style.display = 'none';});$('#add-pdfPage').on("click", function () {    const items = `    <div class="form-group mb10" style="text-align:center;">      <label class="col-sm-1 control-label padding-no labelpad">` + parseInt(custompPdf.length + 1) + `</label>      <input class="col-sm-5 form-control" style="width:41%;" type="text" placeholder="Title" value="" onchange="addTitleToPage(this, ` + custompPdf.length + `)">      <button class="icube-tool btn btn-primary col-sm-5" onclick="addScreenToPage(this, ` + custompPdf.length + `)">Add image</button>      <label class="col-sm-1 control-label padding-no labelpad" style="text-align:center;cursor:pointer;" onclick=removeFromPage(` + custompPdf.length + `)><i class="el fa fa-trash" href="#"></i></label>    </div>`;    $('#pdfPages').append(items);    custompPdf.push({title: '', image: ''});});$('#gen-pdf').on("click", function () {    $('#waiting').show('fast', () => {        Export_PDF.generateCustomFile();        tracking(39);    });});function addTitleToPage(elem, page) {    custompPdf[page].title = $(elem).val();}function addScreenToPage(elem, page) {    scene.render();    BABYLON.Tools.CreateScreenshot(scene.getEngine(), scene.activeCamera, {width: 1440, height: 870}, function (data) {        custompPdf[page].image = data;        renderScene();        $(elem).html('Add image <i class="el fa fa-check"></i>');    });}function removeFromPage(page) {    custompPdf.splice(page, 1);    $('#pdfPages').html('');    for (let i = 0; i < custompPdf.length; i++) {        const items = `      <div class="form-group mb10" style="text-align:center;">        <label class="col-sm-1 control-label padding-no labelpad">` + parseInt(i + 1) + `</label>        <input class="col-sm-5 form-control" style="width:41%;" type="text" placeholder="Title" onchange="addTitleToPage(this, ` + i + `)" value="` + custompPdf[i].title + `">        <button class="icube-tool btn btn-primary col-sm-5" onclick="addScreenToPage(this, ` + i + `)">Add image ` + (custompPdf[i].image !== '' ? `<i class="el fa fa-check"></i>` : ``) + `</button>        <label class="col-sm-1 control-label padding-no labelpad" style="text-align:center;cursor:pointer;" onclick=removeFromPage(` + i + `)><i class="el fa fa-trash" href="#"></i></label>      </div>`;        $('#pdfPages').append(items);    }}$('#add-measurement').on("click", function () {    g_measureEnabled = !g_measureEnabled;    clickableItems(!g_measureEnabled);});$('#settingsModeS1').on("click", function () {    $('#advancedSettings01').hide();    $('#advancedSettings11').hide();    $('#advancedSettings12').hide();    $('#simpleSettings12').show();    if ($('#lastLSetting').is(':visible')) {        $('#customLastRow').trigger('click');    }    $('#customLastRow').attr('disabled', true);    if (!$(this).hasClass('active-icube-setting')) {        $(this).addClass('active-icube-setting');    }    if ($("#settingsModeA1").hasClass('active-icube-setting')) {        $("#settingsModeA1").removeClass('active-icube-setting');    }    if (!$('#settingsModeS2').hasClass('active-icube-setting')) {        $('#settingsModeS2').trigger('click');    }});$('#settingsModeA1').on("click", function () {    $('#advancedSettings01').show();    $('#advancedSettings11').show();    $('#advancedSettings12').show();    $('#simpleSettings12').hide();    $('#customLastRow').attr('disabled', false);    if (!$(this).hasClass('active-icube-setting')) {        $(this).addClass('active-icube-setting');    }    if ($("#settingsModeS1").hasClass('active-icube-setting')) {        $("#settingsModeS1").removeClass('active-icube-setting');    }    if (!$('#settingsModeA2').hasClass('active-icube-setting')) {        $('#settingsModeA2').trigger('click');    }});$('#settingsModeS2').on("click", function () {    $('#advancedSettings22').hide();    $('#set-icube-charger').hide();    $('#set-icube-liftpreloading').hide();    if (!$(this).hasClass('active-icube-setting')) {        $(this).addClass('active-icube-setting');    }    if ($("#settingsModeA2").hasClass('active-icube-setting')) {        $("#settingsModeA2").removeClass('active-icube-setting');    }    if (!$('#settingsModeS1').hasClass('active-icube-setting')) {        $('#settingsModeS1').trigger('click');    }});$('#settingsModeA2').on("click", function () {    $('#advancedSettings22').show();    $('#set-icube-charger').show();    $('#set-icube-liftpreloading').show();    if (!$(this).hasClass('active-icube-setting')) {        $(this).addClass('active-icube-setting');    }    if ($("#settingsModeS2").hasClass('active-icube-setting')) {        $("#settingsModeS2").removeClass('active-icube-setting');    }    if (!$('#settingsModeA1').hasClass('active-icube-setting')) {        $('#settingsModeA1').trigger('click');    }});$('#palletSize').on("click", function () {    $('.palletSizeList').toggle();});$(".palletSizeList li").on("click", function () {    tracking(41);    $(this).parent().hide();    const colors = ['#3bf582', '#fc3f3f', '#d2fa41'];    $('#palletSize > span').css('color', colors[$(this).index()]);    $('#palletSize > label').html($(this).children('label').text());    updateDistrPallet($(this).index(), 100);});$('#searchProject').on("keyup", function (e) {    const value = e.target.value;    $('.list-group').children().show();    if (value === '') return;    $('.list-group').children().filter(function () {        return $(this)[0].children[0].innerHTML.toLowerCase().indexOf(value.toLowerCase()) === -1;    }).hide();});$("#optimizeRacking").on("click", function () {    if (selectedIcube)        selectedIcube.optimizeRacking();    tracking(34);});$('.dupl').on("click", function () {    const key = parseInt($(this).attr("control"));    if (key === 5) {        $('#duplicate-tab').hide();    } else {        if (key === 4) {            multiplyIcube();            $('#duplicate-tab').hide();        } else {            duplData[1] = key;            $('.dupl').css('color', '#ffffff');            $(this).css('color', '#333333');        }    }});$('.dupl2').on("click", function () {    const key = parseInt($(this).attr("control"));    duplData[3] = key === 6 ? true : false;    $('.dupl2').css('color', '#ffffff');    $(this).css('color', '#333333');});$('#dupl_distance').on("change", function () {    duplData[0] = parseFloat(event.target.value);});$('input[name="optimize"]').on("change", function (event) {    g_optimizeDirectTL = !!parseInt(event.target.value);});$('#revisions').on("click", function () {    $('#revisions_list').toggle();});function getRevisions(data, index = -1) {    Utils.request(g_BasePath + 'home/getRevisions', 'POST', data, (data) => {        revisions = data;        $('#revisions_list').html('');        if (data.length > 0) {            for (let i = 0; i < data.length; i++) {                let div = ``, clas = ``;                if (index !== -1) {                    if (i === index) clas = `btn-primary`;                } else {                    if (i === data.length - 1) clas = `btn-primary`;                }                if (i === data.length - 1) {                    div = `            <div class="price_rev ` + clas + `" style="display:inline-flex;">                                 <span onclick="loadVersion(` + i + `)" title="` + data[i].saved_time + `" style="overflow:hidden;min-width:150px;">` + documentName + ` - Latest</span>                               </div>`;                } else {                    div = `            <div class="price_rev ` + clas + `" style="display:inline-flex;">              <i class="fa fa-pencil" onclick="editRevisionName(this)" title="Rename" style="line-height:24px;"></i>                              <span onclick="loadVersion(` + i + `)" title="` + data[i].saved_time + `" style="overflow:hidden;min-width:150px;">` + data[i].name + `</span>              <input class="price_rev_input hide" value="` + data[i].name + `" onchange="updateVersionName(this, ` + i + `)" onfocusout="cancelRevisionEdit(this)" />                              <i class="fa fa-times" onclick="deleteVersion(` + i + `)" title="Delete" style="line-height:24px;"></i>            </div>`;                }                $('#revisions_list').append(div);            }        } else {            $('#revisions_list').append('<div style="padding: 5px;">No previous versions</div>');        }    }, null);}function updateVersionName(elem, versionIdx) {    cancelRevisionEdit(elem);    $(elem).prev().html($(elem).val());    Utils.request(g_BasePath + 'home/renameVersion', 'POST', {        saved_time: revisions[versionIdx].saved_time,        name: $(elem).val()    });}function deleteVersion(versionIdx) {    $('#revisions_list').children().eq(versionIdx).remove();    Utils.request(g_BasePath + 'home/deleteVersion', 'POST', {        saved_time: revisions[versionIdx].saved_time    }, () => {        let data = {            document_name: documentName        }        if (documentInfo > 0) {            data = Object.assign({}, data, {slid: documentInfo});        }        loadVersion(revisions.length - 2);    });}function loadVersion(versionIdx) {    const docData = JSON.parse(revisions[versionIdx].documentData);    let icubeData = JSON.parse(revisions[versionIdx].icubeData);    if (!icubeData || !Array.isArray(icubeData)) icubeData = [];    icubeData.forEach((icube) => {        for (key in icube) {            if (!['name', 'uid'].includes(key)) {                icube[key] = JSON.parse(icube[key]);            }        }    });    const data = {        extraInfo: JSON.parse(docData.extraInfo),        extraPrice: JSON.parse(docData.extraPrice),        measurements: JSON.parse(docData.measurements),        custom_values: JSON.parse(docData.custom_values),        documentInfo: (isEditByAdmin) ? documentInfo : "",        document_name: revisions[versionIdx].document_name,        itemMData: JSON.parse(docData.itemMData),        layoutMap: JSON.parse(docData.layoutMap),        unit_measurement: JSON.parse(docData.unit_measurement),        warehouse_dimensions: JSON.parse(docData.warehouse_dimensions),        icubeData: icubeData    }    setProject(data, true, versionIdx);    if (versionIdx < revisions.length - 1) {        $('#project-name').html((revisions[versionIdx].hasOwnProperty('name') ? revisions[versionIdx].name : documentName));    }}function editRevisionName(elem) {    $(elem).next().addClass('hide');    $(elem).next().next().removeClass('hide').focus();}function cancelRevisionEdit(elem) {    $(elem).addClass('hide');    $(elem).prev().removeClass('hide');}$("#newProject").on("click", function () {    $(".new-modal-close").hide();    showModal("new-modal");    hideModal("hello-modal");    g_tutorialIsRunning = false;});$("#loadProject").on("click", function () {    getProjectList(function (datas) {        $(".load-modal-close").hide();        createProjectList(datas);        hideModal("hello-modal");        g_tutorialIsRunning = false;    });});$(".checkbox-dropdown").on("click", function () {    $(this).toggleClass("is-active");});$(".checkbox-dropdown ul").on("click", function (e) {    e.stopPropagation();});$("#send_report").on("click", function () {    showModal("report-modal");});$(".report-modal-close").on("click", function () {    hideModal("report-modal");});$('.report-modal-confirm').on("click", async function () {    const formData = new FormData();    formData.append("documentName", documentName);    formData.append("name", $("#reportName").val());    formData.append("description", $("#reportDesc").val());    const image = await BABYLON.Tools.CreateScreenshotAsync(scene.getEngine(), scene.activeCamera, {        width: 1600,        height: 1000    });    formData.append("screenshot", image);    for (let i = 0; i < $("#reportFile")[0].files.length; i++) {        formData.append("file_" + i, $("#reportFile")[0].files[i]);    }    Utils.requestFormData(g_BasePath + "home/saveReport", "POST", formData);    Utils.logg("错误报告已发送!", "成功");    hideModal("report-modal");});$("#configVariables").on("click", function () {    if (custom_values[0] && custom_values[0] !== -1) {        $("#var_palletWidth").val(custom_values[0]);    }    if (custom_values[1] && custom_values[1] !== -1) {        $("#var_palletLength").val(custom_values[1]);    }    if (custom_values[2] && custom_values[2] !== -1) {        $("#var_palletOverhang").val(custom_values[2]);    }    if (custom_values[3] && custom_values[3] !== -1) {        $("#var_railHeight").val(custom_values[3]);    }    if (custom_values[4] && custom_values[4] !== -1) {        $("#var_distToXtrack").val(custom_values[4]);    }    if (custom_values[5] && custom_values[5] !== -1) {        $("#var_distToMargin").val(custom_values[5]);    }    if (custom_values[6] && custom_values[6] !== -1) {        $("#var_distTo1stStore").val(custom_values[6]);    }    if (custom_values[7] && custom_values[7] !== -1) {        $("#var_distToNextStore").val(custom_values[7]);    }    showModal("configVariables-modal");});$(".configVariables-modal-close").on("click", function () {    hideModal("configVariables-modal");});$(".configVariables-modal-confirm").on("click", function () {    const var_distToNextStore = parseFloat($("#var_distToNextStore").val());    const var_distTo1stStore = parseFloat($("#var_distTo1stStore").val());    const var_distToMargin = parseFloat($("#var_distToMargin").val());    const var_distToXtrack = parseFloat($("#var_distToXtrack").val());    const var_railHeight = parseFloat($("#var_railHeight").val());    const var_palletOverhang = parseFloat($("#var_palletOverhang").val());    const var_palletLength = parseFloat($("#var_palletLength").val());    const var_palletWidth = parseFloat($("#var_palletWidth").val());    custom_values = [        isNaN(var_palletWidth) ? -1 : var_palletWidth,        isNaN(var_palletLength) ? -1 : var_palletLength,        isNaN(var_palletOverhang) ? -1 : var_palletOverhang,        isNaN(var_railHeight) ? -1 : var_railHeight,        isNaN(var_distToXtrack) ? -1 : var_distToXtrack,        isNaN(var_distToMargin) ? -1 : var_distToMargin,        isNaN(var_distTo1stStore) ? -1 : var_distTo1stStore,        isNaN(var_distToNextStore) ? -1 : var_distToNextStore    ];    updateConfigVariables();    hideModal("configVariables-modal");    $('#customValue').html(custom_values.length > 0 ? `<b>⚠ This project contains custom values ⚠</b>` : ``);});function updateConfigVariables() {    const palletIdx = g_palletInfo.max;    const sum = custom_values.filter(e => e === -1);    if (sum.length === custom_values.length) {        custom_values = [];    }    resetConfigVariables();    if (custom_values[0] && custom_values[0] > 800 && custom_values[0] < 1400) {        g_PalletW[palletIdx] = useP(custom_values[0], false);    }    if (custom_values[1] && custom_values[1] > 1000 && custom_values[1] < 1400) {        g_PalletH[palletIdx] = useP(custom_values[1], false);    }    if (custom_values[2] && custom_values[2] >= 0 && custom_values[2] <= 200) {        g_palletOverhang = parseFloat((custom_values[2] / 1000).toFixed(4));    }    if (custom_values[3] && custom_values[3] >= 0 && custom_values[3] <= 1000) {        g_railHeight = useP(custom_values[3], false);    }    if (custom_values[4] && custom_values[4] >= 0 && custom_values[4] <= 500) {        g_difftoXtrack[palletIdx] = useP(custom_values[4], false);    }    if (custom_values[5] && custom_values[5] >= 0 && custom_values[5] <= 500) {        g_diffToEnd[palletIdx] = useP(custom_values[5], false);        g_railOutside = g_diffToEnd[palletIdx];    }    if (custom_values[6] && custom_values[6] >= 0 && custom_values[6] <= 500) {        g_bottomLength = useP(custom_values[6], false);    }    if (custom_values[7] && custom_values[7] >= 0 && custom_values[7] <= 500) {        g_StoreTopGap = useP(custom_values[7], false);    }    g_palletInfo.type = g_palletInfo.value;    updateSelectedIcube();}function resetConfigVariables() {    g_PalletW = [0.8, 1, 1.2];    g_PalletH = [1.2, 1.2, 1.2];    g_palletOverhang = 0.05;    g_difftoXtrack = [0.15, 0.05, 0.05];    g_diffToEnd = [0.175, 0.175, 0.175];    g_railOutside = 0.175;    g_railHeight = 0.38;    g_bottomLength = 0.27;    g_StoreTopGap = 0;    g_palletInfo.type = g_palletInfo.value;}
 |