
/*=================================================================================================
 * MARI HOME   ---------------"--<@
 *-------------------------------------------------------------------------------------------------
 * @코드 명칭 : 마리 멀티 업로더 ( 가제 ) 
 * @요약 정보 : 파일 등록시 타입에 따른 추가 속성을 등록하거나, 불러올때 필요한 속성만을 가져온다
 * @파일 이름 : multi_uploader_setDataAttribute.js
 * @웹용 주소 : 글쓰기등 업로드가 필요한 곳, 파일 탐색기와 같이 파일 미리보기가 필요한 곳에서 외부 파일(js파일)로 호출됨 
 * @호출 파일 : multi_uploader_code.js에 스프레드 연산자로 등록되어 호출됨
 * @서버 위치 : 마리홈 ( ),  그누보드 ( plugin/multi_uploader/ )
 * @소스 제작 : repter ( 예뜨락 ), 홈페이지 ( https://marihome.net ) 
 * @제작 날짜 : 2023.08.01 ( 최초 제작 시작일 )
 * @소스 설명 : 각 타입별로 세분화하고 등록된 파일의 속성을 정형화하는데 사용한다:: 몇가지만 차단하고 올리는 블랙 정책보다는
 *           검수된 선밸적 파일만 올리는 화이트 정책이 보다 보안에는 용이하므로 이러한 속성을 사용한다
 *           파일 유형이 추가되면 그에 따른 속성분류 또한 setDataAttr_image와 같이 해줘야 한다
 * @기타 사항 : 당분간 필요한 업그레이드를 통해서 소스 변경이 자주 일어날 수 있습니다 
 *           자바스크립트 형태 : 객체 리터럴 ( Object Literal )
 *           변수 => 프로퍼티 (Property)   : 프로퍼티 값
 *           함수 => 메서드 (Method)
 * @최종 수정 : 2025.03.26
 * @버전 명시 : 0.9
 *-------------------------------------------------------------------------------------------------
 * Copyright 2023. repter All Rights Reserved.
**===============================================================================================*/ 

// 글로벌 변수 지정
if(typeof(window.MARI) === "undefined") { (function(global) { global.MARI = {}; })(window || global); }
if(typeof(window.MARI.file_uploder) === "undefined") { (function(global) { global.MARI.file_uploder = {}; })(window || global); }

