과제 B3 — 마인드맵·플랜 웹 탭 모듈 (신규 파일만, 라이브 무접촉)
개요
docs.crowny.org/office (한선씨/정적/) 4탭(홈/문서/시트/슬라이드) 구조에 마인드맵·플랜 탭을 추가하기 위한
신규 파일 산출. 라이브 파일(index.html, common.js 등) 직접 Edit 없이 wiring 스펙으로만 배선 지점 제시.
무엇을 했는지
1. mindmap.js + mindmap.한선 (신규)
CrownyMindmapData — 순수 데이터모델: 노드저장소(맵) + 부모/자녀 포인터, 방사형(radial) 좌표.
create/addNode/deleteNode(연쇄삭제)/renameNode/moveNode(드래그)/findChildren/depth/layout/serialize/deserialize
layout()은 오피스네이티브/오피스.한선 뷰마인드맵(고정 4자녀 방사형)의 컨셉을 일반 n-ary 트리로 확장 이식 — 부모 각도구간을 자식수만큼 웨지 분할, depth당 반지름 확장. 드래그로 고정된 노드(x/y 값 있음)는 재배치 안 함.
CrownyMindmap — SVG 렌더러: 툴바(추가/이름변경/삭제/재배치) + 클릭선택 + 더블클릭 이름변경(CrownyDialogs.prompt 재사용) + 드래그 이동(pointerevents) + 삭제(CrownyDialogs.confirm 재사용).
저장: CrownyOffice.storage(localStorage, crowny- 프리픽스) — file-manager.js와 동일 저장 규약 준수. CrownyFileManager 파일목록에는 통합하지 않음(라이브 파일 Edit 금지 범위 밖).
디자인: 신규 팔레트 없음 — crowny-office.css :root 기존 변수(--bg-card, --gold, --border, --text 등)만 인라인 참조.
자동초기화: #mindmap-container 존재 시 DOMContentLoaded에서 자기 부팅(인라인 스크립트 수정 불필요).
mindmap.한선: 크라우니코드 학습DB 기존 패턴(fn_마인드맵_마인드맵생성, fn_마인드맵_노드추가마인드, fn_마인드맵_맵깊이, fn_마인드맵_가지펼치기 계열) 재사용 + 삭제/이름변경/이동/직렬화는 MISS로 신규 작성.
VM 함정 회피: 네이티브 해시맵은 append-only(키 삭제 빌트인 없음) → 노드삭제는 톰스톤(삭제됨=1) 방식으로 구현, 조회/직렬화 함수에서 맵있나(...)!=1로 필터링.2. plan-tab.js + plan-tab.한선 (신규)
- 기존
/plan(옴니플랜 간트, server-docs.js:4864 부근, 인증필요)을 iframe으로 임베드 — 간트 로직 재구현 없음(중복 금지 준수).
- 상단 바 + "새 창에서 열기" 링크(
target=_blank) + iframe(src=/plan).
#plan-container 존재 시 자기 부팅.
3. 검증
node --check mindmap.js / node --check plan-tab.js — 통과.
- Node 스모크 하네스(
mindmap_smoke.js, scratchpad, 산출물 아님) — 노드 추가→직렬화→역직렬화 왕복 + 연쇄삭제 + 톰스톤 필터 + 드래그고정 등 17개 assert 전체 PASS.
hanseonc_high 컴파일(파일기반) + CROWNY_STRICT=1 재컴파일(경고 0) + crownyc run 실행 검증 — mindmap.한선, plan-tab.한선 둘 다 통과. 출력이 데이터모델 동작(추가/이름변경/삭제/직렬화)과 일치함을 확인.
- 크라우니코드: lookup/search HIT 8건(마인드맵 노드추가/생성/깊이/가지펼치기/자식찾기 등, 재사용) / MISS 4건(삭제-톰스톤/이름변경/이동/plan URL조립, 신규생성) / learn 추가 4건.
4. wiring 스펙 (라이브 index.html 직접 미수정 — 아래 3곳만 삽입 필요)
- 탭 버튼 2개 —
data-mode='slide' 버튼 줄 다음에 data-mode='mind'(🧠 마인드맵), data-mode='plan'(📅 플랜) 버튼 삽입.
- 컨테이너 2개 —
mode-slide 패널 닫는 태그 다음, sidebar div 앞에 #mode-mind(#mindmap-container 포함) / #mode-plan(#plan-container 포함) 패널 삽입.
- 스크립트 태그 2개 — 마지막
<script src='/static/최근문서.js'></script> 다음에 mindmap.js, plan-tab.js 삽입.
CrownyOffice.switchMode는 data-mode/mode-<id> 컨벤션으로 완전히 데이터 구동이라 탭 전환·?mode= 딥링크 모두 추가 코드 불필요 — 신규 파일의 자기부팅(DOMContentLoaded)만으로 동작. 상태바 텍스트(status-mode) 라벨 갱신은 선택적 코스메틱(미적용해도 기능엔 무관).
관련 파일
/Users/ef/CrownyDoc/한선씨/정적/mindmap.js
/Users/ef/CrownyDoc/한선씨/정적/mindmap.한선
/Users/ef/CrownyDoc/한선씨/정적/plan-tab.js
/Users/ef/CrownyDoc/한선씨/정적/plan-tab.한선
- 참조만(미수정):
/Users/ef/CrownyDoc/한선씨/정적/index.html, common.js, dialogs.js, file-manager.js, /Users/ef/CrownyDoc/한선씨/오피스네이티브/오피스.한선, /Users/ef/CrownyDoc/server-docs.js(/plan 라우트)
잔여 이슈
- 실제 index.html/공통 스크립트 배선은 이 산출물의 wiring 스펙대로 오너/다른 세션이 적용해야 라이브 반영됨(이번 세션은 라이브 무접촉 지시로 미적용).
- 마인드맵 파일을 CrownyFileManager 파일목록(홈 탭)에 노출하려면 file-manager.js에
type:'mind' 분기 추가가 필요(범위 밖, 별도 작업).
- SVG 렌더러는 대량 노드(수백+) 시 매 상호작용마다 전체 재그리기라 비효율 — 필요시 dirty-node만 갱신하는 최적화 여지.