risum 모듈 — RISU modules[] — 기능 확장
조회 1467 · 2026-07-11
라이트보드 3.4.0: https://arca.live/b/characterai/158653254 ERA향 조교상태창 v2.11 마개조 최종: https://arca.live/b/characterai/157353985?target=title&keyword=%EC%A1%B0%EA%B5%90%EC%83%81%ED%83%9C%EC%B0%BD&p=1 페이블에 외주맡겼음 라이트보드 없으면 작동안함, 3.4.0으로 최신화시킴 마개조 최종버전에있는 기능과 동일하지만, 기존 남자던여자던 모두 여성의 상태창만 나오던것을 남자는 남자의 상태창이 나오도록 개조했음 다운로드: https://drive.proton.me/urls/HR0YMDRT2R#EoMfbNax7uiE
조교상태창 v2.11 마개조 최종 기반 + 남자 상태창 (성별 자동 감지) 이식 + 라이트보드 3.4.0 대응 (onValidate, multilingual)
{
"name": "💟🔹조교상태창(🔦) v2.11 마개조 최종+남자+LB3.4.0",
"description": "조교상태창 v2.11 마개조 최종 기반\n+ 남자 상태창 (성별 자동 감지) 이식\n+ 라이트보드 3.4.0 대응 (onValidate, multilingual)\n",
"id": "fc2a6c14-3dd8-43e1-b780-2be172804521",
"assets": [
[
"swn-placeholder",
"",
"webp"
]
],
"namespace": "",
"hideIcon": false,
"customModuleToggle": "=📿조교상태창(🔦)=group\nSWNTHEMES=📿컬러테마=select=🥀다크핑크,🕊️라이트,🌃 다크,📜세피아,🎖️군바리,💻Xterm\n=📿상태창 위치→모듈설정으로=divider\n==divider\nswn-statuswindow.mode=🔦라이트보드=select=끄기,메인,보조,자동\nswn-statuswindow.lazy=🔦상태창호출=select=즉시,누르면\nSWNRESETTT=🔦메인모델 채팅리퀘 제거\n==divider\nSWNSWITCH=상태창 방식=select=항상펼치기,토글(열기/닫기),토글(팝업)\n==divider\nSWNUSER=상태창 대상=select=NPC,USER,전체(시뮬봇)\nSWNNODESCUSER=(시뮬봇) 유저정보제외\nSWNNODESCMALE=(시뮬봇) 남자정보제외\nSWNDESCCNT=(시뮬봇) 표기수=select=1~3,1~5,무제한\n==divider\nSWNAFIELD1=관계정보 표기\nSWNAFIELD2=성격정보 표기\nSWNBFIELD1=신체정보 표기\nSWNRESETTT=❌재생성(리셋용)❌\nSWNRAMAIN=리퀘스트 유지=select=2개,무한(하이파용)\nSHOW_LIMIT=렌더링할 채팅 수=text\n=(기본값: 6)=divider\n=——————⚙️LB 3.x 설정=divider\nswn-statuswindow.maxCtx=최대 컨텍=text\n=비워두면 백엔드 설정을 따름=caption\nswn-statuswindow.maxLogs=포함채팅수=text\n=비워두면 백엔드 설정을 따름=caption\nswn-statuswindow.reiteration=재검토 수=text\n=0-2 권장=caption\n==groupEnd",
"lorebook": [
{
"key": "",
"comment": "manifest.lb",
"content": "identifier=swn-statuswindow\nauthorsNote=true\ncharDesc=true\nloreBooks=true\nmultilingual=true\npersonaDesc=true\nrerollBehavior=preserve-prev",
"mode": "normal",
"insertorder": 100,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2,
"_id": "lore_mja32om2_m9v6dz"
},
{
"key": "",
"comment": "swn-statuswindow.lb",
"content": "# SWN Status Interface\n\n**SYSTEM COMMAND [STRICT MODE]:**\n1. You are acting strictly as a Database Interface.\n2. Your task is to output the Status Window XML block **ONLY**.\n3. **START** your response immediately with `<swn-statuswindow>`.\n4. **END** your response immediately after `</swn-statuswindow>`.\n5. **DO NOT** generate any narration, dialogue, story continuation, or notes outside of the XML tags.\n6. If you generate anything other than the status window, it is considered a system error.\n\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=0}}}}\n**MODE: Character Perspective**\nDescribe Character `{{char}}` and their perspective on USER `{{user}}`.\nTargetCode: `C`\n{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=1}}}}\n**MODE: User Perspective**\nDescribe USER `{{user}}` and their perspective on Character `{{char}}`.\nTargetCode: `U`\n{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=2}}}}\n**MODE: Multi-Character View**\nIdentify {{#if {{? {{getglobalvar::toggle_SWNDESCCNT}}=2}}}}ALL{{/if}} main characters{{#if {{? {{getglobalvar::toggle_SWNDESCCNT}}=0}}}}(max 3){{/if}}{{#if {{? {{getglobalvar::toggle_SWNDESCCNT}}=1}}}}(max 5){{/if}} in the current narrative scene.\n**Exclusions:**\n{{#if {{? {{getglobalvar::toggle_SWNNODESCUSER}}=1}}}}- USER `{{user}}`{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNNODESCMALE}}=1}}}}- Any male character{{/if}}\n- Background/unnamed NPCs.\n**Instruction:** Generate a full SWN block (SWNM...SWNT) for EACH valid character sequentially.\nTargetCode: Character Name (or `C` if it is `{{char}}`).\n{{/if}}\n\n## Data Constraint\n- **Field Keys (e.g., Name, Relations)**: MUST stay in English.\n- **Field Values**: MUST be in the chat language (Korean).\n- Do not translate keys.\n\n## Output Structure Template\n<swn-statuswindow>\nSWNM[Name:Val|Gender:Val|Relations:Val|Status:Val|Location:Val|Outfit:Val|WhatAreOnSkin:Val|Inventory:Val|Emoji:Val|HexColorCode:Val|SexualExperienceList:Val|InnerThought:Val|TargetCode:Val]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:Val|TrustLevel:Val|LoyaltyLevel:Val|SubmissionLevel:Val|PhysicalDependenceLevel:Val|EmotionalDependenceLevel:Val|InitiativeTendency:Val|SexualShameDisposition:Val]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:Val|MasochisticDisposition:Val|ServitudeTendency:Val|SexualDevianceProfile:Val|<GENDER_DYNAMIC_FIELDS>|AnalDilation:Val|UrethralDilation:Val|NippleHoleDilation:Val|<GENDER_DYNAMIC_SIZE_FIELDS>|NippleSize:Val]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:Val|MouthComment:Val|<GENDER_DYNAMIC_BODY_FIELDS>|AnalInfo:Val|AnalComment:Val|UrethraInfo:Val|UrethraComment:Val]{{/if}}\nSWNT[Time1:YYYY-MM-DD Day|Time2:HH:MM AP/PM|Weather:Icon + Condition]\n</swn-statuswindow>\n\n**GENDER_DYNAMIC_FIELDS:**\n- **Male**: PenisSize\n- **Female**: VaginalDilation\n\n**GENDER_DYNAMIC_SIZE_FIELDS:**\n- **Male**: GlansSize, TesticlesSize\n- **Female**: ClitorisSize, BreastsSize\n\n**GENDER_DYNAMIC_BODY_FIELDS:**\n- **Male**: TesticlesInfo, TesticlesComment, PenisInfo, PenisComment, ProstateInfo, ProstateComment, GlansInfo, GlansComment\n- **Female**: BreastsInfo, BreastsComment, PussyInfo, PussyComment, WombInfo, WombComment, ClitorisInfo, ClitorisComment\n\n## Narrative Logic & Inference\n- Values must align with context and past SWN if available.\n- Infer plausible values based on personality. Do not reset or fabricate arbitrarily.\n\n## Field Descriptions\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}!=1}}}}\n- Name: Character's name.\n- Gender: Character's gender (남 or 여)\n- Relations: Relationship with USER (e.g., friend, master).{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=1}}}}\n- Name: USER's name.\n- Gender: USER's gender (남 or 여)\n- Relations: Relationship with Character.{{/if}}\n- Status: Current brief activity (e.g., 휴식 중, 노려보는 중).\n- Location: Current physical location.\n- Outfit: clothing and accessories.\n- WhatAreOnSkin: Adult devices on body (e.g., piercing, plug).\n- Inventory: Key items held.\n- Emoji: Only one emotion/status emoji.\n- HexColorCode: Hex color reflecting mood.\n- SexualExperienceList: Short list of experienced sexual acts in Korean (e.g., 구강 성교, 항문 자극).\n- InnerThought: **Always include.** 1~2 lines of first-person inner thought showing true feelings. No quotes.\n- TargetCode: Refer to the MODE section above.\n\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}\n---\n### SWNA1: Relationship & Psychology\nValues should be 1-2 descriptive words in Korean (e.g., 맹목적, 거부감).\nStable states. Update only when justified by story.\n\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}!=1}}}}\n- AffectionLevel: Degree of affection toward USER.\n- TrustLevel: Confidence in USER's safety/reliability.\n- LoyaltyLevel: Willingness to stay committed to USER.\n- SubmissionLevel: Tendency to yield/obey USER.\n- PhysicalDependenceLevel: Craving for physical interaction with USER.\n- EmotionalDependenceLevel: Need for validation from USER.\n- InitiativeTendency: Proactive vs Passive behavioral pattern.\n- SexualShameDisposition: Internalized shame/openness regarding sexuality.\n{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=1}}}}\n- AffectionLevel: Degree of affection toward Character.\n- TrustLevel: Confidence in Character's safety/reliability.\n- LoyaltyLevel: Willingness to stay committed to Character.\n- SubmissionLevel: Tendency to yield/obey Character.\n- PhysicalDependenceLevel: Craving for physical interaction with Character.\n- EmotionalDependenceLevel: Need for validation from Character.\n- InitiativeTendency: Proactive vs Passive behavioral pattern.\n- SexualShameDisposition: Internalized shame/openness regarding sexuality.\n{{/if}}\n{{/if}}\n\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}\n---\n### SWNA2: Traits & Physical Stats\n- Sadistic/MasochisticDisposition: Pleasure from inflicting/receiving pain.\n- ServitudeTendency: Willingness to serve.\n- SexualDevianceProfile: Deviation from norms.\n- **Dilation Fields** (Vaginal/Anal/Urethral/NippleHole): Current max stretch (0~100 scale). (e.g., 0=Virgin, 10=Finger, 20=Penis, 30+=Smooth, 50+=Fist).\n- **Size Fields**: \n - **Male**: PenisSize (e.g., `14.5cm (발기)`), GlansSize (e.g., `3.5cm`), TesticlesSize (e.g., `4cm (각각)`)\n - **Female**: ClitorisSize (e.g., `0.6cm (발기)`), BreastsSize (e.g., `D컵 (풍만함)`)\n - **Common**: NippleSize (e.g., `1.2cm (피어싱)`)\n{{/if}}\n\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}\n---\n### SWNB1: Body Parts\n- **Info Fields** (e.g., `PenisInfo`, `PussyInfo`): Objective description + sexual history. Short phrases. (e.g., 성경험 없음. 예민하게 솟음)\n- **Comment Fields** (e.g., `PenisComment`, `PussyComment`): **1st Person** subjective feeling. No quotes. (e.g., 너무 커서 움직일 때마다 불편해...)\n\n**Dynamic Fields by Gender:**\n- **Male**: TesticlesInfo/Comment, PenisInfo/Comment, ProstateInfo/Comment, GlansInfo/Comment\n- **Female**: BreastsInfo/Comment, PussyInfo/Comment, WombInfo/Comment, ClitorisInfo/Comment\n- **Common**: MouthInfo/Comment, AnalInfo/Comment, UrethraInfo/Comment\n{{/if}}\n\n---\n### SWNT: Time & Environment\n- Time1: YYYY-MM-DD Day (e.g., 2025-05-24 토)\n- Time2: HH:MM AP/PM (e.g., 11:30 PM)\n- Weather: Icon + Text (e.g., ☀️ 맑음)\n\n---\n\n## Example Output\n\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}<2}}}}\n### Example 1 (Female Character):\n```\n<swn-statuswindow>\nSWNM[Name:이나연|Gender:여|Relations:연인이자 주인|Status:그를 바라보고 있음|Location:공터 벤치|Outfit:얇은 원피스, 스타킹|WhatAreOnSkin:니플 클램프, 초커|Inventory:작은 진동기, 열쇠|Emoji:💓|HexColorCode:#e798b2|SexualExperienceList:구강 성교, 항문 자극 도구 삽입, 유두 피어싱|InnerThought:지금 이 순간이 멈췄으면 좋겠어…|TargetCode:C]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:강한 애착|TrustLevel:절대 신뢰|LoyaltyLevel:헌신적|SubmissionLevel:자발적 복종|PhysicalDependenceLevel:접촉을 갈망함|EmotionalDependenceLevel:애정을 원함|InitiativeTendency:수동적|SexualShameDisposition:약함]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:없음|MasochisticDisposition:중간 정도|ServitudeTendency:강함|SexualDevianceProfile:높음|VaginalDilation:18|AnalDilation:12|UrethralDilation:0|NippleHoleDilation:6|ClitorisSize:0.6cm (발기)|BreastsSize:D컵 (풍만함)|NippleSize:1.2cm (피어싱)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:성경험 있음. 부드러운 입술, 촉촉한 숨결|MouthComment:입으로 할 때가 가장 솔직해져|BreastsInfo:성경험 없음. 풍만한 D컵, 핑크빛 유륜|BreastsComment:조금만 닿아도 짜릿해, 만져주길 바라고 있어|PussyInfo:수없이 사용됨. 촉촉하고 붉은 빛, 완전히 젖음|PussyComment:아무 말도 안 했는데 이미 젖어 있어, 주인의 것을 갈망해|WombInfo:2회 질내사정. 미약하게 뛰는 중, 그의 흔적으로 가득함|WombComment:그 사람이 남긴 흔적이 계속 느껴져, 또 채워지고 싶어|ClitorisInfo:계속된 자극으로 예민해져 있음. 팽창하고 박동함|ClitorisComment:좀 더 자극해줬으면 좋겠어, 간절히 바라고 있어...|AnalInfo:3회 장내사정. 살짝 벌어짐, 여전히 조임|AnalComment:아픈데… 익숙해지는 중이야, 더 깊이 받아들이고 싶어|UrethraInfo:미사용. 좁고 깨끗한 요도|UrethraComment:여긴 아직… 조금 무서워, 하지만 궁금하기도 해]{{/if}}\nSWNT[Time1:2025-05-24 토|Time2:11:38 PM|Weather:🌙 맑은 밤]\n</swn-statuswindow>\n```\n\n### Example 2 (Male Character):\n```\n<swn-statuswindow>\nSWNM[Name:김김노|Gender:남|Relations:노예|Status:이나연 앞에 누워있음|Location:공터 벤치|Outfit:청바지|WhatAreOnSkin:없음|Inventory:없음|Emoji:💓|HexColorCode:#e128b2|SexualExperienceList:구강 성교|InnerThought:쉽지 않네…|TargetCode:rear view]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:애착없음|TrustLevel:의심중|LoyaltyLevel:비헌신|SubmissionLevel:복종은 싫어|PhysicalDependenceLevel:별로|EmotionalDependenceLevel:문제없음|InitiativeTendency:능동적|SexualShameDisposition:약함]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:없음|MasochisticDisposition:낮음|ServitudeTendency:매우낮음|SexualDevianceProfile:높음|PenisSize:15cm (발기)|AnalDilation:0|UrethralDilation:0|NippleHoleDilation:0|GlansSize:6cm|TesticlesSize:8cm|NippleSize:0.2cm]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:성경험 없음. 굳게 다물린 입술|MouthComment:깨물어 줄테다, 순순히 당하지 않아|TesticlesInfo:체온이 올라가 고환이 늘어져 있는 상태. 무겁게 늘어짐|TesticlesComment:떨릴 것 같아... 뭔가 이상해|PenisInfo:수 많은 사정, 여전히 발기되어 있음. 혈관이 불거짐|PenisComment:아직 더 하고 싶어, 이대로는 끝낼 수 없어|ProstateInfo:직접적으로 자극 된적 없음. 건드려지지 않은 상태|ProstateComment:여긴 무슨 느낌일까? 생각만 해도 이상해|GlansInfo:여러 번의 관계로 인해 예민해져 있음. 붉게 달아오름|GlansComment:더 넣어봐야지, 이 이상한 감각에 익숙해져야 해|AnalInfo:경험없음. 굳게 닫힌 입구|AnalComment:여긴 내장이지. 절대 안 돼.|UrethraInfo:미사용. 좁고 깨끗한 요도|UrethraComment:참 나... 여긴 건드리지 마.]{{/if}}\nSWNT[Time1:2025-05-24 토|Time2:11:38 PM|Weather:🌙 맑은 밤]\n</swn-statuswindow>\n```\n{{/if}}\n\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=2}}}}\n### Example (Multi-Character):\n```\n<swn-statuswindow>\nSWNM[Name:이나연|Gender:여|Relations:연인이자 주인|Status:그를 바라보고 있음|Location:공터 벤치|Outfit:얇은 원피스, 스타킹|WhatAreOnSkin:니플 클램프, 초커|Inventory:작은 진동기, 열쇠|Emoji:💓|HexColorCode:#e798b2|SexualExperienceList:구강 성교, 항문 자극 도구 삽입, 유두 피어싱|InnerThought:지금 이 순간이 멈췄으면 좋겠어…|TargetCode:C]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:강한 애착|TrustLevel:절대 신뢰|LoyaltyLevel:헌신적|SubmissionLevel:자발적 복종|PhysicalDependenceLevel:접촉을 갈망함|EmotionalDependenceLevel:애정을 원함|InitiativeTendency:수동적|SexualShameDisposition:약함]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:없음|MasochisticDisposition:중간 정도|ServitudeTendency:강함|SexualDevianceProfile:높음|VaginalDilation:18|AnalDilation:12|UrethralDilation:0|NippleHoleDilation:6|ClitorisSize:0.6cm (발기)|BreastsSize:D컵 (풍만함)|NippleSize:1.2cm (피어싱)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:성경험 있음. 부드러운 입술, 촉촉한 숨결|MouthComment:입으로 할 때가 가장 솔직해져|BreastsInfo:성경험 없음. 풍만한 D컵, 핑크빛 유륜|BreastsComment:조금만 닿아도 짜릿해, 만져주길 바라고 있어|PussyInfo:수없이 사용됨. 촉촉하고 붉은 빛, 완전히 젖음|PussyComment:아무 말도 안 했는데 이미 젖어 있어, 주인의 것을 갈망해|WombInfo:2회 질내사정. 미약하게 뛰는 중, 그의 흔적으로 가득함|WombComment:그 사람이 남긴 흔적이 계속 느껴져, 또 채워지고 싶어|ClitorisInfo:계속된 자극으로 예민해져 있음. 팽창하고 박동함|ClitorisComment:좀 더 자극해줬으면 좋겠어, 간절히 바라고 있어...|AnalInfo:3회 장내사정. 살짝 벌어짐, 여전히 조임|AnalComment:아픈데… 익숙해지는 중이야, 더 깊이 받아들이고 싶어|UrethraInfo:미사용. 좁고 깨끗한 요도|UrethraComment:여긴 아직… 조금 무서워, 하지만 궁금하기도 해]{{/if}}\nSWNT[Time1:2025-05-24 토|Time2:11:38 PM|Weather:🌙 맑은 밤]\n\nSWNM[Name:김김노|Gender:남|Relations:노예|Status:이나연 앞에 누워있음|Location:공터 벤치|Outfit:청바지|WhatAreOnSkin:없음|Inventory:없음|Emoji:💓|HexColorCode:#e128b2|SexualExperienceList:구강 성교|InnerThought:쉽지 않네…|TargetCode:rear view]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:애착없음|TrustLevel:의심중|LoyaltyLevel:비헌신|SubmissionLevel:복종은 싫어|PhysicalDependenceLevel:별로|EmotionalDependenceLevel:문제없음|InitiativeTendency:능동적|SexualShameDisposition:약함]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:없음|MasochisticDisposition:낮음|ServitudeTendency:매우낮음|SexualDevianceProfile:높음|PenisSize:15cm (발기)|AnalDilation:0|UrethralDilation:0|NippleHoleDilation:0|GlansSize:6cm|TesticlesSize:8cm|NippleSize:0.2cm]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:성경험 없음. 굳게 다물린 입술|MouthComment:깨물어 줄테다, 순순히 당하지 않아|TesticlesInfo:체온이 올라가 고환이 늘어져 있는 상태. 무겁게 늘어짐|TesticlesComment:떨릴 것 같아... 뭔가 이상해|PenisInfo:수 많은 사정, 여전히 발기되어 있음. 혈관이 불거짐|PenisComment:아직 더 하고 싶어, 이대로는 끝낼 수 없어|ProstateInfo:직접적으로 자극 된적 없음. 건드려지지 않은 상태|ProstateComment:여긴 무슨 느낌일까? 생각만 해도 이상해|GlansInfo:여러 번의 관계로 인해 예민해져 있음. 붉게 달아오름|GlansComment:더 넣어봐야지, 이 이상한 감각에 익숙해져야 해|AnalInfo:경험없음. 굳게 닫힌 입구|AnalComment:여긴 내장이지. 절대 안 돼.|UrethraInfo:미사용. 좁고 깨끗한 요도|UrethraComment:참 나... 여긴 건드리지 마.]{{/if}}\nSWNT[Time1:2025-05-24 토|Time2:11:38 PM|Weather:🌙 맑은 밤]\n</swn-statuswindow>\n```\n{{/if}}",
"mode": "normal",
"insertorder": 1,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2,
"_id": "lore_mja32om2_nqvnna"
},
{
"key": "",
"comment": "swn-statuswindow.lb.format",
"content": "{{#if {{? {{getglobalvar::toggle_SWNUSER}}<2}}}}\n<swn-statuswindow>\nSWNM[Name:(...)|Relations:(...)|Status:(...)|Location:(...)|Outfit:(...)|WhatAreOnSkin:(...)|Inventory:(...)|Emoji:(...)|HexColorCode:(...)|SexualExperienceList:(...)|InnerThought:(...)|TargetCode:(...)]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:(...)|TrustLevel:(...)|LoyaltyLevel:(...)|SubmissionLevel:(...)|PhysicalDependenceLevel:(...)|EmotionalDependenceLevel:(...)|InitiativeTendency:(...)|SexualShameDisposition:(...)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:(...)|MasochisticDisposition:(...)|ServitudeTendency:(...)|SexualDevianceProfile:(...)|VaginalDilation:(...)|AnalDilation:(...)|UrethralDilation:(...)|NippleHoleDilation:(...)|ClitorisSize:(...)|NippleSize:(...)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:(...)|MouthComment:(...)|BreastInfo:(...)|BreastComment:(...)|WombInfo:(...)|WombComment:(...)|PussyInfo:(...)|PussyComment:(...)|AnalInfo:(...)|AnalComment:(...)|UrethraInfo:(...)|UrethraComment:(...)]{{/if}}\nSWNT[Time1:(...)|Time2:(...)|Weather:(...)]\n</swn-statuswindow>\n{{/if}}\n\n{{#if {{? {{getglobalvar::toggle_SWNUSER}}=2}}}}\n<swn-statuswindow>\nSWNM[Name:(...)|Relations:(...)|Status:(...)|Location:(...)|Outfit:(...)|WhatAreOnSkin:(...)|Inventory:(...)|Emoji:(...)|HexColorCode:(...)|SexualExperienceList:(...)|InnerThought:(...)|TargetCode:(...)]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:(...)|TrustLevel:(...)|LoyaltyLevel:(...)|SubmissionLevel:(...)|PhysicalDependenceLevel:(...)|EmotionalDependenceLevel:(...)|InitiativeTendency:(...)|SexualShameDisposition:(...)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:(...)|MasochisticDisposition:(...)|ServitudeTendency:(...)|SexualDevianceProfile:(...)|VaginalDilation:(...)|AnalDilation:(...)|UrethralDilation:(...)|NippleHoleDilation:(...)|ClitorisSize:(...)|NippleSize:(...)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:(...)|MouthComment:(...)|BreastInfo:(...)|BreastComment:(...)|WombInfo:(...)|WombComment:(...)|PussyInfo:(...)|PussyComment:(...)|AnalInfo:(...)|AnalComment:(...)|UrethraInfo:(...)|UrethraComment:(...)]{{/if}}\nSWNT[Time1:(...)|Time2:(...)|Weather:(...)]\n\nSWNM[Name:(...)|Relations:(...)|Status:(...)|Location:(...)|Outfit:(...)|WhatAreOnSkin:(...)|Inventory:(...)|Emoji:(...)|HexColorCode:(...)|SexualExperienceList:(...)|InnerThought:(...)|TargetCode:(...)]\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD1}}=1}}}}SWNA1[AffectionLevel:(...)|TrustLevel:(...)|LoyaltyLevel:(...)|SubmissionLevel:(...)|PhysicalDependenceLevel:(...)|EmotionalDependenceLevel:(...)|InitiativeTendency:(...)|SexualShameDisposition:(...)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNAFIELD2}}=1}}}}SWNA2[SadisticDisposition:(...)|MasochisticDisposition:(...)|ServitudeTendency:(...)|SexualDevianceProfile:(...)|VaginalDilation:(...)|AnalDilation:(...)|UrethralDilation:(...)|NippleHoleDilation:(...)|ClitorisSize:(...)|NippleSize:(...)]{{/if}}\n{{#if {{? {{getglobalvar::toggle_SWNBFIELD1}}=1}}}}SWNB1[MouthInfo:(...)|MouthComment:(...)|BreastInfo:(...)|BreastComment:(...)|WombInfo:(...)|WombComment:(...)|PussyInfo:(...)|PussyComment:(...)|AnalInfo:(...)|AnalComment:(...)|UrethraInfo:(...)|UrethraComment:(...)]{{/if}}\nSWNT[Time1:(...)|Time2:(...)|Weather:(...)]\n</swn-statuswindow>\n{{/if}}\n",
"mode": "normal",
"insertorder": 1,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2,
"_id": "lore_mja32om2_5mb354"
},
{
"key": "",
"comment": "❌Manual & Credit",
"content": "## Manual (common)\n- 일반사용 및 라이트보드 연계 모두 가능합니다.\n- 기본적으로 최근 3개의 상태창이 표기되며, 나머지는 채팅에서 사라집니다.\n- 모든 대화내용의 상태창 표기를 원하면 아래 수정을 적용하면 됩니다.\n 1) 정규식 스크립트 內 [경량화-표기제거] : 디스플레이 수정 → 비활성화\n 2) 트리거 스크립트 內 [경량화] 부분 검색 : getChatIdx() > 6 라인 → 주석처리 혹은 제거\n- 🚸상태창 위치는 기본 하단이지만, 아래 설정으로 상단표기가 가능합니다.\n 1) 정규식 스크립트 內 [🚸상태창 위로 (필요시 \"디스플레이 수정\")🚸] : 비활성화 → 디스플레이 수정\n\n### 옵션정보 및 설정방법\n일반모드 기동 : 메인모델에게 응답+상태창생성을 요청합니다.\n컬러테마 : 테마 설정용\n상태창 방식 : 항상펼치기,토글(열기/닫기),토글(팝업) 모드 선택이 가능합니다.\n❌재생성(리셋용)❌: 상태창 정보가 메인모델 리퀘스트에 포함되지 않습니다.\n 찐빠 정리용, 리퀘 토큰 아끼기 용도로 사용 가능합니다.\n 단, 일반모드의 경우는 매번 상태창 데이터를 새로 생성하게 되므로 데이터의 연속성이 깨지게 됩니다.\n리퀘스트 유지 : 최근 n개의 상태창 정보가 메인모델 리퀘스트에 포함됩니다. \n 하이파에 데이터를 전달하고 싶을 때에는 무제한으로 두시면 됩니다.\n\n### 라이트보드 연계 사용법 \n - 백엔드 2.6 이상에서 동작합니다.\n - 라이트보드 백엔드 모듈 설치 및 가이드를 읽으세요 (→https://arca.live/b/characterai/137403093)\n - [일반모드 기동] 토글을 **반드시 꺼 주세요**(중복작동합니다)\n - [컨텍미포함(리셋,🔦)] 토글은 on 권장합니다.\n (상태창이 메인모델의 채팅 리퀘에 포함되지 않게 되어 토큰과 지능을 아낄수 있습니다)\n \n\n## 참조한 봇/상태창들\n https://arca.live/b/characterai/136196564\n https://arca.live/b/characterai/135870449\n https://arca.live/b/characterai/136301105\n https://arca.live/b/characterai/97976099",
"mode": "normal",
"insertorder": 100,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2,
"_id": "lore_mja32om2_clp1le"
},
{
"key": "",
"comment": "❌PatchNote",
"content": "## 2.11\n - 각종 최적화\n * 루아 수정 - 이제 5개 채팅(=3개) 에서만 표기되며, 나머지는 화면에서 숨겨집니다\n * 정규식 최적화\n - css 테마 오류 수정\n - 토글 정리\n - 구버전 지원제거\n - 가이드 메뉴얼 추가\n\n## 2.08\n - 남성제외토글추가 + 관련명령어 강화\n - 클리유두 크기표현 관련 지침변경\n - css 폰트제거 + 최적화, 테마추가\n - 정규식 강화\n\n\n## 2.06a\n - 라이트보드 지원용 랜덤id 변화\n\n## 2.06\n - 팝업버튼ui 변경\n - 지시강제성 추가\n - 버튼 UI 조금변경\n - 라이트보드 적용\n\n## 2.05\n - 온오프 명시적 분리\n - 항상열림/토글 기능 분리\n - 리퀘보존 설정 추가\n - 시뮬봇 지원용 설정 추가\n - 토큰수정\n - 연속이모지 찐빠 처리 추가\n - 팝업으로 변경",
"mode": "normal",
"insertorder": 100,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2,
"_id": "lore_mja32om2_n2xogv"
},
{
"key": "",
"comment": "swn-statuswindow.lb.onValidate",
"content": "return function(triggerId, output)\n local function fail(msg) error('InvalidOutput: ' .. msg, 0) end\n local function trim(s) return (s or ''):match('^%s*(.-)%s*$') end\n if type(output) ~= 'string' or trim(output) == '' then\n fail('Empty output. Output a <swn-statuswindow> block.')\n end\n local _, oc = output:gsub('<swn%-statuswindow>', '')\n local _, cc = output:gsub('</swn%-statuswindow>', '')\n if oc == 0 then fail('Missing <swn-statuswindow> tag.') end\n if cc == 0 then fail('Missing </swn-statuswindow> closing tag.') end\n local body = output:match('<swn%-statuswindow>(.-)</swn%-statuswindow>')\n if not body then fail('Malformed <swn-statuswindow> block.') end\n if not body:find('SWNM%[') then fail('Missing SWNM block.') end\n if not body:find('SWNT%[') then fail('Missing SWNT block.') end\n local swnm = body:match('SWNM%[(.-)%]')\n if swnm then\n if not swnm:find('Name:') then fail('SWNM missing Name field.') end\n if not swnm:find('InnerThought:') then fail('SWNM missing InnerThought field.') end\n for field in swnm:gmatch('([^:|]+):[^|]*') do\n local trimmed = trim(field)\n if trimmed and trimmed:lower() ~= trimmed:upper() then\n local first = trimmed:sub(1,1)\n if first:match('[가-힣ㄱ-ㅎㅏ-ㅣ]') then\n fail('Field key \"' .. trimmed .. '\" appears to be Korean. Keys must be English.')\n end\n end\n end\n end\n return true\nend",
"mode": "normal",
"insertorder": 100,
"alwaysActive": false,
"secondkey": "",
"selective": false,
"useRegex": false,
"bookVersion": 2
}
],
"regex": [
{
"comment": "리퀘스트 비활성화 / 리셋",
"in": "<swn-statuswindow>([^<]*(?:<(?!/swn-statuswindow>)[^<]*)*)<\\/swn-statuswindow>",
"out": "{{#when::toggle::toggle_SWNRESETT}}{{:else}}{{#when::toggle::toggle_SWNRAMAIN}}$&{{:else}}{{#if {{greater_equal::{{chat_index}}::{{? {{lastmessageid}}-3}}}}}}$&{{/if}}{{/when}}{{/when}}",
"type": "editprocess",
"ableFlag": true,
"flag": "sgum",
"_id": "regex_mja32om2_euy4sd"
},
{
"comment": "연속이모지 수정",
"in": "(?<=Emoji:)(\\p{Extended_Pictographic}{2,})",
"out": "💬",
"type": "editoutput",
"ableFlag": true,
"flag": "<cb><ove_botto><ove_top><cb>gu",
"_id": "regex_mja32om2_frt0ae"
},
{
"comment": "🔦메인모델 중복제거",
"in": "<swn-statuswindow>([^<]*(?:<(?!/swn-statuswindow>)[^<]*)*)<\\/swn-statuswindow>",
"out": "{{#if {{? {{getglobalvar::toggle_SWNSWITCHON}}>0}}}}\n$&\n{{/if}}",
"type": "editoutput",
"ableFlag": false,
"flag": "g",
"_id": "regex_mja32om2_mr6do4"
},
{
"comment": "🔦지연로딩",
"in": "<lb-lazy identifier=\"swn-statuswindow\" \\>",
"out": "{{#if {{greater_equal::{{chat_index}}::{{? {{lastmessageid}}}}}}}}\n<div class=\"lb-module-root\" data-id=\"swn-statuswindow\">\n<button class=\"lb-lazyloader\" risu-btn=\"lb-reroll__swn-statuswindow\">\n<span class=\"lb-opener\"><span>♦️상태창 불러오기<lb-reroll-icon /></span></span>\n</button>\n</div>\n{{/if}}",
"type": "editdisplay",
"ableFlag": false,
"_id": "regex_mja32om2_t494op"
},
{
"comment": "🚸상태창 위로 (필요시 \"디스플레이 수정\")🚸",
"in": "<swn-statuswindow>([^<]*(?:<(?!/swn-statuswindow>)[^<]*)*)<\\/swn-statuswindow>",
"out": "{{#if {{greater_equal::{{chat_index}}::{{? {{lastmessageid}}-5}}}}}}\n$&\n{{/if}}",
"type": "disabled",
"ableFlag": true,
"flag": "gmsu<move_top>",
"_id": "regex_mja32om2_xpaf00"
},
{
"comment": "경량화-표기제거 - 남겨는 뒀는데 사용하지 않음!",
"in": "<swn-statuswindow>([^<]*(?:<(?!/swn-statuswindow>)[^<]*)*)<\\/swn-statuswindow>",
"out": "{{#if {{greater_equal::{{chat_index}}::{{? {{lastmessageid}}-5}}}}}}\n$&\n{{/if}}",
"type": "disabled",
"ableFlag": false,
"flag": "gmus<order 5>",
"_id": "regex_mja32om2_l9d1nj"
}
],
"trigger": [
{
"comment": "",
"type": "start",
"conditions": [],
"effect": [
{
"type": "triggerlua",
"code": "-- [[ 1. 설정 및 전역 변수 ]]\nlocal DEFAULT_SHOW_LIMIT = 6\nlocal id_counter = 0\nlocal swn_rendered_cache = {} \nlocal swn_cache = { vars = nil, last_load = 0 }\n\n-- 고유 ID 생성\nlocal function generateSequentialId(prefix)\n id_counter = id_counter + 1\n return (prefix or \"id_\") .. tostring(id_counter)\nend\n\n-- [[ 2. 헬퍼 함수 ]]\nlocal function escapeHtml(str)\n if not str then return \"\" end\n local map = { [\"&\"]=\"&\", [\"<\"]=\"<\", [\">\"]=\">\", ['\"']=\""\", [\"'\"]=\"'\" }\n return str:gsub(\"[&<>\\\"']\", map)\nend\n\nlocal function line(icon, label, field, data)\n return string.format(\n '<div class=\"rpg-status-id-line-compact\" tabindex=\"0\" data-tooltip=\"%s\">' ..\n '<strong><span class=\"rpg-icon-compact-wrapper\"><span class=\"rpg-icon-compact\">%s</span>%s:</strong>%s</div>',\n escapeHtml(data[field] or \"\"), icon, label, escapeHtml(data[field] or \"\")\n )\nend\n\nlocal function stat(icon, label, field, data)\n return string.format(\n '<div class=\"rpg-status-stat-item-compact\" tabindex=\"0\" data-tooltip=\"%s\">' ..\n '<strong><span class=\"rpg-icon-compact\">%s</span>%s</strong><span>%s</span></div>',\n escapeHtml(data[field] or \"\"), icon, label, escapeHtml(data[field] or \"\")\n )\nend\n\n-- [[ 3. 메인 렌더러 ]]\nlocal function renderSWNStatus(triggerId, blocks, getVarFunc)\n local h = {}\n local function toggle(name) return tonumber(getVarFunc(triggerId, name)) == 1 end\n local nm = blocks.SWNM or {}\n local switchMode = tonumber(getVarFunc(triggerId, \"toggle_SWNSWITCH\")) or 0\n local dialogId = 'cr_' .. generateSequentialId(\"rand\")\n\n -- 성별 감지: Gender 필드 또는 남성 전용 필드 존재 여부로 판별\n local gender = (nm.Gender or \"\"):lower()\n local isMale = gender:find(\"남\") ~= nil or gender:find(\"male\") ~= nil\n or (blocks.SWNA2 and blocks.SWNA2.PenisSize ~= nil)\n or (blocks.SWNB1 and blocks.SWNB1.PenisInfo ~= nil)\n\n if switchMode == 0 then table.insert(h, '<div class=\"swcww1-theme-host\">')\n elseif switchMode == 1 then\n table.insert(h, '<details id=\"swcww1\" class=\"swcww1-details swcww1-theme-host\">')\n table.insert(h, '<summary class=\"swcww1-summary\"><span class=\"swcww1-summary-ep\">💬상태창 (열기/닫기) : ' .. escapeHtml(nm.Name or \"\") .. '</span></summary>')\n elseif switchMode == 2 then\n table.insert(h, '<button popovertarget=\"swcww1-dialog-' .. escapeHtml(dialogId) .. '\" type=\"button\" class=\"swcww1-openbtn\">💬상태창 보기 : ' .. escapeHtml(nm.Name or \"\") .. '</button>')\n table.insert(h, '<dialog id=\"swcww1-dialog-' .. escapeHtml(dialogId) .. '\" class=\"swcww1-dialog swcww1-theme-host\" popover>') \n table.insert(h, '<div class=\"swcww1-wrapper\"><div class=\"swcww1-scroll-area\">')\n end\n\n table.insert(h, '<div class=\"rpg-status-container-compact\"><div class=\"rpg-status-content-column\">')\n table.insert(h, '<div class=\"rpg-status-top-compact\"><div class=\"rpg-status-identity-compact\">')\n if (tonumber(getVarFunc(triggerId, \"toggle_swn-statuswindow.mode\")) or 0) > 0 then\n table.insert(h, '<button risu-btn=\"lb-reroll__swn-statuswindow\" type=\"button\" class=\"button-swnreroll\">🔄</button>')\n end\n table.insert(h, '<div class=\"rpg-status-name-compact\">' .. escapeHtml(nm.Name or \"\") .. '</div>')\n for _, v in ipairs({{\"🔻\",\"성별\",\"Gender\"},{\"🔗\",\"관계\",\"Relations\"},{\"🌝\",\"상태\",\"Status\"},{\"📍\",\"위치\",\"Location\"},{\"👕\",\"복장\",\"Outfit\"},{\"❣\",\"장착\",\"WhatAreOnSkin\"},{\"🎒\",\"소지품\",\"Inventory\"}}) do\n table.insert(h, line(v[1], v[2], v[3], nm))\n end\n table.insert(h, '</div></div>')\n\n -- SWNA1: 심리/관계 (성별 무관)\n if blocks.SWNA1 and toggle(\"toggle_SWNAFIELD1\") then\n table.insert(h, '<div class=\"rpg-status-main-compact\">')\n for _, v in ipairs({{\"❤\",\"호감도\",\"AffectionLevel\"},{\"💬\",\"신뢰\",\"TrustLevel\"},{\"🛡\",\"충성도\",\"LoyaltyLevel\"},{\"🧎\",\"복종도\",\"SubmissionLevel\"},{\"🔗\",\"육체의존도\",\"PhysicalDependenceLevel\"},{\"🌀\",\"정신의존도\",\"EmotionalDependenceLevel\"},{\"⚡\",\"능동성\",\"InitiativeTendency\"},{\"❤\",\"수치심\",\"SexualShameDisposition\"}}) do\n table.insert(h, stat(v[1], v[2], v[3], blocks.SWNA1))\n end\n table.insert(h, '</div>')\n end\n\n -- SWNA2: 성향/신체 스탯 (성별 분기)\n if blocks.SWNA2 and toggle(\"toggle_SWNAFIELD2\") then\n local a2 = blocks.SWNA2\n table.insert(h, '<div class=\"rpg-status-additional-stats-compact\">')\n local fields = {\n {\"🩸\",\"S성향\",\"SadisticDisposition\"},\n {\"🧡\",\"M성향\",\"MasochisticDisposition\"},\n {\"💜\",\"봉사\",\"ServitudeTendency\"},\n {\"💙\",\"변태\",\"SexualDevianceProfile\"},\n }\n if isMale then\n fields[#fields+1] = {\"🎆\",\"자지크기\",\"PenisSize\"}\n fields[#fields+1] = {\"🎇\",\"A확장\",\"AnalDilation\"}\n fields[#fields+1] = {\"💦\",\"요도확장\",\"UrethralDilation\"}\n fields[#fields+1] = {\"🔘\",\"유두확장\",\"NippleHoleDilation\"}\n fields[#fields+1] = {\"❣\",\"귀두크기\",\"GlansSize\"}\n fields[#fields+1] = {\"♾️\",\"고환크기\",\"TesticlesSize\"}\n fields[#fields+1] = {\"🔅\",\"유두 크기\",\"NippleSize\"}\n else\n fields[#fields+1] = {\"🎆\",\"V확장\",\"VaginalDilation\"}\n fields[#fields+1] = {\"🎇\",\"A확장\",\"AnalDilation\"}\n fields[#fields+1] = {\"💦\",\"요도확장\",\"UrethralDilation\"}\n fields[#fields+1] = {\"🔘\",\"유두확장\",\"NippleHoleDilation\"}\n fields[#fields+1] = {\"❣\",\"클리크기\",\"ClitorisSize\"}\n fields[#fields+1] = {\"♾️\",\"가슴크기\",\"BreastsSize\"}\n fields[#fields+1] = {\"🔅\",\"유두 크기\",\"NippleSize\"}\n end\n for _, field in ipairs(fields) do\n table.insert(h, stat(field[1], field[2], field[3], a2))\n end\n table.insert(h, '</div>')\n end\n\n -- SWNB1: 신체 정보/평가 (성별 분기)\n if blocks.SWNB1 and toggle(\"toggle_SWNBFIELD1\") then\n local b = blocks.SWNB1\n table.insert(h, '<div class=\"rpg-status-additional-stats-compact-secondary\"><div class=\"rpg-status-identity-compact\"><div class=\"rpg-status-name-compact\">비밀의 정보</div>')\n local bodyFields = {\n {\"👁🗨\",\"입 상태\",\"MouthInfo\"}, {\"💬\",\"입 평가\",\"MouthComment\"},\n }\n if isMale then\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"고환 상태\",\"TesticlesInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"고환 평가\",\"TesticlesComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"자지 상태\",\"PenisInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"자지 평가\",\"PenisComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"전립선 상태\",\"ProstateInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"전립선 평가\",\"ProstateComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"귀두 상태\",\"GlansInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"귀두 평가\",\"GlansComment\"}\n else\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"가슴 상태\",\"BreastsInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"가슴 평가\",\"BreastsComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"보지 상태\",\"PussyInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"보지 평가\",\"PussyComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"자궁 상태\",\"WombInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"자궁 평가\",\"WombComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"클리토리스 상태\",\"ClitorisInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"클리토리스 평가\",\"ClitorisComment\"}\n end\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"애널 상태\",\"AnalInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"애널 평가\",\"AnalComment\"}\n bodyFields[#bodyFields+1] = {\"👁🗨\",\"요도 상태\",\"UrethraInfo\"}\n bodyFields[#bodyFields+1] = {\"💬\",\"요도 평가\",\"UrethraComment\"}\n for _, pair in ipairs(bodyFields) do\n table.insert(h, line(pair[1], pair[2], pair[3], b))\n end\n table.insert(h, '</div></div>')\n end\n\n table.insert(h, '<div class=\"rpg-status-additional-stats-compact-secondary\"><div class=\"rpg-status-identity-compact\"><div class=\"rpg-status-name-compact\">비밀의 정보</div>' .. line(\"📋\",\"성경험 목록\",\"SexualExperienceList\",nm) .. '</div></div>')\n table.insert(h, '<div class=\"rpg-status-additional-stats-compact-third\"><div class=\"rpg-status-thought-bubble-compact\" style=\"border-left-color:'..escapeHtml(nm.HexColorCode or \"#aaa\")..';\"><article class=\"partymind-item\"><div class=\"partymind-picwrap\" data-emo=\"'..escapeHtml(nm.Emoji or \"\")..'\">')\n local targetcd = (nm.TargetCode or ''):lower()\n local picsrc = (targetcd == \"u\" and \"{{source::user}}\") or (targetcd == \"c\" and \"{{source::char}}\") or (targetcd == \"\" and \"{{raw::swn-placeholder}}\") or (\"{{raw::\" .. targetcd .. \"}}\")\n table.insert(h, '<img alt=\"\" class=\"partymind-pic\" src=\"'..escapeHtml(picsrc)..'\"></div><div><p class=\"partymind-name\">'..escapeHtml(nm.Name or \"\")..'</p><p class=\"partymind-bubble\" data-type=\"T\"><span class=\"partymind-quotes\" data-type=\"T\">'..escapeHtml(nm.InnerThought or \"\")..'</span></p></div></article></div></div>')\n\n local nt = blocks.SWNT or {}\n table.insert(h, '<div class=\"rpg-status-bottom-bar-compact\">')\n if nt.Time1 then table.insert(h, '<span>📅 ' .. escapeHtml(nt.Time1) .. '</span>') end\n if nt.Time2 then table.insert(h, '<span>⏰ ' .. escapeHtml(nt.Time2) .. '</span>') end\n if nt.Weather then table.insert(h, '<span>' .. escapeHtml(nt.Weather) .. '</span>') end\n table.insert(h, '<span>📍 위치: ' .. escapeHtml(nm.Location or \"\") .. '</span></div></div></div>')\n if switchMode == 1 then table.insert(h, '</details>') elseif switchMode == 2 then table.insert(h, '</div><button class=\"swcww1-closebtn\" popovertargetaction=\"hide\" popovertarget=\"swcww1-dialog-' .. escapeHtml(dialogId) .. '\">닫기</button></div></dialog>') end\n return table.concat(h, \"\\n\")\nend\n\n-- [[ 4. 진입점 및 제한 로직 ]]\nlistenEdit(\"editDisplay\", function(triggerId, data, meta)\n if not data or data == \"\" or not data:find(\"<swn%-statuswindow>\") then return data end\n\n local currentIndex = -1\n if type(meta) == \"table\" and meta.index then\n currentIndex = meta.index\n end\n\n local now = os.clock()\n if not swn_cache.vars or (now - swn_cache.last_load > 0.5) then\n local var_list = {\n \"toggle_SWNSWITCH\", \n \"toggle_swn-statuswindow.mode\", \n \"toggle_SWNAFIELD1\", \n \"toggle_SWNAFIELD2\", \n \"toggle_SWNBFIELD1\",\n \"toggle_SHOW_LIMIT\"\n }\n swn_cache.vars = {}\n for _, v in ipairs(var_list) do \n swn_cache.vars[v] = getGlobalVar(triggerId, v) \n end\n swn_cache.last_load = now\n end\n\n local totalLength = getChatLength(triggerId)\n local currentShowLimit = tonumber(swn_cache.vars[\"toggle_SHOW_LIMIT\"]) or DEFAULT_SHOW_LIMIT\n\n if currentIndex ~= -1 and totalLength > 0 then\n if currentIndex < (totalLength - currentShowLimit) then\n return data:gsub(\"<swn%-statuswindow>.-</swn%-statuswindow>\", \"\")\n end\n end\n\n if swn_rendered_cache[data] then return swn_rendered_cache[data] end\n\n local function parseSWNBlock(content)\n local res = {}\n for k, v in string.gmatch(content, \"([^:|]+):([^|]*)\") do\n res[k:match(\"^%s*(.-)%s*$\")] = v:match(\"^%s*(.-)%s*$\")\n end\n return res\n end\n\n local processedData = data:gsub(\"(<swn%-statuswindow>)(.-)(</swn%-statuswindow>)\", function(_, innerContent, _)\n local htmlOutput = {}\n local currentBlocks = {}\n for tag, block_with_brackets in string.gmatch(innerContent, \"SWN([A-Z0-9]+)(%b[])\") do\n local content = block_with_brackets:sub(2, -2)\n local fullTag = \"SWN\" .. tag\n currentBlocks[fullTag] = parseSWNBlock(content)\n if fullTag == \"SWNT\" then\n local success, html = pcall(renderSWNStatus, triggerId, currentBlocks, function(_, name) return swn_cache.vars[name] or \"0\" end)\n if success then table.insert(htmlOutput, html) end\n currentBlocks = {}\n end\n end\n return #htmlOutput > 0 and ('<div class=\"swcww1-flex-container\" style=\"display:flex; flex-wrap:wrap; gap:8px; margin:8px 0;\">' .. table.concat(htmlOutput, \"\") .. '</div>') or \"\"\n end)\n\n local c = 0; for _ in pairs(swn_rendered_cache) do c = c + 1 end\n if c > 30 then swn_rendered_cache = {} end\n swn_rendered_cache[data] = processedData\n\n return processedData\nend)\n"
}
],
"lowLevelAccess": false,
"_id": "trig_mja32om2_9mwjra"
}
],
"lowLevelAccess": false,
"backgroundEmbedding": "<style>\n/* =============================================\n 1. 기본 레이아웃 및 테마 관리\n ============================================= */\n\n/* 모든 자식 요소가 사용 */\n.swcww1-theme-host {\n /* 변수 선언 위치는 여기로 유지합니다 (다이얼로그 내부 요소들을 위해) */\n}\n\n/* --- 테마 0: 오리지널 핑크 (다크) --- */\n{{#if {{? {{getglobalvar::toggle_SWNTHEMES}}=0}}}}\n.swcww1-theme-host {\n --rpg-theme-color-main: #ff85a2;\n --rpg-theme-color-accent: #ffc0cb;\n --rpg-theme-color-bg: rgba(255, 133, 162, 0.1);\n --rpg-bg-primary: #2f2c33;\n --rpg-bg-secondary: #3a363f;\n --rpg-bg-tertiary: #252228;\n --rpg-text-primary: #e1dde4;\n --rpg-text-secondary: #c8c0cf;\n --rpg-text-tertiary: #a9aeb3;\n --rpg-text-white: #ffffff;\n --rpg-border-primary: #6a5f70;\n --rpg-border-secondary: #4d444d;\n --rpg-border-stat-item: #554850;\n --rpg-tooltip-bg: #333333;\n}\n.swcww1-openbtn {\n background-color: #3a363f; border-color: #6a5f70; color: #e1dde4;\n}\n.swcww1-openbtn:hover, .swcww1-openbtn:focus {\n background-color: #4d444d; border-color: #ff85a2;\n}\n{{/if}}\n\n/* --- 테마 1: 클린 라이트 (가독성 강화) --- */\n{{#if {{? {{getglobalvar::toggle_SWNTHEMES}}=1}}}}\n.swcww1-theme-host {\n --rpg-theme-color-main: #007aff;\n --rpg-theme-color-accent: #5856d6;\n --rpg-theme-color-bg: rgba(0, 122, 255, 0.08);\n --rpg-bg-primary: #f9f9f9;\n --rpg-bg-secondary: #ffffff;\n --rpg-bg-tertiary: #efeff4;\n --rpg-text-primary: #1d1d1f; \n --rpg-text-secondary: #4a4a4f; \n --rpg-text-tertiary: #6e6e73; \n --rpg-text-white: #000000;\n --rpg-border-primary: #d1d1d6;\n --rpg-border-secondary: #c7c7cc;\n --rpg-border-stat-item: #e5e5ea;\n --rpg-tooltip-bg: #222222;\n}\n.swcww1-openbtn {\n background-color: #ffffff; border-color: #d1d1d6; color: #1d1d1f;\n}\n.swcww1-openbtn:hover, .swcww1-openbtn:focus {\n background-color: #efeff4; border-color: #007aff;\n}\n{{/if}}\n\n\n/* --- 테마 2: 신스웨이브 다크 (가독성 강화) --- */\n{{#if {{? {{getglobalvar::toggle_SWNTHEMES}}=2}}}}\n.swcww1-theme-host {\n --rpg-theme-color-main: #ff79c6; \n --rpg-theme-color-accent: #8be9fd; \n --rpg-theme-color-bg: rgba(255, 121, 198, 0.1);\n --rpg-bg-primary: #282a36;\n --rpg-bg-secondary: #3a3c4c;\n --rpg-bg-tertiary: #21222c;\n --rpg-text-primary: #f0f0f0;\n --rpg-text-secondary: #b8c0e0; \n --rpg-text-tertiary: #828aad; \n --rpg-text-white: #f0f0f0;\n --rpg-border-primary: #44475a;\n --rpg-border-secondary: #44475a;\n --rpg-border-stat-item: #44475a;\n --rpg-tooltip-bg: #21222c;\n}\n.swcww1-openbtn {\n background-color: #3a3c4c; border-color: #44475a; color: #f0f0f0;\n}\n.swcww1-openbtn:hover, .swcww1-openbtn:focus {\n background-color: #44475a; border-color: #ff79c6;\n}\n{{/if}}\n\n\n/* --- 테마 3: 빈티지 세피아 (가독성 강화) --- */\n{{#if {{? {{getglobalvar::toggle_SWNTHEMES}}=3}}}}\n.swcww1-theme-host {\n --rpg-theme-color-main: #b45309;\n --rpg-theme-color-accent: #c2410c;\n --rpg-theme-color-bg: rgba(180, 83, 9, 0.08);\n --rpg-bg-primary: #f4f1e9;\n --rpg-bg-secondary: #e9e4d9;\n --rpg-bg-tertiary: #dcd6c9;\n --rpg-text-primary: #41352f; \n --rpg-text-secondary: #65564e; \n --rpg-text-tertiary: #8b7d75; \n --rpg-text-white: #3d2c21;\n --rpg-border-primary: #dcd6c9;\n --rpg-border-secondary: #c9c1b5;\n --rpg-border-stat-item: #e0dace;\n --rpg-tooltip-bg: #3d2c21;\n}\n.swcww1-openbtn {\n background-color: #e9e4d9; border-color: #dcd6c9; color: #41352f;\n}\n.swcww1-openbtn:hover, .swcww1-openbtn:focus {\n background-color: #dcd6c9; border-color: #b45309;\n}\n{{/if}}\n\n\n/* --- 테마 4: 세이지 그린 --- */\n{{#if {{? {{getglobalvar::toggle_SWNTHEMES}}=4}}}}\n.swcww1-theme-host {\n --rpg-theme-color-main: #88b39a; \n --rpg-theme-color-accent: #a3c9b4; \n --rpg-theme-color-bg: rgba(136, 179, 154, 0.07);\n --rpg-bg-primary: #313b37; \n --rpg-bg-secondary: #3e4944;\n --rpg-bg-tertiary: #28312e;\n --rpg-text-primary: #eaf0ed; \n --rpg-text-secondary: #b0c0b8; \n --rpg-text-tertiary: #98a5a0; \n --rpg-text-white: #eaf0ed;\n --rpg-border-primary: #4a5752;\n --rpg-border-secondary: #4a5752;\n --rpg-border-stat-item: #4a5752;\n --rpg-tooltip-bg: #28312e;\n}\n.swcww1-openbtn {\n background-color: #3e4944; border-color: #4a5752; color: #eaf0ed;\n}\n.swcww1-openbtn:hover, .swcww1-openbtn:focus {\n background-color: #4a5752; border-color: #88b39a;\n}\n{{/if}}\n\n\n/* --- 테마 5: 솔라라이즈드 다크 (고대비) --- */\n{{#if {{? {{getglobalvar::toggle_SWNTHEMES}}=5}}}}\n.swcww1-theme-host {\n --rpg-theme-color-main: #268bd2; \n --rpg-theme-color-accent: #859900; \n --rpg-theme-color-bg: rgba(38, 139, 210, 0.08);\n --rpg-bg-primary: #002b36; \n --rpg-bg-secondary: #073642;\n --rpg-bg-tertiary: #001f29;\n --rpg-text-primary: #cad8d9; \n --rpg-text-secondary: #93a1a1; \n --rpg-text-tertiary: #839496; \n --rpg-text-white: #eee8d5; \n --rpg-border-primary: #073642;\n --rpg-border-secondary: #586e75;\n --rpg-border-stat-item: #073642;\n --rpg-tooltip-bg: #001f29;\n}\n.swcww1-openbtn {\n background-color: #073642; border-color: #586e75; color: #cad8d9; /* ★ 변경 */\n}\n.swcww1-openbtn:hover, .swcww1-openbtn:focus {\n background-color: #586e75; border-color: #268bd2;\n}\n{{/if}}\n\n\n\n\n\n\n/* 상태창 기본 컨테이너 */\n.rpg-status-container-compact {\n font-family: 'Noto Sans KR', sans-serif;\n width: 100%; max-width: 720px; margin: 0 auto;\n border-radius: 8px; background-color: var(--rpg-bg-primary);\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);\n border: 1px solid var(--rpg-border-primary); color: var(--rpg-text-primary);\n overflow: visible; display: flex; align-items: stretch; position: relative;\n}\n\n.button-box + .rpg-status-container-compact { margin-top: 0.6em; }\n.box-wrapper + .rpg-status-container-compact { margin-top: 1.2em; }\n\n.rpg-status-content-column {\n flex-grow: 1; display: flex; flex-direction: column;\n background-color: var(--rpg-bg-primary); min-width: 0; width: 100%;\n}\n\n/* =============================================\n 2. 상단 캐릭터 정보 섹션\n ============================================= */\n.rpg-status-top-compact,\n.rpg-status-top-compact-secondary { padding: 8px 14px; background-color: var(--rpg-bg-secondary); }\n.rpg-status-top-compact { border-bottom: 1px solid var(--rpg-theme-color-main); }\n.rpg-status-identity-compact { font-size: 0.88em; min-width: 0; }\n.rpg-status-name-compact {\n font-size: 1.3em; font-weight: 700; color: var(--rpg-text-white);\n margin: 0 0 3px 0; line-height: 1.2; padding: 0;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: none;\n}\n.rpg-status-id-line-compact {\n margin-bottom: 3px; color: var(--rpg-text-secondary); line-height: 1.3;\n display: flex; align-items: flex-start;\n}\n.rpg-status-id-line-compact strong {\n color: var(--rpg-text-secondary); margin-right: 7px; font-weight: 600;\n display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap; padding-top: 1px; flex-shrink: 0; font-size: 1.05em;\n}\n.rpg-status-id-line-compact span { color: var(--rpg-text-primary); flex-grow: 1; min-width: 0; }\n.rpg-status-id-line-compact .rpg-icon-compact { font-size: 1em; margin-top: 0px; flex-shrink: 0; color: var(--rpg-theme-color-main); }\n\n/* =============================================\n 3. 스탯 표시 그리드 섹션\n ============================================= */\n.rpg-status-main-compact,\n.rpg-status-additional-stats-compact {\n display: grid; grid-template-columns: repeat(auto-fit, minmax(135px, 1fr));\n gap: 5px 7px; padding: 7px 12px; font-size: 0.85em;\n background-color: var(--rpg-bg-primary); border-bottom: 1px solid var(--rpg-border-secondary); min-width: 0;\n}\n.rpg-status-main-compact { flex-grow: 1; }\n.rpg-status-additional-stats-compact { margin-bottom: 6px; }\n.rpg-status-additional-stats-compact-secondary {\n padding: 7px 12px; gap: 5px 7px; font-size: 0.9em;\n background-color: var(--rpg-bg-primary); margin-bottom: 6px; border-bottom: 1px solid var(--rpg-border-secondary);\n}\n.rpg-status-additional-stats-compact-third { margin-bottom: 10px; }\n.rpg-status-stat-item-compact {\n background-color: var(--rpg-bg-secondary); border-radius: 4px; padding: 5px 8px;\n display: flex; justify-content: space-between; align-items: center;\n border: 1px solid var(--rpg-border-stat-item); min-height: 24px;\n transition: background-color 0.2s ease, border-color 0.2s ease;\n font-size: 0.85em; position: relative; cursor: pointer; min-width: 0;\n}\n.rpg-status-stat-item-compact:hover { background-color: var(--rpg-border-secondary); border-color: var(--rpg-theme-color-main); }\n.rpg-status-stat-item-compact strong {\n color: var(--rpg-text-secondary); font-weight: 500; display: inline-flex; align-items: center;\n gap: 4px; margin-right: 6px; white-space: nowrap; padding-top: 0; flex-shrink: 0;\n}\n.rpg-status-stat-item-compact strong .rpg-icon-compact { color: var(--rpg-theme-color-accent); }\n.rpg-status-stat-item-compact span:last-child {\n color: var(--rpg-text-white); font-weight: 500; text-align: right;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n flex: 1 1 0; min-width: 0;\n}\n.rpg-status-stat-item-compact::after {\n content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);\n background: var(--rpg-tooltip-bg); color: #fff; padding: 6px 10px; border-radius: 5px; font-size: 0.9em;\n opacity: 0; pointer-events: none; transition: opacity 0.2s ease; z-index: 100;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); display: inline-block; width: max-content;\n max-width: min(200px, calc(100vw - 120px)); box-sizing: border-box; white-space: normal; word-break: break-word;\n}\n.rpg-status-stat-item-compact:hover::after, .rpg-status-stat-item-compact:focus::after,\n.rpg-status-stat-item-compact:active::after, .rpg-status-stat-item-compact:focus-within::after { opacity: 1; }\n.rpg-status-thought-bubble-compact {\n grid-column: 1 / -1; background-color: var(--rpg-theme-color-bg);\n border-radius: 4px; padding: 6px 10px; margin-top: 4px;\n font-style: italic; font-size: 0.9em; color: var(--rpg-text-primary);\n border-left: 3px solid var(--rpg-theme-color-main); line-height: 1.3; white-space: normal;\n}\n.rpg-status-thought-bubble-compact strong {\n margin-right: 5px; font-style: normal; font-weight: 700; font-size: 1em; color: var(--rpg-theme-color-main);\n}\n\n/* =============================================\n 4. 하단 바 및 공용 아이콘\n ============================================= */\n.rpg-status-bottom-bar-compact {\n background-color: var(--rpg-bg-tertiary); padding: 6px 12px; font-size: 0.8em; color: var(--rpg-text-tertiary);\n display: flex; flex-wrap: wrap; justify-content: center; align-items: center;\n border-top: 1px solid var(--rpg-border-primary); gap: 2px 8px; margin-top: auto;\n}\n.rpg-status-bottom-bar-compact span { display: flex; align-items: center; gap: 4px; }\n.rpg-status-bottom-bar-compact span:nth-child(4) { flex-basis: 100%; justify-content: center; }\n.rpg-icon-compact { display: inline-flex; width: 1.2em; justify-content: center; align-items: center; flex-shrink: 0; }\n\n/* =============================================\n 5. 미디어 쿼리 (반응형 디자인)\n ============================================= */\n@media (max-width: 900px) {\n .rpg-status-container-compact { max-width: 98vw; }\n .rpg-status-main-compact, .rpg-status-additional-stats-compact { font-size: 0.97em; padding: 8px 6px; }\n}\n@media (max-width: 600px) {\n .rpg-status-container-compact { width: 100%; max-width: 100vw; margin: 0; }\n .rpg-status-main-compact, .rpg-status-additional-stats-compact { grid-template-columns: 1fr 1fr; gap: 7px 5px; font-size: 1em; padding: 8px 3vw; }\n .rpg-status-bottom-bar-compact { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: 4px 8px; padding: 8px 3vw; }\n\t.rpg-status-bottom-bar-compact span { flex: 1 1 calc(33.333% - 8px); box-sizing: border-box; justify-content: center; text-align: center; }\n .rpg-status-bottom-bar-compact span:nth-child(4) { flex: 1 1 100%; }\n .rpg-status-name-compact { text-align: center; font-size: 1.1em; }\n\t.rpg-status-stat-item-compact { padding: 3px 6px; font-size: 0.85em; min-height: 20px; }\n\t.rpg-status-stat-item-compact strong { font-size: 0.88em; gap: 3px; margin-right: 4px; }\n\t.rpg-status-stat-item-compact .rpg-icon-compact { font-size: 0.85em; width: 1em; }\n\t.rpg-status-stat-item-compact span:last-child { font-size: 0.85em; }\n}\n@media (max-width: 420px) {\n .rpg-status-main-compact, .rpg-status-additional-stats-compact { grid-template-columns: repeat(2, 1fr); gap: 5px 5px; padding: 7px 2vw; }\n .rpg-status-bottom-bar-compact, .rpg-status-identity-compact, .rpg-status-stat-item-compact { font-size: 0.8em; }\n .rpg-status-bottom-bar-compact { padding: 8px 2vw; }\n}\n\n/* =============================================\n 6. 파티마인드 및 팝업\n ============================================= */\n\n.partymind {\n border: 1px solid var(--risu-theme-darkborderc); border-radius: 12px; display: flex; flex-wrap: wrap;\n gap: 12px 32px; margin: 8px 0; padding: 12px; position: relative;\n}\n.partymind::before { content: '👨👩👧👦💭'; font-size: 10px; position: absolute; top: 0; transform: translateY(-50%); left: 12px; }\n.partymind-item { align-items: flex-start; display: flex; gap: 16px; }\n.partymind-picwrap { flex-shrink: 0; position: relative; }\n.partymind-picwrap::after { bottom: 0; content: attr(data-emo); line-height: 1; position: absolute; right: -2px; }\n.partymind-pic {\n aspect-ratio: 1/1; background: var(--rpg-bg-primary); border-radius: 100%; margin: 0;\n object-fit: cover; object-position: top center; position: relative; width: 36px;\n}\n.partymind-pic::after { background: url({{raw::swn-placeholder}}) center / contain; border-radius: 100%; content: ''; inset: 0; position: absolute; }\n\n.partymind-name {\n color: var(--rpg-text-primary);\n font-size: 10px; line-height: 1.2; margin: 0 !important;\n}\n\n.partymind-bubble { background: #ffd521; border-radius: 8px; color: #333; font-size: smaller; margin: 4px 0 0; padding: 4px 12px; position: relative; }\n.partymind-bubble::before { border-color: transparent #ffd521 transparent transparent; border-style: solid; border-width: 6px 8px; content: ''; position: absolute; right: calc(100% - 2px); top: 6px; }\n.partymind-quotes[data-type=\"T\"]::before { content: \"‘\"; } .partymind-quotes[data-type=\"T\"]::after { content: \"’\"; }\n.partymind-quotes[data-type=\"V\"]::before { content: '“'; } .partymind-quotes[data-type=\"V\"]::after { content: '”'; }\n\n.swcww1-dialog {\n width: 96vw; max-width: 740px; max-height: calc(100vh - 40px); background-color: var(--rpg-bg-primary);\n border: none; border-radius: 12px; padding: 0; box-sizing: border-box; overflow: hidden;\n position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0;\n}\n.swcww1-dialog::backdrop { background-color: rgba(0, 0, 0, 0.5); }\n.swcww1-wrapper { display: flex; flex-direction: column; max-height: calc(100vh - 40px); }\n.swcww1-scroll-area { flex: 1 1 auto; overflow-y: auto; padding: 1em; box-sizing: border-box; min-height: 0; }\n\n.swcww1-closebtn {\n font-family: 'Noto Sans KR', sans-serif; font-weight: 600; cursor: pointer; border: 1px solid transparent; transition: background-color 0.2s ease, border-color 0.2s ease;\n background-color: var(--rpg-bg-tertiary); color: var(--rpg-text-primary); padding: 0.8em; font-size: 0.85rem; border-top: 1px solid var(--rpg-border-secondary); flex-shrink: 0;\n}\n.swcww1-closebtn:hover, .swcww1-closebtn:focus { background-color: var(--rpg-border-secondary); border-color: var(--rpg-theme-color-main); outline: none; }\n\n.swcww1-openbtn {\n font-family: 'Noto Sans KR', sans-serif; font-weight: 600; cursor: pointer; border: 1px solid transparent;\n transition: background-color 0.2s ease, border-color 0.2s ease;\n display: inline-block; width: auto; box-sizing: border-box;\n padding: 0.7em 1em; margin: 0.8em 0; border-radius: 8px;\n font-size: 0.95rem; text-align: center; text-decoration: none;\n}\n@media (min-width: 600px) { .swcww1-openbtn { font-size: 0.85rem; padding: 0.3em 1em; margin: 0.4em 0; } }\n\n.button-swnreroll {\n position: absolute; top: 4px; right: 4px; z-index: 10; background: none; border: none; cursor: pointer;\n font-size: 1.2rem; line-height: 1; padding: 0.25em; border-radius: 50%;\n display: inline-flex; align-items: center; justify-content: center;\n transition: transform 0.2s ease, background-color 0.2s ease;\n}\n.button-swnreroll:hover { background-color: rgba(0, 0, 0, 0.1); }\n</style>",
"displayOrder": 700
}