@coxwave/tap-sdk 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,390 +1,194 @@
1
- # ax-sdk-chatbot
1
+ # @coxwave/tap-sdk
2
2
 
3
- ## version: 1.1.0
3
+ A vanilla JavaScript SDK for embedding AI chat widgets into web applications with seamless iframe communication.
4
4
 
5
- ## 📚 Table of Contents
6
-
7
- - [Installation](#installation)
8
- - [Quick Use](#quick-use)
9
- - [Types](#types)
10
- - [Legacy](#legacy)
11
- - [License](#license)
12
-
13
- ## installation
14
-
15
- ### npm
5
+ ## Installation
16
6
 
17
7
  ```bash
18
- npm i ax-sdk-chatbot
8
+ npm install @coxwave/tap-sdk
19
9
  ```
20
10
 
21
- ### yarn
22
-
23
- ```bash
24
- yarn add ax-sdk-chatbot
25
- ```
26
-
27
- ## Quick Use
28
-
29
- ### vite
30
-
31
- #### Use In Root
32
-
33
- ```ts
34
- -main.tsx;
35
-
36
- import { createRoot } from "react-dom/client";
11
+ ## Quick Start
37
12
 
38
- import TapSDK from "ax-sdk-chatbot";
39
-
40
- import App from "./App.tsx";
41
-
42
- import "./index.css";
13
+ ```javascript
14
+ import TapSDK from "@coxwave/tap-sdk";
43
15
 
44
16
  const sdk = new TapSDK({
45
- hostClientUrl: import.meta.env.VITE_CLIENT_URL, // your client url (if you use localhost, your client url is http://localhost:5173)
46
- pluginKey: import.meta.env.VITE_FIRSTBRAIN_PLUGIN_KEY,
47
- isProd: false,
17
+ pluginKey: "your-plugin-key",
18
+ isProd: true,
48
19
  });
49
20
 
50
- createRoot(document.getElementById("root")!).render(<App />);
51
-
52
- sdk.initChat({
21
+ await sdk.initChat({
53
22
  chatApiParams: {
54
- userId: "user_id",
55
- courseId: "course_id",
56
- courseName: "course_name",
57
- courseCategory: "course_category",
58
- courseSubCategory: "course_sub_category",
59
- clipId: "clip_id",
60
- clipPlayHead: clip_play_head_number,
61
- },
62
- shortcutKey: {
63
- openChat: { key: "/", modifier: "" },
64
- sendChat: { key: "Enter", modifier: "" },
65
- },
66
- customStyles: {
67
- floatingButton: {
68
- isInElement: true,
69
- parentElementId: "root-button", // <------ here is your Floating Button parent element Id
70
- },
23
+ userId: "user-123",
24
+ courseId: "course-456",
25
+ courseName: "JavaScript Fundamentals",
26
+ courseCategory: "Programming",
27
+ courseSubCategory: "Frontend",
28
+ clipId: null,
29
+ clipPlayHead: null,
71
30
  },
72
31
  });
32
+ ```
73
33
 
74
- -App.tsx;
75
-
76
- import { useEffect, useState } from "react";
77
-
78
- import "./App.css";
79
-
80
- import TapSDK from "coxwave-sdk";
81
-
82
- function App({ sdk }: { sdk: TapSDK }) {
83
- const [clipPlayHead, setClipPlayHead] = useState(0);
34
+ ## Features
84
35
 
85
- useEffect(() => {
86
- const interval = setInterval(() => {
87
- setClipPlayHead((prev) => prev + 5);
88
- }, 1000);
36
+ - 🎯 **Iframe Communication** - Secure cross-origin messaging with handshake protocol
37
+ - 🎨 **Customizable UI** - Floating button, chat body, and popup styling
38
+ - 📊 **Event System** - Timeline sync, chat events, alarms, and PDF integration
39
+ - 🔔 **Smart Notifications** - Auto-fading alarm system with custom styling
40
+ - 📱 **Responsive Design** - Mobile-friendly with automatic positioning
41
+ - 🚀 **Zero Dependencies** - Self-contained with tree-shaking optimization
89
42
 
90
- return () => clearInterval(interval);
91
- }, []);
43
+ ## API Reference
92
44
 
93
- useEffect(() => {
94
- sdk.postChatInfo({
95
- clipId: "58767",
96
- clipPlayHead,
97
- });
98
- }, [clipPlayHead]);
45
+ ### Constructor
99
46
 
100
- return (
101
- <>
102
- <div id="root-button">{Your Floating Button styles Element}</div> // <------ This is your floating button parent element. It must have the same ID as parentElementId.
103
- </>
104
- );
105
- }
106
-
107
- export default App;
47
+ ```javascript
48
+ new TapSDK(options)
108
49
  ```
109
50
 
110
- #### Use Custom Hook (with useEffect)
111
-
112
- - Test.tsx (can use any component)
113
-
114
- ```ts
115
- import { useEffect, useState } from "react";
51
+ **Options:**
52
+ - `pluginKey` (string) - Your unique plugin identifier
53
+ - `isProd` (boolean) - Production mode flag (default: false)
54
+ - `isLocal` (boolean) - Local development flag (default: false)
116
55
 
117
- import TapSDK from "ax-sdk-chatbot";
56
+ ### Methods
118
57
 
119
- import BotImage from "./assets/quick-menu.png";
58
+ #### `initChat(config)`
120
59
 
121
- const sdk = new TapSDK({
122
- hostClientUrl: import.meta.env.VITE_CLIENT_URL,
123
- pluginKey: import.meta.env.VITE_FIRSTBRAIN_PLUGIN_KEY,
124
- isProd: import.meta.env.VITE_IS_PROD === "true",
60
+ ```javascript
61
+ await sdk.initChat({
62
+ chatApiParams: {
63
+ userId: string,
64
+ courseId: string | null,
65
+ courseName: string,
66
+ courseCategory: string,
67
+ courseSubCategory: string,
68
+ clipId: string | null,
69
+ clipPlayHead: number | null
70
+ },
71
+ customStyles?: {
72
+ floatingButton?: {
73
+ isInElement?: boolean,
74
+ parentElementId?: string,
75
+ style?: Partial<CSSStyleDeclaration>
76
+ },
77
+ chatBody?: {
78
+ position?: { top?: string, right?: string, left?: string, bottom?: string },
79
+ width?: string,
80
+ height?: string,
81
+ borderRadius?: string
82
+ }
83
+ }
125
84
  });
85
+ ```
126
86
 
87
+ #### `seekTimeline(params)`
127
88
 
128
- function Test() {
129
- const [clipPlayHead, setClipPlayHead] = useState(0);
130
-
131
- useEffect(() => {
132
- sdk.initChat({
133
- chatApiParams: {
134
- userId: "user_id",
135
- courseId: "course_id",
136
- courseName: "course_name",
137
- courseCategory: "course_category",
138
- courseSubCategory: "course_sub_category",
139
- clipId: "clip_id",
140
- clipPlayHead: clip_play_head_number,
141
- },
142
- customStyles: {
143
- floatingButton: {
144
- isInElement: true,
145
- parentElementId: "root-button",
146
- },
147
- },
148
- });
149
-
150
- return () => {
151
- sdk.removeChat(); // this is sdk cleanup function
152
- };
153
- }, []);
154
-
155
- useEffect(() => {
156
- const interval = setInterval(() => {
157
- setClipPlayHead((prev) => prev + 5);
158
- }, 1000);
159
-
160
- return () => clearInterval(interval);
161
- }, []);
162
-
163
- useEffect(() => {
164
- sdk.postChatInfo({
165
- clipId: "58767",
166
- clipPlayHead,
167
- });
168
- }, [clipPlayHead]);
169
-
170
- return (
171
- <S.LayoutContainer $isWhiteBack={true}>
172
- <S.ContentBox>
173
- <S.RootButton id="root-button">
174
- <S.BotImage src={BotImage} />
175
- <S.Text>AI 튜터</S.Text>
176
- </S.RootButton>
177
- </S.ContentBox>
178
- </S.LayoutContainer>
179
- );
180
- }
181
-
182
- export default Test;
89
+ ```javascript
90
+ sdk.seekTimeline({
91
+ clipId: 'clip-123',
92
+ clipPlayHead: 150.5
93
+ });
94
+ ```
183
95
 
184
- const S = {
185
- ~
186
- } // your styles (this example is for styled-components)
96
+ #### `removeChat()`
187
97
 
98
+ ```javascript
99
+ sdk.removeChat();
188
100
  ```
189
101
 
190
- ### Next.js
102
+ ### Event Listeners
191
103
 
192
- - page.tsx
104
+ ```javascript
105
+ // Timeline seek events
106
+ sdk.events.onTimelineSeek((clipPlayHead, clipId) => {
107
+ console.log(`Seek to ${clipPlayHead}s in ${clipId}`);
108
+ });
193
109
 
194
- ```ts
195
- import Sdk from "./Sdk";
196
-
197
- export default function Home() {
198
- return (
199
- <Sdk />
200
- );
201
- }
110
+ // Chat state events
111
+ sdk.events.onChatOpened(() => console.log('Chat opened'));
112
+ sdk.events.onChatClosed(() => console.log('Chat closed'));
202
113
 
114
+ // Notification events
115
+ sdk.events.onAlarmFadeIn((messageInfo) => {
116
+ console.log('Alarm notification:', messageInfo);
117
+ });
203
118
  ```
204
119
 
205
- - Sdk.tsx
120
+ ## Framework Integration
206
121
 
207
- ```ts
208
- "use client"; // if you use this sdk in Next.js, you must use this
122
+ ### React
209
123
 
210
- import { useEffect, useRef } from "react";
124
+ ```jsx
125
+ import { useEffect, useRef } from 'react';
126
+ import TapSDK from '@coxwave/tap-sdk';
211
127
 
212
- import TapSDK from "ax-sdk-chatbot";
213
-
214
- const clientUrl = process.env.NEXT_PUBLIC_HOST_CLIENT_URL; // your client url (if you use localhost, your client url is http://localhost:3000)
215
- const pluginKey = process.env.NEXT_PUBLIC_COXWAVE_PLUGIN_KEY;
216
-
217
- if (!clientUrl) {
218
- throw new Error("NEXT_PUBLIC_COXWAVE_CLIENT_URL is not set");
219
- }
220
-
221
- if (!pluginKey) {
222
- throw new Error("NEXT_PUBLIC_COXWAVE_PLUGIN_KEY is not set");
223
- }
224
-
225
- function Sdk() {
226
- const iframeRef = useRef<HTMLDivElement>(null);
128
+ function ChatWidget({ userId, courseId }) {
129
+ const sdkRef = useRef(null);
227
130
 
228
131
  useEffect(() => {
229
- if (!clientUrl || !pluginKey) return;
230
-
231
- const TapSDKInstance = new TapSDK({
232
- hostClientUrl: clientUrl,
233
- pluginKey: pluginKey,
234
- });
235
-
236
- const init = async () => {
237
- try {
238
- await TapSDKInstance.initChat({
239
- chatApiParams: {
240
- userId: "user_id",
241
- courseId: "course_id",
242
- courseName: "course_name",
243
- courseCategory: "course_category",
244
- courseSubCategory: "course_sub_category",
245
- clipId: "clip_id",
246
- clipPlayHead: clip_play_head_number,
247
- },
248
- customStyles: {
249
- floatingButton: {
250
- isInElement: true,
251
- parentElementId: "root-button", // <------ here is your Floating Button parent element Id
252
- },
253
- },
254
- });
255
- } catch (err) {
256
- console.error("SDK initChat 실패:", err);
257
- }
132
+ const initSDK = async () => {
133
+ sdkRef.current = new TapSDK({
134
+ pluginKey: process.env.REACT_APP_TAP_PLUGIN_KEY,
135
+ isProd: process.env.NODE_ENV === 'production'
136
+ });
137
+
138
+ await sdkRef.current.initChat({
139
+ chatApiParams: { userId, courseId, /* ... */ }
140
+ });
258
141
  };
259
142
 
260
- init(); // 즉시 실행
143
+ initSDK();
144
+ return () => sdkRef.current?.removeChat();
145
+ }, [userId, courseId]);
261
146
 
262
- return () => {
263
- TapSDKInstance.removeChat();
264
- };
265
- }, [clientUrl]);
266
-
267
- return (
268
- <div
269
- ref={iframeRef}
270
- id="root-button" // <------ This is your floating button parent element. It must have the same ID as parentElementId.
271
- style={{
272
- width: "50px",
273
- height: "50px",
274
- backgroundColor: "red",
275
- cursor: "pointer",
276
- }}
277
- >
278
- <button>Open Chat</button>
279
- </div>
280
- );
147
+ return <div id="chat-container" />;
281
148
  }
282
-
283
- export default Sdk;
284
149
  ```
285
150
 
286
- ## Types
287
-
288
- ### SDK Class
289
-
290
- ```ts
291
- const TapSDKInstance = new TapSDK({
292
- hostClientUrl: "~",
293
- pluginKey: "~",
294
- });
151
+ ### Next.js
295
152
 
296
- type TapSDKType = {
297
- hostClientUrl: string;
298
- pluginKey: string;
299
- isProd?: boolean;
300
- };
301
- ```
153
+ ```jsx
154
+ "use client";
155
+ import { useEffect } from 'react';
156
+ import TapSDK from '@coxwave/tap-sdk';
302
157
 
303
- ### initChat Method
304
-
305
- ```ts
306
- async initChat({
307
- chatApiParams,
308
- customStyles,
309
- shortcutKey,
310
- }: {
311
- chatApiParams: ChatApiParamsType;
312
- customStyles?: CustomStylesType;
313
- shortcutKey?: ShortcutKeyType;
314
- })
315
-
316
- type ChatApiParamsType = {
317
- userId: string;
318
- courseId: string;
319
- courseName: string;
320
- courseCategory: string;
321
- courseSubCategory: string;
322
- clipId: string | null;
323
- clipPlayHead: number | null;
324
- };
325
-
326
- type CustomStylesType = {
327
- floatingButton?: FloatingButtonType;
328
- chatBody?: ChatBodyType;
329
- };
330
-
331
- type ShortcutKeyType = {
332
- openChat: ShortcutKeyPropertiesType;
333
- sendChat: ShortcutKeyPropertiesType;
334
- };
335
-
336
- type FloatingButtonType = {
337
- isInElement?: boolean;
338
- parentElementId?: string;
339
- style?: Partial<CSSStyleDeclaration>;
340
- };
341
-
342
- type ChatBodyType = {
343
- position?: PositionType;
344
- width?: string;
345
- height?: string;
346
- };
347
-
348
- type PositionType = {
349
- top?: string;
350
- left?: string;
351
- right?: string;
352
- bottom?: string;
353
- };
354
-
355
- type ShortcutKeyPropertiesType = {
356
- key: string;
357
- modifier: "ctrlKey" | "altKey" | "shiftKey" | "metaKey" | "";
358
- };
158
+ export default function ChatPage() {
159
+ useEffect(() => {
160
+ const sdk = new TapSDK({
161
+ pluginKey: process.env.NEXT_PUBLIC_TAP_PLUGIN_KEY,
162
+ isProd: process.env.NODE_ENV === 'production'
163
+ });
359
164
 
360
- ```
165
+ sdk.initChat({
166
+ chatApiParams: { /* ... */ }
167
+ });
361
168
 
362
- ### postChatInfo Method
169
+ return () => sdk.removeChat();
170
+ }, []);
363
171
 
364
- ```ts
365
- postChatInfo({
366
- clipId,
367
- clipPlayHead,
368
- }: {
369
- clipId: string;
370
- clipPlayHead: number;
371
- })
172
+ return <div>Chat Widget will appear here</div>;
173
+ }
372
174
  ```
373
175
 
374
- - you must use postChatInfo method after initChat method
176
+ ## Build Formats
375
177
 
376
- ### removeChat Method
377
-
378
- ```ts
379
- removeChat();
380
- ```
178
+ - **ESM**: `dist/index.mjs` - Modern ES modules
179
+ - **CJS**: `dist/index.js` - CommonJS for Node.js
180
+ - **IIFE**: `dist/index.global.js` - Browser global variable
181
+ - **Types**: `dist/index.d.ts` - TypeScript declarations
381
182
 
382
- ## legacy
183
+ ## Browser Support
383
184
 
384
- Ver 0.x.x: https://www.npmjs.com/package/ax-sdk-chatbot/v/0.3.7
185
+ - Chrome 60+
186
+ - Firefox 60+
187
+ - Safari 12+
188
+ - Edge 79+
385
189
 
386
- ## license
190
+ ## License
387
191
 
388
- [MIT](https://opensource.org/licenses/MIT)
192
+ MIT
389
193
 
390
- Copyright (c) 2025-present, Coxwave
194
+ Copyright (c) 2025-present, Coxwave
package/dist/index.js CHANGED
@@ -11,14 +11,14 @@
11
11
  }
12
12
  })();
13
13
 
14
- 'use strict';var d=require('valibot');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var d__namespace=/*#__PURE__*/_interopNamespace(d);var xe=Object.defineProperty;var R=s=>{throw TypeError(s)};var Te=(s,t,e)=>t in s?xe(s,t,{enumerable:true,configurable:true,writable:true,value:e}):s[t]=e;var r=(s,t,e)=>Te(s,typeof t!="symbol"?t+"":t,e),z=(s,t,e)=>t.has(s)||R("Cannot "+e);var K=(s,t,e)=>(z(s,t,"read from private field"),e?e.call(s):t.get(s)),v=(s,t,e)=>t.has(s)?R("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(s):t.set(s,e);var g=(s,t,e)=>(z(s,t,"access private method"),e);var V="_1mlv4me2",w="_1mlv4me4";var _="_1mlv4me3";var A=class{constructor(){r(this,"chatBody",null);this.chatBody=null;}createChatBody({customChatBody:t}){return this.chatBody?this.chatBody:(this.chatBody=document.createElement("div"),this.chatBody.id="cw-chat-body",this.chatBody.className=V,this.chatBody.style.setProperty("z-index","10000001","important"),this.chatBody.style.setProperty("position","fixed","important"),Object.assign(this.chatBody.style,{top:t?.position?.top??"50px",right:t?.position?.right??"24px",left:t?.position?.left??"unset",bottom:t?.position?.bottom??"unset",width:t?.width??"340px",height:t?.height??"calc(100% - 116px)",overflow:"hidden",backgroundColor:"transparent",borderRadius:t?.borderRadius??"16px",boxShadow:`
14
+ 'use strict';var je=Object.defineProperty;var J=i=>{throw TypeError(i)};var $e=(i,t,e)=>t in i?je(i,t,{enumerable:true,configurable:true,writable:true,value:e}):i[t]=e;var u=(i,t,e)=>$e(i,typeof t!="symbol"?t+"":t,e),Z=(i,t,e)=>t.has(i)||J("Cannot "+e);var Y=(i,t,e)=>(Z(i,t,"read from private field"),e?e.call(i):t.get(i)),g=(i,t,e)=>t.has(i)?J("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(i):t.set(i,e);var d=(i,t,e)=>(Z(i,t,"access private method"),e);var Q="_1mlv4me2",w="_1mlv4me4";var O="_1mlv4me3";var D=class{constructor(){u(this,"chatBody",null);this.chatBody=null;}createChatBody({customChatBody:t}){return this.chatBody?this.chatBody:(this.chatBody=document.createElement("div"),this.chatBody.id="cw-chat-body",this.chatBody.className=Q,this.chatBody.style.setProperty("z-index","10000001","important"),this.chatBody.style.setProperty("position","fixed","important"),Object.assign(this.chatBody.style,{top:t?.position?.top??"50px",right:t?.position?.right??"24px",left:t?.position?.left??"unset",bottom:t?.position?.bottom??"unset",width:t?.width??"340px",height:t?.height??"calc(100% - 116px)",overflow:"hidden",backgroundColor:"transparent",borderRadius:t?.borderRadius??"16px",boxShadow:`
15
15
  rgba(255, 255, 255, 0.12) 0px 0px 2px 0px inset,
16
16
  rgba(0, 0, 0, 0.05) 0px 0px 2px 1px,
17
17
  rgba(0, 0, 0, 0.3) 0px 12px 60px
18
- `,willChange:"transform, opacity, width, max-height, max-width"}),document.body.appendChild(this.chatBody),this.chatBody)}toggleVisibility(t){if(!this.chatBody)return;this.chatBody.classList.remove(_,w),this.chatBody.style.display="block";let e=()=>{this.chatBody&&(this.chatBody.classList.contains(w)&&(this.chatBody.style.display="none"),this.chatBody.removeEventListener("animationend",e));};this.chatBody.addEventListener("animationend",e),requestAnimationFrame(()=>{this.chatBody?.classList.add(t?_:w);});}removeChatBody(){this.chatBody&&(this.chatBody.remove(),this.chatBody=null);}resizeChatBody(t,e){if(!this.chatBody)return;let i=e?.width??"340px",a=parseInt(i,10),o=a/3*10-a,n=t?`${a+o}px`:`${a}px`;this.chatBody.style.width=n;}},W=A;var G="_6j1ub51",L={default:"_6j1ub5b _6j1ub5a","call-to-action":"_6j1ub5c _6j1ub5a"},$="_6j1ub5a",q="_6j1ub59",P={default:"_6j1ub5e _6j1ub5d","call-to-action":"_6j1ub5f _6j1ub5d"},Y="_6j1ub5d",X="_6j1ub5h",J="_6j1ub5g",O="_6j1ub53",Z="_6j1ub58",S={default:"_6j1ub56 _6j1ub55","call-to-action":"_6j1ub57 _6j1ub55"},Q="_6j1ub55",H="_6j1ub52",ee="_6j1ub54";var c,te,ae,ie,re,se,j=class{constructor(){v(this,c);r(this,"container");r(this,"alarmTimeout");r(this,"alarmCornerSVG");r(this,"textContainer");r(this,"circleElement");r(this,"textInTextContainer");r(this,"messageInfo");}render({rootElement:t}){this.container=document.createElement("div"),this.container.id="alarm-container",this.container.className=G,this.container.addEventListener("click",i=>{i.stopPropagation();}),t.appendChild(this.container),g(this,c,te).call(this,this.container);let e=g(this,c,ae).call(this,this.container);g(this,c,re).call(this,e),g(this,c,ie).call(this,e);}fadeIn(t){t.type==="default"||t.type==="hourSpent"?(this.textContainer.className=S.default,this.alarmCornerSVG.setAttribute("class",L.default),this.circleElement.className=P.default):(this.textContainer.className=S["call-to-action"],this.alarmCornerSVG.setAttribute("class",L["call-to-action"]),this.circleElement.className=P["call-to-action"]),this.messageInfo=t,this.textInTextContainer.textContent=t.message,this.toggleVisibility(true),this.alarmTimeout=setTimeout(()=>{this.toggleVisibility(false);},18*1e3);}addClickEvent({callback:t}){this.container.addEventListener("click",()=>{this.toggleVisibility(false),t(this.messageInfo);});}toggleVisibility(t){this.container.classList.remove(H,O),requestAnimationFrame(()=>{this.container?.classList.add(t?H:O);});}remove(){this.container&&this.toggleVisibility(false),this.alarmTimeout&&clearTimeout(this.alarmTimeout);}};c=new WeakSet,te=function(t){let e=document.createElement("div");e.className=q,t.appendChild(e);let i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","11"),i.setAttribute("height","8"),i.setAttribute("viewBox","0 0 11 8"),i.setAttribute("fill","currentColor"),i.setAttribute("class",$);let a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("d","M5.5 0L11.1292 8.25H-0.129165L5.5 0Z"),a.setAttribute("fill","currentColor"),i.appendChild(a),this.alarmCornerSVG=i,e.appendChild(i);},ae=function(t){let e=document.createElement("div");return e.className=ee,t.appendChild(e),e},ie=function(t){this.textContainer=document.createElement("div"),this.textContainer.className=Q,t.appendChild(this.textContainer),this.textInTextContainer=document.createElement("span"),this.textInTextContainer.className=Z,this.textContainer.appendChild(this.textInTextContainer);},re=function(t){let e=document.createElement("div");e.className=Y,t.appendChild(e),e.addEventListener("click",a=>{a.stopPropagation(),this.remove();});let i=document.createElement("span");i.className=X,e.appendChild(i),i.textContent="\uC54C\uB9BC \uB044\uAE30",g(this,c,se).call(this,e),this.circleElement=e;},se=function(t){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("width","10"),e.setAttribute("height","10"),e.setAttribute("viewBox","0 0 14 14"),e.setAttribute("fill","none"),e.setAttribute("class",J);let i=document.createElementNS("http://www.w3.org/2000/svg","path");i.setAttribute("d","M1 1L13 13M13 1L1 13"),i.setAttribute("stroke","currentColor"),i.setAttribute("stroke-width","2"),i.setAttribute("stroke-linecap","round"),e.appendChild(i),t.appendChild(e);};var ne=j;var C,F=class{constructor(){r(this,"customFloatingButton");r(this,"floatingButton");r(this,"alarm");v(this,C,(t,e)=>t.key===e?true:t.code.startsWith("Key")?t.code.slice(3).toLowerCase()===e:false);this.alarm=new ne;}render({customFloatingButton:t}){if(this.customFloatingButton=t,this.customFloatingButton?.isInElement&&this.customFloatingButton?.parentElementId){let e=document.getElementById(this.customFloatingButton.parentElementId);e?.style.setProperty("position","relative","important"),e?.style.setProperty("z-index","10000001","important"),this.floatingButton=e;}else {let e=document.getElementById("cw-plugin");e||(e=document.createElement("button"),e.id="cw-plugin",e.style.zIndex="10000001",e.style.setProperty("z-index","10000001","important"),e.style.setProperty("position","fixed","important"),e.style.width="50px",e.style.height="50px",e.style.borderRadius="50%",e.style.backgroundColor="#000",document.body.appendChild(e),this.floatingButton=e);}return this.alarm.render({rootElement:this.floatingButton}),this.floatingButton}addClickEvent({callback:t}){if(!this.floatingButton)throw new Error("not initialized");this.floatingButton.addEventListener("click",()=>{t();});}addAlarmClickEvent({callback:t}){this.alarm.addClickEvent({callback:t});}addShortCutEvent({openChatShortcutKey:t,callback:e}){if(!this.floatingButton)throw new Error("not initialized");window.addEventListener("keydown",i=>{K(this,C).call(this,i,t.key)&&(!t.modifier||i[t.modifier])&&e();});}alarmFadeIn(t){this.alarm.fadeIn(t);}alarmRemove(){this.alarm.remove();}};C=new WeakMap;var oe=F;var le="chat:init",Ee="chat:initiated";var de=d__namespace.object({type:d__namespace.literal(Ee),gaId:d__namespace.string()}),pe=d__namespace.object({type:d__namespace.literal("GA_EVENT"),payload:d__namespace.record(d__namespace.string(),d__namespace.any())});var E=class{constructor(){r(this,"listeners",new Map);r(this,"unifiedMessageHandler",null);}on(t,e){let i=o=>{if(this.isValidOrigin(o))try{let n=o.data,p=typeof n=="string"?JSON.parse(n):n,{type:u}=p;u===t&&e(p);}catch(n){console.warn("Messenger: Failed to parse message data",n);}},a=this.listeners.get(t)||[];return a.push(i),this.listeners.set(t,a),this.unifiedMessageHandler||(this.unifiedMessageHandler=o=>{this.listeners.forEach(n=>n.forEach(p=>p(o)));},window.addEventListener("message",this.unifiedMessageHandler)),()=>{this.unifiedMessageHandler&&(window.removeEventListener("message",this.unifiedMessageHandler),this.unifiedMessageHandler=null);}}removeListener(t){this.listeners.delete(t);}removeAllListeners(){this.listeners.clear(),this.unifiedMessageHandler&&(window.removeEventListener("message",this.unifiedMessageHandler),this.unifiedMessageHandler=null);}postMessage(t){try{let e=this.getMessageTarget();return e?(e.postMessage(t,this.getTargetOrigin()),!0):(console.warn("Messenger: Message target not available"),!1)}catch(e){return console.error("Messenger: postMessage failed",e),false}}};var f=class extends Error{constructor(e,i,a){super(`Handshake failed: ${e}${i?` - ${i}`:""}`);this.reason=e;this.details=i;this.originalError=a;this.name="HandshakeError";}},M=class{constructor(t,e,i){this.getTargetWindow=t;this.getTargetOrigin=e;this.isValidOrigin=i;r(this,"abortController",null);r(this,"messageListener",null);}async execute(t,e={}){let{timeout:i=1e4,maxRetries:a=10,retryInterval:o=500}=e;return this.cancel(),this.abortController=new AbortController,new Promise((n,p)=>{let u=0,y,m=()=>{y&&clearTimeout(y),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null);},b=()=>{m(),p(new f("TIMEOUT","Handshake was cancelled"));};this.abortController?.signal.addEventListener("abort",b),this.messageListener=l=>{if(this.isValidOrigin(l))try{let x=l.data,be=typeof x=="string"?JSON.parse(x):x;try{let U=d__namespace.safeParse(de,be);m(),this.abortController=null,n(U.output);return}catch{}}catch(x){console.warn("Failed to parse handshake message:",x);}},window.addEventListener("message",this.messageListener),y=setTimeout(()=>{m(),this.abortController=null,p(new f("TIMEOUT",`No valid response received within ${i}ms`));},i);let h=()=>{if(!this.abortController?.signal.aborted)try{let l=this.getTargetWindow();if(!l)throw new f("NO_TARGET_WINDOW","Target iframe window is not available");l.postMessage(t,this.getTargetOrigin()),u++,u<a&&setTimeout(()=>{this.abortController?.signal.aborted||h();},o);}catch(l){m(),this.abortController=null,l instanceof f?p(l):p(new f("MESSAGE_SEND_FAILED","Failed to send handshake message",l));}};h();})}cancel(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null);}isActive(){return this.abortController!==null&&!this.abortController.signal.aborted}};var B=class extends E{constructor({hostClientUrl:e,pluginKey:i}){super();r(this,"hostClientUrl");r(this,"pluginKey");r(this,"iframe");r(this,"listenToTap",super.on);this.hostClientUrl=e,this.pluginKey=i;}isValidOrigin(e){if(!this.iframe)return false;let i=e.origin,a=new URL(this.iframe.src).origin;return !!(i===a||i.includes("vercel.app")&&a.includes("vercel.app")||i.includes("localhost")&&a.includes("localhost"))}getMessageTarget(){return this.iframe?.contentWindow||null}getTargetOrigin(){if(!this.iframe?.src)return "*";try{return new URL(this.iframe.src).origin}catch{return "*"}}renderIframe({chatBody:e,isProd:i,isLocal:a}){return new Promise(o=>{this.iframe=document.createElement("iframe"),this.iframe.style.setProperty("display","flex","important"),this.iframe.style.setProperty("border","none","important"),a?this.iframe.src=`${this.hostClientUrl}/chat`:this.iframe.src="https://ax-tap-fe-staging.vercel.app/chat",this.iframe.style.width="100%",this.iframe.style.height="100%",this.iframe.onload=()=>o(this.iframe),e.appendChild(this.iframe);})}hasIframe(){return !!this.iframe}removeIframe(){this.iframe?.remove(),this.iframe=null,this.removeAllListeners();}get postToTap(){return this.iframe||console.warn("TapIframeBridge: iframe not found"),super.postMessage}async performHandshake(e,i){if(!this.iframe)throw new Error("TapIframeBridge: iframe not available for handshake");let a=new M(()=>this.getMessageTarget(),()=>this.getTargetOrigin(),n=>this.isValidOrigin(n)),o={type:le,hostClientUrl:this.hostClientUrl,pluginKey:this.pluginKey,chatApiParams:e.chatApiParams,theme:e.customStyles};try{return await a.execute(o,i)}catch(n){throw n instanceof Error?new Error(`TapIframeBridge handshake failed: ${n.message}`):n}}};var I=class{constructor(t){this.iframeBridge=t;}onTimelineSeek(t){this.iframeBridge.listenToTap("timeline:seek",e=>t(e.clipPlayHead,e.clipId));}onChatOpened(t){this.iframeBridge.listenToTap("chat:opened",t);}onChatClosed(t){this.iframeBridge.listenToTap("chat:closed",t);}onChatInitiated(t){this.iframeBridge.listenToTap("chat:initiated",t);}onAlarmFadeIn(t){this.iframeBridge.listenToTap("alarm:fadeIn",e=>{t(e.messageInfo);});}onPopUpOpen(t){this.iframeBridge.listenToTap("popUp:open",e=>{t(e.popUpInfo);});}onPdfOpen(t){this.iframeBridge.listenToTap("pdf:open",t);}onPdfClose(t){this.iframeBridge.listenToTap("pdf:close",t);}};var he="wu2gm66",me="wu2gm67",ge="wu2gm68";function Be({htmlString:s,callback:t,customStyles:e}){let i=document.createElement("div");i.style.position="fixed",i.style.top="0",i.style.left="0",i.style.width="100vw",i.style.height="100vh",i.style.background="rgba(0, 0, 0, 0.4)",i.style.zIndex="10000002";let a=document.createElement("div");a.style.position="fixed",a.style.display="flex",a.style.flexDirection="column";let n=15;if(e?.width){let h=parseFloat(e.width),l=e.width.match(/[a-zA-Z%]+/)?.[0];!isNaN(h)&&l==="px"&&(n+=h);}else n+=340;if(e?.position?.right){let h=parseFloat(e?.position?.right),l=e?.position?.right.match(/[a-zA-Z%]+/)?.[0];!isNaN(h)&&l==="px"&&(n+=h);}else n=n+24;a.style.top=e?.position?.top??"50px",a.style.right=`${n}px`,a.style.left=e?.position?.left??"unset",a.style.bottom=e?.position?.bottom??"unset",a.style.maxWidth="calc(100vw - 100px)",a.style.maxHeight=e?.height??"calc(100vh - 116px)",a.style.overflow="auto",a.style.background="#fff",a.style.padding="20px",a.style.border="1px solid #ccc",a.style.boxShadow="0 4px 20px rgba(0,0,0,0.2)",a.style.zIndex="10000003",a.style.borderRadius="8px";let p=document.createElement("div");p.innerHTML=s,i.addEventListener("click",()=>{document.body.removeChild(i),document.body.removeChild(a),t();}),a.addEventListener("click",h=>{h.stopPropagation();}),a.appendChild(p),document.body.appendChild(i),document.body.appendChild(a);let u=document.querySelector(`.${he}`),y=document.querySelector(".cw-plugin-code-block"),m=document.querySelector(`.${ge}`),b=document.querySelector(`.${me}`);u&&y&&m&&b&&u.addEventListener("click",()=>{navigator.clipboard.writeText(y.textContent??""),m.style.display="none",b.textContent="\uBCF5\uC0AC\uB428",setTimeout(()=>{b.textContent="\uBCF5\uC0AC",m.style.display="inline";},1e3);});}var ue=Be;var T=class T{constructor({gaId:t}){T.isInitialized||(this.init(t),T.isInitialized=true);}init(t){if(!document.querySelector(`script[src="https://www.googletagmanager.com/gtag/js?id=${t}"]`)){let e=document.createElement("script");e.async=true,e.src=`https://www.googletagmanager.com/gtag/js?id=${t}`,document.head.appendChild(e);}if(typeof window.gtag!="function"){let e=document.createElement("script");e.innerHTML=`
18
+ `,willChange:"transform, opacity, width, max-height, max-width"}),document.body.appendChild(this.chatBody),this.chatBody)}toggleVisibility(t){if(!this.chatBody)return;this.chatBody.classList.remove(O,w),this.chatBody.style.display="block";let e=()=>{this.chatBody&&(this.chatBody.classList.contains(w)&&(this.chatBody.style.display="none"),this.chatBody.removeEventListener("animationend",e));};this.chatBody.addEventListener("animationend",e),requestAnimationFrame(()=>{this.chatBody?.classList.add(t?O:w);});}removeChatBody(){this.chatBody&&(this.chatBody.remove(),this.chatBody=null);}resizeChatBody(t,e){if(!this.chatBody)return;let n=e?.width??"340px",r=parseInt(n,10),o=r/3*10-r,s=t?`${r+o}px`:`${r}px`;this.chatBody.style.width=s;}},ee=D;var te="_6j1ub51",P={default:"_6j1ub5b _6j1ub5a","call-to-action":"_6j1ub5c _6j1ub5a"},ne="_6j1ub5a",re="_6j1ub59",L={default:"_6j1ub5e _6j1ub5d","call-to-action":"_6j1ub5f _6j1ub5d"},ie="_6j1ub5d",se="_6j1ub5h",ue="_6j1ub5g",S="_6j1ub53",oe="_6j1ub58",N={default:"_6j1ub56 _6j1ub55","call-to-action":"_6j1ub57 _6j1ub55"},ae="_6j1ub55",q="_6j1ub52",le="_6j1ub54";var h,ce,pe,fe,ye,he,R=class{constructor(){g(this,h);u(this,"container");u(this,"alarmTimeout");u(this,"alarmCornerSVG");u(this,"textContainer");u(this,"circleElement");u(this,"textInTextContainer");u(this,"messageInfo");}render({rootElement:t}){this.container=document.createElement("div"),this.container.id="alarm-container",this.container.className=te,this.container.addEventListener("click",n=>{n.stopPropagation();}),t.appendChild(this.container),d(this,h,ce).call(this,this.container);let e=d(this,h,pe).call(this,this.container);d(this,h,ye).call(this,e),d(this,h,fe).call(this,e);}fadeIn(t){t.type==="default"||t.type==="hourSpent"?(this.textContainer.className=N.default,this.alarmCornerSVG.setAttribute("class",P.default),this.circleElement.className=L.default):(this.textContainer.className=N["call-to-action"],this.alarmCornerSVG.setAttribute("class",P["call-to-action"]),this.circleElement.className=L["call-to-action"]),this.messageInfo=t,this.textInTextContainer.textContent=t.message,this.toggleVisibility(true),this.alarmTimeout=setTimeout(()=>{this.toggleVisibility(false);},18*1e3);}addClickEvent({callback:t}){this.container.addEventListener("click",()=>{this.toggleVisibility(false),t(this.messageInfo);});}toggleVisibility(t){this.container.classList.remove(q,S),requestAnimationFrame(()=>{this.container?.classList.add(t?q:S);});}remove(){this.container&&this.toggleVisibility(false),this.alarmTimeout&&clearTimeout(this.alarmTimeout);}};h=new WeakSet,ce=function(t){let e=document.createElement("div");e.className=re,t.appendChild(e);let n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width","11"),n.setAttribute("height","8"),n.setAttribute("viewBox","0 0 11 8"),n.setAttribute("fill","currentColor"),n.setAttribute("class",ne);let r=document.createElementNS("http://www.w3.org/2000/svg","path");r.setAttribute("d","M5.5 0L11.1292 8.25H-0.129165L5.5 0Z"),r.setAttribute("fill","currentColor"),n.appendChild(r),this.alarmCornerSVG=n,e.appendChild(n);},pe=function(t){let e=document.createElement("div");return e.className=le,t.appendChild(e),e},fe=function(t){this.textContainer=document.createElement("div"),this.textContainer.className=ae,t.appendChild(this.textContainer),this.textInTextContainer=document.createElement("span"),this.textInTextContainer.className=oe,this.textContainer.appendChild(this.textInTextContainer);},ye=function(t){let e=document.createElement("div");e.className=ie,t.appendChild(e),e.addEventListener("click",r=>{r.stopPropagation(),this.remove();});let n=document.createElement("span");n.className=se,e.appendChild(n),n.textContent="\uC54C\uB9BC \uB044\uAE30",d(this,h,he).call(this,e),this.circleElement=e;},he=function(t){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("width","10"),e.setAttribute("height","10"),e.setAttribute("viewBox","0 0 14 14"),e.setAttribute("fill","none"),e.setAttribute("class",ue);let n=document.createElementNS("http://www.w3.org/2000/svg","path");n.setAttribute("d","M1 1L13 13M13 1L1 13"),n.setAttribute("stroke","currentColor"),n.setAttribute("stroke-width","2"),n.setAttribute("stroke-linecap","round"),e.appendChild(n),t.appendChild(e);};var me=R;var _,z=class{constructor(){u(this,"customFloatingButton");u(this,"floatingButton");u(this,"alarm");g(this,_,(t,e)=>t.key===e?true:t.code.startsWith("Key")?t.code.slice(3).toLowerCase()===e:false);this.alarm=new me;}render({customFloatingButton:t}){if(this.customFloatingButton=t,this.customFloatingButton?.isInElement&&this.customFloatingButton?.parentElementId){let e=document.getElementById(this.customFloatingButton.parentElementId);e?.style.setProperty("position","relative","important"),e?.style.setProperty("z-index","10000001","important"),this.floatingButton=e;}else {let e=document.getElementById("cw-plugin");e||(e=document.createElement("button"),e.id="cw-plugin",e.style.zIndex="10000001",e.style.setProperty("z-index","10000001","important"),e.style.setProperty("position","fixed","important"),e.style.width="50px",e.style.height="50px",e.style.borderRadius="50%",e.style.backgroundColor="#000",document.body.appendChild(e),this.floatingButton=e);}return this.alarm.render({rootElement:this.floatingButton}),this.floatingButton}addClickEvent({callback:t}){if(!this.floatingButton)throw new Error("not initialized");this.floatingButton.addEventListener("click",()=>{t();});}addAlarmClickEvent({callback:t}){this.alarm.addClickEvent({callback:t});}addShortCutEvent({openChatShortcutKey:t,callback:e}){if(!this.floatingButton)throw new Error("not initialized");window.addEventListener("keydown",n=>{Y(this,_).call(this,n,t.key)&&(!t.modifier||n[t.modifier])&&e();});}alarmFadeIn(t){this.alarm.fadeIn(t);}alarmRemove(){this.alarm.remove();}};_=new WeakMap;var de=z;var F;function H(i){return {lang:i?.lang??F?.lang,message:i?.message,abortEarly:i?.abortEarly??F?.abortEarly,abortPipeEarly:i?.abortPipeEarly??F?.abortPipeEarly}}var De;function Pe(i){return De?.get(i)}var Le;function Se(i){return Le?.get(i)}var Ne;function qe(i,t){return Ne?.get(i)?.get(t)}function ve(i){let t=typeof i;return t==="string"?`"${i}"`:t==="number"||t==="bigint"||t==="boolean"?`${i}`:t==="object"||t==="function"?(i&&Object.getPrototypeOf(i)?.constructor?.name)??"null":t}function k(i,t,e,n,r){let o=r&&"input"in r?r.input:e.value,s=r?.expected??i.expects??null,c=r?.received??ve(o),a={kind:i.kind,type:i.type,input:o,expected:s,received:c,message:`Invalid ${t}: ${s?`Expected ${s} but r`:"R"}eceived ${c}`,requirement:i.requirement,path:r?.path,issues:r?.issues,lang:n.lang,abortEarly:n.abortEarly,abortPipeEarly:n.abortPipeEarly},p=i.kind==="schema",l=r?.message??i.message??qe(i.reference,a.lang)??(p?Se(a.lang):null)??n.message??Pe(a.lang);l!==void 0&&(a.message=typeof l=="function"?l(a):l),p&&(e.typed=false),e.issues?e.issues.push(a):e.issues=[a];}function x(i){return {version:1,vendor:"valibot",validate(t){return i["~run"]({value:t},H())}}}function Re(i,t){return Object.hasOwn(i,t)&&t!=="__proto__"&&t!=="prototype"&&t!=="constructor"}var ze=class extends Error{constructor(i){super(i[0].message),this.name="ValiError",this.issues=i;}};function Fe(i,t,e){return typeof i.fallback=="function"?i.fallback(t,e):i.fallback}function He(i,t,e){return typeof i.default=="function"?i.default(t,e):i.default}function G(){return {kind:"schema",type:"any",reference:G,expects:"any",async:false,get"~standard"(){return x(this)},"~run"(i){return i.typed=true,i}}}function T(i,t){return {kind:"schema",type:"literal",reference:T,expects:ve(i),async:false,literal:i,message:t,get"~standard"(){return x(this)},"~run"(e,n){return e.value===this.literal?e.typed=true:k(this,"type",e,n),e}}}function I(i,t){return {kind:"schema",type:"object",reference:I,expects:"Object",async:false,entries:i,message:t,get"~standard"(){return x(this)},"~run"(e,n){let r=e.value;if(r&&typeof r=="object"){e.typed=true,e.value={};for(let o in this.entries){let s=this.entries[o];if(o in r||(s.type==="exact_optional"||s.type==="optional"||s.type==="nullish")&&s.default!==void 0){let c=o in r?r[o]:He(s),a=s["~run"]({value:c},n);if(a.issues){let p={type:"object",origin:"value",input:r,key:o,value:c};for(let l of a.issues)l.path?l.path.unshift(p):l.path=[p],e.issues?.push(l);if(e.issues||(e.issues=a.issues),n.abortEarly){e.typed=false;break}}a.typed||(e.typed=false),e.value[o]=a.value;}else if(s.fallback!==void 0)e.value[o]=Fe(s);else if(s.type!=="exact_optional"&&s.type!=="optional"&&s.type!=="nullish"&&(k(this,"key",e,n,{input:void 0,expected:`"${o}"`,path:[{type:"object",origin:"key",input:r,key:o,value:r[o]}]}),n.abortEarly))break}}else k(this,"type",e,n);return e}}}function V(i,t,e){return {kind:"schema",type:"record",reference:V,expects:"Object",async:false,key:i,value:t,message:e,get"~standard"(){return x(this)},"~run"(n,r){let o=n.value;if(o&&typeof o=="object"){n.typed=true,n.value={};for(let s in o)if(Re(o,s)){let c=o[s],a=this.key["~run"]({value:s},r);if(a.issues){let l={type:"object",origin:"key",input:o,key:s,value:c};for(let f of a.issues)f.path=[l],n.issues?.push(f);if(n.issues||(n.issues=a.issues),r.abortEarly){n.typed=false;break}}let p=this.value["~run"]({value:c},r);if(p.issues){let l={type:"object",origin:"value",input:o,key:s,value:c};for(let f of p.issues)f.path?f.path.unshift(l):f.path=[l],n.issues?.push(f);if(n.issues||(n.issues=p.issues),r.abortEarly){n.typed=false;break}}(!a.typed||!p.typed)&&(n.typed=false),a.typed&&(n.value[a.value]=p.value);}}else k(this,"type",n,r);return n}}}function C(i){return {kind:"schema",type:"string",reference:C,expects:"string",async:false,message:i,get"~standard"(){return x(this)},"~run"(t,e){return typeof t.value=="string"?t.typed=true:k(this,"type",t,e),t}}}function ge(i,t,e){let n=i["~run"]({value:t},H(e));if(n.issues)throw new ze(n.issues);return n.value}function be(i,t,e){let n=i["~run"]({value:t},H(e));return {typed:n.typed,success:!n.issues,output:n.value,issues:n.issues}}var ke="chat:init",Ge="chat:initiated";var xe=I({type:T(Ge),gaId:C()}),Ee=I({type:T("GA_EVENT"),payload:V(C(),G())});var A=class{constructor(){u(this,"listeners",new Map);u(this,"unifiedMessageHandler",null);}on(t,e){let n=o=>{if(this.isValidOrigin(o))try{let s=o.data,c=typeof s=="string"?JSON.parse(s):s,{type:a}=c;a===t&&e(c);}catch(s){console.warn("Messenger: Failed to parse message data",s);}},r=this.listeners.get(t)||[];return r.push(n),this.listeners.set(t,r),this.unifiedMessageHandler||(this.unifiedMessageHandler=o=>{this.listeners.forEach(s=>s.forEach(c=>c(o)));},window.addEventListener("message",this.unifiedMessageHandler)),()=>{this.unifiedMessageHandler&&(window.removeEventListener("message",this.unifiedMessageHandler),this.unifiedMessageHandler=null);}}removeListener(t){this.listeners.delete(t);}removeAllListeners(){this.listeners.clear(),this.unifiedMessageHandler&&(window.removeEventListener("message",this.unifiedMessageHandler),this.unifiedMessageHandler=null);}postMessage(t){try{let e=this.getMessageTarget();return e?(e.postMessage(t,this.getTargetOrigin()),!0):(console.warn("Messenger: Message target not available"),!1)}catch(e){return console.error("Messenger: postMessage failed",e),false}}};var v=class extends Error{constructor(e,n,r){super(`Handshake failed: ${e}${n?` - ${n}`:""}`);this.reason=e;this.details=n;this.originalError=r;this.name="HandshakeError";}},M=class{constructor(t,e,n){this.getTargetWindow=t;this.getTargetOrigin=e;this.isValidOrigin=n;u(this,"abortController",null);u(this,"messageListener",null);}async execute(t,e={}){let{timeout:n=1e4,maxRetries:r=10,retryInterval:o=500}=e;return this.cancel(),this.abortController=new AbortController,new Promise((s,c)=>{let a=0,p,l=()=>{p&&clearTimeout(p),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null);},f=()=>{l(),c(new v("TIMEOUT","Handshake was cancelled"));};this.abortController?.signal.addEventListener("abort",f),this.messageListener=y=>{if(this.isValidOrigin(y))try{let b=y.data,Me=typeof b=="string"?JSON.parse(b):b;try{let K=be(xe,Me);l(),this.abortController=null,s(K.output);return}catch{}}catch(b){console.warn("Failed to parse handshake message:",b);}},window.addEventListener("message",this.messageListener),p=setTimeout(()=>{l(),this.abortController=null,c(new v("TIMEOUT",`No valid response received within ${n}ms`));},n);let m=()=>{if(!this.abortController?.signal.aborted)try{let y=this.getTargetWindow();if(!y)throw new v("NO_TARGET_WINDOW","Target iframe window is not available");y.postMessage(t,this.getTargetOrigin()),a++,a<r&&setTimeout(()=>{this.abortController?.signal.aborted||m();},o);}catch(y){l(),this.abortController=null,y instanceof v?c(y):c(new v("MESSAGE_SEND_FAILED","Failed to send handshake message",y));}};m();})}cancel(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null);}isActive(){return this.abortController!==null&&!this.abortController.signal.aborted}};var j=class extends A{constructor({hostClientUrl:e,pluginKey:n}){super();u(this,"hostClientUrl");u(this,"pluginKey");u(this,"iframe");u(this,"listenToTap",super.on);this.hostClientUrl=e,this.pluginKey=n;}isValidOrigin(e){if(!this.iframe)return false;let n=e.origin,r=new URL(this.iframe.src).origin;return !!(n===r||n.includes("vercel.app")&&r.includes("vercel.app")||n.includes("localhost")&&r.includes("localhost"))}getMessageTarget(){return this.iframe?.contentWindow||null}getTargetOrigin(){if(!this.iframe?.src)return "*";try{return new URL(this.iframe.src).origin}catch{return "*"}}renderIframe({chatBody:e,isProd:n,isLocal:r}){return new Promise(o=>{this.iframe=document.createElement("iframe"),this.iframe.style.setProperty("display","flex","important"),this.iframe.style.setProperty("border","none","important"),r?this.iframe.src=`${this.hostClientUrl}/chat`:this.iframe.src="https://ax-tap-fe-staging.vercel.app/chat",this.iframe.style.width="100%",this.iframe.style.height="100%",this.iframe.onload=()=>o(this.iframe),e.appendChild(this.iframe);})}hasIframe(){return !!this.iframe}removeIframe(){this.iframe?.remove(),this.iframe=null,this.removeAllListeners();}get postToTap(){return this.iframe||console.warn("TapIframeBridge: iframe not found"),super.postMessage}async performHandshake(e,n){if(!this.iframe)throw new Error("TapIframeBridge: iframe not available for handshake");let r=new M(()=>this.getMessageTarget(),()=>this.getTargetOrigin(),s=>this.isValidOrigin(s)),o={type:ke,hostClientUrl:this.hostClientUrl,pluginKey:this.pluginKey,chatApiParams:e.chatApiParams,theme:e.customStyles};try{return await r.execute(o,n)}catch(s){throw s instanceof Error?new Error(`TapIframeBridge handshake failed: ${s.message}`):s}}};var $=class{constructor(t){this.iframeBridge=t;}onTimelineSeek(t){this.iframeBridge.listenToTap("timeline:seek",e=>t(e.clipPlayHead,e.clipId));}onChatOpened(t){this.iframeBridge.listenToTap("chat:opened",t);}onChatClosed(t){this.iframeBridge.listenToTap("chat:closed",t);}onChatInitiated(t){this.iframeBridge.listenToTap("chat:initiated",t);}onAlarmFadeIn(t){this.iframeBridge.listenToTap("alarm:fadeIn",e=>{t(e.messageInfo);});}onPopUpOpen(t){this.iframeBridge.listenToTap("popUp:open",e=>{t(e.popUpInfo);});}onPdfOpen(t){this.iframeBridge.listenToTap("pdf:open",t);}onPdfClose(t){this.iframeBridge.listenToTap("pdf:close",t);}};var we="wu2gm66",_e="wu2gm67",Te="wu2gm68";function Ue({htmlString:i,callback:t,customStyles:e}){let n=document.createElement("div");n.style.position="fixed",n.style.top="0",n.style.left="0",n.style.width="100vw",n.style.height="100vh",n.style.background="rgba(0, 0, 0, 0.4)",n.style.zIndex="10000002";let r=document.createElement("div");r.style.position="fixed",r.style.display="flex",r.style.flexDirection="column";let s=15;if(e?.width){let m=parseFloat(e.width),y=e.width.match(/[a-zA-Z%]+/)?.[0];!isNaN(m)&&y==="px"&&(s+=m);}else s+=340;if(e?.position?.right){let m=parseFloat(e?.position?.right),y=e?.position?.right.match(/[a-zA-Z%]+/)?.[0];!isNaN(m)&&y==="px"&&(s+=m);}else s=s+24;r.style.top=e?.position?.top??"50px",r.style.right=`${s}px`,r.style.left=e?.position?.left??"unset",r.style.bottom=e?.position?.bottom??"unset",r.style.maxWidth="calc(100vw - 100px)",r.style.maxHeight=e?.height??"calc(100vh - 116px)",r.style.overflow="auto",r.style.background="#fff",r.style.padding="20px",r.style.border="1px solid #ccc",r.style.boxShadow="0 4px 20px rgba(0,0,0,0.2)",r.style.zIndex="10000003",r.style.borderRadius="8px";let c=document.createElement("div");c.innerHTML=i,n.addEventListener("click",()=>{document.body.removeChild(n),document.body.removeChild(r),t();}),r.addEventListener("click",m=>{m.stopPropagation();}),r.appendChild(c),document.body.appendChild(n),document.body.appendChild(r);let a=document.querySelector(`.${we}`),p=document.querySelector(".cw-plugin-code-block"),l=document.querySelector(`.${Te}`),f=document.querySelector(`.${_e}`);a&&p&&l&&f&&a.addEventListener("click",()=>{navigator.clipboard.writeText(p.textContent??""),l.style.display="none",f.textContent="\uBCF5\uC0AC\uB428",setTimeout(()=>{f.textContent="\uBCF5\uC0AC",l.style.display="inline";},1e3);});}var Ie=Ue;var E=class E{constructor({gaId:t}){E.isInitialized||(this.init(t),E.isInitialized=true);}init(t){if(!document.querySelector(`script[src="https://www.googletagmanager.com/gtag/js?id=${t}"]`)){let e=document.createElement("script");e.async=true,e.src=`https://www.googletagmanager.com/gtag/js?id=${t}`,document.head.appendChild(e);}if(typeof window.gtag!="function"){let e=document.createElement("script");e.innerHTML=`
19
19
  window.dataLayer = window.dataLayer || [];
20
20
  function gtag(){dataLayer.push(arguments);}
21
21
  gtag('js', new Date());
22
22
  gtag('config', '${t}');
23
- `,document.head.appendChild(e);}window.addEventListener("message",e=>{try{let i=typeof e.data=="string"?JSON.parse(e.data):e.data,a=d__namespace.parse(pe,i);typeof window.gtag=="function"&&window.gtag("event",a.payload.action??"click",{event_category:a.payload.category??"Default",event_label:a.payload.label,value:a.payload.value,fastCampus_user_id:a.payload.fastCampus_user_id,course_id:a.payload.course_id,...a.payload});}catch{}});}};r(T,"isInitialized",false);var N=T,ye=N;var k,ve,D=class{constructor({pluginKey:t,isProd:e=false,isLocal:i=false}){v(this,k);r(this,"pluginKey");r(this,"iframeBridge");r(this,"events");r(this,"chatBody",null);r(this,"chatBodyMaker");r(this,"floatingButtonMaker");r(this,"shortcutKey",{openChat:{key:"/",modifier:""},sendChat:{key:"Enter",modifier:""}});r(this,"isProd");r(this,"isLocal");r(this,"isOpen");r(this,"isPdfOpen");this.pluginKey=t,this.iframeBridge=new B({hostClientUrl:window.location.origin,pluginKey:this.pluginKey}),this.events=new I(this.iframeBridge),this.floatingButtonMaker=new oe,this.chatBodyMaker=new W,this.isProd=e,this.isLocal=i,this.isOpen=false,this.isPdfOpen=false;}setIsOpen(t){this.isOpen=t;}setIsPdfOpen(t){this.isPdfOpen=t;}seekTimeline({clipId:t,clipPlayHead:e}){this.iframeBridge.postToTap({type:"timeline:seek",clipId:t,clipPlayHead:e});}async initChat({chatApiParams:t,customStyles:e,shortcutKey:i}){if(!g(this,k,ve).call(this))throw new Error("not client");this.shortcutKey={openChat:i?.openChat??this.shortcutKey.openChat,sendChat:i?.sendChat??this.shortcutKey.sendChat},this.chatBody||(this.chatBody=this.chatBodyMaker.createChatBody({...e?.chatBody&&{customChatBody:e.chatBody}})),this.iframeBridge.hasIframe()||await this.iframeBridge.renderIframe({chatBody:this.chatBody,isProd:this.isProd,isLocal:this.isLocal});try{let a=await this.iframeBridge.performHandshake({chatApiParams:t,customStyles:e},{retryInterval:500,maxRetries:10,timeout:1e4});new ye({gaId:a.gaId});}catch(a){throw console.error("Handshake failed:",a),new Error(`Chat initialization failed: ${a instanceof Error?a.message:"Unknown error"}`)}this.floatingButtonMaker.render({...e?.floatingButton&&{customFloatingButton:e.floatingButton}}),this.floatingButtonMaker.addClickEvent({callback:()=>{this.iframeBridge.postToTap({type:this.isOpen?"chat:close":"chat:open"});}}),this.floatingButtonMaker.addAlarmClickEvent({callback:a=>{this.iframeBridge.postToTap({type:"chat:open",isAlarm:true}),this.iframeBridge.postToTap({type:"alarm:click",messageInfo:a});}}),this.iframeBridge.listenToTap("chat:opened",()=>{this.setIsOpen(true),this.chatBodyMaker.toggleVisibility(this.isOpen),this.floatingButtonMaker.alarmRemove();}),this.iframeBridge.listenToTap("chat:closed",()=>{this.setIsOpen(false),this.chatBodyMaker.toggleVisibility(this.isOpen);}),this.iframeBridge.listenToTap("alarm:fadeIn",a=>{this.isOpen||this.floatingButtonMaker.alarmFadeIn(a.messageInfo);}),this.iframeBridge.listenToTap("popUp:open",a=>{ue({htmlString:a.popUpInfo.html,callback:()=>this.iframeBridge.postToTap({type:"popUp:close"}),...e?.chatBody&&{customStyles:e.chatBody}});}),this.iframeBridge.listenToTap("pdf:open",()=>{this.setIsPdfOpen(true),this.chatBodyMaker.resizeChatBody(this.isPdfOpen,e?.chatBody),this.iframeBridge.postToTap({type:"pdf:enlarged"});}),this.iframeBridge.listenToTap("pdf:close",()=>{this.setIsPdfOpen(false),this.chatBodyMaker.resizeChatBody(this.isPdfOpen,e?.chatBody),this.iframeBridge.postToTap({type:"pdf:shrinked"});}),this.isLocal&&this.iframeBridge.listenToTap("alarm:fadeIn",a=>{this.floatingButtonMaker.alarmFadeIn(a.messageInfo);});}removeChat(){if(!this.chatBody)throw new Error("chatBody is not initialized");this.chatBodyMaker.removeChatBody(),this.floatingButtonMaker.alarmRemove(),this.iframeBridge.removeIframe(),this.chatBody=null,this.isOpen=false;}postChatInfo({clipId:t,clipPlayHead:e}){this.seekTimeline({clipId:t,clipPlayHead:e});}getTimelineInfo({callback:t}){this.events.onTimelineSeek(t);}};k=new WeakSet,ve=function(){return typeof window<"u"&&typeof document<"u"};var It=D;module.exports=It;//# sourceMappingURL=index.js.map
23
+ `,document.head.appendChild(e);}window.addEventListener("message",e=>{try{let n=typeof e.data=="string"?JSON.parse(e.data):e.data,r=ge(Ee,n);typeof window.gtag=="function"&&window.gtag("event",r.payload.action??"click",{event_category:r.payload.category??"Default",event_label:r.payload.label,value:r.payload.value,fastCampus_user_id:r.payload.fastCampus_user_id,course_id:r.payload.course_id,...r.payload});}catch{}});}};u(E,"isInitialized",false);var W=E,Ce=W;var B,Ae,X=class{constructor({pluginKey:t,isProd:e=false,isLocal:n=false}){g(this,B);u(this,"pluginKey");u(this,"iframeBridge");u(this,"events");u(this,"chatBody",null);u(this,"chatBodyMaker");u(this,"floatingButtonMaker");u(this,"shortcutKey",{openChat:{key:"/",modifier:""},sendChat:{key:"Enter",modifier:""}});u(this,"isProd");u(this,"isLocal");u(this,"isOpen");u(this,"isPdfOpen");this.pluginKey=t,this.iframeBridge=new j({hostClientUrl:window.location.origin,pluginKey:this.pluginKey}),this.events=new $(this.iframeBridge),this.floatingButtonMaker=new de,this.chatBodyMaker=new ee,this.isProd=e,this.isLocal=n,this.isOpen=false,this.isPdfOpen=false;}setIsOpen(t){this.isOpen=t;}setIsPdfOpen(t){this.isPdfOpen=t;}seekTimeline({clipId:t,clipPlayHead:e}){this.iframeBridge.postToTap({type:"timeline:seek",clipId:t,clipPlayHead:e});}async initChat({chatApiParams:t,customStyles:e,shortcutKey:n}){if(!d(this,B,Ae).call(this))throw new Error("not client");this.shortcutKey={openChat:n?.openChat??this.shortcutKey.openChat,sendChat:n?.sendChat??this.shortcutKey.sendChat},this.chatBody||(this.chatBody=this.chatBodyMaker.createChatBody({...e?.chatBody&&{customChatBody:e.chatBody}})),this.iframeBridge.hasIframe()||await this.iframeBridge.renderIframe({chatBody:this.chatBody,isProd:this.isProd,isLocal:this.isLocal});try{let r=await this.iframeBridge.performHandshake({chatApiParams:t,customStyles:e},{retryInterval:500,maxRetries:10,timeout:1e4});new Ce({gaId:r.gaId});}catch(r){throw console.error("Handshake failed:",r),new Error(`Chat initialization failed: ${r instanceof Error?r.message:"Unknown error"}`)}this.floatingButtonMaker.render({...e?.floatingButton&&{customFloatingButton:e.floatingButton}}),this.floatingButtonMaker.addClickEvent({callback:()=>{this.iframeBridge.postToTap({type:this.isOpen?"chat:close":"chat:open"});}}),this.floatingButtonMaker.addAlarmClickEvent({callback:r=>{this.iframeBridge.postToTap({type:"chat:open",isAlarm:true}),this.iframeBridge.postToTap({type:"alarm:click",messageInfo:r});}}),this.iframeBridge.listenToTap("chat:opened",()=>{this.setIsOpen(true),this.chatBodyMaker.toggleVisibility(this.isOpen),this.floatingButtonMaker.alarmRemove();}),this.iframeBridge.listenToTap("chat:closed",()=>{this.setIsOpen(false),this.chatBodyMaker.toggleVisibility(this.isOpen);}),this.iframeBridge.listenToTap("alarm:fadeIn",r=>{this.isOpen||this.floatingButtonMaker.alarmFadeIn(r.messageInfo);}),this.iframeBridge.listenToTap("popUp:open",r=>{Ie({htmlString:r.popUpInfo.html,callback:()=>this.iframeBridge.postToTap({type:"popUp:close"}),...e?.chatBody&&{customStyles:e.chatBody}});}),this.iframeBridge.listenToTap("pdf:open",()=>{this.setIsPdfOpen(true),this.chatBodyMaker.resizeChatBody(this.isPdfOpen,e?.chatBody),this.iframeBridge.postToTap({type:"pdf:enlarged"});}),this.iframeBridge.listenToTap("pdf:close",()=>{this.setIsPdfOpen(false),this.chatBodyMaker.resizeChatBody(this.isPdfOpen,e?.chatBody),this.iframeBridge.postToTap({type:"pdf:shrinked"});}),this.isLocal&&this.iframeBridge.listenToTap("alarm:fadeIn",r=>{this.floatingButtonMaker.alarmFadeIn(r.messageInfo);});}removeChat(){if(!this.chatBody)throw new Error("chatBody is not initialized");this.chatBodyMaker.removeChatBody(),this.floatingButtonMaker.alarmRemove(),this.iframeBridge.removeIframe(),this.chatBody=null,this.isOpen=false;}postChatInfo({clipId:t,clipPlayHead:e}){this.seekTimeline({clipId:t,clipPlayHead:e});}getTimelineInfo({callback:t}){this.events.onTimelineSeek(t);}};B=new WeakSet,Ae=function(){return typeof window<"u"&&typeof document<"u"};var Xt=X;module.exports=Xt;//# sourceMappingURL=index.js.map
24
24
  //# sourceMappingURL=index.js.map