/*=========================================================================================
 * 1. 파일 업로더시 데이터에 관련된 유틸
**----------------------------------------------------------------------------------------*/
if(typeof(window.MARI.file_uploder.setData) === "undefined") {
	MARI.file_uploder.setData  = {

        /*===============================================
         * 리스트 속성 리턴, 스피너 페이드 아웃
        **----------------------------------------------*/ 
        setAttrReturn : function(eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_util  = MARI.file_uploder.util;
            let obj_this  = MARI.file_uploder.code; 
            let objLang   = MARI.file_uploder.langObj[obj_this.country];  // 언어 객체에서 선택된 언어 가져오기
            let li_obj    = obj_this.li_obj(eq_idx);
            let lastIdx   = (objType === 'Modify') ? aryIndex : li_obj.length - 1;
            let getDatas  = obj_this.getFileInfo2(eq_idx, objType, aryIndex, 'All', '150'); // 데이터  
            let doms = obj_this.listAttrDomReturn(eq_idx, lastIdx); // 리스트의 속성값을 넣어야할 html돔 정보
            let imgs = new Image();          // 이미지 객체 생성

            // 이미지와 그렇지 않은 경우로 나누어 처리 
            let ext      = obj_util.getFileExtension(getDatas.dataPicture);// 확장자만 가져온다
            let isImg    = obj_util.isImageFile(ext); 
            let thumbPic = getDatas.dataPicture; // 사진 주소를 넣어준다  
            if(isImg === false){ 
 			     thumbPic = obj_this.moduleUrl +'/images/file_type1/'+getDatas.dataExt+'.png';  // 이미지외엔 확장자 썸네일 이미지
            } 

            imgs.src = thumbPic; // 사진 주소를 넣어준다  
            if( doms.thumbnailDiv ){
                imgs.addEventListener('load', function() { 
                    obj_this.listAttrSetReturn(eq_idx, this, getDatas, doms, listIdx);
                    obj_this.spinnerFadeOut(eq_idx, listIdx); // 스피너를 감춘다
                }); 
                imgs.addEventListener('error', function() {
                    // 이미지 로드 실패 시 수행할 작업
                    obj_this.log('썸네일 이미지 로드 실패');
                    obj_this.listAttrSetReturn(eq_idx, this, getDatas, doms, listIdx);
                    obj_this.spinnerFadeOut(eq_idx, listIdx); // 스피너를 감춘다 (실패 시에도)
                    // 필요한 추가적인 오류 처리 로직을 여기에 추가
                });
            }

        },

        /*=========================================================================================
         *  ※ 파일을 사용하기 위한 등록
         *  다음의 세군데에서 등록이 이뤄져야 파일 업로드가 된다
         *  obj_this.add_atribute     :: ( multi_uploader_code.js )
         *  obj_this.file_preview_act :: ( multi_uploader_dragAction.js)
         *  obj_this.setDataAttr_flac :: ( multi_uploader_setDataAttribute.js)
        **---------------------------------------------------------------------------------------*/ 

        /*===============================================
         * mp3 셋팅 :: 썸네일 추출::보강이 많이 필요한 부분 ( 만들것 )
        **----------------------------------------------*/ 
        setDataAttr_mp3_img : function(eq_idx, objType, aryIndex, info_Ary, listIdx){// 썸네일 생성
            // 비동기 함수를 호출하여 파일 처리 시작  
            let obj_this   = MARI.file_uploder.code;  
            return false;

        },
        
        /*===============================================
         * 텍스트 데이터 셋팅 :: 썸네일 추출::보강이 많이 필요한 부분
        **----------------------------------------------*/ 
        setDataAttr_mp4_img : function(eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_util = MARI.file_uploder.util;
            let obj_this = MARI.file_uploder.code; 
            let objLang  = MARI.file_uploder.langObj[obj_this.country];  // 언어 객체에서 선택된 언어 가져오기
            let li_obj   = obj_this.li_obj(eq_idx);
            let lastIdx  = (objType === 'Modify') ? aryIndex : li_obj.length - 1;
            let getDatas = obj_this.getFileInfo2(eq_idx, objType, aryIndex, 'All', '94'); // 데이터  
            let doms     = obj_this.listAttrDomReturn(eq_idx, lastIdx); // 리스트의 속성값을 넣어야할 html돔 정보
            // 비디오 요소 가져오기 
            let loaderMain = obj_this.loader_main_obj(eq_idx); 
            let video      = li_obj[aryIndex].querySelector('.list_video'); // 비디오 플레이어

            // 캔버스 생성 및 설정
            const canvas          = document.createElement("canvas");
            canvas.id             = 'canvas' + eq_idx;
            canvas.style.width    = video.videoWidth;
            canvas.style.height   = video.videoHeight;
            canvas.style.position = 'absolute';
            canvas.style.top      = - 10000 + 'px';
            canvas.style.left     = - 10000 + 'px';

            document.body.appendChild(canvas); // body에 캔버스 추가
            const context = canvas.getContext("2d"); 
            if(video){
                video.src = getDatas.dataFileSrc;
                video.addEventListener("loadeddata", () => {
                    video.currentTime = 5; // 2초 지점의 프레임을 캡처
                });

                video.addEventListener("seeked",(event) => {
                    canvas.style.display  = 'none';
                    canvas.width  = video.videoWidth;
                    canvas.height = video.videoHeight;
                    context.drawImage(video, 0, 0, canvas.width, canvas.height);
                    canvas.toBlob((blob) => {
                        let thumbnail = URL.createObjectURL(blob);
                        let info_Ary  = {};
                        info_Ary['dataPicture']   = thumbnail;
                        info_Ary['dataThumbnail'] = thumbnail;
                        info_Ary['dataTempIdx']   = getDatas.dataTempIdx;  
                        let datas = obj_this.setFileInfo(event, eq_idx, objType, aryIndex, info_Ary);   // 데이터 셋팅 후 데이터를 리턴 

                        obj_this.log(getDatas); 
                        // 리스트 속성 리턴, 스피너 페이드 아웃
                        obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
                    });
                });
            }

        },

        /*===============================================
         * 이미지 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_image : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx);
        },
 
        /*===============================================
         * mp3 데이터 셋팅
        **----------------------------------------------*/ 
        //setDataAttr_mp3 : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
        //    let obj_this  = MARI.file_uploder.code; 
        //    obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx);
        //},

        setDataAttr_mp3 : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            // 비동기 함수를 호출하여 파일 처리 시작  
            //processFile(event, objType, eq_idx, aryIndex, info_Ary); 

            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx);
        },
 
        /*===============================================
         * mp4 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_mp4 : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx);
        },

        /*===============================================
         * txt 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_txt : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx);
        },

        /*===============================================
         * html 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_html : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx);
        },
 
        /*===============================================
         * pdf 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_pdf : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },
 
        /*===============================================
         * hwpx 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_hwpx : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },
 
        /*===============================================
         * hwp 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_hwp : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },

        /*===============================================
         * webm 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_webm : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },
 
        /*===============================================
         * flac 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_flac : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },

        /*===============================================
         * zip 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_zip : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },
        
        /*===============================================
         * tar 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_tar : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },

        /*===============================================
         * 7z 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_7z : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },

        /*===============================================
         * asf 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_asf : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },

        /*===============================================
         * xlsx 데이터 셋팅
        **----------------------------------------------*/ 
        setDataAttr_xlsx : function(event, eq_idx, objType, aryIndex, info_Ary, listIdx){
            let obj_this  = MARI.file_uploder.code;
            obj_this.setAttrReturn(eq_idx, objType, aryIndex, info_Ary, listIdx); 
        },
 






        // 파일 읽기가 완료된 시점이니 스피너를 감춘다 새로운 리스트 호출은 new_file_add 루프에서 한다 
        spinnerFadeOut : function(eq_idx2, listIdx){
            let obj_util      = MARI.file_uploder.util;
            let obj_this      = MARI.file_uploder.code;
            let eq_idx        = obj_this.event_eq(event);             //사용 가능하게 설정된 업로더에서의 인덱스 
            let li_obj        = obj_this.li_obj(eq_idx2);
            let oneList       = li_obj[listIdx];
 
            // 파일 읽기가 완료된 시점이니 스피너를 감춘다 새로운 리스트 호출은 new_file_add 루프에서 한다 
            if(oneList){ 
                let spinner = oneList.querySelector('.spinner_cover');
                let content = oneList.querySelector('.contentDiv');
                // 다수의 리스트에 사용할때 느려지는 경향이 있어서 css로 대체
                spinner.classList.add('off'); 
                content.classList.add('on');
            }
        },


        // 리스트 관련 추가 데이터를 넣어주고  필요한 html 속성을 넣어서 html을 완성 한다
        // 예:이미지 관련 데이터 추가 ( 로드된 시점 이후 알수 있는 정보들 )
        listAttrSetReturn : function(eq_idx, objThis, datas, doms, listIdx){
            let obj_util    = MARI.file_uploder.util;
            let obj_this    = MARI.file_uploder.code; 
            let list_shape  = obj_this.list_shape[eq_idx]; 
            let loaderMain  = obj_this.loader_main_obj(eq_idx);  
            let ext         = obj_util.getFileExtension(datas.dataPicture);// 확장자만 가져온다
            let isImg       = obj_util.isImageFile(ext); 
            let thumbPic    = datas.dataPicture; // 사진 주소를 넣어준다  
            
            if(isImg === false ){
                if(datas.dataMakeType === "Modify"){ 
 			        thumbPic = obj_this.moduleUrl +'/images/file_type1/'+ext+'.png';  // 저장된 확장자 썸네일 이미지
                } 
                if(datas.dataMakeType === "New"){ 
 			        thumbPic = datas.dataThumbnail;  // 새로운 업로드일 때 확장자 썸네일 이미지
                } 
            }
            
       //썸네일을 만든다     
            
            datas.dataThumbnail        = thumbPic;// 이미지 파일이면 이미지를 아니면 확장자 이미지를
            datas.dataImgWidth         = datas.dataImgWidth;
            datas.dataImgHeight        = datas.dataImgHeight;// 이미지 높이
            // html에 내용을 넣어준다
            doms.fileIconDiv.src       = datas.dataIcon;          // 파일 아이콘    
            doms.thumbnailDiv.src      = datas.dataThumbnail;     // 리스트의 썸네일 이미지를 넣는다
            doms.fileNameDiv.innerHTML = datas.dataFileName;      // 파일 이름 
            doms.fileTypeDiv.innerHTML = datas.dataFileType2;     // 파일 유형
            doms.modifiedDiv.innerHTML = datas.dataModifyDate;    // 수정한 날짜
            doms.fileSizeDiv.innerHTML = datas.dataFileSize;      // 파일 크기 표기 ( Mb or Kb ) 
            doms.picSizeDiv.innerHTML  = datas.dataImgWidth + ' x ' + datas.dataImgHeight; // 사진 크기
            if(obj_this.fileIconUse === 'No' && ( list_shape !== 'shape4' || list_shape !== 'shape5' || list_shape !== 'shape6' || list_shape !== 'shape7' || list_shape !== 'shape8')){   
            //  loaderMain.querySelector('.file_icon').style.display = 'none'; 
                doms.fileIconDiv.style.display = 'none'; 
            } else {
                doms.fileIconDiv.removeAttribute('style');
            }
            // 현재 라인에서 가장 높은 이미지의 높이에 맞춰 나머지 높이를 맞춘다 :: 첫 돔 생성시  
            obj_this.equalizeImageHeights(eq_idx, 'listAttr', list_shape, listIdx); 

        },

        // 리스트의 속성값을 넣어야할 html돔 정보를 리턴한다
        listAttrDomReturn : function(eq_idx, listIdx){
            let obj_util = MARI.file_uploder.util;
            let obj_this = MARI.file_uploder.code; 
            let li_obj   = obj_this.li_obj(eq_idx);
            let oneList  = li_obj[listIdx];
            if (oneList) {
                let doms = {
                    thumbnailDiv : oneList.querySelector('.upload_thumb'), 
                    fileIconDiv  : oneList.querySelector('.file_icon'),
                    fileNameDiv  : oneList.querySelector('.file_name'),
                    fileTypeDiv  : oneList.querySelector('.file_type_in > em'),
                    fileSizeDiv  : oneList.querySelector('.file_size_in > em'),
                    picSizeDiv   : oneList.querySelector('.file_pic_size_in > em'),
                    modifiedDiv  : oneList.querySelector('.modified_date_in > em'),    
                };
                return doms;
            } else {
                return false;
            }

        },


		/*=========================================================================================
         * 현재까지의 데이터 저장 상태를 보구 싶을 때 사용
         * console.log(obj_this.nowDatas(newFile[tempNum])); // 배열 상태 출력
		**---------------------------------------------------------------------------------------*/
        nowDatas : function(infoObj){
            let resultObj = {}; 
            if (infoObj && typeof infoObj === 'object') {
                Object.keys(infoObj).forEach(key => {
                    if (!(infoObj[key] instanceof File)) { // File 객체는 제외 ( 덮어 씌우기시 오류 )
                        resultObj[key] = infoObj[key];
                    }
                });
            }

            return resultObj;//JSON.stringify(resultObj, null, 4);
        },


		/*=========================================================================================
		 * 리스트에 파일 데이터 속성을 넣어줌
		 *    event, objType, eq_idx2, listIdx, info_Ary 
         *    listIdx 0,1,2,3  0,1,2... 0,1,2... 와 같이 새로 담을 때 마다 0부터 인덱스 시작
         *    새로 추가시 ::: init -> changeEvent -> newFileAdd    -> newAddDom    -> listAddDom
         *    수정 추가시 ::: init ->      ->     -> modifyFileAdd -> modifyAddDom -> listAddDom 
         *
         *    주의 사항  ::: 타입에 따른 modify, new를 접근시 배열 인덱스 번호로 해당 개체들의 정보를 셋팅하게 되는데 들어올때
         *                listIdx 는 그대로 사용하게 되므로 함수 밖에서 배열 인덱스를 맞춰서 함수의 인자로 넣어준다
		**---------------------------------------------------------------------------------------*/
		/* 파일 데이터 속성을 넣어줌 */ 
        setFileInfo : function(event, eq_idx, objType, listIdx, info_Ary){ 
            /*==============================================
             * ※ 데이터 호출시 주의 사항 :: 2024-10-13(일) ※
             *    - 업로더에 리스트 돔이 생성되기 이전 :: 배열 인덱스를 받아서 직접 찾는다
             *       - 새로운 파일
             *            업로드중 파일  -> temp_Ary   ( 사용할 때 마다 새로 담긴다 ) 
             *       - 수정용 파일
             *            서버 저장 파일 -> modifyFile ( 서버에 저장되어 있는 수정용 파일 ) 
             *
             *    - 업로더에 리스트 돔이 생성되기 이후 :: 리스트의 데이터코드를 참고해서 배열을 찾는다 
             *       - 새로운 파일
             *            업로드중 파일  -> temp_Ary   ( 사용할 때 마다 새로 담긴다 => 진행중 )
             *            업로드한 파일  -> newFile    ( 새로운 파일을 누적을 시킨다 => 완료한 )
             *       - 수정용 파일
             *            서버 저장 파일 -> modifyFile ( 서버에 저장되어 있는 수정용 파일 )
             *
             * ======== 추후 소스 개량할 것 2025-03-18(화) ========
            **---------------------------------------------*/
            let obj_util   = MARI.file_uploder.util; 
            let obj_this   = MARI.file_uploder.code;  
            let objLang    = MARI.file_uploder.langObj[obj_this.country];  // 언어 객체에서 선택된 언어 가져오기  
            let li_obj     = obj_this.li_obj(eq_idx);
            let tempAry    = MARI.file_uploder.code.temp_Ary[eq_idx] || null;  // 파일 업로드 시 리셋되는 임시 배열
            let dTaAry     = MARI.file_uploder.code.dTa_Ary[eq_idx] || null;   // New, Modify 데이터가 담기는 배열
            let newFile    = dTaAry?.new_files?.files || null;                 // New 파일이 담기는 배열
            let modifyFile = dTaAry?.modify_files || null;                     // Modify 파일이 담기는 배열
            let savedFile  = modifyFile_Ary[eq_idx]?.file_ary || null;         // 1.서버에 저장된 수정용 파일

            /*=================================================================================
             * ※ 업로더에서 제일 중요한 부분 이부분에 의해 전체적인 데이터가 영향을 받는다
             * - 리스트 로드 되기전에는 배열 인덱스에 직접, 리스트가 돔에 로드된 이후에는 li_obj를 이용해서 dataCodes를 통해
             *   인텍스를 가져와 배열에 접근
             *   2.새로 업로드된 파일
            **---------------------------------------------*/
            let dataCodes = null;
            // 최종 데이터 코드 ::: 항상 마지막으로 저장된 변수의 값을 덮어씌움  
            if (objType === 'Add') {           // 새로 받아 템프에 있는 파일
                dataCodes = newFile?.[listIdx]?.dataCode;
            } else if (objType === 'New') {    // 새로 받으면 템프는 리셋 되므로 새로 받기 이전의 새로 받아둔 파일들 
                dataCodes = newFile?.[listIdx]?.dataCode; 
            } else if (objType === 'Modify') { // 서버에서 저장된 파일들
                dataCodes = savedFile?.[listIdx]?.dataCode;
            }

            /*==============================================
             * ※ 데이터 호출시 주의 사항 :: 2024-10-13(일) ※
             * ※ 리스트의 데이터 코드를 통해서 인덱스를 얻어서 찾고
             * ※ 없으면 데이터의 데이터 코드를 통해서 접근한다
            **---------------------------------------------*/ 
            if(dataCodes === null){
               // alert('setFileInfo::'+ listIdx +'|'+ modifyFile.length +'dataCodes값을 찾을수 없습니다1');
                alert(objLang.txt601(listIdx, modifyFile.length));
                return false;
            }

            let datas;
            if (objType === 'Add') {
                datas = tempAry[info_Ary.dataTempIdx]; // MARI.file_uploder.code.temp_Ary[0]
            } else if (objType === 'New') {
                datas = newFile[listIdx];              // MARI.file_uploder.code.dTa_Ary[0].new_files.files
            } else if (objType === 'Modify') {
                datas = modifyFile[listIdx]; 
            } 

            // 기본 datas에 외부에서 들어온 info_Ary를 합해서 하나의 객체를 만든다 
            if (!(datas && typeof datas === 'object')) {
                //alert( listIdx +' datas 객체가 유효하지 않습니다.'); 
                alert(objLang.txt602(listIdx));
                return false;
            }

            // 파일명 관련 데이터 추가
         	let dataExt          = datas.dataExt;
            let ext              = file_ext_list[obj_this.country][dataExt] || '알수 없음';  // file_ext_list => mime_types.js

            // ※ 저장시 이를 적극 활용해서 바뀐 데이터를 넘긴다
            datas.dataExt        = datas.dataExt; //  
 			datas.dataFileType2  = `${ext.toUpperCase()} ( ${dataExt} )`;
 			datas.dataFileType3  = `유형 : <em>${ext === '알수 없음' ? dataExt : ext}${!file_ext_list[obj_this.country][dataExt] ? ' ( 알수 없음 )' : ''}</em>`;
            datas.dataFileSrc    = (objType === 'New' || objType === 'Add') 
                                 ? URL.createObjectURL(datas)
                                 : datas.dataFileSrc; //modifyData
             // 이미지 관련
 			datas.dataExtImg     = obj_this.moduleUrl +'/images/file_type1/'+datas.dataExt+'.png';  // 확장자 썸네일 이미지
 			datas.dataIcon       = obj_this.moduleUrl +'/images/file_kind/'+datas.dataExt+'.gif'; // 파일 아이콘
            datas.dataPicture    = datas.dataPicture;
            datas.dataThumbnail  = datas.dataPicture;
             
            
            
            /*
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
  
//            let thumbnailMake = obj_this.createThumbnail(datas.dataPicture, function (result) { 
////                datas.dataPicture.dataThumbnail  = result.thumbnailUrl;// 
////                datas.dataPicture.dataPicture    = result.pictureUrl;  
////                datas.dataPicture.pictureWidth   = result.pictureWidth; // 원본 이미지 너비
////                datas.dataPicture.pictureHeight  = result.pictureHeight;// 원본 이미지 너비  
//            });  
       //     datas.dataThumbnail  =  thumbnailMake;  
            
  
                        
//        class FileHandler {
//            async urlToFile(url, fileName = "image.jpg") {
//                const response = await fetch(url);
//                const blob = await response.blob();
//                return new File([blob], fileName, { type: blob.type });
//            }
//
//            async processFile(url) {
//                const file = await this.urlToFile(url);
//                console.log(file); // File 객체 출력
//            }
//        }
//
//        const handler = new FileHandler();
//        const thumbFile = handler.processFile(datas.dataPicture);
//                        
//        console.log( thumbFile );
        
        
        
        
                
        async function getFileFromUrl(url, fileName = "image.jpg") {
            const response = await fetch(url);
            const blob = await response.blob();
            return new File([blob], fileName, { type: blob.type });
        }

        function createThumb(imgUrl) {
            return getFileFromUrl(imgUrl);
        }
        
//        let thumbfile;
//        (async () => {
//            let thumbfile = await createThumb(datas.dataPicture);
//           // console.log(thumbfile);
//        })();
//                
//        
//        console.log( thumbfile );
//        
//        
//        
        
        



let thumbfile;
async function fetchThumbFile() {
    thumbfile = await createThumb(datas.dataPicture);
     console.log(thumbfile);  // 파일 객체 출력
}

(async () => {
    await fetchThumbFile();
    console.log(thumbfile);  // 비동기 작업이 끝난 후 값 확인
})();

*/









//        let thumbnailMake = obj_this.createThumbnail(thumbFile, function (result) { 
//            thumbFile.dataThumbnail  = result.thumbnailUrl;// 
//            thumbFile.dataPicture    = result.pictureUrl;  
//            thumbFile.pictureWidth   = result.pictureWidth; // 원본 이미지 너비
//            thumbFile.pictureHeight  = result.pictureHeight;// 원본 이미지 너비  
//        });  
//           datas.dataThumbnail  =  thumbnailMake;    
                
                
                
                
                
                
//        // 함수 실행 예시
//        let thumbUrl = '';
//        const url = datas.dataPicture;
//        obj_util.generateFileWithThumbnail(url).then(result => {
//            console.log(result.file); // 원본 파일
//            console.log(result.thumbnail); // 썸네일 파일 
//            thumbUrl = result.thumbnail;
//        }); 
//        datas.dataThumbnail = thumbUrl;                    
//        console.log( datas.dataThumbnail );   
                   
                   
































            
            datas.dataImgWidth   =  datas.dataImgWidth  ? datas.dataImgWidth  : datas.pictureWidth;
            datas.dataImgHeight  =  datas.dataImgHeight ? datas.dataImgHeight : datas.pictureHeight; 

            // 날짜 관련  datas.last_modified => 1130685152000
 	 	 	datas.lastModified   = new Date(parseInt(datas.last_modified));  // Mon Oct 31 2005 00:12:32 GMT+0900 (한국 표준시) 
 	 		datas.dataModifyDate = obj_util.dateFormat(datas.lastModified);  // 날짜 형식을 취한 형태 ( 2005-10-31(월) 오전 12:12 )  

            // 사이즈 관련 
            let dataSize         = datas.size;                        // 파일 크기이면서 바이트
            let dataByte         = datas.size;                        // 바이트이면서 파일크기
            let dataByteSize     = dataSize;                          // 바이트
            let dataKbSize0      = dataByte / 1024;                   // 킬로바이트  obj_util.bite_to_killo(datas.size);
            let dataMbSize0      = dataByte / (1024 ** 2);            // 메가바이트 obj_util.bite_to_mega(dataSize); 
            let dataKbSize       = obj_util.bite_to_killo(datas.size);// 자릿수 맞춘 킬로바이트
            let dataMbSize       = obj_util.bite_to_mega(dataSize);   // 자릿수 맞춘 메가바이트
            let dataGbSize       = dataByte / (1024 ** 3); // 기가바이트
            let dataTbSize       = dataByte / (1024 ** 4); // 테라바이트
            let dataFileSize     = ( dataKbSize > 1000 ) ? dataMbSize+'MB' : dataKbSize+'KB'; // 표기 파일 크기

            //사이즈 관련 데이터 추가
 			datas.dataSize       = dataSize;       // 데이터 사이즈   ( 바이트로 표기 원본 숫자로만 173187 )
 			datas.dataFileSize   = dataFileSize;   // 사이즈 표기, 메가바이트 또는 킬로 바이트로 표기 ( "169.12KB" )
 			datas.dataByteSize   = dataByteSize;   // 바이트로만 표기
 			datas.dataKbSize     = dataKbSize;     // 킬로 바이트로만 소숫점 이하 두자리 까지 표기   169.12
 			datas.dataMbSize     = dataMbSize;     // 메가 바이트로만 소숫점 이하 두자리 까지 표기
 			datas.dataGbSize     = dataGbSize;     // 기가 바이트로만 소숫점 이하 두자리 까지 표기
 			datas.dataTbSize     = dataTbSize;     // 테라 바이트로만 소숫점 이하 두자리 까지 표기

            // 기본 datas에 외부에서 들어온 info_Ary를 합해서 하나의 객체를 만든다  기존에 있는 데이터라면 덮어 씌우기를 해야 하기에 아래에서 호출
            if (datas && typeof datas === 'object') {
                Object.keys(info_Ary).forEach(key => { 
                    datas[key] = info_Ary[key]; // 존재하지 않으면 병합
                });
            }

            return datas;

        },  // setFileInfo


		/*=========================================================================================
		 * 선택된 리스트에서 원하는 값 리턴
         * eq_idx => 파일 업로드 인덱스, listIdx => 파일 인덱스,
         * outPut => 출력 형태 
		**---------------------------------------------------------------------------------------*/
		/* 파일 데이터 속성을 넣어줌 */ 
        /*
         * 호출 예시:
         * 첫 번째 New 데이터 출력: 
         * MARI.file_uploder.code.getFileInfo2(0, 'New', 1, 'All');
         * MARI.file_uploder.code.getFileInfo2(0, 'New', 1, 'dataFileOriginalName');
         *
         * @param   {Event}  event_eq        - 이벤트가 일어나고 있는 업로더의 인덱스
         * @param   {string} objType         - 현재 데이터의 타입으로 'Add', 'New', 'Modify' 중 하나
         * @param   {number} aryNum          - 데이터 배열에서 가져올 데이터의 인덱스 
         * @param   {string} [atrName='All'] - 출력할 속성 이름, 'All'이면 모든 속성을 출력, 특정 속성만 출력할 수도 있음 
         * @returns {object}                 - 선택된 데이터의 값을 객체 형태로 반환
         */
        getFileInfo2 : function(event_eq, objType, aryNum, atrName = 'All', debergEcho = ''){ 
            /*==============================================
             * ※ 데이터 호출시 주의 사항 :: 2024-10-13(일) ※
             *    - 업로더에 리스트 돔이 생성되기 이전 :: 배열 인덱스를 받아서 직접 찾는다
             *       - 새로운 파일
             *            업로드중 파일  -> temp_Ary   ( 사용할 때 마다 새로 담긴다 ) 
             *       - 수정용 파일
             *            서버 저장 파일 -> modifyFile ( 서버에 저장되어 있는 수정용 파일 ) 
             *
             *    - 업로더에 리스트 돔이 생성되기 이후 :: 리스트의 데이터코드를 참고해서 배열을 찾는다 
             *       - 새로운 파일
             *            업로드중 파일  -> temp_Ary   ( 사용할 때 마다 새로 담긴다 => 진행중 )
             *            업로드한 파일  -> newFile    ( 새로운 파일을 누적을 시킨다 => 완료한 )
             *       - 수정용 파일
             *            서버 저장 파일 -> modifyFile ( 서버에 저장되어 있는 수정용 파일 )
            **---------------------------------------------*/
            let obj_this   = MARI.file_uploder.code;
            let objLang    = MARI.file_uploder.langObj[obj_this.country];  // 언어 객체에서 선택된 언어 가져오기
            let eq_idx     = event_eq;// obj_this.event_eq(event);             // 사용 가능하게 설정된 업로더에서의 인덱스 
            let tempAry    = MARI.file_uploder.code.temp_Ary[eq_idx] || null;  // 파일 업로드 시 리셋되는 임시 배열
            let dTaAry     = MARI.file_uploder.code.dTa_Ary[eq_idx] || null;   // New, Modify 데이터가 담기는 배열
            let newFile    = dTaAry?.new_files?.files || null;                 // New 파일이 담기는 배열
            let modifyFile = dTaAry?.modify_files || null;                     // Modify 파일이 담기는 배열
            // 데이터 가져오기
            let modifyData = modifyFile[aryNum];  
            let tempData   = tempAry[aryNum] || null; 
            let newData    = newFile[aryNum];
            let datas      = null;
            /*==============================================
             * ※ 데이터 호출시 주의 사항 :: 2024-10-13(일) ※
             * ※ 리스트의 데이터 코드를 통해서 인덱스를 얻어서 찾고
             * ※ 없으면 데이터의 데이터 코드를 통해서 접근한다
            **---------------------------------------------*/  
            if (objType === 'Add') {
                datas = tempData; 
            } else if (objType === 'New') {
                datas = newData; 
            } else if (objType === 'Modify') {
                datas = modifyData;
            }
            // datas를 가져오기 위한 처리 : 끝

            // 디버깅을 위한 현재 소스가 처리된 곳의 파일명과 라인 가져오기
            //const err = new Error();
            //const stackLines = err.stack.split('\n');
            //const lineInfo = stackLines[2]?.trim().match(/([^/\\]+:\d+:\d+)/)?.[1] || '';
            //console.log(lineInfo); 

            if(atrName === 'All'){// 모두 출력
                obj_this.log(datas);
                return datas;
            } else { // 입력된 명칭만 출력  
                obj_this.log( atrName );

                if(atrName !== '' && atrName !== 'All'){
                    // 방법 1:: 출력하고자 하는 것을 배열 형태로 받아서 여러개를 출력할 때
                    // MARI.file_uploder.code.getFileInfo2(0, 'New', 1,['dataFileOriginalName','dataFileSrc']); 
                    if(typeof(atrName) === 'object'){ // 객체 형태로 여러개를 담아서 들어오고 들어온 것을 담아서 리턴할때 객체로 리턴
                        let result = {};
                        atrName.forEach((atr_name) => { // for문을 간단하게 forEach문으로
                            result[atr_name] = datas[atr_name]; 
                        });
                        return result; 
                    } else { 
                        // 방법 2:: 출력하고자 하는 것을 속성명 하나만 받아서 하나만을 출력할 때
                        // MARI.file_uploder.code.getFileInfo2(0, 'New', 1,'', 'dataFileOriginalName'); 
                        obj_this.log( '속성명을 받은것 하나만 출력',datas );

                        return datas[atrName]; 
                    }
                } else {
                    return 'No Atribute'; 
                }
            }
            
        },  // setFileInfo 


	};// end property  
}// end if(typeof(window.MARI.file_uploder.setData) === "undefined") {
        
