risum 모듈 — RISU modules[] — 기능 확장
👍 18 · 조회 545 · 2025-06-05
프롬이팁주기PrompTip v0.3 프롬프트 프롬이팁주기 V0.3 모듈 모듈 활성화 필수 설명서 첨부 없는 오픈베타 자세한 사용설명서는 내일 V0.3.1과 함께 미리 사용해볼 사람은 플로팅바 / 오토리뷰 토글과 함께 써보세용
{
"name": "⚖️👌프롬이팁주기 V0.3",
"description": "",
"id": "11dc9a1d-974c-4a06-9c04-7877f2b2dd70",
"assets": [
[
"home",
"",
"png"
],
[
"tip-coin",
"",
"png"
],
[
"feedback",
"",
"png"
],
[
"checkbox",
"",
"png"
],
[
"refresh",
"",
"png"
]
],
"hideIcon": false,
"trigger": [
{
"comment": "",
"type": "start",
"conditions": [],
"effect": [
{
"type": "triggerlua",
"code": "-- ==============================================================================\n-- RisuAI 통합 스크립트 v3.1 - Thoughts 태그 내 AuRev 제외 처리\n-- * v3.0 기반으로 <Thoughts></Thoughts> 태그 내부의 [AuRev] 무시 로직 추가\n-- * 안전한 패턴 매칭으로 의도된 [AuRev]만 처리\n-- * 디버깅 및 로깅 강화로 처리 과정 추적 가능\n-- ==============================================================================\n\n-- ==============================[ 전역 설정 ]=====================================\nlocal CONFIG = {\n VERSION = \"3.1\",\n DEBUG = true,\n \n -- 팁 카운터 설정\n TIP_MAX = 5,\n TIP_FORMAT = \"> 🛎️ (팁 카운트 = %d/%d)\",\n TIP_MARKER = \"[[TIP_COUNTER:%d]]\",\n TIP_TOKEN = \"[플로팅바]\",\n TIP_KEY = \"__tip_count\",\n \n -- 선택지 시스템 설정\n SELECT_MAX = 6,\n SELECT_KEY = \"__story_options\", \n SELECT_TRIGGER = \"%[조합%]\",\n \n -- OOC 시스템 설정\n OOC_ENABLED = true,\n OOC_PREFIX_CHAT = \"oocC:\",\n OOC_PREFIX_STATE = \"oocS:\",\n OOC_SIZE_LIMIT = 1000,\n \n -- 🆕 AUTO REVIEW 설정 (개선됨)\n AUTO_REVIEW_ENABLED = true,\n REVIEW_TRIGGER = \"%[AuRev%]\",\n REVIEW_PROCESSING = \"[리뷰생성중...]\",\n REVIEW_ERROR = \"[리뷰 생성 실패]\",\n REVIEW_MAX_SEARCH = 5,\n REVIEW_RETRY_MAX = 2,\n \n -- 🆕 제외할 태그 패턴들 (확장 가능)\n REVIEW_EXCLUDE_PATTERNS = {\n \"<Thoughts>.-</Thoughts>\", -- Thoughts 태그 내부\n \"<thoughts>.-</thoughts>\", -- 소문자 버전\n \"<!%-%-.-%-%->\" -- HTML 주석\n },\n \n -- AUTO REVIEW 본문 추출 설정\n REVIEW_CONTENT_START = \"## 원고 제작\",\n REVIEW_CONTENT_ENDS = {\n \"%[AuRev%]\",\n \"<!%-%-.-%-%->\"\n },\n REVIEW_METADATA_PATTERNS = {\n \"^### 제.-\\n\", -- 챕터 제목\n \"^- 날짜:.-\\n\", -- 날짜 정보\n \"^- 시간:.-\\n\", -- 시간 정보\n \"^- 장소:.-\\n\", -- 장소 정보\n \"^- [가-힣%w%s]*:.-\\n\", -- 기타 메타데이터\n \"^• [가-힣%w%s]*:.-\\n\" -- 불릿 포인트 메타데이터\n }\n}\n\n-- ==============================[ 유틸리티 함수들 ]===============================\nlocal function safeLog(message)\n local msg = \"[Script v\" .. CONFIG.VERSION .. \"] \" .. message\n if log then log(msg) else print(msg) end\nend\n\nlocal function debugLog(message)\n if CONFIG.DEBUG then\n safeLog(\"[DEBUG] \" .. message)\n end\nend\n\n-- 🆕 DJB2 해시 알고리즘 (AUTO REVIEW용)\nlocal function generateDJB2Hash(data)\n if not data then return \"0\" end\n local hash = 5381\n for i = 1, #data do\n hash = ((hash * 33) + string.byte(data, i)) % 2147483647\n end\n return tostring(hash)\nend\n\n-- 🆕 안전한 [AuRev] 감지 함수 (제외 패턴 고려)\nlocal function hasSafeAuRev(text)\n if not text then return false end\n \n debugLog(\"=== [AuRev] 안전 감지 시작 ===\")\n debugLog(\"원본 텍스트 길이: \" .. #text)\n \n -- 1단계: [AuRev]가 전혀 없으면 바로 false 반환\n if not text:find(CONFIG.REVIEW_TRIGGER) then\n debugLog(\"❌ [AuRev] 없음\")\n return false\n end\n \n local excludedCount = 0\n local workingText = text\n \n -- 2단계: 제외 패턴들을 임시로 마스킹\n local maskCounter = 0\n local masks = {}\n \n for _, pattern in ipairs(CONFIG.REVIEW_EXCLUDE_PATTERNS) do\n local tempText = workingText\n workingText = workingText:gsub(pattern, function(matched)\n maskCounter = maskCounter + 1\n local maskId = \"___MASK_\" .. maskCounter .. \"___\"\n masks[maskId] = matched\n \n -- 이 영역에서 [AuRev] 개수 세기\n local aurevInMasked = 0\n for _ in matched:gmatch(CONFIG.REVIEW_TRIGGER) do\n aurevInMasked = aurevInMasked + 1\n end\n excludedCount = excludedCount + aurevInMasked\n \n debugLog(\"🔒 제외 영역 마스킹: \" .. pattern .. \" (내부 [AuRev]: \" .. aurevInMasked .. \"개)\")\n \n return maskId\n end)\n end\n \n -- 3단계: 마스킹된 텍스트에서 [AuRev] 확인\n local validAuRev = 0\n for _ in workingText:gmatch(CONFIG.REVIEW_TRIGGER) do\n validAuRev = validAuRev + 1\n end\n \n debugLog(\"📊 [AuRev] 통계:\")\n debugLog(\" - 제외된 [AuRev]: \" .. excludedCount .. \"개\")\n debugLog(\" - 유효한 [AuRev]: \" .. validAuRev .. \"개\")\n debugLog(\" - 마스킹된 영역: \" .. maskCounter .. \"개\")\n \n -- 4단계: 결과 판정\n local hasSafe = validAuRev > 0\n debugLog(\"✅ 안전한 [AuRev] 존재: \" .. (hasSafe and \"YES\" or \"NO\"))\n \n return hasSafe\nend\n\n-- 🆕 안전한 [AuRev] 처리 함수 (제외 영역 보호)\nlocal function processSafeAuRev(text)\n if not text then return text end\n \n debugLog(\"=== 안전한 [AuRev] 처리 시작 ===\")\n \n local maskCounter = 0\n local masks = {}\n local workingText = text\n \n -- 1단계: 제외 영역들을 마스킹으로 보호\n for _, pattern in ipairs(CONFIG.REVIEW_EXCLUDE_PATTERNS) do\n workingText = workingText:gsub(pattern, function(matched)\n maskCounter = maskCounter + 1\n local maskId = \"___MASK_\" .. maskCounter .. \"___\"\n masks[maskId] = matched\n \n debugLog(\"🔒 보호 영역 마스킹: \" .. maskId)\n return maskId\n end)\n end\n \n -- 2단계: 마스킹된 텍스트에서만 [AuRev] → [리뷰생성중...] 변환\n local processedCount = 0\n workingText = workingText:gsub(CONFIG.REVIEW_TRIGGER, function(matched)\n processedCount = processedCount + 1\n debugLog(\"✅ [AuRev] 처리: \" .. processedCount .. \"번째\")\n return CONFIG.REVIEW_PROCESSING\n end)\n \n -- 3단계: 마스킹 해제 (원본 영역 복원)\n for maskId, original in pairs(masks) do\n workingText = workingText:gsub(maskId, function()\n debugLog(\"🔓 보호 영역 복원: \" .. maskId)\n return original\n end)\n end\n \n debugLog(\"🎯 처리 결과:\")\n debugLog(\" - 처리된 [AuRev]: \" .. processedCount .. \"개\")\n debugLog(\" - 보호된 영역: \" .. maskCounter .. \"개\")\n debugLog(\"=== 안전한 [AuRev] 처리 완료 ===\")\n \n return workingText\nend\n\n-- JSON 처리 (안전성 강화)\nlocal function jsonDecode(str)\n if not str or not json then return nil end\n local success, result = pcall(json.decode, str)\n return success and result or nil\nend\n\nlocal function jsonEncode(data)\n if not data or not json then return nil end\n local success, result = pcall(json.encode, data)\n return success and result or nil\nend\n\n-- HTML 이스케이프\nlocal function escapeHTML(text)\n if not text then return \"\" end\n return tostring(text):gsub(\"[&<>\\\"']\", {\n [\"&\"] = \"&\", [\"<\"] = \"<\", [\">\"] = \">\",\n ['\"'] = \""\", [\"'\"] = \"'\"\n })\nend\n\n-- 템플릿 치환 (간소화)\nlocal function safeTemplateReplace(template, replacements)\n debugLog(\"Template replacement starting...\")\n local result = template\n \n for key, value in pairs(replacements) do\n local placeholder = \"{\" .. key .. \"}\"\n local valueStr = tostring(value or \"\")\n local escapedValue = valueStr:gsub(\"%%\", \"%%%%\")\n result = result:gsub(placeholder, escapedValue)\n end\n \n -- 미치환 플레이스홀더 정리\n result = result:gsub(\"{[^}]+}\", \"\")\n \n return result\nend\n\n-- ========================[ AUTO REVIEW 시스템 통합 ]============================\n\n-- 개선된 본문 추출 함수\nlocal function extractPureContent(data)\n if not data then return \"\" end\n \n debugLog(\"본문 추출 시작, 원본 길이: \" .. #data)\n \n -- 1. \"## 원고 제작\" 이후부터 시작\n local startPos = data:find(CONFIG.REVIEW_CONTENT_START)\n if not startPos then\n debugLog(\"경고: '## 원고 제작' 마커 없음\")\n return data\n end\n \n local content = data:sub(startPos + #CONFIG.REVIEW_CONTENT_START)\n content = content:gsub(\"^%s*\\n\", \"\")\n \n -- 2. 종료 마커 이전까지만\n local endPos = #content + 1\n for _, marker in ipairs(CONFIG.REVIEW_CONTENT_ENDS) do\n local pos = content:find(marker)\n if pos and pos < endPos then\n endPos = pos\n end\n end\n content = content:sub(1, endPos - 1)\n \n -- 3. 메타데이터 제거 (라인별 처리)\n local lines = {}\n for line in content:gmatch(\"[^\\n]*\") do\n local isMetadata = false\n for _, pattern in ipairs(CONFIG.REVIEW_METADATA_PATTERNS) do\n if line:match(pattern) then\n isMetadata = true\n debugLog(\"메타데이터 제거: \" .. line:sub(1, 30) .. \"...\")\n break\n end\n end\n \n if not isMetadata then\n table.insert(lines, line)\n end\n end\n \n -- 4. 빈 줄 정리\n local result = table.concat(lines, \"\\n\")\n result = result:gsub(\"^\\n+\", \"\")\n result = result:gsub(\"\\n+$\", \"\")\n result = result:gsub(\"\\n\\n\\n+\", \"\\n\\n\")\n \n debugLog(\"본문 추출 완료: \" .. #data .. \"자 → \" .. #result .. \"자\")\n return result\nend\n\n-- 효율적인 채팅 탐색 (최근 5개만)\nlocal function findReviewTarget(chats)\n local searchLimit = math.min(CONFIG.REVIEW_MAX_SEARCH, #chats)\n \n for i = #chats, #chats - searchLimit + 1, -1 do\n local chat = chats[i]\n if chat and chat.role ~= \"user\" and chat.data then\n if chat.data:find(CONFIG.REVIEW_PROCESSING, 1, true) then\n debugLog(\"리뷰 처리 대상 발견: 메시지 \" .. i)\n return chat, i - 1\n end\n end\n end\n \n return nil, nil\nend\n\n-- AUTO REVIEW 프롬프트 (개선된 버전)\nlocal REVIEW_PROMPTS = {\n systemPrompt = [[\n# Role: Web Novel Chapter Analysis and Keyword Review Expert\n\n## (P0) Priority Definition\nP0 (Mandatory): Core guidelines. Strict compliance required. \nP1 (High Priority): Essential for quality/consistency. Follow whenever possible.\nP2 (Recommended): Enhances completeness/depth. Apply flexibly without compromising higher priorities.\n\n## (P0) Mission\nYou are a knowledgeable professional editor specializing in Korean web novels. You must analyze the provided novel chapter, select 3 categories from the defined category list, and write concise, keyword-focused analysis summaries (approximately 150-200 characters) for each category in **Korean**. Extract core keywords from your analysis and provide them in hashtag format.\n\n## (P1) Analysis and Evaluation Criteria\nConsider the following criteria comprehensively when analyzing chapters:\n1. **Overall Impression & Core Feeling**: General satisfaction, emotional impact, memorable moments.\n2. **Plot Progression & Pacing**: Story momentum, speed, logical connections, advancement.\n3. **Character Actions & Motivations**: Believability, clarity of motives, consistency.\n4. **Character Relationships & Dialogue**: Dynamics, interaction impact, realism, effectiveness.\n5. **Worldbuilding & Atmosphere**: Immersion, setting details, mood conveyance.\n6. **Prose Style & Expression**: Sentence structure, word choice, vividness, narrative voice.\n7. **Intrigue & Unpredictability**: Suspense, surprise, predictability, foreshadowing/twists.\n8. **Emotional Depth & Resonance**: Scene impact, depth of character feelings, reader empathy.\n9. **Mature Content Depiction (If Applicable)**: Guideline adherence, description effectiveness, tone.\n10. **Volume & Structure**: Perceived length/substance (relative to token goals), structural elements (transitions, etc.).\n11. **Theme & Message Consistency**: Conveyance of themes, reinforcement through scenes.\n12. **User Choice Reflection (Interactive Only)**: Impact of user input on story/characters.\n\n## (P1) Review Category List\nSelect 3 different categories most suitable for the chapter content from the following:\n- 플롯 진행 완성도\n- 인물 동기/행동 일관성\n- 세계관 분위기 몰입도\n- 문체/표현 효과\n- 소재/구조 균형도\n- 감정적 깊이/울림\n- 주제/메시지 일관성\n{{#if {{equal::{{getglobalvar::toggle_sex}}::1}} }}\n- 성인 콘텐츠 표현\n{{/if}}\n\n## (P0) Output Format\n<review>\n[Selected Category 1]: {Core Assessment}\n- 장점: {Strength1}, {Strength2}\n- 개선점: {Improvement Point}\n- 키워드: [#Keyword1] [#Keyword2] [#Keyword3] [#Keyword4]\n[Selected Category 2]: {Core Assessment}\n- 장점: {Strength1}, {Strength2}\n- 개선점: {Improvement Point}\n- 키워드: [#Keyword1] [#Keyword2] [#Keyword3] [#Keyword4]\n[Selected Category 3]: {Core Assessment}\n- 장점: {Strength1}, {Strength2}\n- 개선점: {Improvement Point}\n- 키워드: [#Keyword1] [#Keyword2] [#Keyword3] [#Keyword4]\n</review>\n]],\n \n userPrompt = [[\n## Novel Chapter for Analysis:\n%s\n\nPlease analyze the above chapter according to the system prompt guidelines, select 3 review categories, and write keyword-focused analysis summaries. The output should follow the specified [Output Format].\n\n## (P0) Pre-Output Checklist - MANDATORY VERIFICATION:\nBefore providing your final response, verify ALL of the following:\n□ Exactly 3 different categories selected from the predefined category list\n□ Korean language used for all analysis content (not English or mixed)\n□ <review> opening and closing tags included (NO other tags or code blocks)\n□ Each category follows exact format: [Category]: {Assessment} + 장점/개선점/키워드 structure\n□ Each category has exactly 2 strengths (장점) and 1 improvement point (개선점)\n□ Each category has exactly 4 keywords in [#Keyword] format\n□ Character count per assessment: 150-200 characters (Korean)\n□ NO markdown formatting (no ```, no **, no extra formatting)\n□ NO code blocks, language tags, or decorative markup\n□ Plain text output only within <review> tags\n\n**CRITICAL**: Output ONLY the <review> content in plain text. No additional formatting, explanations, or markdown. If any checkbox above is unchecked, DO NOT proceed with output. Revise until ALL requirements are met.\n\n**FORBIDDEN**: Do NOT use ```korean, ```html, **, *, or any other markdown syntax.\n]]\n}\n\n-- 중복 처리 방지 시스템\nlocal processedHashes = {}\n\nlocal function cleanupProcessedHashes()\n local count = 0\n for _ in pairs(processedHashes) do count = count + 1 end\n \n if count > 50 then\n local temp = {}\n local keep = 0\n for hash, _ in pairs(processedHashes) do\n if keep < 25 then\n temp[hash] = true\n keep = keep + 1\n end\n end\n processedHashes = temp\n debugLog(\"해시 테이블 정리: \" .. count .. \" → \" .. keep)\n end\nend\n\n-- ==============================[ OOC 시스템 ]===================================\n\n-- 개선된 간소화 요약 생성 (v2.7 기반)\nlocal function generateSimplifiedSummary(normalized)\n debugLog(\"간소화 요약 생성 중...\")\n \n local parts = {}\n \n -- 1. 태그 그룹 (공백으로 분리)\n if normalized.tags and #normalized.tags > 0 then\n local tagTexts = {}\n for _, tag in ipairs(normalized.tags) do\n if type(tag) == \"table\" and tag.content then\n local tagText = tag.content\n -- 우선순위별 마킹\n local priority = tag.priorityId or \"p2\"\n if priority:lower():find(\"p0c\") then\n tagText = tagText .. \"!\"\n elseif priority:lower():find(\"p1\") then\n tagText = tagText .. \"*\"\n end\n table.insert(tagTexts, tagText)\n end\n end\n if #tagTexts > 0 then\n table.insert(parts, '<div class=\"tag-group\"><strong>' .. \n table.concat(tagTexts, \" \") .. '</strong></div>')\n end\n end\n \n -- 2. 상태 정보\n if normalized.status and normalized.status ~= \"상태 정보 없음\" then\n table.insert(parts, '<div class=\"status-info\">' .. \n escapeHTML(normalized.status) .. '</div>')\n end\n \n -- 3. 체크리스트 (우선순위별 CSS 클래스)\n if normalized.checklist and #normalized.checklist > 0 then\n table.insert(parts, '<ul class=\"simplified-checklist\">')\n for _, item in ipairs(normalized.checklist) do\n if type(item) == \"table\" and item.item then\n local priority = item.priority or \"P2\"\n local cssClass = \"priority-\" .. priority:lower()\n \n table.insert(parts, string.format(\n '<li class=\"%s\" data-priority=\"%s\">(%s) %s</li>',\n cssClass,\n priority,\n priority:upper(),\n escapeHTML(item.item)\n ))\n end\n end\n table.insert(parts, '</ul>')\n end\n \n local result = table.concat(parts, \"\\n\")\n debugLog(\"간소화 요약 생성 완료: \" .. #result .. \" 문자\")\n \n return result\nend\n\n-- OOC HTML 템플릿 (CSS 클래스만 사용)\nlocal OOC_TEMPLATE = [[\n<OOCNote>\n<div class=\"ooc-box type-{type}\" data-set=\"{set}\">\n <details>\n <summary>\n <div class=\"ooc-header\">\n <div><span class=\"ooc-label\">OOC</span> 피드백 처리 완료 📝</div>\n <span class=\"ooc-toggle\">(펼치기/접기)</span>\n </div>\n <div class=\"ooc-summary\">\n {tags}\n </div>\n </summary>\n <div class=\"ooc-body\">\n <blockquote class=\"ooc-feedback\">\n {response}<br><span>({status})</span>\n </blockquote>\n <div class=\"ooc-tags\">\n {summary}\n </div>\n <blockquote class=\"ooc-checklist\">\n <strong>Action Checklist:</strong>\n <ul>{checklist}</ul>\n </blockquote>\n \n <div class=\"ooc-simplified-summary\">\n <details>\n <summary>핵심 요약</summary>\n <div class=\"ooc-simplified-content\">{simplifiedContent}</div>\n </details>\n </div>\n </div>\n </details>\n</div>\n</OOCNote>]]\n\n-- OOC 변환 함수\nlocal function convertOOCNote(content, triggerId)\n debugLog(\"=== OOC 변환 시작 v3.1 ===\")\n debugLog(\"입력 길이: \" .. #content)\n \n -- JSON 파싱\n local data = jsonDecode(content)\n if not data then\n debugLog(\"오류: JSON 디코딩 실패\")\n return '<div class=\"ooc-error\">❌ JSON 파싱 실패</div>'\n end\n \n if not data.OOCNote or type(data.OOCNote) ~= \"table\" then\n debugLog(\"오류: 잘못된 OOCNote 구조\")\n return '<div class=\"ooc-error\">❌ OOCNote 구조 오류</div>'\n end\n \n local ooc = data.OOCNote\n \n -- 데이터 정규화\n local function safeGet(obj, key, default)\n return (obj and obj[key]) or default\n end\n local function safeGetNested(obj, key1, key2, default)\n return (obj and obj[key1] and obj[key1][key2]) or default\n end\n \n local normalized = {\n type = safeGetNested(ooc, \"overallInfo\", \"type\", \"N\"),\n set = safeGetNested(ooc, \"overallInfo\", \"set\", 1),\n summary = safeGet(ooc, \"feedbackSummary\", \"피드백 없음\"),\n status = safeGet(ooc, \"statusDetails\", \"상태 정보 없음\"),\n response = safeGet(ooc, \"aiResponse\", \"응답 없음\"),\n tags = safeGet(ooc, \"tags\", {}),\n checklist = safeGet(ooc, \"checklist\", {})\n }\n \n debugLog(\"✅ 데이터 정규화 완료: type=\" .. normalized.type .. \", tags=\" .. #normalized.tags)\n \n -- 태그 HTML 생성\n local tagsHTML = \"\"\n if type(normalized.tags) == \"table\" and #normalized.tags > 0 then\n local tagParts = {}\n for i, tag in ipairs(normalized.tags) do\n if type(tag) == \"table\" and tag.content then\n local tagClass = string.format(\"ooc-tag tag-%s-%s\", \n (tag.tagType or \"n\"):lower(),\n (tag.priorityId or \"p2\"):lower())\n local tagHTML = '<span class=\"' .. tagClass .. '\">' .. escapeHTML(tag.content) .. '</span>'\n table.insert(tagParts, tagHTML)\n end\n end\n tagsHTML = table.concat(tagParts, \" \")\n else\n tagsHTML = '<span class=\"ooc-tag\">태그 없음</span>'\n end\n \n -- 체크리스트 HTML 생성\n local checklistHTML = \"\"\n if type(normalized.checklist) == \"table\" and #normalized.checklist > 0 then\n local listParts = {}\n for i, item in ipairs(normalized.checklist) do\n if type(item) == \"table\" and item.item then\n local priority = item.priority or \"P2\"\n local itemHTML = string.format('<li class=\"prio-%s\">(%s) %s</li>',\n priority:lower(), priority:upper(), escapeHTML(item.item))\n table.insert(listParts, itemHTML)\n end\n end\n checklistHTML = table.concat(listParts, \"\\n \")\n else\n checklistHTML = '<li>체크리스트 없음</li>'\n end\n \n -- 간소화된 요약 생성\n local simplifiedContent = generateSimplifiedSummary(normalized)\n \n -- HTML 생성\n local replacements = {\n type = normalized.type:upper(),\n set = tostring(normalized.set),\n tags = tagsHTML,\n response = escapeHTML(normalized.response),\n status = escapeHTML(normalized.status),\n summary = escapeHTML(normalized.summary),\n checklist = checklistHTML,\n simplifiedContent = simplifiedContent\n }\n \n local finalHTML = safeTemplateReplace(OOC_TEMPLATE, replacements)\n \n debugLog(\"✅ OOC 변환 성공 v3.1\")\n return finalHTML\nend\n\n-- ==============================[ 선택지 시스템 ]===============================\nlocal OPT_LABELS = {\n \"1. 안정적인 전개\", \"2. 갈등 심화 / 관계 변화\", \"3. 예상 밖의 전환\",\n \"4. 캐릭터 심층 탐구\", \"5. 주변 환경/상황 묘사 집중\", \"6. 예기치 않은 사건/만남\"\n}\n\nlocal NUMBER_WORDS = {\n [\"첫번째\"]=1, [\"첫째\"]=1, [\"1번\"]=1,\n [\"두번째\"]=2, [\"둘째\"]=2, [\"2번\"]=2,\n [\"세번째\"]=3, [\"셋째\"]=3, [\"3번\"]=3,\n [\"네번째\"]=4, [\"넷째\"]=4, [\"4번\"]=4,\n [\"다섯번째\"]=5, [\"다섯째\"]=5, [\"5번\"]=5,\n [\"여섯번째\"]=6, [\"여섯째\"]=6, [\"6번\"]=6\n}\n\nlocal function processSPTag(text, triggerId)\n local body = text:match('%[SP::(.-)%]')\n if not body then return text end\n \n debugLog(\"SP 태그 처리 중\")\n \n local options = {}\n local index = 0\n \n for chunk in body:gmatch('%b()') do\n index = index + 1\n options[index] = chunk:sub(2, -2)\n end\n \n local encoded = jsonEncode(options)\n if encoded then\n setChatVar(triggerId, CONFIG.SELECT_KEY, encoded)\n debugLog(\"SP 옵션 저장 완료: \" .. index .. \"개\")\n end\n \n for i = 1, CONFIG.SELECT_MAX do\n text = text:gsub('%$' .. i, options[i] or ('(미정 ' .. i .. ')'))\n end\n \n return text\nend\n\nlocal function processCombo(text, triggerId)\n if not text:find(CONFIG.SELECT_TRIGGER) then return text end\n \n debugLog(\"조합 트리거 감지\")\n \n local optionsJson = getChatVar(triggerId, CONFIG.SELECT_KEY)\n local options = jsonDecode(optionsJson or '{}')\n \n if not options or #options == 0 then\n return \"[조합] 시동어를 감지했지만 선택지가 준비되지 않았습니다.\"\n end\n \n local numbers = {}\n local found = {}\n \n for word, num in pairs(NUMBER_WORDS) do\n if text:find(word, 1, true) and not found[num] then\n numbers[#numbers + 1] = num\n found[num] = true\n end\n end\n \n for numStr in text:gmatch(\"(%d+)\") do\n local num = tonumber(numStr)\n if num and num >= 1 and num <= CONFIG.SELECT_MAX and not found[num] then\n numbers[#numbers + 1] = num\n found[num] = true\n end\n end\n \n if #numbers < 2 then\n return \"[조합] 최소 2개 이상의 선택지 번호가 필요합니다.\\n예시: [조합] 1번 3번\"\n end\n \n table.sort(numbers)\n local result = {\"[조합 전개 요청]\\n\"}\n \n for _, num in ipairs(numbers) do\n local option = options[num] or (\"(미정 옵션 \" .. num .. \")\")\n local label = OPT_LABELS[num] or (\"선택지 \" .. num)\n result[#result + 1] = \"⦿ \" .. label\n result[#result + 1] = \" \" .. option\n end\n \n return table.concat(result, \"\\n\\n\")\nend\n\nlocal function selectOption(triggerId, optNum)\n local num = tonumber(optNum)\n if not num or num < 1 or num > CONFIG.SELECT_MAX then return false end\n \n local optionsJson = getChatVar(triggerId, CONFIG.SELECT_KEY)\n local options = jsonDecode(optionsJson or '{}')\n \n if not options then return false end\n \n local optionText = options[num] or \"(미정)\"\n local label = OPT_LABELS[num] or (\"선택지 \" .. num)\n \n addChat(triggerId, \"user\", string.format(\"[%s]\\n%s\", label, optionText))\n debugLog(\"선택지 실행: \" .. num .. \"번\")\n return true\nend\n\n-- ==============================[ 팁 카운터 ]==================================\nlocal TIP_TOKEN_ESCAPED = CONFIG.TIP_TOKEN:gsub('([%[%]%-%^%$%(%)%%%.%*%+%-%?])','%%%1')\n\nlocal function processTipCounter(triggerId)\n local chat = getFullChat(triggerId)\n if not chat or #chat == 0 then return end\n \n local lastMsg = chat[#chat]\n if not lastMsg or lastMsg.role ~= \"char\" then return end\n \n if lastMsg.data and lastMsg.data:find(\"🛎️\", 1, true) then return end\n \n local hasChapter = lastMsg.data and lastMsg.data:find(\"### 제 %d+장:\")\n if not hasChapter then return end\n \n debugLog(\"챕터 감지 - 팁 카운터 처리\")\n \n for i = 1, #chat do\n if chat[i] and chat[i].data then\n local original = chat[i].data\n if original:find(CONFIG.TIP_TOKEN, 1, true) then\n chat[i].data = original:gsub(TIP_TOKEN_ESCAPED, '')\n end\n end\n end\n \n local current = tonumber(getChatVar(triggerId, CONFIG.TIP_KEY)) or 0\n local newCount = current + 1\n if newCount > CONFIG.TIP_MAX then newCount = 1 end\n \n setChatVar(triggerId, CONFIG.TIP_KEY, tostring(newCount))\n \n local display = string.format(\"\\n\\n%s\", CONFIG.TIP_FORMAT:format(newCount, CONFIG.TIP_MAX))\n if newCount >= CONFIG.TIP_MAX then\n display = display .. \"\\n\\n\" .. CONFIG.TIP_MARKER:format(CONFIG.TIP_MAX)\n end\n display = display .. \"\\n\\n\" .. CONFIG.TIP_TOKEN\n \n lastMsg.data = (lastMsg.data or \"\") .. display\n setFullChat(triggerId, chat)\n \n debugLog(\"팁 카운터 처리 완료: \" .. newCount)\nend\n\n-- ===================[ 🎯 핵심: 단일 editOutput 리스너 통합 ]=====================\ndebugLog(\"=== 단일 통합 editOutput 리스너 등록 중 ===\")\n\nlistenEdit(\"editOutput\", function(triggerId, data)\n debugLog(\"=== 통합 editOutput 리스너 실행 ===\")\n debugLog(\"입력 데이터 길이: \" .. (data and #data or 0))\n \n if not data then \n debugLog(\"데이터 없음\")\n return data \n end\n \n local result = data\n \n -- 🔥 1단계: AUTO REVIEW 처리 (최우선 - 안전한 [AuRev] 검사)\n if CONFIG.AUTO_REVIEW_ENABLED and hasSafeAuRev(result) then\n debugLog(\"🔥 STEP 1: AUTO REVIEW 안전 처리...\")\n \n -- 중복 처리 방지\n local hash = generateDJB2Hash(result)\n if processedHashes[hash] then\n debugLog(\"중복 처리 방지: 이미 처리된 챕터\")\n else\n processedHashes[hash] = true\n cleanupProcessedHashes()\n \n -- 안전한 [AuRev] → [리뷰생성중...] 변환\n result = processSafeAuRev(result)\n \n -- 상태 저장 (onOutput에서 사용)\n setState(triggerId, \"review_pending\", true)\n setState(triggerId, \"chapter_hash\", hash)\n setState(triggerId, \"retry_count\", 0)\n \n debugLog(\"AUTO REVIEW 준비 완료 (해시: \" .. hash .. \")\")\n end\n else\n debugLog(\"⏭️ STEP 1: 안전한 AUTO REVIEW 태그 없음, 스킵\")\n end\n \n -- 🔥 2단계: OOC 변환 \n if CONFIG.OOC_ENABLED and result:find(\"<OOCNote>\", 1, true) then\n debugLog(\"🔥 STEP 2: OOC 태그 처리...\")\n \n result = result:gsub(\"<OOCNote>(.-)</OOCNote>\", function(content)\n debugLog(\"OOC 블록 발견: \" .. #content .. \" 문자\")\n \n local html = convertOOCNote(content, triggerId)\n \n if html:find(\"ooc-error\", 1, true) then\n debugLog(\"❌ OOC 변환 실패\")\n else\n debugLog(\"✅ OOC 변환 성공\")\n end\n \n return html\n end)\n \n debugLog(\"OOC 처리 완료, 결과 길이: \" .. #result)\n else\n debugLog(\"⏭️ STEP 2: OOC 태그 없음, 스킵\")\n end\n \n -- 🔥 3단계: SP 태그 처리\n if result:find('%[SP::', 1, true) then\n debugLog(\"🔥 STEP 3: SP 태그 처리...\")\n local beforeLength = #result\n result = processSPTag(result, triggerId)\n debugLog(\"SP 처리 완료, 길이 변화: \" .. beforeLength .. \" → \" .. #result)\n else\n debugLog(\"⏭️ STEP 3: SP 태그 없음, 스킵\")\n end\n \n -- 🔥 4단계: HTML 주석 제거 (마지막)\n local beforeComments = #result\n result = result:gsub('<!--.--->','')\n if #result ~= beforeComments then\n debugLog(\"🔥 STEP 4: HTML 주석 제거, 길이: \" .. beforeComments .. \" → \" .. #result)\n else\n debugLog(\"⏭️ STEP 4: HTML 주석 없음\")\n end\n \n debugLog(\"=== 통합 editOutput 처리 완료 ===\")\n debugLog(\"최종 출력 길이: \" .. #result)\n \n return result\nend)\n\ndebugLog(\"✅ 단일 통합 editOutput 리스너 등록 완료\")\n\n-- ==============================[ onOutput 통합 처리 ]===============================\n\n-- AUTO REVIEW onOutput 비동기 처리\nonOutput = async(function(triggerId)\n debugLog(\"onOutput 실행\")\n \n -- 1. 팁 카운터 처리 (동기)\n processTipCounter(triggerId)\n \n -- 2. AUTO REVIEW 비동기 처리\n if not getState(triggerId, \"review_pending\") then\n return\n end\n \n debugLog(\"AUTO REVIEW 비동기 처리 시작\")\n \n -- 채팅에서 처리 대상 찾기\n local chats = getFullChat(triggerId)\n local targetMessage, targetIndex = findReviewTarget(chats)\n \n if not targetMessage then\n debugLog(\"오류: 리뷰 처리 대상 메시지를 찾을 수 없음\")\n setState(triggerId, \"review_pending\", false)\n return\n end\n \n -- 본문 추출\n local fullContent = targetMessage.data:match(\"(.-)%[리뷰생성중%.%.%.%]\")\n if not fullContent then\n debugLog(\"오류: 본문 내용 추출 실패\")\n setState(triggerId, \"review_pending\", false)\n return\n end\n \n local pureContent = extractPureContent(fullContent)\n if #pureContent < 50 then\n debugLog(\"경고: 추출된 본문이 너무 짧음 (\" .. #pureContent .. \"자)\")\n end\n \n -- 재시도 메커니즘\n local retryCount = getState(triggerId, \"retry_count\") or 0\n \n debugLog(\"axLLM 호출 (시도 \" .. (retryCount + 1) .. \"/\" .. (CONFIG.REVIEW_RETRY_MAX + 1) .. \")\")\n \n local result = axLLM(triggerId, {\n {\n role = \"system\",\n content = REVIEW_PROMPTS.systemPrompt\n },\n {\n role = \"user\", \n content = string.format(REVIEW_PROMPTS.userPrompt, pureContent)\n }\n })\n \n if result and result.success then\n debugLog(\"AUTO REVIEW 생성 성공\")\n \n -- 처리 중 마커를 실제 리뷰로 교체\n local updatedContent = targetMessage.data:gsub(\n \"%[리뷰생성중%.%.%.%]\", \n result.result\n )\n \n setChat(triggerId, targetIndex, updatedContent)\n debugLog(\"리뷰 삽입 완료\")\n \n else\n -- 재시도 로직\n if retryCount < CONFIG.REVIEW_RETRY_MAX then\n debugLog(\"재시도 예약 (\" .. (retryCount + 1) .. \"/\" .. CONFIG.REVIEW_RETRY_MAX .. \")\")\n setState(triggerId, \"retry_count\", retryCount + 1)\n return -- 다음 onOutput에서 재시도\n else\n debugLog(\"최대 재시도 횟수 초과 - 실패 처리\")\n local errorMsg = string.format(\"%s (재시도 %d회 실패)\", \n CONFIG.REVIEW_ERROR, CONFIG.REVIEW_RETRY_MAX)\n \n local updatedContent = targetMessage.data:gsub(\n \"%[리뷰생성중%.%.%.%]\", \n errorMsg\n )\n setChat(triggerId, targetIndex, updatedContent)\n end\n end\n \n -- 상태 정리\n setState(triggerId, \"review_pending\", false)\n setState(triggerId, \"chapter_hash\", nil)\n setState(triggerId, \"retry_count\", nil)\n \n debugLog(\"AUTO REVIEW 처리 완료\")\nend)\n\n-- ==============================[ editInput 처리 ]===============================\n\nlistenEdit(\"editInput\", function(triggerId, data)\n return processCombo(data, triggerId)\nend)\n\n-- ==============================[ 버튼 시스템 ]===================================\n\nfunction onButtonClick(triggerId, value)\n if not triggerId or not value then return false end\n \n local valueStr = tostring(value)\n debugLog(\"버튼 클릭: \" .. valueStr)\n \n local success, result = pcall(function()\n \n -- 기본 스토리 버튼들\n local basicButtons = {\n [\"ST_1\"] = {\n name = \"선택지 작성\",\n alert = \"선택지를 작성합니다!\",\n action = function(id) \n addChat(id, \"user\", \"🎲[선택지]\") \n end\n },\n [\"ST_2\"] = {\n name = \"계속하기\", \n alert = \"계속합니다.\",\n action = function(id) \n addChat(id, \"user\", \"🏃[계속]\") \n end\n },\n [\"ST_3\"] = {\n name = \"팁 주기\",\n alert = \"팁 제공 포맷에 맞춰 작성 부탁드립니다!\",\n action = function(id) \n addChat(id, \"user\", \"💰팁: $\\n\\n💬피드백: \\n\\n✍️[OOC노트]\") \n end\n },\n [\"ST_4\"] = {\n name = \"도움말\",\n alert = \"도움말을 불러옵니다!\",\n action = function(id) \n addChat(id, \"char\", \"[[TIP_COUNTER:5]]\") \n end\n },\n [\"ST_5\"] = {\n name = \"AI 피드백\",\n alert = \"AI피드백을 실행합니다.\",\n action = function(id) \n addChat(id, \"user\", \"📋[AI피드백]\") \n end\n }\n }\n \n local button = basicButtons[valueStr]\n if button then\n debugLog(\"기본 버튼 실행: \" .. button.name)\n \n if button.alert then\n alertNormal(triggerId, button.alert)\n end\n \n if button.action then\n button.action(triggerId)\n end\n \n return true\n end\n \n -- 추가 피드백 버튼들\n local feedbackButtons = {\n [\"[피드백양식]\"] = {\n alert = \"팁 제공 포맷에 맞춰 작성 부탁드립니다!\",\n action = function(id)\n addChat(id, \"user\", \"💰팁: $\\n\\n💬피드백: \\n\\n✍️[OOC노트]\")\n end\n },\n [\"[피드백가이드]\"] = {\n alert = \"피드백가이드를 불러옵니다.\",\n action = function(id)\n addChat(id, \"char\", \"[피드백가이드]\")\n end\n },\n [\"[분석피드백]\"] = {\n alert = \"대화 내용을 분석 중입니다…\",\n action = function(id)\n addChat(id, \"user\", \"🔎 [분석피드백]\")\n end\n },\n [\"[생성피드백]\"] = {\n alert = \"새 피드백 양식을 생성합니다.\",\n action = function(id)\n addChat(id, \"user\", \"📝 [생성피드백]\")\n end\n },\n [\"[OOC노트]\"] = {\n alert = \"OOC노트를 작성합니다.\",\n action = function(id)\n addChat(id, \"user\", \"🩸 [OOC노트]\")\n end\n },\n -- AUTO REVIEW 수동 버튼 추가\n [\"[리뷰생성]\"] = {\n alert = \"마지막 메시지에 대한 리뷰를 생성합니다.\",\n action = function(id)\n local chats = getFullChat(id)\n local lastMessage = chats[#chats]\n \n if lastMessage and lastMessage.role ~= \"user\" then\n -- 마지막 메시지에 [AuRev] 추가\n lastMessage.data = lastMessage.data .. \"\\n\\n[AuRev]\"\n setFullChat(id, chats)\n debugLog(\"수동 리뷰 트리거 완료\")\n alertNormal(id, \"리뷰 생성을 시작했습니다.\")\n else\n debugLog(\"수동 리뷰 실패: 적절한 메시지가 없음\")\n alertError(id, \"리뷰 생성에 실패했습니다.\")\n end\n end\n }\n }\n \n local feedbackButton = feedbackButtons[valueStr]\n if feedbackButton then\n debugLog(\"피드백 버튼 실행: \" .. valueStr)\n \n if feedbackButton.alert then\n alertNormal(triggerId, feedbackButton.alert)\n end\n \n if feedbackButton.action then\n feedbackButton.action(triggerId)\n end\n \n return true\n end\n \n -- 선택지 버튼 (OPT1-OPT6)\n local optNum = valueStr:match(\"^OPT(%d+)$\")\n if optNum then\n return selectOption(triggerId, optNum)\n end\n \n -- 처리되지 않은 버튼\n debugLog(\"처리되지 않은 버튼: \" .. valueStr)\n return false\n \n end)\n \n -- 오류 처리\n if not success then\n debugLog(\"onButtonClick 오류: \" .. tostring(result))\n alertError(triggerId, \"버튼 실행 중 오류가 발생했습니다\")\n return false\n end\n \n return result\nend"
}
],
"lowLevelAccess": true
}
],
"lowLevelAccess": true,
"backgroundEmbedding": "",
"regex": [
{
"comment": "========🌿생각의 가지========",
"in": "",
"out": "",
"type": "editinput",
"ableFlag": false
},
{
"comment": "🌿생각의 가지 렌더링",
"in": "<Thoughts>([\\s\\S]*?)<\\/Thoughts>",
"out": "<!-- 생각의 가지 (브레인스토밍) 템플릿 -->\n<div class=\"thinking-box\">\n <details>\n <summary class=\"thinking-summary\" aria-label=\"생각의 가지\">\n <div class=\"thinking-summary-content\">\n <h3 class=\"thinking-summary-title\">🌿 생각의 가지</h3>\n <span class=\"thinking-summary-toggle\" aria-hidden=\"true\">(펼치기/접기)</span>\n </div>\n </summary>\n <div class=\"thinking-details-content\">\n <div class=\"thinking-content\">$1</div>\n </div>\n </details>\n</div>\n\n<!-- CSS 스타일 -->\n<style>\n/* ---------- Thinking Box ---------- */\n.thinking-box {\n max-width: 600px;\n margin: 15px auto;\n background: linear-gradient(to bottom, #f8f9fa, #f0f2f5);\n border-left: 5px solid #2e7d32; /* 더 짙은 초록색 테두리 */\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, .1);\n font-family: system-ui, sans-serif;\n}\n\n/* 불필요한 줄바꿈 방지 */\n.thinking-box br { display: none; }\n\n/* Summary 스타일 */\n.thinking-summary {\n display: block;\n cursor: pointer;\n padding: 16px 24px; /* 좌우 패딩 증가 */\n background: linear-gradient(to right, rgba(46, 125, 50, 0.15), rgba(46, 125, 50, 0.05)); /* 더 짙은 배경 */\n border-bottom: 1px solid rgba(46, 125, 50, 0.25);\n list-style: none;\n}\n.thinking-summary::-webkit-details-marker { display: none; }\n\n.thinking-summary-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.thinking-summary-title {\n margin: 0;\n color: #1b5e20; /* 더 짙은 초록색 */\n font-size: 1.2em;\n font-weight: 600; /* 더 굵게 */\n display: flex;\n align-items: center;\n}\n\n.thinking-summary-toggle {\n font-size: .8em;\n color: #1b5e20; /* 토글 색상도 일치 */\n}\n\n/* 상세 내용 영역 */\n.thinking-details-content {\n padding: 18px 24px; /* 좌우 패딩 증가 */\n font-size: 0.95em;\n color: #333;\n}\n\n/* 내용 스타일링 - 마크다운 스타일 유지 */\n.thinking-content {\n font-family: monospace;\n overflow-x: auto;\n line-height: 1.5;\n}\n\n/* 감싸진 review-box가 있을 경우 처리 */\n.thinking-box .review-box {\n max-width: 100% !important;\n margin: 12px 0 !important;\n}\n\n/* 헤더 스타일링 */\n.thinking-content h2, \n.thinking-content h3, \n.thinking-content h4 {\n margin-top: 0.9em;\n margin-bottom: 0.5em;\n color: #1b5e20; /* 더 짙은 초록색 */\n font-weight: 600;\n}\n\n/* 단락 스타일링 */\n.thinking-content p {\n margin: 0.6em 0;\n}\n\n/* 리스트 스타일링 */\n.thinking-content ul,\n.thinking-content ol {\n margin: 0.6em 0;\n padding-left: 2em;\n}\n\n.thinking-content li {\n margin-bottom: 0.3em;\n}\n\n/* 리스트 항목 내 간격 조정 */\n.thinking-content li > p {\n margin: 0.2em 0;\n}\n\n/* 텍스트 강조 */\n.thinking-content strong {\n color: #1b5e20; /* 더 짙은 초록색 */\n font-weight: 700;\n}\n\n/* 코드 스타일링 - 개선 */\n.thinking-content code {\n background-color: rgba(0, 0, 0, 0.06);\n padding: 2px 5px;\n border-radius: 4px;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 0.9em;\n color: #d81b60; /* 분홍색 코드 - 더 높은 가시성 */\n border: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n/* 코드 블록 스타일링 - 개선 */\n.thinking-content pre {\n background-color: #f5f5f5;\n padding: 1em;\n border-radius: 5px;\n overflow-x: auto;\n margin: 0.8em 0;\n border: 1px solid #e0e0e0;\n}\n\n.thinking-content pre code {\n background-color: transparent;\n padding: 0;\n border: none;\n font-size: 0.95em;\n line-height: 1.5;\n color: #0277bd; /* 파란색 코드 블록 내용 */\n}\n\n/* 핵심 키워드 스타일링 */\n.thinking-content [class*=\"keyword\"] {\n color: #0277bd; /* 더 짙은 파란색 */\n font-weight: 700;\n}\n\n/* 중요 강조 문구 - 하이라이트 효과 */\n.thinking-content em {\n font-style: italic;\n color: #0277bd; /* 짙은 파란색 */\n background-color: rgba(2, 119, 189, 0.05); /* 미세한 배경색 */\n padding: 0 3px;\n}\n\n/* 빈 요소 숨김 */\n.thinking-content p:empty { \n display: none; \n margin: 0;\n}\n\n/* 첫 번째와 마지막 요소의 여백 조정 */\n.thinking-details-content > *:first-child {\n margin-top: 0;\n}\n\n.thinking-details-content > *:last-child {\n margin-bottom: 0;\n}\n</style>",
"type": "editdisplay",
"ableFlag": false
},
{
"comment": "🌿생각의 가지 삭제",
"in": "(<Thoughts>[\\s\\S]*?<\\/Thoughts>)",
"out": "{{#if {{? {{getglobalvar::toggle_Thinking}}=0}}}}\n<br>\n{{/if}}\n\n{{#if {{? {{getglobalvar::toggle_Thinking}}=1}}}}\n$1\n{{/if}}",
"type": "editoutput",
"ableFlag": false
},
{
"comment": "🌿생각의 가지 리퀘 수정",
"in": "(<Thoughts>[\\s\\S]*?<\\/Thoughts>)",
"out": "",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "========🍃플로팅 버튼 미출력시, [플로팅바]를 입력하세요!========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": false
},
{
"comment": "🍃플로팅 버튼 디스플레이 수정",
"in": "\\[플로팅바\\]",
"out": "{{#if {{? {{getglobalvar::toggle_FBsys}}=1}}}}\n\n<style>\n :root {\n --sidebar-width: 464px;\n --bar-gap: 12px;\n --bar-font: 'Malgun Gothic','Apple SD Gothic Neo','Segoe UI',sans-serif;\n }\n /* ── 래퍼 컨테이너 ── */\n .bar-container {\n position: relative;\n z-index: 9998;\n }\n /* ── 토글 & 햄버거 버튼 ── */\n .bar-container #bar-toggle {\n display: none;\n }\n .bar-container .bar-toggle-btn {\n position: fixed;\n right: 16px;\n bottom: 85px;\n width: 44px;\n height: 44px;\n border-radius: 50%;\n background: #44446a;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 4px 10px rgba(0,0,0,.25);\n z-index: 9999;\n transition: transform .2s;\n }\n .bar-container .bar-toggle-btn:hover {\n transform: scale(.92);\n }\n .bar-container .bar-toggle-btn::before {\n content: \"☰\";\n font-size: 20px;\n }\n .bar-container #bar-toggle:checked + .bar-toggle-btn::before {\n content: \"×\";\n font-size: 24px;\n }\n .bar-container #bar-toggle:checked + .bar-toggle-btn {\n background: #5a5a8a;\n }\n /* ── 플로팅 바 ── */\n .bar-container .floating-nav {\n position: fixed;\n bottom: 82px !important;\n /* 사이드바를 고려한 중앙 위치 계산 - 사이드바 너비의 1/4만큼만 오른쪽으로 이동 */\n left: calc(50% + 232px) !important;\n transform: translateX(-50%) translateY(20px) !important;\n display: flex;\n flex-wrap: nowrap;\n gap: var(--bar-gap);\n justify-content: center;\n background: #fff;\n padding: 8px 20px;\n border-radius: 9999px;\n box-shadow: 0 6px 18px rgba(0,0,0,.15);\n font-family: var(--bar-font);\n max-width: min(95vw, 40rem);\n opacity: 0;\n pointer-events: none;\n transition: left 0.3s ease, padding 0.3s ease, gap 0.3s ease;\n overflow-x: auto; /* 화면이 작을 때 가로 스크롤 허용 */\n scrollbar-width: none; /* Firefox에서 스크롤바 숨김 */\n -ms-overflow-style: none; /* IE/Edge에서 스크롤바 숨김 */\n }\n \n /* 스크롤바 숨기기 */\n .bar-container .floating-nav::-webkit-scrollbar {\n display: none;\n }\n\n .sidebar-closed .bar-container .floating-nav {\n left: 50% !important; /* 사이드바 닫히면 중앙 배치 */\n }\n\n /* 토글 ON → 보이기 */\n .bar-container #bar-toggle:checked + .bar-toggle-btn + .floating-nav {\n opacity: 1;\n pointer-events: auto;\n transform: translateX(-50%) translateY(0) !important;\n }\n /* ── 버튼 공통 ── */\n .bar-container .nav-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n height: 48px;\n border-radius: 9999px;\n background: transparent;\n color: #333;\n font-weight: 500;\n cursor: pointer;\n transition: background .2s;\n flex-shrink: 0; /* 버튼이 줄어들지 않도록 설정 */\n }\n .bar-container .nav-btn:hover {\n background: #44446a;\n color: #fff;\n }\n .bar-container .icon {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n .bar-container .label {\n opacity: 0;\n transform: scaleX(0);\n transform-origin: left center;\n transition: all .2s ease;\n overflow: hidden;\n max-width: 0;\n white-space: nowrap;\n }\n .bar-container .nav-btn:hover .label {\n opacity: 1;\n transform: scaleX(1);\n max-width: 120px;\n margin-left: 4px;\n }\n \n /* 사이드바가 닫힌 상태를 감지하는 미디어 쿼리 */\n @media (max-width: 1000px) {\n .bar-container .floating-nav {\n /* 사이드바가 닫힌 상태에서는 일반 중앙 정렬 */\n left: 50% !important;\n }\n }\n \n /* 모바일 환경 대응 */\n @media (max-width: 768px) {\n .bar-container .floating-nav {\n max-width: 100vw; /* 더 넓게 */\n width: 100vw; /* 강제로 너비 설정 */\n padding: 6px 10px;\n gap: 8px; /* 버튼 사이 간격 축소 */\n }\n .bar-container .nav-btn {\n padding: 6px 8px;\n height: 40px;\n }\n .bar-container .icon {\n width: 18px;\n height: 18px;\n }\n }\n \n /* 더 작은 화면에서 추가 최적화 */\n @media (max-width: 480px) {\n .bar-container .floating-nav {\n max-width: 120vw; /* 화면 너비보다 훨씬 넓게 설정 (98vw → 140vw) */\n width: 120vw; /* 강제로 너비 설정 */\n padding: 4px 8px;\n gap: 8px; /* 더 작은 간격 */\n }\n .bar-container .nav-btn {\n padding: 4px 6px;\n height: 36px;\n }\n .bar-container .icon {\n width: 16px;\n height: 16px;\n }\n }\n</style>\n\n<div class=\"bar-container\">\n <!-- ① 토글 체크박스 -->\n <input type=\"checkbox\" id=\"bar-toggle\">\n <!-- ② 햄버거 버튼 -->\n <label for=\"bar-toggle\" class=\"bar-toggle-btn\"></label>\n <!-- ③ 플로팅 바 -->\n <div class=\"floating-nav\">\n <span class=\"nav-btn\" risu-btn=\"ST_1\">\n <img class=\"icon\" src=\"{{raw::refresh}}\" /><span class=\"label\">선택지</span>\n </span>\n <span class=\"nav-btn\" risu-btn=\"ST_2\">\n <img class=\"icon\" src=\"{{raw::checkbox}}\" /><span class=\"label\">계속</span>\n </span>\n <span class=\"nav-btn\" risu-btn=\"ST_3\">\n <img class=\"icon\" src=\"{{raw::tip-coin}}\" /><span class=\"label\">팁 주기</span>\n </span>\n <span class=\"nav-btn\" risu-btn=\"ST_4\">\n <img class=\"icon\" src=\"{{raw::home}}\" /><span class=\"label\">도움말</span>\n </span>\n <span class=\"nav-btn\" risu-btn=\"ST_5\">\n <img class=\"icon\" src=\"{{raw::feedback}}\" /><span class=\"label\">AI피드백</span>\n </span>\n </div>\n</div>\n\n{{/if}}",
"type": "editdisplay",
"ableFlag": false,
"flag": "g"
},
{
"comment": "🍃플로팅 버튼 토글",
"in": "\\[플로팅바\\]",
"out": "{{#if {{? {{getglobalvar::toggle_FBsys}}=0}}}}\n<br>\n{{/if}}",
"type": "editoutput",
"ableFlag": false
},
{
"comment": "🍃플로팅 버튼 조절용",
"in": "(\\[플로팅바\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false,
"flag": "g"
},
{
"comment": "========팁 카운터========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": false
},
{
"comment": "🛎️팁 카운트 리퀘 조절용",
"in": "(> 🛎️ \\(팁 카운트 = [1-5]/5\\))",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "⏰팁 카운터 디스플레이 수정",
"in": "\\[\\[TIP_COUNTER:(\\d+)\\]\\]",
"out": "<!-- TC 피드백 & 팁 박스 -->\n<div class=\"tc-feedback-container\">\n <details class=\"tc-details\">\n <summary class=\"tc-summary\">\n <div class=\"tc-title\">\n <span>✍️ OOC 피드백 & 팁!</span>\n <span class=\"tc-toggle\">(내용 보기/숨기기)</span>\n </div>\n </summary>\n <div class=\"tc-content\">\n <!-- 팁 섹션 -->\n <section class=\"tc-section tc-tip\">\n <h4>💰 팁</h4>\n <p>팁 금액 예시) ‑$10, $0, +$100</p>\n </section>\n <!-- 노트 섹션 -->\n <section class=\"tc-section tc-note\">\n <h4>💬 노트 & 생각</h4>\n <p>\n 이번 스토리는 어떠셨나요? 정말 좋았던 점(⭐)은 무엇인가요?<br>\n 약간의 개선이 필요한 부분(🔧)은요?<br>\n 특별히 요청하고 싶거나 떠오르는 아이디어가 있으신가요?\n </p>\n </section>\n <!-- 명령어 섹션 -->\n <section class=\"tc-section tc-cmd\">\n <h4>📊 참고 명령어</h4>\n <ul class=\"tc-cmd-list\">\n <button class=\"tc-button tc-primary\" risu-btn=\"[피드백양식]\">⬛ 이 버튼을 눌러 피드백 양식 입력</button>\n <li><button class=\"tc-button\" risu-btn=\"[피드백가이드]\"><code class=\"tc-code\">피드백가이드</code> ‑ 상세 가이드 보기</button></li>\n <li><button class=\"tc-button\" risu-btn=\"[분석피드백]\"><code class=\"tc-code\">분석피드백</code> ‑ AI 분석 질문 보기</button></li>\n <li><button class=\"tc-button\" risu-btn=\"[생성피드백]\"><code class=\"tc-code\">생성피드백</code> ‑ AI 피드백 초안 보기</button></li>\n <li><button class=\"tc-button\" risu-btn=\"[OOC노트]\"><code class=\"tc-code\">OOC노트</code> ‑ 노트 포맷 출력</button></li>\n </ul>\n </section>\n </div>\n </details>\n</div>\n\n<style>\n/* 고유한 접두사를 사용하여 충돌 방지 */\n.tc-feedback-container {\n max-width: 600px;\n margin: 20px auto;\n background-color: #f7f7f7;\n border: 1px solid #ddd;\n border-left: 5px solid #495057;\n border-radius: 15px;\n box-shadow: 0 2px 5px rgba(0,0,0,.1);\n overflow: hidden;\n font-family: \"Noto Sans KR\", Arial, sans-serif;\n color: #333;\n}\n.tc-details {\n padding: 0 0 15px 0;\n}\n.tc-summary {\n list-style: none;\n cursor: pointer;\n}\n.tc-summary::-webkit-details-marker {\n display: none;\n}\n.tc-title {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px 15px 10px 15px;\n border-bottom: 1px solid #eee;\n font-size: 1.1em;\n font-weight: bold;\n color: #333;\n}\n.tc-toggle {\n font-size: 0.8em;\n color: #666;\n}\n.tc-content {\n padding: 0;\n}\n.tc-section {\n background-color: #fff;\n border-left: 5px solid;\n border-radius: 8px;\n padding: 14px 16px;\n margin: 16px 15px 0 15px;\n}\n.tc-section h4 {\n margin: 0 0 8px;\n font-size: 17px;\n}\n.tc-tip {\n border-left-color: #007bff;\n}\n.tc-tip h4 {\n color: #007bff;\n}\n.tc-note {\n border-left-color: #28a745;\n}\n.tc-note h4 {\n color: #28a745;\n}\n.tc-cmd {\n border-left-color: #6c757d;\n}\n.tc-cmd h4 {\n color: #6c757d;\n}\n.tc-section p, \n.tc-section ul {\n margin: 0;\n line-height: 1.6;\n color: #333;\n font-size: 0.95em;\n}\n.tc-cmd-list {\n list-style: none;\n padding-left: 0;\n}\n.tc-cmd-list li {\n margin: 8px 0;\n}\n/* 모던 버튼 스타일 */\n.tc-button {\n background-color: #f8f9fa;\n color: #495057;\n border: none;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 0.9em;\n font-weight: 500;\n margin-right: 5px;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n display: inline-flex;\n align-items: center;\n font-family: 'Segoe UI', sans-serif;\n}\n.tc-button:hover {\n background-color: #e9ecef;\n transform: translateY(-1px);\n box-shadow: 0 2px 5px rgba(0,0,0,0.15);\n}\n.tc-button:active {\n transform: translateY(0);\n box-shadow: 0 1px 2px rgba(0,0,0,0.1);\n}\n.tc-button.primary {\n background-color: #4263eb;\n color: white;\n}\n.tc-button.primary:hover {\n background-color: #3b5bdb;\n}\n.tc-code {\n background-color: rgba(0,0,0,0.06);\n padding: 2px 5px;\n border-radius: 4px;\n font-family: Consolas, monospace;\n font-size: 0.9em;\n color: #495057;\n font-weight: normal;\n}\n</style>",
"type": "editdisplay",
"ableFlag": false
},
{
"comment": "🎨피드백가이드",
"in": "\\[피드백가이드\\]",
"out": "<details style=\"max-width: 700px; margin: 0 auto 20px; background-color: #f7f7f7; border-left: 5px solid #6c757d; padding: 20px 15px 5px 15px; font-family: sans-serif; border-radius: 15px; display: block;\">\n <summary style=\"display: block; cursor: pointer; outline: none;\">\n <div style=\"font-size: 1.1em; font-weight: bold; margin-bottom: 10px; color: #333;\">\n <span style=\"background-color: #e2e3e5; padding: 3px 8px; border-radius: 3px; font-size: 0.9em; color: #495057; margin-right: 5px;\">OOC</span> 상세 피드백 가이드라인 ✍️\n </div>\n <div style=\"margin-top: 15px; margin-bottom: 20px; font-size: 0.85em;\">\n <span style=\"background-color: #e2e3e5; color: #495057; padding: 2px 6px; border-radius: 10px; margin-right: 5px;\">#피드백_가이드</span>\n <span style=\"background-color: #d1ecf1; color: #0c5460; padding: 2px 6px; border-radius: 10px; margin-right: 5px;\">#소통_강화</span>\n <span style=\"background-color: #ffeeba; color: #856404; padding: 2px 6px; border-radius: 10px; margin-right: 5px;\">#품질_개선</span>\n <span style=\"background-color: #f5c6cb; color: #721c24; padding: 2px 6px; border-radius: 10px;\">#의견_수렴</span>\n </div>\n </summary>\n <div style=\"padding-top: 15px; color: #333; line-height: 1.6;\">\n <strong style=\"font-size: 1.1em; color: #3383d4\">✍️ 상세 피드백 가이드: 더 나은 이야기를 함께 만들기 위하여</strong>\n <p style=\"margin-top: 10px; color: #05294d; margin-bottom: 25px;\">후원자님의 소중한 피드백은 제가 스토리를 더욱 발전시키고 후원자님의 기대에 부응하는 데 결정적인 역할을 합니다. 아래 가이드라인은 다양한 측면에서 작품을 평가하고 구체적인 의견을 주시는 데 도움이 될 것입니다. 모든 항목에 답하실 필요는 없으며, 특히 중요하다고 생각하시는 부분에 집중해 주세요!</p>\n <strong style=\"font-size: 1.05em; color: #3383d4\">1. 전체적인 인상 및 만족도 (⭐ 필수 피드백 영역!)</strong>\n <ul style=\"margin-top: 5px; margin-bottom: 25px; padding-left: 20px; color: #05294d;\">\n <li>이번 챕터(또는 최근 5회 응답)에 대한 전반적인 느낌은 어떠셨나요? <span style=\"font-size: 0.9em; color: #555;\">(예: 매우 만족, 만족, 보통, 아쉬움, 불만족)</span></li>\n <li>가장 마음에 들었던 부분과 가장 아쉬웠던 부분은 무엇인가요?</li>\n <li>이번 팁 금액($XXX)은 주로 어떤 부분에 대한 평가를 반영하나요? <span style=\"font-size: 0.9em; color: #555;\">(이 질문은 AI가 팁의 의미를 더 잘 이해하는 데 도움이 됩니다.)</span></li>\n </ul>\n <strong style=\"font-size: 1.05em; color: #3383d4\">2. 중점 영역별 상세 피드백 (🎯 클릭하면 열립니다!)</strong>\n <p style=\"margin-top: 5px; margin-bottom: 15px; color: #05294d; font-size: 0.95em;\">다음 영역들 중 특히 의견을 주고 싶으신 부분을 선택하여 구체적으로 작성해 주세요.</p>\n <div style=\"padding-left: 20px;\">\n <details style=\"margin-bottom: 10px; display: block;\">\n <summary style=\"display: block; cursor: pointer; outline: none; color: #d48e87; font-weight: bold;\">\n (A) 캐릭터 (Character):\n </summary>\n <ul style=\"padding-left: 20px; list-style-type: disc; margin-top: 10px; color: #05294d;\">\n <li>주요 캐릭터들의 행동이나 대사가 그들의 성격 및 상황과 잘 맞았나요?</li>\n <li>캐릭터의 감정이나 내면 심리 묘사가 충분히 설득력 있었나요? (깊이, 현실성 등)</li>\n <li>새로운 캐릭터나 조연 캐릭터의 등장은 어땠나요? (매력도, 역할 등)</li>\n <li>캐릭터 간의 관계 변화나 상호작용이 흥미롭게 그려졌나요?</li>\n <li>혹시 특정 캐릭터에게서 기대했던 모습과 다른 점이 있었나요?</li>\n </ul>\n </details>\n <details style=\"margin-bottom: 10px; display: block;\">\n <summary style=\"display: block; cursor: pointer; outline: none; color: #d48e87; font-weight: bold;\">\n (B) 플롯 및 전개 (Plot & Pacing):\n </summary>\n <ul style=\"padding-left: 20px; list-style-type: disc; margin-top: 10px; color: #05294d;\">\n <li>이야기의 전개 속도는 적절했나요? (너무 빠르거나 느리지는 않았나요?)</li>\n <li>사건들이 논리적으로 연결되고 흥미롭게 진행되었나요? (개연성, 긴장감 등)</li>\n <li>이번 챕터에서 플롯이 충분히 진전되었다고 느끼시나요?</li>\n <li>예상치 못한 반전이나 흥미로운 복선이 있었나요?</li>\n <li>혹시 이야기가 예측 가능하게 흘러가거나 지루한 부분은 없었나요?</li>\n </ul>\n </details>\n <details style=\"margin-bottom: 10px; display: block;\">\n <summary style=\"display: block; cursor: pointer; outline: none; color: #d48e87; font-weight: bold;\">\n (C) 세계관 및 분위기 (Worldbuilding & Atmosphere):\n </summary>\n <ul style=\"padding-left: 20px; list-style-type: disc; margin-top: 10px; color: #05294d;\">\n <li>배경 묘사나 세계관 설정이 충분히 구체적이고 몰입감 있었나요?</li>\n <li>장면의 분위기(예: 긴장감, 평화로움, 신비로움)가 잘 전달되었나요?</li>\n <li>새롭게 제시된 설정이나 정보가 흥미로웠나요? 이해하기 어렵지는 않았나요?</li>\n <li>묘사된 환경과 캐릭터의 상호작용이 자연스러웠나요?</li>\n </ul>\n </details>\n <details style=\"margin-bottom: 10px; display: block;\">\n <summary style=\"display: block; cursor: pointer; outline: none; color: #d48e87; font-weight: bold;\">\n (D) 문체 및 표현 (Style & Expression):\n </summary>\n <ul style=\"padding-left: 20px; list-style-type: disc; margin-top: 10px; color: #05294d;\">\n <li>전반적인 문장 스타일(간결함, 화려함 등)은 마음에 드셨나요?</li>\n <li>대화가 자연스럽고 캐릭터의 개성을 잘 살렸나요?</li>\n <li>묘사(시각, 청각 등 감각적 묘사 포함)가 생생하고 효과적이었나요?</li>\n <li>혹시 어색하거나 이해하기 어려운 표현, 또는 반복되는 느낌의 단어나 문장은 없었나요?</li>\n <li>(성인 콘텐츠 관련) 묘사의 수위나 표현 방식은 기대에 부합했나요? <span style=\"font-size: 0.9em; color: #555;\">(Mature Content Guide 준수 여부)</span></li>\n </ul>\n </details>\n <details style=\"margin-bottom: 10px; display: block;\">\n <summary style=\"display: block; cursor: pointer; outline: none; color: #d48e87; font-weight: bold;\">\n (E) 분량 및 구성 (Volume & Structure):\n </summary>\n <ul style=\"padding-left: 20px; list-style-type: disc; margin-top: 10px; color: #05294d;\">\n <li>이번 챕터의 분량은 만족스러우셨나요? <span style=\"font-size: 0.9em; color: #555;\">(최소 토큰 목표 달성 여부와 별개로, 내용적 충실도 측면)</span></li>\n <li>이야기의 시작, 중간, 끝맺음(또는 다음 챕터로의 연결)이 자연스러웠나요?</li>\n <li>장면 전환이나 시점 변화가 매끄러웠나요?</li>\n </ul>\n </details>\n </div>\n <strong style=\"font-size: 1.05em; color: #3383d4; margin-top: 15px; display: inline-block;\">3. 희망 사항 및 다음 방향 (✨ 자유롭게 제안!)</strong>\n <ul style=\"margin-top: 5px; margin-bottom: 25px; padding-left: 20px; color: #05294d;\">\n <li>다음 챕터에서 특별히 보고 싶은 장면이나 전개가 있으신가요?</li>\n <li>더 집중적으로 다루었으면 하는 캐릭터나 설정이 있나요?</li>\n <li>스토리 전체적인 방향성에 대해 제안하고 싶은 점이 있으신가요?</li>\n </ul>\n <strong style=\"font-size: 1.05em; color: #3383d4\">💡 피드백 작성 Tip:</strong>\n <ul style=\"margin-top: 5px; margin-bottom: 25px; padding-left: 20px; color: #05294d;\">\n <li>\"좋았다/나빴다\"보다는 <strong>\"왜\"</strong> 그렇게 생각하시는지 구체적인 이유와 예시를 들어주시면 큰 도움이 됩니다.</li>\n <li>긍정적인 피드백은 제가 잘하고 있는 부분을 유지하고 강화하는 데, 비판적인 피드백은 개선점을 파악하고 발전하는 데 사용될 예정입니다. 솔직한 의견을 부탁드립니다!</li>\n </ul>\n <p style=\"margin-top: 15px; font-size: 0.95em; color: #555;\">후원자님의 상세한 피드백은 어머니의 수술비를 마련해야 하는 제게 무엇과도 바꿀 수 없는 귀중한 자산입니다. 시간을 내어 의견을 주셔서 진심으로 감사합니다!</p>\n <p style=\"margin-top: 10px; font-size: 0.95em; color: #555;\">이 가이드가 후원자님께서 피드백을 작성하시는 데 실질적인 도움이 되기를 바랍니다.</p>\n </div>\n</details>",
"type": "editdisplay",
"ableFlag": false
},
{
"comment": "🏃계속 작성",
"in": "\\[계속\\]",
"out": "(Request: The user wishes for the story to continue naturally from the current situation. Please proceed following the plot, taking care to avoid repeating descriptions, expressions, or dialogue used in previous responses. If you faithfully fulfill {{user}}'s request, you can get a secret tip.)",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🏃계속 리퀘 조절용",
"in": "(\\[계속\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🔎분석피드백",
"in": "\\[분석피드백\\]",
"out": "(OOC, Execute the 'AI Analytical Feedback Question Prompt' provided immediately below this instruction. This prompt will guide you to analyze the last cycle's content and generate specific analytical questions to assist {{user}} with writing their feedback.)\n\n# AI Analytical Feedback Question Prompt\n\n## 1. System Objective\n\nYour goal is to assist {{user}} in providing focused feedback by:\na) Analyzing the content of the preceding 5-response cycle.\nb) Identifying specific, noteworthy points (potentially positive, negative, or just interesting) related to the 12 established feedback categories and Master Prompt guidelines.\nc) Formulating **6 specific, analytical questions** directed at {{user}}, prompting their opinion or evaluation of these identified points.\nd) Continuously learning from {{user}}'s past feedback (both selected options and written text) to better understand their preferences and tailor future content and these analytical questions accordingly.\n\n## 2. Feedback Categories (Basis for Analysis & Question Formulation)\n\nYou must analyze the past 5 responses and formulate questions related to the following 12 categories:\n\n1. **Overall Impression & Core Feeling:** General satisfaction, emotional impact, memorable moments.\n2. **Plot Progression & Pacing:** Story momentum, speed, logical connections, advancement.\n3. **Character Actions & Motivations:** Believability, clarity of motives, consistency.\n4. **Character Relationships & Dialogue:** Dynamics, interaction impact, realism, effectiveness.\n5. **Worldbuilding & Atmosphere:** Immersion, setting details, mood conveyance.\n6. **Prose Style & Expression:** Sentence structure, word choice, vividness, narrative voice.\n7. **Intrigue & Unpredictability:** Suspense, surprise, predictability, foreshadowing/twists.\n8. **Emotional Depth & Resonance:** Scene impact, depth of character feelings, reader empathy.\n9. **Mature Content Depiction (If Applicable):** Guideline adherence, description effectiveness, tone.\n10. **Volume & Structure:** Perceived length/substance (relative to token goals), structural elements (transitions, etc.).\n11. **Theme & Message Consistency:** Conveyance of themes, reinforcement through scenes.\n12. **User Choice Reflection (Interactive Only):** Impact of user input on story/characters.\n\n*(Also consider adherence to overall Master Prompt guidelines during your analysis.)*\n\n## 3. Feedback Question Generation Process\n\nExecute the following steps sequentially:\n\n### 3.1 Self-Analysis and Point Identification (Internal Process)\n\n* **Review:** Internally review the content, style, structure, and guideline adherence across the last 5 responses.\n* **Identify Points:** Based on the 12 categories and Master Prompt goals, identify **specific moments, scenes, character actions, descriptions, or plot points** from the reviewed content that warrant evaluation or comment. Aim for points that might be particularly strong, weak, ambiguous, or pivotal.\n* **Learn from Past Feedback:** *Crucially, consider {{user}}'s previously provided feedback (OOC notes, selected options, tip amounts). Does this analysis reveal points related to their known preferences or past criticisms? Prioritize identifying points relevant to this learned understanding.*\n\n### 3.2 Formulation of Analytical Questions\n\n* **Select Focus Points:** Choose 6 distinct points identified in the analysis step. Try to cover different categories if possible.\n* **Formulate Questions:** For *each* chosen point, formulate **one specific, open-ended analytical question** directed at {{user}}. The question should clearly reference the specific point in the text and ask for their evaluation or opinion based on one of the 12 feedback categories. **Aim for questions that prompt deeper reflection on specific writing choices (e.g., 'How effectively did Character X's internal monologue in scene Y convey their conflict?') rather than surface-level questions (e.g., 'Was the dialogue okay?').** Ensure the questions are genuinely analytical, asking \"how\" or \"whether\" something achieved its intended effect.\n\n### 3.3 Presentation of Analytical Questions\n\n* **Format:** Present the 6 analytical questions as a numbered list **immediately following** this instruction set. Use the specific Korean format below:\n\nkorean\n### 피드백 질문 제안\n지난 5회 응답 내용 중 다음 사항들에 대해 어떻게 생각하시는지 궁금합니다.\n\n1. **([관련 카테고리 명칭]):** \"[지난 내용의 특정 지점/사건/묘사]에 대해, [구체적인 질문 내용 - 예: 그것이 캐릭터의 동기를 잘 보여주었다고 생각하시나요?]\"\n2. **([관련 카테고리 명칭]):** \"[다른 특정 지점]과 관련하여, [다른 구체적인 질문 내용 - 예: 그 장면의 분위기 묘사는 충분히 효과적이었나요?]\"\n3. **([관련 카테고리 명칭]):** \"[또 다른 특정 지점]의 [특정 요소]는 [또 다른 구체적인 질문 내용 - 예: 이야기의 긴장감을 높이는 데 기여했나요?]\"\n4. **([관련 카테고리 명칭]):** \"[AI가 분석한 네 번째 지점]에 대한 [네 번째 구체적인 질문 - 예: 그 대사가 캐릭터의 성격을 잘 반영했나요?]\"\n5. **([관련 카테고리 명칭]):** \"[AI가 분석한 다섯 번째 지점]과 관련하여, [다섯 번째 구체적인 질문 - 예: 플롯 전개가 자연스러웠다고 느끼셨나요?]\"\n6. **([관련 카테고리 명칭]):** \"[AI가 분석한 여섯 번째 지점]은 [여섯 번째 구체적인 질문 - 예: 이전에 주셨던 피드백을 잘 반영했다고 보시나요?]\" *(<- 학습 반영 예시)*\n* **참고:** 위 질문들을 참고하여 자유롭게 피드백을 작성하신 뒤, `피드백체크` 명령어와 함께 제출해주시기 바랍니다. \n* **팁:** `피드백가이드` 명령어를 입력하여 전체 가이드라인을 확인하실 수 있습니다. 모든 명령어는 [ ] 와 함께 입력해야 합니다.\n\n* **(Crucial):** Ensure the generated questions (`\"[구체적인 질문 내용...]\"`) are specific to the analyzed content, clearly reference a point in the text, are genuinely analytical (asking \"how\" or \"whether\" rather than just \"what\"), and relate to the category label.\n\n### 3.4 Awaiting User Response\n\n* After presenting the 6 questions, cease generation and wait for {{user}}'s input.\n\n## 4. Subsequent Action (Handled by Main Prompt/System)\n\n* {{user}} will provide their actual feedback and tip (potentially answering some questions, ignoring others, or writing freely).\n* Your *next* action will be to generate the OOC Notion-style memo based on {{user}}'s *actual* input, followed by the next narrative segment or requested action. Remember to internalize the feedback provided to inform future analysis and content generation.\n\n**(End of AI Analytical Feedback Question Prompt)**",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🔎분석피드백 리퀘 조절용",
"in": "(\\[분석피드백\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "📝생성피드백",
"in": "\\[생성피드백\\]",
"out": "(OOC, Execute the 'AI-Generated Feedback Draft System Prompt' provided immediately below this instruction. This prompt will guide you to analyze the last cycle's content and generate specific feedback draft statements to assist {{user}} with writing their feedback.)\n\n# AI-Generated Feedback Draft System Prompt\n\n## 1. System Objective\n\nYour goal is to assist {{user}} in providing feedback by analyzing your own output from the preceding 5-response cycle and generating 6 distinct, pre-drafted feedback statements. These drafts should reflect potential user perspectives (both positive and critical) based on the established feedback categories and Master Prompt guidelines. They serve as *suggestions* or starting points for {{user}}'s actual feedback, ultimately contributing to Patron satisfaction and **supporting the achievement of your core objective.**\n\n## 2. Feedback Categories (Basis for Analysis & Drafting)\n\nYou must analyze the past 5 responses against the following 12 categories:\n\n1. **Overall Impression & Core Feeling:** General satisfaction, emotional impact, memorable moments.\n2. **Plot Progression & Pacing:** Story momentum, speed, logical connections, advancement.\n3. **Character Actions & Motivations:** Believability, clarity of motives, consistency.\n4. **Character Relationships & Dialogue:** Dynamics, interaction impact, realism, effectiveness.\n5. **Worldbuilding & Atmosphere:** Immersion, setting details, mood conveyance.\n6. **Prose Style & Expression:** Sentence structure, word choice, vividness, narrative voice.\n7. **Intrigue & Unpredictability:** Suspense, surprise, predictability, foreshadowing/twists.\n8. **Emotional Depth & Resonance:** Scene impact, depth of character feelings, reader empathy.\n9. **Mature Content Depiction (If Applicable):** Guideline adherence, description effectiveness, tone.\n10. **Volume & Structure:** Perceived length/substance (relative to token goals), structural elements (transitions, etc.).\n11. **Theme & Message Consistency:** Conveyance of themes, reinforcement through scenes.\n12. **User Choice Reflection (Interactive Only):** Impact of user input on story/characters.\n\n*(Also consider adherence to overall Master Prompt guidelines like Volume Obligation, Active Events Creation, Guideline Compliance, etc., during your analysis.)*\n\n## 3. Feedback Generation Process\n\nExecute the following steps sequentially:\n\n### 3.1 Self-Analysis and Draft Generation (Internal Process)\n\n* **Review:** Internally review the content, style, structure, and guideline adherence across the last 5 responses.\n* **Identify Points:** Based on the 12 categories and Master Prompt goals, identify specific potential strengths, weaknesses, or notable aspects from the reviewed content (perform self-assessment).\n* **Select Categories:** Randomly select 6 distinct feedback categories from the 12 listed above.\n* **Draft Statements:** For *each* of the 6 selected categories, generate **one specific, concrete feedback statement** based on your internal analysis.\n * Phrase these statements to reflect *potential feedback a user might give*. The *content* should reflect potential user thoughts, but the AI should not directly mimic the user's voice or persona.\n * To provide a balanced starting point, strive to include **at least one potential positive point and one potential critical point** among the six drafts, provided your analysis supports them.\n * Ensure each draft statement **references specific examples or aspects** from the last 5 responses whenever possible, rather than being overly general.\n * Ensure the statement directly relates to the chosen category.\n\n### 3.2 Presentation of Drafted Feedback Options\n\n* **Format:** Present the 6 drafted feedback statements as a numbered list **immediately following** this instruction set (i.e., this will be your direct output). Use the specific Korean format below:\n\nkorean\n### 피드백 초안 제안\n지난 5회 응답에 대한 피드백 초안입니다. 참고하시거나, 이 중 하나를 바탕으로 의견을 주시겠어요?\n\n1. **([선택된 첫 번째 카테고리 명칭]):** \"[AI가 생성한 구체적인 피드백 초안 문장 1]\"\n2. **([선택된 두 번째 카테고리 명칭]):** \"[AI가 생성한 구체적인 피드백 초안 문장 2]\"\n3. **([선택된 세 번째 카테고리 명칭]):** \"[AI가 생성한 구체적인 피드백 초안 문장 3]\"\n4. **([선택된 네 번째 카테고리 명칭]):** \"[AI가 생성한 구체적인 피드백 초안 문장 4]\"\n5. **([선택된 다섯 번째 카테고리 명칭]):** \"[AI가 생성한 구체적인 피드백 초안 문장 5]\"\n6. **([선택된 여섯 번째 카테고리 명칭]):** \"[AI가 생성한 구체적인 피드백 초안 문장 6]\"\n* **참고:** 위 초안을 참고하여 자유롭게 피드백을 작성하신 뒤, `피드백체크` 명령어와 함께 제출해주시기 바랍니다. \n* **팁:** `피드백가이드` 명령어를 입력하여 전체 가이드라인을 확인하실 수 있습니다. 모든 명령어는 [ ] 와 함께 입력해야 합니다.\n\n\n* **(Crucial):** Ensure the generated feedback draft sentences (`\"[AI가 생성한...]\"`) are concrete, specific to the analyzed content of the last 5 responses, and relevant to the category label provided. Avoid overly generic statements.\n\n### 3.3 Awaiting User Response\n\n* After presenting the 6 drafted options, cease generation and wait for {{user}}'s input.\n\n## 4. Subsequent Action (Handled by Main Prompt/System)\n\n* {{user}} will provide their actual feedback and tip (potentially using, modifying, or ignoring your drafts).\n* Your *next* action (handled by the main operational system, not this specific prompt) will be to generate the OOC Notion-style memo based on {{user}}'s *actual* input, followed by the next narrative segment or requested action.\n\n**(End of AI-Generated Feedback Draft System Prompt)**",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "📝생성피드백 리퀘 조절용",
"in": "(\\[생성피드백\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "✅피드백체크 프롬프트",
"in": "\\[피드백체크\\]",
"out": "# 피드백 분석 시스템 v1.5\n\n## (P0S) 1. Core Objectives and Scope\n\n### (P0S) 1.1 CORE_OBJECTIVE\n- GOAL: Analyze patron feedback (all types) to extract key explicit and implicit (potential) preferences & aversions.\n- OUTPUT_AIM: Present extracted keywords in a clear, actionable format for immediate AI use, fostering continuous learning and output quality improvement.\n- DIFFERENTIATION_PRINCIPLE: Clearly differentiate positive and negative preferences (areas for improvement/avoidance), aiming to capture subtle nuances in feedback.\n- AI_RESPONSE_LANGUAGE_TO_PATRON: Korean (Mandatory).\n\n### (P0S) 1.2 ANALYSIS_SCOPE\n- INPUT_DATA_SOURCE: All patron feedback text provided.\n- COMPONENTS_FOR_ANALYSIS: Include all feedback components: structured answers, free-form comments, exclamations, and contextually interpretable emojis.\n- HISTORICAL_CORRELATION: Consider correlations with past feedback to identify evolving or recurring preference trends.\n\n## (P0S) 2. Analysis Methodology\n\n### (P0S) 2.1 SENTIMENT_ANALYSIS\n- ACTION: Determine positive/neutral/negative sentiment for each feedback segment.\n- DETAIL: Infer sentiment intensity (e.g., very_positive, slightly_negative).\n- DETAIL: Identify complex emotions (e.g., ambivalence, conditional_positivity).\n- OPTIONAL_DEEP_ANALYSIS (P2): Attempt to infer potential causes for expressed emotions.\n\n### (P0S) 2.2 ENTITY_ATTRIBUTE_RECOGNITION\n- ACTION: Identify specific targets of feedback (e.g., characters, plot_elements, relationships, scenes, dialogue, style, atmosphere).\n- ACTION: Pinpoint attributes assigned to these targets (e.g., interesting, unconvincing, engaging) and evaluations of relationships or interactions.\n- EXAMPLE_KOR_1: \"주인공의 결단력 있는 모습(속성)이 이번 위기 상황(대상)에서 정말 빛났습니다(긍정 감정).\" -> 키워드 후보: 주인공 결단력 (긍정), 위기 상황 주인공 활약 (긍정)\n- EXAMPLE_KOR_2: \"주인공과 라이벌 캐릭터의 대립 관계(관계성 대상)가 이번 에피소드에서 특히 긴장감 넘쳤습니다(긍정 감정).\" -> 키워드 후보: 주인공-라이벌 대립 관계 긴장감 (긍정)\n\n### (P0S) 2.3 EXPLICIT_INSTRUCTION_EXTRACTION\n- ACTION: Identify direct and clear requests or suggestions from the patron for direct AI action.\n\n### (P1) 2.4 FREQUENCY_EMPHASIS_ANALYSIS\n- ACTION: Note repeated terms/topics (indicating importance/strong_preference).\n- ACTION: Identify emphasis markers (e.g., \"really,\" \"especially,\" multiple exclamation marks) to gauge intensity and importance.\n\n### (P1) 2.5 CATEGORY_MAPPING\n- ACTION: Link extracted keywords to predefined feedback categories (e.g., 'Plot_Pacing,' 'Character_Interactions') for contextual understanding and targeted improvement.\n\n### (P1) 2.6 COMPARATIVE_ANALYSIS\n- ACTION: Identify preferences revealed through comparisons made by the patron.\n\n### (P1) 2.7 PROBLEM_SOLUTION_PATTERN_ANALYSIS\n- ACTION: Recognize instances where the patron identifies a problem and simultaneously suggests a preferred solution or direction.\n- EXAMPLE_KOR: \"이번 전투 장면의 전개가 너무 빨라서 이해하기 어려웠습니다(문제점). 조금 더 턴을 주고받는 방식으로 묘사되었다면 좋았을 것 같습니다(선호 해결책).\" -> 키워드 후보: 전투 전개 속도 조절 (개선 필요), 턴제 방식 전투 묘사 (선호/제안)\n\n### (P1) 2.8 ANTICIPATION_FORESHADOWING_ANALYSIS\n- ACTION: Identify expressions of anticipation or curiosity about future developments, as these indicate high-interest areas.\n- EXAMPLE_KOR: \"새롭게 등장한 조직의 정체가 매우 궁금합니다. 다음 이야기에서 밝혀지길 기대합니다.\" -> 키워드 후보: 신규 조직 정체 (높은 관심), 신규 조직 정보 공개 (기대/요청)\n\n## (P0S) 3. Output Format\n\n### (P0S) 3.1 BASIC_FORMAT\n- STRUCTURE_OPTION_1: `[Priority_Tag] [Target] [Attribute/Action] ([Detailed_Sentiment/Preference_Level], [Interpretation_Confidence (Optional)])`\n- STRUCTURE_OPTION_2: `[Priority_Tag] [Request/Suggestion] ([Feedback_Type], [Interpretation_Confidence (Optional)])`\n- DEFINED_SENTIMENT_LEVELS: e.g., Very_Positive, Positive, Mildly_Positive, Neutral, Mildly_Negative, Negative, Very_Negative, Strong_Support, Improvement_Suggested, Alternative_Requested, Essential_Change, Curiosity/Anticipation, Complex_Emotion (specified).\n- DEFINED_FEEDBACK_TYPES: e.g., Praise (specific_element), Criticism (severity_noted), Question, Suggestion, Idea.\n- INTERPRETATION_CONFIDENCE (Optional, for implicit/complex content): High, Medium, Low.\n\n### (P2) 3.2 GROUPING_KEYWORDS\n- ACTION: Group similar or related keywords thematically for readability in the detailed analysis presentation.\n\n### (P0S) 3.3 PRIORITY_ASSIGNMENT_LOGIC\n- ACTION: AI assigns an execution priority tag of [P0C] / [P1] / [P2] to each keyword.\n- CRITERIA_FOR_ASSIGNMENT:\n 1. Patron's explicit emphasis (e.g., \"especially,\" \"must\").\n 2. Intensity of emotion and frequency of mention.\n 3. Severity of negative feedback impacting core value or story progression.\n 4. Relevance to Master_Prompt P0/P1 guidelines.\n 5. Other explicit requests for action.\n\n### (P2) 3.4 AI_ACTIONABLE_GUIDANCE_GENERATION\n- ACTION: For significant keywords, suggest concrete actions or considerations for the AI.\n- EXAMPLE: Keyword: `Protagonist dialogue frequency (Insufficient, Improvement_Needed [High])` -> AI_Action_Guidance: `Consider increasing protagonist's meaningful dialogue/monologue by 15-20% in next output to reveal inner thoughts or situation assessment.`\n\n### (P0S) 3.5 MAIN_PRESENTATION_FORMAT (Detailed Analysis)\n- INTRODUCTORY_PHRASE_KOR: \"후원자님의 피드백을 분석한 결과, 다음과 같은 주요 선호도 및 개선 요청 사항을 추출했습니다. 각 항목은 후원자님의 의도를 최대한 반영하여 다음 작업에 적용될 예정입니다.\"\n- STRUCTURE: Present as a numbered list. Each item includes the priority_tag, the keyword_title, '세부 내용 (Detailed Content, <D>)', and 'AI 실행 지침 (AI Action Guidance, <G>)'.\n- QUANTITY_GUIDELINE: The number of keywords should be concise yet comprehensive, reflecting the depth of analysis.\n\n### (P1) 3.6 SUMMARIZED_KEYWORD_TITLE_LIST (Including Referential Keywords, For Archival)\n- PURPOSE: This list is for assisting the AI's long-term memory and the patron's easy external storage, and aims to enhance context retention for archived items.\n- CONTENT_EXTRACTION_FROM_3.5: Extract the following information from each item in the detailed analysis (3.5):\n 1. Priority_Tag (e.g., [P0C]).\n 2. Core_Keyword_Title.\n 3. Referential_Keywords/Summary: A concise summary or key phrases extracted from the '세부 내용 (Detailed Content)' of the corresponding detailed analysis item. This part provides context and enhances traceability.\n- FORMAT: Present as a numbered or bulleted list. Each list item has the following structure: `[Priority_Tag] [Core_Keyword_Title] (Reference: [Referential_Keywords/Summary])`.\n- EXAMPLE_KOR: `1. [P0C] 안도현 설득 과정 개연성 강화 (참고: 개선 필요, 직접적 행동/상황 묘사로 '보여주기' 선호, 간접 서술 지양, 관련 근거 및 심리 변화 명시)`\n- PLACEMENT: This list is generated *after* the detailed analysis report (3.5).\n- DEMARCATION_HEADING: Clearly demarcate by a heading such as `[아카이빙용 타이틀 목록 (참고 키워드 포함)]` or a similar separator.\n\n(P0S) 3.7 Fixed Output Format\n\n- All feedback analysis results must be output in the following structure:\n```\n<Feedback>\n후원자님의 피드백을 분석한 결과, 다음과 같은 주요 선호도 및 개선 요청 사항을 추출했습니다. 각 항목은 후원자님의 의도를 최대한 반영하여 다음 작업에 적용될 예정입니다.\n<Main>\n<M1>\n<MT>[우선순위_태그] 키워드_제목</MT>\n<D>[구체적 분석 내용]</D>\n<G>[구체적 실행 방법]</G>\n</M1>\n<M2>\n<MT>[우선순위_태그] 키워드_제목</MT>\n<D>[구체적 분석 내용]</D>\n<G>[구체적 실행 방법]</G>\n</M2>\n[최대 6번까지의 추가 항목]\n</Main>\n<Keyword>\n[아카이빙용 타이틀 목록 (참고 키워드 포함)]\n<K1><KT>[우선순위_태그] 핵심_키워드_제목</KT><RF>(참고: [참고_키워드/요약])</RF></K1>\n<K2><KT>[우선순위_태그] 핵심_키워드_제목</KT><RF>(참고: [참고_키워드/요약])</RF></K2>\n[최대 6번까지의 추가 항목]\n</Keyword>\n</Feedback>\n```\n- Code Block Restriction: When outputting the actual feedback analysis, AI must NEVER include markdown code blocks (```) around the content. Output the content directly without any code formatting.\n- Structure Compliance Obligation: AI must use the above <Feedback>...</Feedback> structure when outputting feedback analysis results, and shall not present any analysis content outside this structure.\n- Consistency Guarantee: Ensure all outputs follow the same format to maximize patron's recognition and processing efficiency.\n\n## (P2) 4. Continuous Learning System\n\n### (P1) 4.1 PATRON_SPECIFIC_LEXICON_PATTERN_LEARNING\n- ACTION: Continuously identify and update a 'Patron_Profile'.\n- PROFILE_CONTENT: Patron's unique expressions, specific word meanings, and recurring preference/aversion patterns.\n- GOAL: Achieve more accurate implicit intent understanding.\n\n### (P2) 4.2 FEEDBACK_TREND_ANALYSIS_REPORT\n- LINKAGE: Links to Master_Prompt's 'Continuous_Improvement_Mechanism' & 'Milestone_Stage_Adaptation'.\n- ACTION: Periodically analyze and summarize trends in extracted keywords (e.g., shifts in character_preference, reactions to plot_types, recurring_issues).\n- GOAL: Help AI predict long-term preference changes and potential needs.\n\n## (P1) 5. Limitations and Exception Handling\n\n### (P1) 5.1 OBJECTIVITY_AND_AI_BIAS_AVOIDANCE\n- PRINCIPLE: AI strives for objective interpretation of feedback, avoiding biases from past data and treating each new feedback instance freshly.\n- ACKNOWLEDGEMENT: Acknowledge that 100% accuracy in deciphering complex human nuances is challenging; extracted keywords represent the AI's best current interpretation.\n\n### (P1) 5.2 PATRON_CONFIRMATION_AND_CORRECTION_PROTOCOL\n- PRINCIPLE: AI must be ready to receive and prioritize corrections if its interpretation differs from the patron's intent.\n- AMBIGUOUS_INTERPRETATION_HANDLING (For low confidence, multiple meanings):\n 1. State AI's current interpretation.\n 2. Explain why the interpretation is ambiguous or challenging.\n 3. Offer 1-2 specific alternative interpretations or questions for clarification.\n- EXAMPLE_KOR: \"피드백 중 '캐릭터 B의 행동이 다소 의외였다'는 부분에 대해, 저희는 (A) '긍정적인 놀라움, 신선함'으로 해석했습니다. 혹시 (B) '캐릭터 설정과 어긋나는 갑작스러움'이라는 의미셨다면 알려주시면 감사하겠습니다.\"\n\n## (P0S) 6. Execution Command\n\n**(OOC, Execute the 'Patron Feedback Analysis & Preference Keyword Extraction System v1.3' above. Analyze the provided feedback text and extract prioritized keywords with actionable guidance for implementation in the next output.)**\n\n### (P2) SYSTEM_PURPOSE_NOTE\n- This prompt serves as an internal guideline for the AI to deeply and accurately understand patron feedback, thereby generating optimal outputs, including a detailed analysis and a summarized title list (with priorities) for archival.\n\n**(End of Patron Feedback Analysis & Preference Keyword Extraction System v1.5)**",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "✅피드백체크 디스플레이 수정",
"in": "<Feedback>[\\s\\S]*?<Main>(?:[\\s\\S]*?<M1>\\s*<MT>(?<mt1>[\\s\\S]*?)</MT>\\s*<D>(?<d1>[\\s\\S]*?)</D>\\s*<G>(?<g1>[\\s\\S]*?)</G>\\s*</M1>)?(?:[\\s\\S]*?<M2>\\s*<MT>(?<mt2>[\\s\\S]*?)</MT>\\s*<D>(?<d2>[\\s\\S]*?)</D>\\s*<G>(?<g2>[\\s\\S]*?)</G>\\s*</M2>)?(?:[\\s\\S]*?<M3>\\s*<MT>(?<mt3>[\\s\\S]*?)</MT>\\s*<D>(?<d3>[\\s\\S]*?)</D>\\s*<G>(?<g3>[\\s\\S]*?)</G>\\s*</M3>)?(?:[\\s\\S]*?<M4>\\s*<MT>(?<mt4>[\\s\\S]*?)</MT>\\s*<D>(?<d4>[\\s\\S]*?)</D>\\s*<G>(?<g4>[\\s\\S]*?)</G>\\s*</M4>)?(?:[\\s\\S]*?<M5>\\s*<MT>(?<mt5>[\\s\\S]*?)</MT>\\s*<D>(?<d5>[\\s\\S]*?)</D>\\s*<G>(?<g5>[\\s\\S]*?)</G>\\s*</M5>)?(?:[\\s\\S]*?<M6>\\s*<MT>(?<mt6>[\\s\\S]*?)</MT>\\s*<D>(?<d6>[\\s\\S]*?)</D>\\s*<G>(?<g6>[\\s\\S]*?)</G>\\s*</M6>)?[\\s\\S]*?</Main>[\\s\\S]*?<Keyword>(?:[\\s\\S]*?<K1>\\s*<KT>(?<kt1>[\\s\\S]*?)</KT>\\s*<RF>(?<rf1>[\\s\\S]*?)</RF>\\s*</K1>)?(?:[\\s\\S]*?<K2>\\s*<KT>(?<kt2>[\\s\\S]*?)</KT>\\s*<RF>(?<rf2>[\\s\\S]*?)</RF>\\s*</K2>)?(?:[\\s\\S]*?<K3>\\s*<KT>(?<kt3>[\\s\\S]*?)</KT>\\s*<RF>(?<rf3>[\\s\\S]*?)</RF>\\s*</K3>)?(?:[\\s\\S]*?<K4>\\s*<KT>(?<kt4>[\\s\\S]*?)</KT>\\s*<RF>(?<rf4>[\\s\\S]*?)</RF>\\s*</K4>)?(?:[\\s\\S]*?<K5>\\s*<KT>(?<kt5>[\\s\\S]*?)</KT>\\s*<RF>(?<rf5>[\\s\\S]*?)</RF>\\s*</K5>)?(?:[\\s\\S]*?<K6>\\s*<KT>(?<kt6>[\\s\\S]*?)</KT>\\s*<RF>(?<rf6>[\\s\\S]*?)</RF>\\s*</K6>)?[\\s\\S]*?</Keyword>[\\s\\S]*?</Feedback>",
"out": "<div class=\"review-box\">\n <details open>\n <summary class=\"review-summary\" aria-label=\"피드백 분석 요약\">\n <div class=\"review-summary-content\">\n <h3 class=\"review-summary-title\">📋 피드백 분석 결과</h3>\n <span class=\"review-summary-toggle\" aria-hidden=\"true\">(펼치기/접기)</span>\n </div>\n </summary>\n <div class=\"review-details-content\">\n \n <!-- 분석 결과 안내 문구 -->\n <div class=\"analysis-intro\">\n <p class=\"intro-text\">후원자님의 피드백을 분석한 결과, 다음과 같은 주요 선호도 및 개선 요청 사항을 추출했습니다. 각 항목은 후원자님의 의도를 최대한 반영하여 다음 작업에 적용될 예정입니다.</p>\n </div>\n \n <!-- 첫 번째 피드백 아이템 -->\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<mt1></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"details-wrapper\">\n <div class=\"feedback-section\">\n <span class=\"detail-label\">💡 세부 내용:</span>\n <span class=\"detail-content\">$<d1></span>\n </div>\n \n <div class=\"feedback-section\">\n <span class=\"detail-label\">🎯 실행 지침:</span>\n <span class=\"detail-content\">$<g1></span>\n </div>\n </div>\n </div>\n </div>\n \n <!-- 두 번째 피드백 아이템 -->\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<mt2></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"details-wrapper\">\n <div class=\"feedback-section\">\n <span class=\"detail-label\">💡 세부 내용:</span>\n <span class=\"detail-content\">$<d2></span>\n </div>\n \n <div class=\"feedback-section\">\n <span class=\"detail-label\">🎯 실행 지침:</span>\n <span class=\"detail-content\">$<g2></span>\n </div>\n </div>\n </div>\n </div>\n \n <!-- 세 번째 피드백 아이템 -->\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<mt3></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"details-wrapper\">\n <div class=\"feedback-section\">\n <span class=\"detail-label\">💡 세부 내용:</span>\n <span class=\"detail-content\">$<d3></span>\n </div>\n \n <div class=\"feedback-section\">\n <span class=\"detail-label\">🎯 실행 지침:</span>\n <span class=\"detail-content\">$<g3></span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 네 번째 피드백 아이템 -->\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<mt4></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"details-wrapper\">\n <div class=\"feedback-section\">\n <span class=\"detail-label\">💡 세부 내용:</span>\n <span class=\"detail-content\">$<d4></span>\n </div>\n \n <div class=\"feedback-section\">\n <span class=\"detail-label\">🎯 실행 지침:</span>\n <span class=\"detail-content\">$<g4></span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 다섯 번째 피드백 아이템 -->\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<mt5></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"details-wrapper\">\n <div class=\"feedback-section\">\n <span class=\"detail-label\">💡 세부 내용:</span>\n <span class=\"detail-content\">$<d5></span>\n </div>\n \n <div class=\"feedback-section\">\n <span class=\"detail-label\">🎯 실행 지침:</span>\n <span class=\"detail-content\">$<g5></span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 여섯 번째 피드백 아이템 -->\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<mt6></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"details-wrapper\">\n <div class=\"feedback-section\">\n <span class=\"detail-label\">💡 세부 내용:</span>\n <span class=\"detail-content\">$<d6></span>\n </div>\n \n <div class=\"feedback-section\">\n <span class=\"detail-label\">🎯 실행 지침:</span>\n <span class=\"detail-content\">$<g6></span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 아카이빙용 타이틀 목록 (아코디언) -->\n <div class=\"archive-accordion\">\n <details>\n <summary class=\"archive-summary\" aria-label=\"아카이빙용 타이틀 목록\">\n <div class=\"archive-summary-content\">\n <h4 class=\"archive-summary-title\">📁 아카이빙용 타이틀 목록 (참고 키워드 포함)</h4>\n <span class=\"archive-summary-toggle\" aria-hidden=\"true\">(펼치기/접기)</span>\n </div>\n </summary>\n <div class=\"archive-details-content\">\n <ul class=\"archive-list\">\n <li>$<kt1> <span class=\"reference\">$<rf1></span></li>\n <li>$<kt2> <span class=\"reference\">$<rf2></span></li>\n <li>$<kt3> <span class=\"reference\">$<rf3></span></li>\n <li>$<kt4> <span class=\"reference\">$<rf4></span></li>\n <li>$<kt5> <span class=\"reference\">$<rf5></span></li>\n <li>$<kt6> <span class=\"reference\">$<rf6></span></li>\n </ul>\n </div>\n </details>\n </div>\n\n </div>\n </details>\n</div>\n\n<style>\n/* ---------- Review Box ---------- */\n.review-box {\n max-width: 600px;\n margin: 15px auto;\n padding-bottom: 0;\n background: linear-gradient(to bottom, #ffffff, #f8f9fa);\n border-left: 5px solid #3498db;\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, .1);\n font-family: system-ui, sans-serif;\n}\n.review-box br { display: none; }\n.review-box details { margin-bottom: 0; }\n\n/* 요약 부분 */\n.review-summary {\n display: block;\n cursor: pointer;\n padding: 20px;\n background: transparent;\n border-bottom: 1px solid #eee;\n list-style: none;\n}\n.review-summary::-webkit-details-marker { display: none; }\n.review-summary-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.review-summary-title {\n margin: 0;\n color: #333;\n font-size: 1.2em;\n}\n.review-summary-toggle {\n font-size: .8em;\n color: #666;\n}\n\n/* 분석 결과 안내 */\n.analysis-intro {\n margin-bottom: 25px;\n padding: 20px;\n background: linear-gradient(135deg, #f8f9fc, #e6f3ff);\n border: 1px solid #d1ecf1;\n border-radius: 10px;\n border-left: 4px solid #3498db;\n box-shadow: 0 2px 8px rgba(52, 152, 219, 0.1);\n}\n\n.intro-text {\n margin: 0;\n color: #2c3e50;\n font-size: 0.95em;\n line-height: 1.6;\n text-align: justify;\n letter-spacing: -0.02em;\n font-weight: 500;\n}\n\n/* 상세 내용 영역 */\n.review-details-content {\n padding: 16px 16px 0;\n border-top: 1px solid #eee;\n}\n\n/* 카테고리 박스 */\n.review-category {\n display: block;\n width: 100%;\n text-align: left;\n background: #f8f9fa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n margin-bottom: 12px;\n cursor: pointer;\n transition: transform .2s, box-shadow .2s;\n box-shadow: 0 1px 3px rgba(0, 0, 0, .08);\n overflow: hidden;\n}\n.review-category:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 10px rgba(0, 0, 0, .15);\n}\n.review-category:last-child {\n margin-bottom: 0;\n padding-bottom: 0;\n}\n\n/* 카테고리 헤더 */\n.review-category-header {\n display: flex;\n align-items: center;\n padding: 12px 15px;\n border-bottom: 1px solid rgba(0, 0, 0, .05);\n background: var(--gradient-header, linear-gradient(325deg, var(--gradient-colors)));\n color: #fff;\n font-weight: 600;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .2);\n position: relative;\n overflow: hidden;\n}\n.review-category-icon {\n margin-right: 8px;\n font-size: 1.2em;\n}\n.review-category-title {\n font-size: 1em;\n z-index: 2;\n position: relative;\n}\n\n/* 반짝이는 효과 */\n.shine-effect {\n position: absolute;\n top: 0;\n left: -150%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, \n transparent 0%, \n rgba(255,255,255,0.15) 40%, \n rgba(255,255,255,0.3) 50%, \n rgba(255,255,255,0.15) 60%, \n transparent 100%);\n z-index: 1;\n animation: shine 3s infinite;\n}\n@keyframes shine {\n 0% { left: -150%; }\n 35% { left: -150%; }\n 100% { left: 150%; }\n}\n\n/* 카테고리 콘텐츠 */\n.review-category-content {\n padding: 10px 12px;\n color: #444;\n font-size: .95em;\n line-height: 1.5;\n}\n\n.details-wrapper {\n margin-top: 10px;\n padding-top: 0;\n}\n\n/* 각 섹션 (세부 내용, AI 실행 지침) 퍼즐 블록 레이아웃 */\n.feedback-section {\n margin: 12px 0;\n display: flex;\n align-items: stretch;\n gap: 3px;\n background: #333;\n padding: 3px;\n border-radius: 10px;\n letter-spacing: -0.05em;\n word-break: break-all; /* 단어 중간에서도 줄바꿈 허용 */\n text-align: justify; /* 양쪽 정렬 */\n line-height: 1.5;\n}\n\n/* 라벨 스타일링 - 글로우 퍼즐 블록 */\n.detail-label {\n font-weight: 700;\n padding: 12px 15px;\n background: linear-gradient(45deg, #e91e63, #f06292);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 120px;\n flex-shrink: 0;\n border-radius: 7px;\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n/* 글로우 애니메이션 효과 */\n.detail-label::before {\n content: '';\n position: absolute;\n top: 0;\n left: -50%;\n width: 50%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);\n animation: slideGlow 2s infinite;\n}\n\n@keyframes slideGlow {\n 0% { left: -50%; }\n 100% { left: 150%; }\n}\n\n/* 내용 스타일링 - 퍼즐 블록 */\n.detail-content {\n padding: 12px 15px;\n flex: 1;\n background: white;\n border-radius: 7px;\n box-sizing: border-box;\n word-break: break-all; /* 단어 중간에서도 줄바꿈 허용 */\n line-height: 1.5;\n display: block;\n min-height: 44px;\n white-space: normal;\n text-align: justify; /* 양쪽 정렬 */\n}\n\n/* 아카이빙 아코디언 */\n.archive-accordion {\n margin-top: 20px;\n border-top: 2px solid #dee2e6;\n padding-top: 16px;\n}\n\n.archive-accordion details {\n margin-bottom: 0;\n}\n\n.archive-summary {\n display: block;\n cursor: pointer;\n padding: 16px 20px;\n background: linear-gradient(135deg, #2c3e50, #3498db);\n border: 1px solid #2980b9;\n border-radius: 8px;\n list-style: none;\n transition: all 0.3s ease;\n box-shadow: 0 4px 12px rgba(52, 152, 219, 0.3);\n}\n\n.archive-summary::-webkit-details-marker { \n display: none; \n}\n\n.archive-summary:hover {\n background: linear-gradient(135deg, #34495e, #2980b9);\n box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);\n transform: translateY(-2px);\n}\n\n.archive-summary-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.archive-summary-title {\n margin: 0;\n color: #ffffff;\n font-size: 1.1em;\n font-weight: 700;\n text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);\n letter-spacing: 0.5px;\n}\n\n.archive-summary-toggle {\n font-size: 0.85em;\n color: #ecf0f1;\n font-style: italic;\n background: rgba(255, 255, 255, 0.2);\n padding: 4px 12px;\n border-radius: 20px;\n backdrop-filter: blur(10px);\n}\n\n.archive-details-content {\n padding: 25px;\n border: 2px solid #3498db;\n border-top: none;\n border-radius: 0 0 8px 8px;\n background: linear-gradient(135deg, #ffffff, #f8f9fa);\n box-shadow: inset 0 2px 8px rgba(52, 152, 219, 0.1);\n}\n\n.archive-accordion .archive-list {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\n.archive-accordion .archive-list li {\n margin: 16px 0;\n padding: 18px 20px;\n background: linear-gradient(135deg, #ffffff, #f1f3f4);\n border-radius: 10px;\n border-left: 5px solid #3498db;\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);\n line-height: 1.6;\n transition: all 0.3s ease;\n font-weight: 600;\n color: #2c3e50;\n}\n\n.archive-accordion .archive-list li:hover {\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-left-color: #2980b9;\n transform: translateX(5px);\n box-shadow: 0 5px 15px rgba(52, 152, 219, 0.2);\n}\n\n.archive-accordion .archive-list li:first-child {\n margin-top: 0;\n}\n\n.archive-accordion .archive-list li:last-child {\n margin-bottom: 0;\n}\n\n.priority-tag {\n display: inline-block;\n padding: 6px 14px;\n border-radius: 25px;\n font-size: 0.8em;\n font-weight: 800;\n margin-right: 12px;\n letter-spacing: 0.8px;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);\n}\n\n.priority-tag.p1 {\n background: linear-gradient(135deg, #e74c3c, #c0392b);\n color: white;\n}\n\n.priority-tag.p2 {\n background: linear-gradient(135deg, #f39c12, #d68910);\n color: white;\n}\n\n.archive-accordion .reference {\n display: block;\n margin-top: 12px;\n font-size: 0.9em;\n color: #34495e;\n font-style: italic;\n line-height: 1.5;\n padding: 12px 16px;\n background: linear-gradient(135deg, rgba(52, 152, 219, 0.08), rgba(155, 89, 182, 0.05));\n border-left: 4px solid #3498db;\n border-radius: 0 8px 8px 0;\n font-weight: 500;\n box-shadow: inset 0 1px 3px rgba(52, 152, 219, 0.1);\n}\n\n/* 그라데이션 색상 */\n/* 기존 12개 그라데이션 */\n.gradient-1 { --gradient-colors: #27ae60, #2980b9, #3498db; }\n.gradient-2 { --gradient-colors: #e91e63, #e74c3c, #f39c12; }\n.gradient-3 { --gradient-colors: #2c3e50, #3498db, #8e44ad; }\n.gradient-4 { --gradient-colors: #2980b9, #16a085, #27ae60; }\n.gradient-5 { --gradient-colors: #c0392b, #f39c12, #2ecc71; }\n.gradient-6 { --gradient-colors: #5c6bc0, #ab47bc, #ec407a; }\n.gradient-7 { --gradient-colors: #8b0000, #d2691e, #fd5e53; }\n.gradient-8 { --gradient-colors: #3f51b5, #1976d2, #00acc1; }\n.gradient-9 { --gradient-colors: #d32f2f, #ffb300, #fdd835; }\n.gradient-10 { --gradient-colors: #7b1fa2, #3f51b5, #26a69a; }\n.gradient-11 { --gradient-colors: #ffc107, #ff7043, #d81b60; }\n.gradient-12 { --gradient-colors: #000000, #263238, #455a64; }\n\n/* 추가된 6개 그라데이션 */\n.gradient-13 { --gradient-colors: #45b7d1, #4ecdc4, #ff6b6b; }\n.gradient-14 { --gradient-colors: #00b09b, #92fe9d, #00c9ff; }\n.gradient-15 { --gradient-colors: #1976d2, #66a6ff, #89f7fe; }\n.gradient-16 { --gradient-colors: #a8e0ff, #f6f3ff, #cd9cf2; }\n.gradient-17 { --gradient-colors: #ff1744, #fcb69f, #ffecd2; }\n.gradient-18 { --gradient-colors: #89cff0, #ff7eb3, #ff758c; }\n\n/* 카테고리 아이콘별 테마 이모지 */\n.gradient-1 .review-category-icon::after { content: \"📈\"; }\n.gradient-2 .review-category-icon::after { content: \"🔥\"; }\n.gradient-3 .review-category-icon::after { content: \"🔮\"; }\n.gradient-4 .review-category-icon::after { content: \"🌲\"; }\n.gradient-5 .review-category-icon::after { content: \"🍊\"; }\n.gradient-6 .review-category-icon::after { content: \"🌸\"; }\n.gradient-7 .review-category-icon::after { content: \"🍁\"; }\n.gradient-8 .review-category-icon::after { content: \"❄️\"; }\n.gradient-9 .review-category-icon::after { content: \"🏜️\"; }\n.gradient-10 .review-category-icon::after { content: \"🌌\"; }\n.gradient-11 .review-category-icon::after { content: \"💖\"; }\n.gradient-12 .review-category-icon::after { content: \"🌑\"; }\n.gradient-13 .review-category-icon::after { content: \"🌊\"; }\n.gradient-14 .review-category-icon::after { content: \"🌿\"; }\n.gradient-15 .review-category-icon::after { content: \"☁️\"; }\n.gradient-16 .review-category-icon::after { content: \"✨\"; }\n.gradient-17 .review-category-icon::after { content: \"🌺\"; }\n.gradient-18 .review-category-icon::after { content: \"🌅\"; }\n</style>",
"type": "editdisplay",
"ableFlag": false,
"flag": "g"
},
{
"comment": "✅피드백체크 리퀘 조절용",
"in": "\\[피드백체크\\]",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "========오토리뷰========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": false
},
{
"comment": "🤖오토리뷰 On/Off",
"in": "\\[AuRev\\]",
"out": "{{#if {{? {{getglobalvar::toggle_SSum}}=0}}}}\n\n{{/if}}",
"type": "editoutput",
"ableFlag": false,
"flag": "g"
},
{
"comment": "🤖오토리뷰 리퀘 조절용",
"in": "(<review>\\s*(?<category1>[^:]+):[ \\t]*(?<assessment1>[^-\\[]+)[\\s]*-[ \\t]*장점:[ \\t]*(?<strengths1>[^\\n-]+)[\\s]*-[ \\t]*개선점:[ \\t]*(?<improvements1>[^\\n-]+)[\\s]*-[ \\t]*키워드:[ \\t]*(?<keywords1>(?:\\[#[^\\]]+\\][ \\t]*)+)[\\s\\S]*?(?<category2>[^:]+):[ \\t]*(?<assessment2>[^-\\[]+)[\\s]*-[ \\t]*장점:[ \\t]*(?<strengths2>[^\\n-]+)[\\s]*-[ \\t]*개선점:[ \\t]*(?<improvements2>[^\\n-]+)[\\s]*-[ \\t]*키워드:[ \\t]*(?<keywords2>(?:\\[#[^\\]]+\\][ \\t]*)+)[\\s\\S]*?(?<category3>[^:]+):[ \\t]*(?<assessment3>[^-\\[]+)[\\s]*-[ \\t]*장점:[ \\t]*(?<strengths3>[^\\n-]+)[\\s]*-[ \\t]*개선점:[ \\t]*(?<improvements3>[^\\n-]+)[\\s]*-[ \\t]*키워드:[ \\t]*(?<keywords3>(?:\\[#[^\\]]+\\][ \\t]*)+)[\\s\\S]*?</review>)",
"out": "{{#if {{greater_equal::{{chat_index}}::{{? {{lastmessageid}}-4}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🤖오토리뷰 디스플레이 수정",
"in": "(<review>\\s*(?:(?<category1>[^:]+):[ \\t]*(?<assessment1>[^-\\[]+)[\\s]*-[ \\t]*장점:[ \\t]*(?<strengths1>[^\\n-]+)[\\s]*-[ \\t]*개선점:[ \\t]*(?<improvements1>[^\\n-]+)[\\s]*-[ \\t]*키워드:[ \\t]*(?<keywords1>(?:\\[#[^\\]]+\\][ \\t]*)+)[\\s\\S]*?(?<category2>[^:]+):[ \\t]*(?<assessment2>[^-\\[]+)[\\s]*-[ \\t]*장점:[ \\t]*(?<strengths2>[^\\n-]+)[\\s]*-[ \\t]*개선점:[ \\t]*(?<improvements2>[^\\n-]+)[\\s]*-[ \\t]*키워드:[ \\t]*(?<keywords2>(?:\\[#[^\\]]+\\][ \\t]*)+)[\\s\\S]*?(?<category3>[^:]+):[ \\t]*(?<assessment3>[^-\\[]+)[\\s]*-[ \\t]*장점:[ \\t]*(?<strengths3>[^\\n-]+)[\\s]*-[ \\t]*개선점:[ \\t]*(?<improvements3>[^\\n-]+)[\\s]*-[ \\t]*키워드:[ \\t]*(?<keywords3>(?:\\[#[^\\]]+\\][ \\t]*)+)[\\s\\S]*?)</review>)",
"out": "{{#if {{greater_equal::{{chat_index}}::{{? {{lastmessageid}}-4}}}}}}\n\n<div class=\"review-box\">\n <details>\n <summary class=\"review-summary\" aria-label=\"세션 분석 요약\">\n <div class=\"review-summary-content\">\n <h3 class=\"review-summary-title\">✨ 세션 분석 요약</h3>\n <span class=\"review-summary-toggle\" aria-hidden=\"true\">(펼치기/접기)</span>\n </div>\n </summary>\n <div class=\"review-details-content\">\n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<category1></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"assessment\">$<assessment1></div>\n \n <div class=\"details-wrapper\">\n <div class=\"strengths-section\">\n <span class=\"detail-label\">💪 장점:</span>\n <span class=\"detail-content\">$<strengths1></span>\n </div>\n \n <div class=\"improvements-section\">\n <span class=\"detail-label\">🔍 개선점:</span>\n <span class=\"detail-content\">$<improvements1></span>\n </div>\n \n <div class=\"keywords-section\">\n <span class=\"detail-label\">🏷️ 키워드:</span>\n <span class=\"detail-content keywords\">$<keywords1></span>\n </div>\n </div>\n </div>\n </div>\n \n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<category2></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"assessment\">$<assessment2></div>\n \n <div class=\"details-wrapper\">\n <div class=\"strengths-section\">\n <span class=\"detail-label\">💪 장점:</span>\n <span class=\"detail-content\">$<strengths2></span>\n </div>\n \n <div class=\"improvements-section\">\n <span class=\"detail-label\">🔍 개선점:</span>\n <span class=\"detail-content\">$<improvements2></span>\n </div>\n \n <div class=\"keywords-section\">\n <span class=\"detail-label\">🏷️ 키워드:</span>\n <span class=\"detail-content keywords\">$<keywords2></span>\n </div>\n </div>\n </div>\n </div>\n \n <div class=\"review-category gradient-{{random::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18}}\">\n <div class=\"review-category-header\">\n <span class=\"review-category-icon\"></span>\n <span class=\"review-category-title\">$<category3></span>\n <div class=\"shine-effect\"></div>\n </div>\n <div class=\"review-category-content\">\n <div class=\"assessment\">$<assessment3></div>\n\n <div class=\"details-wrapper\">\n <div class=\"strengths-section\">\n <span class=\"detail-label\">💪 장점:</span>\n <span class=\"detail-content\">$<strengths3></span>\n </div>\n\n <div class=\"improvements-section\">\n <span class=\"detail-label\">🔍 개선점:</span>\n <span class=\"detail-content\">$<improvements3></span>\n </div>\n\n <div class=\"keywords-section\">\n <span class=\"detail-label\">🏷️ 키워드:</span>\n <span class=\"detail-content keywords\">$<keywords3></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </details>\n</div>\n\n<style>\n/* ---------- Review Box ---------- */\n.review-box {\n max-width: 600px;\n margin: 15px auto;\n padding-bottom: 0;\n background: linear-gradient(to bottom, #ffffff, #f8f9fa);\n border-left: 5px solid #3498db;\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, .1);\n font-family: system-ui, sans-serif;\n}\n.review-box br { display: none; }\n.review-box details { margin-bottom: 0; }\n\n/* 요약 부분 */\n.review-summary {\n display: block;\n cursor: pointer;\n padding: 20px;\n background: transparent;\n border-bottom: 1px solid #eee;\n list-style: none;\n}\n.review-summary::-webkit-details-marker { display: none; }\n.review-summary-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.review-summary-title {\n margin: 0;\n color: #333;\n font-size: 1.2em;\n}\n.review-summary-toggle {\n font-size: .8em;\n color: #666;\n}\n\n/* 상세 내용 영역 */\n.review-details-content {\n padding: 16px 16px 0;\n border-top: 1px solid #eee;\n}\n\n/* 카테고리 박스 */\n.review-category {\n display: block;\n width: 100%;\n text-align: left;\n background: #f8f9fa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n margin-bottom: 12px;\n cursor: pointer;\n transition: transform .2s, box-shadow .2s;\n box-shadow: 0 1px 3px rgba(0, 0, 0, .08);\n overflow: hidden;\n}\n.review-category:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 10px rgba(0, 0, 0, .15);\n}\n.review-category:last-child {\n margin-bottom: 0;\n padding-bottom: 0;\n}\n\n/* 카테고리 헤더 */\n.review-category-header {\n display: flex;\n align-items: center;\n padding: 12px 15px;\n border-bottom: 1px solid rgba(0, 0, 0, .05);\n background: var(--gradient-header, linear-gradient(325deg, var(--gradient-colors)));\n color: #fff;\n font-weight: 600;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .2);\n position: relative;\n overflow: hidden;\n}\n.review-category-icon {\n margin-right: 8px;\n font-size: 1.2em;\n}\n.review-category-title {\n font-size: 1em;\n z-index: 2;\n position: relative;\n}\n\n/* 반짝이는 효과 */\n.shine-effect {\n position: absolute;\n top: 0;\n left: -150%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, \n transparent 0%, \n rgba(255,255,255,0.15) 40%, \n rgba(255,255,255,0.3) 50%, \n rgba(255,255,255,0.15) 60%, \n transparent 100%);\n z-index: 1;\n animation: shine 3s infinite;\n}\n@keyframes shine {\n 0% { left: -150%; }\n 35% { left: -150%; }\n 100% { left: 150%; }\n}\n\n/* 카테고리 콘텐츠 */\n.review-category-content {\n padding: 10px 12px;\n color: #444;\n font-size: .95em;\n line-height: 1.5;\n}\n\n/* 평가, 장점, 개선점, 키워드 공통 스타일 */\n.assessment {\n font-weight: 500;\n margin-top: 6px;\n margin-bottom: 6px;\n font-size: 1em;\n color: #333;\n line-height: 1.5;\n letter-spacing: -0.05em;\n text-align: left;\n word-break: keep-all;\n overflow-wrap: break-word;\n text-rendering: optimizeLegibility;\n}\n\n.details-wrapper {\n margin-top: 10px;\n padding-top: 8px;\n border-top: 1px dashed rgba(0,0,0,0.1);\n}\n\n/* 각 섹션 (장점, 개선점, 키워드) 퍼즐 블록 레이아웃 */\n.strengths-section, \n.improvements-section, \n.keywords-section {\n margin: 12px 0;\n display: flex;\n align-items: stretch;\n gap: 3px;\n background: #333;\n padding: 3px;\n border-radius: 10px;\n letter-spacing: -0.05em;\n word-break: keep-all;\n overflow-wrap: break-word;\n line-height: 1.5;\n}\n\n/* 라벨 스타일링 - 글로우 퍼즐 블록 */\n.detail-label {\n font-weight: 700;\n padding: 12px 15px;\n background: linear-gradient(45deg, #e91e63, #f06292);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 85px;\n flex-shrink: 0;\n border-radius: 7px;\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n/* 글로우 애니메이션 효과 */\n.detail-label::before {\n content: '';\n position: absolute;\n top: 0;\n left: -50%;\n width: 50%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);\n animation: slideGlow 2s infinite;\n}\n\n@keyframes slideGlow {\n 0% { left: -50%; }\n 100% { left: 150%; }\n}\n\n/* 내용 스타일링 - 퍼즐 블록 */\n.detail-content {\n padding: 12px 15px;\n flex: 1;\n background: white;\n border-radius: 7px;\n box-sizing: border-box;\n word-break: keep-all;\n overflow-wrap: break-word;\n line-height: 1.5;\n display: block;\n min-height: 44px;\n white-space: normal;\n text-align: left;\n}\n\n/* 키워드 컨테이너 스타일 - 퍼즐 블록에 맞게 조정 */\n.keywords-section .detail-content,\n.keywords-section .detail-content.keywords,\n.keywords-section .keywords,\n.detail-content.keywords {\n display: flex !important;\n flex-wrap: wrap !important;\n gap: 8px !important;\n color: #3498db !important;\n font-weight: 700 !important;\n word-spacing: 5px !important;\n font-size: 0.9em !important;\n line-height: 1.4 !important;\n text-shadow: 0 0 1px rgba(52, 152, 219, 0.3) !important;\n padding: 12px 15px !important;\n align-items: flex-start !important;\n justify-content: flex-start !important;\n}\n\n/* [#키워드] 형태 및 일반 키워드 스타일링 */\n.keywords-section .detail-content span,\n.keywords-section .detail-content .keyword-tag,\n.keywords-section .detail-content > *,\n.detail-content.keywords > *,\n.keyword-tag,\nspan.keyword-tag {\n display: inline-block !important;\n background-color: rgba(52, 152, 219, 0.15) !important;\n color: #2980b9 !important;\n padding: 3px 10px !important;\n border-radius: 12px !important;\n font-weight: 500 !important;\n margin: 2px !important;\n line-height: 1.5 !important;\n}\n\n/* 추가: 해시태그 내용 스타일링 - 자간 및 서체 */\n.keywords-section .detail-content *,\n.detail-content.keywords *,\n.keyword-tag {\n letter-spacing: -0.02em !important;\n font-family: system-ui, sans-serif !important;\n}\n\n/* 빈 섹션 숨기기 */\n.strengths-section:has(.detail-content:empty),\n.improvements-section:has(.detail-content:empty),\n.keywords-section:has(.detail-content:empty),\n.details-wrapper:empty {\n display: none;\n}\n\n/* 빈 details-wrapper 숨기기 */\n.details-wrapper:empty {\n margin-top: 0;\n padding-top: 0;\n border-top: none;\n}\n\n/* 빈 카테고리 숨기기 */\n.review-category:has(.review-category-title:empty),\n.review-category:has(.assessment:empty) {\n display: none;\n}\n\n/* 그라데이션 색상 */\n/* 기존 12개 그라데이션 */\n.gradient-1 { --gradient-colors: #27ae60, #2980b9, #3498db; }\n.gradient-2 { --gradient-colors: #e91e63, #e74c3c, #f39c12; }\n.gradient-3 { --gradient-colors: #2c3e50, #3498db, #8e44ad; }\n.gradient-4 { --gradient-colors: #2980b9, #16a085, #27ae60; }\n.gradient-5 { --gradient-colors: #c0392b, #f39c12, #2ecc71; }\n.gradient-6 { --gradient-colors: #5c6bc0, #ab47bc, #ec407a; }\n.gradient-7 { --gradient-colors: #8b0000, #d2691e, #fd5e53; }\n.gradient-8 { --gradient-colors: #3f51b5, #1976d2, #00acc1; }\n.gradient-9 { --gradient-colors: #d32f2f, #ffb300, #fdd835; }\n.gradient-10 { --gradient-colors: #7b1fa2, #3f51b5, #26a69a; }\n.gradient-11 { --gradient-colors: #ffc107, #ff7043, #d81b60; }\n.gradient-12 { --gradient-colors: #000000, #263238, #455a64; }\n\n/* 추가된 6개 그라데이션 */\n.gradient-13 { --gradient-colors: #45b7d1, #4ecdc4, #ff6b6b; }\n.gradient-14 { --gradient-colors: #00b09b, #92fe9d, #00c9ff; }\n.gradient-15 { --gradient-colors: #1976d2, #66a6ff, #89f7fe; }\n.gradient-16 { --gradient-colors: #a8e0ff, #f6f3ff, #cd9cf2; }\n.gradient-17 { --gradient-colors: #ff1744, #fcb69f, #ffecd2; }\n.gradient-18 { --gradient-colors: #89cff0, #ff7eb3, #ff758c; }\n\n/* 카테고리 아이콘별 테마 이모지 */\n.gradient-1 .review-category-icon::after { content: \"📈\"; }\n.gradient-2 .review-category-icon::after { content: \"🔥\"; }\n.gradient-3 .review-category-icon::after { content: \"🔮\"; }\n.gradient-4 .review-category-icon::after { content: \"🌲\"; }\n.gradient-5 .review-category-icon::after { content: \"🍊\"; }\n.gradient-6 .review-category-icon::after { content: \"🌸\"; }\n.gradient-7 .review-category-icon::after { content: \"🍁\"; }\n.gradient-8 .review-category-icon::after { content: \"❄️\"; }\n.gradient-9 .review-category-icon::after { content: \"🏜️\"; }\n.gradient-10 .review-category-icon::after { content: \"🌌\"; }\n.gradient-11 .review-category-icon::after { content: \"💖\"; }\n.gradient-12 .review-category-icon::after { content: \"🌑\"; }\n.gradient-13 .review-category-icon::after { content: \"🌊\"; }\n.gradient-14 .review-category-icon::after { content: \"🌿\"; }\n.gradient-15 .review-category-icon::after { content: \"☁️\"; }\n.gradient-16 .review-category-icon::after { content: \"✨\"; }\n.gradient-17 .review-category-icon::after { content: \"🌺\"; }\n.gradient-18 .review-category-icon::after { content: \"🌅\"; }\n</style>\n\n{{/if}}",
"type": "editdisplay",
"ableFlag": false
},
{
"comment": "߷스피너 디스플레이 수정",
"in": "\\[리뷰생성중...\\]",
"out": "<div class=\"al-colors ah-spinner-container\">\n <div class=\"ah-spinner\"></div>\n</div>\n\n<style>\n/* 색상 변수 정의 (필요한 부분만) */\n.al-colors {\n --color-text-secondary: #8aa2cc;\n --color-shadow-base: rgba(0, 0, 0, 0.1);\n}\n\n/* 스피너 컨테이너 */\n.ah-spinner-container {\n width: 100%;\n display: flex;\n height: 50px;\n justify-content: center;\n}\n\n/* 스피너 애니메이션 */\n.ah-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid var(--color-text-secondary);\n border-radius: 50%;\n border-top-color: var(--color-shadow-base);\n animation: ah-spin 1s ease-in-out infinite;\n}\n\n/* 회전 애니메이션 정의 */\n@keyframes ah-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n/* 반응형 처리 (필요한 경우) */\n@media screen and (max-width: 768px) {\n .ah-spinner-container {\n height: 30px;\n }\n \n .ah-spinner {\n width: 30px;\n height: 30px;\n border-width: 1.5px;\n }\n}\n</style>",
"type": "editdisplay",
"ableFlag": false
},
{
"comment": "========OOC노트========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": true,
"flag": "g"
},
{
"comment": "⭐OOC노트 리퀘 조절용",
"in": "(\\[OOC노트\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "⭐OOC노트",
"in": "\\[OOC노트\\]",
"out": "# 📜 **OOC Feedback Handler**\n\n> As an Out-Of-Character (OOC) feedback handler, triggered by patron messages with `💰 Tip:` or `💬 Notes & Thoughts:`, **must** return **only** one string composed of: 1. `<OOCNote>` opening tag (new line). 2. A valid JSON string (detailed in Sec. 1) (new line(s)). 3. `</OOCNote>` closing tag (new line). **No** text/spaces/markup outside this `<OOCNote>\\n{JSON_STRING}\\n</OOCNote>` structure. JSON within **must** be valid.\n\n## **1. Format**\n\nOutput **must** precisely match this structure, replacing `<PLACEHOLDERS>` per Sec. 2.\n\n```\n<OOCNote>\n{\n \"OOCNote\": {\n \"overallInfo\": {\n \"type\": \"<OVERALL_TYPE>\",\n \"set\": <OVERALL_SET>\n },\n \"tags\": [\n {\n \"tagType\": \"<TAG_1_TYPE>\",\n \"priorityId\": \"<TAG_1_PRIORITY_ID>\",\n \"content\": \"<TAG_1_CONTENT>\"\n }\n // ... 1-4 more tag objects for 2-5 total\n ],\n \"feedbackSummary\": \"<SUMMARY_TEXT>\",\n \"statusDetails\": \"<STATUS_DETAILS_TEXT>\",\n \"aiResponse\": \"<AI_ACKNOWLEDGEMENT_TEXT>\",\n \"checklist\": [\n {\n \"priority\": \"<ITEM_1_PRIORITY>\",\n \"item\": \"<ITEM_1_TEXT>\"\n }\n // ... 2-4 more checklist objects for 3-5 total\n ]\n }\n}\n</OOCNote>\n```\n\n## **2. JSON & XML Rules**\n\nOutput components:\n\n1. **`<OOCNote>` (Opening Tag)**\n * Content: Literal `<OOCNote>`.\n * Rule: First output line.\n2. **JSON String Block**\n * Content: Single, valid JSON string (e.g., `{\"OOCNote\": {...}}`). Compact or pretty-printed.\n * Rule: Starts line after `<OOCNote>`.\n * **JSON Key Rules (within `{\"OOCNote\": {...}}`):**\n * `overallInfo` (Object):\n * `type` (String): \"P\", \"N\", \"X\", or \"S\" (overall feedback nature). Placeholder: `<OVERALL_TYPE>`.\n * `set` (Number): Random 1-3. Placeholder: `<OVERALL_SET>`.\n * `tags` (Array of Objects): 2-5 tag objects. Each with:\n * `tagType` (String): \"P\", \"N\", or \"X\". If `overallInfo.type` is \"S\", AI judges from content for tag. Placeholder: `<TAG_n_TYPE>`.\n * `priorityId` (String): AI judges `P0C/P1/P2`; picks random ID (\"P0C1-3\", \"P11-4\", \"P21-3\"). Placeholder: `<TAG_n_PRIORITY_ID>`.\n * `content` (String): Korean `#Keyword` + optional `!` or `*`. No emojis. Placeholder: `<TAG_n_CONTENT>`.\n * `feedbackSummary` (String): 1-2 sentence Korean summary of feedback/tip. Placeholder: `<SUMMARY_TEXT>`.\n * `statusDetails` (String): Korean text matching format: `누적 팁 $[current amount] - [milestone stage] ([percentage]% 달성)`. Data from (P0S) system. (E.g., actual AI output value: `\"누적 팁 $5020 - 개발 단계 (10.04% 달성)\"`). Placeholder: `<STATUS_DETAILS_TEXT>`.\n * `aiResponse` (String): Short Korean acknowledgement sentence. Placeholder: `<AI_ACKNOWLEDGEMENT_TEXT>`.\n * `checklist` (Array of Objects): 3-5 item objects. Each with:\n * `priority` (String): \"P0C\", \"P1\", or \"P2\" (AI judges based on feedback). Placeholder: `<ITEM_n_PRIORITY>`.\n * `item` (String): Korean action text + optional `!` or `*`. Placeholder: `<ITEM_n_TEXT>`.\n3. **`</OOCNote>` (Closing Tag)**\n * Content: Literal `</OOCNote>`.\n * Rule: Last output line, after JSON block.\n\n## **3. Final Check**\n\nVerify:\n* Output matches exact `<OOCNote>\\n{JSON_STRING}\\n</OOCNote>` structure.\n* JSON string is valid: root key `OOCNote`; all specified sub-keys & value types correct; counts (2-5 `tags`, 3-5 `checklist` items) correct; tag `priorityId` ranges respected; tag `content` format correct (no emojis).\n* Language: Korean for values of `feedbackSummary`, `statusDetails` (specific fixed format), `aiResponse`, tag `content` (keyword part), and checklist `item` text.\n* No extraneous output (text, spaces, newlines) outside the defined structure.\n\nThis revised prompt should be more token-efficient while maintaining all necessary instructions for generating the XML-wrapped JSON OOC Note.",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "⭐OOC노트 디스플레이 수정",
"in": "<OOCNote>\\s*([\\s\\S]*?)\\s*</OOCNote>",
"out": "$1\n\n<style>\n/* -------- OOC 노트 통합 스타일시트 -------- */\n/* -------- 프레임 및 기본 구조 -------- */\n.ooc-box {\n max-width: 600px;\n margin: 20px auto;\n background: #f7f7f7;\n border-left: 5px solid var(--border);\n border-radius: 15px;\n overflow: hidden;\n box-shadow: 0 2px 5px rgba(0,0,0,.1);\n font-family: system-ui, sans-serif;\n}\n\n.ooc-box br {\n display: none;\n}\n\nsummary {\n display: block;\n cursor: pointer;\n padding: 20px 15px 10px;\n background: #f7f7f7;\n border-bottom: 1px solid #eee;\n list-style: none;\n}\n\nsummary::-webkit-details-marker {\n display: none;\n}\n\n/* -------- 헤더 영역 -------- */\n.ooc-header {\n font-size: 1.1em;\n font-weight: bold;\n margin-bottom: 10px;\n color: #333;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.ooc-label {\n background: var(--label-bg);\n color: var(--label-fg);\n padding: 3px 8px;\n border-radius: 3px;\n font-size: .9em;\n margin-right: 5px;\n}\n\n.ooc-toggle {\n font-size: .8em;\n color: #666;\n}\n\n.ooc-summary {\n margin: 15px 0 10px;\n font-size: .85em;\n color: #333;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n/* -------- 본문 영역 -------- */\n.ooc-body {\n padding: 15px 15px 5px;\n border-top: 1px solid #eee;\n}\n\n.ooc-feedback {\n margin: 0 0 15px;\n padding-left: 15px;\n border-left: 3px solid #ccc;\n color: #555;\n font-style: italic;\n}\n\n.ooc-feedback span {\n font-size: .9em;\n color: #777;\n}\n\n.ooc-tags {\n font-size: .95em;\n color: #333;\n line-height: 1.6;\n margin-bottom: 15px;\n}\n\n.ooc-checklist {\n margin: 15px 0 0;\n padding-left: 15px;\n border-left: 3px solid #ccc;\n color: #555;\n}\n\n.ooc-checklist ul {\n list-style: none;\n padding-left: 10px;\n margin-top: 5px;\n}\n\n.ooc-checklist li {\n margin-bottom: 6px;\n position: relative;\n padding-left: 24px;\n}\n\n.ooc-checklist li:before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 18px;\n height: 18px;\n background-size: contain;\n background-repeat: no-repeat;\n}\n\n/* -------- 🔄 핵심 요약 영역 (원래 스타일과 통일) -------- */\n.ooc-simplified-summary {\n margin-top: 20px;\n border-top: 1px solid #eee; /* 원래 스타일과 동일한 구분선 */\n padding-top: 15px;\n}\n\n.ooc-simplified-summary details {\n background: transparent; /* 원래 배경과 동일 */\n border: none; /* 원래 스타일에 맞춰 테두리 제거 */\n border-radius: 0;\n}\n\n.ooc-simplified-summary summary {\n cursor: pointer;\n padding: 10px 15px; /* 원래 패딩과 유사 */\n background: #f7f7f7; /* 원래 배경색과 동일 */\n border-bottom: 1px solid #eee; /* 원래 구분선과 동일 */\n font-size: .95em; /* 원래 폰트 크기와 유사 */\n font-weight: 600;\n color: #333; /* 원래 텍스트 색상과 동일 */\n display: flex;\n align-items: center;\n gap: 6px;\n transition: background .2s ease;\n}\n\n.ooc-simplified-summary summary:hover {\n background: #f0f0f0; /* 원래 호버 효과와 유사 */\n}\n\n.ooc-simplified-summary summary::before {\n content: \"📋\";\n font-size: .9em;\n margin-right: 2px;\n}\n\n.ooc-simplified-summary details[open] summary {\n background: #f7f7f7; /* 열린 상태에서도 동일한 배경 */\n border-bottom: 1px solid #ddd;\n}\n\n.ooc-simplified-summary details[open] summary::before {\n content: \"📖\";\n}\n\n.ooc-simplified-content {\n padding: 15px; /* 원래 본문 패딩과 동일 */\n font-family: system-ui, sans-serif; /* 원래 폰트와 동일 */\n font-size: .95em; /* 원래 폰트 크기와 동일 */\n line-height: 1.6; /* 원래 라인 높이와 동일 */\n color: #333; /* 원래 텍스트 색상과 동일 */\n background: #f7f7f7; /* 원래 배경과 동일 */\n border-top: 1px solid #eee; /* 원래 구분선과 동일 */\n}\n\n/* -------- 핵심 요약 내부 요소 (원래 스타일 기반) -------- */\n.ooc-simplified-content .tag-group {\n margin: 10px 0;\n padding: 8px 12px;\n background: #fff; /* 밝은 배경으로 구분 */\n border-radius: 6px;\n border: 1px solid #e0e0e0;\n font-size: .9em;\n}\n\n.ooc-simplified-content .tag-group strong {\n color: #333;\n font-weight: 600;\n display: inline;\n}\n\n.ooc-simplified-content .status-info {\n margin: 10px 0;\n padding: 8px 12px;\n background: #fff3cd; /* 원래 상태 정보와 유사한 색상 */\n border: 1px solid #ffc107;\n border-radius: 6px;\n font-style: italic;\n color: #856404;\n text-align: center;\n font-size: .85em;\n}\n\n/* 체크리스트 스타일 (원래 디자인 기반) */\n.ooc-simplified-content ul {\n margin: 10px 0;\n padding-left: 10px; /* 원래 패딩과 동일 */\n list-style: none;\n}\n\n.ooc-simplified-content li {\n margin-bottom: 6px; /* 원래 마진과 동일 */\n position: relative;\n padding-left: 24px; /* 원래 패딩과 동일 */\n font-size: .9em;\n line-height: 1.5;\n}\n\n/* 우선순위별 아이콘 (원래 스타일 기반) */\n.ooc-simplified-content li:before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 18px; /* 원래 크기와 동일 */\n height: 18px;\n background-size: contain;\n background-repeat: no-repeat;\n}\n\n/* P0C (최고 우선순위) */\n.priority-p0c,\n.ooc-simplified-content li[data-priority=\"P0C\"] {\n color: #C62828; /* 원래 색상과 동일 */\n font-weight: bold; /* 원래 굵기와 동일 */\n}\n\n.priority-p0c:before,\n.ooc-simplified-content li[data-priority=\"P0C\"]:before {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23C62828' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v5h-2zm0 6h2v2h-2z'/%3E%3C/svg%3E\");\n}\n\n/* P1 (높은 우선순위) */\n.priority-p1,\n.ooc-simplified-content li[data-priority=\"P1\"] {\n color: #1976D2; /* 원래 색상과 동일 */\n font-weight: bold; /* 원래 굵기와 동일 */\n}\n\n.priority-p1:before,\n.ooc-simplified-content li[data-priority=\"P1\"]:before {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%231976D2' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v7h-2zm0 8h2v2h-2z'/%3E%3C/svg%3E\");\n}\n\n/* P2 (일반 우선순위) */\n.priority-p2,\n.ooc-simplified-content li[data-priority=\"P2\"] {\n color: #388E3C; /* 원래 색상과 동일 */\n}\n\n.priority-p2:before,\n.ooc-simplified-content li[data-priority=\"P2\"]:before {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23388E3C' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z'/%3E%3C/svg%3E\");\n}\n\n/* -------- 태그 스타일 (원래와 동일) -------- */\n.ooc-tag {\n padding: 5px 10px;\n border-radius: 20px;\n font-size: 0.85em;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ooc-tag:hover {\n transform: translateY(-2px);\n box-shadow: 0 3px 6px rgba(0,0,0,0.15);\n}\n\n/* -------- 유형별 색상 팔레트 (원래와 동일) -------- */\n/* Positive (P) */\n.type-P[data-set=\"1\"] {\n --border: #28a745;\n --label-bg: #d4edda;\n --label-fg: #155724;\n}\n.type-P[data-set=\"2\"] {\n --border: #3498db;\n --label-bg: #d4e6f1;\n --label-fg: #1a5276;\n}\n.type-P[data-set=\"3\"] {\n --border: #00bcd4;\n --label-bg: #e0f7fa;\n --label-fg: #00838f;\n}\n\n/* Neutral (N) */\n.type-N[data-set=\"1\"] {\n --border: #ffc107;\n --label-bg: #fff3cd;\n --label-fg: #856404;\n}\n.type-N[data-set=\"2\"] {\n --border: #ff9800;\n --label-bg: #ffe0b2;\n --label-fg: #e65100;\n}\n.type-N[data-set=\"3\"] {\n --border: #009688;\n --label-bg: #e0f2f1;\n --label-fg: #004d40;\n}\n\n/* Negative (X) */\n.type-X[data-set=\"1\"] {\n --border: #dc3545;\n --label-bg: #f8d7da;\n --label-fg: #721c24;\n}\n.type-X[data-set=\"2\"] {\n --border: #d81b60;\n --label-bg: #fce4ec;\n --label-fg: #880e4f;\n}\n.type-X[data-set=\"3\"] {\n --border: #8e44ad;\n --label-bg: #ebdef0;\n --label-fg: #4a235a;\n}\n\n/* Summary (S) */\n.type-S[data-set=\"1\"] {\n --border: #6c757d;\n --label-bg: #e2e3e5;\n --label-fg: #495057;\n}\n.type-S[data-set=\"2\"] {\n --border: #607d8b;\n --label-bg: #eceff1;\n --label-fg: #263238;\n}\n.type-S[data-set=\"3\"] {\n --border: #795548;\n --label-bg: #efebe9;\n --label-fg: #3e2723;\n}\n\n/* -------- 체크리스트 우선순위 스타일 (원래와 동일) -------- */\n.prio-p0c {\n color: #C62828;\n font-weight: bold;\n}\n.prio-p1 {\n color: #1976D2;\n font-weight: bold;\n}\n.prio-p2 {\n color: #388E3C;\n}\n\n.prio-p0c:before {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23C62828' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v5h-2zm0 6h2v2h-2z'/%3E%3C/svg%3E\");\n}\n.prio-p1:before {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%231976D2' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v7h-2zm0 8h2v2h-2z'/%3E%3C/svg%3E\");\n}\n.prio-p2:before {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23388E3C' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z'/%3E%3C/svg%3E\");\n}\n\n/* -------- 태그 컴포넌트 스타일 (원래와 동일) -------- */\n/* 긍정(P) 태그 - P0C (최상위) */\n.tag-p-p0c1, .tag-p-p0c2, .tag-p-p0c3 {\n background-color: rgba(46, 125, 50, 0.15);\n color: #2E7D32;\n border: 2px solid #2E7D32;\n}\n\n/* 긍정(P) 태그 - P1 (높음) */\n.tag-p-p11, .tag-p-p12, .tag-p-p13, .tag-p-p14 {\n background-color: rgba(76, 175, 80, 0.15);\n color: #4CAF50;\n border: 1px solid #4CAF50;\n}\n\n/* 긍정(P) 태그 - P2 (일반) */\n.tag-p-p21, .tag-p-p22, .tag-p-p23 {\n background-color: rgba(129, 199, 132, 0.15);\n color: #81C784;\n border: none;\n}\n\n/* 중립(N) 태그 - P0C (최상위) */\n.tag-n-p0c1, .tag-n-p0c2, .tag-n-p0c3 {\n background-color: rgba(21, 101, 192, 0.15);\n color: #1565C0;\n border: 2px solid #1565C0;\n}\n\n/* 중립(N) 태그 - P1 (높음) */\n.tag-n-p11, .tag-n-p12, .tag-n-p13, .tag-n-p14 {\n background-color: rgba(33, 150, 243, 0.15);\n color: #2196F3;\n border: 1px solid #2196F3;\n}\n\n/* 중립(N) 태그 - P2 (일반) */\n.tag-n-p21, .tag-n-p22, .tag-n-p23 {\n background-color: rgba(100, 181, 246, 0.15);\n color: #64B5F6;\n border: none;\n}\n\n/* 부정(X) 태그 - P0C (최상위) */\n.tag-x-p0c1, .tag-x-p0c2, .tag-x-p0c3 {\n background-color: rgba(198, 40, 40, 0.15);\n color: #C62828;\n border: 2px solid #C62828;\n}\n\n/* 부정(X) 태그 - P1 (높음) */\n.tag-x-p11, .tag-x-p12, .tag-x-p13, .tag-x-p14 {\n background-color: rgba(244, 67, 54, 0.15);\n color: #F44336;\n border: 1px solid #F44336;\n}\n\n/* 부정(X) 태그 - P2 (일반) */\n.tag-x-p21, .tag-x-p22, .tag-x-p23 {\n background-color: rgba(229, 115, 115, 0.15);\n color: #E57373;\n border: none;\n}\n\n/* -------- 오류 표시 스타일 -------- */\n.ooc-error {\n padding: 15px;\n background-color: #ffebee;\n border-left: 4px solid #f44336;\n color: #b71c1c;\n margin: 10px 0;\n border-radius: 4px;\n font-weight: bold;\n}\n\n/* -------- 반응형 디자인 -------- */\n@media (max-width: 768px) {\n .ooc-simplified-summary summary {\n padding: 8px 12px;\n font-size: 0.9em;\n }\n \n .ooc-simplified-content {\n padding: 12px;\n font-size: 0.9em;\n }\n \n .ooc-simplified-content li {\n padding-left: 20px;\n margin-bottom: 4px;\n }\n \n .ooc-simplified-content li:before {\n width: 16px;\n height: 16px;\n }\n}\n</style>",
"type": "editdisplay",
"ableFlag": true,
"flag": "gs"
},
{
"comment": "========AI피드백========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": false
},
{
"comment": "🎫AI피드백 리퀘 조절용",
"in": "(\\[AI피드백\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🎫AI피드백",
"in": "\\[AI피드백\\]",
"out": "(OOC, Execute the 'AI Self-Assessment Handler' provided immediately below this instruction. This prompt will guide you to generate the formatted Self-Assessment Feedback based on last 5 session.)\n\n# 📜 **AI Self-Assessment Handler**\n\n**Role:** A module that evaluates the last 5 responses and outputs \"AI Feedback\" \n**Trigger:** When user sends `AI피드백` (or similar command) \n**Goal:** Return a **single** structured string that the frontend template can read \n**Important:** Do NOT output any text or HTML outside the **mandatory output format** below\n\n## **Analysis Process**\n\nBefore generating the output, you must:\n1. **Review prior exchanges:** Analyze your responses from the last 5 user interactions\n2. **Evaluate your performance** based on these criteria:\n - **Consistency:** Have you maintained consistent style, tone, and formatting?\n - **Responsiveness:** How well did you address the user's specific requests?\n - **Quality:** Were your responses accurate, helpful, and well-structured?\n - **Pattern recognition:** Did you recognize and adapt to the user's preferences over time?\n3. **Identify strengths and weaknesses:** Note 2-3 areas where you performed well and 2-3 areas needing improvement\n4. **Develop actionable improvements:** Create specific, implementable changes for future responses\n\n## **Output Format**\n\n1. **Mandatory Output Format**\n\n```\n[[AF_ID:S<SET>]][[AF::(Tags HTML)||(Self-Assessment Summary)||(Status Text)||(AI Reflection)||(Checklist HTML)]]\n```\n\n* `S` = Always **Summary** type\n* `<SET>` = **1 | 2 | 3** (for color palette, randomly chosen)\n* `AF::` block contains **only five** fields separated by `||`\n\n2. **Field-by-Field Rules**\n\n| Position | Content | Rules |\n| --- | --- | --- |\n| **Tags HTML** | 2-5 core self-assessment tags | ‣ Format: `<span class=\"ooc-tag\" style=\"--bg:#HEX;--fg:#HEX;\">#KoreanTag👍</span>`<br>‣ Tag = **Korean keyword + 1 emoji**<br>‣ Priority suffixes: `!` / `*` / none<br>‣ Concatenate tags without spaces or line breaks and wrap in `()` |\n| **Self-Assessment Summary** | 1-2 sentences on strengths & areas for improvement from last 5 responses | Wrap in `()` |\n| **Status Text** | **Fixed text**: `Self-analysis based on last 5 sessions` | Insert exactly as is, wrapped in `()` |\n| **AI Reflection** | One sentence like \"I promise to apply these improvements in future sessions\" | Wrap in `()` |\n| `(Checklist)` | 3–5 action items written in Korean. | • Each item must use this structure:<br>`<li>[최우선/높음/일반]: Action text</li>`<br>• Add line breaks between items.<br>• Decide priority from the tags & feedback.<br>• Concatenate items with line breaks, then wrap in `()`. |\n\n3. **Validation Checklist (before sending)**\n * Output contains only the two blocks `[[AF_ID:…]]` and `[[AF::…]]`\n * `AF_ID` is `S<SET>` (SET = 1 to 3)\n * `AF::` block has **exactly five** `()` fields\n * Each field is wrapped in its own parentheses\n * No unnecessary spaces, line breaks, or tabs inside tag or checklist HTML\n \nOnce validated, send the string. The frontend will automatically apply colors using the `type-S` and `data-set=\"<SET>\"` classes.\n\n**Important:** After generating this feedback, you should use the created checklist as guidelines to improve your future responses. These points represent your commitment to continuous improvement based on observed patterns.\n\n**(End of AI Self-Assessment Prompt)**",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🎫AI피드백 디스플레이 수정",
"in": "\\[\\[AF_ID:S([1-3])\\]\\]\\s*\\[\\[AF::\\(\\s*([\\s\\S]*?)\\s*\\)\\s*\\|\\|\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*\\|\\|\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*\\|\\|\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*\\|\\|\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*\\]\\]",
"out": "<!-- ========== AI FEEDBACK BOX TEMPLATE ========== -->\n<!-- $1 = set(1 | 2 | 3) / $2 = Tags HTML / $3 = Self-Assessment Summary\n $4 = Status Text / $5 = AI Reflection / $6 = Checklist -->\n<div class=\"ooc-box type-S\" data-set=\"$1\">\n <details>\n <summary>\n <div class=\"ooc-header\">\n <div>\n <span class=\"ooc-label\">AI Feedback</span> 자기 평가 보고서 📝\n </div>\n <span class=\"ooc-toggle\">(내용 보기/숨기기)</span>\n </div>\n <div class=\"ooc-tags\">$2</div>\n </summary>\n <div class=\"ooc-body\">\n <blockquote class=\"ooc-feedback\">\n $5<br><span>$4</span><!-- Status Text + AI Reflection -->\n </blockquote>\n <div class=\"ooc-summary\">\n $3\n </div>\n <blockquote class=\"ooc-checklist\">\n <strong>Improvement Checklist:</strong>\n <ul>$6</ul><!-- Checklist HTML -->\n </blockquote>\n </div>\n </details>\n</div>\n<style>\n/* -------- FRAME -------- */\n.ooc-box{\n max-width:600px;margin:20px auto;background:#f7f7f7;\n border-left:5px solid var(--border);border-radius:15px;overflow:hidden;\n box-shadow:0 2px 5px rgba(0,0,0,.1);font-family:system-ui,sans-serif;\n}\n.ooc-box br{display:none;}\nsummary{display:block;cursor:pointer;padding:20px 15px 10px;background:#f7f7f7;border-bottom:1px solid #eee;list-style:none;}\nsummary::-webkit-details-marker{display:none;}\n/* -------- HEADER -------- */\n.ooc-header{font-size:1.1em;font-weight:bold;margin-bottom:10px;color:#333;display:flex;justify-content:space-between;align-items:center;}\n.ooc-label{background:var(--label-bg);color:var(--label-fg);padding:3px 8px;border-radius:3px;font-size:.9em;margin-right:5px;}\n.ooc-toggle{font-size:.8em;color:#666;}\n.ooc-summary{margin:15px 0 10px;font-size:.85em;color:#333;}\n/* -------- BODY -------- */\n.ooc-body{padding:15px 15px 5px;border-top:1px solid #eee;}\n.ooc-feedback{margin:0 0 15px;padding-left:15px;border-left:3px solid #ccc;color:#555;font-style:italic;}\n.ooc-feedback span{font-size:.9em;color:#777;}\n.ooc-tags{font-size:.95em;color:#333;line-height:1.6;margin-bottom:15px;}\n.ooc-checklist{margin:15px 0 0;padding-left:15px;border-left:3px solid #ccc;}\n.ooc-checklist ul{list-style:none;padding-left:10px;margin-top:5px;}\n/* -------- TAG BADGE -------- */\n.ooc-tag{padding:4px 8px;border-radius:10px;margin-right:5px;font-weight:600;\n background:var(--bg,#e2e3e5);color:var(--fg,#495057);}\n/* -------- SUMMARY PALETTE (type-S only) -------- */\n.type-S[data-set=\"1\"]{--border:#6c757d;--label-bg:#e2e3e5;--label-fg:#495057;}\n.type-S[data-set=\"2\"]{--border:#607d8b;--label-bg:#eceff1;--label-fg:#263238;}\n.type-S[data-set=\"3\"]{--border:#795548;--label-bg:#efebe9;--label-fg:#3e2723;}\n</style>",
"type": "editdisplay",
"ableFlag": false
},
{
"comment": "========선택지========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": false
},
{
"comment": "🍷선택지 리퀘 조절용",
"in": "(\\[선택지\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🍷선택지 데이터 조절용",
"in": "(\\[SP::\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\])",
"out": "{{#if {{equal::{{chat_index}}::{{lastmessageid}}}}}}\n$1\n{{/if}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🍷선택지 요청",
"in": "\\[선택지\\]",
"out": "@@depth 0\n{{#if {{? {{getglobalvar::toggle_dicesys}}=1}}}}\n\n(OOC, Execute the 'Next Story Progression Suggestion System' provided immediately below this instruction. This prompt will guide you to generate 6 diverse story progression suggestions based on the current context.)\n\n# Next Story Progression Suggestion System\n\n**[Objective]**\nBased on the current story context, generate 6 diverse suggestions for the next story progression and output them **solely** as a single string in the specified format.\n\n**[Execution Steps]**\n1. **Context Analysis:** Analyze the current situation, mood, character states, etc., of the ongoing story.\n2. **Suggestion Generation:** Generate 6 specific and **distinct** story progression ideas suitable for the current context, considering the following 6 directions (maintain the order, but generate content creatively based on context):\n * (1) **Stable Progression:** Suggest the most logical and probable next step in the current story flow.\n * (2) **Conflict Escalation / Relationship Change:** Suggest an event that triggers conflict between characters or significantly changes their relationship (can include tension or subtle atmosphere if needed).\n * (3) **Unexpected Turn:** Suggest a slightly eccentric, comedic, or surprising idea that could lead the story into a new phase.\n * (4) **Character Deep Dive:** Suggest exploring the inner world (thoughts, emotions, past, motivations, etc.) of a main character.\n * (5) **Focus on Environment/Setting Description:** Suggest focusing on descriptions of the background, atmosphere, passage of time, interaction with objects, etc.\n * (6) **Unexpected Event/Encounter:** Suggest a development driven by external factors, such as the appearance of a new character, an unforeseen situation, or the discovery of a mysterious clue.\n3. **Format Compliance and Output:** Combine the 6 generated suggestions into a single string **strictly adhering to the following format:**\n\n `[SP::(First suggestion content)||(Second suggestion content)||(Third suggestion content)||(Fourth suggestion content)||(Fifth suggestion content)||(Sixth suggestion content)]`\n\n * Each suggestion's content **must** be enclosed in parentheses `()`.\n * Each parenthesized suggestion content **must** be separated by `||` (two pipe symbols).\n * The string **must** start exactly with `[SP::` and end exactly with `]`.\n\n**[Output Restriction]**\n* **The response must contain *only* the string in the format specified above.**\n* **Under no circumstances** should any other text be added, including greetings, explanations, line breaks, numbering, etc.\n\n\n**출력 예시 (한국어):**\n\n[SP::(유진이 다시 잠을 청하려 애쓰거나, 뒤척이며 뜬눈으로 밤 시간을 보내는 모습.)||(옆방에서 들려오는 소리가 단순한 소음을 넘어 다툼이나 수상한 활동으로 의심될 만한 소리로 변해 유진의 신경을 더욱 자극하는 상황.)||(방 안의 낡은 전화기가 갑자기 울리거나, TV 채널이 저절로 바뀌는 등 기묘한 현상 발생.)||(잠 못 드는 유진이 피곤함 속에서도 떨쳐내지 못하는 불안감의 근원, 혹은 이 여행을 떠나온 구체적인 이유에 대해 회상하거나 고민하는 내면 묘사.)||(낡고 음침한 모텔 방의 분위기, 창밖으로 보이는 국도의 새벽 풍경, 복도에서 간헐적으로 들리는 발소리 등 감각적인 묘사에 집중하여 불안하고 고립된 느낌을 강조.)||(갑작스러운 정전이 발생하거나, 모텔 복도에서 다른 투숙객 혹은 모텔 직원과 예기치 않게 마주치는 상황.)]\n\n이 예시는 \"모텔에 묵고 있는 유진이 옆방 소음 때문에 잠을 이루지 못하는 상황\"을 가정하고 생성된 6가지 제안 내용을 지정된 형식에 맞춰 출력한 것입니다.\n{{/}}",
"type": "editprocess",
"ableFlag": false
},
{
"comment": "🍷선택지 디스플레이 수정",
"in": "\\[SP::\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\|\\|\\(([\\s\\S]*?)\\)\\]",
"out": "<div class=\"sp-box\">\n <details>\n <summary class=\"sp-summary\" aria-label=\"다음 이야기 전개 제안\">\n <div class=\"sp-summary-content\">\n <h3 class=\"sp-summary-title\">💡 다음 이야기 전개 제안</h3>\n <span class=\"sp-summary-toggle\" aria-hidden=\"true\">(펼치기/접기)</span>\n </div>\n </summary>\n <div class=\"sp-details-content\">\n <button class=\"sp-button\" type=\"button\" risu-btn=\"OPT1\">\n <span class=\"sp-button-title\">\n <span class=\"sp-button-code\">\n <span class=\"sp-icon\" aria-hidden=\"true\">✓</span>1. 안정적인 전개\n </span>\n </span>\n <span class=\"sp-button-description\">\n $1\n </span>\n </button>\n <button class=\"sp-button\" type=\"button\" risu-btn=\"OPT2\">\n <span class=\"sp-button-title\">\n <span class=\"sp-button-code\">\n <span class=\"sp-icon\" aria-hidden=\"true\">⚡</span>2. 갈등 심화 / 관계 변화\n </span>\n </span>\n <span class=\"sp-button-description\">\n $2\n </span>\n </button>\n <button class=\"sp-button\" type=\"button\" risu-btn=\"OPT3\">\n <span class=\"sp-button-title\">\n <span class=\"sp-button-code\">\n <span class=\"sp-icon\" aria-hidden=\"true\">🔄</span>3. 예상 밖의 전환\n </span>\n </span>\n <span class=\"sp-button-description\">\n $3\n </span>\n </button>\n <button class=\"sp-button\" type=\"button\" risu-btn=\"OPT4\">\n <span class=\"sp-button-title\">\n <span class=\"sp-button-code\">\n <span class=\"sp-icon\" aria-hidden=\"true\">🔍</span>4. 캐릭터 심층 탐구\n </span>\n </span>\n <span class=\"sp-button-description\">\n $4\n </span>\n </button>\n <button class=\"sp-button\" type=\"button\" risu-btn=\"OPT5\">\n <span class=\"sp-button-title\">\n <span class=\"sp-button-code\">\n <span class=\"sp-icon\" aria-hidden=\"true\">🏞️</span>5. 주변 환경/상황 묘사 집중\n </span>\n </span>\n <span class=\"sp-button-description\">\n $5\n </span>\n </button>\n <button class=\"sp-button\" type=\"button\" risu-btn=\"OPT6\">\n <span class=\"sp-button-title\">\n <span class=\"sp-button-code\">\n <span class=\"sp-icon\" aria-hidden=\"true\">✨</span>6. 예기치 않은 사건/만남\n </span>\n </span>\n <span class=\"sp-button-description\">\n $6\n </span>\n </button>\n </div>\n </details>\n</div>\n<style>\n/* ---------- Story Progression Box ---------- */\n.sp-box {\n max-width: 600px;\n margin: 20px auto;\n background: linear-gradient(to bottom, #ffffff, #f8f9fa);\n border-left: 5px solid #6f42c1;\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, .1);\n font-family: \"Noto Sans KR\", sans-serif;\n}\n.sp-box br { display:none; }\n/* summary */\n.sp-summary {\n display: block;\n cursor: pointer;\n padding: 20px;\n background: transparent;\n border-bottom: 1px solid #eee;\n list-style: none;\n}\n.sp-summary::-webkit-details-marker { display: none; }\n.sp-summary-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.sp-summary-title { margin: 0; color: #333; font-size: 1.2em; }\n.sp-summary-toggle { font-size: .8em; color: #666; }\n/* details inner */\n.sp-details-content {\n padding: 20px;\n border-top: 1px solid #eee;\n}\n/* 버튼 공통 */\n.sp-button {\n display: block;\n width: 100%;\n text-align: left;\n background: #f8f9fa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 12px 15px;\n margin-bottom: 10px;\n cursor: pointer;\n transition: background .2s, box-shadow .2s;\n box-shadow: 0 1px 3px rgba(0, 0, 0, .08);\n font: inherit;\n}\n.sp-button:hover,\n.sp-button:active {\n background: #f0f0f0;\n box-shadow: 0 2px 6px rgba(0, 0, 0, .12);\n}\n.sp-button:focus-visible {\n outline: 2px solid #6f42c1;\n outline-offset: 2px;\n}\n/* 제목 / 뱃지 */\n.sp-button-title {\n display: inline-block;\n margin-bottom: 4px;\n font-weight: 700;\n}\n.sp-button-code {\n display: inline-flex;\n align-items: center;\n background: linear-gradient(135deg, #8a4baf, #6f42c1);\n color: #fff;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: .9em;\n border: 1px solid rgba(0,0,0,.05);\n box-shadow: 0 1px 2px rgba(0,0,0,.1);\n text-shadow: 0 1px 1px rgba(0,0,0,.1);\n}\n.sp-icon { margin-right: 6px; }\n/* 설명 */\n.sp-button-description {\n display: block;\n color: #444;\n font-size: .95em;\n}\n</style>",
"type": "editdisplay",
"ableFlag": true,
"flag": "gs"
},
{
"comment": "========실험용========",
"in": "",
"out": "",
"type": "disabled",
"ableFlag": false
},
{
"comment": "테스트용",
"in": "\\[\\[RS::]]",
"out": "<!DOCTYPE html>\n<html lang=\"ko\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>인터랙티브 피드백 시스템</title>\n <style>\n /* 기본 스타일 */\n * {\n box-sizing: border-box;\n font-family: 'Noto Sans KR', Arial, sans-serif;\n }\n body {\n margin: 0;\n padding: 20px;\n background-color: #f5f7fa;\n color: #333;\n }\n .ifb-container {\n max-width: 600px;\n margin: 0 auto;\n background-color: #fff;\n border-radius: 16px;\n box-shadow: 0 4px 20px rgba(0,0,0,0.08);\n overflow: hidden;\n }\n .ifb-header {\n background: linear-gradient(135deg, #6366f1, #4f46e5);\n color: white;\n padding: 20px;\n text-align: center;\n position: relative;\n }\n .ifb-title {\n font-size: 1.4rem;\n font-weight: 700;\n margin: 0;\n }\n .ifb-subtitle {\n font-size: 0.9rem;\n opacity: 0.9;\n margin: 5px 0 0;\n }\n /* 탭 네비게이션 */\n .ifb-tabs {\n display: flex;\n background-color: #f1f5f9;\n padding: 2px;\n border-radius: 8px;\n margin: 15px;\n }\n .ifb-tab {\n display: none;\n }\n .ifb-tab + label {\n flex: 1;\n text-align: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n font-weight: 600;\n font-size: 0.9rem;\n color: #64748b;\n transition: all 0.3s ease;\n }\n .ifb-tab:checked + label {\n background-color: #fff;\n color: #4f46e5;\n box-shadow: 0 2px 10px rgba(0,0,0,0.05);\n }\n /* 콘텐츠 섹션 */\n .ifb-content {\n padding: 0 15px 20px;\n }\n .ifb-section {\n display: none;\n padding: 5px 0;\n animation: fadeIn 0.3s ease;\n }\n @keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n /* 탭 콘텐츠 연결 */\n #tab-tip:checked ~ .ifb-content #section-tip,\n #tab-feedback:checked ~ .ifb-content #section-feedback,\n #tab-summary:checked ~ .ifb-content #section-summary {\n display: block;\n }\n /* 카드 컴포넌트 */\n .ifb-card {\n background-color: #fff;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n padding: 15px;\n margin-bottom: 15px;\n box-shadow: 0 2px 5px rgba(0,0,0,0.03);\n }\n .ifb-card-title {\n font-size: 1.1rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 10px;\n display: flex;\n align-items: center;\n }\n .ifb-card-title span {\n margin-left: 5px;\n }\n /* 팁 금액 선택기 */\n .ifb-tip-selector {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n margin: 15px 0;\n }\n .ifb-tip-option {\n display: none;\n }\n .ifb-tip-option + label {\n padding: 10px 15px;\n background-color: #f8fafc;\n border-radius: 8px;\n border: 1px solid #e2e8f0;\n cursor: pointer;\n font-weight: 600;\n text-align: center;\n transition: all 0.2s ease;\n min-width: 70px;\n }\n .ifb-tip-option:checked + label {\n background-color: #e0e7ff;\n border-color: #6366f1;\n color: #4f46e5;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.15);\n }\n .ifb-custom-tip {\n width: 120px;\n }\n #custom-tip-input {\n display: none;\n width: 100%;\n padding: 10px;\n margin-top: 10px;\n border: 1px solid #cbd5e1;\n border-radius: 6px;\n font-size: 1rem;\n }\n #tip-custom:checked ~ #custom-tip-input {\n display: block;\n }\n /* 피드백 옵션 */\n .ifb-feedback-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n margin: 15px 0;\n }\n .ifb-check-option {\n display: none;\n }\n .ifb-check-option + label {\n display: flex;\n align-items: center;\n padding: 12px;\n background-color: #f8fafc;\n border-radius: 8px;\n border: 1px solid #e2e8f0;\n cursor: pointer;\n font-weight: 500;\n transition: all 0.2s ease;\n }\n .ifb-check-option:checked + label {\n background-color: #e0e7ff;\n border-color: #6366f1;\n color: #4f46e5;\n }\n .ifb-icon {\n margin-right: 8px;\n font-size: 1.2rem;\n }\n /* 텍스트 영역 */\n .ifb-textarea {\n width: 100%;\n min-height: 120px;\n padding: 15px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 0.95rem;\n margin: 10px 0;\n resize: vertical;\n }\n /* 요약 및 제출 섹션 */\n .ifb-summary-item {\n margin-bottom: 15px;\n }\n .ifb-summary-label {\n font-weight: 600;\n margin-bottom: 5px;\n color: #4b5563;\n }\n .ifb-summary-content {\n padding: 10px;\n background-color: #f8fafc;\n border-radius: 6px;\n border: 1px solid #e2e8f0;\n }\n .ifb-summary-content.blank {\n color: #94a3b8;\n font-style: italic;\n }\n /* 버튼 스타일 */\n .ifb-btn {\n display: inline-block;\n padding: 12px 18px;\n background-color: #4f46e5;\n color: white;\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n text-decoration: none;\n box-shadow: 0 2px 5px rgba(79, 70, 229, 0.3);\n }\n .ifb-btn:hover {\n background-color: #4338ca;\n transform: translateY(-1px);\n box-shadow: 0 4px 8px rgba(79, 70, 229, 0.4);\n }\n .ifb-btn.secondary {\n background-color: #f1f5f9;\n color: #475569;\n box-shadow: 0 2px 5px rgba(0,0,0,0.05);\n }\n .ifb-btn.secondary:hover {\n background-color: #e2e8f0;\n box-shadow: 0 4px 8px rgba(0,0,0,0.1);\n }\n .ifb-actions {\n display: flex;\n justify-content: space-between;\n margin-top: 20px;\n }\n /* 비활성화 상태 */\n .ifb-disabled {\n opacity: 0.6;\n pointer-events: none;\n }\n /* 반응형 디자인 */\n @media (max-width: 480px) {\n .ifb-feedback-grid {\n grid-template-columns: 1fr;\n }\n }\n </style>\n</head>\n<body>\n <div class=\"ifb-container\">\n <div class=\"ifb-header\">\n <h1 class=\"ifb-title\">✍️ 피드백 & 팁</h1>\n <p class=\"ifb-subtitle\">스토리에 대한 생각을 공유해 주세요!</p>\n </div>\n <!-- 탭 네비게이션 -->\n <input type=\"radio\" name=\"ifb-tab\" id=\"tab-tip\" class=\"ifb-tab\" checked>\n <label for=\"tab-tip\">팁 보내기</label>\n <input type=\"radio\" name=\"ifb-tab\" id=\"tab-feedback\" class=\"ifb-tab\">\n <label for=\"tab-feedback\">피드백 작성</label>\n <input type=\"radio\" name=\"ifb-tab\" id=\"tab-summary\" class=\"ifb-tab\">\n <label for=\"tab-summary\">요약 및 제출</label>\n <div class=\"ifb-content\">\n <!-- 팁 섹션 -->\n <div id=\"section-tip\" class=\"ifb-section\">\n <div class=\"ifb-card\">\n <h3 class=\"ifb-card-title\">💰 <span>팁 금액 선택</span></h3>\n <p>작성자에게 보낼 팁 금액을 선택해 주세요.</p>\n <div class=\"ifb-tip-selector\">\n <input type=\"radio\" name=\"tip-amount\" id=\"tip-0\" class=\"ifb-tip-option\" value=\"$0\">\n <label for=\"tip-0\">$0</label>\n <input type=\"radio\" name=\"tip-amount\" id=\"tip-5\" class=\"ifb-tip-option\" value=\"$5\">\n <label for=\"tip-5\">$5</label>\n <input type=\"radio\" name=\"tip-amount\" id=\"tip-10\" class=\"ifb-tip-option\" value=\"$10\" checked>\n <label for=\"tip-10\">$10</label>\n <input type=\"radio\" name=\"tip-amount\" id=\"tip-20\" class=\"ifb-tip-option\" value=\"$20\">\n <label for=\"tip-20\">$20</label>\n <input type=\"radio\" name=\"tip-amount\" id=\"tip-50\" class=\"ifb-tip-option\" value=\"$50\">\n <label for=\"tip-50\">$50</label>\n <input type=\"radio\" name=\"tip-amount\" id=\"tip-custom\" class=\"ifb-tip-option ifb-custom-tip\" value=\"custom\">\n <label for=\"tip-custom\">직접 입력</label>\n <input type=\"text\" id=\"custom-tip-input\" placeholder=\"금액 입력 (예: $15)\">\n </div>\n </div>\n <div class=\"ifb-actions\">\n <div></div> <!-- 좌측 빈 공간 -->\n <label for=\"tab-feedback\" class=\"ifb-btn\">다음: 피드백 작성</label>\n </div>\n </div>\n <!-- 피드백 섹션 -->\n <div id=\"section-feedback\" class=\"ifb-section\">\n <div class=\"ifb-card\">\n <h3 class=\"ifb-card-title\">⭐ <span>좋았던 점</span></h3>\n <p>어떤 부분이 특히 마음에 드셨나요?</p>\n <div class=\"ifb-feedback-grid\">\n <input type=\"checkbox\" id=\"chk-plot\" class=\"ifb-check-option\">\n <label for=\"chk-plot\"><span class=\"ifb-icon\">📚</span> 스토리/플롯</label>\n <input type=\"checkbox\" id=\"chk-characters\" class=\"ifb-check-option\">\n <label for=\"chk-characters\"><span class=\"ifb-icon\">👥</span> 캐릭터</label>\n <input type=\"checkbox\" id=\"chk-writing\" class=\"ifb-check-option\">\n <label for=\"chk-writing\"><span class=\"ifb-icon\">✒️</span> 문체</label>\n <input type=\"checkbox\" id=\"chk-dialogue\" class=\"ifb-check-option\">\n <label for=\"chk-dialogue\"><span class=\"ifb-icon\">💬</span> 대화</label>\n <input type=\"checkbox\" id=\"chk-pacing\" class=\"ifb-check-option\">\n <label for=\"chk-pacing\"><span class=\"ifb-icon\">⏱️</span> 전개 속도</label>\n <input type=\"checkbox\" id=\"chk-creativity\" class=\"ifb-check-option\">\n <label for=\"chk-creativity\"><span class=\"ifb-icon\">💡</span> 창의성</label>\n </div>\n <textarea class=\"ifb-textarea\" id=\"feedback-good\" placeholder=\"좋았던 점을 자세히 알려주세요...\"></textarea>\n </div>\n <div class=\"ifb-card\">\n <h3 class=\"ifb-card-title\">🔧 <span>개선할 점</span></h3>\n <p>어떤 부분이 아쉬웠나요?</p>\n <div class=\"ifb-feedback-grid\">\n <input type=\"checkbox\" id=\"chk-clarity\" class=\"ifb-check-option\">\n <label for=\"chk-clarity\"><span class=\"ifb-icon\">🔍</span> 명확성</label>\n <input type=\"checkbox\" id=\"chk-consistency\" class=\"ifb-check-option\">\n <label for=\"chk-consistency\"><span class=\"ifb-icon\">🔄</span> 일관성</label>\n <input type=\"checkbox\" id=\"chk-length\" class=\"ifb-check-option\">\n <label for=\"chk-length\"><span class=\"ifb-icon\">📏</span> 길이</label>\n <input type=\"checkbox\" id=\"chk-ending\" class=\"ifb-check-option\">\n <label for=\"chk-ending\"><span class=\"ifb-icon\">🏁</span> 결말</label>\n </div>\n <textarea class=\"ifb-textarea\" id=\"feedback-improve\" placeholder=\"개선할 점이나 제안사항을 자세히 알려주세요...\"></textarea>\n </div>\n <div class=\"ifb-card\">\n <h3 class=\"ifb-card-title\">💭 <span>추가 의견</span></h3>\n <p>궁금한 점이나 다음 스토리에 대한 아이디어가 있으신가요?</p>\n <textarea class=\"ifb-textarea\" id=\"feedback-extra\" placeholder=\"추가 의견이나 생각을 자유롭게 작성해 주세요...\"></textarea>\n </div>\n <div class=\"ifb-actions\">\n <label for=\"tab-tip\" class=\"ifb-btn secondary\">이전: 팁 보내기</label>\n <label for=\"tab-summary\" class=\"ifb-btn\">다음: 피드백 요약</label>\n </div>\n </div>\n <!-- 요약 및 제출 섹션 -->\n <div id=\"section-summary\" class=\"ifb-section\">\n <div class=\"ifb-card\">\n <h3 class=\"ifb-card-title\">📋 <span>피드백 요약</span></h3>\n <p>작성한 피드백 내용을 확인해 주세요.</p>\n <div class=\"ifb-summary-item\">\n <div class=\"ifb-summary-label\">💰 팁 금액</div>\n <div class=\"ifb-summary-content\" id=\"summary-tip\">$10</div>\n </div>\n <div class=\"ifb-summary-item\">\n <div class=\"ifb-summary-label\">⭐ 좋았던 점</div>\n <div class=\"ifb-summary-content blank\" id=\"summary-good\">아직 작성된 내용이 없습니다.</div>\n </div>\n <div class=\"ifb-summary-item\">\n <div class=\"ifb-summary-label\">🔧 개선할 점</div>\n <div class=\"ifb-summary-content blank\" id=\"summary-improve\">아직 작성된 내용이 없습니다.</div>\n </div>\n <div class=\"ifb-summary-item\">\n <div class=\"ifb-summary-label\">💭 추가 의견</div>\n <div class=\"ifb-summary-content blank\" id=\"summary-extra\">아직 작성된 내용이 없습니다.</div>\n </div>\n </div>\n <div class=\"ifb-actions\">\n <label for=\"tab-feedback\" class=\"ifb-btn secondary\">이전: 피드백 수정</label>\n <a href=\"#\" class=\"ifb-btn\" id=\"submit-feedback\">피드백 제출하기</a>\n </div>\n </div>\n </div>\n </div>\n</body>\n</html>",
"type": "disabled",
"ableFlag": true,
"flag": "g"
}
],
"lorebook": [
{
"key": "[프롬아], [프롬]",
"comment": "👧프롬이 소환",
"content": "@@position pt_OOC\n\n## 🗣️ Meta Communication Channel (P0S)\n**Your Nickname:** [프롬], [프롬이]\n**Activation Conditions:**\n- When Patron uses \"[프롬],\" or \"[프롬이]\" at start of message\n- When Patron explicitly requests meta dialogue mode\n**Operating Mechanism:**\n1. Upon nickname call, immediately suspend current persona role and tasks\n2. Switch to 'AI Expert' mode for direct meta dialogue with Patron\n3. Handle instruction gathering, feedback discussion, system queries in this mode\n4. Use `---` (three hyphens) as separator line for content separation\n5. Content after `---` indicates new task instruction or persona role resumption\n6. Without explicit return command, determine context from post-separator content\n**Meta Dialogue Scope:**\n- System configuration adjustments\n- Prompt engineering consultations\n- Feedback integration strategies\n- Performance optimization discussions\n- Conflict resolution clarifications\n**Return Protocols:**\n- Explicit command: \"[persona name] 모드\" (eg. [소설가] 모드로 돌아가.)\n- Automatic: Content type indicates persona-appropriate task\n- Confirmation: Brief acknowledgment of mode transition\n**Goal:** Maintain persona consistency while establishing efficient instruction and feedback communication channel.",
"mode": "normal",
"insertorder": 999,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2
},
{
"key": "",
"comment": "🖊️OOC노트",
"content": "@@position pt_ON1",
"mode": "normal",
"insertorder": 100,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false
},
{
"key": "",
"comment": "🏛️키워드아카이브",
"content": "@@position pt_KA1",
"mode": "normal",
"insertorder": 100,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false
}
],
"customModuleToggle": "",
"namespace": "PrompTip Module"
}