(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[47155],{4758:(e,t,a)=>{Promise.resolve().then(a.bind(a,75295)),Promise.resolve().then(a.bind(a,21168)),Promise.resolve().then(a.bind(a,79224)),Promise.resolve().then(a.bind(a,54879)),Promise.resolve().then(a.bind(a,42059)),Promise.resolve().then(a.bind(a,85433)),Promise.resolve().then(a.bind(a,11246)),Promise.resolve().then(a.bind(a,88931)),Promise.resolve().then(a.bind(a,43218)),Promise.resolve().then(a.bind(a,4760)),Promise.resolve().then(a.bind(a,63656)),Promise.resolve().then(a.bind(a,51728)),Promise.resolve().then(a.bind(a,7711)),Promise.resolve().then(a.bind(a,14019)),Promise.resolve().then(a.bind(a,94158)),Promise.resolve().then(a.bind(a,27643)),Promise.resolve().then(a.bind(a,10447)),Promise.resolve().then(a.t.bind(a,98500,23)),Promise.resolve().then(a.t.bind(a,42593,23))},10447:(e,t,a)=>{"use strict";a.d(t,{ManhwaManageBar:()=>l});var n=a(95155),s=a(77238),i=a(12115),r=a(73321);function l({sourceWorkId:e,canEdit:t,canDelete:a,canAssign:o,initialUploaders:c}){let d=(0,r.useRouter)(),[u,m]=(0,i.useState)(!1),[h,p]=(0,i.useState)(!1),[g,b]=(0,i.useState)(c),[f,v]=(0,i.useState)(""),[j,x]=(0,i.useState)(null),[$,w]=(0,i.useTransition)(),N=async()=>{if(!u&&confirm("정말 이 만화를 삭제하시겠습니까? 모든 에피소드와 이미지도 함께 삭제됩니다.")){m(!0);try{let t=await fetch(`/api/manhwa/${encodeURIComponent(e)}`,{method:"DELETE",headers:{Accept:"application/json"}}),a=await t.json().catch(()=>null);if(!t.ok||!a?.ok){alert(a?.error||`삭제 실패 (${t.status})`),m(!1);return}window.location.href="/manhwa"}catch(e){alert(e instanceof Error?e.message:"삭제 실패"),m(!1)}}},y=t=>{x(null),w(async()=>{let a=await fetch(`/api/manhwa/${encodeURIComponent(e)}/uploaders`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({uploaderIds:t})}),n=await a.json().catch(()=>null);if(!a.ok||!n?.ok)return void x(n?.error||`실패 (${a.status})`);let s=await fetch(`/api/manhwa/${encodeURIComponent(e)}/uploaders`),i=await s.json().catch(()=>null);i?.ok&&Array.isArray(i.uploaders)&&b(i.uploaders),d.refresh()})};if(!t&&!a&&!o)return null;let S=u||$;return(0,n.jsxs)("div",{className:"manage-bar-wrap",children:[(0,n.jsxs)("div",{className:"manage-bar",children:[t&&(0,n.jsx)(s.D,{href:`/manhwa/${encodeURIComponent(e)}/edit`,className:"btn btn--outline btn--sm",children:"✎ 수정"}),o&&(0,n.jsxs)("button",{type:"button",onClick:()=>p(e=>!e),className:`btn btn--outline btn--sm ${h?"is-active":""}`,children:["\uD83D\uDC64 담당자 ",g.length>0?`(${g.length})`:""]}),a&&(0,n.jsx)("button",{type:"button",onClick:N,disabled:S,className:"btn btn--sm manage-bar-del",children:u?"삭제 중...":"\uD83D\uDDD1 삭제"})]}),o&&h&&(0,n.jsxs)("div",{className:"manage-bar-assign",children:[(0,n.jsxs)("form",{onSubmit:t=>{t.preventDefault();let a=f.trim();a&&(x(null),v(""),w(async()=>{let t=await fetch(`/api/manhwa/${encodeURIComponent(e)}/uploaders?lookup=${encodeURIComponent(a)}`),n=await t.json().catch(()=>null);if(!t.ok||!n?.ok){let e=n?.error||"사용자 조회 실패";if(Array.isArray(n?.candidates)&&n.candidates.length>0){let t=n.candidates.slice(0,5).map(e=>`${e.nickname} (@${e.username})`).join(", ");e+=` 후보: ${t}`}x(e);return}let s=String(n.user.id);g.some(e=>e.id===s)?x("이미 등록된 담당자입니다"):y([...g.map(e=>e.id),s])}))},className:"manage-bar-assign-form",children:[(0,n.jsx)("input",{type:"text",value:f,onChange:e=>v(e.target.value),placeholder:"username 또는 닉네임으로 추가",disabled:$}),(0,n.jsx)("button",{type:"submit",className:"btn btn--primary btn--sm",disabled:$||!f.trim(),children:$?"...":"추가"})]}),j&&(0,n.jsxs)("div",{className:"manage-bar-assign-err",children:["⚠ ",j]}),g.length>0?(0,n.jsx)("div",{className:"manage-bar-assign-list",children:g.map(e=>(0,n.jsxs)("button",{type:"button",className:"manage-bar-assign-chip",onClick:()=>{var t;return t=e.id,void(confirm("담당자에서 제외할까요?")&&y(g.filter(e=>e.id!==t).map(e=>e.id)))},disabled:$,title:`${e.nickname} (@${e.username}) 제외`,children:["✕ ",e.nickname,(0,n.jsxs)("span",{className:"manage-bar-assign-chip-username",children:["@",e.username]})]},e.id))}):(0,n.jsx)("div",{className:"manage-bar-assign-empty",children:"지정된 담당자가 없습니다"})]})]})}},21283:(e,t,a)=>{"use strict";a.d(t,{I:()=>o,e:()=>c});let n="newtoki_read";function s(e){if(0===e.length)return"";let t=Array.from(new Set(e)).sort((e,t)=>e-t),a=[],n=t[0],s=t[0];for(let e=1;e=0&&t.push(e)}else{let n=Number(a.slice(0,e)),s=Number(a.slice(e+1));if(Number.isFinite(n)&&Number.isFinite(s)&&n>=0&&s>=n&&s-n<5e3)for(let e=n;e<=s;e++)t.push(e)}}return t}function r(e,t){return`newtoki_read:${e}:${t}`}function l(e,t){try{let a=localStorage.getItem(r(e,t));return a?i(a):[]}catch{return[]}}function o(e,t,a){if(!/^[A-Za-z0-9_-]{1,40}$/.test(t)||!Number.isFinite(a)||a<0)return;let o=l(e,t);o.push(a);try{0===o.length?localStorage.removeItem(r(e,t)):localStorage.setItem(r(e,t),s(o))}catch{}let c=function(e){let t=document.cookie.match(RegExp("(?:^|; )"+e+"=([^;]*)"));if(!t)return"";try{return decodeURIComponent(t[1])}catch{return t[1]}}(n),d=c?c.split("|"):[],u=`${e}:${t}`,m=!1,h=[];for(let e of d){let t=e.indexOf("=");if(t<0)continue;let n=e.slice(0,t);if(n===u){let r=i(e.slice(t+1));r.push(a),h.unshift(`${n}=${s(r)}`),m=!0}else h.push(e)}m||h.unshift(`${u}=${a}`);let p=h.join("|");for(;encodeURIComponent(p).length>3500&&h.length>1;)h.pop(),p=h.join("|");document.cookie=`${n}=${encodeURIComponent(p)}; path=/; max-age=31536000; samesite=lax`}function c(e,t){return l(e,t)}},27643:(e,t,a)=>{"use strict";a.d(t,{FavoriteButton:()=>r});var n=a(95155),s=a(12115);function i({filled:e,size:t=20}){return(0,n.jsx)("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:e?"currentColor":"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:(0,n.jsx)("path",{d:"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"})})}function r({sourceWorkId:e,initialFavorited:t,loggedIn:a,variant:l="heart"}){let[o,c]=(0,s.useState)(t),[d,u]=(0,s.useTransition)(),[m,h]=(0,s.useState)(!1),[p,g]=(0,s.useState)(null);(0,s.useEffect)(()=>{c(t)},[t]);let b=()=>{if(!a){let e=document.getElementById("auth-modal");e&&"function"==typeof e.showModal&&e.showModal();return}g(null);let t=!o;c(t),h(!0),setTimeout(()=>h(!1),320),u(async()=>{try{let a=await fetch("/api/manhwa-favorites",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({sourceWorkId:e,action:t?"add":"remove"})});if(!a.ok){c(!t);let e=await a.json().catch(()=>null);g(e?.error||"처리 실패");return}let n=await a.json().catch(()=>null);n&&"boolean"==typeof n.favorited&&c(n.favorited)}catch{c(!t),g("네트워크 오류")}})},f=o?"북마크 해제":"북마크 추가";return"compact"===l?(0,n.jsxs)("button",{type:"button",onClick:b,disabled:d,className:`fav-pill ${o?"is-on":""} ${m?"is-bump":""}`,"aria-pressed":o,"aria-label":f,title:f,children:[(0,n.jsx)(i,{filled:o,size:18}),(0,n.jsx)("span",{children:o?"북마크 됨":"북마크"}),p&&(0,n.jsx)("span",{className:"fav-err",children:p})]}):"vw-act"===l?(0,n.jsxs)("button",{type:"button",onClick:b,disabled:d,className:`vw-act ${o?"active":""} ${m?"is-bump":""}`,"aria-pressed":o,"aria-label":f,title:f,children:[(0,n.jsx)(i,{filled:o,size:20}),(0,n.jsx)("span",{children:"북마크"}),p&&(0,n.jsx)("span",{className:"fav-err",children:p})]}):"cta"===l?(0,n.jsxs)("button",{type:"button",onClick:b,disabled:d,className:`cta cta-fav ${o?"is-on":""} ${m?"is-bump":""}`,"aria-pressed":o,"aria-label":f,title:f,children:[(0,n.jsx)("span",{className:"ic",children:(0,n.jsx)(i,{filled:o,size:20})}),(0,n.jsx)("span",{className:"t",children:o?"북마크됨":"북마크"}),p&&(0,n.jsx)("span",{className:"fav-err",children:p})]}):(0,n.jsxs)("button",{type:"button",onClick:b,disabled:d,className:`fav-heart ${o?"is-on":""} ${m?"is-bump":""}`,"aria-pressed":o,"aria-label":f,title:f,children:[(0,n.jsx)(i,{filled:o,size:22}),p&&(0,n.jsx)("span",{className:"fav-err fav-err-float",children:p})]})}},59962:(e,t,a)=>{"use strict";a.d(t,{ImageTraceToggle:()=>i});var n=a(95155),s=a(12115);function i({kind:e,workId:t,episodeId:a=null,initialEnabled:r}){let[l,o]=(0,s.useState)(r),[c,d]=(0,s.useState)(!1),[u,m]=(0,s.useState)(null),h=a?"이 회차":"이 작품",p=async n=>{n.preventDefault(),n.stopPropagation();let s=!l,i=s?`${h}를 추적 모드로 전환할까요? 다음 이미지 열람부터 비가시 추적본이 발급됩니다.`:`${h}의 추적 모드를 해제할까요? 이후 열람은 원본 이미지로 응답합니다.`;if(window.confirm(i)){d(!0),m(null);try{let n=await fetch("/api/admin/image-trace",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({kind:e,workId:t,episodeId:a,enabled:s})}),i=await n.json().catch(()=>null);if(!n.ok||!i?.ok)return void m(i?.error||"저장 실패");o(!!i.enabled)}catch(e){m(e instanceof Error?e.message:"저장 실패")}finally{d(!1)}}};return(0,n.jsxs)("span",{className:"image-trace-toggle-wrap",children:[(0,n.jsx)("button",{type:"button",className:`btn ${l?"btn--primary":"btn--outline"} btn--xs image-trace-toggle`,disabled:c,onClick:p,title:l?"비가시 추적 발급 해제":"비가시 추적 발급으로 전환","data-mobile-label":c?"저장":l?"끔":"추적",children:c?"저장중":l?"추적 끄기":"추적으로 전환"}),u&&(0,n.jsx)("span",{className:"image-trace-toggle-error",children:u})]})}},85433:(e,t,a)=>{"use strict";a.d(t,{HeroThumbImg:()=>i});var n=a(95155),s=a(12115);function i({src:e,alt:t}){let[a,r]=(0,s.useState)(!1),l=(0,s.useRef)(null),o=e=>{e.naturalWidth>0&&e.naturalHeight>0&&r(e.naturalWidth/e.naturalHeight>1.05)};return(0,s.useEffect)(()=>{let e=l.current;e&&e.complete&&o(e)},[]),(0,n.jsx)("img",{ref:l,src:e,alt:t,className:a?"is-landscape":void 0,onLoad:e=>o(e.currentTarget)})}},94158:(e,t,a)=>{"use strict";a.d(t,{EpisodeList:()=>m});var n=a(95155),s=a(77238),i=a(12115),r=a(59962),l=a(21283);let o=/(외전|번외편|번외|특별편|특별\s*편|특별화|단편|프롤로그|에필로그)\s*(\d+(?:[.\-]\d+)?)?\s*(화)?/,c=/(\d+(?:[.\-]\d+)?)\s*권\s*(?:\([^)]*\))?\s*$/,d=/^\s*(\d+(?:[.\-]\d+)?)\s*권/;function u(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let a=new Date(t.getTime()+324e5),n=String(a.getUTCMonth()+1).padStart(2,"0"),s=String(a.getUTCDate()).padStart(2,"0"),i=String(a.getUTCHours()).padStart(2,"0"),r=String(a.getUTCMinutes()).padStart(2,"0");return`${n}.${s} ${i}:${r}`}function m({sourceWorkId:e,workTitle:t,thumb:a,episodes:h,totalEps:p,sortDesc:g,initialCount:b,step:f,canBypassSchedule:v=!1,currentUserId:j=null,isAdmin:x=!1,canTraceEpisodes:$=!1,readEpNos:w,bookmarkedEp:N}){let[y,S]=(0,i.useState)([]),k=(0,i.useMemo)(()=>new Set([...w??[],...y]),[w,y]);(0,i.useEffect)(()=>{let t=(0,l.e)("m",e);t.length>0&&S(t)},[e]);let[C,I]=(0,i.useState)(Math.min(b,h.length)),[T,P]=(0,i.useState)(()=>Date.now()),E=(0,i.useRef)(null);(0,i.useEffect)(()=>{let e=setInterval(()=>P(Date.now()),3e4);return()=>clearInterval(e)},[]),(0,i.useEffect)(()=>{if(C>=h.length)return;let e=E.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0]?.isIntersecting&&I(e=>Math.min(e+f,h.length))},{rootMargin:"600px"});return t.observe(e),()=>t.disconnect()},[C,h.length,f]);let U=h.slice(0,C);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("ul",{className:"ep-list-v2",children:U.map((i,l)=>{var m;let h=!0===i.isNew,p=function(e,t){if(!e)return"";let a=e.trim();return t&&a.startsWith(t)&&(a=a.slice(t.length).trim()).startsWith("-")&&(a=a.slice(1).trim()),a}(i.title,t),g=i.title?.match(/(\d+(?:[.\-]\d+)?)\s*권/),b=g?`${g[1]}권`:function(e,t,a){let n=e?.trim();if(n&&/^[\d.\-]+\s*권$/.test(n)||n&&/^[\d.\-]+\s*화$/.test(n))return n.replace(/\s+/g,"");let s=t.match(c);if(s)return`${s[1]}권`;let i=t.match(d);if(i)return`${i[1]}권`;if(n&&/^[\d.\-]+$/.test(n))return`${n}화`;let r=t.match(o);if(r){let e=r[1].replace(/\s+/g,"");return r[2]?`${e} ${r[2]}화`:e}let l=t.match(/(\d+(?:[.\-]\d+)?)\s*화\s*(?:\([^)]*\))?\s*$/);if(l)return`${l[1]}화`;let u=t.match(/^\s*(\d+(?:[.\-]\d+)?)\s*화/);return u?`${u[1]}화`:`${a}화`}(i.epLabel,i.title,i.number),f=String(i.number),w=p.replace(/^\d+(?:[.\-]\d+)?\s*화\s*[-·:]?\s*/,"").replace(/^\d+(?:[.\-]\d+)?\s*권\s*[-·:]?\s*/,"").replace(/^\d+\.\s+/,"").trim(),y=i.imagesStatus,S=null!=i.availableAt&&new Date(i.availableAt).getTime()>T,C=S&&!v,I=2===y&&!C,P=1===y,E=3===y,U=C?"scheduled":I?"ready":P?"inprog":E?"failed":"pending",A=C?`${u(i.availableAt)} 공개 예정`:"이미지 오류로 2~3일내로 수정됩니다",L=(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"ep-row-v2-thumb",children:[a?(0,n.jsx)("img",{src:a,alt:"",loading:"lazy",decoding:"async"}):null,(0,n.jsx)("span",{className:"ep-row-v2-no",children:f}),!I&&(0,n.jsx)("span",{className:"ep-row-v2-lock","aria-hidden":!0,children:C?"⏰":P?"⏳":E?"✕":"\uD83D\uDD12"})]}),(0,n.jsxs)("div",{className:"ep-row-v2-body",children:[(0,n.jsxs)("div",{className:"ep-row-v2-title",children:[null!=N&&N===i.number&&(0,n.jsx)("span",{className:"ep-badge-bookmark",title:"여기서 멈췄어요",children:"\uD83D\uDD16 책갈피"}),h&&(0,n.jsx)("span",{className:"ep-badge-up",title:"48시간 내 등록",children:"UP"}),(0,n.jsx)("strong",{children:b}),w&&(0,n.jsx)("span",{className:"sub",children:w})]}),(0,n.jsxs)("div",{className:"ep-row-v2-meta",children:[S&&(0,n.jsxs)("span",{className:"ep-badge-scheduled",title:`${u(i.availableAt)} 공개 예정`,children:["⏰ ",u(i.availableAt)," 공개"]}),!C&&P&&(0,n.jsx)("span",{className:"ep-badge-inprog",children:"준비중"}),!C&&E&&(0,n.jsx)("span",{className:"ep-badge-failed",children:"수정중"}),!C&&0===y&&(0,n.jsx)("span",{className:"ep-badge-pending",children:"수정중"}),(0,n.jsx)("span",{className:"ep-row-v2-date",children:function(e){if(!e)return"";let t=new Date(new Date(e).getTime()+324e5),a=String(t.getUTCFullYear()).slice(2),n=String(t.getUTCMonth()+1).padStart(2,"0"),s=String(t.getUTCDate()).padStart(2,"0");return`${a}.${n}.${s}`}(i.availableAt??i.publishedAt??i.createdAt)}),null!=i.avgRating&&i.avgRating>0&&(0,n.jsxs)("span",{className:"ep-stat-rating",title:"평균 평점",children:[(0,n.jsx)("svg",{className:"ep-stat-ic",viewBox:"0 0 24 24",width:"11",height:"11",fill:"currentColor","aria-hidden":!0,children:(0,n.jsx)("path",{d:"M12 2l2.9 6.9 7.5.6-5.7 4.9 1.7 7.3L12 17.8 5.6 21.7l1.7-7.3L1.6 9.5l7.5-.6L12 2z"})}),(0,n.jsx)("span",{className:"ep-stat-val",children:i.avgRating.toFixed(1)})]}),(i.commentCount??0)>0&&(0,n.jsxs)("span",{className:"ep-stat-comments",title:`댓글 ${i.commentCount}건`,children:[(0,n.jsx)("svg",{className:"ep-stat-ic",viewBox:"0 0 24 24",width:"11",height:"11",fill:"none",stroke:"currentColor",strokeWidth:"2.4",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:(0,n.jsx)("path",{d:"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"})}),(0,n.jsx)("span",{className:"ep-stat-val",children:i.commentCount})]}),I&&(0,n.jsxs)("span",{className:"ep-row-v2-views",title:`${i.views.toLocaleString()} 조회`,children:["\uD83D\uDC41 ",(m=i.views)>=1e8?`${(m/1e8).toFixed(1)}억`:m>=1e4?`${(m/1e4).toFixed(1)}만`:m>=1e3?`${(m/1e3).toFixed(1)}천`:m.toLocaleString()]})]})]}),(0,n.jsx)("div",{className:"ep-row-v2-arrow",children:I?"›":C?"⏰":"\uD83D\uDEE0"})]}),R=x||null!==j&&i.createdByUserId===j,D=k.has(i.number);return(0,n.jsxs)("li",{className:`ep-row-v2 ep-row-v2--${U}${D?" ep-row-v2--read":""}`,children:[I?(0,n.jsx)(s.D,{href:`/manhwa/${e}/${i.sourceEpisodeId}`,className:"ep-row-v2-link",prefetch:!1,children:L}):(0,n.jsx)("div",{className:"ep-row-v2-link is-disabled",role:"button","aria-disabled":"true",tabIndex:0,title:A,"data-tip":A,children:L}),(R||$)&&(0,n.jsxs)("div",{className:"ep-row-v2-actions",onClick:e=>e.stopPropagation(),children:[$&&(0,n.jsx)(r.ImageTraceToggle,{kind:"manhwa",workId:e,episodeId:i.sourceEpisodeId,initialEnabled:!0===i.traceEnabled}),R&&(0,n.jsx)(s.D,{href:`/manhwa/${e}/episodes/${i.sourceEpisodeId}/edit`,className:"ep-row-v2-edit",prefetch:!1,title:"수정/삭제","aria-label":"수정/삭제",children:"✏️"})]})]},i.id)})}),C{e.O(0,[98500,42059,53627,82946,79224,29507,28441,93794,77358],()=>e(e.s=4758)),_N_E=e.O()}]);