/* eslint-disable */

/**
 * Generated by Verge3D Puzzles v.4.10.0
 * Fri, 12 Dec 2025 20:14:14 GMT
 * Prefer not editing this file as your changes may get overridden once Puzzles are saved.
 * Check out https://www.soft8soft.com/docs/manual/en/introduction/Using-JavaScript.html
 * for the information on how to add your own JavaScript to Verge3D apps.
 */
function createPL(v3d = window.v3d) {

// global variables used in the init tab
const _initGlob = {
    percentage: 0,
    output: {
        initOptions: {
            fadeAnnotations: true,
            useBkgTransp: false,
            preserveDrawBuf: false,
            useCompAssets: false,
            useFullscreen: true,
            useCustomPreloader: false,
            preloaderStartCb: function() {},
            preloaderProgressCb: function() {},
            preloaderEndCb: function() {},
        },
    },
};


// global variables/constants used by puzzles' functions
var _pGlob = {};

_pGlob.objCache = new Map();
_pGlob.fadeAnnotations = true;
_pGlob.pickedObject = '';
_pGlob.hoveredObject = '';
_pGlob.mediaElements = {};
_pGlob.loadedFile = '';
_pGlob.states = [];
_pGlob.percentage = 0;
_pGlob.openedFile = '';
_pGlob.openedFileMeta = {};
_pGlob.xrSessionAcquired = false;
_pGlob.xrSessionCallbacks = [];
_pGlob.screenCoords = new v3d.Vector2();
_pGlob.intervalTimers = {};
_pGlob.customEvents = new v3d.EventDispatcher();
_pGlob.eventListeners = [];
_pGlob.htmlElements = new Set();
_pGlob.materialsCache = new Map();

_pGlob.AXIS_X = new v3d.Vector3(1, 0, 0);
_pGlob.AXIS_Y = new v3d.Vector3(0, 1, 0);
_pGlob.AXIS_Z = new v3d.Vector3(0, 0, 1);
_pGlob.MIN_DRAG_SCALE = 10e-4;
_pGlob.SET_OBJ_ROT_EPS = 1e-8;

_pGlob.vec2Tmp = new v3d.Vector2();
_pGlob.vec2Tmp2 = new v3d.Vector2();
_pGlob.vec3Tmp = new v3d.Vector3();
_pGlob.vec3Tmp2 = new v3d.Vector3();
_pGlob.vec3Tmp3 = new v3d.Vector3();
_pGlob.vec3Tmp4 = new v3d.Vector3();
_pGlob.eulerTmp = new v3d.Euler();
_pGlob.eulerTmp2 = new v3d.Euler();
_pGlob.quatTmp = new v3d.Quaternion();
_pGlob.quatTmp2 = new v3d.Quaternion();
_pGlob.colorTmp = new v3d.Color();
_pGlob.mat4Tmp = new v3d.Matrix4();
_pGlob.planeTmp = new v3d.Plane();
_pGlob.raycasterTmp = new v3d.Raycaster(); // always check visibility

const createPzLib = ({ v3d=null, appInstance=null }) => {
    function transformCoordsSpace(coords, spaceFrom, spaceTo, noSignChange=false) {
    
        if (spaceFrom === spaceTo) {
            return coords;
        }
    
        const y = coords.y;
        const z = coords.z;
    
        if (spaceFrom === 'Z_UP_RIGHT' && spaceTo === 'Y_UP_RIGHT') {
            coords.y = z;
            coords.z = noSignChange ? y : -y;
        } else if (spaceFrom === 'Y_UP_RIGHT' && spaceTo === 'Z_UP_RIGHT') {
            coords.y = noSignChange ? z : -z;
            coords.z = y;
        } else {
            console.error('transformCoordsSpace: Unsupported coordinate space');
        }
    
        return coords;
    }
        
    function getSceneCoordSystem() {
        const scene = appInstance.scene;
        if (scene && 'coordSystem' in scene.userData) {
            return scene.userData.coordSystem;
        }
    
        return 'Y_UP_RIGHT';
    }
        
    function isObjectWorthProcessing(obj) {
        return obj.name !== '' &&
                !(obj.isMesh && obj.isMaterialGeneratedMesh) &&
                !obj.isAuxClippingMesh;
    }
        
    function getObjectByName(objName) {
        let objFound = null;
    
        // COMPAT: <4.9.0, old engine, new puzzles
        const isID = v3d.MathUtils.checkUUID ? v3d.MathUtils.checkUUID(objName) : false;
    
        const pGlobAvailable = _pGlob !== undefined;
        if (pGlobAvailable)
            objFound = _pGlob.objCache.get(objName);
    
        if (objFound && (isID ? objFound.uuid === objName : objFound.name === objName))
            return objFound;
    
        function findValidByName(obj, objName) {
            if ((isID ? obj.uuid === objName : obj.name === objName) && isObjectWorthProcessing(obj))
                return obj;
    
            for (let i = 0; i < obj.children.length; i++) {
                const child = obj.children[i];
                const object = findValidByName(child, objName);
                if (object !== null)
                    return object;
            }
    
            return null;
        }
    
        if (appInstance.scene) {
            objFound = findValidByName(appInstance.scene, objName);
            if (objFound && pGlobAvailable)
                _pGlob.objCache.set(objName, objFound);
        }
    
        return objFound;
    }
        
    function getObjectNamesByGroupName(groupName) {
        const objNameList = [];
        appInstance.scene.traverse(obj => {
            if (isObjectWorthProcessing(obj)) {
                const objGroupNames = obj.groupNames;
                if (!objGroupNames) {
                    return;
                }
    
                for (let i = 0; i < objGroupNames.length; i++) {
                    const objGroupName = objGroupNames[i];
                    if (objGroupName === groupName) {
                        objNameList.push(obj.name);
                    }
                }
            }
        });
        return objNameList;
    }
        
    function getAllObjectNames() {
        const objNameList = [];
        appInstance.scene.traverse(obj => {
            if (isObjectWorthProcessing(obj)) {
                objNameList.push(obj.name);
            }
        });
        return objNameList;
    }
        
    function retrieveObjectNamesAccum(currObjNames, namesAccum) {
        if (typeof currObjNames === 'string') {
            namesAccum.push(currObjNames);
        } else if (Array.isArray(currObjNames) && currObjNames[0] === 'GROUP') {
            const newObjNames = getObjectNamesByGroupName(currObjNames[1]);
            for (let i = 0; i < newObjNames.length; i++) {
                namesAccum.push(newObjNames[i]);
            }
        } else if (Array.isArray(currObjNames) && currObjNames[0] === 'ALL_OBJECTS') {
            const newObjNames = getAllObjectNames();
            for (let i = 0; i < newObjNames.length; i++) {
                namesAccum.push(newObjNames[i]);
            }
        } else if (Array.isArray(currObjNames)) {
            for (let i = 0; i < currObjNames.length; i++) {
                retrieveObjectNamesAccum(currObjNames[i], namesAccum);
            }
        }
    }
        
    function retrieveObjectNames(objNames) {
        const accum = [];
        retrieveObjectNamesAccum(objNames, accum);
        return accum.filter(name => name !== '');
    }

    return {
        transformCoordsSpace, getSceneCoordSystem, getObjectByName, retrieveObjectNames,
    };
};

var PL = {};



// backward compatibility
if (v3d[Symbol.toStringTag] !== 'Module') {
    v3d.PL = v3d.puzzles = PL;
}

PL.procedures = PL.procedures || {};




PL.execInitPuzzles = function(options) {
    // always null, should not be available in "init" puzzles
    var appInstance = null;
    // app is more conventional than appInstance (used in exec script and app templates)
    var app = null;

    const PzLib = createPzLib({ v3d });

    // provide the container's id to puzzles that need access to the container
    _initGlob.container = options !== undefined && 'container' in options
            ? options.container : "";

    

    
    return _initGlob.output;
}

PL.init = function(appInstance, initOptions) {

// app is more conventional than appInstance (used in exec script and app templates)
var app = appInstance;

const PzLib = createPzLib({ v3d, appInstance });

initOptions = initOptions || {};

if ('fadeAnnotations' in initOptions) {
    _pGlob.fadeAnnotations = initOptions.fadeAnnotations;
}



// applyObjLocalTransform puzzle
function applyObjLocalTransform(objSelector, mode, vector) {

    var objNames = PzLib.retrieveObjectNames(objSelector);
    var x = vector[0] || 0;
      var y = vector[1] || 0;
      var z = vector[2] || 0;

    var defValue = mode == "scale" ? 1 : 0;
    if (typeof x != "number") x = defValue;
    if (typeof y != "number") y = defValue;
    if (typeof z != "number") z = defValue;

    var coords = PzLib.transformCoordsSpace(_pGlob.vec3Tmp.set(x, y, z),
            PzLib.getSceneCoordSystem(), 'Y_UP_RIGHT', mode == 'scale');

    for (var i = 0; i < objNames.length; i++) {
        var objName = objNames[i];
        if (!objName) continue;

        var obj = PzLib.getObjectByName(objName);
        if (!obj) continue;

        // don't transform values for cameras, their local space happens
        // to be the same as for Blender/Max cameras, bcz their different
        // rest orientation balances difference in coordinate systems
        var useTransformed = !obj.isCamera;
        var xVal = useTransformed ? coords.x : x;
        var yVal = useTransformed ? coords.y : y;
        var zVal = useTransformed ? coords.z : z;

        switch (mode) {
        case "position":
            if (_pGlob.xrSessionAcquired && obj.isCamera) {
                v3d.WebXRUtils.translateVRCamera(obj, _pGlob.AXIS_X, xVal);
                v3d.WebXRUtils.translateVRCamera(obj, _pGlob.AXIS_Y, yVal);
                v3d.WebXRUtils.translateVRCamera(obj, _pGlob.AXIS_Z, zVal);
            } else {
                obj.translateX(xVal);
                obj.translateY(yVal);
                obj.translateZ(zVal);
            }
            break;
        case "rotation":
            if (_pGlob.xrSessionAcquired && obj.isCamera) {
                v3d.WebXRUtils.rotateVRCamera(obj, _pGlob.AXIS_X, v3d.MathUtils.degToRad(xVal));
                v3d.WebXRUtils.rotateVRCamera(obj, _pGlob.AXIS_Y, v3d.MathUtils.degToRad(yVal));
                v3d.WebXRUtils.rotateVRCamera(obj, _pGlob.AXIS_Z, v3d.MathUtils.degToRad(zVal));
            } else {
                obj.rotateX(v3d.MathUtils.degToRad(xVal));
                obj.rotateY(v3d.MathUtils.degToRad(yVal));
                obj.rotateZ(v3d.MathUtils.degToRad(zVal));
            }
            break;
        case "scale":
            obj.scale.x *= xVal;
            obj.scale.y *= yVal;
            obj.scale.z *= zVal;
            break;
        }

        obj.updateWorldMatrix(false, true);
    }
}


applyObjLocalTransform('PKR-Blade', 'rotation', [-(285), '', '']);



} // end of PL.init function

PL.disposeListeners = function() {
    if (_pGlob) {
        _pGlob.eventListeners.forEach(({ target, type, listener, optionsOrUseCapture }) => {
            target.removeEventListener(type, listener, optionsOrUseCapture);
        });
        _pGlob.eventListeners.length = 0;
    }
}

PL.disposeHTMLElements = function() {
    if (_pGlob) {
        _pGlob.htmlElements.forEach(elem => {
            elem.remove();
        });
        _pGlob.htmlElements.clear();
    }
}

PL.disposeMaterialsCache = function() {
    if (_pGlob) {
        for (const mat of _pGlob.materialsCache.values()) {
            mat.dispose();
        }
        _pGlob.materialsCache.clear();
    }
}

PL.dispose = function() {
    PL.disposeListeners();
    PL.disposeHTMLElements();
    PL.disposeMaterialsCache();
    _pGlob = null;
    // backward compatibility
    if (v3d[Symbol.toStringTag] !== 'Module') {
        delete v3d.PL;
        delete v3d.puzzles;
    }
}



return PL;

}

export { createPL };
