[{"data":1,"prerenderedAt":8978},["ShallowReactive",2],{"doc:\u002Fwbs-tracker":3},{"id":4,"title":5,"body":6,"description":8971,"extension":8972,"meta":8973,"navigation":376,"path":8974,"seo":8975,"stem":8976,"__hash__":8977},"docs\u002FWBS-TRACKER.md","WBS Live Tracker — 자체 완결 빌드 가이드",{"type":7,"value":8,"toc":8938},"minimark",[9,13,22,51,54,59,62,104,107,109,113,205,210,274,284,289,308,310,314,322,754,761,764,1053,1057,1075,1077,1081,1089,1094,1134,1136,1140,1147,1216,1224,2140,2148,2206,2210,2281,2285,2385,2387,2391,2395,2420,2427,2436,8455,8459,8465,8494,8496,8500,8609,8625,8627,8631,8714,8716,8720,8723,8795,8798,8800,8804,8838,8840,8844,8934],[10,11,5],"h1",{"id":12},"wbs-live-tracker-자체-완결-빌드-가이드",[14,15,16,17,21],"p",{},"이 문서 하나만 있으면 어떤 프로젝트에서도 ",[18,19,20],"strong",{},"동일한 WBS Live Tracker 페이지","를 처음부터 만들 수 있다.\n프론트엔드(Nuxt) + 백엔드(Hono on Workers) + 영속화(R2) + 자동 저장 흐름을 전부 포함한다.",[23,24,25],"blockquote",{},[14,26,27,28,32,33,36,37,40,41,46,47,50],{},"본 프로젝트(",[29,30,31],"code",{},"malgn-helper-pms"," + ",[29,34,35],{},"malgn-helper-api",")에서 운영 중인 ",[29,38,39],{},"\u002Fwbs"," 페이지의 사양·코드·셋업 절차를 그대로 정리한 자체 완결 사양서.\n작업 항목 목록(=콘텐츠)은 ",[42,43,45],"a",{"href":44},".\u002FWBS","WBS.md","에 있고, 본 문서는 ",[18,48,49],{},"그것을 보여주고 편집하는 시스템(=툴)"," 을 다룬다.",[52,53],"hr",{},[55,56,58],"h2",{"id":57},"_1-무엇을-만드는가","1. 무엇을 만드는가",[14,60,61],{},"웹 페이지 한 화면에 프로젝트 WBS(Work Breakdown Structure)를 표시·편집한다.",[63,64,65,72,78,88,94],"ul",{},[66,67,68,71],"li",{},[18,69,70],{},"읽기",": 단계별 진행률, 가중평균, 완료\u002F진행 카운트, 단계별 작업 표",[66,73,74,77],{},[18,75,76],{},"편집(인라인)",": 산출물 URL · 목표일 · 완료일 · 상태 — 모두 표 안에서 즉시 수정",[66,79,80,83,84,87],{},[18,81,82],{},"저장",": 모든 수정은 ",[18,85,86],{},"800ms 디바운스 후 R2에 자동 저장",". \"저장\" 버튼 없음",[66,89,90,93],{},[18,91,92],{},"공유",": 같은 URL을 열면 다른 사용자도 최신 상태를 즉시 봄",[66,95,96,99,100,103],{},[18,97,98],{},"백업",": 언제든 현재 상태를 ",[29,101,102],{},"wbs.json","으로 다운로드",[14,105,106],{},"전형적인 \"Notion 데이터베이스 + 자동 동기화\" 경험을 단일 JSON으로 단순화한 형태.",[52,108],{},[55,110,112],{"id":111},"_2-디자인-컨셉-soft-saas-notion-linear-height-풍","2. 디자인 컨셉 — Soft SaaS (Notion \u002F Linear \u002F Height 풍)",[114,115,116,129],"table",{},[117,118,119],"thead",{},[120,121,122,126],"tr",{},[123,124,125],"th",{},"토큰",[123,127,128],{},"값",[130,131,132,141,149,160,175,186,194],"tbody",{},[120,133,134,138],{},[135,136,137],"td",{},"톤",[135,139,140],{},"라이트, 부드러운 모서리, 옅은 회색 라인",[120,142,143,146],{},[135,144,145],{},"폰트",[135,147,148],{},"Pretendard Variable (한국어 가독성)",[120,150,151,154],{},[135,152,153],{},"색상",[135,155,156,159],{},[29,157,158],{},"neutral"," 기반 + 의미색 5가지",[120,161,162,165],{},[135,163,164],{},"모서리",[135,166,167,170,171,174],{},[29,168,169],{},"rounded-xl"," (카드) \u002F ",[29,172,173],{},"rounded-md"," (인풋·칩)",[120,176,177,180],{},[135,178,179],{},"그림자",[135,181,182,183],{},"거의 없음. 플로팅 바만 ",[29,184,185],{},"shadow-lg shadow-neutral-900\u002F10",[120,187,188,191],{},[135,189,190],{},"본문 폰트",[135,192,193],{},"14px 기본, 12~13px 보조",[120,195,196,199],{},[135,197,198],{},"폭",[135,200,201,204],{},[29,202,203],{},"max-w-5xl"," 중앙 정렬",[14,206,207],{},[18,208,209],{},"의미색 (상태 \u002F 진행률 \u002F 마감)",[114,211,212,222],{},[117,213,214],{},[120,215,216,219],{},[123,217,218],{},"의미",[123,220,221],{},"Tailwind",[130,223,224,234,244,254,264],{},[120,225,226,229],{},[135,227,228],{},"완료 \u002F 70%+ 진행",[135,230,231],{},[29,232,233],{},"emerald-500 \u002F 50 \u002F 200 \u002F 700",[120,235,236,239],{},[135,237,238],{},"진행 중 \u002F 30~69% \u002F 수정 감지",[135,240,241],{},[29,242,243],{},"amber-500 \u002F 50 \u002F 200 \u002F 700",[120,245,246,249],{},[135,247,248],{},"대기 \u002F 0%",[135,250,251],{},[29,252,253],{},"neutral-300 \u002F 50 \u002F 200 \u002F 600",[120,255,256,259],{},[135,257,258],{},"보류 \u002F 마감 초과",[135,260,261],{},[29,262,263],{},"rose-500 \u002F 50 \u002F 200 \u002F 700",[120,265,266,269],{},[135,267,268],{},"저장 중",[135,270,271],{},[29,272,273],{},"sky-500",[14,275,276,279,280,283],{},[18,277,278],{},"비주얼 앵커",": 6단계 이모지 ",[29,281,282],{},"🎯 📐 🛠️ 📚 🧪 🚀"," — 화면 상단·각 단계 헤더에 동일 위치로 반복해 시선 동선을 만든다.",[14,285,286],{},[18,287,288],{},"레이아웃 원칙",[290,291,292,295,298,301],"ol",{},[66,293,294],{},"상단 히어로 4칸(전체 진행률·완료·진행중 + 여유칸)으로 즉시 요약",[66,296,297],{},"단계별 한 줄 리스트(이름·요약·진행률 게이지·건수) → 클릭 시 해당 섹션으로 스크롤",[66,299,300],{},"단계별 표는 Notion 데이터베이스 스타일 — 헤더 얇은 회색, 행 호버, 셀이 곧 인풋",[66,302,303,304,307],{},"우하단 플로팅 바로 자동 저장 상태 노출 (",[29,305,306],{},"수정 감지 → 저장 중 → 저장됨 · n초 전",")",[52,309],{},[55,311,313],{"id":312},"_3-데이터-모델","3. 데이터 모델",[315,316,318,319,321],"h3",{"id":317},"_3-1-wbsjson-스키마","3-1. ",[29,320,102],{}," 스키마",[323,324,329],"pre",{"className":325,"code":326,"language":327,"meta":328,"style":328},"language-ts shiki shiki-themes github-light github-dark","type Status = \"done\" | \"in_progress\" | \"pending\" | \"blocked\";\n\ntype Task = {\n  id: string;              \u002F\u002F 전역 유니크 (예: \"P1-3-9\")\n  taskNo: string;          \u002F\u002F 단계 내 표시용 번호 (예: \"3-9\")\n  title: string;\n  status: Status;\n  note: string | null;\n  targetDate: string | null;      \u002F\u002F \"YYYY-MM-DD\"\n  completionDate: string | null;  \u002F\u002F \"YYYY-MM-DD\"\n  deliverableUrl: string | null;\n};\n\ntype Stage = {\n  id: string;       \u002F\u002F \"P1-1\" 등\n  name: string;\n  weight: number;   \u002F\u002F 합계 100\n  progress: number; \u002F\u002F 0~100\n  summary: string;\n  tasks: Task[];\n};\n\ntype WbsDoc = {\n  _meta: {\n    lastUpdated: string;  \u002F\u002F \"YYYY-MM-DD\" — 저장 시 자동 갱신\n    project: string;\n    source: string;       \u002F\u002F 외부 참조 문서 경로 (예: \"doc\u002FWBS.md\")\n    editGuide: string;    \u002F\u002F 편집 가이드 한 줄\n  };\n  phase1: { stages: Stage[] };\n};\n","ts","",[29,330,331,371,378,391,412,428,440,452,469,489,508,524,530,535,547,562,574,591,607,619,632,637,642,654,664,679,691,706,722,728,749],{"__ignoreMap":328},[332,333,336,340,344,347,351,354,357,359,362,364,367],"span",{"class":334,"line":335},"line",1,[332,337,339],{"class":338},"szBVR","type",[332,341,343],{"class":342},"sScJk"," Status",[332,345,346],{"class":338}," =",[332,348,350],{"class":349},"sZZnC"," \"done\"",[332,352,353],{"class":338}," |",[332,355,356],{"class":349}," \"in_progress\"",[332,358,353],{"class":338},[332,360,361],{"class":349}," \"pending\"",[332,363,353],{"class":338},[332,365,366],{"class":349}," \"blocked\"",[332,368,370],{"class":369},"sVt8B",";\n",[332,372,374],{"class":334,"line":373},2,[332,375,377],{"emptyLinePlaceholder":376},true,"\n",[332,379,381,383,386,388],{"class":334,"line":380},3,[332,382,339],{"class":338},[332,384,385],{"class":342}," Task",[332,387,346],{"class":338},[332,389,390],{"class":369}," {\n",[332,392,394,398,401,405,408],{"class":334,"line":393},4,[332,395,397],{"class":396},"s4XuR","  id",[332,399,400],{"class":338},":",[332,402,404],{"class":403},"sj4cs"," string",[332,406,407],{"class":369},";              ",[332,409,411],{"class":410},"sJ8bj","\u002F\u002F 전역 유니크 (예: \"P1-3-9\")\n",[332,413,415,418,420,422,425],{"class":334,"line":414},5,[332,416,417],{"class":396},"  taskNo",[332,419,400],{"class":338},[332,421,404],{"class":403},[332,423,424],{"class":369},";          ",[332,426,427],{"class":410},"\u002F\u002F 단계 내 표시용 번호 (예: \"3-9\")\n",[332,429,431,434,436,438],{"class":334,"line":430},6,[332,432,433],{"class":396},"  title",[332,435,400],{"class":338},[332,437,404],{"class":403},[332,439,370],{"class":369},[332,441,443,446,448,450],{"class":334,"line":442},7,[332,444,445],{"class":396},"  status",[332,447,400],{"class":338},[332,449,343],{"class":342},[332,451,370],{"class":369},[332,453,455,458,460,462,464,467],{"class":334,"line":454},8,[332,456,457],{"class":396},"  note",[332,459,400],{"class":338},[332,461,404],{"class":403},[332,463,353],{"class":338},[332,465,466],{"class":403}," null",[332,468,370],{"class":369},[332,470,472,475,477,479,481,483,486],{"class":334,"line":471},9,[332,473,474],{"class":396},"  targetDate",[332,476,400],{"class":338},[332,478,404],{"class":403},[332,480,353],{"class":338},[332,482,466],{"class":403},[332,484,485],{"class":369},";      ",[332,487,488],{"class":410},"\u002F\u002F \"YYYY-MM-DD\"\n",[332,490,492,495,497,499,501,503,506],{"class":334,"line":491},10,[332,493,494],{"class":396},"  completionDate",[332,496,400],{"class":338},[332,498,404],{"class":403},[332,500,353],{"class":338},[332,502,466],{"class":403},[332,504,505],{"class":369},";  ",[332,507,488],{"class":410},[332,509,511,514,516,518,520,522],{"class":334,"line":510},11,[332,512,513],{"class":396},"  deliverableUrl",[332,515,400],{"class":338},[332,517,404],{"class":403},[332,519,353],{"class":338},[332,521,466],{"class":403},[332,523,370],{"class":369},[332,525,527],{"class":334,"line":526},12,[332,528,529],{"class":369},"};\n",[332,531,533],{"class":334,"line":532},13,[332,534,377],{"emptyLinePlaceholder":376},[332,536,538,540,543,545],{"class":334,"line":537},14,[332,539,339],{"class":338},[332,541,542],{"class":342}," Stage",[332,544,346],{"class":338},[332,546,390],{"class":369},[332,548,550,552,554,556,559],{"class":334,"line":549},15,[332,551,397],{"class":396},[332,553,400],{"class":338},[332,555,404],{"class":403},[332,557,558],{"class":369},";       ",[332,560,561],{"class":410},"\u002F\u002F \"P1-1\" 등\n",[332,563,565,568,570,572],{"class":334,"line":564},16,[332,566,567],{"class":396},"  name",[332,569,400],{"class":338},[332,571,404],{"class":403},[332,573,370],{"class":369},[332,575,577,580,582,585,588],{"class":334,"line":576},17,[332,578,579],{"class":396},"  weight",[332,581,400],{"class":338},[332,583,584],{"class":403}," number",[332,586,587],{"class":369},";   ",[332,589,590],{"class":410},"\u002F\u002F 합계 100\n",[332,592,594,597,599,601,604],{"class":334,"line":593},18,[332,595,596],{"class":396},"  progress",[332,598,400],{"class":338},[332,600,584],{"class":403},[332,602,603],{"class":369},"; ",[332,605,606],{"class":410},"\u002F\u002F 0~100\n",[332,608,610,613,615,617],{"class":334,"line":609},19,[332,611,612],{"class":396},"  summary",[332,614,400],{"class":338},[332,616,404],{"class":403},[332,618,370],{"class":369},[332,620,622,625,627,629],{"class":334,"line":621},20,[332,623,624],{"class":396},"  tasks",[332,626,400],{"class":338},[332,628,385],{"class":342},[332,630,631],{"class":369},"[];\n",[332,633,635],{"class":334,"line":634},21,[332,636,529],{"class":369},[332,638,640],{"class":334,"line":639},22,[332,641,377],{"emptyLinePlaceholder":376},[332,643,645,647,650,652],{"class":334,"line":644},23,[332,646,339],{"class":338},[332,648,649],{"class":342}," WbsDoc",[332,651,346],{"class":338},[332,653,390],{"class":369},[332,655,657,660,662],{"class":334,"line":656},24,[332,658,659],{"class":396},"  _meta",[332,661,400],{"class":338},[332,663,390],{"class":369},[332,665,667,670,672,674,676],{"class":334,"line":666},25,[332,668,669],{"class":396},"    lastUpdated",[332,671,400],{"class":338},[332,673,404],{"class":403},[332,675,505],{"class":369},[332,677,678],{"class":410},"\u002F\u002F \"YYYY-MM-DD\" — 저장 시 자동 갱신\n",[332,680,682,685,687,689],{"class":334,"line":681},26,[332,683,684],{"class":396},"    project",[332,686,400],{"class":338},[332,688,404],{"class":403},[332,690,370],{"class":369},[332,692,694,697,699,701,703],{"class":334,"line":693},27,[332,695,696],{"class":396},"    source",[332,698,400],{"class":338},[332,700,404],{"class":403},[332,702,558],{"class":369},[332,704,705],{"class":410},"\u002F\u002F 외부 참조 문서 경로 (예: \"doc\u002FWBS.md\")\n",[332,707,709,712,714,716,719],{"class":334,"line":708},28,[332,710,711],{"class":396},"    editGuide",[332,713,400],{"class":338},[332,715,404],{"class":403},[332,717,718],{"class":369},";    ",[332,720,721],{"class":410},"\u002F\u002F 편집 가이드 한 줄\n",[332,723,725],{"class":334,"line":724},29,[332,726,727],{"class":369},"  };\n",[332,729,731,734,736,739,742,744,746],{"class":334,"line":730},30,[332,732,733],{"class":396},"  phase1",[332,735,400],{"class":338},[332,737,738],{"class":369}," { ",[332,740,741],{"class":396},"stages",[332,743,400],{"class":338},[332,745,542],{"class":342},[332,747,748],{"class":369},"[] };\n",[332,750,752],{"class":334,"line":751},31,[332,753,529],{"class":369},[315,755,757,758,307],{"id":756},"_3-2-초기-시드-예시-publicwbsjson","3-2. 초기 시드 예시 (",[29,759,760],{},"public\u002Fwbs.json",[14,762,763],{},"R2가 비었을 때 fallback으로 한 번 읽힌 뒤, 첫 저장 때 R2에 복사된다. 이후 시드 파일은 사용되지 않는다.",[323,765,769],{"className":766,"code":767,"language":768,"meta":328,"style":328},"language-json shiki shiki-themes github-light github-dark","{\n  \"_meta\": {\n    \"lastUpdated\": \"2026-05-29\",\n    \"project\": \"Malgn Helper\",\n    \"source\": \"doc\u002FWBS.md\",\n    \"editGuide\": \"각 항목 수정 즉시 API(R2)에 자동 저장됨\"\n  },\n  \"phase1\": {\n    \"stages\": [\n      {\n        \"id\": \"P1-1\",\n        \"name\": \"착수 \u002F 분석\",\n        \"weight\": 10,\n        \"progress\": 70,\n        \"summary\": \"요구사항·범위·이해관계자 정리\",\n        \"tasks\": [\n          {\n            \"id\": \"P1-1-1\",\n            \"taskNo\": \"1-1\",\n            \"title\": \"이해관계자 인터뷰\",\n            \"status\": \"done\",\n            \"note\": null,\n            \"targetDate\": \"2026-05-20\",\n            \"completionDate\": \"2026-05-18\",\n            \"deliverableUrl\": null\n          }\n        ]\n      }\n    ]\n  }\n}\n","json",[29,770,771,776,784,798,810,822,832,837,844,852,857,869,881,893,905,917,924,929,941,953,965,977,989,1001,1013,1023,1028,1033,1038,1043,1048],{"__ignoreMap":328},[332,772,773],{"class":334,"line":335},[332,774,775],{"class":369},"{\n",[332,777,778,781],{"class":334,"line":373},[332,779,780],{"class":403},"  \"_meta\"",[332,782,783],{"class":369},": {\n",[332,785,786,789,792,795],{"class":334,"line":380},[332,787,788],{"class":403},"    \"lastUpdated\"",[332,790,791],{"class":369},": ",[332,793,794],{"class":349},"\"2026-05-29\"",[332,796,797],{"class":369},",\n",[332,799,800,803,805,808],{"class":334,"line":393},[332,801,802],{"class":403},"    \"project\"",[332,804,791],{"class":369},[332,806,807],{"class":349},"\"Malgn Helper\"",[332,809,797],{"class":369},[332,811,812,815,817,820],{"class":334,"line":414},[332,813,814],{"class":403},"    \"source\"",[332,816,791],{"class":369},[332,818,819],{"class":349},"\"doc\u002FWBS.md\"",[332,821,797],{"class":369},[332,823,824,827,829],{"class":334,"line":430},[332,825,826],{"class":403},"    \"editGuide\"",[332,828,791],{"class":369},[332,830,831],{"class":349},"\"각 항목 수정 즉시 API(R2)에 자동 저장됨\"\n",[332,833,834],{"class":334,"line":442},[332,835,836],{"class":369},"  },\n",[332,838,839,842],{"class":334,"line":454},[332,840,841],{"class":403},"  \"phase1\"",[332,843,783],{"class":369},[332,845,846,849],{"class":334,"line":471},[332,847,848],{"class":403},"    \"stages\"",[332,850,851],{"class":369},": [\n",[332,853,854],{"class":334,"line":491},[332,855,856],{"class":369},"      {\n",[332,858,859,862,864,867],{"class":334,"line":510},[332,860,861],{"class":403},"        \"id\"",[332,863,791],{"class":369},[332,865,866],{"class":349},"\"P1-1\"",[332,868,797],{"class":369},[332,870,871,874,876,879],{"class":334,"line":526},[332,872,873],{"class":403},"        \"name\"",[332,875,791],{"class":369},[332,877,878],{"class":349},"\"착수 \u002F 분석\"",[332,880,797],{"class":369},[332,882,883,886,888,891],{"class":334,"line":532},[332,884,885],{"class":403},"        \"weight\"",[332,887,791],{"class":369},[332,889,890],{"class":403},"10",[332,892,797],{"class":369},[332,894,895,898,900,903],{"class":334,"line":537},[332,896,897],{"class":403},"        \"progress\"",[332,899,791],{"class":369},[332,901,902],{"class":403},"70",[332,904,797],{"class":369},[332,906,907,910,912,915],{"class":334,"line":549},[332,908,909],{"class":403},"        \"summary\"",[332,911,791],{"class":369},[332,913,914],{"class":349},"\"요구사항·범위·이해관계자 정리\"",[332,916,797],{"class":369},[332,918,919,922],{"class":334,"line":564},[332,920,921],{"class":403},"        \"tasks\"",[332,923,851],{"class":369},[332,925,926],{"class":334,"line":576},[332,927,928],{"class":369},"          {\n",[332,930,931,934,936,939],{"class":334,"line":593},[332,932,933],{"class":403},"            \"id\"",[332,935,791],{"class":369},[332,937,938],{"class":349},"\"P1-1-1\"",[332,940,797],{"class":369},[332,942,943,946,948,951],{"class":334,"line":609},[332,944,945],{"class":403},"            \"taskNo\"",[332,947,791],{"class":369},[332,949,950],{"class":349},"\"1-1\"",[332,952,797],{"class":369},[332,954,955,958,960,963],{"class":334,"line":621},[332,956,957],{"class":403},"            \"title\"",[332,959,791],{"class":369},[332,961,962],{"class":349},"\"이해관계자 인터뷰\"",[332,964,797],{"class":369},[332,966,967,970,972,975],{"class":334,"line":634},[332,968,969],{"class":403},"            \"status\"",[332,971,791],{"class":369},[332,973,974],{"class":349},"\"done\"",[332,976,797],{"class":369},[332,978,979,982,984,987],{"class":334,"line":639},[332,980,981],{"class":403},"            \"note\"",[332,983,791],{"class":369},[332,985,986],{"class":403},"null",[332,988,797],{"class":369},[332,990,991,994,996,999],{"class":334,"line":644},[332,992,993],{"class":403},"            \"targetDate\"",[332,995,791],{"class":369},[332,997,998],{"class":349},"\"2026-05-20\"",[332,1000,797],{"class":369},[332,1002,1003,1006,1008,1011],{"class":334,"line":656},[332,1004,1005],{"class":403},"            \"completionDate\"",[332,1007,791],{"class":369},[332,1009,1010],{"class":349},"\"2026-05-18\"",[332,1012,797],{"class":369},[332,1014,1015,1018,1020],{"class":334,"line":666},[332,1016,1017],{"class":403},"            \"deliverableUrl\"",[332,1019,791],{"class":369},[332,1021,1022],{"class":403},"null\n",[332,1024,1025],{"class":334,"line":681},[332,1026,1027],{"class":369},"          }\n",[332,1029,1030],{"class":334,"line":693},[332,1031,1032],{"class":369},"        ]\n",[332,1034,1035],{"class":334,"line":708},[332,1036,1037],{"class":369},"      }\n",[332,1039,1040],{"class":334,"line":724},[332,1041,1042],{"class":369},"    ]\n",[332,1044,1045],{"class":334,"line":730},[332,1046,1047],{"class":369},"  }\n",[332,1049,1050],{"class":334,"line":751},[332,1051,1052],{"class":369},"}\n",[315,1054,1056],{"id":1055},"_3-3-비즈니스-규칙","3-3. 비즈니스 규칙",[63,1058,1059,1064,1069],{},[66,1060,1061],{},[29,1062,1063],{},"weightedAverage = round(Σ(stage.progress × stage.weight) \u002F Σ(stage.weight), 0.1)",[66,1065,1066],{},[29,1067,1068],{},"isOverdue(task) = task.status !== \"done\" && task.targetDate && task.targetDate \u003C _meta.lastUpdated",[66,1070,1071,1072,1074],{},"빈 문자열은 모두 ",[29,1073,986],{},"로 정규화 (입력값 ↔ JSON 직렬화 안정성)",[52,1076],{},[55,1078,1080],{"id":1079},"_4-아키텍처","4. 아키텍처",[323,1082,1087],{"className":1083,"code":1085,"language":1086},[1084],"language-text","브라우저 (Nuxt 페이지 \u002Fwbs)\n    │\n    │  GET  \u002Fwbs   ← 초기 로드\n    │  PUT  \u002Fwbs   ← 800ms 디바운스 후\n    ▼\n\u003Capi> Worker (Hono on Cloudflare Workers)\n    │\n    │  R2.get(\"wbs\u002Fwbs.json\")\n    │  R2.put(\"wbs\u002Fwbs.json\", body)\n    ▼\nCloudflare R2 bucket\n","text",[29,1088,1085],{"__ignoreMap":328},[14,1090,1091],{},[18,1092,1093],{},"핵심 결정",[63,1095,1096,1106,1112,1118,1128],{},[66,1097,1098,1101,1102,1105],{},[18,1099,1100],{},"R2 단일 객체","(",[29,1103,1104],{},"wbs\u002Fwbs.json",")에 전체 문서를 통째로 저장. 동시 편집은 가정하지 않음(team 내부 도구).",[66,1107,1108,1111],{},[18,1109,1110],{},"DB 미사용",". WBS 1건만 다루므로 D1\u002FMySQL은 과도. R2 + JSON으로 충분.",[66,1113,1114,1117],{},[18,1115,1116],{},"localStorage 미사용",". 자동 저장 + 공유가 목표이므로 클라이언트 로컬 상태는 두지 않음.",[66,1119,1120,1127],{},[18,1121,1122,1123,1126],{},"초기 시드는 ",[29,1124,1125],{},"public\u002F","에 정적 호스팅"," → R2 비었을 때 1회만 사용.",[66,1129,1130,1133],{},[18,1131,1132],{},"인증은 의도적으로 생략","(MVP). 사내 운영자만 URL을 알도록 운영. 필요 시 Cloudflare Access로 페이지 + API 동시 보호.",[52,1135],{},[55,1137,1139],{"id":1138},"_5-백엔드-구현-hono-on-workers","5. 백엔드 구현 (Hono on Workers)",[315,1141,1143,1144],{"id":1142},"_5-1-wranglerjsonc","5-1. ",[29,1145,1146],{},"wrangler.jsonc",[323,1148,1152],{"className":1149,"code":1150,"language":1151,"meta":328,"style":328},"language-jsonc shiki shiki-themes github-light github-dark","{\n  \"$schema\": \"https:\u002F\u002Fjson.schemastore.org\u002Fwrangler.json\",\n  \"name\": \"\u003Capi-worker-name>\",\n  \"account_id\": \"\u003Cyour-account-id>\",\n  \"main\": \"src\u002Findex.ts\",\n  \"compatibility_date\": \"2026-05-27\",\n  \"compatibility_flags\": [\"nodejs_compat\"],\n  \"observability\": { \"enabled\": true },\n\n  \"r2_buckets\": [\n    { \"binding\": \"R2\", \"bucket_name\": \"\u003Cyour-r2-bucket>\" }\n  ]\n}\n","jsonc",[29,1153,1154,1158,1163,1168,1173,1178,1183,1188,1193,1197,1202,1207,1212],{"__ignoreMap":328},[332,1155,1156],{"class":334,"line":335},[332,1157,775],{},[332,1159,1160],{"class":334,"line":373},[332,1161,1162],{},"  \"$schema\": \"https:\u002F\u002Fjson.schemastore.org\u002Fwrangler.json\",\n",[332,1164,1165],{"class":334,"line":380},[332,1166,1167],{},"  \"name\": \"\u003Capi-worker-name>\",\n",[332,1169,1170],{"class":334,"line":393},[332,1171,1172],{},"  \"account_id\": \"\u003Cyour-account-id>\",\n",[332,1174,1175],{"class":334,"line":414},[332,1176,1177],{},"  \"main\": \"src\u002Findex.ts\",\n",[332,1179,1180],{"class":334,"line":430},[332,1181,1182],{},"  \"compatibility_date\": \"2026-05-27\",\n",[332,1184,1185],{"class":334,"line":442},[332,1186,1187],{},"  \"compatibility_flags\": [\"nodejs_compat\"],\n",[332,1189,1190],{"class":334,"line":454},[332,1191,1192],{},"  \"observability\": { \"enabled\": true },\n",[332,1194,1195],{"class":334,"line":471},[332,1196,377],{"emptyLinePlaceholder":376},[332,1198,1199],{"class":334,"line":491},[332,1200,1201],{},"  \"r2_buckets\": [\n",[332,1203,1204],{"class":334,"line":510},[332,1205,1206],{},"    { \"binding\": \"R2\", \"bucket_name\": \"\u003Cyour-r2-bucket>\" }\n",[332,1208,1209],{"class":334,"line":526},[332,1210,1211],{},"  ]\n",[332,1213,1214],{"class":334,"line":532},[332,1215,1052],{},[315,1217,1219,1220,1223],{"id":1218},"_5-2-srcindexts-전체","5-2. ",[29,1221,1222],{},"src\u002Findex.ts"," (전체)",[323,1225,1227],{"className":325,"code":1226,"language":327,"meta":328,"style":328},"import { Hono } from \"hono\";\nimport { cors } from \"hono\u002Fcors\";\n\ntype Bindings = {\n  R2: R2Bucket;\n};\n\nconst app = new Hono\u003C{ Bindings: Bindings }>();\n\napp.use(\n  \"*\",\n  cors({\n    origin: (origin) => {\n      if (!origin) return \"*\";\n      if (\u002F\\.pages\\.dev$\u002F.test(origin)) return origin;\n      if (\u002F\\.malgnsoft\\.com$\u002F.test(origin)) return origin;   \u002F\u002F ← 자기 도메인 패턴으로 교체\n      if (\u002F^https?:\\\u002F\\\u002F(localhost|127\\.0\\.0\\.1)(:\\d+)?$\u002F.test(origin)) return origin;\n      return null;\n    },\n    allowMethods: [\"GET\", \"PUT\", \"POST\", \"OPTIONS\"],\n    allowHeaders: [\"Content-Type\"],\n    maxAge: 86400,\n  }),\n);\n\napp.get(\"\u002F\", (c) => c.json({ name: \"wbs-api\", status: \"ok\" }));\napp.get(\"\u002Fhealthz\", (c) => c.json({ ok: true }));\n\nconst WBS_KEY = \"wbs\u002Fwbs.json\";\n\napp.get(\"\u002Fwbs\", async (c) => {\n  const obj = await c.env.R2.get(WBS_KEY);\n  if (!obj) return c.json({ exists: false }, 404);\n  const body = await obj.text();\n  return new Response(body, {\n    headers: {\n      \"Content-Type\": \"application\u002Fjson; charset=utf-8\",\n      \"Cache-Control\": \"no-store\",\n      ETag: obj.httpEtag,\n    },\n  });\n});\n\napp.put(\"\u002Fwbs\", async (c) => {\n  const text = await c.req.text();\n  try {\n    JSON.parse(text);\n  } catch {\n    return c.json({ error: \"invalid json\" }, 400);\n  }\n  if (text.length > 1_000_000) {\n    return c.json({ error: \"payload too large\" }, 413);\n  }\n  await c.env.R2.put(WBS_KEY, text, {\n    httpMetadata: { contentType: \"application\u002Fjson; charset=utf-8\" },\n  });\n  return c.json({ ok: true, size: text.length, savedAt: new Date().toISOString() });\n});\n\nexport default app;\n",[29,1228,1229,1245,1259,1263,1274,1286,1290,1294,1323,1327,1338,1345,1353,1372,1394,1435,1471,1539,1548,1553,1580,1590,1600,1605,1610,1614,1656,1687,1691,1705,1709,1735,1766,1799,1819,1833,1839,1852,1865,1871,1876,1882,1888,1893,1919,1938,1946,1960,1971,1994,1999,2019,2040,2045,2066,2077,2082,2118,2123,2128],{"__ignoreMap":328},[332,1230,1231,1234,1237,1240,1243],{"class":334,"line":335},[332,1232,1233],{"class":338},"import",[332,1235,1236],{"class":369}," { Hono } ",[332,1238,1239],{"class":338},"from",[332,1241,1242],{"class":349}," \"hono\"",[332,1244,370],{"class":369},[332,1246,1247,1249,1252,1254,1257],{"class":334,"line":373},[332,1248,1233],{"class":338},[332,1250,1251],{"class":369}," { cors } ",[332,1253,1239],{"class":338},[332,1255,1256],{"class":349}," \"hono\u002Fcors\"",[332,1258,370],{"class":369},[332,1260,1261],{"class":334,"line":380},[332,1262,377],{"emptyLinePlaceholder":376},[332,1264,1265,1267,1270,1272],{"class":334,"line":393},[332,1266,339],{"class":338},[332,1268,1269],{"class":342}," Bindings",[332,1271,346],{"class":338},[332,1273,390],{"class":369},[332,1275,1276,1279,1281,1284],{"class":334,"line":414},[332,1277,1278],{"class":396},"  R2",[332,1280,400],{"class":338},[332,1282,1283],{"class":342}," R2Bucket",[332,1285,370],{"class":369},[332,1287,1288],{"class":334,"line":430},[332,1289,529],{"class":369},[332,1291,1292],{"class":334,"line":442},[332,1293,377],{"emptyLinePlaceholder":376},[332,1295,1296,1299,1302,1304,1307,1310,1313,1316,1318,1320],{"class":334,"line":454},[332,1297,1298],{"class":338},"const",[332,1300,1301],{"class":403}," app",[332,1303,346],{"class":338},[332,1305,1306],{"class":338}," new",[332,1308,1309],{"class":342}," Hono",[332,1311,1312],{"class":369},"\u003C{ ",[332,1314,1315],{"class":396},"Bindings",[332,1317,400],{"class":338},[332,1319,1269],{"class":342},[332,1321,1322],{"class":369}," }>();\n",[332,1324,1325],{"class":334,"line":471},[332,1326,377],{"emptyLinePlaceholder":376},[332,1328,1329,1332,1335],{"class":334,"line":491},[332,1330,1331],{"class":369},"app.",[332,1333,1334],{"class":342},"use",[332,1336,1337],{"class":369},"(\n",[332,1339,1340,1343],{"class":334,"line":510},[332,1341,1342],{"class":349},"  \"*\"",[332,1344,797],{"class":369},[332,1346,1347,1350],{"class":334,"line":526},[332,1348,1349],{"class":342},"  cors",[332,1351,1352],{"class":369},"({\n",[332,1354,1355,1358,1361,1364,1367,1370],{"class":334,"line":532},[332,1356,1357],{"class":342},"    origin",[332,1359,1360],{"class":369},": (",[332,1362,1363],{"class":396},"origin",[332,1365,1366],{"class":369},") ",[332,1368,1369],{"class":338},"=>",[332,1371,390],{"class":369},[332,1373,1374,1377,1380,1383,1386,1389,1392],{"class":334,"line":537},[332,1375,1376],{"class":338},"      if",[332,1378,1379],{"class":369}," (",[332,1381,1382],{"class":338},"!",[332,1384,1385],{"class":369},"origin) ",[332,1387,1388],{"class":338},"return",[332,1390,1391],{"class":349}," \"*\"",[332,1393,370],{"class":369},[332,1395,1396,1398,1400,1403,1407,1411,1413,1416,1419,1421,1424,1427,1430,1432],{"class":334,"line":549},[332,1397,1376],{"class":338},[332,1399,1379],{"class":369},[332,1401,1402],{"class":349},"\u002F",[332,1404,1406],{"class":1405},"snhLl","\\.",[332,1408,1410],{"class":1409},"sA_wV","pages",[332,1412,1406],{"class":1405},[332,1414,1415],{"class":1409},"dev",[332,1417,1418],{"class":338},"$",[332,1420,1402],{"class":349},[332,1422,1423],{"class":369},".",[332,1425,1426],{"class":342},"test",[332,1428,1429],{"class":369},"(origin)) ",[332,1431,1388],{"class":338},[332,1433,1434],{"class":369}," origin;\n",[332,1436,1437,1439,1441,1443,1445,1448,1450,1453,1455,1457,1459,1461,1463,1465,1468],{"class":334,"line":564},[332,1438,1376],{"class":338},[332,1440,1379],{"class":369},[332,1442,1402],{"class":349},[332,1444,1406],{"class":1405},[332,1446,1447],{"class":1409},"malgnsoft",[332,1449,1406],{"class":1405},[332,1451,1452],{"class":1409},"com",[332,1454,1418],{"class":338},[332,1456,1402],{"class":349},[332,1458,1423],{"class":369},[332,1460,1426],{"class":342},[332,1462,1429],{"class":369},[332,1464,1388],{"class":338},[332,1466,1467],{"class":369}," origin;   ",[332,1469,1470],{"class":410},"\u002F\u002F ← 자기 도메인 패턴으로 교체\n",[332,1472,1473,1475,1477,1479,1482,1485,1488,1490,1493,1496,1499,1502,1504,1507,1509,1511,1513,1516,1519,1522,1524,1527,1529,1531,1533,1535,1537],{"class":334,"line":576},[332,1474,1376],{"class":338},[332,1476,1379],{"class":369},[332,1478,1402],{"class":349},[332,1480,1481],{"class":338},"^",[332,1483,1484],{"class":1409},"https",[332,1486,1487],{"class":338},"?",[332,1489,400],{"class":1409},[332,1491,1492],{"class":1405},"\\\u002F\\\u002F",[332,1494,1495],{"class":1409},"(localhost",[332,1497,1498],{"class":338},"|",[332,1500,1501],{"class":1409},"127",[332,1503,1406],{"class":1405},[332,1505,1506],{"class":1409},"0",[332,1508,1406],{"class":1405},[332,1510,1506],{"class":1409},[332,1512,1406],{"class":1405},[332,1514,1515],{"class":1409},"1)(:",[332,1517,1518],{"class":403},"\\d",[332,1520,1521],{"class":338},"+",[332,1523,307],{"class":1409},[332,1525,1526],{"class":338},"?$",[332,1528,1402],{"class":349},[332,1530,1423],{"class":369},[332,1532,1426],{"class":342},[332,1534,1429],{"class":369},[332,1536,1388],{"class":338},[332,1538,1434],{"class":369},[332,1540,1541,1544,1546],{"class":334,"line":593},[332,1542,1543],{"class":338},"      return",[332,1545,466],{"class":403},[332,1547,370],{"class":369},[332,1549,1550],{"class":334,"line":609},[332,1551,1552],{"class":369},"    },\n",[332,1554,1555,1558,1561,1564,1567,1569,1572,1574,1577],{"class":334,"line":621},[332,1556,1557],{"class":369},"    allowMethods: [",[332,1559,1560],{"class":349},"\"GET\"",[332,1562,1563],{"class":369},", ",[332,1565,1566],{"class":349},"\"PUT\"",[332,1568,1563],{"class":369},[332,1570,1571],{"class":349},"\"POST\"",[332,1573,1563],{"class":369},[332,1575,1576],{"class":349},"\"OPTIONS\"",[332,1578,1579],{"class":369},"],\n",[332,1581,1582,1585,1588],{"class":334,"line":634},[332,1583,1584],{"class":369},"    allowHeaders: [",[332,1586,1587],{"class":349},"\"Content-Type\"",[332,1589,1579],{"class":369},[332,1591,1592,1595,1598],{"class":334,"line":639},[332,1593,1594],{"class":369},"    maxAge: ",[332,1596,1597],{"class":403},"86400",[332,1599,797],{"class":369},[332,1601,1602],{"class":334,"line":644},[332,1603,1604],{"class":369},"  }),\n",[332,1606,1607],{"class":334,"line":656},[332,1608,1609],{"class":369},");\n",[332,1611,1612],{"class":334,"line":666},[332,1613,377],{"emptyLinePlaceholder":376},[332,1615,1616,1618,1621,1623,1626,1629,1632,1634,1636,1639,1641,1644,1647,1650,1653],{"class":334,"line":681},[332,1617,1331],{"class":369},[332,1619,1620],{"class":342},"get",[332,1622,1101],{"class":369},[332,1624,1625],{"class":349},"\"\u002F\"",[332,1627,1628],{"class":369},", (",[332,1630,1631],{"class":396},"c",[332,1633,1366],{"class":369},[332,1635,1369],{"class":338},[332,1637,1638],{"class":369}," c.",[332,1640,768],{"class":342},[332,1642,1643],{"class":369},"({ name: ",[332,1645,1646],{"class":349},"\"wbs-api\"",[332,1648,1649],{"class":369},", status: ",[332,1651,1652],{"class":349},"\"ok\"",[332,1654,1655],{"class":369}," }));\n",[332,1657,1658,1660,1662,1664,1667,1669,1671,1673,1675,1677,1679,1682,1685],{"class":334,"line":693},[332,1659,1331],{"class":369},[332,1661,1620],{"class":342},[332,1663,1101],{"class":369},[332,1665,1666],{"class":349},"\"\u002Fhealthz\"",[332,1668,1628],{"class":369},[332,1670,1631],{"class":396},[332,1672,1366],{"class":369},[332,1674,1369],{"class":338},[332,1676,1638],{"class":369},[332,1678,768],{"class":342},[332,1680,1681],{"class":369},"({ ok: ",[332,1683,1684],{"class":403},"true",[332,1686,1655],{"class":369},[332,1688,1689],{"class":334,"line":708},[332,1690,377],{"emptyLinePlaceholder":376},[332,1692,1693,1695,1698,1700,1703],{"class":334,"line":724},[332,1694,1298],{"class":338},[332,1696,1697],{"class":403}," WBS_KEY",[332,1699,346],{"class":338},[332,1701,1702],{"class":349}," \"wbs\u002Fwbs.json\"",[332,1704,370],{"class":369},[332,1706,1707],{"class":334,"line":730},[332,1708,377],{"emptyLinePlaceholder":376},[332,1710,1711,1713,1715,1717,1720,1722,1725,1727,1729,1731,1733],{"class":334,"line":751},[332,1712,1331],{"class":369},[332,1714,1620],{"class":342},[332,1716,1101],{"class":369},[332,1718,1719],{"class":349},"\"\u002Fwbs\"",[332,1721,1563],{"class":369},[332,1723,1724],{"class":338},"async",[332,1726,1379],{"class":369},[332,1728,1631],{"class":396},[332,1730,1366],{"class":369},[332,1732,1369],{"class":338},[332,1734,390],{"class":369},[332,1736,1738,1741,1744,1746,1749,1752,1755,1757,1759,1761,1764],{"class":334,"line":1737},32,[332,1739,1740],{"class":338},"  const",[332,1742,1743],{"class":403}," obj",[332,1745,346],{"class":338},[332,1747,1748],{"class":338}," await",[332,1750,1751],{"class":369}," c.env.",[332,1753,1754],{"class":403},"R2",[332,1756,1423],{"class":369},[332,1758,1620],{"class":342},[332,1760,1101],{"class":369},[332,1762,1763],{"class":403},"WBS_KEY",[332,1765,1609],{"class":369},[332,1767,1769,1772,1774,1776,1779,1781,1783,1785,1788,1791,1794,1797],{"class":334,"line":1768},33,[332,1770,1771],{"class":338},"  if",[332,1773,1379],{"class":369},[332,1775,1382],{"class":338},[332,1777,1778],{"class":369},"obj) ",[332,1780,1388],{"class":338},[332,1782,1638],{"class":369},[332,1784,768],{"class":342},[332,1786,1787],{"class":369},"({ exists: ",[332,1789,1790],{"class":403},"false",[332,1792,1793],{"class":369}," }, ",[332,1795,1796],{"class":403},"404",[332,1798,1609],{"class":369},[332,1800,1802,1804,1807,1809,1811,1814,1816],{"class":334,"line":1801},34,[332,1803,1740],{"class":338},[332,1805,1806],{"class":403}," body",[332,1808,346],{"class":338},[332,1810,1748],{"class":338},[332,1812,1813],{"class":369}," obj.",[332,1815,1086],{"class":342},[332,1817,1818],{"class":369},"();\n",[332,1820,1822,1825,1827,1830],{"class":334,"line":1821},35,[332,1823,1824],{"class":338},"  return",[332,1826,1306],{"class":338},[332,1828,1829],{"class":342}," Response",[332,1831,1832],{"class":369},"(body, {\n",[332,1834,1836],{"class":334,"line":1835},36,[332,1837,1838],{"class":369},"    headers: {\n",[332,1840,1842,1845,1847,1850],{"class":334,"line":1841},37,[332,1843,1844],{"class":349},"      \"Content-Type\"",[332,1846,791],{"class":369},[332,1848,1849],{"class":349},"\"application\u002Fjson; charset=utf-8\"",[332,1851,797],{"class":369},[332,1853,1855,1858,1860,1863],{"class":334,"line":1854},38,[332,1856,1857],{"class":349},"      \"Cache-Control\"",[332,1859,791],{"class":369},[332,1861,1862],{"class":349},"\"no-store\"",[332,1864,797],{"class":369},[332,1866,1868],{"class":334,"line":1867},39,[332,1869,1870],{"class":369},"      ETag: obj.httpEtag,\n",[332,1872,1874],{"class":334,"line":1873},40,[332,1875,1552],{"class":369},[332,1877,1879],{"class":334,"line":1878},41,[332,1880,1881],{"class":369},"  });\n",[332,1883,1885],{"class":334,"line":1884},42,[332,1886,1887],{"class":369},"});\n",[332,1889,1891],{"class":334,"line":1890},43,[332,1892,377],{"emptyLinePlaceholder":376},[332,1894,1896,1898,1901,1903,1905,1907,1909,1911,1913,1915,1917],{"class":334,"line":1895},44,[332,1897,1331],{"class":369},[332,1899,1900],{"class":342},"put",[332,1902,1101],{"class":369},[332,1904,1719],{"class":349},[332,1906,1563],{"class":369},[332,1908,1724],{"class":338},[332,1910,1379],{"class":369},[332,1912,1631],{"class":396},[332,1914,1366],{"class":369},[332,1916,1369],{"class":338},[332,1918,390],{"class":369},[332,1920,1922,1924,1927,1929,1931,1934,1936],{"class":334,"line":1921},45,[332,1923,1740],{"class":338},[332,1925,1926],{"class":403}," text",[332,1928,346],{"class":338},[332,1930,1748],{"class":338},[332,1932,1933],{"class":369}," c.req.",[332,1935,1086],{"class":342},[332,1937,1818],{"class":369},[332,1939,1941,1944],{"class":334,"line":1940},46,[332,1942,1943],{"class":338},"  try",[332,1945,390],{"class":369},[332,1947,1949,1952,1954,1957],{"class":334,"line":1948},47,[332,1950,1951],{"class":403},"    JSON",[332,1953,1423],{"class":369},[332,1955,1956],{"class":342},"parse",[332,1958,1959],{"class":369},"(text);\n",[332,1961,1963,1966,1969],{"class":334,"line":1962},48,[332,1964,1965],{"class":369},"  } ",[332,1967,1968],{"class":338},"catch",[332,1970,390],{"class":369},[332,1972,1974,1977,1979,1981,1984,1987,1989,1992],{"class":334,"line":1973},49,[332,1975,1976],{"class":338},"    return",[332,1978,1638],{"class":369},[332,1980,768],{"class":342},[332,1982,1983],{"class":369},"({ error: ",[332,1985,1986],{"class":349},"\"invalid json\"",[332,1988,1793],{"class":369},[332,1990,1991],{"class":403},"400",[332,1993,1609],{"class":369},[332,1995,1997],{"class":334,"line":1996},50,[332,1998,1047],{"class":369},[332,2000,2002,2004,2007,2010,2013,2016],{"class":334,"line":2001},51,[332,2003,1771],{"class":338},[332,2005,2006],{"class":369}," (text.",[332,2008,2009],{"class":403},"length",[332,2011,2012],{"class":338}," >",[332,2014,2015],{"class":403}," 1_000_000",[332,2017,2018],{"class":369},") {\n",[332,2020,2022,2024,2026,2028,2030,2033,2035,2038],{"class":334,"line":2021},52,[332,2023,1976],{"class":338},[332,2025,1638],{"class":369},[332,2027,768],{"class":342},[332,2029,1983],{"class":369},[332,2031,2032],{"class":349},"\"payload too large\"",[332,2034,1793],{"class":369},[332,2036,2037],{"class":403},"413",[332,2039,1609],{"class":369},[332,2041,2043],{"class":334,"line":2042},53,[332,2044,1047],{"class":369},[332,2046,2048,2051,2053,2055,2057,2059,2061,2063],{"class":334,"line":2047},54,[332,2049,2050],{"class":338},"  await",[332,2052,1751],{"class":369},[332,2054,1754],{"class":403},[332,2056,1423],{"class":369},[332,2058,1900],{"class":342},[332,2060,1101],{"class":369},[332,2062,1763],{"class":403},[332,2064,2065],{"class":369},", text, {\n",[332,2067,2069,2072,2074],{"class":334,"line":2068},55,[332,2070,2071],{"class":369},"    httpMetadata: { contentType: ",[332,2073,1849],{"class":349},[332,2075,2076],{"class":369}," },\n",[332,2078,2080],{"class":334,"line":2079},56,[332,2081,1881],{"class":369},[332,2083,2085,2087,2089,2091,2093,2095,2098,2100,2103,2106,2109,2112,2115],{"class":334,"line":2084},57,[332,2086,1824],{"class":338},[332,2088,1638],{"class":369},[332,2090,768],{"class":342},[332,2092,1681],{"class":369},[332,2094,1684],{"class":403},[332,2096,2097],{"class":369},", size: text.",[332,2099,2009],{"class":403},[332,2101,2102],{"class":369},", savedAt: ",[332,2104,2105],{"class":338},"new",[332,2107,2108],{"class":342}," Date",[332,2110,2111],{"class":369},"().",[332,2113,2114],{"class":342},"toISOString",[332,2116,2117],{"class":369},"() });\n",[332,2119,2121],{"class":334,"line":2120},58,[332,2122,1887],{"class":369},[332,2124,2126],{"class":334,"line":2125},59,[332,2127,377],{"emptyLinePlaceholder":376},[332,2129,2131,2134,2137],{"class":334,"line":2130},60,[332,2132,2133],{"class":338},"export",[332,2135,2136],{"class":338}," default",[332,2138,2139],{"class":369}," app;\n",[315,2141,2143,2144,2147],{"id":2142},"_5-3-packagejson-최소-의존","5-3. ",[29,2145,2146],{},"package.json"," 최소 의존",[323,2149,2151],{"className":766,"code":2150,"language":768,"meta":328,"style":328},"{\n  \"dependencies\": { \"hono\": \"^4.0.0\" },\n  \"devDependencies\": { \"wrangler\": \"^4.0.0\", \"typescript\": \"^5.0.0\" }\n}\n",[29,2152,2153,2157,2175,2202],{"__ignoreMap":328},[332,2154,2155],{"class":334,"line":335},[332,2156,775],{"class":369},[332,2158,2159,2162,2165,2168,2170,2173],{"class":334,"line":373},[332,2160,2161],{"class":403},"  \"dependencies\"",[332,2163,2164],{"class":369},": { ",[332,2166,2167],{"class":403},"\"hono\"",[332,2169,791],{"class":369},[332,2171,2172],{"class":349},"\"^4.0.0\"",[332,2174,2076],{"class":369},[332,2176,2177,2180,2182,2185,2187,2189,2191,2194,2196,2199],{"class":334,"line":380},[332,2178,2179],{"class":403},"  \"devDependencies\"",[332,2181,2164],{"class":369},[332,2183,2184],{"class":403},"\"wrangler\"",[332,2186,791],{"class":369},[332,2188,2172],{"class":349},[332,2190,1563],{"class":369},[332,2192,2193],{"class":403},"\"typescript\"",[332,2195,791],{"class":369},[332,2197,2198],{"class":349},"\"^5.0.0\"",[332,2200,2201],{"class":369}," }\n",[332,2203,2204],{"class":334,"line":393},[332,2205,1052],{"class":369},[315,2207,2209],{"id":2208},"_5-4-셋업배포","5-4. 셋업·배포",[323,2211,2215],{"className":2212,"code":2213,"language":2214,"meta":328,"style":328},"language-bash shiki shiki-themes github-light github-dark","# 1) R2 버킷 (대화형 프롬프트가 떠도 자동 거절)\necho \"no\" | wrangler r2 bucket create \u003Cyour-r2-bucket>\n\n# 2) 배포\npnpm run deploy\n# → 배포 URL: https:\u002F\u002F\u003Cworker-name>.\u003Csubdomain>.workers.dev\n","bash",[29,2216,2217,2222,2256,2260,2265,2276],{"__ignoreMap":328},[332,2218,2219],{"class":334,"line":335},[332,2220,2221],{"class":410},"# 1) R2 버킷 (대화형 프롬프트가 떠도 자동 거절)\n",[332,2223,2224,2227,2230,2232,2235,2238,2241,2244,2247,2250,2253],{"class":334,"line":373},[332,2225,2226],{"class":403},"echo",[332,2228,2229],{"class":349}," \"no\"",[332,2231,353],{"class":338},[332,2233,2234],{"class":342}," wrangler",[332,2236,2237],{"class":349}," r2",[332,2239,2240],{"class":349}," bucket",[332,2242,2243],{"class":349}," create",[332,2245,2246],{"class":338}," \u003C",[332,2248,2249],{"class":349},"your-r2-bucke",[332,2251,2252],{"class":369},"t",[332,2254,2255],{"class":338},">\n",[332,2257,2258],{"class":334,"line":380},[332,2259,377],{"emptyLinePlaceholder":376},[332,2261,2262],{"class":334,"line":393},[332,2263,2264],{"class":410},"# 2) 배포\n",[332,2266,2267,2270,2273],{"class":334,"line":414},[332,2268,2269],{"class":342},"pnpm",[332,2271,2272],{"class":349}," run",[332,2274,2275],{"class":349}," deploy\n",[332,2277,2278],{"class":334,"line":430},[332,2279,2280],{"class":410},"# → 배포 URL: https:\u002F\u002F\u003Cworker-name>.\u003Csubdomain>.workers.dev\n",[315,2282,2284],{"id":2283},"_5-5-스모크-테스트","5-5. 스모크 테스트",[323,2286,2288],{"className":2212,"code":2287,"language":2214,"meta":328,"style":328},"curl -i https:\u002F\u002F\u003Capi>\u002Fhealthz\ncurl -X PUT https:\u002F\u002F\u003Capi>\u002Fwbs -H 'Content-Type: application\u002Fjson' \\\n  --data-binary @public\u002Fwbs.json\ncurl -s https:\u002F\u002F\u003Capi>\u002Fwbs | head -c 200\n",[29,2289,2290,2316,2347,2355],{"__ignoreMap":328},[332,2291,2292,2295,2298,2301,2304,2307,2310,2313],{"class":334,"line":335},[332,2293,2294],{"class":342},"curl",[332,2296,2297],{"class":403}," -i",[332,2299,2300],{"class":349}," https:\u002F\u002F",[332,2302,2303],{"class":338},"\u003C",[332,2305,2306],{"class":349},"ap",[332,2308,2309],{"class":369},"i",[332,2311,2312],{"class":338},">",[332,2314,2315],{"class":349},"\u002Fhealthz\n",[332,2317,2318,2320,2323,2326,2328,2330,2332,2334,2336,2338,2341,2344],{"class":334,"line":373},[332,2319,2294],{"class":342},[332,2321,2322],{"class":403}," -X",[332,2324,2325],{"class":349}," PUT",[332,2327,2300],{"class":349},[332,2329,2303],{"class":338},[332,2331,2306],{"class":349},[332,2333,2309],{"class":369},[332,2335,2312],{"class":338},[332,2337,39],{"class":349},[332,2339,2340],{"class":403}," -H",[332,2342,2343],{"class":349}," 'Content-Type: application\u002Fjson'",[332,2345,2346],{"class":403}," \\\n",[332,2348,2349,2352],{"class":334,"line":380},[332,2350,2351],{"class":403},"  --data-binary",[332,2353,2354],{"class":349}," @public\u002Fwbs.json\n",[332,2356,2357,2359,2362,2364,2366,2368,2370,2372,2374,2376,2379,2382],{"class":334,"line":393},[332,2358,2294],{"class":342},[332,2360,2361],{"class":403}," -s",[332,2363,2300],{"class":349},[332,2365,2303],{"class":338},[332,2367,2306],{"class":349},[332,2369,2309],{"class":369},[332,2371,2312],{"class":338},[332,2373,39],{"class":349},[332,2375,353],{"class":338},[332,2377,2378],{"class":342}," head",[332,2380,2381],{"class":403}," -c",[332,2383,2384],{"class":403}," 200\n",[52,2386],{},[55,2388,2390],{"id":2389},"_6-프론트엔드-구현-nuxt-3","6. 프론트엔드 구현 (Nuxt 3)",[315,2392,2394],{"id":2393},"_6-1-전제","6-1. 전제",[63,2396,2397,2403,2410,2413],{},[66,2398,2399,2400,307],{},"Nuxt 3 + Cloudflare Pages 프리셋(",[29,2401,2402],{},"output dir = dist\u002F",[66,2404,2405,2406,2409],{},"Tailwind CSS v4 (",[29,2407,2408],{},"@source \"..\u002F..\""," 직접 스캔 권장)",[66,2411,2412],{},"Pretendard Variable 폰트",[66,2414,2415,2416,2419],{},"@nuxt\u002Fui는 ",[18,2417,2418],{},"선택 사항",". 본 페이지는 순수 Tailwind 클래스만 사용",[315,2421,2423,2424,1223],{"id":2422},"_6-2-단일-파일-pageswbsvue-전체","6-2. 단일 파일 — ",[29,2425,2426],{},"pages\u002Fwbs.vue",[23,2428,2429],{},[14,2430,2431,2432,2435],{},"그대로 복사하면 동작한다. ",[29,2433,2434],{},"API_BASE","만 자기 Worker URL로 바꿀 것.",[323,2437,2441],{"className":2438,"code":2439,"language":2440,"meta":328,"style":328},"language-vue shiki shiki-themes github-light github-dark","\u003C!--\n  pages\u002Fwbs.vue\n  WBS Live Tracker — Soft SaaS (Notion\u002FLinear\u002FHeight 풍)\n  데이터: API GET \u002Fwbs (R2) → 없으면 \u002Fwbs.json fallback\n  편집: 모든 수정은 800ms 디바운스 후 PUT \u002Fwbs로 자동 영구 저장\n-->\n\u003Cscript setup lang=\"ts\">\nuseHead({ title: \"WBS\" });\n\ntype Status = \"done\" | \"in_progress\" | \"pending\" | \"blocked\";\n\ntype Task = {\n  id: string;\n  taskNo: string;\n  title: string;\n  status: Status;\n  note: string | null;\n  targetDate: string | null;\n  completionDate: string | null;\n  deliverableUrl: string | null;\n};\n\ntype Stage = {\n  id: string;\n  name: string;\n  weight: number;\n  progress: number;\n  summary: string;\n  tasks: Task[];\n};\n\ntype WbsDoc = {\n  _meta: { lastUpdated: string; project: string; source: string; editGuide: string };\n  phase1: { stages: Stage[] };\n};\n\n\u002F\u002F ⚠️ 자기 환경에 맞게 교체\nconst API_BASE = \"https:\u002F\u002F\u003Capi-worker-name>.\u003Csubdomain>.workers.dev\";\n\nconst wbs = ref\u003CWbsDoc | null>(null);\nconst pending = ref(true);\nconst error = ref\u003CError | null>(null);\n\ntype TaskPatch = Partial\u003C\n  Pick\u003CTask, \"deliverableUrl\" | \"status\" | \"targetDate\" | \"completionDate\" | \"note\">\n>;\n\nasync function loadWbs() {\n  pending.value = true;\n  error.value = null;\n  try {\n    const apiRes = await fetch(`${API_BASE}\u002Fwbs`, { cache: \"no-store\" });\n    if (apiRes.ok) {\n      wbs.value = (await apiRes.json()) as WbsDoc;\n    } else if (apiRes.status === 404) {\n      const seed = await fetch(\"\u002Fwbs.json\", { cache: \"no-store\" });\n      if (!seed.ok) throw new Error(`seed ${seed.status}`);\n      wbs.value = (await seed.json()) as WbsDoc;\n    } else {\n      throw new Error(`api ${apiRes.status}`);\n    }\n  } catch (e) {\n    error.value = e as Error;\n  } finally {\n    pending.value = false;\n  }\n}\nonMounted(loadWbs);\n\n\u002F\u002F ── 자동 저장 ──────────────────────────────────────────\ntype SaveState = \"idle\" | \"dirty\" | \"saving\" | \"saved\" | \"error\";\nconst saveState = ref\u003CSaveState>(\"idle\");\nconst lastSavedAt = ref\u003CDate | null>(null);\nconst saveError = ref\u003Cstring | null>(null);\nlet saveTimer: ReturnType\u003Ctypeof setTimeout> | null = null;\n\nasync function saveNow() {\n  if (!wbs.value) return;\n  if (saveTimer) { clearTimeout(saveTimer); saveTimer = null; }\n  const payload = {\n    ...wbs.value,\n    _meta: { ...wbs.value._meta, lastUpdated: new Date().toISOString().slice(0, 10) },\n  };\n  saveState.value = \"saving\";\n  saveError.value = null;\n  try {\n    const res = await fetch(`${API_BASE}\u002Fwbs`, {\n      method: \"PUT\",\n      headers: { \"Content-Type\": \"application\u002Fjson\" },\n      body: JSON.stringify(payload),\n    });\n    if (!res.ok) throw new Error(`save ${res.status}`);\n    lastSavedAt.value = new Date();\n    saveState.value = \"saved\";\n    wbs.value._meta = payload._meta;\n  } catch (e) {\n    saveError.value = (e as Error).message;\n    saveState.value = \"error\";\n  }\n}\n\nfunction scheduleSave() {\n  saveState.value = \"dirty\";\n  if (saveTimer) clearTimeout(saveTimer);\n  saveTimer = setTimeout(saveNow, 800);\n}\n\nfunction setOverride(taskId: string, patch: TaskPatch) {\n  if (!wbs.value) return;\n  for (const s of wbs.value.phase1.stages) {\n    const idx = s.tasks.findIndex((t) => t.id === taskId);\n    if (idx === -1) continue;\n    const cur = s.tasks[idx];\n    const next: Task = {\n      ...cur,\n      ...patch,\n      deliverableUrl: patch.deliverableUrl !== undefined ? patch.deliverableUrl || null : cur.deliverableUrl,\n      targetDate: patch.targetDate !== undefined ? patch.targetDate || null : cur.targetDate,\n      completionDate: patch.completionDate !== undefined ? patch.completionDate || null : cur.completionDate,\n      note: patch.note !== undefined ? patch.note || null : cur.note,\n    };\n    s.tasks.splice(idx, 1, next);\n    scheduleSave();\n    return;\n  }\n}\n\n\u002F\u002F ── 파생 상태 ──────────────────────────────────────────\nconst mergedStages = computed\u003CStage[]>(() => wbs.value?.phase1.stages ?? []);\nconst PROJECT_NAME = computed(() => wbs.value?._meta.project ?? \"Project\");\nconst LAST_UPDATED = computed(() => wbs.value?._meta.lastUpdated ?? \"—\");\n\nconst weightedAverage = computed(() => {\n  const st = mergedStages.value;\n  if (!st.length) return 0;\n  \u002F\u002F 가중평균(%) = Σ(weight × progress) \u002F Σ(weight). progress가 이미 %단위이므로 추가 \u002F100 없음.\n  const w = st.reduce((s, x) => s + x.weight, 0);\n  const p = st.reduce((s, x) => s + x.weight * x.progress, 0);\n  return Math.round((p \u002F w) * 10) \u002F 10;\n});\n\nconst allTasks = computed(() => mergedStages.value.flatMap((s) => s.tasks));\nconst totalCounts = computed(() => {\n  const acc: Record\u003CStatus, number> = { done: 0, in_progress: 0, pending: 0, blocked: 0 };\n  for (const t of allTasks.value) acc[t.status]++;\n  return acc;\n});\n\nfunction isOverdue(t: Task) {\n  if (t.status === \"done\" || !t.targetDate) return false;\n  return t.targetDate \u003C LAST_UPDATED.value;\n}\n\nconst statusMeta: Record\u003CStatus, { label: string; chipCls: string; emoji: string }> = {\n  done:        { label: \"완료\",   chipCls: \"bg-emerald-50 text-emerald-700 border-emerald-200\", emoji: \"✓\" },\n  in_progress: { label: \"진행 중\", chipCls: \"bg-amber-50 text-amber-700 border-amber-200\",       emoji: \"◐\" },\n  pending:     { label: \"대기\",   chipCls: \"bg-neutral-50 text-neutral-600 border-neutral-200\", emoji: \"○\" },\n  blocked:     { label: \"보류\",   chipCls: \"bg-rose-50 text-rose-700 border-rose-200\",          emoji: \"✕\" },\n};\n\nfunction progressFill(pct: number) {\n  if (pct >= 70) return \"bg-emerald-500\";\n  if (pct >= 30) return \"bg-amber-500\";\n  if (pct > 0)   return \"bg-neutral-400\";\n  return \"bg-neutral-200\";\n}\n\nconst stageEmoji = [\"🎯\", \"📐\", \"🛠️\", \"📚\", \"🧪\", \"🚀\"];\n\n\u002F\u002F ── 백업 다운로드 ─────────────────────────────────────\nconst currentJsonString = computed(() => wbs.value ? JSON.stringify(wbs.value, null, 2) + \"\\n\" : \"\");\nfunction downloadJson() {\n  const blob = new Blob([currentJsonString.value], { type: \"application\u002Fjson\" });\n  const url = URL.createObjectURL(blob);\n  const a = document.createElement(\"a\");\n  a.href = url; a.download = \"wbs.json\"; a.click();\n  setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\n\n\u002F\u002F ── \"n초 전\" 갱신 ─────────────────────────────────────\nconst savedAgo = ref(\"\");\nlet agoTimer: ReturnType\u003Ctypeof setInterval> | null = null;\nfunction formatAgo(d: Date) {\n  const s = Math.floor((Date.now() - d.getTime()) \u002F 1000);\n  if (s \u003C 5) return \"방금\";\n  if (s \u003C 60) return `${s}초 전`;\n  const m = Math.floor(s \u002F 60);\n  if (m \u003C 60) return `${m}분 전`;\n  return `${Math.floor(m \u002F 60)}시간 전`;\n}\nonMounted(() => {\n  agoTimer = setInterval(() => {\n    savedAgo.value = lastSavedAt.value ? formatAgo(lastSavedAt.value) : \"\";\n  }, 1000);\n});\nonUnmounted(() => {\n  if (agoTimer) clearInterval(agoTimer);\n  if (saveTimer) clearTimeout(saveTimer);\n});\n\nfunction scrollToStage(stageId: string) {\n  document.getElementById(`stage-${stageId}`)?.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"min-h-screen bg-neutral-50\u002F60 pb-24\">\n    \u003Cdiv class=\"mx-auto max-w-5xl px-6 pt-10 sm:px-10 sm:pt-14\">\n      \u003C!-- HEADER -->\n      \u003Cheader class=\"mt-4 flex items-start justify-between gap-4\">\n        \u003Cdiv class=\"flex items-start gap-3\">\n          \u003Cspan class=\"mt-1 text-[30px]\">📋\u003C\u002Fspan>\n          \u003Cdiv>\n            \u003Ch1 class=\"text-[28px] font-semibold tracking-tight text-neutral-900\">\n              {{ PROJECT_NAME }} · Phase 1\n            \u003C\u002Fh1>\n            \u003Cp class=\"mt-1 text-[14px] text-neutral-500\">\n              마지막 현행화 {{ LAST_UPDATED }}\n            \u003C\u002Fp>\n          \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Fheader>\n\n      \u003C!-- LOADING \u002F ERROR -->\n      \u003Cdiv v-if=\"pending\" class=\"mt-8 rounded-xl border border-neutral-200 bg-white p-6 text-[14px] text-neutral-500\">\n        로딩 중…\n      \u003C\u002Fdiv>\n      \u003Cdiv v-else-if=\"error\" class=\"mt-8 rounded-xl border border-rose-200 bg-rose-50 p-6 text-[14px] text-rose-700\">\n        로드 실패: {{ error.message }}\n      \u003C\u002Fdiv>\n\n      \u003Ctemplate v-else>\n        \u003C!-- HERO -->\n        \u003Csection class=\"mt-6 grid grid-cols-1 gap-3 sm:grid-cols-4\">\n          \u003Cdiv class=\"rounded-xl border border-neutral-200 bg-white p-5 sm:col-span-2\">\n            \u003Cp class=\"text-[12px] text-neutral-500\">전체 진행률\u003C\u002Fp>\n            \u003Cp class=\"mt-1 text-[36px] font-semibold tracking-tight text-neutral-900 tabular-nums\">\n              {{ weightedAverage }}\u003Cspan class=\"ml-0.5 text-[24px] text-neutral-400\">%\u003C\u002Fspan>\n            \u003C\u002Fp>\n            \u003Cdiv class=\"mt-4 h-1.5 overflow-hidden rounded-full bg-neutral-100\">\n              \u003Cdiv class=\"h-full rounded-full bg-neutral-900 transition-all\" :style=\"{ width: weightedAverage + '%' }\" \u002F>\n            \u003C\u002Fdiv>\n          \u003C\u002Fdiv>\n          \u003Cdiv class=\"rounded-xl border border-neutral-200 bg-white p-5\">\n            \u003Cdiv class=\"flex items-center gap-1.5\">\n              \u003Cspan class=\"inline-block size-1.5 rounded-full bg-emerald-500\" \u002F>\n              \u003Cp class=\"text-[12px] text-neutral-500\">완료\u003C\u002Fp>\n            \u003C\u002Fdiv>\n            \u003Cp class=\"mt-1 text-[30px] font-semibold text-neutral-900 tabular-nums\">\n              {{ totalCounts.done }}\u003Cspan class=\"text-[16px] text-neutral-400\">\u002F{{ allTasks.length }}\u003C\u002Fspan>\n            \u003C\u002Fp>\n          \u003C\u002Fdiv>\n          \u003Cdiv class=\"rounded-xl border border-neutral-200 bg-white p-5\">\n            \u003Cdiv class=\"flex items-center gap-1.5\">\n              \u003Cspan class=\"inline-block size-1.5 rounded-full bg-amber-500\" \u002F>\n              \u003Cp class=\"text-[12px] text-neutral-500\">진행 중\u003C\u002Fp>\n            \u003C\u002Fdiv>\n            \u003Cp class=\"mt-1 text-[30px] font-semibold text-neutral-900 tabular-nums\">\n              {{ totalCounts.in_progress }}\n            \u003C\u002Fp>\n          \u003C\u002Fdiv>\n        \u003C\u002Fsection>\n\n        \u003C!-- STAGES OVERVIEW -->\n        \u003Csection class=\"mt-8\">\n          \u003Ch2 class=\"mb-2 text-[14px] font-semibold text-neutral-700\">단계별 진행률\u003C\u002Fh2>\n          \u003Cul class=\"overflow-hidden rounded-xl border border-neutral-200 bg-white\">\n            \u003Cli\n              v-for=\"(s, i) in mergedStages\" :key=\"s.id\"\n              class=\"grid cursor-pointer grid-cols-[24px_24px_1fr_auto_140px_auto] items-center gap-4 px-4 py-3 hover:bg-neutral-50\"\n              :class=\"i > 0 ? 'border-t border-neutral-100' : ''\"\n              @click=\"scrollToStage(s.id)\"\n            >\n              \u003Cspan class=\"text-[18px] leading-none\">{{ stageEmoji[i] }}\u003C\u002Fspan>\n              \u003Cspan class=\"font-mono text-[14px] tabular-nums text-neutral-400\">{{ String(i + 1).padStart(2, \"0\") }}\u003C\u002Fspan>\n              \u003Cdiv class=\"min-w-0\">\n                \u003Cp class=\"truncate text-[14px] font-medium text-neutral-900\">{{ s.name }}\u003C\u002Fp>\n                \u003Cp class=\"truncate text-[14px] text-neutral-500\">{{ s.summary }}\u003C\u002Fp>\n              \u003C\u002Fdiv>\n              \u003Cspan class=\"text-[14px] text-neutral-400\">{{ s.tasks.length }}건\u003C\u002Fspan>\n              \u003Cdiv class=\"flex items-center gap-2.5\">\n                \u003Cdiv class=\"h-1 w-24 overflow-hidden rounded-full bg-neutral-100\">\n                  \u003Cdiv :class=\"['h-full rounded-full', progressFill(s.progress)]\" :style=\"{ width: s.progress + '%' }\" \u002F>\n                \u003C\u002Fdiv>\n                \u003Cspan class=\"w-9 text-right text-[14px] font-medium tabular-nums text-neutral-700\">{{ s.progress }}%\u003C\u002Fspan>\n              \u003C\u002Fdiv>\n              \u003Cspan class=\"text-neutral-300\">→\u003C\u002Fspan>\n            \u003C\u002Fli>\n          \u003C\u002Ful>\n        \u003C\u002Fsection>\n\n        \u003C!-- STAGE DETAILS -->\n        \u003Csection v-for=\"(s, sIdx) in mergedStages\" :key=\"s.id\" :id=\"`stage-${s.id}`\" class=\"mt-10\">\n          \u003Cdiv class=\"flex items-baseline justify-between gap-3\">\n            \u003Cdiv class=\"flex items-baseline gap-2.5\">\n              \u003Cspan class=\"text-[20px] leading-none\">{{ stageEmoji[sIdx] }}\u003C\u002Fspan>\n              \u003Ch2 class=\"text-[18px] font-semibold tracking-tight text-neutral-900\">{{ s.name }}\u003C\u002Fh2>\n              \u003Cspan class=\"font-mono text-[14px] text-neutral-400\">{{ s.id }}\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"flex items-center gap-3 text-[14px] text-neutral-500\">\n              \u003Cspan>비중 {{ s.weight }}%\u003C\u002Fspan>\n              \u003Cspan class=\"text-neutral-200\">·\u003C\u002Fspan>\n              \u003Cspan class=\"font-medium text-neutral-700\">진행 {{ s.progress }}%\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n          \u003C\u002Fdiv>\n          \u003Cp class=\"mt-1 text-[14px] text-neutral-500\">{{ s.summary }}\u003C\u002Fp>\n          \u003Cdiv class=\"mt-3 h-1 overflow-hidden rounded-full bg-neutral-100\">\n            \u003Cdiv :class=\"['h-full rounded-full', progressFill(s.progress)]\" :style=\"{ width: s.progress + '%' }\" \u002F>\n          \u003C\u002Fdiv>\n\n          \u003Cdiv class=\"mt-4 overflow-hidden rounded-xl border border-neutral-200 bg-white\">\n            \u003Ctable class=\"w-full text-[14px]\">\n              \u003Cthead>\n                \u003Ctr class=\"border-b border-neutral-100 text-[14px] font-medium text-neutral-500\">\n                  \u003Cth class=\"w-20 px-3 py-2 text-left\">ID\u003C\u002Fth>\n                  \u003Cth class=\"px-3 py-2 text-left\">작업 · 산출물\u003C\u002Fth>\n                  \u003Cth class=\"w-36 px-3 py-2 text-left\">목표일\u003C\u002Fth>\n                  \u003Cth class=\"w-36 px-3 py-2 text-left\">완료일\u003C\u002Fth>\n                  \u003Cth class=\"w-28 px-3 py-2 text-left\">상태\u003C\u002Fth>\n                \u003C\u002Ftr>\n              \u003C\u002Fthead>\n              \u003Ctbody>\n                \u003Ctr\n                  v-for=\"(t, ti) in s.tasks\" :key=\"t.id\"\n                  class=\"align-top hover:bg-neutral-50\u002F60\"\n                  :class=\"ti > 0 ? 'border-t border-neutral-100' : ''\"\n                >\n                  \u003Ctd class=\"px-3 py-3 font-mono text-[14px] tabular-nums text-neutral-400\">{{ s.id }}-{{ t.taskNo }}\u003C\u002Ftd>\n                  \u003Ctd class=\"px-3 py-3\">\n                    \u003Cp class=\"text-[13.5px] font-medium text-neutral-900\">{{ t.title }}\u003C\u002Fp>\n                    \u003Cp v-if=\"t.note\" class=\"mt-0.5 text-[14px] leading-relaxed text-neutral-500\">{{ t.note }}\u003C\u002Fp>\n                    \u003Cdiv class=\"mt-2 flex items-center gap-2\">\n                      \u003Cspan class=\"text-[14px] text-neutral-400\">🔗\u003C\u002Fspan>\n                      \u003Cinput\n                        :value=\"t.deliverableUrl ?? ''\" type=\"url\" placeholder=\"산출물 URL 입력\"\n                        class=\"min-w-0 flex-1 rounded-md border border-transparent bg-transparent px-1.5 py-1 font-mono text-[13px] text-neutral-700 placeholder:text-neutral-400 hover:border-neutral-200 focus:border-neutral-300 focus:bg-white focus:outline-none focus:ring-1 focus:ring-neutral-200\"\n                        @change=\"(e) => setOverride(t.id, { deliverableUrl: (e.target as HTMLInputElement).value || null })\"\n                      \u002F>\n                      \u003Ca v-if=\"t.deliverableUrl\" :href=\"t.deliverableUrl\" target=\"_blank\" rel=\"noopener\"\n                         class=\"shrink-0 rounded-md px-1.5 py-1 text-[14px] text-neutral-500 hover:bg-neutral-100 hover:text-neutral-900\">\n                        열기 ↗\n                      \u003C\u002Fa>\n                    \u003C\u002Fdiv>\n                  \u003C\u002Ftd>\n                  \u003Ctd class=\"whitespace-nowrap px-2 py-3\">\n                    \u003Cinput\n                      type=\"date\" :value=\"t.targetDate ?? ''\"\n                      :class=\"['w-full rounded-md border border-transparent bg-transparent px-1.5 py-1 font-mono text-[12px] tabular-nums hover:border-neutral-200 focus:border-neutral-300 focus:bg-white focus:outline-none focus:ring-1 focus:ring-neutral-200',\n                               isOverdue(t) ? 'font-semibold text-rose-600' : 'text-neutral-600']\"\n                      @change=\"(e) => setOverride(t.id, { targetDate: (e.target as HTMLInputElement).value || null })\"\n                    \u002F>\n                  \u003C\u002Ftd>\n                  \u003Ctd class=\"whitespace-nowrap px-2 py-3\">\n                    \u003Cinput\n                      type=\"date\" :value=\"t.completionDate ?? ''\"\n                      class=\"w-full rounded-md border border-transparent bg-transparent px-1.5 py-1 font-mono text-[12px] tabular-nums text-emerald-700 hover:border-neutral-200 focus:border-neutral-300 focus:bg-white focus:outline-none focus:ring-1 focus:ring-neutral-200\"\n                      @change=\"(e) => setOverride(t.id, { completionDate: (e.target as HTMLInputElement).value || null })\"\n                    \u002F>\n                  \u003C\u002Ftd>\n                  \u003Ctd class=\"whitespace-nowrap px-3 py-3\">\n                    \u003Clabel :class=\"['relative inline-flex cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-md border px-2 py-0.5 text-[13px] font-medium hover:brightness-95',\n                                    statusMeta[t.status].chipCls]\">\n                      \u003Cspan class=\"text-[13px]\">{{ statusMeta[t.status].emoji }}\u003C\u002Fspan>\n                      {{ statusMeta[t.status].label }}\n                      \u003Cselect\n                        :value=\"t.status\" class=\"absolute inset-0 cursor-pointer opacity-0\"\n                        @change=\"(e) => setOverride(t.id, { status: (e.target as HTMLSelectElement).value as Status })\"\n                      >\n                        \u003Coption v-for=\"(meta, key) in statusMeta\" :key=\"key\" :value=\"key\">\n                          {{ meta.emoji }} {{ meta.label }}\n                        \u003C\u002Foption>\n                      \u003C\u002Fselect>\n                    \u003C\u002Flabel>\n                  \u003C\u002Ftd>\n                \u003C\u002Ftr>\n              \u003C\u002Ftbody>\n            \u003C\u002Ftable>\n          \u003C\u002Fdiv>\n        \u003C\u002Fsection>\n      \u003C\u002Ftemplate>\n    \u003C\u002Fdiv>\n\n    \u003C!-- FLOATING AUTOSAVE STATUS -->\n    \u003Cdiv v-if=\"saveState !== 'idle'\"\n         class=\"fixed bottom-6 left-1\u002F2 z-50 flex -translate-x-1\u002F2 items-center gap-2.5 rounded-full border border-neutral-200 bg-white px-3 py-2 shadow-lg shadow-neutral-900\u002F10\">\n      \u003Cspan class=\"flex items-center gap-2 pl-1 text-[14px] text-neutral-700\">\n        \u003Ctemplate v-if=\"saveState === 'dirty'\">\n          \u003Cspan class=\"inline-block size-1.5 rounded-full bg-amber-500\" \u002F>\u003Cspan>수정 감지…\u003C\u002Fspan>\n        \u003C\u002Ftemplate>\n        \u003Ctemplate v-else-if=\"saveState === 'saving'\">\n          \u003Cspan class=\"inline-block size-1.5 animate-pulse rounded-full bg-sky-500\" \u002F>\u003Cspan>저장 중…\u003C\u002Fspan>\n        \u003C\u002Ftemplate>\n        \u003Ctemplate v-else-if=\"saveState === 'saved'\">\n          \u003Cspan class=\"inline-block size-1.5 rounded-full bg-emerald-500\" \u002F>\n          \u003Cspan>저장됨 \u003Cspan class=\"text-neutral-400\">· {{ savedAgo }}\u003C\u002Fspan>\u003C\u002Fspan>\n        \u003C\u002Ftemplate>\n        \u003Ctemplate v-else-if=\"saveState === 'error'\">\n          \u003Cspan class=\"inline-block size-1.5 rounded-full bg-rose-500\" \u002F>\n          \u003Cspan class=\"text-rose-700\">저장 실패: {{ saveError }}\u003C\u002Fspan>\n        \u003C\u002Ftemplate>\n      \u003C\u002Fspan>\n      \u003Cspan class=\"h-4 w-px bg-neutral-200\" \u002F>\n      \u003Cbutton v-if=\"saveState === 'error'\"\n              class=\"rounded-md bg-neutral-900 px-3 py-1 text-[14px] font-medium text-white hover:bg-neutral-700\"\n              @click=\"saveNow\">재시도\u003C\u002Fbutton>\n      \u003Cbutton class=\"rounded-md px-2.5 py-1 text-[14px] text-neutral-600 hover:bg-neutral-100\"\n              @click=\"downloadJson\" title=\"현재 상태를 wbs.json으로 다운로드\">↓ 백업\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","vue",[29,2442,2443,2448,2453,2458,2463,2468,2473,2495,2509,2513,2537,2541,2551,2561,2571,2581,2591,2605,2619,2633,2647,2651,2655,2665,2675,2685,2695,2705,2715,2725,2729,2733,2743,2788,2804,2808,2812,2817,2831,2835,2863,2880,2906,2910,2925,2962,2967,2971,2984,2996,3007,3013,3045,3053,3080,3102,3127,3164,3187,3195,3220,3226,3236,3253,3263,3276,3281,3286,3295,3300,3306,3341,3365,3392,3419,3451,3456,3468,3484,3505,3517,3526,3562,3567,3579,3591,3598,3623,3633,3648,3665,3671,3705,3719,3731,3742,3751,3769,3780,3785,3790,3795,3806,3817,3830,3849,3854,3859,3887,3902,3921,3954,3977,3990,4006,4015,4023,4052,4076,4100,4124,4130,4147,4155,4162,4167,4172,4177,4183,4215,4242,4268,4273,4291,4304,4327,4333,4375,4418,4450,4455,4460,4493,4511,4561,4583,4591,4596,4601,4619,4646,4661,4666,4671,4722,4745,4768,4789,4811,4816,4821,4840,4863,4884,4905,4915,4920,4925,4969,4974,4980,5038,5048,5070,5091,5114,5138,5163,5168,5173,5179,5198,5227,5246,5287,5309,5335,5358,5384,5414,5419,5430,5447,5471,5481,5486,5498,5512,5523,5528,5533,5552,5590,5595,5605,5610,5620,5639,5656,5662,5680,5697,5719,5728,5745,5751,5761,5777,5783,5792,5802,5812,5822,5827,5833,5857,5863,5872,5896,5902,5911,5916,5928,5934,5951,5967,5988,6004,6026,6035,6051,6079,6088,6097,6113,6129,6147,6167,6176,6192,6214,6223,6232,6247,6262,6280,6300,6309,6324,6330,6339,6348,6357,6362,6368,6384,6405,6421,6429,6448,6459,6470,6481,6487,6508,6529,6545,6567,6588,6598,6619,6635,6651,6678,6688,6709,6718,6739,6748,6757,6766,6771,6777,6816,6832,6848,6869,6889,6910,6919,6935,6949,6970,6991,7000,7009,7028,7044,7067,7076,7081,7097,7113,7122,7138,7159,7180,7201,7221,7242,7251,7260,7269,7277,7295,7306,7317,7323,7344,7360,7382,7410,7426,7447,7455,7482,7493,7504,7510,7547,7560,7566,7576,7586,7596,7612,7619,7638,7649,7655,7666,7672,7681,7696,7703,7719,7730,7740,7745,7754,7770,7784,7792,7813,7819,7827,7844,7854,7860,7891,7897,7907,7917,7926,7935,7944,7953,7962,7971,7980,7989,7999,8004,8010,8024,8037,8053,8076,8103,8112,8134,8161,8170,8192,8209,8240,8249,8271,8289,8310,8319,8328,8346,8361,8371,8388,8402,8427,8436,8446],{"__ignoreMap":328},[332,2444,2445],{"class":334,"line":335},[332,2446,2447],{"class":410},"\u003C!--\n",[332,2449,2450],{"class":334,"line":373},[332,2451,2452],{"class":410},"  pages\u002Fwbs.vue\n",[332,2454,2455],{"class":334,"line":380},[332,2456,2457],{"class":410},"  WBS Live Tracker — Soft SaaS (Notion\u002FLinear\u002FHeight 풍)\n",[332,2459,2460],{"class":334,"line":393},[332,2461,2462],{"class":410},"  데이터: API GET \u002Fwbs (R2) → 없으면 \u002Fwbs.json fallback\n",[332,2464,2465],{"class":334,"line":414},[332,2466,2467],{"class":410},"  편집: 모든 수정은 800ms 디바운스 후 PUT \u002Fwbs로 자동 영구 저장\n",[332,2469,2470],{"class":334,"line":430},[332,2471,2472],{"class":410},"-->\n",[332,2474,2475,2477,2481,2484,2487,2490,2493],{"class":334,"line":442},[332,2476,2303],{"class":369},[332,2478,2480],{"class":2479},"s9eBZ","script",[332,2482,2483],{"class":342}," setup",[332,2485,2486],{"class":342}," lang",[332,2488,2489],{"class":369},"=",[332,2491,2492],{"class":349},"\"ts\"",[332,2494,2255],{"class":369},[332,2496,2497,2500,2503,2506],{"class":334,"line":454},[332,2498,2499],{"class":342},"useHead",[332,2501,2502],{"class":369},"({ title: ",[332,2504,2505],{"class":349},"\"WBS\"",[332,2507,2508],{"class":369}," });\n",[332,2510,2511],{"class":334,"line":471},[332,2512,377],{"emptyLinePlaceholder":376},[332,2514,2515,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535],{"class":334,"line":491},[332,2516,339],{"class":338},[332,2518,343],{"class":342},[332,2520,346],{"class":338},[332,2522,350],{"class":349},[332,2524,353],{"class":338},[332,2526,356],{"class":349},[332,2528,353],{"class":338},[332,2530,361],{"class":349},[332,2532,353],{"class":338},[332,2534,366],{"class":349},[332,2536,370],{"class":369},[332,2538,2539],{"class":334,"line":510},[332,2540,377],{"emptyLinePlaceholder":376},[332,2542,2543,2545,2547,2549],{"class":334,"line":526},[332,2544,339],{"class":338},[332,2546,385],{"class":342},[332,2548,346],{"class":338},[332,2550,390],{"class":369},[332,2552,2553,2555,2557,2559],{"class":334,"line":532},[332,2554,397],{"class":396},[332,2556,400],{"class":338},[332,2558,404],{"class":403},[332,2560,370],{"class":369},[332,2562,2563,2565,2567,2569],{"class":334,"line":537},[332,2564,417],{"class":396},[332,2566,400],{"class":338},[332,2568,404],{"class":403},[332,2570,370],{"class":369},[332,2572,2573,2575,2577,2579],{"class":334,"line":549},[332,2574,433],{"class":396},[332,2576,400],{"class":338},[332,2578,404],{"class":403},[332,2580,370],{"class":369},[332,2582,2583,2585,2587,2589],{"class":334,"line":564},[332,2584,445],{"class":396},[332,2586,400],{"class":338},[332,2588,343],{"class":342},[332,2590,370],{"class":369},[332,2592,2593,2595,2597,2599,2601,2603],{"class":334,"line":576},[332,2594,457],{"class":396},[332,2596,400],{"class":338},[332,2598,404],{"class":403},[332,2600,353],{"class":338},[332,2602,466],{"class":403},[332,2604,370],{"class":369},[332,2606,2607,2609,2611,2613,2615,2617],{"class":334,"line":593},[332,2608,474],{"class":396},[332,2610,400],{"class":338},[332,2612,404],{"class":403},[332,2614,353],{"class":338},[332,2616,466],{"class":403},[332,2618,370],{"class":369},[332,2620,2621,2623,2625,2627,2629,2631],{"class":334,"line":609},[332,2622,494],{"class":396},[332,2624,400],{"class":338},[332,2626,404],{"class":403},[332,2628,353],{"class":338},[332,2630,466],{"class":403},[332,2632,370],{"class":369},[332,2634,2635,2637,2639,2641,2643,2645],{"class":334,"line":621},[332,2636,513],{"class":396},[332,2638,400],{"class":338},[332,2640,404],{"class":403},[332,2642,353],{"class":338},[332,2644,466],{"class":403},[332,2646,370],{"class":369},[332,2648,2649],{"class":334,"line":634},[332,2650,529],{"class":369},[332,2652,2653],{"class":334,"line":639},[332,2654,377],{"emptyLinePlaceholder":376},[332,2656,2657,2659,2661,2663],{"class":334,"line":644},[332,2658,339],{"class":338},[332,2660,542],{"class":342},[332,2662,346],{"class":338},[332,2664,390],{"class":369},[332,2666,2667,2669,2671,2673],{"class":334,"line":656},[332,2668,397],{"class":396},[332,2670,400],{"class":338},[332,2672,404],{"class":403},[332,2674,370],{"class":369},[332,2676,2677,2679,2681,2683],{"class":334,"line":666},[332,2678,567],{"class":396},[332,2680,400],{"class":338},[332,2682,404],{"class":403},[332,2684,370],{"class":369},[332,2686,2687,2689,2691,2693],{"class":334,"line":681},[332,2688,579],{"class":396},[332,2690,400],{"class":338},[332,2692,584],{"class":403},[332,2694,370],{"class":369},[332,2696,2697,2699,2701,2703],{"class":334,"line":693},[332,2698,596],{"class":396},[332,2700,400],{"class":338},[332,2702,584],{"class":403},[332,2704,370],{"class":369},[332,2706,2707,2709,2711,2713],{"class":334,"line":708},[332,2708,612],{"class":396},[332,2710,400],{"class":338},[332,2712,404],{"class":403},[332,2714,370],{"class":369},[332,2716,2717,2719,2721,2723],{"class":334,"line":724},[332,2718,624],{"class":396},[332,2720,400],{"class":338},[332,2722,385],{"class":342},[332,2724,631],{"class":369},[332,2726,2727],{"class":334,"line":730},[332,2728,529],{"class":369},[332,2730,2731],{"class":334,"line":751},[332,2732,377],{"emptyLinePlaceholder":376},[332,2734,2735,2737,2739,2741],{"class":334,"line":1737},[332,2736,339],{"class":338},[332,2738,649],{"class":342},[332,2740,346],{"class":338},[332,2742,390],{"class":369},[332,2744,2745,2747,2749,2751,2754,2756,2758,2760,2763,2765,2767,2769,2772,2774,2776,2778,2781,2783,2785],{"class":334,"line":1768},[332,2746,659],{"class":396},[332,2748,400],{"class":338},[332,2750,738],{"class":369},[332,2752,2753],{"class":396},"lastUpdated",[332,2755,400],{"class":338},[332,2757,404],{"class":403},[332,2759,603],{"class":369},[332,2761,2762],{"class":396},"project",[332,2764,400],{"class":338},[332,2766,404],{"class":403},[332,2768,603],{"class":369},[332,2770,2771],{"class":396},"source",[332,2773,400],{"class":338},[332,2775,404],{"class":403},[332,2777,603],{"class":369},[332,2779,2780],{"class":396},"editGuide",[332,2782,400],{"class":338},[332,2784,404],{"class":403},[332,2786,2787],{"class":369}," };\n",[332,2789,2790,2792,2794,2796,2798,2800,2802],{"class":334,"line":1801},[332,2791,733],{"class":396},[332,2793,400],{"class":338},[332,2795,738],{"class":369},[332,2797,741],{"class":396},[332,2799,400],{"class":338},[332,2801,542],{"class":342},[332,2803,748],{"class":369},[332,2805,2806],{"class":334,"line":1821},[332,2807,529],{"class":369},[332,2809,2810],{"class":334,"line":1835},[332,2811,377],{"emptyLinePlaceholder":376},[332,2813,2814],{"class":334,"line":1841},[332,2815,2816],{"class":410},"\u002F\u002F ⚠️ 자기 환경에 맞게 교체\n",[332,2818,2819,2821,2824,2826,2829],{"class":334,"line":1854},[332,2820,1298],{"class":338},[332,2822,2823],{"class":403}," API_BASE",[332,2825,346],{"class":338},[332,2827,2828],{"class":349}," \"https:\u002F\u002F\u003Capi-worker-name>.\u003Csubdomain>.workers.dev\"",[332,2830,370],{"class":369},[332,2832,2833],{"class":334,"line":1867},[332,2834,377],{"emptyLinePlaceholder":376},[332,2836,2837,2839,2842,2844,2847,2849,2852,2854,2856,2859,2861],{"class":334,"line":1873},[332,2838,1298],{"class":338},[332,2840,2841],{"class":403}," wbs",[332,2843,346],{"class":338},[332,2845,2846],{"class":342}," ref",[332,2848,2303],{"class":369},[332,2850,2851],{"class":342},"WbsDoc",[332,2853,353],{"class":338},[332,2855,466],{"class":403},[332,2857,2858],{"class":369},">(",[332,2860,986],{"class":403},[332,2862,1609],{"class":369},[332,2864,2865,2867,2870,2872,2874,2876,2878],{"class":334,"line":1878},[332,2866,1298],{"class":338},[332,2868,2869],{"class":403}," pending",[332,2871,346],{"class":338},[332,2873,2846],{"class":342},[332,2875,1101],{"class":369},[332,2877,1684],{"class":403},[332,2879,1609],{"class":369},[332,2881,2882,2884,2887,2889,2891,2893,2896,2898,2900,2902,2904],{"class":334,"line":1884},[332,2883,1298],{"class":338},[332,2885,2886],{"class":403}," error",[332,2888,346],{"class":338},[332,2890,2846],{"class":342},[332,2892,2303],{"class":369},[332,2894,2895],{"class":342},"Error",[332,2897,353],{"class":338},[332,2899,466],{"class":403},[332,2901,2858],{"class":369},[332,2903,986],{"class":403},[332,2905,1609],{"class":369},[332,2907,2908],{"class":334,"line":1890},[332,2909,377],{"emptyLinePlaceholder":376},[332,2911,2912,2914,2917,2919,2922],{"class":334,"line":1895},[332,2913,339],{"class":338},[332,2915,2916],{"class":342}," TaskPatch",[332,2918,346],{"class":338},[332,2920,2921],{"class":342}," Partial",[332,2923,2924],{"class":369},"\u003C\n",[332,2926,2927,2930,2932,2935,2937,2940,2942,2945,2947,2950,2952,2955,2957,2960],{"class":334,"line":1921},[332,2928,2929],{"class":342},"  Pick",[332,2931,2303],{"class":369},[332,2933,2934],{"class":342},"Task",[332,2936,1563],{"class":369},[332,2938,2939],{"class":349},"\"deliverableUrl\"",[332,2941,353],{"class":338},[332,2943,2944],{"class":349}," \"status\"",[332,2946,353],{"class":338},[332,2948,2949],{"class":349}," \"targetDate\"",[332,2951,353],{"class":338},[332,2953,2954],{"class":349}," \"completionDate\"",[332,2956,353],{"class":338},[332,2958,2959],{"class":349}," \"note\"",[332,2961,2255],{"class":369},[332,2963,2964],{"class":334,"line":1940},[332,2965,2966],{"class":369},">;\n",[332,2968,2969],{"class":334,"line":1948},[332,2970,377],{"emptyLinePlaceholder":376},[332,2972,2973,2975,2978,2981],{"class":334,"line":1962},[332,2974,1724],{"class":338},[332,2976,2977],{"class":338}," function",[332,2979,2980],{"class":342}," loadWbs",[332,2982,2983],{"class":369},"() {\n",[332,2985,2986,2989,2991,2994],{"class":334,"line":1973},[332,2987,2988],{"class":369},"  pending.value ",[332,2990,2489],{"class":338},[332,2992,2993],{"class":403}," true",[332,2995,370],{"class":369},[332,2997,2998,3001,3003,3005],{"class":334,"line":1996},[332,2999,3000],{"class":369},"  error.value ",[332,3002,2489],{"class":338},[332,3004,466],{"class":403},[332,3006,370],{"class":369},[332,3008,3009,3011],{"class":334,"line":2001},[332,3010,1943],{"class":338},[332,3012,390],{"class":369},[332,3014,3015,3018,3021,3023,3025,3028,3030,3033,3035,3038,3041,3043],{"class":334,"line":2021},[332,3016,3017],{"class":338},"    const",[332,3019,3020],{"class":403}," apiRes",[332,3022,346],{"class":338},[332,3024,1748],{"class":338},[332,3026,3027],{"class":342}," fetch",[332,3029,1101],{"class":369},[332,3031,3032],{"class":349},"`${",[332,3034,2434],{"class":403},[332,3036,3037],{"class":349},"}\u002Fwbs`",[332,3039,3040],{"class":369},", { cache: ",[332,3042,1862],{"class":349},[332,3044,2508],{"class":369},[332,3046,3047,3050],{"class":334,"line":2042},[332,3048,3049],{"class":338},"    if",[332,3051,3052],{"class":369}," (apiRes.ok) {\n",[332,3054,3055,3058,3060,3062,3065,3068,3070,3073,3076,3078],{"class":334,"line":2047},[332,3056,3057],{"class":369},"      wbs.value ",[332,3059,2489],{"class":338},[332,3061,1379],{"class":369},[332,3063,3064],{"class":338},"await",[332,3066,3067],{"class":369}," apiRes.",[332,3069,768],{"class":342},[332,3071,3072],{"class":369},"()) ",[332,3074,3075],{"class":338},"as",[332,3077,649],{"class":342},[332,3079,370],{"class":369},[332,3081,3082,3085,3088,3091,3094,3097,3100],{"class":334,"line":2068},[332,3083,3084],{"class":369},"    } ",[332,3086,3087],{"class":338},"else",[332,3089,3090],{"class":338}," if",[332,3092,3093],{"class":369}," (apiRes.status ",[332,3095,3096],{"class":338},"===",[332,3098,3099],{"class":403}," 404",[332,3101,2018],{"class":369},[332,3103,3104,3107,3110,3112,3114,3116,3118,3121,3123,3125],{"class":334,"line":2079},[332,3105,3106],{"class":338},"      const",[332,3108,3109],{"class":403}," seed",[332,3111,346],{"class":338},[332,3113,1748],{"class":338},[332,3115,3027],{"class":342},[332,3117,1101],{"class":369},[332,3119,3120],{"class":349},"\"\u002Fwbs.json\"",[332,3122,3040],{"class":369},[332,3124,1862],{"class":349},[332,3126,2508],{"class":369},[332,3128,3129,3131,3133,3135,3138,3141,3143,3146,3148,3151,3154,3156,3159,3162],{"class":334,"line":2084},[332,3130,1376],{"class":338},[332,3132,1379],{"class":369},[332,3134,1382],{"class":338},[332,3136,3137],{"class":369},"seed.ok) ",[332,3139,3140],{"class":338},"throw",[332,3142,1306],{"class":338},[332,3144,3145],{"class":342}," Error",[332,3147,1101],{"class":369},[332,3149,3150],{"class":349},"`seed ${",[332,3152,3153],{"class":369},"seed",[332,3155,1423],{"class":349},[332,3157,3158],{"class":369},"status",[332,3160,3161],{"class":349},"}`",[332,3163,1609],{"class":369},[332,3165,3166,3168,3170,3172,3174,3177,3179,3181,3183,3185],{"class":334,"line":2120},[332,3167,3057],{"class":369},[332,3169,2489],{"class":338},[332,3171,1379],{"class":369},[332,3173,3064],{"class":338},[332,3175,3176],{"class":369}," seed.",[332,3178,768],{"class":342},[332,3180,3072],{"class":369},[332,3182,3075],{"class":338},[332,3184,649],{"class":342},[332,3186,370],{"class":369},[332,3188,3189,3191,3193],{"class":334,"line":2125},[332,3190,3084],{"class":369},[332,3192,3087],{"class":338},[332,3194,390],{"class":369},[332,3196,3197,3200,3202,3204,3206,3209,3212,3214,3216,3218],{"class":334,"line":2130},[332,3198,3199],{"class":338},"      throw",[332,3201,1306],{"class":338},[332,3203,3145],{"class":342},[332,3205,1101],{"class":369},[332,3207,3208],{"class":349},"`api ${",[332,3210,3211],{"class":369},"apiRes",[332,3213,1423],{"class":349},[332,3215,3158],{"class":369},[332,3217,3161],{"class":349},[332,3219,1609],{"class":369},[332,3221,3223],{"class":334,"line":3222},61,[332,3224,3225],{"class":369},"    }\n",[332,3227,3229,3231,3233],{"class":334,"line":3228},62,[332,3230,1965],{"class":369},[332,3232,1968],{"class":338},[332,3234,3235],{"class":369}," (e) {\n",[332,3237,3239,3242,3244,3247,3249,3251],{"class":334,"line":3238},63,[332,3240,3241],{"class":369},"    error.value ",[332,3243,2489],{"class":338},[332,3245,3246],{"class":369}," e ",[332,3248,3075],{"class":338},[332,3250,3145],{"class":342},[332,3252,370],{"class":369},[332,3254,3256,3258,3261],{"class":334,"line":3255},64,[332,3257,1965],{"class":369},[332,3259,3260],{"class":338},"finally",[332,3262,390],{"class":369},[332,3264,3266,3269,3271,3274],{"class":334,"line":3265},65,[332,3267,3268],{"class":369},"    pending.value ",[332,3270,2489],{"class":338},[332,3272,3273],{"class":403}," false",[332,3275,370],{"class":369},[332,3277,3279],{"class":334,"line":3278},66,[332,3280,1047],{"class":369},[332,3282,3284],{"class":334,"line":3283},67,[332,3285,1052],{"class":369},[332,3287,3289,3292],{"class":334,"line":3288},68,[332,3290,3291],{"class":342},"onMounted",[332,3293,3294],{"class":369},"(loadWbs);\n",[332,3296,3298],{"class":334,"line":3297},69,[332,3299,377],{"emptyLinePlaceholder":376},[332,3301,3303],{"class":334,"line":3302},70,[332,3304,3305],{"class":410},"\u002F\u002F ── 자동 저장 ──────────────────────────────────────────\n",[332,3307,3309,3311,3314,3316,3319,3321,3324,3326,3329,3331,3334,3336,3339],{"class":334,"line":3308},71,[332,3310,339],{"class":338},[332,3312,3313],{"class":342}," SaveState",[332,3315,346],{"class":338},[332,3317,3318],{"class":349}," \"idle\"",[332,3320,353],{"class":338},[332,3322,3323],{"class":349}," \"dirty\"",[332,3325,353],{"class":338},[332,3327,3328],{"class":349}," \"saving\"",[332,3330,353],{"class":338},[332,3332,3333],{"class":349}," \"saved\"",[332,3335,353],{"class":338},[332,3337,3338],{"class":349}," \"error\"",[332,3340,370],{"class":369},[332,3342,3344,3346,3349,3351,3353,3355,3358,3360,3363],{"class":334,"line":3343},72,[332,3345,1298],{"class":338},[332,3347,3348],{"class":403}," saveState",[332,3350,346],{"class":338},[332,3352,2846],{"class":342},[332,3354,2303],{"class":369},[332,3356,3357],{"class":342},"SaveState",[332,3359,2858],{"class":369},[332,3361,3362],{"class":349},"\"idle\"",[332,3364,1609],{"class":369},[332,3366,3368,3370,3373,3375,3377,3379,3382,3384,3386,3388,3390],{"class":334,"line":3367},73,[332,3369,1298],{"class":338},[332,3371,3372],{"class":403}," lastSavedAt",[332,3374,346],{"class":338},[332,3376,2846],{"class":342},[332,3378,2303],{"class":369},[332,3380,3381],{"class":342},"Date",[332,3383,353],{"class":338},[332,3385,466],{"class":403},[332,3387,2858],{"class":369},[332,3389,986],{"class":403},[332,3391,1609],{"class":369},[332,3393,3395,3397,3400,3402,3404,3406,3409,3411,3413,3415,3417],{"class":334,"line":3394},74,[332,3396,1298],{"class":338},[332,3398,3399],{"class":403}," saveError",[332,3401,346],{"class":338},[332,3403,2846],{"class":342},[332,3405,2303],{"class":369},[332,3407,3408],{"class":403},"string",[332,3410,353],{"class":338},[332,3412,466],{"class":403},[332,3414,2858],{"class":369},[332,3416,986],{"class":403},[332,3418,1609],{"class":369},[332,3420,3422,3425,3428,3430,3433,3435,3438,3441,3443,3445,3447,3449],{"class":334,"line":3421},75,[332,3423,3424],{"class":338},"let",[332,3426,3427],{"class":369}," saveTimer",[332,3429,400],{"class":338},[332,3431,3432],{"class":342}," ReturnType",[332,3434,2303],{"class":369},[332,3436,3437],{"class":338},"typeof",[332,3439,3440],{"class":369}," setTimeout> ",[332,3442,1498],{"class":338},[332,3444,466],{"class":403},[332,3446,346],{"class":338},[332,3448,466],{"class":403},[332,3450,370],{"class":369},[332,3452,3454],{"class":334,"line":3453},76,[332,3455,377],{"emptyLinePlaceholder":376},[332,3457,3459,3461,3463,3466],{"class":334,"line":3458},77,[332,3460,1724],{"class":338},[332,3462,2977],{"class":338},[332,3464,3465],{"class":342}," saveNow",[332,3467,2983],{"class":369},[332,3469,3471,3473,3475,3477,3480,3482],{"class":334,"line":3470},78,[332,3472,1771],{"class":338},[332,3474,1379],{"class":369},[332,3476,1382],{"class":338},[332,3478,3479],{"class":369},"wbs.value) ",[332,3481,1388],{"class":338},[332,3483,370],{"class":369},[332,3485,3487,3489,3492,3495,3498,3500,3502],{"class":334,"line":3486},79,[332,3488,1771],{"class":338},[332,3490,3491],{"class":369}," (saveTimer) { ",[332,3493,3494],{"class":342},"clearTimeout",[332,3496,3497],{"class":369},"(saveTimer); saveTimer ",[332,3499,2489],{"class":338},[332,3501,466],{"class":403},[332,3503,3504],{"class":369},"; }\n",[332,3506,3508,3510,3513,3515],{"class":334,"line":3507},80,[332,3509,1740],{"class":338},[332,3511,3512],{"class":403}," payload",[332,3514,346],{"class":338},[332,3516,390],{"class":369},[332,3518,3520,3523],{"class":334,"line":3519},81,[332,3521,3522],{"class":338},"    ...",[332,3524,3525],{"class":369},"wbs.value,\n",[332,3527,3529,3532,3535,3538,3540,3542,3544,3546,3548,3551,3553,3555,3557,3559],{"class":334,"line":3528},82,[332,3530,3531],{"class":369},"    _meta: { ",[332,3533,3534],{"class":338},"...",[332,3536,3537],{"class":369},"wbs.value._meta, lastUpdated: ",[332,3539,2105],{"class":338},[332,3541,2108],{"class":342},[332,3543,2111],{"class":369},[332,3545,2114],{"class":342},[332,3547,2111],{"class":369},[332,3549,3550],{"class":342},"slice",[332,3552,1101],{"class":369},[332,3554,1506],{"class":403},[332,3556,1563],{"class":369},[332,3558,890],{"class":403},[332,3560,3561],{"class":369},") },\n",[332,3563,3565],{"class":334,"line":3564},83,[332,3566,727],{"class":369},[332,3568,3570,3573,3575,3577],{"class":334,"line":3569},84,[332,3571,3572],{"class":369},"  saveState.value ",[332,3574,2489],{"class":338},[332,3576,3328],{"class":349},[332,3578,370],{"class":369},[332,3580,3582,3585,3587,3589],{"class":334,"line":3581},85,[332,3583,3584],{"class":369},"  saveError.value ",[332,3586,2489],{"class":338},[332,3588,466],{"class":403},[332,3590,370],{"class":369},[332,3592,3594,3596],{"class":334,"line":3593},86,[332,3595,1943],{"class":338},[332,3597,390],{"class":369},[332,3599,3601,3603,3606,3608,3610,3612,3614,3616,3618,3620],{"class":334,"line":3600},87,[332,3602,3017],{"class":338},[332,3604,3605],{"class":403}," res",[332,3607,346],{"class":338},[332,3609,1748],{"class":338},[332,3611,3027],{"class":342},[332,3613,1101],{"class":369},[332,3615,3032],{"class":349},[332,3617,2434],{"class":403},[332,3619,3037],{"class":349},[332,3621,3622],{"class":369},", {\n",[332,3624,3626,3629,3631],{"class":334,"line":3625},88,[332,3627,3628],{"class":369},"      method: ",[332,3630,1566],{"class":349},[332,3632,797],{"class":369},[332,3634,3636,3639,3641,3643,3646],{"class":334,"line":3635},89,[332,3637,3638],{"class":369},"      headers: { ",[332,3640,1587],{"class":349},[332,3642,791],{"class":369},[332,3644,3645],{"class":349},"\"application\u002Fjson\"",[332,3647,2076],{"class":369},[332,3649,3651,3654,3657,3659,3662],{"class":334,"line":3650},90,[332,3652,3653],{"class":369},"      body: ",[332,3655,3656],{"class":403},"JSON",[332,3658,1423],{"class":369},[332,3660,3661],{"class":342},"stringify",[332,3663,3664],{"class":369},"(payload),\n",[332,3666,3668],{"class":334,"line":3667},91,[332,3669,3670],{"class":369},"    });\n",[332,3672,3674,3676,3678,3680,3683,3685,3687,3689,3691,3694,3697,3699,3701,3703],{"class":334,"line":3673},92,[332,3675,3049],{"class":338},[332,3677,1379],{"class":369},[332,3679,1382],{"class":338},[332,3681,3682],{"class":369},"res.ok) ",[332,3684,3140],{"class":338},[332,3686,1306],{"class":338},[332,3688,3145],{"class":342},[332,3690,1101],{"class":369},[332,3692,3693],{"class":349},"`save ${",[332,3695,3696],{"class":369},"res",[332,3698,1423],{"class":349},[332,3700,3158],{"class":369},[332,3702,3161],{"class":349},[332,3704,1609],{"class":369},[332,3706,3708,3711,3713,3715,3717],{"class":334,"line":3707},93,[332,3709,3710],{"class":369},"    lastSavedAt.value ",[332,3712,2489],{"class":338},[332,3714,1306],{"class":338},[332,3716,2108],{"class":342},[332,3718,1818],{"class":369},[332,3720,3722,3725,3727,3729],{"class":334,"line":3721},94,[332,3723,3724],{"class":369},"    saveState.value ",[332,3726,2489],{"class":338},[332,3728,3333],{"class":349},[332,3730,370],{"class":369},[332,3732,3734,3737,3739],{"class":334,"line":3733},95,[332,3735,3736],{"class":369},"    wbs.value._meta ",[332,3738,2489],{"class":338},[332,3740,3741],{"class":369}," payload._meta;\n",[332,3743,3745,3747,3749],{"class":334,"line":3744},96,[332,3746,1965],{"class":369},[332,3748,1968],{"class":338},[332,3750,3235],{"class":369},[332,3752,3754,3757,3759,3762,3764,3766],{"class":334,"line":3753},97,[332,3755,3756],{"class":369},"    saveError.value ",[332,3758,2489],{"class":338},[332,3760,3761],{"class":369}," (e ",[332,3763,3075],{"class":338},[332,3765,3145],{"class":342},[332,3767,3768],{"class":369},").message;\n",[332,3770,3772,3774,3776,3778],{"class":334,"line":3771},98,[332,3773,3724],{"class":369},[332,3775,2489],{"class":338},[332,3777,3338],{"class":349},[332,3779,370],{"class":369},[332,3781,3783],{"class":334,"line":3782},99,[332,3784,1047],{"class":369},[332,3786,3788],{"class":334,"line":3787},100,[332,3789,1052],{"class":369},[332,3791,3793],{"class":334,"line":3792},101,[332,3794,377],{"emptyLinePlaceholder":376},[332,3796,3798,3801,3804],{"class":334,"line":3797},102,[332,3799,3800],{"class":338},"function",[332,3802,3803],{"class":342}," scheduleSave",[332,3805,2983],{"class":369},[332,3807,3809,3811,3813,3815],{"class":334,"line":3808},103,[332,3810,3572],{"class":369},[332,3812,2489],{"class":338},[332,3814,3323],{"class":349},[332,3816,370],{"class":369},[332,3818,3820,3822,3825,3827],{"class":334,"line":3819},104,[332,3821,1771],{"class":338},[332,3823,3824],{"class":369}," (saveTimer) ",[332,3826,3494],{"class":342},[332,3828,3829],{"class":369},"(saveTimer);\n",[332,3831,3833,3836,3838,3841,3844,3847],{"class":334,"line":3832},105,[332,3834,3835],{"class":369},"  saveTimer ",[332,3837,2489],{"class":338},[332,3839,3840],{"class":342}," setTimeout",[332,3842,3843],{"class":369},"(saveNow, ",[332,3845,3846],{"class":403},"800",[332,3848,1609],{"class":369},[332,3850,3852],{"class":334,"line":3851},106,[332,3853,1052],{"class":369},[332,3855,3857],{"class":334,"line":3856},107,[332,3858,377],{"emptyLinePlaceholder":376},[332,3860,3862,3864,3867,3869,3872,3874,3876,3878,3881,3883,3885],{"class":334,"line":3861},108,[332,3863,3800],{"class":338},[332,3865,3866],{"class":342}," setOverride",[332,3868,1101],{"class":369},[332,3870,3871],{"class":396},"taskId",[332,3873,400],{"class":338},[332,3875,404],{"class":403},[332,3877,1563],{"class":369},[332,3879,3880],{"class":396},"patch",[332,3882,400],{"class":338},[332,3884,2916],{"class":342},[332,3886,2018],{"class":369},[332,3888,3890,3892,3894,3896,3898,3900],{"class":334,"line":3889},109,[332,3891,1771],{"class":338},[332,3893,1379],{"class":369},[332,3895,1382],{"class":338},[332,3897,3479],{"class":369},[332,3899,1388],{"class":338},[332,3901,370],{"class":369},[332,3903,3905,3908,3910,3912,3915,3918],{"class":334,"line":3904},110,[332,3906,3907],{"class":338},"  for",[332,3909,1379],{"class":369},[332,3911,1298],{"class":338},[332,3913,3914],{"class":403}," s",[332,3916,3917],{"class":338}," of",[332,3919,3920],{"class":369}," wbs.value.phase1.stages) {\n",[332,3922,3924,3926,3929,3931,3934,3937,3940,3942,3944,3946,3949,3951],{"class":334,"line":3923},111,[332,3925,3017],{"class":338},[332,3927,3928],{"class":403}," idx",[332,3930,346],{"class":338},[332,3932,3933],{"class":369}," s.tasks.",[332,3935,3936],{"class":342},"findIndex",[332,3938,3939],{"class":369},"((",[332,3941,2252],{"class":396},[332,3943,1366],{"class":369},[332,3945,1369],{"class":338},[332,3947,3948],{"class":369}," t.id ",[332,3950,3096],{"class":338},[332,3952,3953],{"class":369}," taskId);\n",[332,3955,3957,3959,3962,3964,3967,3970,3972,3975],{"class":334,"line":3956},112,[332,3958,3049],{"class":338},[332,3960,3961],{"class":369}," (idx ",[332,3963,3096],{"class":338},[332,3965,3966],{"class":338}," -",[332,3968,3969],{"class":403},"1",[332,3971,1366],{"class":369},[332,3973,3974],{"class":338},"continue",[332,3976,370],{"class":369},[332,3978,3980,3982,3985,3987],{"class":334,"line":3979},113,[332,3981,3017],{"class":338},[332,3983,3984],{"class":403}," cur",[332,3986,346],{"class":338},[332,3988,3989],{"class":369}," s.tasks[idx];\n",[332,3991,3993,3995,3998,4000,4002,4004],{"class":334,"line":3992},114,[332,3994,3017],{"class":338},[332,3996,3997],{"class":403}," next",[332,3999,400],{"class":338},[332,4001,385],{"class":342},[332,4003,346],{"class":338},[332,4005,390],{"class":369},[332,4007,4009,4012],{"class":334,"line":4008},115,[332,4010,4011],{"class":338},"      ...",[332,4013,4014],{"class":369},"cur,\n",[332,4016,4018,4020],{"class":334,"line":4017},116,[332,4019,4011],{"class":338},[332,4021,4022],{"class":369},"patch,\n",[332,4024,4026,4029,4032,4035,4038,4041,4044,4046,4049],{"class":334,"line":4025},117,[332,4027,4028],{"class":369},"      deliverableUrl: patch.deliverableUrl ",[332,4030,4031],{"class":338},"!==",[332,4033,4034],{"class":403}," undefined",[332,4036,4037],{"class":338}," ?",[332,4039,4040],{"class":369}," patch.deliverableUrl ",[332,4042,4043],{"class":338},"||",[332,4045,466],{"class":403},[332,4047,4048],{"class":338}," :",[332,4050,4051],{"class":369}," cur.deliverableUrl,\n",[332,4053,4055,4058,4060,4062,4064,4067,4069,4071,4073],{"class":334,"line":4054},118,[332,4056,4057],{"class":369},"      targetDate: patch.targetDate ",[332,4059,4031],{"class":338},[332,4061,4034],{"class":403},[332,4063,4037],{"class":338},[332,4065,4066],{"class":369}," patch.targetDate ",[332,4068,4043],{"class":338},[332,4070,466],{"class":403},[332,4072,4048],{"class":338},[332,4074,4075],{"class":369}," cur.targetDate,\n",[332,4077,4079,4082,4084,4086,4088,4091,4093,4095,4097],{"class":334,"line":4078},119,[332,4080,4081],{"class":369},"      completionDate: patch.completionDate ",[332,4083,4031],{"class":338},[332,4085,4034],{"class":403},[332,4087,4037],{"class":338},[332,4089,4090],{"class":369}," patch.completionDate ",[332,4092,4043],{"class":338},[332,4094,466],{"class":403},[332,4096,4048],{"class":338},[332,4098,4099],{"class":369}," cur.completionDate,\n",[332,4101,4103,4106,4108,4110,4112,4115,4117,4119,4121],{"class":334,"line":4102},120,[332,4104,4105],{"class":369},"      note: patch.note ",[332,4107,4031],{"class":338},[332,4109,4034],{"class":403},[332,4111,4037],{"class":338},[332,4113,4114],{"class":369}," patch.note ",[332,4116,4043],{"class":338},[332,4118,466],{"class":403},[332,4120,4048],{"class":338},[332,4122,4123],{"class":369}," cur.note,\n",[332,4125,4127],{"class":334,"line":4126},121,[332,4128,4129],{"class":369},"    };\n",[332,4131,4133,4136,4139,4142,4144],{"class":334,"line":4132},122,[332,4134,4135],{"class":369},"    s.tasks.",[332,4137,4138],{"class":342},"splice",[332,4140,4141],{"class":369},"(idx, ",[332,4143,3969],{"class":403},[332,4145,4146],{"class":369},", next);\n",[332,4148,4150,4153],{"class":334,"line":4149},123,[332,4151,4152],{"class":342},"    scheduleSave",[332,4154,1818],{"class":369},[332,4156,4158,4160],{"class":334,"line":4157},124,[332,4159,1976],{"class":338},[332,4161,370],{"class":369},[332,4163,4165],{"class":334,"line":4164},125,[332,4166,1047],{"class":369},[332,4168,4170],{"class":334,"line":4169},126,[332,4171,1052],{"class":369},[332,4173,4175],{"class":334,"line":4174},127,[332,4176,377],{"emptyLinePlaceholder":376},[332,4178,4180],{"class":334,"line":4179},128,[332,4181,4182],{"class":410},"\u002F\u002F ── 파생 상태 ──────────────────────────────────────────\n",[332,4184,4186,4188,4191,4193,4196,4198,4201,4204,4206,4209,4212],{"class":334,"line":4185},129,[332,4187,1298],{"class":338},[332,4189,4190],{"class":403}," mergedStages",[332,4192,346],{"class":338},[332,4194,4195],{"class":342}," computed",[332,4197,2303],{"class":369},[332,4199,4200],{"class":342},"Stage",[332,4202,4203],{"class":369},"[]>(() ",[332,4205,1369],{"class":338},[332,4207,4208],{"class":369}," wbs.value?.phase1.stages ",[332,4210,4211],{"class":338},"??",[332,4213,4214],{"class":369}," []);\n",[332,4216,4218,4220,4223,4225,4227,4230,4232,4235,4237,4240],{"class":334,"line":4217},130,[332,4219,1298],{"class":338},[332,4221,4222],{"class":403}," PROJECT_NAME",[332,4224,346],{"class":338},[332,4226,4195],{"class":342},[332,4228,4229],{"class":369},"(() ",[332,4231,1369],{"class":338},[332,4233,4234],{"class":369}," wbs.value?._meta.project ",[332,4236,4211],{"class":338},[332,4238,4239],{"class":349}," \"Project\"",[332,4241,1609],{"class":369},[332,4243,4245,4247,4250,4252,4254,4256,4258,4261,4263,4266],{"class":334,"line":4244},131,[332,4246,1298],{"class":338},[332,4248,4249],{"class":403}," LAST_UPDATED",[332,4251,346],{"class":338},[332,4253,4195],{"class":342},[332,4255,4229],{"class":369},[332,4257,1369],{"class":338},[332,4259,4260],{"class":369}," wbs.value?._meta.lastUpdated ",[332,4262,4211],{"class":338},[332,4264,4265],{"class":349}," \"—\"",[332,4267,1609],{"class":369},[332,4269,4271],{"class":334,"line":4270},132,[332,4272,377],{"emptyLinePlaceholder":376},[332,4274,4276,4278,4281,4283,4285,4287,4289],{"class":334,"line":4275},133,[332,4277,1298],{"class":338},[332,4279,4280],{"class":403}," weightedAverage",[332,4282,346],{"class":338},[332,4284,4195],{"class":342},[332,4286,4229],{"class":369},[332,4288,1369],{"class":338},[332,4290,390],{"class":369},[332,4292,4294,4296,4299,4301],{"class":334,"line":4293},134,[332,4295,1740],{"class":338},[332,4297,4298],{"class":403}," st",[332,4300,346],{"class":338},[332,4302,4303],{"class":369}," mergedStages.value;\n",[332,4305,4307,4309,4311,4313,4316,4318,4320,4322,4325],{"class":334,"line":4306},135,[332,4308,1771],{"class":338},[332,4310,1379],{"class":369},[332,4312,1382],{"class":338},[332,4314,4315],{"class":369},"st.",[332,4317,2009],{"class":403},[332,4319,1366],{"class":369},[332,4321,1388],{"class":338},[332,4323,4324],{"class":403}," 0",[332,4326,370],{"class":369},[332,4328,4330],{"class":334,"line":4329},136,[332,4331,4332],{"class":410},"  \u002F\u002F 가중평균(%) = Σ(weight × progress) \u002F Σ(weight). progress가 이미 %단위이므로 추가 \u002F100 없음.\n",[332,4334,4336,4338,4341,4343,4346,4349,4351,4354,4356,4359,4361,4363,4366,4368,4371,4373],{"class":334,"line":4335},137,[332,4337,1740],{"class":338},[332,4339,4340],{"class":403}," w",[332,4342,346],{"class":338},[332,4344,4345],{"class":369}," st.",[332,4347,4348],{"class":342},"reduce",[332,4350,3939],{"class":369},[332,4352,4353],{"class":396},"s",[332,4355,1563],{"class":369},[332,4357,4358],{"class":396},"x",[332,4360,1366],{"class":369},[332,4362,1369],{"class":338},[332,4364,4365],{"class":369}," s ",[332,4367,1521],{"class":338},[332,4369,4370],{"class":369}," x.weight, ",[332,4372,1506],{"class":403},[332,4374,1609],{"class":369},[332,4376,4378,4380,4383,4385,4387,4389,4391,4393,4395,4397,4399,4401,4403,4405,4408,4411,4414,4416],{"class":334,"line":4377},138,[332,4379,1740],{"class":338},[332,4381,4382],{"class":403}," p",[332,4384,346],{"class":338},[332,4386,4345],{"class":369},[332,4388,4348],{"class":342},[332,4390,3939],{"class":369},[332,4392,4353],{"class":396},[332,4394,1563],{"class":369},[332,4396,4358],{"class":396},[332,4398,1366],{"class":369},[332,4400,1369],{"class":338},[332,4402,4365],{"class":369},[332,4404,1521],{"class":338},[332,4406,4407],{"class":369}," x.weight ",[332,4409,4410],{"class":338},"*",[332,4412,4413],{"class":369}," x.progress, ",[332,4415,1506],{"class":403},[332,4417,1609],{"class":369},[332,4419,4421,4423,4426,4429,4432,4434,4437,4439,4442,4444,4446,4448],{"class":334,"line":4420},139,[332,4422,1824],{"class":338},[332,4424,4425],{"class":369}," Math.",[332,4427,4428],{"class":342},"round",[332,4430,4431],{"class":369},"((p ",[332,4433,1402],{"class":338},[332,4435,4436],{"class":369}," w) ",[332,4438,4410],{"class":338},[332,4440,4441],{"class":403}," 10",[332,4443,1366],{"class":369},[332,4445,1402],{"class":338},[332,4447,4441],{"class":403},[332,4449,370],{"class":369},[332,4451,4453],{"class":334,"line":4452},140,[332,4454,1887],{"class":369},[332,4456,4458],{"class":334,"line":4457},141,[332,4459,377],{"emptyLinePlaceholder":376},[332,4461,4463,4465,4468,4470,4472,4474,4476,4479,4482,4484,4486,4488,4490],{"class":334,"line":4462},142,[332,4464,1298],{"class":338},[332,4466,4467],{"class":403}," allTasks",[332,4469,346],{"class":338},[332,4471,4195],{"class":342},[332,4473,4229],{"class":369},[332,4475,1369],{"class":338},[332,4477,4478],{"class":369}," mergedStages.value.",[332,4480,4481],{"class":342},"flatMap",[332,4483,3939],{"class":369},[332,4485,4353],{"class":396},[332,4487,1366],{"class":369},[332,4489,1369],{"class":338},[332,4491,4492],{"class":369}," s.tasks));\n",[332,4494,4496,4498,4501,4503,4505,4507,4509],{"class":334,"line":4495},143,[332,4497,1298],{"class":338},[332,4499,4500],{"class":403}," totalCounts",[332,4502,346],{"class":338},[332,4504,4195],{"class":342},[332,4506,4229],{"class":369},[332,4508,1369],{"class":338},[332,4510,390],{"class":369},[332,4512,4514,4516,4519,4521,4524,4526,4529,4531,4534,4537,4539,4542,4544,4547,4549,4552,4554,4557,4559],{"class":334,"line":4513},144,[332,4515,1740],{"class":338},[332,4517,4518],{"class":403}," acc",[332,4520,400],{"class":338},[332,4522,4523],{"class":342}," Record",[332,4525,2303],{"class":369},[332,4527,4528],{"class":342},"Status",[332,4530,1563],{"class":369},[332,4532,4533],{"class":403},"number",[332,4535,4536],{"class":369},"> ",[332,4538,2489],{"class":338},[332,4540,4541],{"class":369}," { done: ",[332,4543,1506],{"class":403},[332,4545,4546],{"class":369},", in_progress: ",[332,4548,1506],{"class":403},[332,4550,4551],{"class":369},", pending: ",[332,4553,1506],{"class":403},[332,4555,4556],{"class":369},", blocked: ",[332,4558,1506],{"class":403},[332,4560,2787],{"class":369},[332,4562,4564,4566,4568,4570,4573,4575,4578,4581],{"class":334,"line":4563},145,[332,4565,3907],{"class":338},[332,4567,1379],{"class":369},[332,4569,1298],{"class":338},[332,4571,4572],{"class":403}," t",[332,4574,3917],{"class":338},[332,4576,4577],{"class":369}," allTasks.value) acc[t.status]",[332,4579,4580],{"class":338},"++",[332,4582,370],{"class":369},[332,4584,4586,4588],{"class":334,"line":4585},146,[332,4587,1824],{"class":338},[332,4589,4590],{"class":369}," acc;\n",[332,4592,4594],{"class":334,"line":4593},147,[332,4595,1887],{"class":369},[332,4597,4599],{"class":334,"line":4598},148,[332,4600,377],{"emptyLinePlaceholder":376},[332,4602,4604,4606,4609,4611,4613,4615,4617],{"class":334,"line":4603},149,[332,4605,3800],{"class":338},[332,4607,4608],{"class":342}," isOverdue",[332,4610,1101],{"class":369},[332,4612,2252],{"class":396},[332,4614,400],{"class":338},[332,4616,385],{"class":342},[332,4618,2018],{"class":369},[332,4620,4622,4624,4627,4629,4631,4634,4637,4640,4642,4644],{"class":334,"line":4621},150,[332,4623,1771],{"class":338},[332,4625,4626],{"class":369}," (t.status ",[332,4628,3096],{"class":338},[332,4630,350],{"class":349},[332,4632,4633],{"class":338}," ||",[332,4635,4636],{"class":338}," !",[332,4638,4639],{"class":369},"t.targetDate) ",[332,4641,1388],{"class":338},[332,4643,3273],{"class":403},[332,4645,370],{"class":369},[332,4647,4649,4651,4654,4656,4658],{"class":334,"line":4648},151,[332,4650,1824],{"class":338},[332,4652,4653],{"class":369}," t.targetDate ",[332,4655,2303],{"class":338},[332,4657,4249],{"class":403},[332,4659,4660],{"class":369},".value;\n",[332,4662,4664],{"class":334,"line":4663},152,[332,4665,1052],{"class":369},[332,4667,4669],{"class":334,"line":4668},153,[332,4670,377],{"emptyLinePlaceholder":376},[332,4672,4674,4676,4679,4681,4683,4685,4687,4690,4693,4695,4697,4699,4702,4704,4706,4708,4711,4713,4715,4718,4720],{"class":334,"line":4673},154,[332,4675,1298],{"class":338},[332,4677,4678],{"class":403}," statusMeta",[332,4680,400],{"class":338},[332,4682,4523],{"class":342},[332,4684,2303],{"class":369},[332,4686,4528],{"class":342},[332,4688,4689],{"class":369},", { ",[332,4691,4692],{"class":396},"label",[332,4694,400],{"class":338},[332,4696,404],{"class":403},[332,4698,603],{"class":369},[332,4700,4701],{"class":396},"chipCls",[332,4703,400],{"class":338},[332,4705,404],{"class":403},[332,4707,603],{"class":369},[332,4709,4710],{"class":396},"emoji",[332,4712,400],{"class":338},[332,4714,404],{"class":403},[332,4716,4717],{"class":369}," }> ",[332,4719,2489],{"class":338},[332,4721,390],{"class":369},[332,4723,4725,4728,4731,4734,4737,4740,4743],{"class":334,"line":4724},155,[332,4726,4727],{"class":369},"  done:        { label: ",[332,4729,4730],{"class":349},"\"완료\"",[332,4732,4733],{"class":369},",   chipCls: ",[332,4735,4736],{"class":349},"\"bg-emerald-50 text-emerald-700 border-emerald-200\"",[332,4738,4739],{"class":369},", emoji: ",[332,4741,4742],{"class":349},"\"✓\"",[332,4744,2076],{"class":369},[332,4746,4748,4751,4754,4757,4760,4763,4766],{"class":334,"line":4747},156,[332,4749,4750],{"class":369},"  in_progress: { label: ",[332,4752,4753],{"class":349},"\"진행 중\"",[332,4755,4756],{"class":369},", chipCls: ",[332,4758,4759],{"class":349},"\"bg-amber-50 text-amber-700 border-amber-200\"",[332,4761,4762],{"class":369},",       emoji: ",[332,4764,4765],{"class":349},"\"◐\"",[332,4767,2076],{"class":369},[332,4769,4771,4774,4777,4779,4782,4784,4787],{"class":334,"line":4770},157,[332,4772,4773],{"class":369},"  pending:     { label: ",[332,4775,4776],{"class":349},"\"대기\"",[332,4778,4733],{"class":369},[332,4780,4781],{"class":349},"\"bg-neutral-50 text-neutral-600 border-neutral-200\"",[332,4783,4739],{"class":369},[332,4785,4786],{"class":349},"\"○\"",[332,4788,2076],{"class":369},[332,4790,4792,4795,4798,4800,4803,4806,4809],{"class":334,"line":4791},158,[332,4793,4794],{"class":369},"  blocked:     { label: ",[332,4796,4797],{"class":349},"\"보류\"",[332,4799,4733],{"class":369},[332,4801,4802],{"class":349},"\"bg-rose-50 text-rose-700 border-rose-200\"",[332,4804,4805],{"class":369},",          emoji: ",[332,4807,4808],{"class":349},"\"✕\"",[332,4810,2076],{"class":369},[332,4812,4814],{"class":334,"line":4813},159,[332,4815,529],{"class":369},[332,4817,4819],{"class":334,"line":4818},160,[332,4820,377],{"emptyLinePlaceholder":376},[332,4822,4824,4826,4829,4831,4834,4836,4838],{"class":334,"line":4823},161,[332,4825,3800],{"class":338},[332,4827,4828],{"class":342}," progressFill",[332,4830,1101],{"class":369},[332,4832,4833],{"class":396},"pct",[332,4835,400],{"class":338},[332,4837,584],{"class":403},[332,4839,2018],{"class":369},[332,4841,4843,4845,4848,4851,4854,4856,4858,4861],{"class":334,"line":4842},162,[332,4844,1771],{"class":338},[332,4846,4847],{"class":369}," (pct ",[332,4849,4850],{"class":338},">=",[332,4852,4853],{"class":403}," 70",[332,4855,1366],{"class":369},[332,4857,1388],{"class":338},[332,4859,4860],{"class":349}," \"bg-emerald-500\"",[332,4862,370],{"class":369},[332,4864,4866,4868,4870,4872,4875,4877,4879,4882],{"class":334,"line":4865},163,[332,4867,1771],{"class":338},[332,4869,4847],{"class":369},[332,4871,4850],{"class":338},[332,4873,4874],{"class":403}," 30",[332,4876,1366],{"class":369},[332,4878,1388],{"class":338},[332,4880,4881],{"class":349}," \"bg-amber-500\"",[332,4883,370],{"class":369},[332,4885,4887,4889,4891,4893,4895,4898,4900,4903],{"class":334,"line":4886},164,[332,4888,1771],{"class":338},[332,4890,4847],{"class":369},[332,4892,2312],{"class":338},[332,4894,4324],{"class":403},[332,4896,4897],{"class":369},")   ",[332,4899,1388],{"class":338},[332,4901,4902],{"class":349}," \"bg-neutral-400\"",[332,4904,370],{"class":369},[332,4906,4908,4910,4913],{"class":334,"line":4907},165,[332,4909,1824],{"class":338},[332,4911,4912],{"class":349}," \"bg-neutral-200\"",[332,4914,370],{"class":369},[332,4916,4918],{"class":334,"line":4917},166,[332,4919,1052],{"class":369},[332,4921,4923],{"class":334,"line":4922},167,[332,4924,377],{"emptyLinePlaceholder":376},[332,4926,4928,4930,4933,4935,4938,4941,4943,4946,4948,4951,4953,4956,4958,4961,4963,4966],{"class":334,"line":4927},168,[332,4929,1298],{"class":338},[332,4931,4932],{"class":403}," stageEmoji",[332,4934,346],{"class":338},[332,4936,4937],{"class":369}," [",[332,4939,4940],{"class":349},"\"🎯\"",[332,4942,1563],{"class":369},[332,4944,4945],{"class":349},"\"📐\"",[332,4947,1563],{"class":369},[332,4949,4950],{"class":349},"\"🛠️\"",[332,4952,1563],{"class":369},[332,4954,4955],{"class":349},"\"📚\"",[332,4957,1563],{"class":369},[332,4959,4960],{"class":349},"\"🧪\"",[332,4962,1563],{"class":369},[332,4964,4965],{"class":349},"\"🚀\"",[332,4967,4968],{"class":369},"];\n",[332,4970,4972],{"class":334,"line":4971},169,[332,4973,377],{"emptyLinePlaceholder":376},[332,4975,4977],{"class":334,"line":4976},170,[332,4978,4979],{"class":410},"\u002F\u002F ── 백업 다운로드 ─────────────────────────────────────\n",[332,4981,4983,4985,4988,4990,4992,4994,4996,4999,5001,5004,5006,5008,5011,5013,5015,5018,5020,5022,5025,5028,5031,5033,5036],{"class":334,"line":4982},171,[332,4984,1298],{"class":338},[332,4986,4987],{"class":403}," currentJsonString",[332,4989,346],{"class":338},[332,4991,4195],{"class":342},[332,4993,4229],{"class":369},[332,4995,1369],{"class":338},[332,4997,4998],{"class":369}," wbs.value ",[332,5000,1487],{"class":338},[332,5002,5003],{"class":403}," JSON",[332,5005,1423],{"class":369},[332,5007,3661],{"class":342},[332,5009,5010],{"class":369},"(wbs.value, ",[332,5012,986],{"class":403},[332,5014,1563],{"class":369},[332,5016,5017],{"class":403},"2",[332,5019,1366],{"class":369},[332,5021,1521],{"class":338},[332,5023,5024],{"class":349}," \"",[332,5026,5027],{"class":403},"\\n",[332,5029,5030],{"class":349},"\"",[332,5032,4048],{"class":338},[332,5034,5035],{"class":349}," \"\"",[332,5037,1609],{"class":369},[332,5039,5041,5043,5046],{"class":334,"line":5040},172,[332,5042,3800],{"class":338},[332,5044,5045],{"class":342}," downloadJson",[332,5047,2983],{"class":369},[332,5049,5051,5053,5056,5058,5060,5063,5066,5068],{"class":334,"line":5050},173,[332,5052,1740],{"class":338},[332,5054,5055],{"class":403}," blob",[332,5057,346],{"class":338},[332,5059,1306],{"class":338},[332,5061,5062],{"class":342}," Blob",[332,5064,5065],{"class":369},"([currentJsonString.value], { type: ",[332,5067,3645],{"class":349},[332,5069,2508],{"class":369},[332,5071,5073,5075,5078,5080,5083,5085,5088],{"class":334,"line":5072},174,[332,5074,1740],{"class":338},[332,5076,5077],{"class":403}," url",[332,5079,346],{"class":338},[332,5081,5082],{"class":403}," URL",[332,5084,1423],{"class":369},[332,5086,5087],{"class":342},"createObjectURL",[332,5089,5090],{"class":369},"(blob);\n",[332,5092,5094,5096,5099,5101,5104,5107,5109,5112],{"class":334,"line":5093},175,[332,5095,1740],{"class":338},[332,5097,5098],{"class":403}," a",[332,5100,346],{"class":338},[332,5102,5103],{"class":369}," document.",[332,5105,5106],{"class":342},"createElement",[332,5108,1101],{"class":369},[332,5110,5111],{"class":349},"\"a\"",[332,5113,1609],{"class":369},[332,5115,5117,5120,5122,5125,5127,5130,5133,5136],{"class":334,"line":5116},176,[332,5118,5119],{"class":369},"  a.href ",[332,5121,2489],{"class":338},[332,5123,5124],{"class":369}," url; a.download ",[332,5126,2489],{"class":338},[332,5128,5129],{"class":349}," \"wbs.json\"",[332,5131,5132],{"class":369},"; a.",[332,5134,5135],{"class":342},"click",[332,5137,1818],{"class":369},[332,5139,5141,5144,5146,5148,5150,5152,5155,5158,5161],{"class":334,"line":5140},177,[332,5142,5143],{"class":342},"  setTimeout",[332,5145,4229],{"class":369},[332,5147,1369],{"class":338},[332,5149,5082],{"class":403},[332,5151,1423],{"class":369},[332,5153,5154],{"class":342},"revokeObjectURL",[332,5156,5157],{"class":369},"(url), ",[332,5159,5160],{"class":403},"1000",[332,5162,1609],{"class":369},[332,5164,5166],{"class":334,"line":5165},178,[332,5167,1052],{"class":369},[332,5169,5171],{"class":334,"line":5170},179,[332,5172,377],{"emptyLinePlaceholder":376},[332,5174,5176],{"class":334,"line":5175},180,[332,5177,5178],{"class":410},"\u002F\u002F ── \"n초 전\" 갱신 ─────────────────────────────────────\n",[332,5180,5182,5184,5187,5189,5191,5193,5196],{"class":334,"line":5181},181,[332,5183,1298],{"class":338},[332,5185,5186],{"class":403}," savedAgo",[332,5188,346],{"class":338},[332,5190,2846],{"class":342},[332,5192,1101],{"class":369},[332,5194,5195],{"class":349},"\"\"",[332,5197,1609],{"class":369},[332,5199,5201,5203,5206,5208,5210,5212,5214,5217,5219,5221,5223,5225],{"class":334,"line":5200},182,[332,5202,3424],{"class":338},[332,5204,5205],{"class":369}," agoTimer",[332,5207,400],{"class":338},[332,5209,3432],{"class":342},[332,5211,2303],{"class":369},[332,5213,3437],{"class":338},[332,5215,5216],{"class":369}," setInterval> ",[332,5218,1498],{"class":338},[332,5220,466],{"class":403},[332,5222,346],{"class":338},[332,5224,466],{"class":403},[332,5226,370],{"class":369},[332,5228,5230,5232,5235,5237,5240,5242,5244],{"class":334,"line":5229},183,[332,5231,3800],{"class":338},[332,5233,5234],{"class":342}," formatAgo",[332,5236,1101],{"class":369},[332,5238,5239],{"class":396},"d",[332,5241,400],{"class":338},[332,5243,2108],{"class":342},[332,5245,2018],{"class":369},[332,5247,5249,5251,5253,5255,5257,5260,5263,5266,5269,5272,5275,5278,5280,5282,5285],{"class":334,"line":5248},184,[332,5250,1740],{"class":338},[332,5252,3914],{"class":403},[332,5254,346],{"class":338},[332,5256,4425],{"class":369},[332,5258,5259],{"class":342},"floor",[332,5261,5262],{"class":369},"((Date.",[332,5264,5265],{"class":342},"now",[332,5267,5268],{"class":369},"() ",[332,5270,5271],{"class":338},"-",[332,5273,5274],{"class":369}," d.",[332,5276,5277],{"class":342},"getTime",[332,5279,3072],{"class":369},[332,5281,1402],{"class":338},[332,5283,5284],{"class":403}," 1000",[332,5286,1609],{"class":369},[332,5288,5290,5292,5295,5297,5300,5302,5304,5307],{"class":334,"line":5289},185,[332,5291,1771],{"class":338},[332,5293,5294],{"class":369}," (s ",[332,5296,2303],{"class":338},[332,5298,5299],{"class":403}," 5",[332,5301,1366],{"class":369},[332,5303,1388],{"class":338},[332,5305,5306],{"class":349}," \"방금\"",[332,5308,370],{"class":369},[332,5310,5312,5314,5316,5318,5321,5323,5325,5328,5330,5333],{"class":334,"line":5311},186,[332,5313,1771],{"class":338},[332,5315,5294],{"class":369},[332,5317,2303],{"class":338},[332,5319,5320],{"class":403}," 60",[332,5322,1366],{"class":369},[332,5324,1388],{"class":338},[332,5326,5327],{"class":349}," `${",[332,5329,4353],{"class":369},[332,5331,5332],{"class":349},"}초 전`",[332,5334,370],{"class":369},[332,5336,5338,5340,5343,5345,5347,5349,5352,5354,5356],{"class":334,"line":5337},187,[332,5339,1740],{"class":338},[332,5341,5342],{"class":403}," m",[332,5344,346],{"class":338},[332,5346,4425],{"class":369},[332,5348,5259],{"class":342},[332,5350,5351],{"class":369},"(s ",[332,5353,1402],{"class":338},[332,5355,5320],{"class":403},[332,5357,1609],{"class":369},[332,5359,5361,5363,5366,5368,5370,5372,5374,5376,5379,5382],{"class":334,"line":5360},188,[332,5362,1771],{"class":338},[332,5364,5365],{"class":369}," (m ",[332,5367,2303],{"class":338},[332,5369,5320],{"class":403},[332,5371,1366],{"class":369},[332,5373,1388],{"class":338},[332,5375,5327],{"class":349},[332,5377,5378],{"class":369},"m",[332,5380,5381],{"class":349},"}분 전`",[332,5383,370],{"class":369},[332,5385,5387,5389,5391,5394,5396,5398,5400,5402,5405,5407,5409,5412],{"class":334,"line":5386},189,[332,5388,1824],{"class":338},[332,5390,5327],{"class":349},[332,5392,5393],{"class":369},"Math",[332,5395,1423],{"class":349},[332,5397,5259],{"class":342},[332,5399,1101],{"class":349},[332,5401,5378],{"class":369},[332,5403,5404],{"class":338}," \u002F",[332,5406,5320],{"class":403},[332,5408,307],{"class":349},[332,5410,5411],{"class":349},"}시간 전`",[332,5413,370],{"class":369},[332,5415,5417],{"class":334,"line":5416},190,[332,5418,1052],{"class":369},[332,5420,5422,5424,5426,5428],{"class":334,"line":5421},191,[332,5423,3291],{"class":342},[332,5425,4229],{"class":369},[332,5427,1369],{"class":338},[332,5429,390],{"class":369},[332,5431,5433,5436,5438,5441,5443,5445],{"class":334,"line":5432},192,[332,5434,5435],{"class":369},"  agoTimer ",[332,5437,2489],{"class":338},[332,5439,5440],{"class":342}," setInterval",[332,5442,4229],{"class":369},[332,5444,1369],{"class":338},[332,5446,390],{"class":369},[332,5448,5450,5453,5455,5458,5460,5462,5465,5467,5469],{"class":334,"line":5449},193,[332,5451,5452],{"class":369},"    savedAgo.value ",[332,5454,2489],{"class":338},[332,5456,5457],{"class":369}," lastSavedAt.value ",[332,5459,1487],{"class":338},[332,5461,5234],{"class":342},[332,5463,5464],{"class":369},"(lastSavedAt.value) ",[332,5466,400],{"class":338},[332,5468,5035],{"class":349},[332,5470,370],{"class":369},[332,5472,5474,5477,5479],{"class":334,"line":5473},194,[332,5475,5476],{"class":369},"  }, ",[332,5478,5160],{"class":403},[332,5480,1609],{"class":369},[332,5482,5484],{"class":334,"line":5483},195,[332,5485,1887],{"class":369},[332,5487,5489,5492,5494,5496],{"class":334,"line":5488},196,[332,5490,5491],{"class":342},"onUnmounted",[332,5493,4229],{"class":369},[332,5495,1369],{"class":338},[332,5497,390],{"class":369},[332,5499,5501,5503,5506,5509],{"class":334,"line":5500},197,[332,5502,1771],{"class":338},[332,5504,5505],{"class":369}," (agoTimer) ",[332,5507,5508],{"class":342},"clearInterval",[332,5510,5511],{"class":369},"(agoTimer);\n",[332,5513,5515,5517,5519,5521],{"class":334,"line":5514},198,[332,5516,1771],{"class":338},[332,5518,3824],{"class":369},[332,5520,3494],{"class":342},[332,5522,3829],{"class":369},[332,5524,5526],{"class":334,"line":5525},199,[332,5527,1887],{"class":369},[332,5529,5531],{"class":334,"line":5530},200,[332,5532,377],{"emptyLinePlaceholder":376},[332,5534,5536,5538,5541,5543,5546,5548,5550],{"class":334,"line":5535},201,[332,5537,3800],{"class":338},[332,5539,5540],{"class":342}," scrollToStage",[332,5542,1101],{"class":369},[332,5544,5545],{"class":396},"stageId",[332,5547,400],{"class":338},[332,5549,404],{"class":403},[332,5551,2018],{"class":369},[332,5553,5555,5558,5561,5563,5566,5568,5570,5573,5576,5579,5582,5585,5588],{"class":334,"line":5554},202,[332,5556,5557],{"class":369},"  document.",[332,5559,5560],{"class":342},"getElementById",[332,5562,1101],{"class":369},[332,5564,5565],{"class":349},"`stage-${",[332,5567,5545],{"class":369},[332,5569,3161],{"class":349},[332,5571,5572],{"class":369},")?.",[332,5574,5575],{"class":342},"scrollIntoView",[332,5577,5578],{"class":369},"({ behavior: ",[332,5580,5581],{"class":349},"\"smooth\"",[332,5583,5584],{"class":369},", block: ",[332,5586,5587],{"class":349},"\"start\"",[332,5589,2508],{"class":369},[332,5591,5593],{"class":334,"line":5592},203,[332,5594,1052],{"class":369},[332,5596,5598,5601,5603],{"class":334,"line":5597},204,[332,5599,5600],{"class":369},"\u003C\u002F",[332,5602,2480],{"class":2479},[332,5604,2255],{"class":369},[332,5606,5608],{"class":334,"line":5607},205,[332,5609,377],{"emptyLinePlaceholder":376},[332,5611,5613,5615,5618],{"class":334,"line":5612},206,[332,5614,2303],{"class":369},[332,5616,5617],{"class":2479},"template",[332,5619,2255],{"class":369},[332,5621,5623,5626,5629,5632,5634,5637],{"class":334,"line":5622},207,[332,5624,5625],{"class":369},"  \u003C",[332,5627,5628],{"class":2479},"div",[332,5630,5631],{"class":342}," class",[332,5633,2489],{"class":369},[332,5635,5636],{"class":349},"\"min-h-screen bg-neutral-50\u002F60 pb-24\"",[332,5638,2255],{"class":369},[332,5640,5642,5645,5647,5649,5651,5654],{"class":334,"line":5641},208,[332,5643,5644],{"class":369},"    \u003C",[332,5646,5628],{"class":2479},[332,5648,5631],{"class":342},[332,5650,2489],{"class":369},[332,5652,5653],{"class":349},"\"mx-auto max-w-5xl px-6 pt-10 sm:px-10 sm:pt-14\"",[332,5655,2255],{"class":369},[332,5657,5659],{"class":334,"line":5658},209,[332,5660,5661],{"class":410},"      \u003C!-- HEADER -->\n",[332,5663,5665,5668,5671,5673,5675,5678],{"class":334,"line":5664},210,[332,5666,5667],{"class":369},"      \u003C",[332,5669,5670],{"class":2479},"header",[332,5672,5631],{"class":342},[332,5674,2489],{"class":369},[332,5676,5677],{"class":349},"\"mt-4 flex items-start justify-between gap-4\"",[332,5679,2255],{"class":369},[332,5681,5683,5686,5688,5690,5692,5695],{"class":334,"line":5682},211,[332,5684,5685],{"class":369},"        \u003C",[332,5687,5628],{"class":2479},[332,5689,5631],{"class":342},[332,5691,2489],{"class":369},[332,5693,5694],{"class":349},"\"flex items-start gap-3\"",[332,5696,2255],{"class":369},[332,5698,5700,5703,5705,5707,5709,5712,5715,5717],{"class":334,"line":5699},212,[332,5701,5702],{"class":369},"          \u003C",[332,5704,332],{"class":2479},[332,5706,5631],{"class":342},[332,5708,2489],{"class":369},[332,5710,5711],{"class":349},"\"mt-1 text-[30px]\"",[332,5713,5714],{"class":369},">📋\u003C\u002F",[332,5716,332],{"class":2479},[332,5718,2255],{"class":369},[332,5720,5722,5724,5726],{"class":334,"line":5721},213,[332,5723,5702],{"class":369},[332,5725,5628],{"class":2479},[332,5727,2255],{"class":369},[332,5729,5731,5734,5736,5738,5740,5743],{"class":334,"line":5730},214,[332,5732,5733],{"class":369},"            \u003C",[332,5735,10],{"class":2479},[332,5737,5631],{"class":342},[332,5739,2489],{"class":369},[332,5741,5742],{"class":349},"\"text-[28px] font-semibold tracking-tight text-neutral-900\"",[332,5744,2255],{"class":369},[332,5746,5748],{"class":334,"line":5747},215,[332,5749,5750],{"class":369},"              {{ PROJECT_NAME }} · Phase 1\n",[332,5752,5754,5757,5759],{"class":334,"line":5753},216,[332,5755,5756],{"class":369},"            \u003C\u002F",[332,5758,10],{"class":2479},[332,5760,2255],{"class":369},[332,5762,5764,5766,5768,5770,5772,5775],{"class":334,"line":5763},217,[332,5765,5733],{"class":369},[332,5767,14],{"class":2479},[332,5769,5631],{"class":342},[332,5771,2489],{"class":369},[332,5773,5774],{"class":349},"\"mt-1 text-[14px] text-neutral-500\"",[332,5776,2255],{"class":369},[332,5778,5780],{"class":334,"line":5779},218,[332,5781,5782],{"class":369},"              마지막 현행화 {{ LAST_UPDATED }}\n",[332,5784,5786,5788,5790],{"class":334,"line":5785},219,[332,5787,5756],{"class":369},[332,5789,14],{"class":2479},[332,5791,2255],{"class":369},[332,5793,5795,5798,5800],{"class":334,"line":5794},220,[332,5796,5797],{"class":369},"          \u003C\u002F",[332,5799,5628],{"class":2479},[332,5801,2255],{"class":369},[332,5803,5805,5808,5810],{"class":334,"line":5804},221,[332,5806,5807],{"class":369},"        \u003C\u002F",[332,5809,5628],{"class":2479},[332,5811,2255],{"class":369},[332,5813,5815,5818,5820],{"class":334,"line":5814},222,[332,5816,5817],{"class":369},"      \u003C\u002F",[332,5819,5670],{"class":2479},[332,5821,2255],{"class":369},[332,5823,5825],{"class":334,"line":5824},223,[332,5826,377],{"emptyLinePlaceholder":376},[332,5828,5830],{"class":334,"line":5829},224,[332,5831,5832],{"class":410},"      \u003C!-- LOADING \u002F ERROR -->\n",[332,5834,5836,5838,5840,5843,5845,5848,5850,5852,5855],{"class":334,"line":5835},225,[332,5837,5667],{"class":369},[332,5839,5628],{"class":2479},[332,5841,5842],{"class":342}," v-if",[332,5844,2489],{"class":369},[332,5846,5847],{"class":349},"\"pending\"",[332,5849,5631],{"class":342},[332,5851,2489],{"class":369},[332,5853,5854],{"class":349},"\"mt-8 rounded-xl border border-neutral-200 bg-white p-6 text-[14px] text-neutral-500\"",[332,5856,2255],{"class":369},[332,5858,5860],{"class":334,"line":5859},226,[332,5861,5862],{"class":369},"        로딩 중…\n",[332,5864,5866,5868,5870],{"class":334,"line":5865},227,[332,5867,5817],{"class":369},[332,5869,5628],{"class":2479},[332,5871,2255],{"class":369},[332,5873,5875,5877,5879,5882,5884,5887,5889,5891,5894],{"class":334,"line":5874},228,[332,5876,5667],{"class":369},[332,5878,5628],{"class":2479},[332,5880,5881],{"class":342}," v-else-if",[332,5883,2489],{"class":369},[332,5885,5886],{"class":349},"\"error\"",[332,5888,5631],{"class":342},[332,5890,2489],{"class":369},[332,5892,5893],{"class":349},"\"mt-8 rounded-xl border border-rose-200 bg-rose-50 p-6 text-[14px] text-rose-700\"",[332,5895,2255],{"class":369},[332,5897,5899],{"class":334,"line":5898},229,[332,5900,5901],{"class":369},"        로드 실패: {{ error.message }}\n",[332,5903,5905,5907,5909],{"class":334,"line":5904},230,[332,5906,5817],{"class":369},[332,5908,5628],{"class":2479},[332,5910,2255],{"class":369},[332,5912,5914],{"class":334,"line":5913},231,[332,5915,377],{"emptyLinePlaceholder":376},[332,5917,5919,5921,5923,5926],{"class":334,"line":5918},232,[332,5920,5667],{"class":369},[332,5922,5617],{"class":2479},[332,5924,5925],{"class":338}," v-else",[332,5927,2255],{"class":369},[332,5929,5931],{"class":334,"line":5930},233,[332,5932,5933],{"class":410},"        \u003C!-- HERO -->\n",[332,5935,5937,5939,5942,5944,5946,5949],{"class":334,"line":5936},234,[332,5938,5685],{"class":369},[332,5940,5941],{"class":2479},"section",[332,5943,5631],{"class":342},[332,5945,2489],{"class":369},[332,5947,5948],{"class":349},"\"mt-6 grid grid-cols-1 gap-3 sm:grid-cols-4\"",[332,5950,2255],{"class":369},[332,5952,5954,5956,5958,5960,5962,5965],{"class":334,"line":5953},235,[332,5955,5702],{"class":369},[332,5957,5628],{"class":2479},[332,5959,5631],{"class":342},[332,5961,2489],{"class":369},[332,5963,5964],{"class":349},"\"rounded-xl border border-neutral-200 bg-white p-5 sm:col-span-2\"",[332,5966,2255],{"class":369},[332,5968,5970,5972,5974,5976,5978,5981,5984,5986],{"class":334,"line":5969},236,[332,5971,5733],{"class":369},[332,5973,14],{"class":2479},[332,5975,5631],{"class":342},[332,5977,2489],{"class":369},[332,5979,5980],{"class":349},"\"text-[12px] text-neutral-500\"",[332,5982,5983],{"class":369},">전체 진행률\u003C\u002F",[332,5985,14],{"class":2479},[332,5987,2255],{"class":369},[332,5989,5991,5993,5995,5997,5999,6002],{"class":334,"line":5990},237,[332,5992,5733],{"class":369},[332,5994,14],{"class":2479},[332,5996,5631],{"class":342},[332,5998,2489],{"class":369},[332,6000,6001],{"class":349},"\"mt-1 text-[36px] font-semibold tracking-tight text-neutral-900 tabular-nums\"",[332,6003,2255],{"class":369},[332,6005,6007,6010,6012,6014,6016,6019,6022,6024],{"class":334,"line":6006},238,[332,6008,6009],{"class":369},"              {{ weightedAverage }}\u003C",[332,6011,332],{"class":2479},[332,6013,5631],{"class":342},[332,6015,2489],{"class":369},[332,6017,6018],{"class":349},"\"ml-0.5 text-[24px] text-neutral-400\"",[332,6020,6021],{"class":369},">%\u003C\u002F",[332,6023,332],{"class":2479},[332,6025,2255],{"class":369},[332,6027,6029,6031,6033],{"class":334,"line":6028},239,[332,6030,5756],{"class":369},[332,6032,14],{"class":2479},[332,6034,2255],{"class":369},[332,6036,6038,6040,6042,6044,6046,6049],{"class":334,"line":6037},240,[332,6039,5733],{"class":369},[332,6041,5628],{"class":2479},[332,6043,5631],{"class":342},[332,6045,2489],{"class":369},[332,6047,6048],{"class":349},"\"mt-4 h-1.5 overflow-hidden rounded-full bg-neutral-100\"",[332,6050,2255],{"class":369},[332,6052,6054,6057,6059,6061,6063,6066,6069,6071,6074,6077],{"class":334,"line":6053},241,[332,6055,6056],{"class":369},"              \u003C",[332,6058,5628],{"class":2479},[332,6060,5631],{"class":342},[332,6062,2489],{"class":369},[332,6064,6065],{"class":349},"\"h-full rounded-full bg-neutral-900 transition-all\"",[332,6067,6068],{"class":342}," :style",[332,6070,2489],{"class":369},[332,6072,6073],{"class":349},"\"{ width: weightedAverage + '%' }\"",[332,6075,5404],{"class":6076},"s7hpK",[332,6078,2255],{"class":369},[332,6080,6082,6084,6086],{"class":334,"line":6081},242,[332,6083,5756],{"class":369},[332,6085,5628],{"class":2479},[332,6087,2255],{"class":369},[332,6089,6091,6093,6095],{"class":334,"line":6090},243,[332,6092,5797],{"class":369},[332,6094,5628],{"class":2479},[332,6096,2255],{"class":369},[332,6098,6100,6102,6104,6106,6108,6111],{"class":334,"line":6099},244,[332,6101,5702],{"class":369},[332,6103,5628],{"class":2479},[332,6105,5631],{"class":342},[332,6107,2489],{"class":369},[332,6109,6110],{"class":349},"\"rounded-xl border border-neutral-200 bg-white p-5\"",[332,6112,2255],{"class":369},[332,6114,6116,6118,6120,6122,6124,6127],{"class":334,"line":6115},245,[332,6117,5733],{"class":369},[332,6119,5628],{"class":2479},[332,6121,5631],{"class":342},[332,6123,2489],{"class":369},[332,6125,6126],{"class":349},"\"flex items-center gap-1.5\"",[332,6128,2255],{"class":369},[332,6130,6132,6134,6136,6138,6140,6143,6145],{"class":334,"line":6131},246,[332,6133,6056],{"class":369},[332,6135,332],{"class":2479},[332,6137,5631],{"class":342},[332,6139,2489],{"class":369},[332,6141,6142],{"class":349},"\"inline-block size-1.5 rounded-full bg-emerald-500\"",[332,6144,5404],{"class":6076},[332,6146,2255],{"class":369},[332,6148,6150,6152,6154,6156,6158,6160,6163,6165],{"class":334,"line":6149},247,[332,6151,6056],{"class":369},[332,6153,14],{"class":2479},[332,6155,5631],{"class":342},[332,6157,2489],{"class":369},[332,6159,5980],{"class":349},[332,6161,6162],{"class":369},">완료\u003C\u002F",[332,6164,14],{"class":2479},[332,6166,2255],{"class":369},[332,6168,6170,6172,6174],{"class":334,"line":6169},248,[332,6171,5756],{"class":369},[332,6173,5628],{"class":2479},[332,6175,2255],{"class":369},[332,6177,6179,6181,6183,6185,6187,6190],{"class":334,"line":6178},249,[332,6180,5733],{"class":369},[332,6182,14],{"class":2479},[332,6184,5631],{"class":342},[332,6186,2489],{"class":369},[332,6188,6189],{"class":349},"\"mt-1 text-[30px] font-semibold text-neutral-900 tabular-nums\"",[332,6191,2255],{"class":369},[332,6193,6195,6198,6200,6202,6204,6207,6210,6212],{"class":334,"line":6194},250,[332,6196,6197],{"class":369},"              {{ totalCounts.done }}\u003C",[332,6199,332],{"class":2479},[332,6201,5631],{"class":342},[332,6203,2489],{"class":369},[332,6205,6206],{"class":349},"\"text-[16px] text-neutral-400\"",[332,6208,6209],{"class":369},">\u002F{{ allTasks.length }}\u003C\u002F",[332,6211,332],{"class":2479},[332,6213,2255],{"class":369},[332,6215,6217,6219,6221],{"class":334,"line":6216},251,[332,6218,5756],{"class":369},[332,6220,14],{"class":2479},[332,6222,2255],{"class":369},[332,6224,6226,6228,6230],{"class":334,"line":6225},252,[332,6227,5797],{"class":369},[332,6229,5628],{"class":2479},[332,6231,2255],{"class":369},[332,6233,6235,6237,6239,6241,6243,6245],{"class":334,"line":6234},253,[332,6236,5702],{"class":369},[332,6238,5628],{"class":2479},[332,6240,5631],{"class":342},[332,6242,2489],{"class":369},[332,6244,6110],{"class":349},[332,6246,2255],{"class":369},[332,6248,6250,6252,6254,6256,6258,6260],{"class":334,"line":6249},254,[332,6251,5733],{"class":369},[332,6253,5628],{"class":2479},[332,6255,5631],{"class":342},[332,6257,2489],{"class":369},[332,6259,6126],{"class":349},[332,6261,2255],{"class":369},[332,6263,6265,6267,6269,6271,6273,6276,6278],{"class":334,"line":6264},255,[332,6266,6056],{"class":369},[332,6268,332],{"class":2479},[332,6270,5631],{"class":342},[332,6272,2489],{"class":369},[332,6274,6275],{"class":349},"\"inline-block size-1.5 rounded-full bg-amber-500\"",[332,6277,5404],{"class":6076},[332,6279,2255],{"class":369},[332,6281,6283,6285,6287,6289,6291,6293,6296,6298],{"class":334,"line":6282},256,[332,6284,6056],{"class":369},[332,6286,14],{"class":2479},[332,6288,5631],{"class":342},[332,6290,2489],{"class":369},[332,6292,5980],{"class":349},[332,6294,6295],{"class":369},">진행 중\u003C\u002F",[332,6297,14],{"class":2479},[332,6299,2255],{"class":369},[332,6301,6303,6305,6307],{"class":334,"line":6302},257,[332,6304,5756],{"class":369},[332,6306,5628],{"class":2479},[332,6308,2255],{"class":369},[332,6310,6312,6314,6316,6318,6320,6322],{"class":334,"line":6311},258,[332,6313,5733],{"class":369},[332,6315,14],{"class":2479},[332,6317,5631],{"class":342},[332,6319,2489],{"class":369},[332,6321,6189],{"class":349},[332,6323,2255],{"class":369},[332,6325,6327],{"class":334,"line":6326},259,[332,6328,6329],{"class":369},"              {{ totalCounts.in_progress }}\n",[332,6331,6333,6335,6337],{"class":334,"line":6332},260,[332,6334,5756],{"class":369},[332,6336,14],{"class":2479},[332,6338,2255],{"class":369},[332,6340,6342,6344,6346],{"class":334,"line":6341},261,[332,6343,5797],{"class":369},[332,6345,5628],{"class":2479},[332,6347,2255],{"class":369},[332,6349,6351,6353,6355],{"class":334,"line":6350},262,[332,6352,5807],{"class":369},[332,6354,5941],{"class":2479},[332,6356,2255],{"class":369},[332,6358,6360],{"class":334,"line":6359},263,[332,6361,377],{"emptyLinePlaceholder":376},[332,6363,6365],{"class":334,"line":6364},264,[332,6366,6367],{"class":410},"        \u003C!-- STAGES OVERVIEW -->\n",[332,6369,6371,6373,6375,6377,6379,6382],{"class":334,"line":6370},265,[332,6372,5685],{"class":369},[332,6374,5941],{"class":2479},[332,6376,5631],{"class":342},[332,6378,2489],{"class":369},[332,6380,6381],{"class":349},"\"mt-8\"",[332,6383,2255],{"class":369},[332,6385,6387,6389,6391,6393,6395,6398,6401,6403],{"class":334,"line":6386},266,[332,6388,5702],{"class":369},[332,6390,55],{"class":2479},[332,6392,5631],{"class":342},[332,6394,2489],{"class":369},[332,6396,6397],{"class":349},"\"mb-2 text-[14px] font-semibold text-neutral-700\"",[332,6399,6400],{"class":369},">단계별 진행률\u003C\u002F",[332,6402,55],{"class":2479},[332,6404,2255],{"class":369},[332,6406,6408,6410,6412,6414,6416,6419],{"class":334,"line":6407},267,[332,6409,5702],{"class":369},[332,6411,63],{"class":2479},[332,6413,5631],{"class":342},[332,6415,2489],{"class":369},[332,6417,6418],{"class":349},"\"overflow-hidden rounded-xl border border-neutral-200 bg-white\"",[332,6420,2255],{"class":369},[332,6422,6424,6426],{"class":334,"line":6423},268,[332,6425,5733],{"class":369},[332,6427,6428],{"class":2479},"li\n",[332,6430,6432,6435,6437,6440,6443,6445],{"class":334,"line":6431},269,[332,6433,6434],{"class":342},"              v-for",[332,6436,2489],{"class":369},[332,6438,6439],{"class":349},"\"(s, i) in mergedStages\"",[332,6441,6442],{"class":342}," :key",[332,6444,2489],{"class":369},[332,6446,6447],{"class":349},"\"s.id\"\n",[332,6449,6451,6454,6456],{"class":334,"line":6450},270,[332,6452,6453],{"class":342},"              class",[332,6455,2489],{"class":369},[332,6457,6458],{"class":349},"\"grid cursor-pointer grid-cols-[24px_24px_1fr_auto_140px_auto] items-center gap-4 px-4 py-3 hover:bg-neutral-50\"\n",[332,6460,6462,6465,6467],{"class":334,"line":6461},271,[332,6463,6464],{"class":342},"              :class",[332,6466,2489],{"class":369},[332,6468,6469],{"class":349},"\"i > 0 ? 'border-t border-neutral-100' : ''\"\n",[332,6471,6473,6476,6478],{"class":334,"line":6472},272,[332,6474,6475],{"class":342},"              @click",[332,6477,2489],{"class":369},[332,6479,6480],{"class":349},"\"scrollToStage(s.id)\"\n",[332,6482,6484],{"class":334,"line":6483},273,[332,6485,6486],{"class":369},"            >\n",[332,6488,6490,6492,6494,6496,6498,6501,6504,6506],{"class":334,"line":6489},274,[332,6491,6056],{"class":369},[332,6493,332],{"class":2479},[332,6495,5631],{"class":342},[332,6497,2489],{"class":369},[332,6499,6500],{"class":349},"\"text-[18px] leading-none\"",[332,6502,6503],{"class":369},">{{ stageEmoji[i] }}\u003C\u002F",[332,6505,332],{"class":2479},[332,6507,2255],{"class":369},[332,6509,6511,6513,6515,6517,6519,6522,6525,6527],{"class":334,"line":6510},275,[332,6512,6056],{"class":369},[332,6514,332],{"class":2479},[332,6516,5631],{"class":342},[332,6518,2489],{"class":369},[332,6520,6521],{"class":349},"\"font-mono text-[14px] tabular-nums text-neutral-400\"",[332,6523,6524],{"class":369},">{{ String(i + 1).padStart(2, \"0\") }}\u003C\u002F",[332,6526,332],{"class":2479},[332,6528,2255],{"class":369},[332,6530,6532,6534,6536,6538,6540,6543],{"class":334,"line":6531},276,[332,6533,6056],{"class":369},[332,6535,5628],{"class":2479},[332,6537,5631],{"class":342},[332,6539,2489],{"class":369},[332,6541,6542],{"class":349},"\"min-w-0\"",[332,6544,2255],{"class":369},[332,6546,6548,6551,6553,6555,6557,6560,6563,6565],{"class":334,"line":6547},277,[332,6549,6550],{"class":369},"                \u003C",[332,6552,14],{"class":2479},[332,6554,5631],{"class":342},[332,6556,2489],{"class":369},[332,6558,6559],{"class":349},"\"truncate text-[14px] font-medium text-neutral-900\"",[332,6561,6562],{"class":369},">{{ s.name }}\u003C\u002F",[332,6564,14],{"class":2479},[332,6566,2255],{"class":369},[332,6568,6570,6572,6574,6576,6578,6581,6584,6586],{"class":334,"line":6569},278,[332,6571,6550],{"class":369},[332,6573,14],{"class":2479},[332,6575,5631],{"class":342},[332,6577,2489],{"class":369},[332,6579,6580],{"class":349},"\"truncate text-[14px] text-neutral-500\"",[332,6582,6583],{"class":369},">{{ s.summary }}\u003C\u002F",[332,6585,14],{"class":2479},[332,6587,2255],{"class":369},[332,6589,6591,6594,6596],{"class":334,"line":6590},279,[332,6592,6593],{"class":369},"              \u003C\u002F",[332,6595,5628],{"class":2479},[332,6597,2255],{"class":369},[332,6599,6601,6603,6605,6607,6609,6612,6615,6617],{"class":334,"line":6600},280,[332,6602,6056],{"class":369},[332,6604,332],{"class":2479},[332,6606,5631],{"class":342},[332,6608,2489],{"class":369},[332,6610,6611],{"class":349},"\"text-[14px] text-neutral-400\"",[332,6613,6614],{"class":369},">{{ s.tasks.length }}건\u003C\u002F",[332,6616,332],{"class":2479},[332,6618,2255],{"class":369},[332,6620,6622,6624,6626,6628,6630,6633],{"class":334,"line":6621},281,[332,6623,6056],{"class":369},[332,6625,5628],{"class":2479},[332,6627,5631],{"class":342},[332,6629,2489],{"class":369},[332,6631,6632],{"class":349},"\"flex items-center gap-2.5\"",[332,6634,2255],{"class":369},[332,6636,6638,6640,6642,6644,6646,6649],{"class":334,"line":6637},282,[332,6639,6550],{"class":369},[332,6641,5628],{"class":2479},[332,6643,5631],{"class":342},[332,6645,2489],{"class":369},[332,6647,6648],{"class":349},"\"h-1 w-24 overflow-hidden rounded-full bg-neutral-100\"",[332,6650,2255],{"class":369},[332,6652,6654,6657,6659,6662,6664,6667,6669,6671,6674,6676],{"class":334,"line":6653},283,[332,6655,6656],{"class":369},"                  \u003C",[332,6658,5628],{"class":2479},[332,6660,6661],{"class":342}," :class",[332,6663,2489],{"class":369},[332,6665,6666],{"class":349},"\"['h-full rounded-full', progressFill(s.progress)]\"",[332,6668,6068],{"class":342},[332,6670,2489],{"class":369},[332,6672,6673],{"class":349},"\"{ width: s.progress + '%' }\"",[332,6675,5404],{"class":6076},[332,6677,2255],{"class":369},[332,6679,6681,6684,6686],{"class":334,"line":6680},284,[332,6682,6683],{"class":369},"                \u003C\u002F",[332,6685,5628],{"class":2479},[332,6687,2255],{"class":369},[332,6689,6691,6693,6695,6697,6699,6702,6705,6707],{"class":334,"line":6690},285,[332,6692,6550],{"class":369},[332,6694,332],{"class":2479},[332,6696,5631],{"class":342},[332,6698,2489],{"class":369},[332,6700,6701],{"class":349},"\"w-9 text-right text-[14px] font-medium tabular-nums text-neutral-700\"",[332,6703,6704],{"class":369},">{{ s.progress }}%\u003C\u002F",[332,6706,332],{"class":2479},[332,6708,2255],{"class":369},[332,6710,6712,6714,6716],{"class":334,"line":6711},286,[332,6713,6593],{"class":369},[332,6715,5628],{"class":2479},[332,6717,2255],{"class":369},[332,6719,6721,6723,6725,6727,6729,6732,6735,6737],{"class":334,"line":6720},287,[332,6722,6056],{"class":369},[332,6724,332],{"class":2479},[332,6726,5631],{"class":342},[332,6728,2489],{"class":369},[332,6730,6731],{"class":349},"\"text-neutral-300\"",[332,6733,6734],{"class":369},">→\u003C\u002F",[332,6736,332],{"class":2479},[332,6738,2255],{"class":369},[332,6740,6742,6744,6746],{"class":334,"line":6741},288,[332,6743,5756],{"class":369},[332,6745,66],{"class":2479},[332,6747,2255],{"class":369},[332,6749,6751,6753,6755],{"class":334,"line":6750},289,[332,6752,5797],{"class":369},[332,6754,63],{"class":2479},[332,6756,2255],{"class":369},[332,6758,6760,6762,6764],{"class":334,"line":6759},290,[332,6761,5807],{"class":369},[332,6763,5941],{"class":2479},[332,6765,2255],{"class":369},[332,6767,6769],{"class":334,"line":6768},291,[332,6770,377],{"emptyLinePlaceholder":376},[332,6772,6774],{"class":334,"line":6773},292,[332,6775,6776],{"class":410},"        \u003C!-- STAGE DETAILS -->\n",[332,6778,6780,6782,6784,6787,6789,6792,6794,6796,6799,6802,6804,6807,6809,6811,6814],{"class":334,"line":6779},293,[332,6781,5685],{"class":369},[332,6783,5941],{"class":2479},[332,6785,6786],{"class":342}," v-for",[332,6788,2489],{"class":369},[332,6790,6791],{"class":349},"\"(s, sIdx) in mergedStages\"",[332,6793,6442],{"class":342},[332,6795,2489],{"class":369},[332,6797,6798],{"class":349},"\"s.id\"",[332,6800,6801],{"class":342}," :id",[332,6803,2489],{"class":369},[332,6805,6806],{"class":349},"\"`stage-${s.id}`\"",[332,6808,5631],{"class":342},[332,6810,2489],{"class":369},[332,6812,6813],{"class":349},"\"mt-10\"",[332,6815,2255],{"class":369},[332,6817,6819,6821,6823,6825,6827,6830],{"class":334,"line":6818},294,[332,6820,5702],{"class":369},[332,6822,5628],{"class":2479},[332,6824,5631],{"class":342},[332,6826,2489],{"class":369},[332,6828,6829],{"class":349},"\"flex items-baseline justify-between gap-3\"",[332,6831,2255],{"class":369},[332,6833,6835,6837,6839,6841,6843,6846],{"class":334,"line":6834},295,[332,6836,5733],{"class":369},[332,6838,5628],{"class":2479},[332,6840,5631],{"class":342},[332,6842,2489],{"class":369},[332,6844,6845],{"class":349},"\"flex items-baseline gap-2.5\"",[332,6847,2255],{"class":369},[332,6849,6851,6853,6855,6857,6859,6862,6865,6867],{"class":334,"line":6850},296,[332,6852,6056],{"class":369},[332,6854,332],{"class":2479},[332,6856,5631],{"class":342},[332,6858,2489],{"class":369},[332,6860,6861],{"class":349},"\"text-[20px] leading-none\"",[332,6863,6864],{"class":369},">{{ stageEmoji[sIdx] }}\u003C\u002F",[332,6866,332],{"class":2479},[332,6868,2255],{"class":369},[332,6870,6872,6874,6876,6878,6880,6883,6885,6887],{"class":334,"line":6871},297,[332,6873,6056],{"class":369},[332,6875,55],{"class":2479},[332,6877,5631],{"class":342},[332,6879,2489],{"class":369},[332,6881,6882],{"class":349},"\"text-[18px] font-semibold tracking-tight text-neutral-900\"",[332,6884,6562],{"class":369},[332,6886,55],{"class":2479},[332,6888,2255],{"class":369},[332,6890,6892,6894,6896,6898,6900,6903,6906,6908],{"class":334,"line":6891},298,[332,6893,6056],{"class":369},[332,6895,332],{"class":2479},[332,6897,5631],{"class":342},[332,6899,2489],{"class":369},[332,6901,6902],{"class":349},"\"font-mono text-[14px] text-neutral-400\"",[332,6904,6905],{"class":369},">{{ s.id }}\u003C\u002F",[332,6907,332],{"class":2479},[332,6909,2255],{"class":369},[332,6911,6913,6915,6917],{"class":334,"line":6912},299,[332,6914,5756],{"class":369},[332,6916,5628],{"class":2479},[332,6918,2255],{"class":369},[332,6920,6922,6924,6926,6928,6930,6933],{"class":334,"line":6921},300,[332,6923,5733],{"class":369},[332,6925,5628],{"class":2479},[332,6927,5631],{"class":342},[332,6929,2489],{"class":369},[332,6931,6932],{"class":349},"\"flex items-center gap-3 text-[14px] text-neutral-500\"",[332,6934,2255],{"class":369},[332,6936,6938,6940,6942,6945,6947],{"class":334,"line":6937},301,[332,6939,6056],{"class":369},[332,6941,332],{"class":2479},[332,6943,6944],{"class":369},">비중 {{ s.weight }}%\u003C\u002F",[332,6946,332],{"class":2479},[332,6948,2255],{"class":369},[332,6950,6952,6954,6956,6958,6960,6963,6966,6968],{"class":334,"line":6951},302,[332,6953,6056],{"class":369},[332,6955,332],{"class":2479},[332,6957,5631],{"class":342},[332,6959,2489],{"class":369},[332,6961,6962],{"class":349},"\"text-neutral-200\"",[332,6964,6965],{"class":369},">·\u003C\u002F",[332,6967,332],{"class":2479},[332,6969,2255],{"class":369},[332,6971,6973,6975,6977,6979,6981,6984,6987,6989],{"class":334,"line":6972},303,[332,6974,6056],{"class":369},[332,6976,332],{"class":2479},[332,6978,5631],{"class":342},[332,6980,2489],{"class":369},[332,6982,6983],{"class":349},"\"font-medium text-neutral-700\"",[332,6985,6986],{"class":369},">진행 {{ s.progress }}%\u003C\u002F",[332,6988,332],{"class":2479},[332,6990,2255],{"class":369},[332,6992,6994,6996,6998],{"class":334,"line":6993},304,[332,6995,5756],{"class":369},[332,6997,5628],{"class":2479},[332,6999,2255],{"class":369},[332,7001,7003,7005,7007],{"class":334,"line":7002},305,[332,7004,5797],{"class":369},[332,7006,5628],{"class":2479},[332,7008,2255],{"class":369},[332,7010,7012,7014,7016,7018,7020,7022,7024,7026],{"class":334,"line":7011},306,[332,7013,5702],{"class":369},[332,7015,14],{"class":2479},[332,7017,5631],{"class":342},[332,7019,2489],{"class":369},[332,7021,5774],{"class":349},[332,7023,6583],{"class":369},[332,7025,14],{"class":2479},[332,7027,2255],{"class":369},[332,7029,7031,7033,7035,7037,7039,7042],{"class":334,"line":7030},307,[332,7032,5702],{"class":369},[332,7034,5628],{"class":2479},[332,7036,5631],{"class":342},[332,7038,2489],{"class":369},[332,7040,7041],{"class":349},"\"mt-3 h-1 overflow-hidden rounded-full bg-neutral-100\"",[332,7043,2255],{"class":369},[332,7045,7047,7049,7051,7053,7055,7057,7059,7061,7063,7065],{"class":334,"line":7046},308,[332,7048,5733],{"class":369},[332,7050,5628],{"class":2479},[332,7052,6661],{"class":342},[332,7054,2489],{"class":369},[332,7056,6666],{"class":349},[332,7058,6068],{"class":342},[332,7060,2489],{"class":369},[332,7062,6673],{"class":349},[332,7064,5404],{"class":6076},[332,7066,2255],{"class":369},[332,7068,7070,7072,7074],{"class":334,"line":7069},309,[332,7071,5797],{"class":369},[332,7073,5628],{"class":2479},[332,7075,2255],{"class":369},[332,7077,7079],{"class":334,"line":7078},310,[332,7080,377],{"emptyLinePlaceholder":376},[332,7082,7084,7086,7088,7090,7092,7095],{"class":334,"line":7083},311,[332,7085,5702],{"class":369},[332,7087,5628],{"class":2479},[332,7089,5631],{"class":342},[332,7091,2489],{"class":369},[332,7093,7094],{"class":349},"\"mt-4 overflow-hidden rounded-xl border border-neutral-200 bg-white\"",[332,7096,2255],{"class":369},[332,7098,7100,7102,7104,7106,7108,7111],{"class":334,"line":7099},312,[332,7101,5733],{"class":369},[332,7103,114],{"class":2479},[332,7105,5631],{"class":342},[332,7107,2489],{"class":369},[332,7109,7110],{"class":349},"\"w-full text-[14px]\"",[332,7112,2255],{"class":369},[332,7114,7116,7118,7120],{"class":334,"line":7115},313,[332,7117,6056],{"class":369},[332,7119,117],{"class":2479},[332,7121,2255],{"class":369},[332,7123,7125,7127,7129,7131,7133,7136],{"class":334,"line":7124},314,[332,7126,6550],{"class":369},[332,7128,120],{"class":2479},[332,7130,5631],{"class":342},[332,7132,2489],{"class":369},[332,7134,7135],{"class":349},"\"border-b border-neutral-100 text-[14px] font-medium text-neutral-500\"",[332,7137,2255],{"class":369},[332,7139,7141,7143,7145,7147,7149,7152,7155,7157],{"class":334,"line":7140},315,[332,7142,6656],{"class":369},[332,7144,123],{"class":2479},[332,7146,5631],{"class":342},[332,7148,2489],{"class":369},[332,7150,7151],{"class":349},"\"w-20 px-3 py-2 text-left\"",[332,7153,7154],{"class":369},">ID\u003C\u002F",[332,7156,123],{"class":2479},[332,7158,2255],{"class":369},[332,7160,7162,7164,7166,7168,7170,7173,7176,7178],{"class":334,"line":7161},316,[332,7163,6656],{"class":369},[332,7165,123],{"class":2479},[332,7167,5631],{"class":342},[332,7169,2489],{"class":369},[332,7171,7172],{"class":349},"\"px-3 py-2 text-left\"",[332,7174,7175],{"class":369},">작업 · 산출물\u003C\u002F",[332,7177,123],{"class":2479},[332,7179,2255],{"class":369},[332,7181,7183,7185,7187,7189,7191,7194,7197,7199],{"class":334,"line":7182},317,[332,7184,6656],{"class":369},[332,7186,123],{"class":2479},[332,7188,5631],{"class":342},[332,7190,2489],{"class":369},[332,7192,7193],{"class":349},"\"w-36 px-3 py-2 text-left\"",[332,7195,7196],{"class":369},">목표일\u003C\u002F",[332,7198,123],{"class":2479},[332,7200,2255],{"class":369},[332,7202,7204,7206,7208,7210,7212,7214,7217,7219],{"class":334,"line":7203},318,[332,7205,6656],{"class":369},[332,7207,123],{"class":2479},[332,7209,5631],{"class":342},[332,7211,2489],{"class":369},[332,7213,7193],{"class":349},[332,7215,7216],{"class":369},">완료일\u003C\u002F",[332,7218,123],{"class":2479},[332,7220,2255],{"class":369},[332,7222,7224,7226,7228,7230,7232,7235,7238,7240],{"class":334,"line":7223},319,[332,7225,6656],{"class":369},[332,7227,123],{"class":2479},[332,7229,5631],{"class":342},[332,7231,2489],{"class":369},[332,7233,7234],{"class":349},"\"w-28 px-3 py-2 text-left\"",[332,7236,7237],{"class":369},">상태\u003C\u002F",[332,7239,123],{"class":2479},[332,7241,2255],{"class":369},[332,7243,7245,7247,7249],{"class":334,"line":7244},320,[332,7246,6683],{"class":369},[332,7248,120],{"class":2479},[332,7250,2255],{"class":369},[332,7252,7254,7256,7258],{"class":334,"line":7253},321,[332,7255,6593],{"class":369},[332,7257,117],{"class":2479},[332,7259,2255],{"class":369},[332,7261,7263,7265,7267],{"class":334,"line":7262},322,[332,7264,6056],{"class":369},[332,7266,130],{"class":2479},[332,7268,2255],{"class":369},[332,7270,7272,7274],{"class":334,"line":7271},323,[332,7273,6550],{"class":369},[332,7275,7276],{"class":2479},"tr\n",[332,7278,7280,7283,7285,7288,7290,7292],{"class":334,"line":7279},324,[332,7281,7282],{"class":342},"                  v-for",[332,7284,2489],{"class":369},[332,7286,7287],{"class":349},"\"(t, ti) in s.tasks\"",[332,7289,6442],{"class":342},[332,7291,2489],{"class":369},[332,7293,7294],{"class":349},"\"t.id\"\n",[332,7296,7298,7301,7303],{"class":334,"line":7297},325,[332,7299,7300],{"class":342},"                  class",[332,7302,2489],{"class":369},[332,7304,7305],{"class":349},"\"align-top hover:bg-neutral-50\u002F60\"\n",[332,7307,7309,7312,7314],{"class":334,"line":7308},326,[332,7310,7311],{"class":342},"                  :class",[332,7313,2489],{"class":369},[332,7315,7316],{"class":349},"\"ti > 0 ? 'border-t border-neutral-100' : ''\"\n",[332,7318,7320],{"class":334,"line":7319},327,[332,7321,7322],{"class":369},"                >\n",[332,7324,7326,7328,7330,7332,7334,7337,7340,7342],{"class":334,"line":7325},328,[332,7327,6656],{"class":369},[332,7329,135],{"class":2479},[332,7331,5631],{"class":342},[332,7333,2489],{"class":369},[332,7335,7336],{"class":349},"\"px-3 py-3 font-mono text-[14px] tabular-nums text-neutral-400\"",[332,7338,7339],{"class":369},">{{ s.id }}-{{ t.taskNo }}\u003C\u002F",[332,7341,135],{"class":2479},[332,7343,2255],{"class":369},[332,7345,7347,7349,7351,7353,7355,7358],{"class":334,"line":7346},329,[332,7348,6656],{"class":369},[332,7350,135],{"class":2479},[332,7352,5631],{"class":342},[332,7354,2489],{"class":369},[332,7356,7357],{"class":349},"\"px-3 py-3\"",[332,7359,2255],{"class":369},[332,7361,7363,7366,7368,7370,7372,7375,7378,7380],{"class":334,"line":7362},330,[332,7364,7365],{"class":369},"                    \u003C",[332,7367,14],{"class":2479},[332,7369,5631],{"class":342},[332,7371,2489],{"class":369},[332,7373,7374],{"class":349},"\"text-[13.5px] font-medium text-neutral-900\"",[332,7376,7377],{"class":369},">{{ t.title }}\u003C\u002F",[332,7379,14],{"class":2479},[332,7381,2255],{"class":369},[332,7383,7385,7387,7389,7391,7393,7396,7398,7400,7403,7406,7408],{"class":334,"line":7384},331,[332,7386,7365],{"class":369},[332,7388,14],{"class":2479},[332,7390,5842],{"class":342},[332,7392,2489],{"class":369},[332,7394,7395],{"class":349},"\"t.note\"",[332,7397,5631],{"class":342},[332,7399,2489],{"class":369},[332,7401,7402],{"class":349},"\"mt-0.5 text-[14px] leading-relaxed text-neutral-500\"",[332,7404,7405],{"class":369},">{{ t.note }}\u003C\u002F",[332,7407,14],{"class":2479},[332,7409,2255],{"class":369},[332,7411,7413,7415,7417,7419,7421,7424],{"class":334,"line":7412},332,[332,7414,7365],{"class":369},[332,7416,5628],{"class":2479},[332,7418,5631],{"class":342},[332,7420,2489],{"class":369},[332,7422,7423],{"class":349},"\"mt-2 flex items-center gap-2\"",[332,7425,2255],{"class":369},[332,7427,7429,7432,7434,7436,7438,7440,7443,7445],{"class":334,"line":7428},333,[332,7430,7431],{"class":369},"                      \u003C",[332,7433,332],{"class":2479},[332,7435,5631],{"class":342},[332,7437,2489],{"class":369},[332,7439,6611],{"class":349},[332,7441,7442],{"class":369},">🔗\u003C\u002F",[332,7444,332],{"class":2479},[332,7446,2255],{"class":369},[332,7448,7450,7452],{"class":334,"line":7449},334,[332,7451,7431],{"class":369},[332,7453,7454],{"class":2479},"input\n",[332,7456,7458,7461,7463,7466,7469,7471,7474,7477,7479],{"class":334,"line":7457},335,[332,7459,7460],{"class":342},"                        :value",[332,7462,2489],{"class":369},[332,7464,7465],{"class":349},"\"t.deliverableUrl ?? ''\"",[332,7467,7468],{"class":342}," type",[332,7470,2489],{"class":369},[332,7472,7473],{"class":349},"\"url\"",[332,7475,7476],{"class":342}," placeholder",[332,7478,2489],{"class":369},[332,7480,7481],{"class":349},"\"산출물 URL 입력\"\n",[332,7483,7485,7488,7490],{"class":334,"line":7484},336,[332,7486,7487],{"class":342},"                        class",[332,7489,2489],{"class":369},[332,7491,7492],{"class":349},"\"min-w-0 flex-1 rounded-md border border-transparent bg-transparent px-1.5 py-1 font-mono text-[13px] text-neutral-700 placeholder:text-neutral-400 hover:border-neutral-200 focus:border-neutral-300 focus:bg-white focus:outline-none focus:ring-1 focus:ring-neutral-200\"\n",[332,7494,7496,7499,7501],{"class":334,"line":7495},337,[332,7497,7498],{"class":342},"                        @change",[332,7500,2489],{"class":369},[332,7502,7503],{"class":349},"\"(e) => setOverride(t.id, { deliverableUrl: (e.target as HTMLInputElement).value || null })\"\n",[332,7505,7507],{"class":334,"line":7506},338,[332,7508,7509],{"class":369},"                      \u002F>\n",[332,7511,7513,7515,7517,7519,7521,7524,7527,7529,7531,7534,7536,7539,7542,7544],{"class":334,"line":7512},339,[332,7514,7431],{"class":369},[332,7516,42],{"class":2479},[332,7518,5842],{"class":342},[332,7520,2489],{"class":369},[332,7522,7523],{"class":349},"\"t.deliverableUrl\"",[332,7525,7526],{"class":342}," :href",[332,7528,2489],{"class":369},[332,7530,7523],{"class":349},[332,7532,7533],{"class":342}," target",[332,7535,2489],{"class":369},[332,7537,7538],{"class":349},"\"_blank\"",[332,7540,7541],{"class":342}," rel",[332,7543,2489],{"class":369},[332,7545,7546],{"class":349},"\"noopener\"\n",[332,7548,7550,7553,7555,7558],{"class":334,"line":7549},340,[332,7551,7552],{"class":342},"                         class",[332,7554,2489],{"class":369},[332,7556,7557],{"class":349},"\"shrink-0 rounded-md px-1.5 py-1 text-[14px] text-neutral-500 hover:bg-neutral-100 hover:text-neutral-900\"",[332,7559,2255],{"class":369},[332,7561,7563],{"class":334,"line":7562},341,[332,7564,7565],{"class":369},"                        열기 ↗\n",[332,7567,7569,7572,7574],{"class":334,"line":7568},342,[332,7570,7571],{"class":369},"                      \u003C\u002F",[332,7573,42],{"class":2479},[332,7575,2255],{"class":369},[332,7577,7579,7582,7584],{"class":334,"line":7578},343,[332,7580,7581],{"class":369},"                    \u003C\u002F",[332,7583,5628],{"class":2479},[332,7585,2255],{"class":369},[332,7587,7589,7592,7594],{"class":334,"line":7588},344,[332,7590,7591],{"class":369},"                  \u003C\u002F",[332,7593,135],{"class":2479},[332,7595,2255],{"class":369},[332,7597,7599,7601,7603,7605,7607,7610],{"class":334,"line":7598},345,[332,7600,6656],{"class":369},[332,7602,135],{"class":2479},[332,7604,5631],{"class":342},[332,7606,2489],{"class":369},[332,7608,7609],{"class":349},"\"whitespace-nowrap px-2 py-3\"",[332,7611,2255],{"class":369},[332,7613,7615,7617],{"class":334,"line":7614},346,[332,7616,7365],{"class":369},[332,7618,7454],{"class":2479},[332,7620,7622,7625,7627,7630,7633,7635],{"class":334,"line":7621},347,[332,7623,7624],{"class":342},"                      type",[332,7626,2489],{"class":369},[332,7628,7629],{"class":349},"\"date\"",[332,7631,7632],{"class":342}," :value",[332,7634,2489],{"class":369},[332,7636,7637],{"class":349},"\"t.targetDate ?? ''\"\n",[332,7639,7641,7644,7646],{"class":334,"line":7640},348,[332,7642,7643],{"class":342},"                      :class",[332,7645,2489],{"class":369},[332,7647,7648],{"class":349},"\"['w-full rounded-md border border-transparent bg-transparent px-1.5 py-1 font-mono text-[12px] tabular-nums hover:border-neutral-200 focus:border-neutral-300 focus:bg-white focus:outline-none focus:ring-1 focus:ring-neutral-200',\n",[332,7650,7652],{"class":334,"line":7651},349,[332,7653,7654],{"class":349},"                               isOverdue(t) ? 'font-semibold text-rose-600' : 'text-neutral-600']\"\n",[332,7656,7658,7661,7663],{"class":334,"line":7657},350,[332,7659,7660],{"class":342},"                      @change",[332,7662,2489],{"class":369},[332,7664,7665],{"class":349},"\"(e) => setOverride(t.id, { targetDate: (e.target as HTMLInputElement).value || null })\"\n",[332,7667,7669],{"class":334,"line":7668},351,[332,7670,7671],{"class":369},"                    \u002F>\n",[332,7673,7675,7677,7679],{"class":334,"line":7674},352,[332,7676,7591],{"class":369},[332,7678,135],{"class":2479},[332,7680,2255],{"class":369},[332,7682,7684,7686,7688,7690,7692,7694],{"class":334,"line":7683},353,[332,7685,6656],{"class":369},[332,7687,135],{"class":2479},[332,7689,5631],{"class":342},[332,7691,2489],{"class":369},[332,7693,7609],{"class":349},[332,7695,2255],{"class":369},[332,7697,7699,7701],{"class":334,"line":7698},354,[332,7700,7365],{"class":369},[332,7702,7454],{"class":2479},[332,7704,7706,7708,7710,7712,7714,7716],{"class":334,"line":7705},355,[332,7707,7624],{"class":342},[332,7709,2489],{"class":369},[332,7711,7629],{"class":349},[332,7713,7632],{"class":342},[332,7715,2489],{"class":369},[332,7717,7718],{"class":349},"\"t.completionDate ?? ''\"\n",[332,7720,7722,7725,7727],{"class":334,"line":7721},356,[332,7723,7724],{"class":342},"                      class",[332,7726,2489],{"class":369},[332,7728,7729],{"class":349},"\"w-full rounded-md border border-transparent bg-transparent px-1.5 py-1 font-mono text-[12px] tabular-nums text-emerald-700 hover:border-neutral-200 focus:border-neutral-300 focus:bg-white focus:outline-none focus:ring-1 focus:ring-neutral-200\"\n",[332,7731,7733,7735,7737],{"class":334,"line":7732},357,[332,7734,7660],{"class":342},[332,7736,2489],{"class":369},[332,7738,7739],{"class":349},"\"(e) => setOverride(t.id, { completionDate: (e.target as HTMLInputElement).value || null })\"\n",[332,7741,7743],{"class":334,"line":7742},358,[332,7744,7671],{"class":369},[332,7746,7748,7750,7752],{"class":334,"line":7747},359,[332,7749,7591],{"class":369},[332,7751,135],{"class":2479},[332,7753,2255],{"class":369},[332,7755,7757,7759,7761,7763,7765,7768],{"class":334,"line":7756},360,[332,7758,6656],{"class":369},[332,7760,135],{"class":2479},[332,7762,5631],{"class":342},[332,7764,2489],{"class":369},[332,7766,7767],{"class":349},"\"whitespace-nowrap px-3 py-3\"",[332,7769,2255],{"class":369},[332,7771,7773,7775,7777,7779,7781],{"class":334,"line":7772},361,[332,7774,7365],{"class":369},[332,7776,4692],{"class":2479},[332,7778,6661],{"class":342},[332,7780,2489],{"class":369},[332,7782,7783],{"class":349},"\"['relative inline-flex cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-md border px-2 py-0.5 text-[13px] font-medium hover:brightness-95',\n",[332,7785,7787,7790],{"class":334,"line":7786},362,[332,7788,7789],{"class":349},"                                    statusMeta[t.status].chipCls]\"",[332,7791,2255],{"class":369},[332,7793,7795,7797,7799,7801,7803,7806,7809,7811],{"class":334,"line":7794},363,[332,7796,7431],{"class":369},[332,7798,332],{"class":2479},[332,7800,5631],{"class":342},[332,7802,2489],{"class":369},[332,7804,7805],{"class":349},"\"text-[13px]\"",[332,7807,7808],{"class":369},">{{ statusMeta[t.status].emoji }}\u003C\u002F",[332,7810,332],{"class":2479},[332,7812,2255],{"class":369},[332,7814,7816],{"class":334,"line":7815},364,[332,7817,7818],{"class":369},"                      {{ statusMeta[t.status].label }}\n",[332,7820,7822,7824],{"class":334,"line":7821},365,[332,7823,7431],{"class":369},[332,7825,7826],{"class":2479},"select\n",[332,7828,7830,7832,7834,7837,7839,7841],{"class":334,"line":7829},366,[332,7831,7460],{"class":342},[332,7833,2489],{"class":369},[332,7835,7836],{"class":349},"\"t.status\"",[332,7838,5631],{"class":342},[332,7840,2489],{"class":369},[332,7842,7843],{"class":349},"\"absolute inset-0 cursor-pointer opacity-0\"\n",[332,7845,7847,7849,7851],{"class":334,"line":7846},367,[332,7848,7498],{"class":342},[332,7850,2489],{"class":369},[332,7852,7853],{"class":349},"\"(e) => setOverride(t.id, { status: (e.target as HTMLSelectElement).value as Status })\"\n",[332,7855,7857],{"class":334,"line":7856},368,[332,7858,7859],{"class":369},"                      >\n",[332,7861,7863,7866,7869,7871,7873,7876,7878,7880,7883,7885,7887,7889],{"class":334,"line":7862},369,[332,7864,7865],{"class":369},"                        \u003C",[332,7867,7868],{"class":2479},"option",[332,7870,6786],{"class":342},[332,7872,2489],{"class":369},[332,7874,7875],{"class":349},"\"(meta, key) in statusMeta\"",[332,7877,6442],{"class":342},[332,7879,2489],{"class":369},[332,7881,7882],{"class":349},"\"key\"",[332,7884,7632],{"class":342},[332,7886,2489],{"class":369},[332,7888,7882],{"class":349},[332,7890,2255],{"class":369},[332,7892,7894],{"class":334,"line":7893},370,[332,7895,7896],{"class":369},"                          {{ meta.emoji }} {{ meta.label }}\n",[332,7898,7900,7903,7905],{"class":334,"line":7899},371,[332,7901,7902],{"class":369},"                        \u003C\u002F",[332,7904,7868],{"class":2479},[332,7906,2255],{"class":369},[332,7908,7910,7912,7915],{"class":334,"line":7909},372,[332,7911,7571],{"class":369},[332,7913,7914],{"class":2479},"select",[332,7916,2255],{"class":369},[332,7918,7920,7922,7924],{"class":334,"line":7919},373,[332,7921,7581],{"class":369},[332,7923,4692],{"class":2479},[332,7925,2255],{"class":369},[332,7927,7929,7931,7933],{"class":334,"line":7928},374,[332,7930,7591],{"class":369},[332,7932,135],{"class":2479},[332,7934,2255],{"class":369},[332,7936,7938,7940,7942],{"class":334,"line":7937},375,[332,7939,6683],{"class":369},[332,7941,120],{"class":2479},[332,7943,2255],{"class":369},[332,7945,7947,7949,7951],{"class":334,"line":7946},376,[332,7948,6593],{"class":369},[332,7950,130],{"class":2479},[332,7952,2255],{"class":369},[332,7954,7956,7958,7960],{"class":334,"line":7955},377,[332,7957,5756],{"class":369},[332,7959,114],{"class":2479},[332,7961,2255],{"class":369},[332,7963,7965,7967,7969],{"class":334,"line":7964},378,[332,7966,5797],{"class":369},[332,7968,5628],{"class":2479},[332,7970,2255],{"class":369},[332,7972,7974,7976,7978],{"class":334,"line":7973},379,[332,7975,5807],{"class":369},[332,7977,5941],{"class":2479},[332,7979,2255],{"class":369},[332,7981,7983,7985,7987],{"class":334,"line":7982},380,[332,7984,5817],{"class":369},[332,7986,5617],{"class":2479},[332,7988,2255],{"class":369},[332,7990,7992,7995,7997],{"class":334,"line":7991},381,[332,7993,7994],{"class":369},"    \u003C\u002F",[332,7996,5628],{"class":2479},[332,7998,2255],{"class":369},[332,8000,8002],{"class":334,"line":8001},382,[332,8003,377],{"emptyLinePlaceholder":376},[332,8005,8007],{"class":334,"line":8006},383,[332,8008,8009],{"class":410},"    \u003C!-- FLOATING AUTOSAVE STATUS -->\n",[332,8011,8013,8015,8017,8019,8021],{"class":334,"line":8012},384,[332,8014,5644],{"class":369},[332,8016,5628],{"class":2479},[332,8018,5842],{"class":342},[332,8020,2489],{"class":369},[332,8022,8023],{"class":349},"\"saveState !== 'idle'\"\n",[332,8025,8027,8030,8032,8035],{"class":334,"line":8026},385,[332,8028,8029],{"class":342},"         class",[332,8031,2489],{"class":369},[332,8033,8034],{"class":349},"\"fixed bottom-6 left-1\u002F2 z-50 flex -translate-x-1\u002F2 items-center gap-2.5 rounded-full border border-neutral-200 bg-white px-3 py-2 shadow-lg shadow-neutral-900\u002F10\"",[332,8036,2255],{"class":369},[332,8038,8040,8042,8044,8046,8048,8051],{"class":334,"line":8039},386,[332,8041,5667],{"class":369},[332,8043,332],{"class":2479},[332,8045,5631],{"class":342},[332,8047,2489],{"class":369},[332,8049,8050],{"class":349},"\"flex items-center gap-2 pl-1 text-[14px] text-neutral-700\"",[332,8052,2255],{"class":369},[332,8054,8056,8058,8060,8062,8064,8066,8069,8071,8074],{"class":334,"line":8055},387,[332,8057,5685],{"class":369},[332,8059,5617],{"class":2479},[332,8061,5842],{"class":338},[332,8063,2489],{"class":369},[332,8065,5030],{"class":349},[332,8067,8068],{"class":369},"saveState ",[332,8070,3096],{"class":338},[332,8072,8073],{"class":349}," 'dirty'\"",[332,8075,2255],{"class":369},[332,8077,8079,8081,8083,8085,8087,8089,8091,8094,8096,8099,8101],{"class":334,"line":8078},388,[332,8080,5702],{"class":369},[332,8082,332],{"class":2479},[332,8084,5631],{"class":342},[332,8086,2489],{"class":369},[332,8088,6275],{"class":349},[332,8090,5404],{"class":6076},[332,8092,8093],{"class":369},">\u003C",[332,8095,332],{"class":2479},[332,8097,8098],{"class":369},">수정 감지…\u003C\u002F",[332,8100,332],{"class":2479},[332,8102,2255],{"class":369},[332,8104,8106,8108,8110],{"class":334,"line":8105},389,[332,8107,5807],{"class":369},[332,8109,5617],{"class":2479},[332,8111,2255],{"class":369},[332,8113,8115,8117,8119,8121,8123,8125,8127,8129,8132],{"class":334,"line":8114},390,[332,8116,5685],{"class":369},[332,8118,5617],{"class":2479},[332,8120,5881],{"class":338},[332,8122,2489],{"class":369},[332,8124,5030],{"class":349},[332,8126,8068],{"class":369},[332,8128,3096],{"class":338},[332,8130,8131],{"class":349}," 'saving'\"",[332,8133,2255],{"class":369},[332,8135,8137,8139,8141,8143,8145,8148,8150,8152,8154,8157,8159],{"class":334,"line":8136},391,[332,8138,5702],{"class":369},[332,8140,332],{"class":2479},[332,8142,5631],{"class":342},[332,8144,2489],{"class":369},[332,8146,8147],{"class":349},"\"inline-block size-1.5 animate-pulse rounded-full bg-sky-500\"",[332,8149,5404],{"class":6076},[332,8151,8093],{"class":369},[332,8153,332],{"class":2479},[332,8155,8156],{"class":369},">저장 중…\u003C\u002F",[332,8158,332],{"class":2479},[332,8160,2255],{"class":369},[332,8162,8164,8166,8168],{"class":334,"line":8163},392,[332,8165,5807],{"class":369},[332,8167,5617],{"class":2479},[332,8169,2255],{"class":369},[332,8171,8173,8175,8177,8179,8181,8183,8185,8187,8190],{"class":334,"line":8172},393,[332,8174,5685],{"class":369},[332,8176,5617],{"class":2479},[332,8178,5881],{"class":338},[332,8180,2489],{"class":369},[332,8182,5030],{"class":349},[332,8184,8068],{"class":369},[332,8186,3096],{"class":338},[332,8188,8189],{"class":349}," 'saved'\"",[332,8191,2255],{"class":369},[332,8193,8195,8197,8199,8201,8203,8205,8207],{"class":334,"line":8194},394,[332,8196,5702],{"class":369},[332,8198,332],{"class":2479},[332,8200,5631],{"class":342},[332,8202,2489],{"class":369},[332,8204,6142],{"class":349},[332,8206,5404],{"class":6076},[332,8208,2255],{"class":369},[332,8210,8212,8214,8216,8219,8221,8223,8225,8228,8231,8233,8236,8238],{"class":334,"line":8211},395,[332,8213,5702],{"class":369},[332,8215,332],{"class":2479},[332,8217,8218],{"class":369},">저장됨 \u003C",[332,8220,332],{"class":2479},[332,8222,5631],{"class":342},[332,8224,2489],{"class":369},[332,8226,8227],{"class":349},"\"text-neutral-400\"",[332,8229,8230],{"class":369},">· {{ savedAgo }}\u003C\u002F",[332,8232,332],{"class":2479},[332,8234,8235],{"class":369},">\u003C\u002F",[332,8237,332],{"class":2479},[332,8239,2255],{"class":369},[332,8241,8243,8245,8247],{"class":334,"line":8242},396,[332,8244,5807],{"class":369},[332,8246,5617],{"class":2479},[332,8248,2255],{"class":369},[332,8250,8252,8254,8256,8258,8260,8262,8264,8266,8269],{"class":334,"line":8251},397,[332,8253,5685],{"class":369},[332,8255,5617],{"class":2479},[332,8257,5881],{"class":338},[332,8259,2489],{"class":369},[332,8261,5030],{"class":349},[332,8263,8068],{"class":369},[332,8265,3096],{"class":338},[332,8267,8268],{"class":349}," 'error'\"",[332,8270,2255],{"class":369},[332,8272,8274,8276,8278,8280,8282,8285,8287],{"class":334,"line":8273},398,[332,8275,5702],{"class":369},[332,8277,332],{"class":2479},[332,8279,5631],{"class":342},[332,8281,2489],{"class":369},[332,8283,8284],{"class":349},"\"inline-block size-1.5 rounded-full bg-rose-500\"",[332,8286,5404],{"class":6076},[332,8288,2255],{"class":369},[332,8290,8292,8294,8296,8298,8300,8303,8306,8308],{"class":334,"line":8291},399,[332,8293,5702],{"class":369},[332,8295,332],{"class":2479},[332,8297,5631],{"class":342},[332,8299,2489],{"class":369},[332,8301,8302],{"class":349},"\"text-rose-700\"",[332,8304,8305],{"class":369},">저장 실패: {{ saveError }}\u003C\u002F",[332,8307,332],{"class":2479},[332,8309,2255],{"class":369},[332,8311,8313,8315,8317],{"class":334,"line":8312},400,[332,8314,5807],{"class":369},[332,8316,5617],{"class":2479},[332,8318,2255],{"class":369},[332,8320,8322,8324,8326],{"class":334,"line":8321},401,[332,8323,5817],{"class":369},[332,8325,332],{"class":2479},[332,8327,2255],{"class":369},[332,8329,8331,8333,8335,8337,8339,8342,8344],{"class":334,"line":8330},402,[332,8332,5667],{"class":369},[332,8334,332],{"class":2479},[332,8336,5631],{"class":342},[332,8338,2489],{"class":369},[332,8340,8341],{"class":349},"\"h-4 w-px bg-neutral-200\"",[332,8343,5404],{"class":6076},[332,8345,2255],{"class":369},[332,8347,8349,8351,8354,8356,8358],{"class":334,"line":8348},403,[332,8350,5667],{"class":369},[332,8352,8353],{"class":2479},"button",[332,8355,5842],{"class":342},[332,8357,2489],{"class":369},[332,8359,8360],{"class":349},"\"saveState === 'error'\"\n",[332,8362,8364,8366,8368],{"class":334,"line":8363},404,[332,8365,6453],{"class":342},[332,8367,2489],{"class":369},[332,8369,8370],{"class":349},"\"rounded-md bg-neutral-900 px-3 py-1 text-[14px] font-medium text-white hover:bg-neutral-700\"\n",[332,8372,8374,8376,8378,8381,8384,8386],{"class":334,"line":8373},405,[332,8375,6475],{"class":342},[332,8377,2489],{"class":369},[332,8379,8380],{"class":349},"\"saveNow\"",[332,8382,8383],{"class":369},">재시도\u003C\u002F",[332,8385,8353],{"class":2479},[332,8387,2255],{"class":369},[332,8389,8391,8393,8395,8397,8399],{"class":334,"line":8390},406,[332,8392,5667],{"class":369},[332,8394,8353],{"class":2479},[332,8396,5631],{"class":342},[332,8398,2489],{"class":369},[332,8400,8401],{"class":349},"\"rounded-md px-2.5 py-1 text-[14px] text-neutral-600 hover:bg-neutral-100\"\n",[332,8403,8405,8407,8409,8412,8415,8417,8420,8423,8425],{"class":334,"line":8404},407,[332,8406,6475],{"class":342},[332,8408,2489],{"class":369},[332,8410,8411],{"class":349},"\"downloadJson\"",[332,8413,8414],{"class":342}," title",[332,8416,2489],{"class":369},[332,8418,8419],{"class":349},"\"현재 상태를 wbs.json으로 다운로드\"",[332,8421,8422],{"class":369},">↓ 백업\u003C\u002F",[332,8424,8353],{"class":2479},[332,8426,2255],{"class":369},[332,8428,8430,8432,8434],{"class":334,"line":8429},408,[332,8431,7994],{"class":369},[332,8433,5628],{"class":2479},[332,8435,2255],{"class":369},[332,8437,8439,8442,8444],{"class":334,"line":8438},409,[332,8440,8441],{"class":369},"  \u003C\u002F",[332,8443,5628],{"class":2479},[332,8445,2255],{"class":369},[332,8447,8449,8451,8453],{"class":334,"line":8448},410,[332,8450,5600],{"class":369},[332,8452,5617],{"class":2479},[332,8454,2255],{"class":369},[315,8456,8458],{"id":8457},"_6-3-자동-저장-상태-머신","6-3. 자동 저장 상태 머신",[323,8460,8463],{"className":8461,"code":8462,"language":1086},[1084],"[idle] ─ 첫 편집 ─▶ [dirty] ─ 800ms 무편집 ─▶ [saving] ─ 200 OK ─▶ [saved]\n                       │                              │\n                       └─ 추가 편집 시 타이머 재시작     └─ 실패 시 ▶ [error] ─ 재시도 ─▶ [saving]\n",[29,8464,8462],{"__ignoreMap":328},[63,8466,8467,8470,8476,8479],{},[66,8468,8469],{},"새 편집이 들어오면 timer 갱신 → 디바운스 보장",[66,8471,8472,8475],{},[29,8473,8474],{},"saving"," 중 새 편집은 다음 사이클에서 통째로 PUT (변경 단위가 아닌 문서 단위)",[66,8477,8478],{},"페이지 unmount 시 timer cleanup. 저장 누락 위험은 디바운스 800ms로 한정됨",[66,8480,8481,8482,8485,8486,8489,8490,8493],{},"더 강건하게 가려면 ",[29,8483,8484],{},"beforeunload"," 핸들러에서 ",[29,8487,8488],{},"saveState === 'dirty'","일 때 ",[29,8491,8492],{},"navigator.sendBeacon","으로 마지막 PUT을 보낼 수 있음",[52,8495],{},[55,8497,8499],{"id":8498},"_7-새-프로젝트에서-초기화하기-체크리스트","7. 새 프로젝트에서 초기화하기 — 체크리스트",[290,8501,8502,8517,8556,8583,8596],{},[66,8503,8504,8507],{},[18,8505,8506],{},"Cloudflare",[63,8508,8509,8512],{},[66,8510,8511],{},"계정에서 R2 활성화",[66,8513,8514],{},[29,8515,8516],{},"wrangler r2 bucket create \u003Cmy-bucket>",[66,8518,8519,8526],{},[18,8520,8521,8522,8525],{},"백엔드 (",[29,8523,8524],{},"\u003Capi>"," 레포)",[63,8527,8528,8537,8550],{},[66,8529,8530,8533,8534],{},[29,8531,8532],{},"pnpm add hono"," \u002F ",[29,8535,8536],{},"pnpm add -D wrangler typescript",[66,8538,8539,8540,1563,8543,1563,8546,8549],{},"위 §5-1, §5-2 그대로 복사. ",[29,8541,8542],{},"name",[29,8544,8545],{},"account_id",[29,8547,8548],{},"bucket_name","만 교체",[66,8551,8552,8555],{},[29,8553,8554],{},"pnpm wrangler deploy"," → API URL 확보",[66,8557,8558,8565],{},[18,8559,8560,8561,8564],{},"프론트엔드 (",[29,8562,8563],{},"\u003Cpages>"," 레포, Nuxt 3)",[63,8566,8567,8575,8580],{},[66,8568,8569,8571,8572,8574],{},[29,8570,2426],{}," 생성 → §6-2 복사 → ",[29,8573,2434],{},"를 자기 API URL로 교체",[66,8576,8577,8579],{},[29,8578,760],{},"에 §3-2 형태의 초기 시드 작성",[66,8581,8582],{},"한 번 빌드·배포 후 페이지 접속 → 첫 편집 시 R2에 자동 시드됨",[66,8584,8585,8588],{},[18,8586,8587],{},"CORS 확인",[63,8589,8590],{},[66,8591,8592,8593,8595],{},"§5-2의 ",[29,8594,1363],{}," 함수에 자기 페이지 도메인 패턴 추가",[66,8597,8598,8601],{},[18,8599,8600],{},"검증",[63,8602,8603,8606],{},[66,8604,8605],{},"다른 브라우저에서 같은 URL을 열어 변경 즉시 반영되는지 확인",[66,8607,8608],{},"네트워크 탭에서 PUT이 800ms 디바운스 후 1회만 가는지 확인",[23,8610,8611],{},[14,8612,8613,8614,8617,8618,8620,8621,8624],{},"인증이 필요한 환경이면 ",[18,8615,8616],{},"Cloudflare Access","로 ",[29,8619,8563],{}," 도메인과 ",[29,8622,8623],{},"\u003Capi>\u002Fwbs"," 라우트를 동시에 보호하는 것이 가장 단순. 인증 코드 작성 불필요.",[52,8626],{},[55,8628,8630],{"id":8629},"_8-운영-메모","8. 운영 메모",[114,8632,8633,8643],{},[117,8634,8635],{},[120,8636,8637,8640],{},[123,8638,8639],{},"항목",[123,8641,8642],{},"방침",[130,8644,8645,8653,8664,8678,8694,8706],{},[120,8646,8647,8650],{},[135,8648,8649],{},"동시 편집 충돌",[135,8651,8652],{},"last-write-wins. ETag 기반 conditional PUT은 미적용 (사내 1~3명 운영 가정)",[120,8654,8655,8657],{},[135,8656,98],{},[135,8658,8659,8660,8663],{},"우하단 ",[29,8661,8662],{},"↓ 백업"," 버튼으로 수시 다운로드. 또는 R2 versioning 활성화 권장",[120,8665,8666,8669],{},[135,8667,8668],{},"시드 갱신",[135,8670,8671,8673,8674,8677],{},[29,8672,760],{}," 수정은 ",[18,8675,8676],{},"R2가 비어 있을 때만"," 의미가 있음. 운영 중에는 R2가 정본",[120,8679,8680,8683],{},[135,8681,8682],{},"마이그레이션",[135,8684,8685,8686,8689,8690,8693],{},"스키마 변경 시 ",[29,8687,8688],{},"_meta.schemaVersion"," 필드를 추가하고 ",[29,8691,8692],{},"app.put","에서 변환",[120,8695,8696,8699],{},[135,8697,8698],{},"모니터링",[135,8700,8701,8702,8705],{},"Workers ",[29,8703,8704],{},"observability: true","로 PUT 실패 로그 추적",[120,8707,8708,8711],{},[135,8709,8710],{},"보안",[135,8712,8713],{},"현재 무인증. 공개 도메인에 둘 거라면 반드시 Access 또는 토큰 헤더 검증 추가",[52,8715],{},[55,8717,8719],{"id":8718},"_9-디자인-변형-가이드","9. 디자인 변형 가이드",[14,8721,8722],{},"이 페이지의 디자인 토큰은 의도적으로 단순하다. 다음 한 줄만 바꿔도 분위기가 크게 달라진다.",[63,8724,8725,8753,8771,8786],{},[66,8726,8727,8730,8731,8734,8735,8738,8739,8734,8742,8745,8746,8734,8749,8752],{},[18,8728,8729],{},"다크 모드",": 컨테이너 ",[29,8732,8733],{},"bg-neutral-50\u002F60"," → ",[29,8736,8737],{},"bg-neutral-950",", 카드 ",[29,8740,8741],{},"bg-white",[29,8743,8744],{},"bg-neutral-900",", 라인 ",[29,8747,8748],{},"border-neutral-200",[29,8750,8751],{},"border-neutral-800",". 텍스트 명도만 반전",[66,8754,8755,791,8758,8734,8761,8764,8765,8734,8768],{},[18,8756,8757],{},"밀도 ↑",[29,8759,8760],{},"px-3 py-3",[29,8762,8763],{},"px-2 py-2",", 본문 ",[29,8766,8767],{},"text-[14px]",[29,8769,8770],{},"text-[13px]",[66,8772,8773,8776,8777,8780,8781,8734,8783],{},[18,8774,8775],{},"에디토리얼",": 헤더에 serif 디스플레이 폰트(",[29,8778,8779],{},"Instrument Serif"," 등) + 본문 mono. 카드 모서리 ",[29,8782,169],{},[29,8784,8785],{},"rounded-none",[66,8787,8788,8791,8792,8794],{},[18,8789,8790],{},"터미널\u002FIDE",": 카드 제거, 단일 ",[29,8793,323],{},", JetBrains Mono, 좌측 라인 거터 추가",[14,8796,8797],{},"색·간격은 토큰화돼 있어서 한 파일에서 전체 분위기를 바꿀 수 있다.",[52,8799],{},[55,8801,8803],{"id":8802},"_10-알려진-한계","10. 알려진 한계",[63,8805,8806,8812,8818,8828],{},[66,8807,8808,8811],{},[18,8809,8810],{},"다중 사용자 동시 편집 시 마지막 저장이 이김"," — 실시간 동기화(WebSocket\u002FSSE)는 없음",[66,8813,8814,8817],{},[18,8815,8816],{},"인증 없음"," — 외부 노출 시 Cloudflare Access 등으로 별도 보호 필요",[66,8819,8820,8823,8824,8827],{},[18,8821,8822],{},"이력 추적 없음"," — R2 versioning을 켜거나, PUT 시점에 ",[29,8825,8826],{},"wbs\u002Fhistory\u002F\u003Cts>.json","로 스냅샷 저장하면 해결 가능",[66,8829,8830,8833,8834,8837],{},[18,8831,8832],{},"Phase 1만 모델링"," — ",[29,8835,8836],{},"phase1.stages[]"," 구조. Phase 2 이상은 동일 패턴으로 키 추가 후 컴포넌트에서 반복 렌더링",[52,8839],{},[55,8841,8843],{"id":8842},"_11-본-프로젝트의-실제-값-참고","11. 본 프로젝트의 실제 값 (참고)",[114,8845,8846,8855],{},[117,8847,8848],{},[120,8849,8850,8853],{},[123,8851,8852],{},"키",[123,8854,128],{},[130,8856,8857,8867,8877,8887,8900,8910,8920],{},[120,8858,8859,8862],{},[135,8860,8861],{},"API URL",[135,8863,8864],{},[29,8865,8866],{},"https:\u002F\u002Fmalgn-helper-api.malgnsoft.workers.dev",[120,8868,8869,8872],{},[135,8870,8871],{},"API 레포",[135,8873,8874],{},[29,8875,8876],{},"~\u002FProjects\u002Fmalgn-helper-api",[120,8878,8879,8882],{},[135,8880,8881],{},"Pages 레포",[135,8883,8884],{},[29,8885,8886],{},"~\u002FProjects\u002Fmalgn-helper-pms",[120,8888,8889,8892],{},[135,8890,8891],{},"R2 버킷",[135,8893,8894,8897,8898,307],{},[29,8895,8896],{},"malgn-helper-files"," (key: ",[29,8899,1104],{},[120,8901,8902,8905],{},[135,8903,8904],{},"페이지 URL",[135,8906,8907],{},[29,8908,8909],{},"https:\u002F\u002Fmalgn-helper-pms.pages.dev\u002Fwbs",[120,8911,8912,8915],{},[135,8913,8914],{},"시드 위치",[135,8916,8917],{},[29,8918,8919],{},"malgn-helper-pms\u002Fpublic\u002Fwbs.json",[120,8921,8922,8925],{},[135,8923,8924],{},"Cloudflare account_id",[135,8926,8927,1379,8930,307],{},[29,8928,8929],{},"d2b8c5524b7259214fa302f1fecb4ad6",[42,8931,8933],{"href":8932},"mailto:Info@malgnsoft.com","Info@malgnsoft.com",[8935,8936,8937],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":328,"searchDepth":380,"depth":380,"links":8939},[8940,8941,8942,8949,8950,8960,8966,8967,8968,8969,8970],{"id":57,"depth":373,"text":58},{"id":111,"depth":373,"text":112},{"id":312,"depth":373,"text":313,"children":8943},[8944,8946,8948],{"id":317,"depth":380,"text":8945},"3-1. wbs.json 스키마",{"id":756,"depth":380,"text":8947},"3-2. 초기 시드 예시 (public\u002Fwbs.json)",{"id":1055,"depth":380,"text":1056},{"id":1079,"depth":373,"text":1080},{"id":1138,"depth":373,"text":1139,"children":8951},[8952,8954,8956,8958,8959],{"id":1142,"depth":380,"text":8953},"5-1. wrangler.jsonc",{"id":1218,"depth":380,"text":8955},"5-2. src\u002Findex.ts (전체)",{"id":2142,"depth":380,"text":8957},"5-3. package.json 최소 의존",{"id":2208,"depth":380,"text":2209},{"id":2283,"depth":380,"text":2284},{"id":2389,"depth":373,"text":2390,"children":8961},[8962,8963,8965],{"id":2393,"depth":380,"text":2394},{"id":2422,"depth":380,"text":8964},"6-2. 단일 파일 — pages\u002Fwbs.vue (전체)",{"id":8457,"depth":380,"text":8458},{"id":8498,"depth":373,"text":8499},{"id":8629,"depth":373,"text":8630},{"id":8718,"depth":373,"text":8719},{"id":8802,"depth":373,"text":8803},{"id":8842,"depth":373,"text":8843},"이 문서 하나만 있으면 어떤 프로젝트에서도 동일한 WBS Live Tracker 페이지를 처음부터 만들 수 있다.\n프론트엔드(Nuxt) + 백엔드(Hono on Workers) + 영속화(R2) + 자동 저장 흐름을 전부 포함한다.","md",{},"\u002Fwbs-tracker",{"title":5,"description":8971},"WBS-TRACKER","i086HB2qpUcUTC6DGKmfExYH4514OCpCFKzdA3zgwug",1780990720862]