PageSourceSearch

https://naemo.ai/_next/static/chunks/5708.46f9e401f4fbfaa0.js

js naemo.ai collected 2026-10-02 01:15:03 UTC 36,893 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5708],{51817:function(e,s,a){"use strict";a.d(s,{Z:function(){return t}});let t=(0,a(79205).Z)("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]])},76980:function(e,s,a){"use strict";a.d(s,{Z:function(){return t}});let t=(0,a(79205).Z)("Paperclip",[["path",{d:"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48",key:"1u3ebp"}]])},25708:function(e,s,a){"use strict";a.r(s),a.d(s,{default:function(){return z}});var t=a(57437),r=a(2265),l=a(33145),n=a(30401),i=a(51817),c=a(92934),o=a(76858);a(83079);var d=a(12119),u=(0,d.$)("cbe091676eefe5be89695417f9581cae5a9585c8"),h=(0,d.$)("3738969fa34e6b134d81367ace3f5fb1064ece4b"),m=(0,d.$)("5f43e1371298d97ef203adea4369ff8b5c9c8fa7"),p=(0,d.$)("b974951a52dd302a03507faf9f7556c442603c11"),f=(0,d.$)("3802924ed388f307eb2e0ce6078d5129df7e9380"),g=a(55369),x=a(29827),j=a(86900),N=a(21636),v=class extends j.z{constructor(e,s){super(e,s)}bindMethods(){super.bindMethods(),this.fetchNextPage=this.fetchNextPage.bind(this),this.fetchPreviousPage=this.fetchPreviousPage.bind(this)}setOptions(e){super.setOptions({...e,behavior:(0,N.Gm)()})}getOptimisticResult(e){return e.behavior=(0,N.Gm)(),super.getOptimisticResult(e)}fetchNextPage(e){return this.fetch({...e,meta:{fetchMore:{direction:"forward"}}})}fetchPreviousPage(e){return this.fetch({...e,meta:{fetchMore:{direction:"backward"}}})}createResult(e,s){let{state:a}=e,t=super.createResult(e,s),{isFetching:r,isRefetching:l,isError:n,isRefetchError:i}=t,c=a.fetchMeta?.fetchMore?.direction,o=n&&"forward"===c,d=r&&"forward"===c,u=n&&"backward"===c,h=r&&"backward"===c;return{...t,fetchNextPage:this.fetchNextPage,fetchPreviousPage:this.fetchPreviousPage,hasNextPage:(0,N.Qy)(s,a.data),hasPreviousPage:(0,N.ZF)(s,a.data),isFetchNextPageError:o,isFetchingNextPage:d,isFetchPreviousPageError:u,isFetchingPreviousPage:h,isRefetchError:i&&!o&&!u,isRefetching:l&&!d&&!h}}},b=a(68873),y=(0,d.$)("8ae102925b3264f2cb07e4abd7cb90cb5d213696"),_=(0,d.$)("10a12c97cb938b7a8b3e5ee040158d20c15cba84"),k=a(50647),w=a.n(k);function S(e){var s;let{detail:a,version:l,onRestored:n,domain:i="scores"}=e,c=(0,x.NL)(),[o,d]=(0,r.useState)(null),[u,h]=(0,r.useState)(!1),[m,p]=(0,r.useState)(""),[f,g]=(0,r.useState)(""),j=(0,r.useRef)(!1),N="life"===i,k=N?"생기부 분석":"성적 파일",S=N?"school-life-history":"school-score-history",P=(s={queryKey:[S,a.space.id,a.space.currentYear,a.me.assignments,l],initialPageParam:null,queryFn:async e=>{let{pageParam:s}=e,t={action:"list",spaceId:a.space.id,...s?{before:s}:{}};if(N){let e=await _(t);if(!e.success)throw Error(e.error);if("list"!==e.data.kind)throw Error("생기부 반영 이력을 확인하지 못했습니다.");return{...e.data,uploads:e.data.uploads.map(e=>({id:String(e.sequence),label:"생기부 분석\xb7요약",acceptedAt:e.acceptedAt,students:e.students,status:e.status,uploadedBy:"uploadedBy"in e?e.uploadedBy:null,fileName:"fileName"in e&&"string"==typeof e.fileName?e.fileName:null}))}}let r=await y(t);if(!r.success)throw Error(r.error);if("list"!==r.data.kind)throw Error("성적 파일 이력을 확인하지 못했습니다.");return{...r.data,uploads:r.data.uploads.map(e=>{var s;return{id:e.id,label:e.cumulative?"누적 내신":(s=e.exam,"".concat(s.academicYear,"학년도 ").concat(s.grade,"학년 \xb7 ").concat("mock"===s.domain?"".concat(s.period,"월 ").concat("legacy-month"===s.kind?"모의고사":s.kind):"".concat(s.period,"학기 ").concat("midterm"===s.kind?"중간고사":"학기말 내신"))),acceptedAt:e.acceptedAt,students:e.students,status:e.status,uploadedBy:"uploadedBy"in e?e.uploadedBy:null,fileName:"fileName"in e&&"string"==typeof e.fileName?e.fileName:null}})}},getNextPageParam:e=>e.nextBefore,staleTime:0,gcTime:0,refetchOnWindowFocus:"always",retry:!1},(0,b.r)(s,v,void 0)),C=async e=>{if(!j.current){j.current=!0,h(!0),g(""),p("");try{let s=N?await _({action:"restore",spaceId:a.space.id,sequence:Number(e)}):await y({action:"restore",spaceId:a.space.id,uploadId:e});if(!s.success){g(s.error),d(null),await P.refetch();return}if("restored"!==s.data.kind)throw Error("Unexpected response");p("".concat(s.data.students,"명의 ").concat(N?"생기부 분석을":"성적을"," 파일 반영 전으로 되돌렸습니다.")),d(null),null==n||n(),await Promise.all([S,"school-personal-student","smv-dashboard-grades","students"].map(e=>c.invalidateQueries({queryKey:[e]})))}
1catch(e){g("처리 결과를 확인하지 못했습니다. 다시 시도해도 중복으로 되돌리지 않습니다.")}finally{j.current=!1,h(!1)}}};if(P.isError)return(0,t.jsxs)("p",{className:w().error,role:"alert",children:[P.error.message," ",(0,t.jsx)("button",{className:w().secondary,onClick:()=>void P.refetch(),children:"다시 확인"})]});if(P.isPending)return(0,t.jsxs)("p",{className:w().note,role:"status",children:[k," 이력을 확인하고 있습니다."]});let F=P.data.pages.flatMap(e=>e.uploads);return(0,t.jsxs)("div",{"aria-busy":u,children:[(0,t.jsxs)("p",{className:w().note,children:[N?"학교에 반영한 생기부 분석 이력입니다. 원본 PDF는 변경하지 않습니다.":"담임과 관리자가 학교에 반영한 성적 파일 중 현재 담당 범위에 해당하는 이력입니다."," 이후 수정이 없는 파일만 되돌릴 수 있습니다."]}),!F.length&&(0,t.jsxs)("p",{children:["이 범위에서 확인할 ",k," 이력이 없습니다."]}),(0,t.jsx)("ul",{className:w().historyList,children:F.map(e=>(0,t.jsxs)("li",{children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("strong",{children:e.label}),e.fileName?(0,t.jsx)("p",{className:w().note,children:e.fileName}):null,(0,t.jsxs)("p",{className:w().note,children:[new Date(e.acceptedAt).toLocaleString("ko-KR")," \xb7 ",e.students,"명 반영",e.uploadedBy?" \xb7 ".concat(e.uploadedBy):""]})]}),"restored"===e.status?(0,t.jsx)("span",{className:w().note,children:"되돌림 완료"}):"changed"===e.status?(0,t.jsx)("span",{className:w().note,children:"이후 변경 있어 되돌릴 수 없음"}):o!==e.id?(0,t.jsx)("button",{className:w().secondary,disabled:u,onClick:()=>{d(e.id),g(""),p("")},children:"되돌리기"}):null,o===e.id&&"available"===e.status&&(0,t.jsxs)("div",{className:w().confirm,children:[(0,t.jsxs)("p",{children:[e.students,"명의 ",N?"생기부 분석\xb7요약을":"이 시험 자료를"," 파일 반영 전으로 되돌립니다. 처음 등록한 ",N?"분석":"성적","은 미등록 상태로 돌아갑니다."]}),(0,t.jsx)("button",{className:w().secondary,disabled:u,onClick:()=>d(null),children:"취소"})," ",(0,t.jsx)("button",{className:w().primary,disabled:u,onClick:()=>void C(e.id),children:N?"이전 생기부 분석으로 되돌리기":"이전 성적으로 되돌리기"})]})]},e.id))}),P.hasNextPage&&(0,t.jsx)("button",{className:w().secondary,disabled:u||P.isFetchingNextPage,onClick:()=>void P.fetchNextPage(),children:"이전 파일 더 보기"}),f&&(0,t.jsx)("p",{className:w().error,role:"alert",children:f}),m&&(0,t.jsx)("p",{className:w().notice,role:"status",children:m})]})}var P=a(76980),C=a(32489),F=a(53947),I=a.n(F);function M(e){let{file:s,accept:a,label:l,hint:n,disabled:i,onFile:c}=e,o=(0,r.useId)(),[d,u]=(0,r.useState)(!1);return(0,t.jsxs)("div",{className:I().fileArea,children:[(0,t.jsxs)("label",{htmlFor:o,className:I().dropzone,"data-dragging":d,"data-disabled":i,onDragOver:e=>{e.preventDefault(),i||u(!0)},onDragLeave:()=>u(!1),onDrop:e=>{e.preventDefault(),u(!1),!i&&e.dataTransfer.files.length&&c(e.dataTransfer.files[0])},children:[(0,t.jsx)("input",{id:o,className:I().fileInput,type:"file",accept:a,"aria-label":l,disabled:i,onChange:e=>{var s,a;c(null!==(a=null===(s=e.target.files)||void 0===s?void 0:s[0])&&void 0!==a?a:null),e.target.value=""}}),(0,t.jsx)(P.Z,{size:20,strokeWidth:1.5,"aria-hidden":"true"}),(0,t.jsxs)("span",{className:I().fileCopy,children:[(0,t.jsx)("strong",{children:s?s.name:"파일 선택"}),s?(0,t.jsx)("span",{children:"눌러서 바꾸기"}):(0,t.jsx)("span",{className:I().dropHint,children:"또는 여기에 끌어 놓기"})]}),(0,t.jsx)("span",{className:I().fileMeta,children:s?"".concat((s.size/1024/1024).toFixed(2)," MB"):n})]}),s&&(0,t.jsx)("button",{type:"button",className:I().removeFile,disabled:i,"aria-label":"선택한 파일 삭제",onClick:()=>c(null),children:(0,t.jsx)(C.Z,{size:16})})]})}function B(e){let{category:s}=e;return(0,t.jsx)("div",{className:I().fileGuide,"aria-label":"파일 다운로드 안내",children:"mock"===s?(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"파일 받는 곳"}),"시험업무지원포털(www.csat.re.kr) → 성적출력 → 성적일람표 \xb7 PDF로 저장"]}):"life"===s?(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"파일 받는 곳"}),"나이스 → 학급담임 → 학교생활기록부 → 학생부 조회 및 출력 → 학생부II 선택 → PDF로 저장"]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"학기말 내신"}),"나이스 → 학급담임 → 학교생활기록부 → 학생부 항목별 조회 → 교과학습발달상황 → 저장 → XLS data"]}),(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"중간고사"}),"나이스 → 성적조회/통계 → 학기말 성적 조회 → 성적일람표 전과목/전학생 → ‘한 페이지로 출력’ 체크 → 저장 → XLS"]}),(0,t.jsx)("p",{className:I().guideNote,children:"중간고사 파일은 성적업무 담당 선생님께 받을 수 있어요."})]})})}var D=a(36950),A=a(74791);function E(e){let{detail:s,registered:a,onRegistered:l,onOpenRoster:n,onBusyChange:i,onRosterChange:c}=e,o=s.classes.filter(e=>
1s.me.operator||(0,g.Ko)(s.me.assignments,{academicYear:s.space.currentYear,grade:e.grade,classId:e.id})),[d,u]=(0,r.useState)(""),[h,m]=(0,r.useState)(null),[p,f]=(0,r.useState)([]),[x,j]=(0,r.useState)([]),[N,v]=(0,r.useState)(""),[b,y]=(0,r.useState)(""),[_,k]=(0,r.useState)(!1),w=(0,r.useRef)(!1),S=(0,r.useRef)(new Map),P=(0,r.useRef)(0),C={groups:[],unresolved:!1},F="";try{C=function(e,s){let a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",t=new Map,r=!1;for(let n of e){var l;if(!Number.isInteger(n.number)||n.number<1||n.number>999||!n.name.trim())throw Error("학생 번호와 이름을 확인해 주세요.");let e=s.filter(e=>(void 0===n.grade||n.grade===e.grade)&&(void 0===n.classNum||n.classNum===e.classNum));if(!e.length)throw Error("파일의 학년\xb7반에 등록할 권한이 없거나, 학교에 해당 학급이 없습니다.");let i=1===e.length?e[0]:e.find(e=>e.id===a);if(!i){r=!0;continue}let c=null!==(l=t.get(i.id))&&void 0!==l?l:{target:i,rows:[]};if(c.rows.some(e=>e.number===n.number))throw Error("".concat(i.grade,"학년 ").concat(i.classNum,"반에 중복 번호가 있습니다."));if(c.rows.push({number:n.number,name:n.name}),c.rows.length>100)throw Error("한 반에는 최대 100명까지 등록할 수 있습니다.");t.set(i.id,c)}return{groups:Array.from(t.values()),unresolved:r}}(p,o,d)}catch(e){F=e instanceof Error?e.message:"명단을 확인해 주세요."}let B=C.groups.filter(e=>!x.includes(e.target.id)),E=p.filter(e=>o.filter(s=>(void 0===e.grade||e.grade===s.grade)&&(void 0===e.classNum||e.classNum===s.classNum)).length>1),R=o.filter(e=>E.every(s=>(void 0===s.grade||s.grade===e.grade)&&(void 0===s.classNum||s.classNum===e.classNum)));async function z(e){if(!w.current&&(P.current=0,m(e),f([]),u(""),j([]),v(""),y(""),e)){w.current=!0,k(!0),i(!0);try{if(!/\.xlsx?$/i.test(e.name)||!e.size||e.size>8388608)throw Error("8MB 이하의 엑셀 파일(.xls, .xlsx)을 선택해 주세요.");let s=await (0,A.DX)(e);if(!s.length)throw Error("파일에서 학생을 찾지 못했습니다. 번호\xb7이름이 있는지 확인해 주세요.");f(s)}catch(e){v(e instanceof Error?e.message:"명단을 읽지 못했습니다. 다시 시도해 주세요.")}finally{w.current=!1,k(!1),i(!1)}}}async function Z(){if(w.current||F||C.unresolved||!B.length)return;w.current=!0,k(!0),i(!0),v("");let e=[...x],t=P.current;try{for(let{target:i,rows:c}of B){var r,n,o;let d=S.current.get(i.id),u=(null==d?void 0:d.original)===i.revision?d.current:i.revision,h=await (0,D.F)({action:"register-roster",spaceId:s.space.id,classId:i.id,revision:u,rows:c});if(!h.success){v("".concat(i.grade,"학년 ").concat(i.classNum,"반: ").concat(h.error).concat(e.length?" 완료된 학급은 유지되며, 다시 누르면 남은 학급만 등록합니다.":""));return}!Array.isArray(h.data)&&"conflicts"in h.data&&(t+=Number(h.data.conflicts||0)),P.current=t,e.push(i.id),j([...e]);let m=null!==(o=null!==(n=a[i.id])&&void 0!==n?n:null===(r=i._count)||void 0===r?void 0:r.enrollments)&&void 0!==o?o:0,p=!Array.isArray(h.data)&&"registered"in h.data&&!h.data.reused?h.data.registered:0;Number(p)>0&&S.current.set(i.id,{original:i.revision,current:u+1}),l(i.id,Math.max(m+Number(p),1)),y("".concat(e.length,"개 학급의 명단을 확인\xb7등록했습니다.").concat(t?" 번호\xb7이름이 다른 ".concat(t,"명은 반영하지 않았습니다. 학급 학생 명단에서 확인해 주세요."):""))}}catch(e){v("등록 결과를 확인하지 못했습니다. 다시 누르면 미완료 학급을 확인합니다.")}finally{if(e.length>x.length)try{await (null==c?void 0:c())}catch(e){v(e=>e||"명단은 등록했지만 화면을 갱신하지 못했습니다. 새로고침해 주세요.")}w.current=!1,k(!1),i(!1)}}return(0,t.jsxs)("div",{className:I().workspace,children:[o.length?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(M,{file:h,accept:".xls,.xlsx",label:"학생 명단 파일 \xb7 최대 8MB",hint:"Excel (.xls, .xlsx) \xb7 최대 8MB",disabled:_,onFile:e=>void z(e)}),(0,t.jsxs)("div",{className:I().detectedSummary,children:[(0,t.jsx)("p",{className:I().helper,children:"학교에서 쓰던 학생 명단 엑셀이나 제공 양식을 사용하세요. 첫 번째 시트의 학년\xb7반\xb7번호\xb7이름을 읽습니다."}),(0,t.jsx)("button",{className:I().textButton,disabled:_,onClick:()=>void(0,A.RM)().catch(()=>v("양식을 내려받지 못했습니다. 다시 시도해 주세요.")),children:"엑셀 양식 받기"})]}),_&&(0,t.jsx)("p",{className:I().reading,role:"status",children:p.length?"명단을 등록하고 있어요…":"명단을 읽고 있어요…"}),p.length>0&&!F&&(0,t.jsxs)(t.Fragment,{children:[E.length>0&&(0,t.jsxs)("div",{className:I().fields,children:[(0,t.jsxs)("label",{children:["등록할 학급",(0,t.jsxs)("select",{value:d,disabled:_||x.length>0,onChange:e=>{u(e.target.value),v("")},children:[(0,t.jsx)("option",{value:"",disabled:!0,children:"파일에 없는 학급 정보 선택"}),R.map(e=>(0,t.jsxs)("option",{value:e.id,children:[e.grade,"학년 ",e.classNum,"반"]}
1,e.id))]})]}),!R.length&&(0,t.jsx)("p",{className:I().helper,children:"학급을 구분할 수 없습니다. 파일에 학생별 학년\xb7반을 추가해 주세요."})]}),C.groups.map(e=>{var s,r,l;let{target:i,rows:c}=e;return(0,t.jsxs)("div",{className:I().preview,children:[(0,t.jsxs)("div",{className:I().previewHeading,children:[(0,t.jsxs)("h3",{children:[i.grade,"학년 ",i.classNum,"반 \xb7 ",c.length,"명"]}),x.includes(i.id)&&(0,t.jsx)("span",{children:"확인\xb7등록 완료"})]}),(null!==(l=null!==(r=a[i.id])&&void 0!==r?r:null===(s=i._count)||void 0===s?void 0:s.enrollments)&&void 0!==l?l:0)>0&&(0,t.jsxs)("p",{className:I().helper,children:["기존 학생은 유지하고 새 학생만 추가합니다.",n&&(0,t.jsx)("button",{className:I().textButton,disabled:_,onClick:()=>n(i.id),children:"명단 보기"})]}),(0,t.jsx)("div",{className:I().tableScroll,children:(0,t.jsxs)("table",{children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{scope:"col",children:"번호"}),(0,t.jsx)("th",{scope:"col",children:"이름"})]})}),(0,t.jsx)("tbody",{children:c.map(e=>(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{children:e.number}),(0,t.jsx)("td",{children:e.name})]},e.number))})]})})]},i.id)}),B.length>0&&(0,t.jsx)("button",{className:I().primary,disabled:_||C.unresolved,onClick:()=>void Z(),children:"학교 학생 명단 등록"})]})]}):(0,t.jsx)("p",{className:I().helper,children:"학생 명단은 해당 반 담임 또는 학교 관리자가 등록할 수 있어요."}),(N||F)&&(0,t.jsx)("p",{className:I().error,role:"alert",children:N||F}),b&&(0,t.jsx)("p",{className:I().success,role:"status",children:b})]})}let R=[{id:"roster",name:"학생 명단",description:"학생 등록부터 시작해요",icon:"roster"},{id:"grades",name:"내신 성적",description:"학기말 \xb7 중간고사",icon:"grades"},{id:"mock",name:"모의고사 성적",description:"월별 모의고사 결과",icon:"mock"},{id:"life",name:"생기부",description:"학생별 분석과 요약",icon:"life"}];function z(e){var s,a,d;let{detail:x,initialClassId:j,onOpenRoster:N,onRosterChange:v,onBusyChange:b}=e,y=x.classes.find(e=>e.id===j),[_,k]=(0,r.useState)(()=>(y?[y]:x.classes).some(e=>(0,g.yV)(x.me.assignments,{academicYear:x.space.currentYear,grade:e.grade,classId:e.id},"grades"))?"final":"mock"),[w,P]=(0,r.useState)(!1),[C,F]=(0,r.useState)(!1),[D,A]=(0,r.useState)({}),z="life"===_?"life":"mock"===_?"mock":"grades",Z=x.classes.filter(e=>(0,g.yV)(x.me.assignments,{academicYear:x.space.currentYear,grade:e.grade,classId:e.id},z)),$=Array.from(new Set(Z.map(e=>e.grade))).sort(),[q,G]=(0,r.useState)(null!==(a=null==y?void 0:y.grade)&&void 0!==a?a:0),[Y,O]=(0,r.useState)("mock"===_?3:1),[H,K]=(0,r.useState)(null!==(d=null==y?void 0:y.classNum)&&void 0!==d?d:0),T=Z.filter(e=>e.grade===q),L=T.filter(e=>{var s,a,t;return("life"===_||!H||e.classNum===H)&&!(null!==(t=null!==(a=D[e.id])&&void 0!==a?a:null===(s=e._count)||void 0===s?void 0:s.enrollments)&&void 0!==t?t:0)}),[X,U]=(0,r.useState)(null),[W,Q]=(0,r.useState)(!1),[J,V]=(0,r.useState)(null),[ee,es]=(0,r.useState)(null),[ea,et]=(0,r.useState)(!1),[er,el]=(0,r.useState)(""),[en,ei]=(0,r.useState)(""),[ec,eo]=(0,r.useState)(!1),[ed,eu]=(0,r.useState)(null),[eh,em]=(0,r.useState)(!1),[ep,ef]=(0,r.useState)(0),eg=(0,r.useRef)(!1),ex=(0,r.useRef)(null),[ej,eN]=(0,r.useState)(!1),ev="school-life-upload:".concat(x.me.id,":").concat(x.space.id);(0,r.useEffect)(()=>{try{ex.current=sessionStorage.getItem(ev)}catch(e){ex.current=null}eN(!!ex.current)},[ev]);let eb=e=>{ex.current=e,eN(!!e);try{e?sessionStorage.setItem(ev,e):sessionStorage.removeItem(ev)}catch(e){}},ey=async()=>{if(ex.current&&!eg.current){eg.current=!0,et(!0),null==b||b(!0),el("");try{var e;let s=await u(x.space.id,ex.current);if(!s.success){el(s.error);return}if("pending"===s.data.kind){ei("생기부를 처리 중입니다. 잠시 후 처리 결과를 다시 확인해 주세요.");return}if(eb(null),"failed"===s.data.kind){el(s.data.error);return}ei("".concat(s.data.replaced,"명의 생기부 분석을 반영했습니다.").concat(s.data.skipped?" 더 최근 자료가 있는 ".concat(s.data.skipped,"명은 유지했습니다."):"")),eu(null!==(e=s.data.fileKey)&&void 0!==e?e:null),V(null),ef(e=>e+1),eo(!0)}
1catch(e){el("처리 결과를 확인하지 못했습니다. 다시 확인해 주세요.")}finally{eg.current=!1,et(!1),null==b||b(!1)}}},e_=()=>{eo(!1),es(null),el(""),ei(""),eu(null)},ek=async(e,s)=>{if(!e||!(null==s?void 0:s.kind)||!s.grade||null===s.classNum||!s.period||eg.current)return;let a=s.grade,t=s.classNum,r=s.period,l=s.kind;eg.current=!0,et(!0),null==b||b(!0),e_();try{if("life"===l){var n;let s=null!==(n=ex.current)&&void 0!==n?n:crypto.randomUUID();eb(s);let t=new FormData;t.set("spaceId",x.space.id),t.set("grade",String(a)),t.set("file",e),t.set("requestId",s);let r=await h(t);if(!r.success){el(r.error),"pending"in r&&r.pending||eb(null);return}eb(null),ei("".concat(r.replaced,"명의 생기부 분석을 반영했습니다.").concat(r.skipped?" 더 최근 자료가 있는 ".concat(r.skipped,"명은 유지했습니다."):"")),eu(r.fileKey),V(null),ef(e=>e+1),eo(!0);return}let s={domain:"mock"===l?"mock":"grades",academicYear:x.space.currentYear,grade:a,period:r,kind:"mock"===l?"legacy-month":l},i=new FormData;i.set("spaceId",x.space.id),i.set("exam",JSON.stringify(s)),i.set("classNum",String(t)),i.set("file",e);let c=await p(i);c.success?es(c):el(c.error)}catch(e){el("파일을 확인하지 못했습니다. 연결 상태와 파일 크기를 확인해 주세요.")}finally{eg.current=!1,et(!1),null==b||b(!1)}},ew=async()=>{if(ee&&!eg.current){eg.current=!0,et(!0),null==b||b(!0),el("");try{let e=await m(x.space.id,ee.uploadId);if(!e.success){el(e.error);return}ei("".concat(e.replaced,"건의 학생별 시험 성적을 반영했습니다.").concat(e.skipped?" 더 최근 자료가 있는 ".concat(e.skipped,"건은 기존 자료를 유지했습니다."):"")),es(null),V(null),ef(e=>e+1),eo(!0)}catch(e){el("반영 결과를 확인하지 못했습니다. 같은 버튼으로 다시 시도해도 중복 저장되지 않습니다.")}finally{eg.current=!1,et(!1),null==b||b(!1)}}},eS=w?"roster":"final"===_||"midterm"===_?"grades":_,eP=e=>{e!==eS&&(P("roster"===e),"roster"!==e&&(k("grades"===e?"final":e),O("mock"===e?3:1)),V(null),U(null),Q(!1),e_())},eC=async(e,s)=>{if(eg.current)return;eg.current=!0,et(!0),null==b||b(!0),el("");let a=null;try{var t,r,l,n;let i=new FormData;i.set("spaceId",x.space.id),i.set("category",eS),i.set("file",e),s&&i.set("kind",s);let c=await f(i);if(!c.success){el(c.error);return}let o={...c.detected};if(o.grade&&!$.includes(o.grade)){el("파일의 학년에 자료를 등록할 권한이 없습니다. 담당 배정을 확인해 주세요.");return}null!==(t=o.grade)&&void 0!==t||(o.grade=1===$.length?$[0]:null);let d=Z.filter(e=>e.grade===o.grade);if(o.classNum&&!d.some(e=>e.classNum===o.classNum)){el("파일의 학급에 자료를 등록할 권한이 없습니다.");return}null===o.classNum&&1===d.length&&(o.classNum=d[0].classNum),U(o),G(null!==(r=o.grade)&&void 0!==r?r:0),K(null!==(l=o.classNum)&&void 0!==l?l:-1),O(null!==(n=o.period)&&void 0!==n?n:0),o.kind&&k(o.kind),o.kind&&o.grade&&null!==o.classNum&&o.period&&(a=o)}catch(e){el("파일 정보를 읽지 못했습니다. 연결 상태를 확인하고 다시 시도해 주세요.")}finally{eg.current=!1,et(!1),null==b||b(!1)}a&&"life"!==a.kind&&await ek(e,a)},eF=X?{...X,grade:q||null,classNum:H<0?null:H,period:Y||null}:null,eI=!!(null==eF?void 0:eF.kind)&&!!eF.grade&&null!==eF.classNum&&!!eF.period;return(0,t.jsxs)("section",{className:I().root,"aria-busy":ea||C,children:[(0,t.jsxs)("header",{className:I().intro,children:[(0,t.jsx)("h2",{children:"어떤 자료를 올릴까요?"}),(0,t.jsx)("p",{children:"자료를 선택하고 파일을 놓아 주세요."})]}),(0,t.jsx)("div",{className:I().typeGrid,role:"group","aria-label":"자료 종류",children:R.map(e=>(0,t.jsxs)("button",{type:"button",className:I().typeCard,"aria-label":e.name,"aria-pressed":eS===e.id,disabled:ea||C,onClick:()=>eP(e.id),children:[(0,t.jsx)("span",{className:I().selectionMark,"aria-hidden":"true",children:eS===e.id&&(0,t.jsx)(n.Z,{size:13,strokeWidth:2.5})}),(0,t.jsx)(l.default,{src:"/images/school-files/".concat(e.icon,".svg"),alt:"",width:88,height:88,unoptimized:!0}),(0,t.jsx)("strong",{children:e.name}),(0,t.jsx)("span",{className:I().typeDescription,children:e.description})]},e.id))}),w?(0,t.jsx)(E,{detail:x,initialClassId:j,registered:D,onRegistered:(e,s)=>A(a=>({...a,[e]:s})),onOpenRoster:N,onRosterChange:v,onBusyChange:e=>{F(e),null==b||b(e)}}):(0,t.jsxs)("div",{className:I().workspace,children:[(0,t.jsxs)("fieldset",{disabled:ea,className:I().form,children:[(0,t.jsx)(M,{file:J,accept:"mock"===_||"life"===_?".pdf":".xls,.xlsx",label:"life"===_?"생기부 PDF \xb7 최대 20MB":"성적 파일 \xb7 최대 8MB",hint:"life"===_?"PDF \xb7 최대 20MB":"mock"===_?"PDF \xb7 최대 8MB":"Excel (.xls, .xlsx) \xb7 최대 8MB",disabled:ea||!$.length||"life"===_&&ej,onFile:e=>{if(eg.current||(e_(),V(null),U(null),Q(!1),!e))return;let s="life"===_||"mock"===_;
1if(!(s?/\.pdf$/i:/\.xlsx?$/i).test(e.name)){el(s?"PDF 파일을 선택해 주세요.":"엑셀 파일(.xls, .xlsx)을 선택해 주세요.");return}if(!e.size||e.size>("life"===_?20:8)*1048576){el("".concat("life"===_?20:8,"MB 이하의 비어 있지 않은 파일을 선택해 주세요."));return}V(e),eC(e)}}),!J&&(0,t.jsx)(B,{category:z}),"life"===_&&(0,t.jsx)("p",{className:I().helper,children:"분석\xb7요약만 공유하며, 원본 PDF는 본인만 볼 수 있어요."}),ea&&(0,t.jsxs)("p",{className:I().reading,role:"status",children:[(0,t.jsx)(i.Z,{size:16,className:I().spinner}),"파일을 읽고 있어요…"]}),J&&X&&!ea&&(0,t.jsx)(t.Fragment,{children:null===X.kind?(0,t.jsx)("div",{className:I().fields,children:(0,t.jsxs)("label",{children:["내신 종류",(0,t.jsxs)("select",{"aria-label":"내신 종류",value:"",onChange:e=>void eC(J,e.target.value),children:[(0,t.jsx)("option",{value:"",disabled:!0,children:"파일의 내신 종류를 선택해 주세요"}),(0,t.jsx)("option",{value:"final",children:"학기말 내신"}),(0,t.jsx)("option",{value:"midterm",children:"중간고사"})]})]})}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:I().detectedSummary,children:[(0,t.jsxs)("span",{children:[q?"".concat(q,"학년"):"현재 학년 확인 필요",H>0?" ".concat(H,"반"):"","mock"===_&&Y?" \xb7 ".concat(Y,"월 모의고사"):"midterm"===_&&Y?" \xb7 ".concat(Y,"학기 중간고사"):"final"===_?" \xb7 학기말 내신":""]}),!W&&eI&&(0,t.jsx)("button",{type:"button",className:I().textButton,disabled:ej,onClick:()=>{e_(),Q(!0)},children:"수정"})]}),(W||!eI)&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:I().helper,children:W?"반영할 정보를 확인해 주세요.":"파일에서 확인하지 못한 정보만 알려 주세요."}),(0,t.jsxs)("div",{className:I().fields,children:[(W||!X.grade)&&(0,t.jsxs)("label",{children:["현재 학년",(0,t.jsxs)("select",{value:q,onChange:e=>{G(Number(e.target.value)),K(0===X.classNum?0:-1),e_()},children:[(0,t.jsx)("option",{value:"0",disabled:!0,children:"학년 선택"}),$.map(e=>(0,t.jsxs)("option",{value:e,children:[e,"학년"]},e))]})]}),"life"!==_&&(W||null===X.classNum||H<0)&&(0,t.jsxs)("label",{children:["대상 반",(0,t.jsxs)("select",{value:H,disabled:!q,onChange:e=>{K(Number(e.target.value)),e_()},children:[(0,t.jsx)("option",{value:"-1",disabled:!0,children:"반 선택"}),0===X.classNum&&(0,t.jsx)("option",{value:"0",children:"파일에 포함된 반"}),T.map(e=>(0,t.jsxs)("option",{value:e.classNum,children:[e.classNum,"반"]},e.id))]})]}),("mock"===_||"midterm"===_)&&(W||!X.period)&&(0,t.jsxs)("label",{children:["mock"===_?"시험 월":"학기",(0,t.jsxs)("select",{value:Y,onChange:e=>{O(Number(e.target.value)),e_()},children:[(0,t.jsx)("option",{value:"0",disabled:!0,children:"선택"}),Array.from({length:"mock"===_?12:2},(e,s)=>(0,t.jsxs)("option",{value:s+1,children:[s+1,"mock"===_?"월":"학기"]},s+1))]})]})]})]}),!ee&&(0,t.jsx)("div",{className:I().submitRow,children:(0,t.jsx)("button",{type:"button",className:I().primary,disabled:!eI,onClick:()=>{Q(!1),ek(J,eF)},children:"life"===_?"분석 후 학교에 반영":"계속"})})]})}),J&&er&&!X&&!ea&&(0,t.jsx)("button",{type:"button",className:I().textButton,onClick:()=>void eC(J),children:"다시 읽기"}),J&&er&&L.length>0&&(0,t.jsxs)("div",{className:I().rosterHint,children:[(0,t.jsx)("span",{children:"학생 명단이 없는 학급"}),L.map(e=>(0,t.jsxs)("button",{type:"button",className:I().textButton,onClick:()=>N?N(e.id):eP("roster"),children:[e.grade,"학년 ",e.classNum,"반 학생 명단 등록"]},e.id))]})]}),!$.length&&(0,t.jsx)("p",{className:I().helper,children:"이 자료를 등록할 담당 학급이 없습니다. 학교 관리자에게 담당 배정을 요청해 주세요."}),er&&(0,t.jsx)("p",{className:I().error,role:"alert",children:er}),en&&(0,t.jsx)("p",{className:I().success,role:"status",children:en}),ec&&(0,t.jsxs)("a",{className:I().textButton,href:"/#student-management",target:"_blank",rel:"noopener noreferrer",children:[(0,t.jsx)(c.Z,{size:17}),"학생 관리에서 반영된 자료 확인",(0,t.jsx)(o.Z,{size:15})]}),ed&&(0,t.jsx)("p",{className:I().helper,children:(0,t.jsx)("a",{href:"/api/files/".concat(encodeURIComponent(ed)),target:"_blank",rel:"noopener noreferrer",children:"내가 올린 원본 PDF 열기"})}),ee&&(0,t.jsxs)("div",{className:I().preview,children:[(0,t.jsxs)("div",{className:I().previewHeading,children:[(0,t.jsx)("h3",{children:"반영할 자료 확인"}),(0,t.jsxs)("span",{children:[ee.students,"명 \xb7 ",ee.subjects,"개 과목 기록"]})]}),(0,t.jsx)("p",{className:I().fileName,children:ee.fileName}),(0,t.jsx)("p",{className:I().helper,children:null===(s=ee.periods)||void 0===s?void 0:s.map(e=>"".concat(e.academicYear,"학년도 ").concat(e.grade,"학년 ").concat(e.period).concat("mock"===e.domain?"월":"학기")).join(" \xb7 ")}),(0,t.jsx)("div",{className:I().tableScroll,children:(0,t.jsxs)("table",{children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{scope:"col",children:"반"}),(0,t.jsx)("th",{scope:"col",children:"번호"}),(0,t.jsx)("th",{scope:"col",children:"이름"}),(0,t.jsx)("th",{scope:"col",children:"과목 수"})]})}),(0,t.jsx)("tbody",{children:ee.preview.map(e=>(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{children:e.classNum}),(0,t.jsx)("td",{children:e.number}),(0,t.jsx)("td",{children:e.name}),(0,t.jsx)("td",{children:e.subjects})]},"".concat(e.classNum,":").concat(e.number)))})]})}),(0,t.jsx)("p",{className:I().helper,children:"파일에 포함된 학생의 해당 시험 자료를 교체합니다. 파일에 없는 학생과 다른 시험의 자료는 유지해요."}),(0,t.jsx)("button",{className:I().primary,disabled:ea,onClick:()=>void ew(),children:ea?"반영 중…":"학교에 반영"})]})]}
1),ej&&(0,t.jsxs)("div",{className:I().pending,children:[(0,t.jsx)("p",{children:"처리 중인 생기부가 있어요. 연결이 끊겼다면 다시 올리기 전에 결과를 확인해 주세요."}),(0,t.jsxs)("button",{className:I().textButton,disabled:ea||C,onClick:()=>{eP("life"),ey()},children:["생기부 처리 결과 확인 ",(0,t.jsx)(o.Z,{size:15})]})]}),(0,t.jsxs)("details",{className:I().history,onToggle:e=>em(e.currentTarget.open),children:[(0,t.jsx)("summary",{children:"업로드 기록"}),eh&&(0,t.jsxs)("div",{className:I().historyContent,children:[(0,t.jsx)("h3",{children:"성적 파일\xb7되돌리기"}),(0,t.jsx)(S,{detail:x,version:ep,onRestored:()=>ei("")},"".concat(x.space.id,":").concat(JSON.stringify(x.me.assignments))),(0,t.jsx)("h3",{children:"생기부 분석\xb7되돌리기"}),(0,t.jsx)(S,{domain:"life",detail:x,version:ep,onRestored:()=>{ei(""),eu(null)}},"".concat(x.space.id,":").concat(JSON.stringify(x.me.assignments),":life"))]})]})]})}},60706:function(e,s,a){"use strict";function t(e){let s=String(e).trim().replace(/[^0-9]/g,"");return/^\d{5}$/.test(s)?{grade:parseInt(s[0]),classNum:parseInt(s.slice(1,3)),number:parseInt(s.slice(3))}:/^\d{4}$/.test(s)?{grade:parseInt(s[0]),classNum:parseInt(s[1]),number:parseInt(s.slice(2))}:null}a.d(s,{T:function(){return t}})},74791:function(e,s,a){"use strict";a.d(s,{DX:function(){return i},RM:function(){return l}});var t=a(60706);let r=["학년","반","번호","이름"];async function l(){let e=await Promise.all([a.e(1425),a.e(6919)]).then(a.bind(a,2093)),s=e.utils.book_new(),t=e.utils.aoa_to_sheet([r]);["A1","B1","C1","D1"].forEach(e=>{t[e]&&(t[e].s={alignment:{horizontal:"center"}})}),e.utils.book_append_sheet(s,t,"Sheet1"),e.writeFile(s,"내모_학생명단_양식.xlsx")}async function n(e){let s=await Promise.all([a.e(1425),a.e(6919)]).then(a.bind(a,2093)),r=s.read(new Uint8Array(e),{type:"array"}),l=r.SheetNames[0],n=r.Sheets[l],i=s.utils.sheet_to_json(n,{header:1}),c=-1,o={grade:-1,class:-1,number:-1,name:-1,memo:-1};for(let e=0;e<Math.min(i.length,5);e++){let s=i[e];if(Array.isArray(s)&&(s.forEach((e,s)=>{let a=String(e).trim();a.includes("학년")&&(o.grade=s),("반"===a||a.includes("학급")||a.includes("반"))&&(o.class=s),a.includes("번호")&&(o.number=s),(a.includes("이름")||a.includes("성명"))&&(o.name=s),(a.includes("비고")||a.includes("기록")||a.includes("메모"))&&(o.memo=s)}),-1!==o.number&&-1!==o.name)){c=e;break}}let d=[];return(-1!==c?i.slice(c+1):i).forEach(e=>{let s,a;if(!Array.isArray(e)||0===e.length)return;let r=0,l="",n="",i="number"==typeof e[2]||/^\d+$/.test(e[2])?parseInt(e[2]):NaN,u=e[3];if(-1===c&&e.length>=4&&!isNaN(i)&&"string"==typeof u&&/^[가-힣a-zA-Z\s]{2,20}$/.test(u.trim()))s=parseInt(String(e[0]).replace(/[^0-9]/g,""))||void 0,a=String(e[1]).replace(/[^0-9]/g,""),r=i,l=u.trim();else if(-1!==c&&-1!==o.number&&-1!==o.name){let t=e[o.number],i=e[o.name];t&&i&&(r=parseInt(String(t).replace(/[^0-9]/g,"")),l=String(i).trim(),-1!==o.grade&&(s=parseInt(String(e[o.grade]).replace(/[^0-9]/g,""))||void 0),-1!==o.class&&(a=String(e[o.class]).replace(/[^0-9]/g,"")),-1!==o.memo&&(n=String(e[o.memo])))}else if(-1===c&&e.length>=2){let n=String(e[0]).trim(),i=String(e[1]).trim(),c=(0,t.T)(n);c&&/^[가-힣a-zA-Z\s]{2,20}$/.test(i)&&(s=c.grade,a=String(c.classNum),r=c.number,l=i)}l||e.forEach(e=>{if("number"!=typeof e||r){if("string"==typeof e){let s=e.trim();!r&&/^\d+$/.test(s)?r=parseInt(s):!l&&/^[가-힣a-zA-Z\s]{2,20}$/.test(s)&&(l=s.trim())}}else r=e}),r&&l&&d.push({number:r,name:l,memo:n,grade:s,classNum:a?parseInt(a,10):void 0})}),d.sort((e,s)=>{let a=(Number(e.grade)||0)-(Number(s.grade)||0);if(0!==a)return a;let t=(Number(e.classNum)||0)-(Number(s.classNum)||0);return 0!==t?t:(Number(e.number)||0)-(Number(s.number)||0)})}async function i(e){return n(await e.arrayBuffer())}},53947:function(e){e.exports={settingsSurface:"school-settings_surface__qXgd8",root:"school-file-upload_root__Ggg40",intro:"school-file-upload_intro__seK1O",typeGrid:"school-file-upload_typeGrid__OSaiX",typeCard:"school-file-upload_typeCard__6Fycx",typeDescription:"school-file-upload_typeDescription__g2q5q",selectionMark:"school-file-upload_selectionMark__FuXu5",workspace:"school-file-upload_workspace__lDNFa",preview:"school-file-upload_preview__Ns3gF",form:"school-file-upload_form__llxyj",fields:"school-file-upload_fields__61J_a",helper:"school-file-upload_helper__G_FWo",rosterHint:"school-file-upload_rosterHint__CjDLG",fileArea:"school-file-upload_fileArea__0sT1E",dropzone:"school-file-upload_dropzone__02KMe",fileCopy:"school-file-upload_fileCopy__skDPw",dropHint:"school-file-upload_dropHint__qcCUi",fileMeta:"school-file-upload_fileMeta__UUIMw",removeFile:"school-file-upload_removeFile__xN56V",fileInput:"school-file-upload_fileInput__bA62T",submitRow:"school-file-upload_submitRow__GjQor",primary:"school-file-upload_primary__k9xq3",textButton:"school-file-upload_textButton__M_emD",error:"school-file-upload_error____QdX",success:"school-file-upload_success__9ry_L",previewHeading:"school-file-upload_previewHeading__W9hFt",fileName:"school-file-upload_fileName__lZdTH",tableScroll:"school-file-upload_tableScroll__6Tjuf",pending:"school-file-upload_pending__R_jZH",history:"school-file-upload_history__g4KWW",historyContent:"school-file-upload_historyContent__Anlxj",spinner:"school-file-upload_spinner___9aGn",spin:"school-file-upload_spin__rzePm",detectedSummary:"school-file-upload_detectedSummary__u2WYm",reading:"school-file-upload_reading__YYa30",fileGuide:"school-file-upload_fileGuide__uteN_",guideNote:"school-file-upload_guideNote__vYypi"}},21636:function(e,s,a){"use strict";a.d(s,{Gm:function(){return r},Qy:function(){return i},ZF:function(){return c}});var t=a(45345);function r(e){return{onFetch:(s,a)=>
1{let r=s.options,i=s.fetchOptions?.meta?.fetchMore?.direction,c=s.state.data?.pages||[],o=s.state.data?.pageParams||[],d={pages:[],pageParams:[]},u=0,h=async()=>{let a=!1,h=e=>{(0,t.I4)(e,()=>s.signal,()=>a=!0)},m=(0,t.cG)(s.options,s.fetchOptions),p=async(e,r,l)=>{if(a)return Promise.reject();if(null==r&&e.pages.length)return Promise.resolve(e);let n=(()=>{let e={client:s.client,queryKey:s.queryKey,pageParam:r,direction:l?"backward":"forward",meta:s.options.meta};return h(e),e})(),i=await m(n),{maxPages:c}=s.options,o=l?t.Ht:t.VX;return{pages:o(e.pages,i,c),pageParams:o(e.pageParams,r,c)}};if(i&&c.length){let e="backward"===i,s={pages:c,pageParams:o},a=(e?n:l)(r,s);d=await p(s,a,e)}else{let s=e??c.length;do{let e=0===u?o[0]??r.initialPageParam:l(r,d);if(u>0&&null==e)break;d=await p(d,e),u++}while(u<s)}return d};s.options.persister?s.fetchFn=()=>s.options.persister?.(h,{client:s.client,queryKey:s.queryKey,meta:s.options.meta,signal:s.signal},a):s.fetchFn=h}}}function l(e,{pages:s,pageParams:a}){let t=s.length-1;return s.length>0?e.getNextPageParam(s[t],s,a[t],a):void 0}function n(e,{pages:s,pageParams:a}){return s.length>0?e.getPreviousPageParam?.(s[0],s,a[0],a):void 0}function i(e,s){return!!s&&null!=l(e,s)}function c(e,s){return!!s&&!!e.getPreviousPageParam&&null!=n(e,s)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.