@ourroadmaps/web-sdk 0.3.0

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.
@@ -0,0 +1,205 @@
1
+ type OverlayScript = OverlayScriptV1;
2
+ interface OverlayScriptV1 {
3
+ version: 1;
4
+ cursor?: CursorConfig;
5
+ annotations?: AnnotationsConfig;
6
+ actions: Action[];
7
+ }
8
+ interface CursorConfig {
9
+ name?: string;
10
+ color?: string;
11
+ visible?: boolean;
12
+ }
13
+ interface AnnotationsConfig {
14
+ color?: string;
15
+ strokeWidth?: number;
16
+ }
17
+ interface OverlayOptions {
18
+ cursor?: CursorConfig;
19
+ annotations?: AnnotationsConfig;
20
+ container?: HTMLElement;
21
+ zIndex?: number;
22
+ }
23
+ type Target = SelectorTarget | CursorTarget | Coordinates;
24
+ interface SelectorTarget {
25
+ selector: string;
26
+ anchor?: Anchor;
27
+ offset?: Coordinates;
28
+ fallback?: Coordinates;
29
+ }
30
+ interface CursorTarget {
31
+ cursor: true;
32
+ }
33
+ interface Coordinates {
34
+ x: number;
35
+ y: number;
36
+ }
37
+ type Anchor = 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
38
+ type Action = MoveAction | ClickAction | WaitAction | SetCursorAction | ShowAnnotationsAction | HideAnnotationsAction;
39
+ interface MoveAction {
40
+ type: 'move';
41
+ target: Target;
42
+ duration?: number;
43
+ showAnnotations?: Annotation[];
44
+ }
45
+ interface ClickAction {
46
+ type: 'click';
47
+ target?: Target;
48
+ }
49
+ interface WaitAction {
50
+ type: 'wait';
51
+ duration: number;
52
+ }
53
+ interface SetCursorAction {
54
+ type: 'setCursor';
55
+ visible?: boolean;
56
+ name?: string;
57
+ color?: string;
58
+ }
59
+ interface ShowAnnotationsAction {
60
+ type: 'showAnnotations';
61
+ annotations: Annotation[];
62
+ }
63
+ interface HideAnnotationsAction {
64
+ type: 'hideAnnotations';
65
+ ids?: string[];
66
+ }
67
+ type Annotation = ArrowAnnotation | BadgeAnnotation | BoxAnnotation | CircleAnnotation | LabelAnnotation;
68
+ interface AnnotationBase {
69
+ id?: string;
70
+ color?: string;
71
+ delay?: number;
72
+ duration?: number;
73
+ }
74
+ interface ArrowAnnotation extends AnnotationBase {
75
+ type: 'arrow';
76
+ from: Target;
77
+ to: Target;
78
+ }
79
+ interface BadgeAnnotation extends AnnotationBase {
80
+ type: 'badge';
81
+ target: Target;
82
+ number: number;
83
+ }
84
+ interface BoxAnnotation extends AnnotationBase {
85
+ type: 'box';
86
+ target: Target;
87
+ padding?: number;
88
+ size?: {
89
+ width: number;
90
+ height: number;
91
+ };
92
+ dashed?: boolean;
93
+ }
94
+ interface CircleAnnotation extends AnnotationBase {
95
+ type: 'circle';
96
+ target: Target;
97
+ padding?: number;
98
+ size?: {
99
+ width: number;
100
+ height: number;
101
+ };
102
+ }
103
+ interface LabelAnnotation extends AnnotationBase {
104
+ type: 'label';
105
+ target: Target;
106
+ text: string;
107
+ position?: LabelPosition;
108
+ gap?: number;
109
+ }
110
+ type LabelPosition = 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
111
+ interface OverlayController {
112
+ validate(script: unknown): ValidationResult;
113
+ play(script: OverlayScript): Promise<void>;
114
+ stop(): void;
115
+ readonly isPlaying: boolean;
116
+ readonly currentActionIndex: number | null;
117
+ readonly cursor: CursorController;
118
+ readonly annotations: AnnotationsController;
119
+ on(event: 'start', handler: () => void): () => void;
120
+ on(event: 'complete', handler: () => void): () => void;
121
+ on(event: 'stop', handler: () => void): () => void;
122
+ on(event: 'error', handler: (error: OverlayError) => void): () => void;
123
+ on(event: 'action', handler: (action: Action, index: number, phase: 'start' | 'complete') => void): () => void;
124
+ readonly isDestroyed: boolean;
125
+ destroy(): void;
126
+ }
127
+ interface ValidationResult {
128
+ valid: boolean;
129
+ errors: string[];
130
+ warnings: string[];
131
+ }
132
+ interface OverlayError {
133
+ code: 'ELEMENT_NOT_FOUND' | 'ANIMATION_FAILED' | 'SCROLL_FAILED' | 'INVALID_SCRIPT' | 'INVALID_TARGET' | 'TIMEOUT';
134
+ message: string;
135
+ action?: Action;
136
+ target?: Target;
137
+ }
138
+ interface CursorController {
139
+ moveTo(target: Target, options?: {
140
+ duration?: number;
141
+ }): Promise<void>;
142
+ click(target?: Target): Promise<void>;
143
+ show(): void;
144
+ hide(): void;
145
+ readonly isVisible: boolean;
146
+ setName(name: string): void;
147
+ setColor(color: string): void;
148
+ readonly position: Coordinates | null;
149
+ }
150
+ type ArrowOptions = Omit<Partial<ArrowAnnotation>, 'type' | 'from' | 'to'>;
151
+ type BadgeOptions = Omit<Partial<BadgeAnnotation>, 'type' | 'target' | 'number'>;
152
+ type BoxOptions = Omit<Partial<BoxAnnotation>, 'type' | 'target'>;
153
+ type CircleOptions = Omit<Partial<CircleAnnotation>, 'type' | 'target'>;
154
+ type LabelOptions = Omit<Partial<LabelAnnotation>, 'type' | 'target' | 'text'>;
155
+ interface AnnotationsController {
156
+ show(annotation: Annotation): string;
157
+ show(annotations: Annotation[]): string[];
158
+ hide(id: string): void;
159
+ hide(ids: string[]): void;
160
+ hideAll(): void;
161
+ arrow(from: Target, to: Target, options?: ArrowOptions): string;
162
+ badge(target: Target, number: number, options?: BadgeOptions): string;
163
+ box(target: Target, options?: BoxOptions): string;
164
+ circle(target: Target, options?: CircleOptions): string;
165
+ label(target: Target, text: string, options?: LabelOptions): string;
166
+ readonly activeIds: string[];
167
+ }
168
+
169
+ declare class Overlay implements OverlayController {
170
+ private root;
171
+ private shadow;
172
+ private container;
173
+ private svgContainer;
174
+ private domContainer;
175
+ private _cursor;
176
+ private _annotations;
177
+ private timeline;
178
+ private reducedMotion;
179
+ private motionQuery;
180
+ private eventHandlers;
181
+ private _isDestroyed;
182
+ constructor(options?: OverlayOptions);
183
+ private handleMotionChange;
184
+ get cursor(): CursorController;
185
+ get annotations(): AnnotationsController;
186
+ get isPlaying(): boolean;
187
+ get currentActionIndex(): number | null;
188
+ get isDestroyed(): boolean;
189
+ private static readonly VALID_ACTION_TYPES;
190
+ private validateAction;
191
+ validate(script: unknown): ValidationResult;
192
+ play(script: OverlayScript): Promise<void>;
193
+ stop(): void;
194
+ on(event: 'start', handler: () => void): () => void;
195
+ on(event: 'complete', handler: () => void): () => void;
196
+ on(event: 'stop', handler: () => void): () => void;
197
+ on(event: 'error', handler: (error: OverlayError) => void): () => void;
198
+ on(event: 'action', handler: (action: Action, index: number, phase: 'start' | 'complete') => void): () => void;
199
+ private emit;
200
+ destroy(): void;
201
+ }
202
+
203
+ declare function createOverlay(options?: OverlayOptions): OverlayController;
204
+
205
+ export { type Action, type Anchor, type Annotation, type AnnotationBase, type AnnotationsConfig, type AnnotationsController, type ArrowAnnotation, type BadgeAnnotation, type BoxAnnotation, type CircleAnnotation, type ClickAction, type Coordinates, type CursorConfig, type CursorController, type CursorTarget, type HideAnnotationsAction, type LabelAnnotation, type LabelPosition, type MoveAction, Overlay, type OverlayController, type OverlayError, type OverlayOptions, type OverlayScript, type OverlayScriptV1, type SelectorTarget, type SetCursorAction, type ShowAnnotationsAction, type Target, type ValidationResult, type WaitAction, createOverlay };
@@ -0,0 +1,205 @@
1
+ type OverlayScript = OverlayScriptV1;
2
+ interface OverlayScriptV1 {
3
+ version: 1;
4
+ cursor?: CursorConfig;
5
+ annotations?: AnnotationsConfig;
6
+ actions: Action[];
7
+ }
8
+ interface CursorConfig {
9
+ name?: string;
10
+ color?: string;
11
+ visible?: boolean;
12
+ }
13
+ interface AnnotationsConfig {
14
+ color?: string;
15
+ strokeWidth?: number;
16
+ }
17
+ interface OverlayOptions {
18
+ cursor?: CursorConfig;
19
+ annotations?: AnnotationsConfig;
20
+ container?: HTMLElement;
21
+ zIndex?: number;
22
+ }
23
+ type Target = SelectorTarget | CursorTarget | Coordinates;
24
+ interface SelectorTarget {
25
+ selector: string;
26
+ anchor?: Anchor;
27
+ offset?: Coordinates;
28
+ fallback?: Coordinates;
29
+ }
30
+ interface CursorTarget {
31
+ cursor: true;
32
+ }
33
+ interface Coordinates {
34
+ x: number;
35
+ y: number;
36
+ }
37
+ type Anchor = 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
38
+ type Action = MoveAction | ClickAction | WaitAction | SetCursorAction | ShowAnnotationsAction | HideAnnotationsAction;
39
+ interface MoveAction {
40
+ type: 'move';
41
+ target: Target;
42
+ duration?: number;
43
+ showAnnotations?: Annotation[];
44
+ }
45
+ interface ClickAction {
46
+ type: 'click';
47
+ target?: Target;
48
+ }
49
+ interface WaitAction {
50
+ type: 'wait';
51
+ duration: number;
52
+ }
53
+ interface SetCursorAction {
54
+ type: 'setCursor';
55
+ visible?: boolean;
56
+ name?: string;
57
+ color?: string;
58
+ }
59
+ interface ShowAnnotationsAction {
60
+ type: 'showAnnotations';
61
+ annotations: Annotation[];
62
+ }
63
+ interface HideAnnotationsAction {
64
+ type: 'hideAnnotations';
65
+ ids?: string[];
66
+ }
67
+ type Annotation = ArrowAnnotation | BadgeAnnotation | BoxAnnotation | CircleAnnotation | LabelAnnotation;
68
+ interface AnnotationBase {
69
+ id?: string;
70
+ color?: string;
71
+ delay?: number;
72
+ duration?: number;
73
+ }
74
+ interface ArrowAnnotation extends AnnotationBase {
75
+ type: 'arrow';
76
+ from: Target;
77
+ to: Target;
78
+ }
79
+ interface BadgeAnnotation extends AnnotationBase {
80
+ type: 'badge';
81
+ target: Target;
82
+ number: number;
83
+ }
84
+ interface BoxAnnotation extends AnnotationBase {
85
+ type: 'box';
86
+ target: Target;
87
+ padding?: number;
88
+ size?: {
89
+ width: number;
90
+ height: number;
91
+ };
92
+ dashed?: boolean;
93
+ }
94
+ interface CircleAnnotation extends AnnotationBase {
95
+ type: 'circle';
96
+ target: Target;
97
+ padding?: number;
98
+ size?: {
99
+ width: number;
100
+ height: number;
101
+ };
102
+ }
103
+ interface LabelAnnotation extends AnnotationBase {
104
+ type: 'label';
105
+ target: Target;
106
+ text: string;
107
+ position?: LabelPosition;
108
+ gap?: number;
109
+ }
110
+ type LabelPosition = 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
111
+ interface OverlayController {
112
+ validate(script: unknown): ValidationResult;
113
+ play(script: OverlayScript): Promise<void>;
114
+ stop(): void;
115
+ readonly isPlaying: boolean;
116
+ readonly currentActionIndex: number | null;
117
+ readonly cursor: CursorController;
118
+ readonly annotations: AnnotationsController;
119
+ on(event: 'start', handler: () => void): () => void;
120
+ on(event: 'complete', handler: () => void): () => void;
121
+ on(event: 'stop', handler: () => void): () => void;
122
+ on(event: 'error', handler: (error: OverlayError) => void): () => void;
123
+ on(event: 'action', handler: (action: Action, index: number, phase: 'start' | 'complete') => void): () => void;
124
+ readonly isDestroyed: boolean;
125
+ destroy(): void;
126
+ }
127
+ interface ValidationResult {
128
+ valid: boolean;
129
+ errors: string[];
130
+ warnings: string[];
131
+ }
132
+ interface OverlayError {
133
+ code: 'ELEMENT_NOT_FOUND' | 'ANIMATION_FAILED' | 'SCROLL_FAILED' | 'INVALID_SCRIPT' | 'INVALID_TARGET' | 'TIMEOUT';
134
+ message: string;
135
+ action?: Action;
136
+ target?: Target;
137
+ }
138
+ interface CursorController {
139
+ moveTo(target: Target, options?: {
140
+ duration?: number;
141
+ }): Promise<void>;
142
+ click(target?: Target): Promise<void>;
143
+ show(): void;
144
+ hide(): void;
145
+ readonly isVisible: boolean;
146
+ setName(name: string): void;
147
+ setColor(color: string): void;
148
+ readonly position: Coordinates | null;
149
+ }
150
+ type ArrowOptions = Omit<Partial<ArrowAnnotation>, 'type' | 'from' | 'to'>;
151
+ type BadgeOptions = Omit<Partial<BadgeAnnotation>, 'type' | 'target' | 'number'>;
152
+ type BoxOptions = Omit<Partial<BoxAnnotation>, 'type' | 'target'>;
153
+ type CircleOptions = Omit<Partial<CircleAnnotation>, 'type' | 'target'>;
154
+ type LabelOptions = Omit<Partial<LabelAnnotation>, 'type' | 'target' | 'text'>;
155
+ interface AnnotationsController {
156
+ show(annotation: Annotation): string;
157
+ show(annotations: Annotation[]): string[];
158
+ hide(id: string): void;
159
+ hide(ids: string[]): void;
160
+ hideAll(): void;
161
+ arrow(from: Target, to: Target, options?: ArrowOptions): string;
162
+ badge(target: Target, number: number, options?: BadgeOptions): string;
163
+ box(target: Target, options?: BoxOptions): string;
164
+ circle(target: Target, options?: CircleOptions): string;
165
+ label(target: Target, text: string, options?: LabelOptions): string;
166
+ readonly activeIds: string[];
167
+ }
168
+
169
+ declare class Overlay implements OverlayController {
170
+ private root;
171
+ private shadow;
172
+ private container;
173
+ private svgContainer;
174
+ private domContainer;
175
+ private _cursor;
176
+ private _annotations;
177
+ private timeline;
178
+ private reducedMotion;
179
+ private motionQuery;
180
+ private eventHandlers;
181
+ private _isDestroyed;
182
+ constructor(options?: OverlayOptions);
183
+ private handleMotionChange;
184
+ get cursor(): CursorController;
185
+ get annotations(): AnnotationsController;
186
+ get isPlaying(): boolean;
187
+ get currentActionIndex(): number | null;
188
+ get isDestroyed(): boolean;
189
+ private static readonly VALID_ACTION_TYPES;
190
+ private validateAction;
191
+ validate(script: unknown): ValidationResult;
192
+ play(script: OverlayScript): Promise<void>;
193
+ stop(): void;
194
+ on(event: 'start', handler: () => void): () => void;
195
+ on(event: 'complete', handler: () => void): () => void;
196
+ on(event: 'stop', handler: () => void): () => void;
197
+ on(event: 'error', handler: (error: OverlayError) => void): () => void;
198
+ on(event: 'action', handler: (action: Action, index: number, phase: 'start' | 'complete') => void): () => void;
199
+ private emit;
200
+ destroy(): void;
201
+ }
202
+
203
+ declare function createOverlay(options?: OverlayOptions): OverlayController;
204
+
205
+ export { type Action, type Anchor, type Annotation, type AnnotationBase, type AnnotationsConfig, type AnnotationsController, type ArrowAnnotation, type BadgeAnnotation, type BoxAnnotation, type CircleAnnotation, type ClickAction, type Coordinates, type CursorConfig, type CursorController, type CursorTarget, type HideAnnotationsAction, type LabelAnnotation, type LabelPosition, type MoveAction, Overlay, type OverlayController, type OverlayError, type OverlayOptions, type OverlayScript, type OverlayScriptV1, type SelectorTarget, type SetCursorAction, type ShowAnnotationsAction, type Target, type ValidationResult, type WaitAction, createOverlay };
@@ -0,0 +1,4 @@
1
+ export { Overlay, createOverlay } from '../chunk-XFAAEDJK.js';
2
+ import '../chunk-V6TY7KAL.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,123 @@
1
+ "use strict";var OurRoadmaps=(()=>{var E=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var j=(i,e,t)=>e in i?E(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var q=(i,e)=>{for(var t in e)E(i,t,{get:e[t],enumerable:!0})},K=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of W(e))!z.call(i,o)&&o!==t&&E(i,o,{get:()=>e[o],enumerable:!(n=U(e,o))||n.enumerable});return i};var Y=i=>K(E({},"__esModule",{value:!0}),i);var s=(i,e,t)=>j(i,typeof e!="symbol"?e+"":e,t);var ct={};q(ct,{Overlay:()=>x,createOverlay:()=>lt});function d(i){return typeof i=="object"&&"selector"in i}function g(i){return typeof i=="object"&&"cursor"in i&&i.cursor===!0}function h(i){return typeof i=="object"&&"x"in i&&"y"in i&&!("selector"in i)}function _(i){return d(i)?document.querySelector(i.selector):null}function Q(i,e="center"){switch(e){case"top":return{x:i.left+i.width/2,y:i.top};case"bottom":return{x:i.left+i.width/2,y:i.bottom};case"left":return{x:i.left,y:i.top+i.height/2};case"right":return{x:i.right,y:i.top+i.height/2};case"top-left":return{x:i.left,y:i.top};case"top-right":return{x:i.right,y:i.top};case"bottom-left":return{x:i.left,y:i.bottom};case"bottom-right":return{x:i.right,y:i.bottom};case"center":return{x:i.left+i.width/2,y:i.top+i.height/2}}}function c(i,e){if(h(i))return i;if(g(i))return e;if(d(i)){let t=document.querySelector(i.selector);if(!t)return i.fallback??null;let n=t.getBoundingClientRect(),o=Q(n,i.anchor);return i.offset&&(o.x+=i.offset.x,o.y+=i.offset.y),o}return null}function D(i){let e=i.getBoundingClientRect();return e.top>=0&&e.left>=0&&e.bottom<=window.innerHeight&&e.right<=window.innerWidth}var p={cursorMove:600,cursorClick:150,clickRipple:400,annotationIn:200,annotationOut:150,scrollPause:300},f={easeOut:"cubic-bezier(0, 0, 0.2, 1)",easeInOut:"cubic-bezier(0.4, 0, 0.2, 1)",linear:"linear"};function S(i){return new Promise(e=>setTimeout(e,i))}function I(){return[{opacity:0,transform:"scale(0.9)"},{opacity:1,transform:"scale(1)"}]}function B(){return[{opacity:1},{opacity:0}]}var u=class{constructor(e,t,n,o){s(this,"id");s(this,"config");s(this,"element",null);s(this,"container");s(this,"reducedMotion");s(this,"hideTimeout",null);s(this,"currentAnimation",null);this.id=e,this.config=t,this.container=n,this.reducedMotion=o}async show(){this.config.delay&&this.config.delay>0&&await new Promise(t=>setTimeout(t,this.config.delay)),this.element=this.createElement(),this.config.color&&this.element.style.setProperty("--annotation-color",this.config.color),this.container.appendChild(this.element);let e=this.reducedMotion?1:p.annotationIn;this.currentAnimation=this.element.animate(I(),{duration:e,easing:f.easeOut,fill:"forwards"}),await this.currentAnimation.finished,this.currentAnimation=null,this.config.duration&&this.config.duration>0&&(this.hideTimeout=setTimeout(()=>this.hide(),this.config.duration))}async hide(){if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null),!this.element)return;let e=this.reducedMotion?1:p.annotationOut;this.currentAnimation=this.element.animate(B(),{duration:e,easing:f.linear,fill:"forwards"}),await this.currentAnimation.finished,this.currentAnimation=null,this.element.remove(),this.element=null}cancelAnimations(){this.currentAnimation?.cancel(),this.currentAnimation=null}destroy(){this.hideTimeout&&clearTimeout(this.hideTimeout),this.cancelAnimations(),this.element?.remove()}};var L=12,T=8,y=class extends u{constructor(t,n,o,r,a){super(t,n,o,r);s(this,"cursorPosition");s(this,"pathElement",null);s(this,"markerDef",null);this.cursorPosition=a}createElement(){let t=document.createElementNS("http://www.w3.org/2000/svg","g");t.classList.add("arrow");let n=`arrowhead-${this.id}`;this.markerDef=document.createElementNS("http://www.w3.org/2000/svg","defs");let o=document.createElementNS("http://www.w3.org/2000/svg","marker");o.setAttribute("id",n),o.setAttribute("markerWidth",String(L)),o.setAttribute("markerHeight",String(T)),o.setAttribute("refX",String(L)),o.setAttribute("refY",String(T/2)),o.setAttribute("orient","auto"),o.setAttribute("markerUnits","userSpaceOnUse");let r=document.createElementNS("http://www.w3.org/2000/svg","polygon");return r.setAttribute("points",`0,0 ${L},${T/2} 0,${T}`),r.setAttribute("fill","currentColor"),o.appendChild(r),this.markerDef.appendChild(o),t.appendChild(this.markerDef),this.pathElement=document.createElementNS("http://www.w3.org/2000/svg","path"),this.pathElement.setAttribute("marker-end",`url(#${n})`),this.pathElement.setAttribute("fill","none"),this.pathElement.setAttribute("stroke","currentColor"),t.appendChild(this.pathElement),t}setCursorPosition(t){this.cursorPosition=t,this.element&&this.updatePosition()}resolveTargetPoint(t){if(h(t))return c(t,this.cursorPosition);if(g(t))return this.cursorPosition;if(d(t)){let n=document.querySelector(t.selector);if(!n)return t.fallback??null;let o=n.getBoundingClientRect();return{x:o.left+o.width/2,y:o.top+o.height/2}}return null}updatePosition(){if(!this.pathElement)return;let t=this.config.from,n=this.config.to,o=this.resolveTargetPoint(t),r=this.resolveTargetPoint(n);if(!o||!r)return;let a=`M ${o.x} ${o.y} L ${r.x} ${r.y}`;this.pathElement.setAttribute("d",a)}async show(){await super.show(),this.updatePosition()}destroy(){this.pathElement=null,this.markerDef=null,super.destroy()}};var A=class extends u{constructor(t,n,o,r,a){super(t,n,o,r);s(this,"cursorPosition");this.cursorPosition=a}createElement(){let t=document.createElement("div");t.className="badge",t.textContent=String(this.config.number);let n=c(this.config.target,this.cursorPosition);return n&&(t.style.left=`${n.x}px`,t.style.top=`${n.y}px`),t}};var X=4,H=4,w=class extends u{constructor(t,n,o,r,a){super(t,n,o,r);s(this,"cursorPosition");this.cursorPosition=a}createElement(){let t=document.createElementNS("http://www.w3.org/2000/svg","rect");return t.classList.add("box"),t.setAttribute("rx",String(H)),t.setAttribute("ry",String(H)),this.config.dashed&&t.setAttribute("stroke-dasharray","8 4"),t}setCursorPosition(t){this.cursorPosition=t,this.element&&this.updatePosition()}updatePosition(){if(!this.element)return;let t=this.element,n=this.config.target,o=this.config.padding??X,r;if(d(n)){let a=document.querySelector(n.selector);if(!a)return;r=a.getBoundingClientRect()}else if(h(n)){let a=c(n,this.cursorPosition);if(!a)return;let l=this.config.size?.width??100,m=this.config.size?.height??100;r=new DOMRect(a.x,a.y,l,m)}else return;t.setAttribute("x",String(r.left-o)),t.setAttribute("y",String(r.top-o)),t.setAttribute("width",String(r.width+o*2)),t.setAttribute("height",String(r.height+o*2))}async show(){await super.show(),this.updatePosition()}};var Z=4,b=class extends u{constructor(t,n,o,r,a){super(t,n,o,r);s(this,"cursorPosition");this.cursorPosition=a}createElement(){let t=document.createElementNS("http://www.w3.org/2000/svg","ellipse");return t.classList.add("circle"),t}setCursorPosition(t){this.cursorPosition=t,this.element&&this.updatePosition()}updatePosition(){if(!this.element)return;let t=this.element,n=this.config.target,o=this.config.padding??Z,r;if(d(n)){let v=document.querySelector(n.selector);if(!v)return;r=v.getBoundingClientRect()}else if(h(n)){let v=c(n,this.cursorPosition);if(!v)return;let G=this.config.size?.width??100,F=this.config.size?.height??100;r=new DOMRect(v.x,v.y,G,F)}else return;let a=r.left+r.width/2,l=r.top+r.height/2,m=r.width/2+o,R=r.height/2+o;t.setAttribute("cx",String(a)),t.setAttribute("cy",String(l)),t.setAttribute("rx",String(m)),t.setAttribute("ry",String(R))}async show(){await super.show(),this.updatePosition()}};var J=8,C=class extends u{constructor(t,n,o,r,a){super(t,n,o,r);s(this,"cursorPosition");this.cursorPosition=a}createElement(){let t=document.createElement("div");return t.className="label",t.textContent=this.config.text,t}setCursorPosition(t){this.cursorPosition=t,this.element&&this.updatePosition()}updatePosition(){if(!this.element)return;let t=this.config.target,n=this.config.position||"top",o=this.config.gap??J,r;if(g(t)){if(!this.cursorPosition)return;r=new DOMRect(this.cursorPosition.x,this.cursorPosition.y,0,0)}else if(h(t)){let l=c(t,this.cursorPosition);if(!l)return;r=new DOMRect(l.x,l.y,0,0)}else if(d(t)){let l=document.querySelector(t.selector);if(!l)return;r=l.getBoundingClientRect()}else return;let a=this.calculatePosition(r,n,o);this.element.style.left=`${a.x}px`,this.element.style.top=`${a.y}px`,this.element.style.transform=this.getTransform(n)}calculatePosition(t,n,o){let r=t.left+t.width/2,a=t.top+t.height/2;switch(n){case"top":return{x:r,y:t.top-o};case"top-left":return{x:t.left,y:t.top-o};case"top-right":return{x:t.right,y:t.top-o};case"bottom":return{x:r,y:t.bottom+o};case"bottom-left":return{x:t.left,y:t.bottom+o};case"bottom-right":return{x:t.right,y:t.bottom+o};case"left":return{x:t.left-o,y:a};case"right":return{x:t.right+o,y:a};default:return{x:r,y:t.top-o}}}getTransform(t){switch(t){case"top":case"bottom":return"translate(-50%, -100%)";case"top-left":case"bottom-left":return"translate(0, -100%)";case"top-right":case"bottom-right":return"translate(-100%, -100%)";case"left":return"translate(-100%, -50%)";case"right":return"translate(0, -50%)";default:return"translate(-50%, -100%)"}}async show(){await super.show(),this.updatePosition()}};var tt=0;function et(){return`ann-${++tt}`}var O=class{constructor(e,t,n,o,r){s(this,"config");s(this,"domContainer");s(this,"svgContainer");s(this,"annotations",new Map);s(this,"reducedMotion");s(this,"getCursorPosition");this.config=e,this.domContainer=t,this.svgContainer=n,this.reducedMotion=o,this.getCursorPosition=r}get activeIds(){return Array.from(this.annotations.keys())}show(e){return Array.isArray(e)?e.map(t=>this.showOne(t)):this.showOne(e)}showOne(e){let t=e.id??et(),n=this.getCursorPosition(),o={...e,color:e.color??this.config.color},r;switch(e.type){case"arrow":r=new y(t,o,this.svgContainer,this.reducedMotion,n);break;case"badge":r=new A(t,o,this.domContainer,this.reducedMotion,n);break;case"box":r=new w(t,o,this.svgContainer,this.reducedMotion,n);break;case"circle":r=new b(t,o,this.svgContainer,this.reducedMotion,n);break;case"label":r=new C(t,o,this.domContainer,this.reducedMotion,n);break;default:throw new Error(`Unknown annotation type: ${e.type}`)}return this.annotations.set(t,r),r.show(),t}hide(e){let t=Array.isArray(e)?e:[e];for(let n of t){let o=this.annotations.get(n);o&&(o.hide(),this.annotations.delete(n))}}hideAll(){for(let e of this.annotations.values())e.hide();this.annotations.clear()}arrow(e,t,n){return this.show({type:"arrow",from:e,to:t,...n})}badge(e,t,n){return this.show({type:"badge",target:e,number:t,...n})}box(e,t){return this.show({type:"box",target:e,...t})}circle(e,t){return this.show({type:"circle",target:e,...t})}label(e,t,n){return this.show({type:"label",target:e,text:t,...n})}cancelAllAnimations(){for(let e of this.annotations.values())e.cancelAnimations()}destroy(){for(let e of this.annotations.values())e.destroy();this.annotations.clear()}};function ot(i){let e=i.replace("#",""),t=parseInt(e,16);return[t>>16&255,t>>8&255,t&255]}function nt(i){let[e,t,n]=ot(i).map(o=>{let r=o/255;return r<=.03928?r/12.92:((r+.055)/1.055)**2.4});return .2126*e+.7152*t+.0722*n}function V(i){return nt(i)>.5?"black":"white"}async function N(i){let e=i.getBoundingClientRect();if(!(e.top>=0&&e.left>=0&&e.bottom<=window.innerHeight&&e.right<=window.innerWidth))return new Promise(n=>{i.scrollIntoView({behavior:"smooth",block:"center",inline:"center"});let o=new IntersectionObserver(r=>{r[0]?.isIntersecting&&(o.disconnect(),n())},{threshold:.5});o.observe(i),setTimeout(()=>{o.disconnect(),n()},1e3)})}var it=`<svg class="cursor-arrow" viewBox="0 0 24 24">
2
+ <path d="M5.5 3.21V20.8c0 .45.54.67.85.35l4.86-4.86a.5.5 0 0 1 .35-.15h6.87a.5.5 0 0 0 .35-.85L6.35 2.85a.5.5 0 0 0-.85.36Z"/>
3
+ </svg>`,P=class{constructor(e,t){s(this,"container");s(this,"element");s(this,"labelElement");s(this,"rippleElement");s(this,"currentAnimation",null);s(this,"activeRipples",new Set);s(this,"_position",null);s(this,"_isVisible",!0);s(this,"reducedMotion");this.container=e,this.reducedMotion=t,this.element=document.createElement("div"),this.element.className="cursor",this.element.innerHTML=`${it}<div class="cursor-label">Guide</div>`,this.labelElement=this.element.querySelector(".cursor-label"),this.rippleElement=document.createElement("div"),this.rippleElement.className="click-ripple",e.appendChild(this.element),e.appendChild(this.rippleElement)}get position(){return this._position}get isVisible(){return this._isVisible}show(){this._isVisible=!0,this.element.classList.remove("hidden")}hide(){this._isVisible=!1,this.element.classList.add("hidden")}setName(e){this.labelElement.textContent=e}setColor(e){this.element.style.setProperty("--cursor-color",e),this.element.style.setProperty("--cursor-text-color",V(e))}async moveTo(e,t){let n=_(e);n&&!D(n)&&(await N(n),await S(p.scrollPause));let o=c(e,this._position);if(!o){console.warn("[Overlay] Target not found:",e);return}this.currentAnimation?.cancel();let r=this.reducedMotion?1:t?.duration??p.cursorMove,a=this._position??o;this.currentAnimation=this.element.animate([{transform:`translate(${a.x}px, ${a.y}px)`},{transform:`translate(${o.x}px, ${o.y}px)`}],{duration:r,easing:f.easeInOut,fill:"forwards"});try{await this.currentAnimation.finished,this._position=o}catch{}finally{this.currentAnimation=null}}async click(e){if(e&&await this.moveTo(e),!this._position)return;let t=this.reducedMotion?1:p.cursorClick,n=this.element.animate([{transform:`translate(${this._position.x}px, ${this._position.y}px) scale(1)`},{transform:`translate(${this._position.x}px, ${this._position.y}px) scale(0.85)`},{transform:`translate(${this._position.x}px, ${this._position.y}px) scale(1)`}],{duration:t,easing:f.easeOut});this.showRipple(this._position),await n.finished}showRipple(e){let t=this.rippleElement.cloneNode();t.style.left=`${e.x}px`,t.style.top=`${e.y}px`,this.container.appendChild(t),this.activeRipples.add(t);let n=this.reducedMotion?1:p.clickRipple,o=t.animate([{opacity:.4,transform:"translate(-50%, -50%) scale(0)"},{opacity:0,transform:"translate(-50%, -50%) scale(2)"}],{duration:n,easing:f.easeOut});o.onfinish=()=>{t.remove(),this.activeRipples.delete(t)}}cancelAnimations(){this.currentAnimation?.cancel(),this.currentAnimation=null;for(let e of this.activeRipples)e.remove();this.activeRipples.clear()}destroy(){this.cancelAnimations(),this.element.remove(),this.rippleElement.remove()}};var $=`
4
+ :host {
5
+ all: initial;
6
+ }
7
+
8
+ .overlay-container {
9
+ position: fixed;
10
+ inset: 0;
11
+ pointer-events: none;
12
+ z-index: var(--overlay-z-index, 9999);
13
+ overflow: hidden;
14
+ }
15
+
16
+ /* Cursor */
17
+ .cursor {
18
+ position: absolute;
19
+ display: flex;
20
+ align-items: flex-start;
21
+ gap: 2px;
22
+ filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));
23
+ will-change: transform;
24
+ transition: opacity 0.15s ease-out;
25
+ }
26
+
27
+ .cursor.hidden {
28
+ opacity: 0;
29
+ pointer-events: none;
30
+ }
31
+
32
+ .cursor-arrow {
33
+ width: 20px;
34
+ height: 20px;
35
+ fill: var(--cursor-color, #3B82F6);
36
+ }
37
+
38
+ .cursor-label {
39
+ background: var(--cursor-color, #3B82F6);
40
+ color: var(--cursor-text-color, white);
41
+ font-family: system-ui, -apple-system, sans-serif;
42
+ font-size: 12px;
43
+ font-weight: 500;
44
+ padding: 4px 8px;
45
+ border-radius: 4px;
46
+ white-space: nowrap;
47
+ margin-top: 12px;
48
+ }
49
+
50
+ /* Click Ripple */
51
+ .click-ripple {
52
+ position: absolute;
53
+ width: 24px;
54
+ height: 24px;
55
+ border-radius: 50%;
56
+ background: var(--cursor-color, #3B82F6);
57
+ opacity: 0;
58
+ transform: translate(-50%, -50%) scale(0);
59
+ pointer-events: none;
60
+ }
61
+
62
+ /* Annotations SVG Layer */
63
+ .annotations-svg {
64
+ position: absolute;
65
+ inset: 0;
66
+ width: 100%;
67
+ height: 100%;
68
+ overflow: visible;
69
+ }
70
+
71
+ /* Annotations DOM Layer */
72
+ .annotations-dom {
73
+ position: absolute;
74
+ inset: 0;
75
+ }
76
+
77
+ /* Badge */
78
+ .badge {
79
+ position: absolute;
80
+ width: 28px;
81
+ height: 28px;
82
+ border-radius: 50%;
83
+ background: var(--annotation-color, #EF4444);
84
+ color: white;
85
+ font-family: system-ui, -apple-system, sans-serif;
86
+ font-size: 14px;
87
+ font-weight: 600;
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ transform: translate(-50%, -50%);
92
+ }
93
+
94
+ /* Label */
95
+ .label {
96
+ position: absolute;
97
+ background: var(--annotation-color, #EF4444);
98
+ color: white;
99
+ font-family: system-ui, -apple-system, sans-serif;
100
+ font-size: 14px;
101
+ font-weight: 500;
102
+ padding: 6px 12px;
103
+ border-radius: 6px;
104
+ max-width: 280px;
105
+ overflow: hidden;
106
+ text-overflow: ellipsis;
107
+ display: -webkit-box;
108
+ -webkit-line-clamp: 3;
109
+ -webkit-box-orient: vertical;
110
+ }
111
+
112
+ /* Note: Box, Circle, and Arrow annotations use SVG elements
113
+ styled via attributes, not CSS classes */
114
+
115
+ /* Reduced Motion */
116
+ @media (prefers-reduced-motion: reduce) {
117
+ *, *::before, *::after {
118
+ animation-duration: 0.01ms !important;
119
+ transition-duration: 0.01ms !important;
120
+ }
121
+ }
122
+ `;var M=class{constructor(e,t,n){s(this,"cursor");s(this,"annotations");s(this,"callbacks");s(this,"isRunning",!1);s(this,"currentIndex",0);s(this,"abortController",null);this.cursor=e,this.annotations=t,this.callbacks=n}get running(){return this.isRunning}get actionIndex(){return this.isRunning?this.currentIndex:null}async play(e){this.isRunning&&(console.warn("[Overlay] Stopping current playback to start new script"),this.stop()),this.isRunning=!0,this.currentIndex=0,this.abortController=new AbortController,e.cursor&&(e.cursor.name&&this.cursor.setName(e.cursor.name),e.cursor.color&&this.cursor.setColor(e.cursor.color),e.cursor.visible===!1?this.cursor.hide():this.cursor.show()),this.callbacks.onStart();try{for(let t=0;t<e.actions.length&&this.isRunning;t++){this.currentIndex=t;let n=e.actions[t];this.callbacks.onAction(n,t,"start");try{await this.executeAction(n)}catch(o){if(o instanceof Error&&o.name==="AbortError")break;this.callbacks.onError(o,n)}this.callbacks.onAction(n,t,"complete")}this.isRunning&&this.callbacks.onComplete()}finally{this.isRunning=!1,this.abortController=null}}stop(){this.isRunning&&(this.isRunning=!1,this.abortController?.abort(),this.cursor.cancelAnimations(),this.annotations.cancelAllAnimations(),this.callbacks.onStop())}async executeAction(e){switch(e.type){case"move":await this.executeMove(e);break;case"click":await this.executeClick(e);break;case"wait":await this.executeWait(e);break;case"setCursor":this.executeSetCursor(e);break;case"showAnnotations":this.executeShowAnnotations(e);break;case"hideAnnotations":this.executeHideAnnotations(e);break;default:console.warn("[Overlay] Unknown action type:",e.type)}}async executeMove(e){await this.cursor.moveTo(e.target,{duration:e.duration}),e.showAnnotations&&this.annotations.show(e.showAnnotations)}async executeClick(e){await this.cursor.click(e.target)}async executeWait(e){await S(e.duration)}executeSetCursor(e){e.visible!==void 0&&(e.visible?this.cursor.show():this.cursor.hide()),e.name&&this.cursor.setName(e.name),e.color&&this.cursor.setColor(e.color)}executeShowAnnotations(e){this.annotations.show(e.annotations)}executeHideAnnotations(e){e.ids?this.annotations.hide(e.ids):this.annotations.hideAll()}destroy(){this.stop()}};var rt="#3B82F6",st="#EF4444",at=9999,k=class k{constructor(e={}){s(this,"root");s(this,"shadow");s(this,"container");s(this,"svgContainer");s(this,"domContainer");s(this,"_cursor");s(this,"_annotations");s(this,"timeline");s(this,"reducedMotion");s(this,"motionQuery");s(this,"eventHandlers",new Map);s(this,"_isDestroyed",!1);s(this,"handleMotionChange",e=>{this.reducedMotion=e.matches});let t=e.container??document.body,n=e.zIndex??at;this.motionQuery=window.matchMedia("(prefers-reduced-motion: reduce)"),this.reducedMotion=this.motionQuery.matches,this.motionQuery.addEventListener("change",this.handleMotionChange),this.root=document.createElement("div"),this.root.id="ourroadmaps-overlay",this.shadow=this.root.attachShadow({mode:"open"});let o=document.createElement("style");o.textContent=$,this.shadow.appendChild(o),this.container=document.createElement("div"),this.container.className="overlay-container",this.container.style.setProperty("--overlay-z-index",String(n)),this.shadow.appendChild(this.container),this.svgContainer=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svgContainer.setAttribute("class","annotations-svg"),this.container.appendChild(this.svgContainer),this.domContainer=document.createElement("div"),this.domContainer.className="annotations-dom",this.container.appendChild(this.domContainer);let r={name:e.cursor?.name??"Guide",color:e.cursor?.color??rt,visible:e.cursor?.visible??!0};this._cursor=new P(this.container,this.reducedMotion),this._cursor.setName(r.name),this._cursor.setColor(r.color),r.visible||this._cursor.hide();let a={color:e.annotations?.color??st,strokeWidth:e.annotations?.strokeWidth??3};this._annotations=new O(a,this.domContainer,this.svgContainer,this.reducedMotion,()=>this._cursor.position),this.timeline=new M(this._cursor,this._annotations,{onStart:()=>this.emit("start"),onComplete:()=>this.emit("complete"),onStop:()=>this.emit("stop"),onError:(l,m)=>{this.emit("error",{code:"ANIMATION_FAILED",message:l.message,action:m})},onAction:(l,m,R)=>this.emit("action",l,m,R)}),t.appendChild(this.root)}get cursor(){return this._cursor}get annotations(){return this._annotations}get isPlaying(){return this.timeline.running}get currentActionIndex(){return this.timeline.actionIndex}get isDestroyed(){return this._isDestroyed}validateAction(e,t){let n=[];if(!e||typeof e!="object")return n.push(`Action ${t} must be an object`),n;let o=e;return k.VALID_ACTION_TYPES.includes(o.type)||n.push(`Action ${t} has invalid type: ${o.type}`),o.type==="wait"&&typeof o.duration!="number"&&n.push(`Wait action ${t} must have a numeric duration`),o.type==="move"&&!o.target&&n.push(`Move action ${t} must have a target`),n}validate(e){let t=[],n=[];if(!e||typeof e!="object")return t.push("Script must be an object"),{valid:!1,errors:t,warnings:n};let o=e;if(o.version!==1&&t.push("Script version must be 1"),!Array.isArray(o.actions))t.push("Script must have an actions array");else for(let r=0;r<o.actions.length;r++)t.push(...this.validateAction(o.actions[r],r));return{valid:t.length===0,errors:t,warnings:n}}async play(e){if(this._isDestroyed)throw new Error("Overlay has been destroyed");let t=this.validate(e);if(!t.valid)throw new Error(`Invalid script: ${t.errors.join(", ")}`);await this.timeline.play(e)}stop(){this.timeline.stop()}on(e,t){return this.eventHandlers.has(e)||this.eventHandlers.set(e,new Set),this.eventHandlers.get(e).add(t),()=>{this.eventHandlers.get(e)?.delete(t)}}emit(e,...t){let n=this.eventHandlers.get(e);if(n)for(let o of n)try{o(...t)}catch(r){console.error(`[Overlay] Error in ${e} handler:`,r)}}destroy(){this._isDestroyed||(this._isDestroyed=!0,this.timeline.destroy(),this._cursor.destroy(),this._annotations.destroy(),this.motionQuery.removeEventListener("change",this.handleMotionChange),this.eventHandlers.clear(),this.root.remove())}};s(k,"VALID_ACTION_TYPES",["move","click","wait","setCursor","showAnnotations","hideAnnotations"]);var x=k;function lt(i){return new x(i)}return Y(ct);})();
123
+ //# sourceMappingURL=overlay.global.js.map